2017-09-24 22:23:22 +00:00
module TK.SpaceTac.UI {
2018-03-11 23:07:41 +00:00
export enum CharacterSheetMode {
CREATION ,
EDITION ,
DISPLAY
}
2017-02-27 23:36:12 +00:00
/ * *
* Character sheet , displaying ship characteristics
* /
2018-05-15 14:57:45 +00:00
export class CharacterSheet {
2018-03-11 23:07:41 +00:00
// Global sheet mode
2018-03-20 22:06:39 +00:00
mode : CharacterSheetMode
2017-11-14 23:45:09 +00:00
2017-03-15 21:40:19 +00:00
// Parent view
2017-10-09 22:59:49 +00:00
view : BaseView
2017-03-15 21:40:19 +00:00
2017-10-11 21:49:56 +00:00
// UI components builder
2018-05-15 14:57:45 +00:00
container : UIContainer
2017-10-11 21:49:56 +00:00
builder : UIBuilder
2018-03-20 22:06:39 +00:00
// Close/validate button
close_button : UIButton
2017-02-28 00:07:37 +00:00
// X positions
2018-02-08 15:16:03 +00:00
xshown = 0
xhidden = - 2000
// Groups
2018-05-15 14:57:45 +00:00
group_level : UIContainer
group_portraits : UIContainer
group_attributes : UIContainer
group_actions : UIContainer
group_upgrades : UIContainer
2017-10-09 22:59:49 +00:00
2017-02-27 23:36:12 +00:00
// Currently displayed fleet
2018-02-08 15:16:03 +00:00
fleet? : Fleet
2017-02-27 23:36:12 +00:00
// Currently displayed ship
2018-02-08 15:16:03 +00:00
ship? : Ship
// Variable data
2018-03-20 22:06:39 +00:00
personality? : CharacterPersonality
2018-05-15 14:57:45 +00:00
image_portrait : UIImage
text_model : UIText
text_description : UIText
text_name? : UIText
text_level : UIText
text_upgrade_points : UIText
2018-02-08 15:16:03 +00:00
valuebar_experience : ValueBar
2018-03-20 22:06:39 +00:00
constructor ( view : BaseView , mode : CharacterSheetMode , onclose? : Function ) {
2018-05-15 14:57:45 +00:00
this . view = view ;
this . mode = mode ;
let builder = new UIBuilder ( view ) ;
this . container = builder . container ( "character-sheet" ) ;
builder = builder . in ( this . container ) ;
let bg = builder . image ( "character-sheet" ) ;
bg . setInteractive ( ) ;
this . builder = builder . styled ( { color : "#dce9f9" , size : 16 , shadow : true } ) ;
2017-02-27 23:36:12 +00:00
2018-03-20 22:06:39 +00:00
if ( ! onclose ) {
onclose = ( ) = > this . hide ( ) ;
}
2018-02-08 15:16:03 +00:00
this . xhidden = - this . view . getWidth ( ) ;
2018-05-15 14:57:45 +00:00
this . container . x = this . xhidden ;
2017-02-28 22:34:02 +00:00
2018-06-06 21:00:22 +00:00
this . image_portrait = this . builder . image ( "common-transparent" , 435 , 271 , true ) ;
2017-03-23 18:58:09 +00:00
2018-03-20 22:06:39 +00:00
this . builder . image ( "character-entry" , 24 , 740 ) ;
2017-03-12 23:32:41 +00:00
2018-05-15 14:57:45 +00:00
this . group_portraits = this . builder . container ( "portraits" , 90 , 755 ) ;
2017-03-23 18:58:09 +00:00
2018-02-08 15:16:03 +00:00
let model_bg = this . builder . image ( "character-ship-model" , 434 , 500 , true ) ;
this . text_model = this . builder . in ( model_bg ) . text ( "" , 0 , 0 , { size : 28 } ) ;
2017-02-27 23:36:12 +00:00
2018-02-08 15:16:03 +00:00
let description_bg = this . builder . image ( "character-ship-description" , 434 , 654 , true ) ;
this . text_description = this . builder . in ( description_bg ) . text ( "" , 0 , 0 , { color : "#a0afc3" , width : 510 } ) ;
2017-03-05 23:29:02 +00:00
2018-05-15 14:57:45 +00:00
this . group_attributes = this . builder . container ( "attributes" , 28 , 28 ) ;
this . group_actions = this . builder . container ( "actions" , 698 , 28 ) ;
2017-02-27 23:36:12 +00:00
2018-05-15 14:57:45 +00:00
this . group_level = this . builder . container ( "level" ) ;
2018-03-20 22:06:39 +00:00
let points_bg = this . builder . in ( this . group_level ) . image ( "character-level-upgrades" , 582 , 986 ) ;
2018-02-08 15:16:03 +00:00
this . builder . in ( points_bg , builder = > {
builder . text ( "Upgrade points" , 46 , 10 , { center : false , vcenter : false } ) ;
builder . image ( "character-upgrade-point" , 147 , 59 , true ) ;
} ) ;
this . text_upgrade_points = this . builder . in ( points_bg ) . text ( "" , 106 , 60 , { size : 28 } ) ;
2017-03-15 21:40:19 +00:00
2018-03-20 22:06:39 +00:00
let level_bg = this . builder . in ( this . group_level ) . image ( "character-level-display" , 434 , 1032 , true ) ;
2018-02-08 15:16:03 +00:00
this . text_level = this . builder . in ( level_bg ) . text ( "" , 0 , 4 , { size : 28 } ) ;
this . valuebar_experience = this . builder . in ( level_bg ) . valuebar ( "character-level-experience" , - level_bg . width * 0.5 , - level_bg . height * 0.5 ) ;
2017-02-27 23:36:12 +00:00
2018-05-15 14:57:45 +00:00
this . group_upgrades = this . builder . container ( "upgrades" ) ;
2017-10-10 17:01:09 +00:00
2018-03-20 22:06:39 +00:00
if ( this . mode == CharacterSheetMode . CREATION ) {
this . builder . in ( this . builder . image ( "character-section-title" , 180 , 30 , false ) ) . text ( "Ship" , 80 , 45 , { color : "#dce9f9" , size : 32 } ) ;
this . personality = new CharacterPersonality ( this . builder , 950 , 30 ) ;
this . close_button = this . builder . button ( "character-validate-creation" , 140 , 930 , onclose ,
"Validate the team, and start the campaign" , undefined , {
hover_bottom : true ,
text : "Validate team" ,
text_x : 295 ,
text_y : 57 ,
text_style : { size : 32 , color : "#fff3df" }
}
) ;
this . builder . in ( this . builder . image ( "character-creation-help" , 970 , 680 ) , builder = > {
builder . text ( "Compose your initial team by choosing a model for each ship, and customize the name and personality of the Artificial Intelligence pilot" ,
405 , 150 , { color : "#a3bbd9" , size : 22 , width : 500 } ) ;
} ) ;
this . builder . button ( "character-model-prev" , 216 , 500 , ( ) = > this . changeModel ( - 1 ) , "Select previous model" , undefined , { center : true } ) ;
this . builder . button ( "character-model-next" , 654 , 500 , ( ) = > this . changeModel ( 1 ) , "Select next model" , undefined , { center : true } ) ;
this . group_level . visible = false ;
this . group_upgrades . visible = false ;
} else {
this . text_name = this . builder . in ( this . builder . image ( "character-name-display" , 434 , 940 , true ) ) . text ( "" , 0 , 0 , { size : 28 } ) ;
2018-05-15 14:57:45 +00:00
this . close_button = this . builder . button ( "character-close-button" , 1837 , 0 , onclose , "Close the character sheet" ) ;
2018-03-20 22:06:39 +00:00
}
2018-02-08 15:16:03 +00:00
this . refreshUpgrades ( ) ;
this . refreshAttributes ( ) ;
this . refreshActions ( ) ;
2017-02-27 23:36:12 +00:00
}
2018-05-15 14:57:45 +00:00
/ * *
* Move the sheet to a specific layer
* /
moveToLayer ( layer : UIContainer ) : void {
layer . add ( this . container ) ;
}
2017-11-14 23:45:09 +00:00
/ * *
* Check if the sheet should be interactive
* /
isInteractive ( ) : boolean {
2018-03-11 23:07:41 +00:00
return this . ship ? ( this . mode != CharacterSheetMode . DISPLAY && ! this . ship . critical ) : false ;
2018-02-08 15:16:03 +00:00
}
/ * *
2018-03-20 22:06:39 +00:00
* Change the ship model
2018-02-08 15:16:03 +00:00
* /
2018-03-20 22:06:39 +00:00
changeModel ( offset : number ) : void {
if ( this . mode == CharacterSheetMode . CREATION && this . ship ) {
let models = ShipModel . getDefaultCollection ( ) ;
let idx = models . map ( model = > model . code ) . indexOf ( this . ship . model . code ) + offset ;
if ( idx < 0 ) {
idx = models . length - 1 ;
} else if ( idx >= models . length ) {
idx = 0 ;
2018-03-11 23:07:41 +00:00
}
2018-03-20 22:06:39 +00:00
this . ship . setModel ( models [ idx ] ) ;
this . refresh ( ) ;
}
2018-02-08 15:16:03 +00:00
}
/ * *
* Refresh the ship information display
* /
private refreshShipInfo ( ) : void {
if ( this . ship ) {
let ship = this . ship ;
this . builder . change ( this . image_portrait , ` ship- ${ ship . model . code } -portrait ` ) ;
2018-03-20 22:06:39 +00:00
if ( this . text_name ) {
this . text_name . setText ( ship . name || "" ) ;
}
if ( this . personality ) {
this . personality . displayShip ( ship ) ;
}
2018-02-08 15:16:03 +00:00
this . text_model . setText ( ship . model . name ) ;
this . text_level . setText ( ` Level ${ ship . level . get ( ) } ` ) ;
this . text_description . setText ( ship . model . getDescription ( ) ) ;
this . text_upgrade_points . setText ( ` ${ ship . getAvailableUpgradePoints ( ) } ` ) ;
this . valuebar_experience . setValue ( ship . level . getExperience ( ) , ship . level . getNextGoal ( ) ) ;
}
2017-11-14 23:45:09 +00:00
}
2017-02-27 23:36:12 +00:00
/ * *
2018-02-08 15:16:03 +00:00
* Refresh the upgrades display
2017-02-27 23:36:12 +00:00
* /
2018-02-08 15:16:03 +00:00
private refreshUpgrades ( ) : void {
let builder = this . builder . in ( this . group_upgrades ) ;
builder . clear ( ) ;
2018-03-20 22:06:39 +00:00
if ( ! this . ship || this . mode == CharacterSheetMode . CREATION ) {
2018-02-08 15:16:03 +00:00
return ;
}
2018-01-31 18:19:50 +00:00
let ship = this . ship ;
2018-02-08 15:16:03 +00:00
let initial = builder . image ( "character-initial" , 970 , 30 ) ;
// Base equipment (level 1)
builder . styled ( { center : false , vcenter : false } ) . in ( initial , builder = > {
builder . text ( "Base equipment" , 32 , 8 , { color : "#e2e9d1" } ) ;
2018-05-15 14:57:45 +00:00
builder . in ( builder . container ( "attributes" ) , builder = > {
2018-02-08 15:16:03 +00:00
let effects = cfilter ( ship . model . getEffects ( 1 , [ ] ) , AttributeEffect ) ;
effects . forEach ( effect = > {
let button = builder . button ( ` attribute- ${ effect . attrcode } ` , 0 , 8 , undefined ,
` ${ capitalize ( SHIP_VALUES_NAMES [ effect . attrcode ] ) } - ${ SHIP_VALUES_DESCRIPTIONS [ effect . attrcode ] } ` ) ;
builder . in ( button , builder = > {
builder . text ( ` ${ effect . value } ` , 56 , 8 , { size : 22 } ) ;
} ) ;
} ) ;
builder . distribute ( "x" , 236 , 870 ) ;
} ) ;
2018-05-15 14:57:45 +00:00
builder . in ( builder . container ( "actions" ) , builder = > {
2018-02-08 15:16:03 +00:00
let actions = ship . model . getActions ( 1 , [ ] ) ;
actions . forEach ( action = > {
2018-06-06 21:00:22 +00:00
let button = builder . button ( "common-transparent" , 0 , 66 , undefined , action . getEffectsDescription ( ) ) ;
2018-02-08 15:16:03 +00:00
builder . in ( button , builder = > {
let icon = builder . image ( ` action- ${ action . code } ` ) ;
2018-05-15 14:57:45 +00:00
icon . setScale ( 0.1875 ) ;
2018-02-08 15:16:03 +00:00
if ( actions . length < 5 ) {
builder . text ( ` ${ action . name } ` , 56 , 12 , { size : 16 } ) ;
}
} ) ;
} ) ;
builder . distribute ( "x" , 28 , 888 ) ;
} ) ;
} ) ;
// Level number
range ( 10 ) . forEach ( i = > {
builder . text ( ` ${ i + 1 } ` , 920 , i == 0 ? 92 : ( 110 + i * 100 ) , {
center : true ,
vcenter : true ,
size : 28 ,
2018-03-20 22:06:39 +00:00
color : ship.level.get ( ) >= ( i + 1 ) ? "#dce9f9" : "#293038"
2018-02-08 15:16:03 +00:00
} ) ;
} ) ;
// Level upgrades
range ( 9 ) . forEach ( i = > {
builder . image ( "character-level-separator" , 844 , 154 + i * 100 ) ;
let level = i + 2 ;
let upgrades = ship . model . getLevelUpgrades ( level ) ;
upgrades . forEach ( ( upgrade , j ) = > {
let onchange = ( selected : boolean ) = > {
this . refreshShipInfo ( ) ; // TODO Only upgrade points
this . refreshActions ( ) ;
this . refreshAttributes ( ) ;
} ;
new CharacterUpgrade ( ship , upgrade , level ) . draw ( builder , 970 + j * 315 , 170 + i * 100 ,
this . isInteractive ( ) ? onchange : undefined ) ;
} ) ;
} ) ;
}
2017-10-11 21:49:56 +00:00
2018-02-08 15:16:03 +00:00
/ * *
* Refresh the attributes display
* /
private refreshAttributes ( ) : void {
let builder = this . builder . in ( this . group_attributes ) ;
builder . clear ( ) ;
2018-05-15 14:57:45 +00:00
builder . image ( "character-ship-column-left" , 0 , 0 ) ;
2018-03-20 22:06:39 +00:00
builder . text ( "Attributes" , 74 , 20 , { color : "#a3bbd9" } ) ;
2017-10-10 17:01:09 +00:00
2018-02-08 15:16:03 +00:00
if ( this . ship ) {
let ship = this . ship ;
2018-05-15 14:57:45 +00:00
builder . in ( builder . container ( "items" ) , builder = > {
2018-02-08 15:16:03 +00:00
keys ( SHIP_ATTRIBUTES ) . forEach ( attribute = > {
let button = builder . button ( ` attribute- ${ attribute } ` , 24 , 0 , undefined ,
ship . getAttributeDescription ( attribute ) ) ;
builder . in ( button ) . text ( ` ${ ship . getAttribute ( attribute ) } ` , 78 , 27 , { size : 22 } ) ;
} ) ;
builder . distribute ( "y" , 40 , 688 ) ;
} ) ;
}
}
2017-07-12 23:18:20 +00:00
2018-02-08 15:16:03 +00:00
/ * *
* Refresh the actions display
* /
private refreshActions ( ) : void {
let builder = this . builder . in ( this . group_actions ) ;
builder . clear ( ) ;
2017-02-27 23:36:12 +00:00
2018-05-15 14:57:45 +00:00
builder . image ( "character-ship-column-right" , 0 , 0 ) ;
2018-03-20 22:06:39 +00:00
builder . text ( "Actions" , 74 , 20 , { color : "#a3bbd9" } ) ;
2017-03-17 00:07:00 +00:00
2018-02-08 15:16:03 +00:00
if ( this . ship ) {
let ship = this . ship ;
2018-05-15 14:57:45 +00:00
builder . in ( builder . container ( "items" ) , builder = > {
2018-02-08 15:16:03 +00:00
let actions = ship . actions . listAll ( ) . filter ( action = > ! ( action instanceof EndTurnAction ) ) ;
actions . forEach ( action = > {
2018-06-06 21:06:04 +00:00
let button = builder . button ( ` action- ${ action . code } ` , 24 , 0 , undefined , filler = > ActionTooltip . fill ( filler , ship , action ) ) ;
2018-05-15 14:57:45 +00:00
button . setScale ( 0.375 ) ;
2018-02-08 15:16:03 +00:00
} ) ;
builder . distribute ( "y" , 40 , 688 ) ;
} ) ;
2017-03-17 00:07:00 +00:00
}
2017-02-27 23:36:12 +00:00
}
/ * *
2018-03-20 22:06:39 +00:00
* Refresh the fleet display
2017-02-27 23:36:12 +00:00
* /
2018-03-20 22:06:39 +00:00
private refreshFleet ( ) : void {
destroyChildren ( this . group_portraits ) ;
2017-02-27 23:36:12 +00:00
2018-03-20 22:06:39 +00:00
if ( this . fleet ) {
2018-02-08 15:16:03 +00:00
let builder = this . builder . in ( this . group_portraits ) ;
2018-03-20 22:06:39 +00:00
this . fleet . ships . forEach ( ( ship , idx ) = > {
2018-03-05 23:52:44 +00:00
let button : UIButton ;
2018-02-08 15:16:03 +00:00
button = new CharacterPortrait ( ship ) . draw ( builder , 64 + idx * 140 , 64 , ( ) = > {
if ( button ) {
2018-05-15 14:57:45 +00:00
button . toggle ( true , UIButtonUnicity . EXCLUSIVE_MIN ) ;
2018-02-08 15:16:03 +00:00
this . ship = ship ;
2018-03-20 22:06:39 +00:00
2018-02-08 15:16:03 +00:00
this . refreshShipInfo ( ) ;
this . refreshActions ( ) ;
this . refreshAttributes ( ) ;
this . refreshUpgrades ( ) ;
}
} ) ;
2018-03-05 23:52:44 +00:00
if ( ship == this . ship ) {
2018-05-15 14:57:45 +00:00
button . toggle ( true ) ;
2018-03-05 23:52:44 +00:00
}
2018-02-08 15:16:03 +00:00
} ) ;
2017-07-02 18:21:04 +00:00
}
2017-02-27 23:36:12 +00:00
}
2017-12-07 00:05:06 +00:00
/ * *
* Check if the sheet is shown
* /
isOpened ( ) : boolean {
2018-05-15 14:57:45 +00:00
return this . container . x != this . xhidden ;
2017-12-07 00:05:06 +00:00
}
2017-02-27 23:36:12 +00:00
/ * *
* Show the sheet for a given ship
* /
2018-03-20 22:06:39 +00:00
show ( ship : Ship , animate = true , sound = true ) {
2017-02-27 23:36:12 +00:00
this . ship = ship ;
2018-03-20 22:06:39 +00:00
this . fleet = ship . fleet ;
2017-02-27 23:36:12 +00:00
2018-02-08 15:16:03 +00:00
this . refreshShipInfo ( ) ;
this . refreshUpgrades ( ) ;
this . refreshAttributes ( ) ;
this . refreshActions ( ) ;
2017-03-14 17:48:04 +00:00
2018-03-20 22:06:39 +00:00
if ( ship . fleet !== this . fleet || ship . fleet . ships . length != this . group_portraits . length ) {
this . refreshFleet ( ) ;
}
2017-02-27 23:36:12 +00:00
2017-07-19 23:22:18 +00:00
if ( sound ) {
this . view . audio . playOnce ( "ui-dialog-open" ) ;
}
2017-02-27 23:36:12 +00:00
if ( animate ) {
2018-05-15 14:57:45 +00:00
this . view . tweens . add ( {
targets : this.container ,
x : this.xshown ,
duration : 400 ,
easing : 'Circ.easeInOut'
} ) ;
2017-02-27 23:36:12 +00:00
} else {
2018-05-15 14:57:45 +00:00
this . container . x = this . xshown ;
2017-02-27 23:36:12 +00:00
}
}
/ * *
* Hide the sheet
* /
2017-02-28 00:07:37 +00:00
hide ( animate = true ) {
2017-07-19 23:22:18 +00:00
this . view . audio . playOnce ( "ui-dialog-close" ) ;
2017-02-28 00:07:37 +00:00
if ( animate ) {
2018-05-15 14:57:45 +00:00
this . view . tweens . add ( {
targets : this.container ,
x : this.xhidden ,
duration : 400 ,
ease : 'Circ.easeInOut'
} ) ;
2017-02-28 00:07:37 +00:00
} else {
2018-05-15 14:57:45 +00:00
this . container . x = this . xhidden ;
2017-02-28 00:07:37 +00:00
}
2017-02-28 22:34:02 +00:00
}
2017-03-05 23:29:02 +00:00
/ * *
* Refresh the sheet display
* /
refresh() {
2018-01-31 18:19:50 +00:00
if ( this . ship ) {
2018-03-20 22:06:39 +00:00
this . refreshShipInfo ( ) ;
this . refreshUpgrades ( ) ;
this . refreshAttributes ( ) ;
this . refreshActions ( ) ;
this . refreshFleet ( ) ;
2018-01-31 18:19:50 +00:00
}
2017-03-05 23:29:02 +00:00
}
2017-02-27 23:36:12 +00:00
}
}