diff --git a/src/js/game/history_manager.js b/src/js/game/history_manager.js
index 8eef0768..f3c31758 100644
--- a/src/js/game/history_manager.js
+++ b/src/js/game/history_manager.js
@@ -4,12 +4,12 @@ import { KEYMAPPINGS } from "./key_action_mapper";
class LiFoQueue {
constructor(size = 20) {
- this.size = size;
+ this._size = size;
this.items = [];
}
enqueue(element) {
- if (this.size < this.items.length + 1) {
+ if (this._size < this.items.length + 1) {
this.items.shift();
}
this.items.push(element);
@@ -22,6 +22,10 @@ class LiFoQueue {
clear() {
this.items = [];
}
+
+ isEmpty() {
+ return !this.items.length;
+ }
}
const ActionType = {
@@ -32,7 +36,7 @@ const ActionType = {
export class HistoryManager {
constructor(root) {
this.root = root;
- this._entities = new LiFoQueue();
+ this._forUndo = new LiFoQueue();
this._forRedo = new LiFoQueue();
this.initializeBindings();
@@ -43,21 +47,29 @@ export class HistoryManager {
this.root.keyMapper.getBinding(KEYMAPPINGS.placement.redo).add(this._redo, this);
}
+ get canUndo() {
+ return !this._forUndo.isEmpty();
+ }
+
+ get canRedo() {
+ return !this._forRedo.isEmpty();
+ }
+
/**
* @param {Entity} entity
*/
addAction(entity) {
this._forRedo.clear();
- this._entities.enqueue({ type: ActionType.add, entity });
+ this._forUndo.enqueue({ type: ActionType.add, entity });
}
removeAction(entity) {
this._forRedo.clear();
- this._entities.enqueue({ type: ActionType.remove, entity });
+ this._forUndo.enqueue({ type: ActionType.remove, entity });
}
_undo() {
- const { type, entity } = this._entities.dequeue() || {};
+ const { type, entity } = this._forUndo.dequeue() || {};
if (!entity) {
return;
}
@@ -78,10 +90,10 @@ export class HistoryManager {
}
if (type === ActionType.remove && this.root.logic.checkCanPlaceEntity(entity)) {
this._placeEntity(entity);
- this._entities.enqueue({ type: ActionType.add, entity });
+ this._forUndo.enqueue({ type: ActionType.add, entity });
}
if (type === ActionType.add && this.root.logic.canDeleteBuilding(entity)) {
- this._entities.enqueue({ type: ActionType.remove, entity: entity.clone() });
+ this._forUndo.enqueue({ type: ActionType.remove, entity: entity.clone() });
this._removeEntity(entity);
}
}
diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js
index 65919d3c..b3713646 100644
--- a/src/js/game/hud/parts/keybinding_overlay.js
+++ b/src/js/game/hud/parts/keybinding_overlay.js
@@ -120,6 +120,14 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
return this.root.camera.getIsMapOverlayActive();
}
+ get undoActive() {
+ return !this.mapOverviewActive && !this.blueprintPlacementActive && this.root.historyMgr.canUndo;
+ }
+
+ get redoActive() {
+ return !this.mapOverviewActive && !this.blueprintPlacementActive && this.root.historyMgr.canRedo;
+ }
+
/**
* Initializes the element
* @param {HTMLElement} parent
@@ -185,6 +193,20 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
condition: () => !this.mapOverviewActive && !this.blueprintPlacementActive,
},
+ {
+ // Undo
+ label: T.ingame.keybindingsOverlay.undo,
+ keys: [k.placement.undo],
+ condition: () => this.undoActive,
+ },
+
+ {
+ // Redo
+ label: T.ingame.keybindingsOverlay.redo,
+ keys: [k.placement.redo],
+ condition: () => this.redoActive,
+ },
+
{
// Area select
label: T.ingame.keybindingsOverlay.selectBuildings,
@@ -297,10 +319,18 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
case ADDER_TOKEN:
html += `+`;
break;
- default:
- html += `${getStringForKeyCode(
- mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode
- )}
`;
+ default: {
+ const binding = mapper.getBinding(/** @type {KeyCode} */ (key));
+ if (binding.shift) {
+ html += `${getStringForKeyCode(16)}
`;
+ html += `+`;
+ }
+ if (binding.ctrl) {
+ html += `${getStringForKeyCode(17)}
`;
+ html += `+`;
+ }
+ html += `${getStringForKeyCode(binding.keyCode)}
`;
+ }
}
}
html += ``;