Readded demo data

This commit is contained in:
dpassoni 2023-03-13 10:59:09 +01:00
parent 1120c8c237
commit 1e502c4869
5 changed files with 439 additions and 175 deletions

View File

@ -27,8 +27,7 @@ const DemoDataGenerator = require('./demo.js');
var demoDataGenerator = new DemoDataGenerator(10);
app.get('/demo/units/refresh', (req, res) => demoDataGenerator.unitsRefresh(req, res));
app.get('/demo/units/update', (req, res) => demoDataGenerator.unitsUpdate(req, res));
app.get('/demo/units', (req, res) => demoDataGenerator.units(req, res));
app.get('/demo/logs', (req, res) => demoDataGenerator.logs(req, res));
app.get('/demo/bullseyes', (req, res) => demoDataGenerator.bullseyes(req, res));
app.get('/demo/airbases', (req, res) => demoDataGenerator.airbases(req, res));

View File

@ -1,21 +1,23 @@
const DEMO_UNIT_DATA = {
["1"]:{
AI: true,
name: "F-5E",
unitName: "Olympus 1-1",
groupName: "Group 1",
alive: true,
category: "Aircraft",
baseData: {
AI: true,
name: "F-5E",
unitName: "Olympus 1-1",
groupName: "Group 1",
alive: true,
category: "Aircraft",
},
flightData: {
latitude: 37.2,
latitude: 37.20,
longitude: -115.8,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
fuel: 50,
flags: {human: false},
ammo: [],
targets: [],
@ -42,12 +44,14 @@ const DEMO_UNIT_DATA = {
}
},
["2"]:{
AI: true,
name: "F-5E",
unitName: "Olympus 1-2",
groupName: "Group 1",
alive: true,
category: "Aircraft",
baseData: {
AI: true,
name: "F-5E",
unitName: "Olympus 1-2",
groupName: "Group 1",
alive: true,
category: "Aircraft",
},
flightData: {
latitude: 37.2,
longitude: -115.75,
@ -83,12 +87,14 @@ const DEMO_UNIT_DATA = {
}
},
["3"]:{
AI: true,
name: "2S6 Tunguska",
unitName: "Olympus 1-3",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
baseData: {
AI: true,
name: "2S6 Tunguska",
unitName: "Olympus 1-3",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
},
flightData: {
latitude: 37.175,
longitude: -115.8,
@ -124,12 +130,14 @@ const DEMO_UNIT_DATA = {
}
},
["4"]:{
AI: true,
name: "2S6 Tunguska",
unitName: "Olympus 1-4",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
baseData: {
AI: true,
name: "2S6 Tunguska",
unitName: "Olympus 1-4",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
},
flightData: {
latitude: 37.175,
longitude: -115.75,
@ -165,12 +173,14 @@ const DEMO_UNIT_DATA = {
}
},
["5"]:{
AI: true,
name: "M-60",
unitName: "Olympus 1-3",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
baseData: {
AI: true,
name: "M-60",
unitName: "Olympus 1-3",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
},
flightData: {
latitude: 37.15,
longitude: -115.8,
@ -206,12 +216,14 @@ const DEMO_UNIT_DATA = {
}
},
["6"]:{
AI: true,
name: "M-60",
unitName: "Olympus 1-4",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
baseData: {
AI: true,
name: "M-60",
unitName: "Olympus 1-4",
groupName: "Group 1",
alive: true,
category: "GroundUnit",
},
flightData: {
latitude: 37.15,
longitude: -115.75,
@ -245,7 +257,265 @@ const DEMO_UNIT_DATA = {
ROE: "None",
reactionToThreat: "None",
}
}
},
["7"]:{
baseData: {
AI: true,
name: "CVN-75",
unitName: "Olympus 1-7",
groupName: "Group 1",
alive: true,
category: "NavyUnit",
},
flightData: {
latitude: 37.125,
longitude: -115.8,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
flags: {human: false},
ammo: [],
targets: [],
hasTask: true,
coalition: "blue"
},
formationData: {
formation: "Echelon",
isLeader: false,
isWingman: false,
leaderID: null,
wingmen: [],
wingmenIDs: []
},
taskData: {
currentTask: "Example task",
activePath: undefined,
targetSpeed: 400,
targetAltitude: 3000
},
optionsData: {
ROE: "None",
reactionToThreat: "None",
}
},
["8"]:{
baseData: {
AI: true,
name: "CVN-75",
unitName: "Olympus 1-8",
groupName: "Group 1",
alive: true,
category: "NavyUnit",
},
flightData: {
latitude: 37.125,
longitude: -115.75,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
flags: {human: false},
ammo: [],
targets: [],
hasTask: true,
coalition: "red"
},
formationData: {
formation: "Echelon",
isLeader: false,
isWingman: false,
leaderID: null,
wingmen: [],
wingmenIDs: []
},
taskData: {
currentTask: "Example task",
activePath: undefined,
targetSpeed: 400,
targetAltitude: 3000
},
optionsData: {
ROE: "None",
reactionToThreat: "None",
}
},
["9"]:{
baseData: {
AI: true,
name: "CVN-75",
unitName: "Olympus 1-9",
groupName: "Group 1",
alive: false,
category: "Aircraft",
},
flightData: {
latitude: 37.10,
longitude: -115.75,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
flags: {human: false},
ammo: [],
targets: [],
hasTask: true,
coalition: "red"
},
formationData: {
formation: "Echelon",
isLeader: false,
isWingman: false,
leaderID: null,
wingmen: [],
wingmenIDs: []
},
taskData: {
currentTask: "Example task",
activePath: undefined,
targetSpeed: 400,
targetAltitude: 3000
},
optionsData: {
ROE: "None",
reactionToThreat: "None",
}
},
["10"]:{
baseData: {
AI: true,
name: "CVN-75",
unitName: "Olympus 1-10",
groupName: "Group 1",
alive: false,
category: "Aircraft",
},
flightData: {
latitude: 37.10,
longitude: -115.8,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
flags: {human: false},
ammo: [],
targets: [],
hasTask: true,
coalition: "blue"
},
formationData: {
formation: "Echelon",
isLeader: false,
isWingman: false,
leaderID: null,
wingmen: [],
wingmenIDs: []
},
taskData: {
currentTask: "Example task",
activePath: undefined,
targetSpeed: 400,
targetAltitude: 3000
},
optionsData: {
ROE: "None",
reactionToThreat: "None",
}
},
["11"]:{
baseData: {
AI: true,
name: "CVN-75",
unitName: "Olympus 1-11",
groupName: "Group 1",
alive: false,
category: "Missile",
},
flightData: {
latitude: 37.075,
longitude: -115.8,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
flags: {human: false},
ammo: [],
targets: [],
hasTask: true,
coalition: "blue"
},
formationData: {
formation: "Echelon",
isLeader: false,
isWingman: false,
leaderID: null,
wingmen: [],
wingmenIDs: []
},
taskData: {
currentTask: "Example task",
activePath: undefined,
targetSpeed: 400,
targetAltitude: 3000
},
optionsData: {
ROE: "None",
reactionToThreat: "None",
}
},
["12"]:{
baseData: {
AI: true,
name: "CVN-75",
unitName: "Olympus 1-12",
groupName: "Group 1",
alive: false,
category: "Missile",
},
flightData: {
latitude: 37.075,
longitude: -115.75,
altitude: 2000,
heading: 0.5,
speed: 300
},
missionData: {
fuel: 0.5,
flags: {human: false},
ammo: [],
targets: [],
hasTask: true,
coalition: "red"
},
formationData: {
formation: "Echelon",
isLeader: false,
isWingman: false,
leaderID: null,
wingmen: [],
wingmenIDs: []
},
taskData: {
currentTask: "Example task",
activePath: undefined,
targetSpeed: 400,
targetAltitude: 3000
},
optionsData: {
ROE: "None",
reactionToThreat: "None",
}
}
}
class DemoDataGenerator {
@ -253,18 +523,8 @@ class DemoDataGenerator {
{
this.demoUnits = this.generateRandomUnitsDemoData(unitsNumber);
}
unitsRefresh(req, res) {
var ret = this.demoUnits;
res.send(JSON.stringify(ret));
}
unitsUpdate(req, res){
//Object.keys(this.demoUnits.units).forEach((ID) => {
// this.demoUnits.units[ID].flightData.heading += 0.05;
// this.demoUnits.units[ID].flightData.latitude += 0.001 * Math.cos(this.demoUnits.units[ID].flightData.heading);
// this.demoUnits.units[ID].flightData.longitude += 0.001 * Math.sin(this.demoUnits.units[ID].flightData.heading);
//});
units(req, res){
var ret = this.demoUnits;
res.send(JSON.stringify(ret));
};

View File

@ -10,14 +10,14 @@ import { AIC } from "./aic/aic";
import { ATC } from "./atc/ATC";
import { FeatureSwitches } from "./FeatureSwitches";
import { LogPanel } from "./panels/logpanel";
import { getAirbases, getBulllseye as getBulllseyes, getUnits } from "./server/server";
import { getAirbases, getBulllseye as getBulllseyes, getUnits, toggleDemoEnabled } from "./server/server";
var map: Map;
var contextMenu: ContextMenu;
var unitsManager: UnitsManager;
var missionHandler: MissionHandler;
var aic: AIC;
var atc: ATC;
@ -38,144 +38,48 @@ function setup() {
featureSwitches = new FeatureSwitches();
/* Initialize */
/* Initialize base functionalitites*/
map = new Map('map-container');
unitsManager = new UnitsManager();
missionHandler = new MissionHandler();
/* Context menus */
contextMenu = new ContextMenu("contextmenu");
/* Panels */
unitInfoPanel = new UnitInfoPanel("unit-info-panel");
unitControlPanel = new UnitControlPanel("unit-control-panel");
connectionStatusPanel = new ConnectionStatusPanel("connection-status-panel");
mouseInfoPanel = new MouseInfoPanel("mouse-info-panel");
//logPanel = new LogPanel("log-panel");
missionHandler = new MissionHandler();
/* AIC */
let aicFeatureSwitch = featureSwitches.getSwitch( "aic" );
if ( aicFeatureSwitch?.isEnabled() ) {
let aicFeatureSwitch = featureSwitches.getSwitch("aic");
if (aicFeatureSwitch?.isEnabled()) {
aic = new AIC();
// TODO: add back buttons
}
/* Generic clicks */
document.addEventListener( "click", ( ev ) => {
if ( ev instanceof PointerEvent && ev.target instanceof HTMLElement ) {
const target = ev.target;
if ( target.classList.contains( "olympus-dialog-close" ) ) {
target.closest( "div.olympus-dialog" )?.classList.add( "hide" );
}
const triggerElement = target.closest( "[data-on-click]" );
if ( triggerElement instanceof HTMLElement ) {
const eventName:string = triggerElement.dataset.onClick || "";
let params = JSON.parse( triggerElement.dataset.onClickParams || "{}" );
params._element = triggerElement;
if ( eventName ) {
document.dispatchEvent( new CustomEvent( eventName, {
detail: params
} ) );
}
}
}
});
/* Keyup events */
document.addEventListener( "keyup", ev => {
switch( ev.code ) {
case "KeyL":
document.body.toggleAttribute( "data-hide-labels" );
break;
}
});
/*
const unitName = document.getElementById( "unit-name" );
if ( unitName instanceof HTMLInputElement ) {
unitName.addEventListener( "change", ev => {
unitName.setAttribute( "disabled", "true" );
unitName.setAttribute( "readonly", "true" );
// Do something with this:
console.log( unitName.value );
});
document.addEventListener( "editUnitName", ev => {
unitName.removeAttribute( "disabled" );
unitName.removeAttribute( "readonly" );
unitName.focus();
});
}
//*/
document.addEventListener( "toggleCoalitionVisibility", ( ev:CustomEventInit ) => {
ev.detail._element.classList.toggle( "off" );
document.body.toggleAttribute( "data-hide-" + ev.detail.coalition );
});
document.addEventListener( "toggleUnitVisibility", ( ev:CustomEventInit ) => {
document.body.toggleAttribute( "data-hide-" + ev.detail.unitType );
});
/** Olympus UI ***/
document.querySelectorAll( ".ol-select" ).forEach( select => {
// Do open/close toggle
select.addEventListener( "click", ev => {
ev.preventDefault();
ev.stopPropagation();
select.classList.toggle( "is-open" );
});
// Autoclose on mouseleave
select.addEventListener( "mouseleave", ev => {
select.classList.remove( "is-open" );
});
});
/* ATC */
let atcFeatureSwitch = featureSwitches.getSwitch( "atc" );
if ( atcFeatureSwitch?.isEnabled() ) {
let atcFeatureSwitch = featureSwitches.getSwitch("atc");
if (atcFeatureSwitch?.isEnabled()) {
atc = new ATC();
// TODO: add back buttons
}
/* Setup event handlers */
setupEvents();
/* On the first connection, force request of full data */
getAirbases((data: AirbasesData) => getMissionData()?.update(data));
getBulllseyes((data: BullseyesData) => getMissionData()?.update(data));
getUnits((data: UnitsData) => getUnitsManager()?.update(data), true /* Does a full refresh */);
/* Start periodically requesting updates */
startPeriodicUpdate();
}
function startPeriodicUpdate()
{
function startPeriodicUpdate() {
requestUpdate();
requestRefresh();
}
@ -201,10 +105,8 @@ function requestRefresh() {
setTimeout(() => requestRefresh(), 5000);
}
function checkSessionHash(newSessionHash: string)
{
if (sessionHash != null)
{
function checkSessionHash(newSessionHash: string) {
if (sessionHash != null) {
if (newSessionHash != sessionHash)
location.reload();
}
@ -212,6 +114,88 @@ function checkSessionHash(newSessionHash: string)
sessionHash = newSessionHash;
}
function setupEvents() {
/* Generic clicks */
document.addEventListener("click", (ev) => {
if (ev instanceof PointerEvent && ev.target instanceof HTMLElement) {
const target = ev.target;
if (target.classList.contains("olympus-dialog-close")) {
target.closest("div.olympus-dialog")?.classList.add("hide");
}
const triggerElement = target.closest("[data-on-click]");
if (triggerElement instanceof HTMLElement) {
const eventName: string = triggerElement.dataset.onClick || "";
let params = JSON.parse(triggerElement.dataset.onClickParams || "{}");
params._element = triggerElement;
if (eventName) {
document.dispatchEvent(new CustomEvent(eventName, {
detail: params
}));
}
}
}
});
/* Keyup events */
document.addEventListener("keyup", ev => {
switch (ev.code) {
case "KeyL":
document.body.toggleAttribute("data-hide-labels");
break;
case "KeyD":
toggleDemoEnabled();
}
});
/*
const unitName = document.getElementById( "unit-name" );
if ( unitName instanceof HTMLInputElement ) {
unitName.addEventListener( "change", ev => {
unitName.setAttribute( "disabled", "true" );
unitName.setAttribute( "readonly", "true" );
// Do something with this:
console.log( unitName.value );
});
document.addEventListener( "editUnitName", ev => {
unitName.removeAttribute( "disabled" );
unitName.removeAttribute( "readonly" );
unitName.focus();
});
}
//*/
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
ev.detail._element.classList.toggle("off");
document.body.toggleAttribute("data-hide-" + ev.detail.coalition);
});
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
document.body.toggleAttribute("data-hide-" + ev.detail.unitType);
});
/** Olympus UI ***/
document.querySelectorAll(".ol-select").forEach(select => {
// Do open/close toggle
select.addEventListener("click", ev => {
ev.preventDefault();
ev.stopPropagation();
select.classList.toggle("is-open");
});
// Autoclose on mouseleave
select.addEventListener("mouseleave", ev => {
select.classList.remove("is-open");
});
});
}
export function getMap() {
return map;
}
@ -250,7 +234,7 @@ export function getConnectionStatusPanel() {
export function setActiveCoalition(newActiveCoalition: string) {
activeCoalition = newActiveCoalition;
document.querySelectorAll('[data-active-coalition]').forEach((element: any) => {element.setAttribute("data-active-coalition", activeCoalition)});
document.querySelectorAll('[data-active-coalition]').forEach((element: any) => { element.setAttribute("data-active-coalition", activeCoalition) });
}
export function getActiveCoalition() {

View File

@ -4,16 +4,23 @@ import { SpawnOptions } from '../controls/contextmenu';
/* Edit here to change server address */
const REST_ADDRESS = "http://localhost:30000/olympus";
const DEMO_ADDRESS = "http://localhost:3000/demo";
const UNITS_URI = "units";
const LOGS_URI = "logs";
const AIRBASES_URI = "airbases";
const BULLSEYE_URI = "bullseyes";
var lastUpdateTime = 0;
var demoEnabled = false;
export function toggleDemoEnabled()
{
demoEnabled = !demoEnabled;
}
export function GET(callback: CallableFunction, uri: string){
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", `${REST_ADDRESS}/${uri}`, true);
xmlHttp.open("GET", `${demoEnabled? DEMO_ADDRESS: REST_ADDRESS}/${uri}`, true);
xmlHttp.onload = function (e) {
var data = JSON.parse(xmlHttp.responseText);
callback(data);
@ -29,7 +36,7 @@ export function GET(callback: CallableFunction, uri: string){
export function POST(request: object, callback: CallableFunction){
var xhr = new XMLHttpRequest();
xhr.open("PUT", REST_ADDRESS);
xhr.open("PUT", demoEnabled? DEMO_ADDRESS: REST_ADDRESS);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = () => {
callback();

View File

@ -370,6 +370,8 @@ export class Unit extends Marker {
element.querySelector(".unit-fuel-level")?.setAttribute("style", `width: ${this.getMissionData().fuel}%`);
element.querySelector(".unit")?.toggleAttribute("data-has-low-fuel", this.getMissionData().fuel < 20);
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.getBaseData().alive);
var unitHeadingDiv = element.querySelector(".unit-heading");
if (unitHeadingDiv != null)
unitHeadingDiv.innerHTML = String(Math.floor(rad2deg(this.getFlightData().heading)));
@ -518,7 +520,13 @@ export class GroundUnit extends Unit {
export class NavyUnit extends Unit {
constructor(ID: number, data: UnitData) {
super(ID, data, "");
super(ID, data, `
<div class="unit" data-object="unit-naval" data-coalition="${data.missionData.coalition}">
<div class="unit-selected-spotlight"></div>
<div class="unit-marker"></div>
<div class="unit-short-label">N</div>
</div>
`);
}
getHidden() {
@ -527,20 +535,26 @@ export class NavyUnit extends Unit {
}
export class Weapon extends Unit {
constructor(ID: number, data: UnitData) {
super(ID, data, "");
constructor(ID: number, data: UnitData, html: string) {
super(ID, data, html);
this.setSelectable(false);
}
}
export class Missile extends Weapon {
constructor(ID: number, data: UnitData) {
super(ID, data);
super(ID, data, `
<div class="unit" data-object="unit-weapon-missile" data-coalition="${data.missionData.coalition}">
<div class="unit-selected-spotlight"></div>
<div class="unit-marker"></div>
<div class="unit-short-label"></div>
</div>
`);
}
}
export class Bomb extends Weapon {
constructor(ID: number, data: UnitData) {
super(ID, data);
super(ID, data, "");
}
}