2023-10-03 17:50:31 +01:00
import BattleScene , { Button } from "../battle-scene" ;
2023-04-05 13:35:15 +01:00
import { Mode } from "./ui" ;
2023-12-21 00:19:23 +00:00
import UiHandler from "./ui-handler" ;
2023-04-06 16:30:22 +01:00
import * as Utils from "../utils" ;
2023-04-07 03:24:13 +01:00
import { PlayerPokemon } from "../pokemon" ;
2023-04-20 20:46:05 +01:00
import { Type } from "../data/type" ;
2024-01-05 16:29:34 +00:00
import { TextStyle , addBBCodeTextObject , addTextObject , getBBCodeFrag , getTextColor } from "./text" ;
2023-04-20 20:46:05 +01:00
import Move , { MoveCategory } from "../data/move" ;
import { getPokeballAtlasKey } from "../data/pokeball" ;
2024-01-06 03:24:05 +00:00
import { Gender , getGenderColor , getGenderSymbol } from "../data/gender" ;
2023-04-23 21:36:03 +01:00
import { getLevelTotalExp } from "../data/exp" ;
import { Stat , getStatName } from "../data/pokemon-stat" ;
2023-04-23 23:40:21 +01:00
import { PokemonHeldItemModifier } from "../modifier/modifier" ;
2023-10-25 19:15:44 +01:00
import { StatusEffect } from "../data/status-effect" ;
2024-01-13 17:24:24 +00:00
import { getBiomeName } from "../data/biomes" ;
2024-01-06 03:24:05 +00:00
import { Nature , getNatureStatMultiplier } from "../data/nature" ;
2023-04-05 13:35:15 +01:00
2023-04-06 15:05:12 +01:00
enum Page {
PROFILE ,
2023-04-23 21:36:03 +01:00
STATS ,
2023-04-06 15:05:12 +01:00
MOVES
}
2023-04-07 03:24:13 +01:00
export enum SummaryUiMode {
DEFAULT ,
LEARN_MOVE
}
2023-04-05 13:35:15 +01:00
export default class SummaryUiHandler extends UiHandler {
2023-04-07 03:24:13 +01:00
private summaryUiMode : SummaryUiMode ;
2023-04-05 13:35:15 +01:00
private summaryContainer : Phaser.GameObjects.Container ;
2023-04-23 23:40:21 +01:00
private tabSprite : Phaser.GameObjects.Sprite ;
2023-04-24 00:41:32 +01:00
private shinyOverlay : Phaser.GameObjects.Image ;
2023-04-09 01:35:45 +01:00
private numberText : Phaser.GameObjects.Text ;
2023-04-07 18:23:55 +01:00
private pokemonSprite : Phaser.GameObjects.Sprite ;
2023-04-09 01:35:45 +01:00
private nameText : Phaser.GameObjects.Text ;
private pokeball : Phaser.GameObjects.Sprite ;
private levelText : Phaser.GameObjects.Text ;
private genderText : Phaser.GameObjects.Text ;
2023-10-25 19:15:44 +01:00
private statusContainer : Phaser.GameObjects.Container ;
private status : Phaser.GameObjects.Image ;
2023-04-06 16:30:22 +01:00
private summaryPageContainer : Phaser.GameObjects.Container ;
2023-04-07 03:24:13 +01:00
private movesContainer : Phaser.GameObjects.Container ;
2023-04-07 05:17:55 +01:00
private moveDescriptionText : Phaser.GameObjects.Text ;
2023-04-07 03:24:13 +01:00
private moveCursorObj : Phaser.GameObjects.Sprite ;
private selectedMoveCursorObj : Phaser.GameObjects.Sprite ;
2023-04-07 05:17:55 +01:00
private moveRowsContainer : Phaser.GameObjects.Container ;
2023-04-07 03:24:13 +01:00
private extraMoveRowContainer : Phaser.GameObjects.Container ;
2023-04-09 01:35:45 +01:00
private moveEffectContainer : Phaser.GameObjects.Container ;
private movePowerText : Phaser.GameObjects.Text ;
private moveAccuracyText : Phaser.GameObjects.Text ;
private moveCategoryIcon : Phaser.GameObjects.Sprite ;
2023-04-06 16:30:22 +01:00
private summaryPageTransitionContainer : Phaser.GameObjects.Container ;
2023-04-06 15:05:12 +01:00
2023-12-11 16:09:58 +00:00
private descriptionScrollTween : Phaser.Tweens.Tween ;
2023-04-07 05:17:55 +01:00
private moveCursorBlinkTimer : Phaser.Time.TimerEvent ;
2023-04-07 03:24:13 +01:00
private pokemon : PlayerPokemon ;
private newMove : Move ;
private moveSelectFunction : Function ;
2023-04-06 16:30:22 +01:00
private transitioning : boolean ;
2023-10-25 19:15:44 +01:00
private statusVisible : boolean ;
2023-04-09 01:35:45 +01:00
private moveEffectsVisible : boolean ;
2023-04-05 13:35:15 +01:00
2023-04-07 03:24:13 +01:00
private moveSelect : boolean ;
private moveCursor : integer ;
private selectedMoveIndex : integer ;
2023-04-05 13:35:15 +01:00
constructor ( scene : BattleScene ) {
super ( scene , Mode . SUMMARY ) ;
}
setup() {
const ui = this . getUi ( ) ;
this . summaryContainer = this . scene . add . container ( 0 , 0 ) ;
this . summaryContainer . setVisible ( false ) ;
ui . add ( this . summaryContainer ) ;
const summaryBg = this . scene . add . image ( 0 , 0 , 'summary_bg' ) ;
2023-04-06 15:05:12 +01:00
summaryBg . setOrigin ( 0 , 1 ) ;
2023-04-05 13:35:15 +01:00
this . summaryContainer . add ( summaryBg ) ;
2023-04-23 23:40:21 +01:00
this . tabSprite = this . scene . add . sprite ( 134 , ( - summaryBg . displayHeight ) + 16 , 'summary_tabs_1' ) ;
this . tabSprite . setOrigin ( 1 , 1 ) ;
this . summaryContainer . add ( this . tabSprite ) ;
2023-10-25 19:15:44 +01:00
const summaryLabel = addTextObject ( this . scene , 4 , - 165 , 'Pokémon Info' , TextStyle . SUMMARY ) ;
summaryLabel . setOrigin ( 0 , 1 ) ;
this . summaryContainer . add ( summaryLabel ) ;
2023-04-24 00:41:32 +01:00
this . shinyOverlay = this . scene . add . image ( 6 , - 54 , 'summary_overlay_shiny' ) ;
this . shinyOverlay . setOrigin ( 0 , 1 ) ;
this . summaryContainer . add ( this . shinyOverlay ) ;
2023-10-25 19:15:44 +01:00
this . numberText = addTextObject ( this . scene , 17 , - 149 , '000' , TextStyle . SUMMARY ) ;
2023-04-09 01:35:45 +01:00
this . numberText . setOrigin ( 0 , 1 ) ;
this . summaryContainer . add ( this . numberText ) ;
2023-04-07 18:23:55 +01:00
this . pokemonSprite = this . scene . add . sprite ( 56 , - 106 , ` pkmn__sub ` ) ;
2023-11-24 20:12:26 +00:00
this . pokemonSprite . setPipeline ( this . scene . spritePipeline , { ignoreOverride : true , tone : [ 0.0 , 0.0 , 0.0 , 0.0 ] , hasShadow : false } ) ;
2023-04-07 18:23:55 +01:00
this . summaryContainer . add ( this . pokemonSprite ) ;
2023-11-04 04:32:12 +00:00
this . nameText = addTextObject ( this . scene , 6 , - 54 , '' , TextStyle . SUMMARY ) ;
this . nameText . setOrigin ( 0 , 0 ) ;
2023-04-09 01:35:45 +01:00
this . summaryContainer . add ( this . nameText ) ;
2023-11-04 04:32:12 +00:00
this . pokeball = this . scene . add . sprite ( 6 , - 19 , 'pb' ) ;
2023-04-09 01:35:45 +01:00
this . pokeball . setOrigin ( 0 , 1 ) ;
this . summaryContainer . add ( this . pokeball ) ;
2023-11-04 04:32:12 +00:00
this . levelText = addTextObject ( this . scene , 36 , - 18 , '' , TextStyle . SUMMARY ) ;
2023-04-09 01:35:45 +01:00
this . levelText . setOrigin ( 0 , 1 ) ;
this . summaryContainer . add ( this . levelText ) ;
2023-11-04 04:32:12 +00:00
this . genderText = addTextObject ( this . scene , 96 , - 18 , '' , TextStyle . SUMMARY ) ;
2023-04-09 01:35:45 +01:00
this . genderText . setOrigin ( 0 , 1 ) ;
this . summaryContainer . add ( this . genderText ) ;
2023-10-25 19:15:44 +01:00
this . statusContainer = this . scene . add . container ( - 106 , - 16 ) ;
const statusBg = this . scene . add . image ( 0 , 0 , 'summary_status' ) ;
statusBg . setOrigin ( 0 , 0 ) ;
this . statusContainer . add ( statusBg ) ;
const statusLabel = addTextObject ( this . scene , 3 , 0 , 'Status' , TextStyle . SUMMARY ) ;
statusLabel . setOrigin ( 0 , 0 ) ;
this . statusContainer . add ( statusLabel ) ;
this . status = this . scene . add . sprite ( 91 , 4 , 'statuses' ) ;
this . status . setOrigin ( 0.5 , 0 ) ;
this . statusContainer . add ( this . status ) ;
this . summaryContainer . add ( this . statusContainer ) ;
2023-04-09 01:35:45 +01:00
this . moveEffectContainer = this . scene . add . container ( 106 , - 62 ) ;
2023-10-18 23:01:15 +01:00
2023-04-09 01:35:45 +01:00
this . summaryContainer . add ( this . moveEffectContainer ) ;
const moveEffectBg = this . scene . add . image ( 0 , 0 , 'summary_moves_effect' ) ;
moveEffectBg . setOrigin ( 0 , 0 ) ;
this . moveEffectContainer . add ( moveEffectBg ) ;
2023-10-18 23:01:15 +01:00
const moveEffectLabels = addTextObject ( this . scene , 8 , 12 , 'Power\nAccuracy\nCategory' , TextStyle . SUMMARY ) ;
moveEffectLabels . setLineSpacing ( 9 ) ;
moveEffectLabels . setOrigin ( 0 , 0 ) ;
this . moveEffectContainer . add ( moveEffectLabels ) ;
2023-04-09 01:35:45 +01:00
this . movePowerText = addTextObject ( this . scene , 99 , 27 , '0' , TextStyle . WINDOW ) ;
this . movePowerText . setOrigin ( 1 , 1 ) ;
this . moveEffectContainer . add ( this . movePowerText ) ;
this . moveAccuracyText = addTextObject ( this . scene , 99 , 43 , '0' , TextStyle . WINDOW ) ;
this . moveAccuracyText . setOrigin ( 1 , 1 ) ;
this . moveEffectContainer . add ( this . moveAccuracyText ) ;
this . moveCategoryIcon = this . scene . add . sprite ( 99 , 57 , 'categories' ) ;
this . moveCategoryIcon . setOrigin ( 1 , 1 ) ;
this . moveEffectContainer . add ( this . moveCategoryIcon ) ;
2023-04-06 16:30:22 +01:00
const getSummaryPageBg = ( ) = > {
const ret = this . scene . add . sprite ( 0 , 0 , this . getPageKey ( 0 ) ) ;
ret . setOrigin ( 0 , 1 ) ;
return ret ;
} ;
2023-04-07 03:24:13 +01:00
this . summaryContainer . add ( ( this . summaryPageContainer = this . scene . add . container ( 106 , 0 ) ) ) ;
this . summaryPageContainer . add ( getSummaryPageBg ( ) ) ;
this . summaryPageContainer . setVisible ( false ) ;
this . summaryContainer . add ( ( this . summaryPageTransitionContainer = this . scene . add . container ( 106 , 0 ) ) ) ;
this . summaryPageTransitionContainer . add ( getSummaryPageBg ( ) ) ;
this . summaryPageTransitionContainer . setVisible ( false ) ;
2023-04-06 15:05:12 +01:00
}
2023-04-06 16:30:22 +01:00
getPageKey ( page? : integer ) {
if ( page === undefined )
page = this . cursor ;
return ` summary_ ${ Page [ page ] . toLowerCase ( ) } ` ;
2023-04-05 13:35:15 +01:00
}
2023-12-30 23:41:25 +00:00
show ( args : any [ ] ) : boolean {
2023-04-05 13:35:15 +01:00
super . show ( args ) ;
2023-04-07 03:24:13 +01:00
this . pokemon = args [ 0 ] as PlayerPokemon ;
this . summaryUiMode = args . length > 1 ? args [ 1 ] as SummaryUiMode : SummaryUiMode.DEFAULT ;
2024-01-11 05:41:08 +00:00
this . scene . ui . bringToTop ( this . summaryContainer ) ;
2023-04-05 13:35:15 +01:00
this . summaryContainer . setVisible ( true ) ;
2023-04-06 16:30:22 +01:00
this . cursor = - 1 ;
2023-04-07 03:24:13 +01:00
2023-11-06 04:48:04 +00:00
this . shinyOverlay . setVisible ( this . pokemon . isShiny ( ) ) ;
2023-04-24 00:41:32 +01:00
2023-04-09 01:35:45 +01:00
this . numberText . setText ( Utils . padInt ( this . pokemon . species . speciesId , 3 ) ) ;
2023-11-06 04:48:04 +00:00
this . numberText . setColor ( getTextColor ( ! this . pokemon . isShiny ( ) ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD ) ) ;
this . numberText . setShadowColor ( getTextColor ( ! this . pokemon . isShiny ( ) ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD , true ) ) ;
2023-04-09 01:35:45 +01:00
2023-10-29 05:28:56 +00:00
this . pokemonSprite . play ( this . pokemon . getSpriteKey ( true ) ) ;
2023-12-30 20:44:20 +00:00
this . pokemonSprite . pipelineData [ 'ignoreTimeTint' ] = true ;
2023-11-24 20:12:26 +00:00
[ 'spriteColors' , 'fusionSpriteColors' ] . map ( k = > {
delete this . pokemonSprite . pipelineData [ ` ${ k } Base ` ] ;
if ( this . pokemon . summonData ? . speciesForm )
k += 'Base' ;
this . pokemonSprite . pipelineData [ k ] = this . pokemon . getSprite ( ) . pipelineData [ k ] ;
} ) ;
2023-04-07 03:24:13 +01:00
this . pokemon . cry ( ) ;
2023-12-01 22:23:26 +00:00
this . nameText . setText ( this . pokemon . name ) ;
2023-11-04 04:32:12 +00:00
2023-04-09 01:35:45 +01:00
this . pokeball . setFrame ( getPokeballAtlasKey ( this . pokemon . pokeball ) ) ;
this . levelText . setText ( this . pokemon . level . toString ( ) ) ;
2023-10-29 05:28:56 +00:00
this . genderText . setText ( getGenderSymbol ( this . pokemon . getGender ( true ) ) ) ;
this . genderText . setColor ( getGenderColor ( this . pokemon . getGender ( true ) ) ) ;
this . genderText . setShadowColor ( getGenderColor ( this . pokemon . getGender ( true ) , true ) ) ;
2023-04-09 01:35:45 +01:00
2023-04-07 03:24:13 +01:00
switch ( this . summaryUiMode ) {
case SummaryUiMode . DEFAULT :
2023-04-09 01:35:45 +01:00
const page = args . length < 2 ? Page.PROFILE : args [ 2 ] as Page ;
this . hideMoveEffect ( true ) ;
this . setCursor ( page ) ;
2023-04-07 03:24:13 +01:00
break ;
case SummaryUiMode . LEARN_MOVE :
this . newMove = args [ 2 ] as Move ;
this . moveSelectFunction = args [ 3 ] as Function ;
2023-04-09 01:35:45 +01:00
this . showMoveEffect ( true ) ;
2023-04-07 03:24:13 +01:00
this . setCursor ( Page . MOVES ) ;
this . showMoveSelect ( ) ;
break ;
}
2023-10-25 19:15:44 +01:00
const fromSummary = args . length >= 2 ;
if ( this . pokemon . status || this . pokemon . pokerus ) {
this . showStatus ( ! fromSummary ) ;
this . status . setFrame ( this . pokemon . status ? StatusEffect [ this . pokemon . status . effect ] . toLowerCase ( ) : 'pokerus' ) ;
} else
this . hideStatus ( ! fromSummary ) ;
2023-12-30 23:41:25 +00:00
return true ;
2023-04-05 13:35:15 +01:00
}
2023-11-12 05:31:40 +00:00
processInput ( button : Button ) : boolean {
2023-04-06 16:30:22 +01:00
if ( this . transitioning )
2023-11-12 05:31:40 +00:00
return false ;
2023-04-06 16:30:22 +01:00
2023-04-05 13:35:15 +01:00
const ui = this . getUi ( ) ;
2023-04-06 15:05:12 +01:00
2023-04-06 16:30:22 +01:00
let success = false ;
2023-11-12 05:31:40 +00:00
let error = false ;
2023-04-06 16:30:22 +01:00
2023-04-07 03:24:13 +01:00
if ( this . moveSelect ) {
2023-04-11 05:24:55 +01:00
if ( button === Button . ACTION ) {
2023-04-07 03:24:13 +01:00
if ( this . moveCursor < this . pokemon . moveset . length ) {
if ( this . summaryUiMode === SummaryUiMode . LEARN_MOVE )
this . moveSelectFunction ( this . moveCursor ) ;
2023-04-07 05:17:55 +01:00
else {
2023-04-07 18:23:55 +01:00
if ( this . selectedMoveIndex === - 1 ) {
2023-04-07 05:17:55 +01:00
this . selectedMoveIndex = this . moveCursor ;
2023-04-07 18:23:55 +01:00
this . setCursor ( this . moveCursor ) ;
} else {
2023-04-07 05:17:55 +01:00
if ( this . selectedMoveIndex !== this . moveCursor ) {
const tempMove = this . pokemon . moveset [ this . selectedMoveIndex ] ;
this . pokemon . moveset [ this . selectedMoveIndex ] = this . pokemon . moveset [ this . moveCursor ] ;
this . pokemon . moveset [ this . moveCursor ] = tempMove ;
const selectedMoveRow = this . moveRowsContainer . getAt ( this . selectedMoveIndex ) as Phaser . GameObjects . Container ;
const switchMoveRow = this . moveRowsContainer . getAt ( this . moveCursor ) as Phaser . GameObjects . Container ;
this . moveRowsContainer . moveTo ( selectedMoveRow , this . moveCursor ) ;
this . moveRowsContainer . moveTo ( switchMoveRow , this . selectedMoveIndex ) ;
selectedMoveRow . setY ( this . moveCursor * 16 ) ;
switchMoveRow . setY ( this . selectedMoveIndex * 16 ) ;
}
this . selectedMoveIndex = - 1 ;
if ( this . selectedMoveCursorObj ) {
this . selectedMoveCursorObj . destroy ( ) ;
this . selectedMoveCursorObj = null ;
}
}
}
2023-04-07 03:24:13 +01:00
success = true ;
} else if ( this . moveCursor === 4 )
2023-11-12 05:31:40 +00:00
return this . processInput ( Button . CANCEL ) ;
2023-04-07 05:17:55 +01:00
else
2023-11-12 05:31:40 +00:00
error = true ;
2023-04-11 05:24:55 +01:00
} else if ( button === Button . CANCEL ) {
2023-04-07 03:24:13 +01:00
this . hideMoveSelect ( ) ;
success = true ;
} else {
2023-04-11 05:24:55 +01:00
switch ( button ) {
case Button . UP :
2023-04-07 03:24:13 +01:00
success = this . setCursor ( this . moveCursor ? this . moveCursor - 1 : 4 ) ;
break ;
2023-04-11 05:24:55 +01:00
case Button . DOWN :
2023-04-07 03:24:13 +01:00
success = this . setCursor ( this . moveCursor < 4 ? this . moveCursor + 1 : 0 ) ;
break ;
}
}
2023-04-06 16:30:22 +01:00
} else {
2023-04-11 05:24:55 +01:00
if ( button === Button . ACTION ) {
2023-04-07 03:24:13 +01:00
if ( this . cursor === Page . MOVES ) {
this . showMoveSelect ( ) ;
success = true ;
}
2023-04-11 05:24:55 +01:00
} else if ( button === Button . CANCEL ) {
2023-04-07 03:24:13 +01:00
ui . setMode ( Mode . PARTY ) ;
success = true ;
} else {
const pages = Utils . getEnumValues ( Page ) ;
2023-04-11 05:24:55 +01:00
switch ( button ) {
case Button . UP :
case Button . DOWN :
const isDown = button === Button . DOWN ;
2023-04-09 01:35:45 +01:00
const party = this . scene . getParty ( ) ;
const partyMemberIndex = party . indexOf ( this . pokemon ) ;
if ( ( isDown && partyMemberIndex < party . length - 1 ) || ( ! isDown && partyMemberIndex ) ) {
const page = this . cursor ;
this . clear ( ) ;
this . show ( [ party [ partyMemberIndex + ( isDown ? 1 : - 1 ) ] , this . summaryUiMode , page ] ) ;
}
break ;
2023-04-11 05:24:55 +01:00
case Button . LEFT :
2023-04-07 03:24:13 +01:00
if ( this . cursor )
success = this . setCursor ( this . cursor - 1 ) ;
break ;
2023-04-11 05:24:55 +01:00
case Button . RIGHT :
2023-04-07 03:24:13 +01:00
if ( this . cursor < pages . length - 1 )
success = this . setCursor ( this . cursor + 1 ) ;
break ;
}
2023-04-06 16:30:22 +01:00
}
2023-04-06 15:05:12 +01:00
}
2023-04-06 16:30:22 +01:00
if ( success )
ui . playSelect ( ) ;
2023-11-12 05:31:40 +00:00
else if ( error )
ui . playError ( ) ;
return success || error ;
2023-04-05 13:35:15 +01:00
}
setCursor ( cursor : integer ) : boolean {
2023-04-07 03:24:13 +01:00
let changed : boolean ;
if ( this . moveSelect ) {
changed = this . moveCursor !== cursor ;
if ( changed ) {
this . moveCursor = cursor ;
2023-04-07 05:17:55 +01:00
const selectedMove = this . getSelectedMove ( ) ;
2023-04-09 01:35:45 +01:00
if ( selectedMove ) {
this . movePowerText . setText ( selectedMove . power >= 0 ? selectedMove . power . toString ( ) : '---' ) ;
this . moveAccuracyText . setText ( selectedMove . accuracy >= 0 ? selectedMove . accuracy . toString ( ) : '---' ) ;
this . moveCategoryIcon . setFrame ( MoveCategory [ selectedMove . category ] . toLowerCase ( ) ) ;
this . showMoveEffect ( ) ;
} else
this . hideMoveEffect ( ) ;
2023-04-07 05:17:55 +01:00
this . moveDescriptionText . setText ( selectedMove ? . effect || '' ) ;
2023-04-07 18:23:55 +01:00
const moveDescriptionLineCount = Math . floor ( this . moveDescriptionText . displayHeight / 14.83 ) ;
2023-12-11 16:09:58 +00:00
if ( this . descriptionScrollTween ) {
this . descriptionScrollTween . remove ( ) ;
this . descriptionScrollTween = null ;
2023-04-07 18:23:55 +01:00
}
if ( moveDescriptionLineCount > 3 ) {
this . moveDescriptionText . setY ( 84 ) ;
2023-12-11 16:09:58 +00:00
this . descriptionScrollTween = this . scene . tweens . add ( {
2023-04-07 18:23:55 +01:00
targets : this.moveDescriptionText ,
2023-12-01 15:07:21 +00:00
delay : Utils.fixedInt ( 2000 ) ,
2023-04-07 18:23:55 +01:00
loop : - 1 ,
2023-12-01 15:07:21 +00:00
hold : Utils.fixedInt ( 2000 ) ,
duration : Utils.fixedInt ( ( moveDescriptionLineCount - 3 ) * 2000 ) ,
y : ` -= ${ 14.83 * ( moveDescriptionLineCount - 3 ) } `
2023-04-07 18:23:55 +01:00
} ) ;
}
2023-04-07 05:17:55 +01:00
}
if ( ! this . moveCursorObj ) {
this . moveCursorObj = this . scene . add . sprite ( - 2 , 0 , 'summary_moves_cursor' , 'highlight' ) ;
this . moveCursorObj . setOrigin ( 0 , 1 ) ;
this . movesContainer . add ( this . moveCursorObj ) ;
}
this . moveCursorObj . setY ( 16 * this . moveCursor + 1 ) ;
if ( this . moveCursorBlinkTimer )
this . moveCursorBlinkTimer . destroy ( ) ;
2023-04-07 18:23:55 +01:00
this . moveCursorObj . setVisible ( true ) ;
2023-04-07 05:17:55 +01:00
this . moveCursorBlinkTimer = this . scene . time . addEvent ( {
loop : true ,
2023-10-26 04:15:54 +01:00
delay : Utils.fixedInt ( 600 ) ,
2023-04-07 05:17:55 +01:00
callback : ( ) = > {
this . moveCursorObj . setVisible ( false ) ;
2023-10-26 04:15:54 +01:00
this . scene . time . delayedCall ( Utils . fixedInt ( 100 ) , ( ) = > {
2023-04-09 01:35:45 +01:00
if ( ! this . moveCursorObj )
return ;
2023-04-07 05:17:55 +01:00
this . moveCursorObj . setVisible ( true ) ;
} ) ;
2023-04-07 03:24:13 +01:00
}
2023-04-07 05:17:55 +01:00
} ) ;
if ( this . selectedMoveIndex > - 1 ) {
if ( ! this . selectedMoveCursorObj ) {
this . selectedMoveCursorObj = this . scene . add . sprite ( - 2 , 0 , 'summary_moves_cursor' , 'select' ) ;
this . selectedMoveCursorObj . setOrigin ( 0 , 1 ) ;
this . movesContainer . add ( this . selectedMoveCursorObj ) ;
this . movesContainer . moveBelow ( this . selectedMoveCursorObj , this . moveCursorObj ) ;
}
this . selectedMoveCursorObj . setY ( 16 * this . selectedMoveIndex + 1 ) ;
2023-04-07 03:24:13 +01:00
}
} else {
changed = this . cursor !== cursor ;
if ( changed ) {
const forward = this . cursor < cursor ;
this . cursor = cursor ;
2023-04-23 23:40:21 +01:00
this . tabSprite . setTexture ( ` summary_tabs_ ${ this . cursor + 1 } ` ) ;
2023-11-02 04:55:20 +00:00
this . getUi ( ) . hideTooltip ( ) ;
2023-04-07 03:24:13 +01:00
if ( this . summaryPageContainer . visible ) {
this . transitioning = true ;
this . populatePageContainer ( this . summaryPageTransitionContainer , forward ? cursor : cursor + 1 ) ;
if ( forward )
this . summaryPageTransitionContainer . x += 214 ;
else
this . populatePageContainer ( this . summaryPageContainer ) ;
this . scene . tweens . add ( {
targets : this.summaryPageTransitionContainer ,
x : forward ? '-=214' : '+=214' ,
duration : 250 ,
onComplete : ( ) = > {
if ( forward )
this . populatePageContainer ( this . summaryPageContainer ) ;
else
this . summaryPageTransitionContainer . x -= 214 ;
this . summaryPageTransitionContainer . setVisible ( false ) ;
this . transitioning = false ;
}
} ) ;
this . summaryPageTransitionContainer . setVisible ( true ) ;
} else {
2023-04-06 16:30:22 +01:00
this . populatePageContainer ( this . summaryPageContainer ) ;
2023-04-07 03:24:13 +01:00
this . summaryPageContainer . setVisible ( true ) ;
}
2023-04-06 16:30:22 +01:00
}
2023-04-05 13:35:15 +01:00
}
return changed ;
}
2023-04-06 16:30:22 +01:00
populatePageContainer ( pageContainer : Phaser.GameObjects.Container , page? : Page ) {
if ( page === undefined )
page = this . cursor ;
2023-04-07 03:24:13 +01:00
if ( pageContainer . getAll ( ) . length > 1 ) {
2023-04-23 21:36:03 +01:00
pageContainer . each ( ( o : Phaser.GameObjects.GameObject ) = > {
if ( o instanceof Phaser . GameObjects . Container )
o . removeAll ( true ) ;
} ) ;
2023-04-06 16:30:22 +01:00
pageContainer . removeBetween ( 1 , undefined , true ) ;
2023-04-07 03:24:13 +01:00
}
const pageBg = ( pageContainer . getAt ( 0 ) as Phaser . GameObjects . Sprite ) ;
pageBg . setTexture ( this . getPageKey ( page ) ) ;
2023-12-11 16:09:58 +00:00
if ( this . descriptionScrollTween ) {
this . descriptionScrollTween . remove ( ) ;
this . descriptionScrollTween = null ;
}
2023-04-06 16:30:22 +01:00
switch ( page ) {
2023-04-23 23:40:21 +01:00
case Page . PROFILE :
const profileContainer = this . scene . add . container ( 0 , - pageBg . height ) ;
pageContainer . add ( profileContainer ) ;
2023-10-18 23:01:15 +01:00
const typeLabel = addTextObject ( this . scene , 7 , 28 , 'Type/' , TextStyle . WINDOW ) ;
2023-04-23 23:40:21 +01:00
typeLabel . setOrigin ( 0 , 0 ) ;
profileContainer . add ( typeLabel ) ;
const getTypeIcon = ( index : integer , type : Type ) = > {
const typeIcon = this . scene . add . sprite ( 39 + 34 * index , 42 , 'types' , Type [ type ] . toLowerCase ( ) ) ;
typeIcon . setOrigin ( 0 , 1 ) ;
return typeIcon ;
} ;
2023-12-01 15:07:21 +00:00
const types = this . pokemon . getTypes ( true ) ;
profileContainer . add ( getTypeIcon ( 0 , types [ 0 ] ) ) ;
if ( types . length > 1 )
profileContainer . add ( getTypeIcon ( 1 , types [ 1 ] ) ) ;
2023-04-23 23:40:21 +01:00
2023-11-04 04:32:12 +00:00
const ability = this . pokemon . getAbility ( ) ;
2023-04-23 23:40:21 +01:00
2023-04-27 06:14:15 +01:00
const abilityNameText = addTextObject ( this . scene , 7 , 66 , ability . name , TextStyle . SUMMARY ) ;
2023-04-23 23:40:21 +01:00
abilityNameText . setOrigin ( 0 , 1 ) ;
profileContainer . add ( abilityNameText ) ;
2023-12-11 16:09:58 +00:00
const abilityDescriptionText = addTextObject ( this . scene , 7 , 69 , ability . description , TextStyle . WINDOW , { wordWrap : { width : 1224 } } ) ;
2023-04-26 05:16:00 +01:00
abilityDescriptionText . setOrigin ( 0 , 0 ) ;
2023-04-23 23:40:21 +01:00
profileContainer . add ( abilityDescriptionText ) ;
2023-12-11 16:09:58 +00:00
const abilityDescriptionTextMaskRect = this . scene . make . graphics ( { } ) ;
abilityDescriptionTextMaskRect . setScale ( 6 ) ;
abilityDescriptionTextMaskRect . fillStyle ( 0xFFFFFF ) ;
abilityDescriptionTextMaskRect . beginPath ( ) ;
abilityDescriptionTextMaskRect . fillRect ( 110 , 90.5 , 206 , 31 ) ;
const abilityDescriptionTextMask = abilityDescriptionTextMaskRect . createGeometryMask ( ) ;
abilityDescriptionText . setMask ( abilityDescriptionTextMask ) ;
const abilityDescriptionLineCount = Math . floor ( abilityDescriptionText . displayHeight / 14.83 ) ;
if ( abilityDescriptionLineCount > 2 ) {
abilityDescriptionText . setY ( 69 ) ;
this . descriptionScrollTween = this . scene . tweens . add ( {
targets : abilityDescriptionText ,
delay : Utils.fixedInt ( 2000 ) ,
loop : - 1 ,
hold : Utils.fixedInt ( 2000 ) ,
duration : Utils.fixedInt ( ( abilityDescriptionLineCount - 2 ) * 2000 ) ,
y : ` -= ${ 14.83 * ( abilityDescriptionLineCount - 2 ) } `
} ) ;
}
2024-01-05 16:29:34 +00:00
2024-01-06 03:24:05 +00:00
let memoString = ` ${ getBBCodeFrag ( Utils . toReadableString ( Nature [ this . pokemon . nature ] ) , TextStyle . SUMMARY_RED ) } nature, \ n ${ getBBCodeFrag ( ` ${ this . pokemon . metBiome === - 1 ? 'apparently ' : '' } met at Lv ` , TextStyle . WINDOW ) } ${ getBBCodeFrag ( this . pokemon . metLevel . toString ( ) , TextStyle . SUMMARY_RED ) } ${ getBBCodeFrag ( ',' , TextStyle . WINDOW ) } \ n ${ getBBCodeFrag ( getBiomeName ( this . pokemon . metBiome ) , TextStyle . SUMMARY_RED ) } ${ getBBCodeFrag ( '.' , TextStyle . WINDOW ) } ` ;
2024-01-05 16:29:34 +00:00
const memoText = addBBCodeTextObject ( this . scene , 7 , 113 , memoString , TextStyle . WINDOW ) ;
memoText . setOrigin ( 0 , 0 ) ;
profileContainer . add ( memoText ) ;
2023-04-23 23:40:21 +01:00
break ;
2023-04-23 21:36:03 +01:00
case Page . STATS :
const statsContainer = this . scene . add . container ( 0 , - pageBg . height ) ;
pageContainer . add ( statsContainer ) ;
const stats = Utils . getEnumValues ( Stat ) as Stat [ ] ;
stats . forEach ( ( stat , s ) = > {
const statName = stat !== Stat . HP
? getStatName ( stat )
: 'HP' ;
const rowIndex = s % 3 ;
const colIndex = Math . floor ( s / 3 ) ;
2024-01-06 03:24:05 +00:00
const natureStatMultiplier = getNatureStatMultiplier ( this . pokemon . nature , s ) ;
const statLabel = addTextObject ( this . scene , 27 + 115 * colIndex , 56 + 16 * rowIndex , statName , natureStatMultiplier === 1 ? TextStyle.SUMMARY : natureStatMultiplier > 1 ? TextStyle.SUMMARY_BLUE : TextStyle.SUMMARY_PINK ) ;
2023-04-23 21:36:03 +01:00
statLabel . setOrigin ( 0.5 , 0 ) ;
statsContainer . add ( statLabel ) ;
const statValueText = stat !== Stat . HP
? this . pokemon . stats [ s ] . toString ( )
: ` ${ this . pokemon . hp } / ${ this . pokemon . getMaxHp ( ) } ` ;
const statValue = addTextObject ( this . scene , 120 + 88 * colIndex , 56 + 16 * rowIndex , statValueText , TextStyle . WINDOW ) ;
statValue . setOrigin ( 1 , 0 ) ;
statsContainer . add ( statValue ) ;
} ) ;
2023-04-23 23:40:21 +01:00
const itemModifiers = this . scene . findModifiers ( m = > m instanceof PokemonHeldItemModifier
&& ( m as PokemonHeldItemModifier ) . pokemonId === this . pokemon . id , true ) as PokemonHeldItemModifier [ ] ;
itemModifiers . forEach ( ( item , i ) = > {
const icon = item . getIcon ( this . scene , true ) ;
icon . setPosition ( ( i % 17 ) * 12 + 3 , 14 * Math . floor ( i / 17 ) + 15 ) ;
statsContainer . add ( icon ) ;
2023-11-02 04:55:20 +00:00
icon . setInteractive ( new Phaser . Geom . Rectangle ( 0 , 0 , 32 , 32 ) , Phaser . Geom . Rectangle . Contains ) ;
2024-01-18 22:22:18 +00:00
icon . on ( 'pointerover' , ( ) = > ( this . scene as BattleScene ) . ui . showTooltip ( item . type . name , item . type . getDescription ( this . scene ) , true ) ) ;
2023-11-02 04:55:20 +00:00
icon . on ( 'pointerout' , ( ) = > ( this . scene as BattleScene ) . ui . hideTooltip ( ) ) ;
2023-04-23 23:40:21 +01:00
} ) ;
2023-04-23 21:36:03 +01:00
const totalLvExp = getLevelTotalExp ( this . pokemon . level , this . pokemon . species . growthRate ) ;
2023-10-03 17:50:31 +01:00
const expRatio = this . pokemon . level < this . scene . getMaxExpLevel ( ) ? this . pokemon . levelExp / totalLvExp : 0 ;
2023-04-23 21:36:03 +01:00
2023-10-18 23:01:15 +01:00
const expLabel = addTextObject ( this . scene , 6 , 112 , 'EXP. Points' , TextStyle . SUMMARY ) ;
2023-04-23 21:36:03 +01:00
expLabel . setOrigin ( 0 , 0 ) ;
statsContainer . add ( expLabel ) ;
2023-10-18 23:01:15 +01:00
const nextLvExpLabel = addTextObject ( this . scene , 6 , 128 , 'Next Lv.' , TextStyle . SUMMARY ) ;
2023-04-23 21:36:03 +01:00
nextLvExpLabel . setOrigin ( 0 , 0 ) ;
statsContainer . add ( nextLvExpLabel ) ;
const expText = addTextObject ( this . scene , 208 , 112 , this . pokemon . exp . toString ( ) , TextStyle . WINDOW ) ;
expText . setOrigin ( 1 , 0 ) ;
statsContainer . add ( expText ) ;
2023-10-03 17:50:31 +01:00
const nextLvExp = this . pokemon . level < this . scene . getMaxExpLevel ( )
2023-10-28 23:38:22 +01:00
? getLevelTotalExp ( this . pokemon . level + 1 , this . pokemon . species . growthRate ) - this . pokemon . exp
2023-04-29 00:56:11 +01:00
: 0 ;
const nextLvExpText = addTextObject ( this . scene , 208 , 128 , nextLvExp . toString ( ) , TextStyle . WINDOW ) ;
2023-04-23 21:36:03 +01:00
nextLvExpText . setOrigin ( 1 , 0 ) ;
statsContainer . add ( nextLvExpText ) ;
const expOverlay = this . scene . add . image ( 140 , 145 , 'summary_stats_overlay_exp' ) ;
expOverlay . setOrigin ( 0 , 0 ) ;
statsContainer . add ( expOverlay ) ;
const expMaskRect = this . scene . make . graphics ( { } ) ;
expMaskRect . setScale ( 6 ) ;
expMaskRect . fillStyle ( 0xFFFFFF ) ;
expMaskRect . beginPath ( ) ;
expMaskRect . fillRect ( 140 + pageContainer . x , 145 + pageContainer . y + 21 , Math . floor ( expRatio * 64 ) , 3 ) ;
const expMask = expMaskRect . createGeometryMask ( ) ;
expOverlay . setMask ( expMask ) ;
break ;
2023-04-06 16:30:22 +01:00
case Page . MOVES :
2023-04-07 03:24:13 +01:00
this . movesContainer = this . scene . add . container ( 5 , - pageBg . height + 26 ) ;
pageContainer . add ( this . movesContainer ) ;
this . extraMoveRowContainer = this . scene . add . container ( 0 , 64 ) ;
2023-04-07 05:17:55 +01:00
this . extraMoveRowContainer . setVisible ( false ) ;
2023-04-07 03:24:13 +01:00
this . movesContainer . add ( this . extraMoveRowContainer ) ;
const extraRowOverlay = this . scene . add . image ( - 2 , 1 , 'summary_moves_overlay_row' ) ;
extraRowOverlay . setOrigin ( 0 , 1 ) ;
this . extraMoveRowContainer . add ( extraRowOverlay ) ;
2023-10-18 23:01:15 +01:00
const extraRowText = addTextObject ( this . scene , 35 , 0 , this . summaryUiMode === SummaryUiMode . LEARN_MOVE ? this . newMove . name : 'Cancel' ,
2024-01-05 16:29:34 +00:00
this . summaryUiMode === SummaryUiMode . LEARN_MOVE ? TextStyle.SUMMARY_PINK : TextStyle.SUMMARY ) ;
2023-04-07 03:24:13 +01:00
extraRowText . setOrigin ( 0 , 1 ) ;
this . extraMoveRowContainer . add ( extraRowText ) ;
2023-04-10 18:54:06 +01:00
if ( this . summaryUiMode === SummaryUiMode . LEARN_MOVE ) {
const newMoveTypeIcon = this . scene . add . sprite ( 0 , 0 , 'types' , Type [ this . newMove . type ] . toLowerCase ( ) ) ;
newMoveTypeIcon . setOrigin ( 0 , 1 ) ;
this . extraMoveRowContainer . add ( newMoveTypeIcon ) ;
2023-04-23 20:13:21 +01:00
const ppOverlay = this . scene . add . image ( 163 , - 1 , 'summary_moves_overlay_pp' ) ;
ppOverlay . setOrigin ( 0 , 1 ) ;
this . extraMoveRowContainer . add ( ppOverlay ) ;
const pp = Utils . padInt ( this . newMove . pp , 2 , ' ' ) ;
const ppText = addTextObject ( this . scene , 173 , 1 , ` ${ pp } / ${ pp } ` , TextStyle . WINDOW ) ;
ppText . setOrigin ( 0 , 1 ) ;
this . extraMoveRowContainer . add ( ppText ) ;
2023-04-10 18:54:06 +01:00
}
2023-04-07 05:17:55 +01:00
this . moveRowsContainer = this . scene . add . container ( 0 , 0 ) ;
this . movesContainer . add ( this . moveRowsContainer ) ;
2023-04-07 03:24:13 +01:00
for ( let m = 0 ; m < 4 ; m ++ ) {
const move = m < this . pokemon . moveset . length ? this . pokemon . moveset [ m ] : null ;
2023-04-07 05:17:55 +01:00
const moveRowContainer = this . scene . add . container ( 0 , 16 * m ) ;
this . moveRowsContainer . add ( moveRowContainer ) ;
2023-04-07 03:24:13 +01:00
if ( move ) {
2023-04-07 05:17:55 +01:00
const typeIcon = this . scene . add . sprite ( 0 , 0 , 'types' , Type [ move . getMove ( ) . type ] . toLowerCase ( ) ) ;
2023-04-07 03:24:13 +01:00
typeIcon . setOrigin ( 0 , 1 ) ;
2023-04-07 05:17:55 +01:00
moveRowContainer . add ( typeIcon ) ;
2023-04-07 03:24:13 +01:00
}
2023-04-07 05:17:55 +01:00
const moveText = addTextObject ( this . scene , 35 , 0 , move ? move . getName ( ) : '-' , TextStyle . SUMMARY ) ;
2023-04-07 03:24:13 +01:00
moveText . setOrigin ( 0 , 1 ) ;
2023-04-07 05:17:55 +01:00
moveRowContainer . add ( moveText ) ;
2023-04-23 20:13:21 +01:00
const ppOverlay = this . scene . add . image ( 163 , - 1 , 'summary_moves_overlay_pp' ) ;
ppOverlay . setOrigin ( 0 , 1 ) ;
moveRowContainer . add ( ppOverlay ) ;
const ppText = addTextObject ( this . scene , 173 , 1 , '--/--' , TextStyle . WINDOW ) ;
ppText . setOrigin ( 0 , 1 ) ;
if ( move ) {
2024-01-30 01:57:59 +00:00
const maxPP = move . getMovePp ( ) ;
2023-04-23 20:13:21 +01:00
const pp = maxPP - move . ppUsed ;
ppText . setText ( ` ${ Utils . padInt ( pp , 2 , ' ' ) } / ${ Utils . padInt ( maxPP , 2 , ' ' ) } ` ) ;
}
moveRowContainer . add ( ppText ) ;
2023-04-07 03:24:13 +01:00
}
2023-04-07 05:17:55 +01:00
2023-04-23 20:13:21 +01:00
this . moveDescriptionText = addTextObject ( this . scene , 2 , 84 , '' , TextStyle . WINDOW , { wordWrap : { width : 1212 } } ) ;
2023-04-07 05:17:55 +01:00
this . movesContainer . add ( this . moveDescriptionText ) ;
2023-04-23 21:36:03 +01:00
const moveDescriptionTextMaskRect = this . scene . make . graphics ( { } ) ;
moveDescriptionTextMaskRect . setScale ( 6 ) ;
moveDescriptionTextMaskRect . fillStyle ( 0xFFFFFF ) ;
moveDescriptionTextMaskRect . beginPath ( ) ;
moveDescriptionTextMaskRect . fillRect ( 112 , 130 , 202 , 46 ) ;
2023-04-07 05:17:55 +01:00
2023-04-23 21:36:03 +01:00
const moveDescriptionTextMask = moveDescriptionTextMaskRect . createGeometryMask ( ) ;
2023-04-07 05:17:55 +01:00
this . moveDescriptionText . setMask ( moveDescriptionTextMask ) ;
2023-04-06 16:30:22 +01:00
break ;
}
}
2023-10-25 19:15:44 +01:00
showStatus ( instant? : boolean ) {
if ( this . statusVisible )
return ;
this . statusVisible = true ;
this . scene . tweens . add ( {
targets : this.statusContainer ,
x : 0 ,
duration : instant ? 0 : 250 ,
ease : 'Sine.easeOut'
} ) ;
}
hideStatus ( instant? : boolean ) {
if ( ! this . statusVisible )
return ;
this . statusVisible = false ;
this . scene . tweens . add ( {
targets : this.statusContainer ,
x : - 106 ,
duration : instant ? 0 : 250 ,
ease : 'Sine.easeIn'
} ) ;
}
2023-04-07 05:17:55 +01:00
getSelectedMove ( ) : Move {
if ( this . cursor !== Page . MOVES )
return null ;
if ( this . moveCursor < 4 && this . moveCursor < this . pokemon . moveset . length )
return this . pokemon . moveset [ this . moveCursor ] . getMove ( ) ;
else if ( this . summaryUiMode === SummaryUiMode . LEARN_MOVE && this . moveCursor === 4 )
return this . newMove ;
return null ;
}
2023-04-07 03:24:13 +01:00
showMoveSelect() {
this . moveSelect = true ;
2023-04-07 05:17:55 +01:00
this . extraMoveRowContainer . setVisible ( true ) ;
this . selectedMoveIndex = - 1 ;
2023-04-07 03:24:13 +01:00
this . setCursor ( 0 ) ;
2023-04-09 01:35:45 +01:00
this . showMoveEffect ( ) ;
2023-04-07 03:24:13 +01:00
}
hideMoveSelect() {
if ( this . summaryUiMode === SummaryUiMode . LEARN_MOVE ) {
this . moveSelectFunction ( 4 ) ;
return ;
}
this . moveSelect = false ;
2023-04-07 05:17:55 +01:00
this . extraMoveRowContainer . setVisible ( false ) ;
2023-05-08 23:48:35 +01:00
this . moveDescriptionText . setText ( '' ) ;
2023-04-07 05:17:55 +01:00
if ( this . moveCursorBlinkTimer ) {
this . moveCursorBlinkTimer . destroy ( ) ;
this . moveCursorBlinkTimer = null ;
}
if ( this . moveCursorObj ) {
this . moveCursorObj . destroy ( ) ;
this . moveCursorObj = null ;
}
if ( this . selectedMoveCursorObj ) {
this . selectedMoveCursorObj . destroy ( ) ;
this . selectedMoveCursorObj = null ;
}
2023-04-09 01:35:45 +01:00
this . hideMoveEffect ( ) ;
}
showMoveEffect ( instant? : boolean ) {
if ( this . moveEffectsVisible )
return ;
this . moveEffectsVisible = true ;
this . scene . tweens . add ( {
targets : this.moveEffectContainer ,
x : 6 ,
duration : instant ? 0 : 250 ,
ease : 'Sine.easeOut'
} ) ;
}
hideMoveEffect ( instant? : boolean ) {
if ( ! this . moveEffectsVisible )
return ;
this . moveEffectsVisible = false ;
this . scene . tweens . add ( {
targets : this.moveEffectContainer ,
x : 106 ,
duration : instant ? 0 : 250 ,
ease : 'Sine.easeIn'
} ) ;
2023-04-07 03:24:13 +01:00
}
2023-04-05 13:35:15 +01:00
clear() {
super . clear ( ) ;
2023-04-07 03:24:13 +01:00
this . pokemon = null ;
2023-04-06 16:30:22 +01:00
this . cursor = - 1 ;
2023-04-07 03:24:13 +01:00
this . newMove = null ;
2023-04-10 18:54:06 +01:00
if ( this . moveSelect ) {
this . moveSelect = false ;
this . moveSelectFunction = null ;
this . extraMoveRowContainer . setVisible ( false ) ;
if ( this . moveCursorBlinkTimer ) {
this . moveCursorBlinkTimer . destroy ( ) ;
this . moveCursorBlinkTimer = null ;
}
if ( this . moveCursorObj ) {
this . moveCursorObj . destroy ( ) ;
this . moveCursorObj = null ;
}
if ( this . selectedMoveCursorObj ) {
this . selectedMoveCursorObj . destroy ( ) ;
this . selectedMoveCursorObj = null ;
}
this . hideMoveEffect ( true ) ;
}
2023-04-05 13:35:15 +01:00
this . summaryContainer . setVisible ( false ) ;
2023-04-06 16:30:22 +01:00
this . summaryPageContainer . setVisible ( false ) ;
2023-04-05 13:35:15 +01:00
}
}