2017-10-08 21:26:33 +00:00
|
|
|
/// <reference path="UIComponent.ts" />
|
|
|
|
|
|
|
|
module TK.SpaceTac.UI {
|
|
|
|
export type UIConversationPiece = { interlocutor: Ship, message: string }
|
|
|
|
export type UIConversationCallback = (conversation: UIConversation, step: number) => boolean
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Style for a conversational message display
|
|
|
|
*/
|
|
|
|
export class UIConversationStyle {
|
|
|
|
// Center the message or not
|
|
|
|
center = false
|
|
|
|
|
|
|
|
// Padding between the content and the external border
|
|
|
|
padding = 10
|
|
|
|
|
|
|
|
// Background fill color
|
2018-05-02 22:47:03 +00:00
|
|
|
background = 0x1B3B4B
|
2017-10-08 21:26:33 +00:00
|
|
|
alpha = 0.9
|
|
|
|
|
|
|
|
// Border color and width
|
2018-05-02 22:47:03 +00:00
|
|
|
border = 0x3A6479
|
2017-10-08 21:26:33 +00:00
|
|
|
border_width = 2
|
|
|
|
|
2018-05-02 22:47:03 +00:00
|
|
|
// Text style
|
|
|
|
text: UITextStyleI = {
|
|
|
|
color: "#DBEFF9",
|
|
|
|
size: 20,
|
|
|
|
bold: true,
|
|
|
|
shadow: true
|
|
|
|
}
|
2017-10-08 21:26:33 +00:00
|
|
|
|
|
|
|
// Portrait or image to display (from atlases)
|
|
|
|
image = ""
|
|
|
|
image_size = 0
|
|
|
|
image_caption = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rectangle to display a message that may appear progressively, as in conversations
|
|
|
|
*/
|
|
|
|
export class UIConversationMessage extends UIComponent {
|
|
|
|
constructor(parent: BaseView | UIComponent, width: number, height: number, message: string, style = new UIConversationStyle()) {
|
|
|
|
super(parent, width, height);
|
|
|
|
|
|
|
|
this.drawBackground(style.background, style.border, style.border_width, style.alpha);
|
|
|
|
|
2018-05-02 22:47:03 +00:00
|
|
|
let builder = this.builder.styled(style.text);
|
|
|
|
if (!style.center) {
|
|
|
|
builder = builder.styled({ center: false, vcenter: false });
|
|
|
|
}
|
|
|
|
|
2017-10-08 21:26:33 +00:00
|
|
|
let offset = 0;
|
|
|
|
if (style.image_size && style.image) {
|
|
|
|
offset = style.image_size + style.padding;
|
|
|
|
width -= offset;
|
|
|
|
|
|
|
|
let ioffset = style.padding + Math.floor(style.image_size / 2);
|
2018-05-15 14:57:45 +00:00
|
|
|
builder.image(style.image, ioffset, ioffset, true);
|
2017-10-08 21:26:33 +00:00
|
|
|
|
|
|
|
if (style.image_caption) {
|
2018-05-02 22:47:03 +00:00
|
|
|
let text_size = Math.ceil(style.text.size ? style.text.size * 0.6 : 16);
|
|
|
|
builder.text(style.image_caption, ioffset, style.padding + style.image_size + text_size, {
|
2018-05-15 14:57:45 +00:00
|
|
|
size: text_size,
|
|
|
|
center: true
|
2018-05-02 22:47:03 +00:00
|
|
|
});
|
2017-10-08 21:26:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-02 22:47:03 +00:00
|
|
|
let text = builder.text(message, offset + (style.center ? width / 2 : style.padding), style.center ? height / 2 : style.padding, {
|
|
|
|
width: width - style.padding * 2
|
|
|
|
});
|
2017-10-08 21:26:33 +00:00
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
/*let i = 0;
|
2017-10-08 21:26:33 +00:00
|
|
|
let colorchar = () => {
|
|
|
|
text.clearColors();
|
|
|
|
if (i < message.length) {
|
|
|
|
text.addColor("transparent", i);
|
|
|
|
i++;
|
|
|
|
this.view.timer.schedule(10, colorchar);
|
|
|
|
}
|
|
|
|
}
|
2018-05-15 14:57:45 +00:00
|
|
|
colorchar();*/
|
2017-10-08 21:26:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display of an active conversation (sequence of messages)
|
|
|
|
*/
|
|
|
|
export class UIConversation extends UIComponent {
|
|
|
|
private step = -1
|
|
|
|
private on_step: UIConversationCallback
|
|
|
|
private ended = false
|
2018-05-15 14:57:45 +00:00
|
|
|
private on_end = new Phaser.Events.EventEmitter()
|
2017-10-08 21:26:33 +00:00
|
|
|
|
|
|
|
constructor(parent: BaseView, on_step: UIConversationCallback) {
|
|
|
|
super(parent, parent.getWidth(), parent.getHeight());
|
|
|
|
|
|
|
|
this.drawBackground(0x404450, undefined, undefined, 0.7, () => this.forward());
|
|
|
|
this.setVisible(false);
|
|
|
|
|
|
|
|
this.on_step = on_step;
|
|
|
|
|
|
|
|
this.forward();
|
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
|
|
|
if (!this.ended) {
|
|
|
|
this.ended = true;
|
2018-05-15 14:57:45 +00:00
|
|
|
this.on_end.emit("done");
|
2017-10-08 21:26:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
super.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Promise to wait for the end of conversation
|
|
|
|
*/
|
|
|
|
waitEnd(): Promise<void> {
|
|
|
|
if (this.ended) {
|
|
|
|
return Promise.resolve();
|
|
|
|
} else {
|
2018-05-15 14:57:45 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
this.on_end.on("done", resolve);
|
2017-10-08 21:26:33 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the currently displayed message
|
|
|
|
*/
|
|
|
|
setCurrentMessage(style: UIConversationStyle, content: string, width: number, height: number, relx: number, rely: number): void {
|
|
|
|
this.clearContent();
|
|
|
|
|
|
|
|
let message = new UIConversationMessage(this, width, height, content, style);
|
|
|
|
message.addButton(width - 60, height - 60, () => this.forward(), "common-arrow");
|
|
|
|
message.setPositionInsideParent(relx, rely);
|
|
|
|
|
|
|
|
this.setVisible(true, 700);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience to set the current message from a ship
|
|
|
|
*
|
|
|
|
* This will automatically set the style and position of the message
|
|
|
|
*/
|
|
|
|
setCurrentShipMessage(ship: Ship, content: string): void {
|
|
|
|
let style = new UIConversationStyle();
|
|
|
|
style.image = `ship-${ship.model.code}-portrait`;
|
2017-12-12 22:17:25 +00:00
|
|
|
style.image_caption = ship.getName(false);
|
2017-10-08 21:26:33 +00:00
|
|
|
style.image_size = 256;
|
|
|
|
|
2018-01-16 00:08:24 +00:00
|
|
|
let own = this.view.gameui.session.player.is(ship.fleet.player);
|
2017-10-08 21:26:33 +00:00
|
|
|
this.setCurrentMessage(style, content, 900, 300, own ? 0.1 : 0.9, own ? 0.2 : 0.8);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Go forward to the next message
|
|
|
|
*/
|
|
|
|
forward(): void {
|
|
|
|
this.step += 1;
|
|
|
|
if (!this.on_step(this, this.step)) {
|
|
|
|
this.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience to create a conversation from a list of pieces
|
|
|
|
*/
|
|
|
|
static newFromPieces(view: BaseView, pieces: UIConversationPiece[]): UIConversation {
|
|
|
|
let result = new UIConversation(view, (conversation, step) => {
|
|
|
|
if (step >= pieces.length) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
conversation.setCurrentShipMessage(pieces[step].interlocutor, pieces[step].message);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|