2020-05-14 17:12:58 +00:00
|
|
|
import { Math_max } from "../../../core/builtins";
|
2020-05-14 11:29:42 +00:00
|
|
|
import { ClickDetector } from "../../../core/click_detector";
|
2020-05-14 17:12:58 +00:00
|
|
|
import { formatBigNumber, makeDiv } from "../../../core/utils";
|
2020-05-14 11:29:42 +00:00
|
|
|
import { ShapeDefinition } from "../../shape_definition";
|
2020-05-14 17:12:58 +00:00
|
|
|
import { BaseHUDPart } from "../base_hud_part";
|
2020-05-28 13:36:38 +00:00
|
|
|
import { blueprintShape } from "../../upgrades";
|
|
|
|
import { enumHubGoalRewards } from "../../tutorial_goals";
|
2020-05-14 11:29:42 +00:00
|
|
|
|
|
|
|
export class HUDPinnedShapes extends BaseHUDPart {
|
|
|
|
createElements(parent) {
|
|
|
|
this.element = makeDiv(parent, "ingame_HUD_PinnedShapes", []);
|
|
|
|
}
|
|
|
|
|
2020-05-28 12:53:11 +00:00
|
|
|
serialize() {
|
|
|
|
return {
|
|
|
|
shapes: this.pinnedShapes,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
deserialize(data) {
|
|
|
|
if (!data || !data.shapes || !Array.isArray(data.shapes)) {
|
|
|
|
return "Invalid pinned shapes data";
|
|
|
|
}
|
|
|
|
this.pinnedShapes = data.shapes;
|
|
|
|
}
|
|
|
|
|
2020-05-14 11:29:42 +00:00
|
|
|
initialize() {
|
2020-05-14 11:40:38 +00:00
|
|
|
/** @type {Array<{ key: string, goal: number }>} */
|
2020-05-14 11:29:42 +00:00
|
|
|
this.pinnedShapes = [];
|
|
|
|
|
|
|
|
/** @type {Array<{key: string, amountLabel: HTMLElement, lastRenderedValue: number, element: HTMLElement, detector?: ClickDetector}>} */
|
|
|
|
this.handles = [];
|
|
|
|
this.rerenderFull();
|
|
|
|
|
|
|
|
this.root.signals.storyGoalCompleted.add(this.rerenderFull, this);
|
2020-05-16 07:51:55 +00:00
|
|
|
this.root.signals.postLoadHook.add(this.rerenderFull, this);
|
2020-05-14 11:29:42 +00:00
|
|
|
this.root.hud.signals.shapePinRequested.add(this.pinNewShape, this);
|
2020-06-06 00:33:35 +00:00
|
|
|
this.root.hud.signals.shapeUnpinRequested.add(this.unpinShape, this);
|
2020-05-14 11:29:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether a given shape is pinned
|
|
|
|
* @param {string} key
|
|
|
|
*/
|
|
|
|
isShapePinned(key) {
|
|
|
|
if (!this.pinnedShapes) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-05-14 11:40:38 +00:00
|
|
|
if (key === this.root.hubGoals.currentGoal.definition.getHash()) {
|
|
|
|
return true;
|
|
|
|
}
|
2020-05-28 13:36:38 +00:00
|
|
|
if (key === blueprintShape) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-05-14 11:40:38 +00:00
|
|
|
for (let i = 0; i < this.pinnedShapes.length; ++i) {
|
|
|
|
if (this.pinnedShapes[i].key === key) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2020-05-14 11:29:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rerenderFull() {
|
2020-05-14 11:40:38 +00:00
|
|
|
const currentGoal = this.root.hubGoals.currentGoal;
|
|
|
|
const currentKey = currentGoal.definition.getHash();
|
2020-05-14 11:29:42 +00:00
|
|
|
|
|
|
|
// First, remove old ones
|
|
|
|
for (let i = 0; i < this.handles.length; ++i) {
|
|
|
|
this.handles[i].element.remove();
|
|
|
|
const detector = this.handles[i].detector;
|
|
|
|
if (detector) {
|
|
|
|
detector.cleanup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.handles = [];
|
|
|
|
|
2020-05-30 17:42:03 +00:00
|
|
|
this.internalPinShape(currentKey, currentGoal.required, false, "goal");
|
2020-05-14 11:29:42 +00:00
|
|
|
|
2020-05-28 13:36:38 +00:00
|
|
|
if (this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
2020-05-30 17:42:03 +00:00
|
|
|
this.internalPinShape(blueprintShape, null, false, "blueprint");
|
2020-05-28 13:36:38 +00:00
|
|
|
}
|
|
|
|
|
2020-05-14 11:29:42 +00:00
|
|
|
for (let i = 0; i < this.pinnedShapes.length; ++i) {
|
2020-05-14 11:40:38 +00:00
|
|
|
const key = this.pinnedShapes[i].key;
|
|
|
|
if (key !== currentKey) {
|
|
|
|
this.internalPinShape(key, this.pinnedShapes[i].goal);
|
2020-05-14 11:29:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pins a shape
|
|
|
|
* @param {string} key
|
2020-05-14 11:40:38 +00:00
|
|
|
* @param {number} goal
|
2020-05-14 11:29:42 +00:00
|
|
|
* @param {boolean} canUnpin
|
2020-05-30 17:42:03 +00:00
|
|
|
* @param {string=} className
|
2020-05-14 11:29:42 +00:00
|
|
|
*/
|
2020-05-30 17:42:03 +00:00
|
|
|
internalPinShape(key, goal, canUnpin = true, className = null) {
|
2020-05-14 11:29:42 +00:00
|
|
|
const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey(key);
|
|
|
|
|
|
|
|
const element = makeDiv(this.element, null, ["shape"]);
|
|
|
|
const canvas = definition.generateAsCanvas(120);
|
|
|
|
element.appendChild(canvas);
|
|
|
|
|
2020-05-30 17:42:03 +00:00
|
|
|
if (className) {
|
|
|
|
element.classList.add(className);
|
|
|
|
}
|
|
|
|
|
2020-05-14 11:29:42 +00:00
|
|
|
let detector = null;
|
|
|
|
if (canUnpin) {
|
|
|
|
element.classList.add("unpinable");
|
|
|
|
detector = new ClickDetector(element, {
|
|
|
|
consumeEvents: true,
|
|
|
|
preventDefault: true,
|
|
|
|
});
|
|
|
|
detector.click.add(() => this.unpinShape(key));
|
|
|
|
} else {
|
|
|
|
element.classList.add("marked");
|
|
|
|
}
|
|
|
|
|
2020-05-14 11:40:38 +00:00
|
|
|
const amountLabel = makeDiv(element, null, ["amountLabel"], "");
|
2020-05-28 16:07:57 +00:00
|
|
|
|
|
|
|
if (goal) {
|
|
|
|
makeDiv(element, null, ["goalLabel"], "/" + formatBigNumber(goal));
|
|
|
|
}
|
2020-05-14 11:29:42 +00:00
|
|
|
|
|
|
|
this.handles.push({
|
|
|
|
key,
|
|
|
|
element,
|
|
|
|
amountLabel,
|
|
|
|
lastRenderedValue: -1,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
update() {
|
|
|
|
for (let i = 0; i < this.handles.length; ++i) {
|
|
|
|
const handle = this.handles[i];
|
|
|
|
|
|
|
|
const currentValue = this.root.hubGoals.getShapesStoredByKey(handle.key);
|
|
|
|
if (currentValue !== handle.lastRenderedValue) {
|
|
|
|
handle.lastRenderedValue = currentValue;
|
|
|
|
handle.amountLabel.innerText = formatBigNumber(currentValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-14 11:40:38 +00:00
|
|
|
/**
|
|
|
|
* Unpins a shape
|
|
|
|
* @param {string} key
|
|
|
|
*/
|
2020-05-14 11:29:42 +00:00
|
|
|
unpinShape(key) {
|
2020-05-14 11:40:38 +00:00
|
|
|
for (let i = 0; i < this.pinnedShapes.length; ++i) {
|
|
|
|
if (this.pinnedShapes[i].key === key) {
|
|
|
|
this.pinnedShapes.splice(i, 1);
|
|
|
|
this.rerenderFull();
|
|
|
|
return;
|
|
|
|
}
|
2020-05-14 11:29:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {ShapeDefinition} definition
|
2020-05-14 11:40:38 +00:00
|
|
|
* @param {number} goal
|
2020-05-14 11:29:42 +00:00
|
|
|
*/
|
2020-05-14 11:40:38 +00:00
|
|
|
pinNewShape(definition, goal) {
|
2020-05-14 11:29:42 +00:00
|
|
|
const key = definition.getHash();
|
|
|
|
if (key === this.root.hubGoals.currentGoal.definition.getHash()) {
|
|
|
|
// Can not pin current goal
|
|
|
|
return;
|
|
|
|
}
|
2020-05-28 13:36:38 +00:00
|
|
|
|
|
|
|
if (key === blueprintShape) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-14 11:40:38 +00:00
|
|
|
for (let i = 0; i < this.pinnedShapes.length; ++i) {
|
|
|
|
if (this.pinnedShapes[i].key === key) {
|
|
|
|
// Already pinned
|
|
|
|
this.pinnedShapes[i].goal = Math_max(this.pinnedShapes[i].goal, goal);
|
|
|
|
return;
|
|
|
|
}
|
2020-05-14 11:29:42 +00:00
|
|
|
}
|
2020-05-14 11:40:38 +00:00
|
|
|
|
|
|
|
this.pinnedShapes.push({ key, goal });
|
|
|
|
this.rerenderFull();
|
2020-05-14 11:29:42 +00:00
|
|
|
}
|
|
|
|
}
|