Added hotkeys

This commit is contained in:
Pax1601
2024-11-09 18:22:21 +01:00
parent c2b0849fb6
commit 95e18f6503
9 changed files with 372 additions and 384 deletions

View File

@@ -1,11 +1,12 @@
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
import { Unit } from "./unit";
import { LatLng } from "leaflet";
import { ContextActionType } from "../constants/constants";
import { ContextActionTarget, ContextActionType } from "../constants/constants";
export interface ContextActionOptions {
executeImmediately?: boolean;
type: ContextActionType;
hotkey?: string;
}
export type ContextActionCallback = (units: Unit[], targetUnit: Unit | null, targetPosition: LatLng | null, originalEvent?: MouseEvent) => void;
@@ -18,9 +19,9 @@ export class ContextAction {
#units: Unit[] = [];
#icon: IconDefinition;
#options: ContextActionOptions;
#target: "unit" | "position" | null = null;
#target: ContextActionTarget;
constructor(id: string, label: string, description: string, icon: IconDefinition, target: "unit" | "position" | null, callback: ContextActionCallback, options: ContextActionOptions) {
constructor(id: string, label: string, description: string, icon: IconDefinition, target: ContextActionTarget, callback: ContextActionCallback, options: ContextActionOptions) {
this.#id = id;
this.#label = label;
this.#description = description;
@@ -33,8 +34,8 @@ export class ContextAction {
};
}
addUnit(unit: Unit) {
this.#units.push(unit);
setUnits(units: Unit[]) {
this.#units = units;
}
getId() {

View File

@@ -1,30 +1,26 @@
import { ContextActionTarget } from "../constants/constants";
import { ContextAction, ContextActionCallback, ContextActionOptions } from "./contextaction";
import { Unit } from "./unit";
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
export class ContextActionSet {
#contextActions: { [key: string]: ContextAction } = {};
#defaultContextAction: ContextAction | null = null;
#units: { [key: string]: Unit[] } = {};
addContextAction(
unit: Unit,
id: string,
label: string,
description: string,
icon: IconDefinition,
target: "unit" | "position" | null,
callback: ContextActionCallback,
options?: ContextActionOptions
contextAction: ContextAction
) {
options = options || {};
if (!(id in this.#contextActions)) {
this.#contextActions[id] = new ContextAction(id, label, description, icon, target, callback, options);
this.#contextActions[contextAction.getId()] = contextAction;
if (!(contextAction.getId() in this.#units)) {
this.#units[contextAction.getId()] = []
this.#contextActions[contextAction.getId()].setUnits(this.#units[contextAction.getId()]);
}
this.#contextActions[id].addUnit(unit);
this.#units[contextAction.getId()].push(unit)
}
getContextActions(targetFilter?: string) {
getContextActions(targetFilter?: ContextActionTarget) {
if (targetFilter) {
var filteredContextActionSet = new ContextActionSet();
Object.keys(this.#contextActions).forEach((key) => {
@@ -36,17 +32,10 @@ export class ContextActionSet {
addDefaultContextAction(
unit: Unit,
id: string,
label: string,
description: string,
icon: IconDefinition,
target: "unit" | "position" | null,
callback: ContextActionCallback,
options?: ContextActionOptions
contextAction: ContextAction
) {
options = options || {};
if (this.#defaultContextAction === null) this.#defaultContextAction = new ContextAction(id, label, description, icon, target, callback, options);
this.#defaultContextAction.addUnit(unit);
if (this.#defaultContextAction === null) this.#defaultContextAction = contextAction;
//this.#defaultContextAction.addUnit(unit);
}
getDefaultContextAction() {

View File

@@ -39,6 +39,7 @@ import {
JTACSubState,
UnitControlSubState,
ContextActionType,
ContextActions,
} from "../constants/constants";
import { DataExtractor } from "../server/dataextractor";
import { Weapon } from "../weapon/weapon";
@@ -80,6 +81,7 @@ import {
UnitSelectedEvent,
UnitUpdatedEvent,
} from "../events";
import { ContextAction } from "./contextaction";
var pathIcon = new Icon({
iconUrl: "/vite/images/markers/marker-icon.png",
@@ -838,102 +840,13 @@ export abstract class Unit extends CustomMarker {
*
*/
appendContextActions(contextActionSet: ContextActionSet) {
contextActionSet.addContextAction(
this,
"stop",
"Stop unit",
"Stops the unit",
faHand,
null,
(units: Unit[], _1, _2) => {
getApp().getUnitsManager().stop(units);
},
{
executeImmediately: true,
type: ContextActionType.MOVE,
}
);
contextActionSet.addContextAction(this, ContextActions.STOP);
contextActionSet.addContextAction(this, ContextActions.MOVE);
contextActionSet.addContextAction(this, ContextActions.PATH);
contextActionSet.addContextAction(this, ContextActions.DELETE);
contextActionSet.addContextAction(this, ContextActions.EXPLODE);
contextActionSet.addContextAction(
this,
"move",
"Set destination",
"Click on the map to move the units there",
faLocationDot,
"position",
(units: Unit[], _, targetPosition, originalEvent) => {
if (!originalEvent?.ctrlKey) getApp().getUnitsManager().clearDestinations(units);
if (targetPosition)
getApp()
.getUnitsManager()
.addDestination(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.MOVE }
);
contextActionSet.addContextAction(
this,
"path",
"Create route",
"Click on the map to add a destination to the path",
faRoute,
"position",
(units: Unit[], _, targetPosition) => {
if (targetPosition)
getApp()
.getUnitsManager()
.addDestination(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.MOVE }
);
contextActionSet.addContextAction(
this,
"delete",
"Delete unit",
"Deletes the unit",
faTrash,
null,
(units: Unit[], _1, _2) => {
getApp().getUnitsManager().delete(false);
},
{
executeImmediately: true,
type: ContextActionType.DELETE,
}
);
contextActionSet.addContextAction(
this,
"explode",
"Explode unit",
"Explodes the unit",
faExplosion,
null,
(units: Unit[], _1, _2) => {
getApp().setState(OlympusState.UNIT_CONTROL, UnitControlSubState.UNIT_EXPLOSION_MENU);
UnitExplosionRequestEvent.dispatch(units);
},
{
executeImmediately: true,
type: ContextActionType.DELETE,
}
);
contextActionSet.addDefaultContextAction(
this,
"default",
"Set destination",
"",
faRoute,
null,
(units: Unit[], targetUnit, targetPosition, originalEvent) => {
if (targetPosition) {
if (!originalEvent?.ctrlKey) getApp().getUnitsManager().clearDestinations(units);
getApp().getUnitsManager().addDestination(targetPosition, false, 0, units);
}
}
);
contextActionSet.addDefaultContextAction(this, ContextActions.MOVE);
}
drawLines() {
@@ -1452,7 +1365,7 @@ export abstract class Unit extends CustomMarker {
#onLongPress(e: any) {
console.log(`Long press on ${this.getUnitName()}`);
if (e.originalEvent.button === 2) {
if (e.originalEvent.button === 2 && !getApp().getMap().getContextAction()) {
getApp().setState(OlympusState.UNIT_CONTROL, UnitControlSubState.UNIT_CONTEXT_MENU);
UnitContextMenuRequestEvent.dispatch(this);
}
@@ -1869,111 +1782,20 @@ export abstract class AirUnit extends Unit {
super.appendContextActions(contextActionSet);
/* Context actions to be executed immediately */
contextActionSet.addContextAction(
this,
"refuel",
"Refuel at tanker",
"Refuel units at the nearest AAR Tanker. If no tanker is available the unit will RTB",
olButtonsContextRefuel,
null,
(units: Unit[]) => {
getApp().getUnitsManager().refuel(units);
},
{ executeImmediately: true, type: ContextActionType.ADMIN }
);
contextActionSet.addContextAction(
this,
"center-map",
"Center map",
"Center the map on the unit and follow it",
faMapLocation,
null,
(units: Unit[]) => {
getApp().getMap().centerOnUnit(units[0]);
},
{ executeImmediately: true, type: ContextActionType.OTHER }
);
contextActionSet.addContextAction(this, ContextActions.REFUEL);
contextActionSet.addContextAction(this, ContextActions.CENTER_MAP);
/* Context actions that require a target unit */
contextActionSet.addContextAction(
this,
"attack",
"Attack unit",
"Click on a unit to attack it using A/A or A/G weapons",
olButtonsContextAttack,
"unit",
(units: Unit[], targetUnit: Unit | null, _) => {
if (targetUnit) getApp().getUnitsManager().attackUnit(targetUnit.ID, units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(
this,
"follow",
"Follow unit",
"Click on a unit to follow it in formation",
olButtonsContextFollow,
"unit",
(units: Unit[], targetUnit: Unit | null, _) => {
if (targetUnit) {
getApp().setState(OlympusState.UNIT_CONTROL, UnitControlSubState.FORMATION);
FormationCreationRequestEvent.dispatch(
targetUnit,
units.filter((unit) => unit !== targetUnit)
);
}
},
{ type: ContextActionType.ADMIN }
);
contextActionSet.addContextAction(this, ContextActions.ATTACK);
contextActionSet.addContextAction(this, ContextActions.FOLLOW);
if (this.canTargetPoint()) {
/* Context actions that require a target position */
contextActionSet.addContextAction(
this,
"bomb",
"Precision bomb location",
"Click on a point to execute a precision bombing attack",
faLocationCrosshairs,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition)
getApp()
.getUnitsManager()
.bombPoint(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(
this,
"carpet-bomb",
"Carpet bomb location",
"Click on a point to execute a carpet bombing attack",
faXmarksLines,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition)
getApp()
.getUnitsManager()
.carpetBomb(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(this, ContextActions.BOMB);
contextActionSet.addContextAction(this, ContextActions.CARPET_BOMB);
}
contextActionSet.addContextAction(
this,
"land",
"Land",
"Click on a point to land at the nearest airbase",
faPlaneArrival,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition) getApp().getUnitsManager().landAt(targetPosition, units);
},
{ type: ContextActionType.ADMIN }
);
contextActionSet.addContextAction(this, ContextActions.LAND);
}
}
@@ -2010,21 +1832,7 @@ export class Helicopter extends AirUnit {
appendContextActions(contextActionSet: ContextActionSet) {
super.appendContextActions(contextActionSet);
contextActionSet.addContextAction(
this,
"land-at-point",
"Land at location",
"Click on a point to land there",
olButtonsContextLandAtPoint,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition)
getApp()
.getUnitsManager()
.landAtPoint(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.ADMIN }
);
contextActionSet.addContextAction(this, ContextActions.LAND_AT_POINT);
}
getMarkerCategory() {
@@ -2062,77 +1870,16 @@ export class GroundUnit extends Unit {
super.appendContextActions(contextActionSet);
/* Context actions to be executed immediately */
contextActionSet.addContextAction(
this,
"group-ground",
"Group ground units",
"Create a group of ground units",
faPeopleGroup,
null,
(units: Unit[], _1, _2) => {
getApp().getUnitsManager().createGroup(units);
},
{ executeImmediately: true, type: ContextActionType.OTHER }
);
contextActionSet.addContextAction(
this,
"center-map",
"Center map",
"Center the map on the unit and follow it",
faMapLocation,
null,
(units: Unit[]) => {
getApp().getMap().centerOnUnit(units[0]);
},
{ executeImmediately: true, type: ContextActionType.OTHER }
);
contextActionSet.addContextAction(this, ContextActions.GROUP);
contextActionSet.addContextAction(this, ContextActions.CENTER_MAP);
/* Context actions that require a target unit */
contextActionSet.addContextAction(
this,
"attack",
"Attack unit",
"Click on a unit to attack it",
olButtonsContextAttack,
"unit",
(units: Unit[], targetUnit: Unit | null, _) => {
if (targetUnit) getApp().getUnitsManager().attackUnit(targetUnit.ID, units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(this, ContextActions.ATTACK);
/* Context actions that require a target position */
if (this.canTargetPoint()) {
contextActionSet.addContextAction(
this,
"fire-at-area",
"Fire at area",
"Click on a point to precisely fire at it (if possible)",
faLocationCrosshairs,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition)
getApp()
.getUnitsManager()
.fireAtArea(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(
this,
"simulate-fire-fight",
"Simulate fire fight",
"Simulate a fire fight by shooting randomly in a certain large area. WARNING: works correctly only on neutral units, blue or red units will aim",
olButtonsContextSimulateFireFight,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition)
getApp()
.getUnitsManager()
.simulateFireFight(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.ADMIN }
);
contextActionSet.addContextAction(this, ContextActions.FIRE_AT_AREA);
contextActionSet.addContextAction(this, ContextActions.SIMULATE_FIRE_FIGHT);
}
}
@@ -2192,61 +1939,14 @@ export class NavyUnit extends Unit {
super.appendContextActions(contextActionSet);
/* Context actions to be executed immediately */
contextActionSet.addContextAction(
this,
"group-navy",
"Group navy units",
"Create a group of navy units",
faQuestionCircle,
null,
(units: Unit[], _1, _2) => {
getApp().getUnitsManager().createGroup(units);
},
{ executeImmediately: true, type: ContextActionType.OTHER }
);
contextActionSet.addContextAction(
this,
"center-map",
"Center map",
"Center the map on the unit and follow it",
faMapLocation,
null,
(units: Unit[]) => {
getApp().getMap().centerOnUnit(units[0]);
},
{ executeImmediately: true, type: ContextActionType.OTHER }
);
contextActionSet.addContextAction(this, ContextActions.GROUP);
contextActionSet.addContextAction(this, ContextActions.CENTER_MAP);
/* Context actions that require a target unit */
contextActionSet.addContextAction(
this,
"attack",
"Attack unit",
"Click on a unit to attack it",
olButtonsContextAttack,
"unit",
(units: Unit[], targetUnit: Unit | null, _) => {
if (targetUnit) getApp().getUnitsManager().attackUnit(targetUnit.ID, units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(this, ContextActions.ATTACK);
/* Context actions that require a target position */
contextActionSet.addContextAction(
this,
"fire-at-area",
"Fire at area",
"Click on a point to precisely fire at it (if possible)",
faLocationCrosshairs,
"position",
(units: Unit[], _, targetPosition: LatLng | null) => {
if (targetPosition)
getApp()
.getUnitsManager()
.fireAtArea(targetPosition, getApp().getMap().getOptions().keepRelativePositions, getApp().getMap().getDestinationRotation(), units);
},
{ type: ContextActionType.ENGAGE }
);
contextActionSet.addContextAction(this, ContextActions.FIRE_AT_AREA);
}
getCategory() {