mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'v0.1.0' of https://github.com/Pax1601/DCSOlympus into v0.1.0
This commit is contained in:
commit
6d57327ff7
11
client/.vscode/launch.json
vendored
11
client/.vscode/launch.json
vendored
@ -4,6 +4,17 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach to Chrome",
|
||||
"port": 9222,
|
||||
"urlFilter": "http://localhost:3000/*",
|
||||
"request": "attach",
|
||||
"type": "chrome",
|
||||
"webRoot": "${workspaceFolder}/public/",
|
||||
"sourceMapPathOverrides": {
|
||||
"src/*": "${workspaceFolder}/src/*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
|
||||
@ -155,6 +155,14 @@ dl.data-grid dd.br-info[data-bearing][data-distance][data-distance-units]::after
|
||||
color: var( --accent-light-blue );
|
||||
}
|
||||
|
||||
#unit-info-panel {
|
||||
bottom: 20px;
|
||||
font-size:12px;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
width: fit-content;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#connection-status-panel {
|
||||
bottom: 20px;
|
||||
|
||||
@ -533,34 +533,34 @@ nav.ol-panel> :last-child {
|
||||
|
||||
|
||||
|
||||
#unit-info-panel {
|
||||
#unit-selection {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#unit-info-panel #unit-identification {
|
||||
#unit-selection #unit-identification {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-bottom: 11px;
|
||||
}
|
||||
|
||||
#unit-info-panel #unit-identification [data-object|="unit"] {
|
||||
#unit-selection #unit-identification [data-object|="unit"] {
|
||||
height: 28px;
|
||||
margin-right: 6px;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
#unit-info-panel #unit-identification [data-object|="unit"] .unit-marker {
|
||||
#unit-selection #unit-identification [data-object|="unit"] .unit-marker {
|
||||
background-size: 28px 28px;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
#unit-info-panel #unit-identification [data-object|="unit"] .unit-short-label {
|
||||
#unit-selection #unit-identification [data-object|="unit"] .unit-short-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#unit-info-panel #unit-identification #unit-name {
|
||||
#unit-selection #unit-identification #unit-name {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
|
||||
@ -167,9 +167,7 @@
|
||||
|
||||
|
||||
/*** Context menu ***/
|
||||
|
||||
--spawn-aircraft-url: url( "/themes/olympus/images/spawn_aircraft.svg" );
|
||||
--spawn-ground-url: url( "/themes/olympus/images/spawn_ground.svg" );
|
||||
--spawn-smoke-url: url( "/themes/olympus/images/spawn_smoke.svg" );
|
||||
|
||||
}
|
||||
21
client/src/@types/unit.d.ts
vendored
21
client/src/@types/unit.d.ts
vendored
@ -1,3 +1,16 @@
|
||||
interface UpdateData {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
interface BaseData {
|
||||
AI: boolean;
|
||||
name: string;
|
||||
unitName: string;
|
||||
groupName: string;
|
||||
alive: boolean;
|
||||
category: string;
|
||||
}
|
||||
|
||||
interface FlightData {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
@ -36,13 +49,7 @@ interface OptionsData {
|
||||
}
|
||||
|
||||
interface UnitData {
|
||||
AI: boolean;
|
||||
name: string;
|
||||
unitName: string;
|
||||
groupName: string;
|
||||
alive: boolean;
|
||||
category: string;
|
||||
|
||||
baseData: BaseData;
|
||||
flightData: FlightData;
|
||||
missionData: MissionData;
|
||||
formationData: FormationData;
|
||||
|
||||
@ -51,7 +51,7 @@ function setup() {
|
||||
mouseInfoPanel = new MouseInfoPanel("mouse-info-panel");
|
||||
//logPanel = new LogPanel("log-panel");
|
||||
|
||||
missionHandler = new MissionHandler();
|
||||
missionHandler = new MissionHandler();
|
||||
|
||||
/* AIC */
|
||||
let aicFeatureSwitch = featureSwitches.getSwitch( "aic" );
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { getUnitsManager } from "..";
|
||||
import { Slider } from "../controls/slider";
|
||||
import { Aircraft, AirUnit, GroundUnit, Helicopter, NavyUnit, Unit } from "../units/unit";
|
||||
import { Unit } from "../units/unit";
|
||||
import { Panel } from "./panel";
|
||||
|
||||
const ROEs: string[] = ["Free", "Designated free", "Designated", "Return", "Hold"];
|
||||
@ -62,13 +62,13 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
|
||||
update(units: Unit[]) {
|
||||
if (this.getElement() != null)
|
||||
if (this.getElement() != null && units.length > 0)
|
||||
{
|
||||
this.#showFlightControlSliders(units);
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit) =>
|
||||
{
|
||||
var button = document.createElement("button");
|
||||
button.innerText = unit.getData().unitName;
|
||||
button.innerText = unit.getBaseData().unitName;
|
||||
button.addEventListener("click", () => getUnitsManager().selectUnit(unit.ID, true));
|
||||
return (button);
|
||||
}));
|
||||
|
||||
@ -40,9 +40,9 @@ export class UnitInfoPanel extends Panel {
|
||||
#onUnitUpdate(unit: Unit) {
|
||||
if (this.getElement() != null && this.getVisible()) {
|
||||
/* Set the unit info */
|
||||
this.#unitName.innerText = unit.getData().unitName;
|
||||
this.#groupName.innerText = unit.getData().groupName;
|
||||
this.#name.innerText = unit.getData().name;
|
||||
this.#unitName.innerText = unit.getBaseData().unitName;
|
||||
this.#groupName.innerText = unit.getBaseData().groupName;
|
||||
this.#name.innerText = unit.getBaseData().name;
|
||||
this.#heading.innerText = String(Math.floor(rad2deg(unit.getFlightData().heading)) + " °");
|
||||
this.#altitude.innerText = String(Math.floor(unit.getFlightData().altitude / 0.3048) + " ft");
|
||||
this.#groundSpeed.innerText = String(Math.floor(unit.getFlightData().speed * 1.94384) + " kts");
|
||||
|
||||
@ -3,20 +3,21 @@ import { setConnected } from '..';
|
||||
import { SpawnOptions } from '../controls/contextmenu';
|
||||
|
||||
/* Edit here to change server address */
|
||||
const REST_ADDRESS = "http://localhost:3000/demo";
|
||||
const REST_ADDRESS = "http://localhost:30000/olympus";
|
||||
const UNITS_URI = "units";
|
||||
const REFRESH_URI = "refresh";
|
||||
const UPDATE_URI = "update";
|
||||
const LOGS_URI = "logs";
|
||||
const AIRBASES_URI = "airbases";
|
||||
const BULLSEYE_URI = "bullseyes";
|
||||
|
||||
var lastUpdateTime = 0;
|
||||
|
||||
export function GET(callback: CallableFunction, uri: string){
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open("GET", `${REST_ADDRESS}/${uri}`, true);
|
||||
xmlHttp.onload = function (e) {
|
||||
var data = JSON.parse(xmlHttp.responseText);
|
||||
callback(data);
|
||||
lastUpdateTime = parseInt(data.time);
|
||||
setConnected(true);
|
||||
};
|
||||
xmlHttp.onerror = function () {
|
||||
@ -49,7 +50,7 @@ export function getLogs(callback: CallableFunction) {
|
||||
}
|
||||
|
||||
export function getUnits(callback: CallableFunction, refresh: boolean = false) {
|
||||
GET(callback, `${UNITS_URI}/${refresh? REFRESH_URI: UPDATE_URI}`);
|
||||
GET(callback, `${UNITS_URI}?time=${refresh? 0: lastUpdateTime}`);
|
||||
}
|
||||
|
||||
export function addDestination(ID: number, path: any) {
|
||||
|
||||
@ -14,7 +14,48 @@ var pathIcon = new Icon({
|
||||
export class Unit extends Marker {
|
||||
ID: number;
|
||||
|
||||
#data: UnitData;
|
||||
#data: UnitData = {
|
||||
baseData: {
|
||||
AI: false,
|
||||
name: "",
|
||||
unitName: "",
|
||||
groupName: "",
|
||||
alive: true,
|
||||
category: "",
|
||||
},
|
||||
flightData: {
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
altitude: 0,
|
||||
heading: 0,
|
||||
speed: 0,
|
||||
},
|
||||
missionData: {
|
||||
fuel: 0,
|
||||
flags: {},
|
||||
ammo: {},
|
||||
targets: {},
|
||||
hasTask: false,
|
||||
coalition: "",
|
||||
},
|
||||
formationData: {
|
||||
formation: "",
|
||||
isLeader: false,
|
||||
isWingman: false,
|
||||
leaderID: 0,
|
||||
wingmenIDs: [],
|
||||
},
|
||||
taskData: {
|
||||
currentTask: "",
|
||||
activePath: {},
|
||||
targetSpeed: 0,
|
||||
targetAltitude: 0,
|
||||
},
|
||||
optionsData: {
|
||||
ROE: "",
|
||||
reactionToThreat: "",
|
||||
}
|
||||
};
|
||||
|
||||
#selectable: boolean;
|
||||
#selected: boolean = false;
|
||||
@ -37,14 +78,13 @@ export class Unit extends Marker {
|
||||
if (type === "NavyUnit") return NavyUnit;
|
||||
}
|
||||
|
||||
constructor(ID: number, data: UnitData, html: string) {
|
||||
constructor(ID: number, data: UpdateData, html: string) {
|
||||
super(new LatLng(0, 0), { riseOnHover: true });
|
||||
|
||||
this.ID = ID;
|
||||
|
||||
this.#selectable = true;
|
||||
this.#data = data;
|
||||
|
||||
|
||||
this.on('click', (e) => this.#onClick(e));
|
||||
this.on('dblclick', (e) => this.#onDoubleClick(e));
|
||||
this.on('contextmenu', (e) => this.#onContextMenu(e));
|
||||
@ -59,37 +99,69 @@ export class Unit extends Marker {
|
||||
this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 });
|
||||
this.#pathPolyline.addTo(getMap());
|
||||
this.#targetsPolylines = [];
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
|
||||
setData(data: UnitData) {
|
||||
setData(data: UpdateData) {
|
||||
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
|
||||
var updateMarker = false;
|
||||
if (this.getFlightData().latitude != data.flightData.latitude ||
|
||||
this.getFlightData().longitude != data.flightData.longitude ||
|
||||
this.getData().alive != data.alive || this.#forceUpdate || !getMap().hasLayer(this))
|
||||
this.getBaseData().alive != data.baseData.alive || this.#forceUpdate || !getMap().hasLayer(this))
|
||||
updateMarker = true;
|
||||
|
||||
|
||||
if (data.baseData != undefined)
|
||||
{
|
||||
for (let key in this.#data.baseData)
|
||||
if (key in data.baseData)
|
||||
//@ts-ignore
|
||||
this.#data.baseData[key] = data.baseData[key];
|
||||
}
|
||||
|
||||
this.#data.AI = data.AI;
|
||||
this.#data.name = data.name;
|
||||
this.#data.unitName = data.unitName;
|
||||
this.#data.groupName = data.groupName;
|
||||
this.#data.alive = data.alive;
|
||||
this.#data.category = data.category;
|
||||
|
||||
if (data.flightData != undefined)
|
||||
this.#data.flightData = data.flightData;
|
||||
if (data.missionData != undefined)
|
||||
this.#data.missionData = data.missionData;
|
||||
if (data.formationData != undefined)
|
||||
this.#data.formationData = data.formationData;
|
||||
if (data.taskData != undefined)
|
||||
this.#data.taskData = data.taskData;
|
||||
if (data.optionsData != undefined)
|
||||
this.#data.optionsData = data.optionsData;
|
||||
{
|
||||
for (let key in this.#data.flightData)
|
||||
if (key in data.flightData)
|
||||
//@ts-ignore
|
||||
this.#data.flightData[key] = data.flightData[key];
|
||||
}
|
||||
|
||||
if (data.missionData != undefined)
|
||||
{
|
||||
for (let key in this.#data.missionData)
|
||||
if (key in data.missionData)
|
||||
//@ts-ignore
|
||||
this.#data.missionData[key] = data.missionData[key];
|
||||
}
|
||||
|
||||
if (data.formationData != undefined)
|
||||
{
|
||||
for (let key in this.#data.formationData)
|
||||
if (key in data.formationData)
|
||||
//@ts-ignore
|
||||
this.#data.formationData[key] = data.formationData[key];
|
||||
}
|
||||
|
||||
if (data.taskData != undefined)
|
||||
{
|
||||
for (let key in this.#data.taskData)
|
||||
if (key in data.taskData)
|
||||
//@ts-ignore
|
||||
this.#data.taskData[key] = data.taskData[key];
|
||||
}
|
||||
|
||||
if (data.optionsData != undefined)
|
||||
{
|
||||
for (let key in this.#data.optionsData)
|
||||
if (key in data.optionsData)
|
||||
//@ts-ignore
|
||||
this.#data.optionsData[key] = data.optionsData[key];
|
||||
}
|
||||
|
||||
/* Dead units can't be selected */
|
||||
this.setSelected(this.getSelected() && this.getData().alive)
|
||||
this.setSelected(this.getSelected() && this.getBaseData().alive)
|
||||
|
||||
if (updateMarker)
|
||||
this.#updateMarker();
|
||||
@ -107,6 +179,10 @@ export class Unit extends Marker {
|
||||
return this.#data;
|
||||
}
|
||||
|
||||
getBaseData() {
|
||||
return this.getData().baseData;
|
||||
}
|
||||
|
||||
getFlightData() {
|
||||
return this.getData().flightData;
|
||||
}
|
||||
@ -129,7 +205,7 @@ export class Unit extends Marker {
|
||||
|
||||
setSelected(selected: boolean) {
|
||||
/* Only alive units can be selected. Some units are not selectable (weapons) */
|
||||
if ((this.getData().alive || !selected) && this.#selectable && this.#selected != selected) {
|
||||
if ((this.getBaseData().alive || !selected) && this.#selectable && this.#selected != selected) {
|
||||
this.#selected = selected;
|
||||
this.getElement()?.querySelector( `[data-object|="unit"]` )?.toggleAttribute( "data-is-selected" );
|
||||
if (selected)
|
||||
@ -288,9 +364,7 @@ export class Unit extends Marker {
|
||||
this.setLatLng(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude));
|
||||
var element = this.getElement();
|
||||
if (element != null) {
|
||||
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${this.getFlightData().speed / 5}px; transform:rotate(${rad2deg(this.getFlightData().heading)}deg);`);
|
||||
element.querySelector(".unit")?.setAttribute("data-fuel-level", "20");
|
||||
element.querySelector(".unit")?.toggleAttribute("data-has-fox-1", true );
|
||||
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.getFlightData().speed / 5}px; transform:rotate(${rad2deg(this.getFlightData().heading)}deg);`);
|
||||
|
||||
var unitHeadingDiv = element.querySelector(".unit-heading");
|
||||
if (unitHeadingDiv != null)
|
||||
@ -390,10 +464,10 @@ export class Aircraft extends AirUnit {
|
||||
<div class="unit-status"></div>
|
||||
<div class="unit-vvi"></div>
|
||||
<div class="unit-hotgroup">
|
||||
<div class="unit-hotgroup-id">4</div>
|
||||
<div class="unit-hotgroup-id"></div>
|
||||
</div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label">${aircraftDatabase.getShortLabelByName(data.name)}</div>
|
||||
<div class="unit-short-label">${aircraftDatabase.getShortLabelByName(data.baseData.name)}</div>
|
||||
<div class="unit-fuel">
|
||||
<div class="unit-fuel-level" style="width:100%;"></div>
|
||||
</div>
|
||||
@ -404,7 +478,7 @@ export class Aircraft extends AirUnit {
|
||||
<div class="unit-ammo-other"></div>
|
||||
</div>
|
||||
<div class="unit-summary">
|
||||
<div class="unit-callsign">${data.unitName}</div>
|
||||
<div class="unit-callsign">${data.baseData.unitName}</div>
|
||||
<div class="unit-heading"></div>
|
||||
<div class="unit-altitude"></div>
|
||||
</div>
|
||||
@ -421,7 +495,7 @@ export class Helicopter extends AirUnit {
|
||||
|
||||
export class GroundUnit extends Unit {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
var role = groundUnitsDatabase.getByName(data.name)?.loadouts[0].roles[0];
|
||||
var role = groundUnitsDatabase.getByName(data.baseData.name)?.loadouts[0].roles[0];
|
||||
var roleType = (role === "SAM") ? "sam" : "mi";
|
||||
|
||||
super(ID, data, `
|
||||
|
||||
@ -33,7 +33,7 @@ export class UnitsManager {
|
||||
|
||||
addUnit(ID: number, data: UnitData) {
|
||||
/* The name of the unit category is exactly the same as the constructor name */
|
||||
var constructor = Unit.getConstructor(data.category);
|
||||
var constructor = Unit.getConstructor(data.baseData.category);
|
||||
if (constructor != undefined) {
|
||||
this.#units[ID] = new constructor(ID, data);
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
<%- include('contextmenu.ejs') %>
|
||||
<%- include('unitcontrolpanel.ejs') %>
|
||||
<%- include('unitinfopanel.ejs') %>
|
||||
<%- include('mouseinfopanel.ejs') %>
|
||||
<%- include('navbar.ejs') %>
|
||||
<%- include('connectionstatuspanel.ejs') %>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div id="unit-control-panel" class="ol-panel ol-panel-padding-lg">
|
||||
|
||||
<div id="unit-info-panel">
|
||||
<div id="unit-selection">
|
||||
|
||||
<div id="unit-identification">
|
||||
<div data-object="unit-air-aircraft">
|
||||
@ -13,36 +13,18 @@
|
||||
<!-- <button id="edit-unit-name" data-on-click="editUnitName"></button> -->
|
||||
</div>
|
||||
|
||||
<div class="ol-group">
|
||||
<div id="name" class="pill highlight-primary">Name</div>
|
||||
<div id="group-name" class="pill highlight-primary">Group</div>
|
||||
<div id="task" class="pill highlight-primary">Task</div>
|
||||
</div>
|
||||
|
||||
<div id="selected-units-container" class="ol-scroll">
|
||||
<!-- This is where all the unit selection buttons will be shown-->
|
||||
</div>
|
||||
|
||||
<div id="flight-data">
|
||||
|
||||
<h4 id="loadout-label">Flight data</h4>
|
||||
|
||||
<dl class="data-grid">
|
||||
<dt>Heading</dt>
|
||||
<dd id="heading">123°</dd>
|
||||
<dt>Speed</dt>
|
||||
<dd id="ground-speed">323kts</dd>
|
||||
<dt>Altitude</dt>
|
||||
<dd id="altitude">27,414ft</dd>
|
||||
</dl>
|
||||
|
||||
<h4>Flight controls</h4>
|
||||
<div class="slider-container flight-control-slider" id="airspeed-slider">
|
||||
<dl class="data-grid">
|
||||
<dt>Speed</dt>
|
||||
<dd class="flight-control-value" id="value">451kts</dd>
|
||||
</dl>
|
||||
<input type="range" min="1" max="600" value="451" class="slider">
|
||||
<input type="range" min="1" max="100" value="0" class="slider">
|
||||
</div>
|
||||
|
||||
<div class="slider-container flight-control-slider" id="altitude-slider">
|
||||
@ -50,19 +32,10 @@
|
||||
<dt>Altitude</dt>
|
||||
<dd class="flight-control-value" id="value">21,594ft</dd>
|
||||
</dl>
|
||||
<input type="range" min="1" max="50000" value="21594" class="slider">
|
||||
<input type="range" min="1" max="100" value="0" class="slider">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="loadout-data" class="panel-section">
|
||||
<h4 id="loadout-label">Loadout<span id="loadout-fuel-level" data-fuel-level="69"></span></h4>
|
||||
<div id="loadout-container" class="ol-group">
|
||||
<div class="pill loadout-item" data-qty="2" data-item="AIM-120B"></div>
|
||||
<div class="pill loadout-item" data-qty="2" data-item="AIM-9P"></div>
|
||||
<div class="pill loadout-item" data-qty="100" data-item="AIM-120B"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <h3>Formation</h3> -->
|
||||
|
||||
28
client/views/unitinfopanel.ejs
Normal file
28
client/views/unitinfopanel.ejs
Normal file
@ -0,0 +1,28 @@
|
||||
<div id="unit-info-panel" class="ol-panel" >
|
||||
<div class="ol-panel-board">
|
||||
<div id="general" class="panel-section">
|
||||
<h1 id="unit-name">Olympus 1-1</h1>
|
||||
<div id="name" class="pill highlight-primary">Name</div>
|
||||
<div id="group-name" class="pill highlight-primary">Group</div>
|
||||
<div id="task" class="pill highlight-primary">Task</div>
|
||||
</div>
|
||||
<div id="flight-data" class="panel-section">
|
||||
<dl class="data-grid">
|
||||
<dt>Heading</dt>
|
||||
<dd id="heading">123°</dd>
|
||||
<dt>Speed</dt>
|
||||
<dd id="ground-speed">323kts</dd>
|
||||
<dt>Altitude</dt>
|
||||
<dd id="altitude">27,414ft</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div id="loadout-data" class="panel-section">
|
||||
<h4 id="loadout-label">Loadout<span id="loadout-fuel-level" data-fuel-level="69"></span></h4>
|
||||
<div id="loadout-container" class="ol-group">
|
||||
<div class="pill loadout-item" data-qty="2" data-item="AIM-120B"></div>
|
||||
<div class="pill loadout-item" data-qty="2" data-item="AIM-9P"></div>
|
||||
<div class="pill loadout-item" data-qty="100" data-item="AIM-120B"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
25187
scripts/unitPayloads.lua
25187
scripts/unitPayloads.lua
File diff suppressed because it is too large
Load Diff
@ -33,13 +33,13 @@ public:
|
||||
int getID() { return ID; }
|
||||
void updateExportData(json::value json);
|
||||
void updateMissionData(json::value json);
|
||||
json::value getData(int time);
|
||||
json::value getData(long long time);
|
||||
|
||||
/********** Base data **********/
|
||||
void setAI(bool newAI) { AI = newAI; addMeasure(L"AI", json::value(newAI)); }
|
||||
void setName(wstring newName) { name = newName; addMeasure(L"name", json::value(newName));}
|
||||
void setUnitName(wstring newUnitName) { name = newUnitName; addMeasure(L"unitName", json::value(newUnitName));}
|
||||
void setGroupName(wstring newGroupName) { name = newGroupName; addMeasure(L"groupName", json::value(newGroupName));}
|
||||
void setUnitName(wstring newUnitName) { unitName = newUnitName; addMeasure(L"unitName", json::value(newUnitName));}
|
||||
void setGroupName(wstring newGroupName) { groupName = newGroupName; addMeasure(L"groupName", json::value(newGroupName));}
|
||||
void setAlive(bool newAlive) { alive = newAlive; addMeasure(L"alive", json::value(newAlive));}
|
||||
void setType(json::value newType) { type = newType; addMeasure(L"type", newType);}
|
||||
void setCountry(int newCountry) { country = newCountry; addMeasure(L"country", json::value(newCountry));}
|
||||
@ -68,20 +68,21 @@ public:
|
||||
void setAmmo(json::value newAmmo) { ammo = newAmmo; addMeasure(L"ammo", json::value(newAmmo));}
|
||||
void setTargets(json::value newTargets) {targets = newTargets; addMeasure(L"targets", json::value(newTargets));}
|
||||
void setHasTask(bool newHasTask) { hasTask = newHasTask; addMeasure(L"hasTask", json::value(newHasTask));}
|
||||
void setCoalitionID(int newCoalitionID) { coalitionID = newCoalitionID; addMeasure(L"coalition", json::value(newCoalitionID)); } // TODO fix
|
||||
void setCoalitionID(int newCoalitionID);
|
||||
void setFlags(json::value newFlags) { flags = newFlags; addMeasure(L"flags", json::value(newFlags));}
|
||||
double getFuel() { return fuel; }
|
||||
json::value getAmmo() { return ammo; }
|
||||
json::value getTargets() { return targets; }
|
||||
bool getHasTask() { return hasTask; }
|
||||
int getCoalitionID() { return coalitionID; }
|
||||
wstring getCoalition() { return coalition; }
|
||||
int getCoalitionID();
|
||||
json::value getFlags() { return flags; }
|
||||
|
||||
/********** Formation data **********/
|
||||
void setIsLeader(bool newIsLeader);
|
||||
void setIsWingman(bool newIsWingman);
|
||||
void setLeader(Unit *newLeader) { leader = newLeader; addMeasure(L"leader", json::value("")); } // TODO fix
|
||||
void setWingmen(vector<Unit*> newWingmen) { wingmen = newWingmen; addMeasure(L"wingmen", json::value("")); } // TODO fix
|
||||
void setLeader(Unit* newLeader);
|
||||
void setWingmen(vector<Unit*> newWingmen);
|
||||
void setFormation(wstring newFormation) { formation = newFormation; addMeasure(L"formation", json::value(formation));}
|
||||
void setFormationOffset(Offset formationOffset);
|
||||
bool getIsLeader() { return isLeader; }
|
||||
@ -145,7 +146,7 @@ protected:
|
||||
json::value ammo = json::value::null();
|
||||
json::value targets = json::value::null();
|
||||
bool hasTask = false;
|
||||
int coalitionID = NULL; // TODO: save coalition directly
|
||||
wstring coalition = L"";
|
||||
json::value flags = json::value::null();
|
||||
|
||||
/********** Formation data **********/
|
||||
|
||||
@ -4,16 +4,16 @@
|
||||
class Measure
|
||||
{
|
||||
public:
|
||||
Measure(json::value value, int time): value(value), time(time) {};
|
||||
Measure(json::value value, long long time): value(value), time(time) {};
|
||||
|
||||
void setValue(json::value newValue) { value = newValue; }
|
||||
void setTime(int newTime) { time = newTime; }
|
||||
void setTime(long long newTime) { time = newTime; }
|
||||
json::value getValue() { return value; }
|
||||
int getTime() { return time; }
|
||||
long long getTime() { return time; }
|
||||
|
||||
private:
|
||||
json::value value;
|
||||
int time;
|
||||
long long time;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ public:
|
||||
Unit* getUnit(int ID);
|
||||
void updateExportData(lua_State* L);
|
||||
void updateMissionData(json::value missionData);
|
||||
void getData(json::value& answer, int time);
|
||||
void getData(json::value& answer, long long time);
|
||||
void deleteUnit(int ID);
|
||||
|
||||
private:
|
||||
|
||||
@ -48,7 +48,7 @@ void Unit::updateExportData(json::value json)
|
||||
{
|
||||
double dist = 0;
|
||||
Geodesic::WGS84().Inverse(latitude, longitude, oldPosition.lat, oldPosition.lng, dist);
|
||||
speed = speed * 0.95 + (dist / UPDATE_TIME_INTERVAL) * 0.05;
|
||||
setSpeed(getSpeed() * 0.95 + (dist / UPDATE_TIME_INTERVAL) * 0.05);
|
||||
}
|
||||
oldPosition = Coords(latitude, longitude, altitude);
|
||||
|
||||
@ -77,11 +77,10 @@ void Unit::updateExportData(json::value json)
|
||||
|
||||
/* All units which contain the name "Olympus" are automatically under AI control */
|
||||
/* TODO: I don't really like using this method */
|
||||
if (unitName.find(L"Olympus") != wstring::npos)
|
||||
setAI(true);
|
||||
setAI(getUnitName().find(L"Olympus") != wstring::npos);
|
||||
|
||||
/* If the unit is alive and it is not a human, run the AI Loop that performs the requested commands and instructions (moving, attacking, etc) */
|
||||
if (AI && alive && flags[L"Human"].as_bool() == false)
|
||||
if (getAI() && getAlive() && getFlags()[L"Human"].as_bool() == false)
|
||||
AIloop();
|
||||
}
|
||||
|
||||
@ -96,83 +95,8 @@ void Unit::updateMissionData(json::value json)
|
||||
if (json.has_boolean_field(L"hasTask"))
|
||||
setHasTask(json[L"hasTask"].as_bool());
|
||||
}
|
||||
//
|
||||
//json::value Unit::getRefreshData()
|
||||
//{
|
||||
// auto json = json::value::object();
|
||||
//
|
||||
// /********** Base data **********/
|
||||
// json[L"baseData"] = json::value::object();
|
||||
// json[L"baseData"][L"AI"] = AI;
|
||||
// json[L"baseData"][L"name"] = json::value::string(name);
|
||||
// json[L"baseData"][L"unitName"] = json::value::string(unitName);
|
||||
// json[L"baseData"][L"groupName"] = json::value::string(groupName);
|
||||
// json[L"baseData"][L"alive"] = alive;
|
||||
// json[L"baseData"][L"category"] = json::value::string(getCategory());
|
||||
//
|
||||
// /********** Flight data **********/
|
||||
// json[L"flightData"] = json::value::object();
|
||||
// json[L"flightData"][L"latitude"] = latitude;
|
||||
// json[L"flightData"][L"longitude"] = longitude;
|
||||
// json[L"flightData"][L"altitude"] = altitude;
|
||||
// json[L"flightData"][L"speed"] = speed;
|
||||
// json[L"flightData"][L"heading"] = heading;
|
||||
//
|
||||
// /********** Mission data **********/
|
||||
// json[L"missionData"] = json::value::object();
|
||||
// json[L"missionData"][L"fuel"] = fuel;
|
||||
// json[L"missionData"][L"ammo"] = ammo;
|
||||
// json[L"missionData"][L"targets"] = targets;
|
||||
// json[L"missionData"][L"hasTask"] = hasTask;
|
||||
// if (coalitionID == 0)
|
||||
// json[L"missionData"][L"coalition"] = json::value::string(L"neutral");
|
||||
// else if (coalitionID == 1)
|
||||
// json[L"missionData"][L"coalition"] = json::value::string(L"red");
|
||||
// else
|
||||
// json[L"missionData"][L"coalition"] = json::value::string(L"blue");
|
||||
// json[L"missionData"][L"flags"] = flags;
|
||||
//
|
||||
// /********** Formation data **********/
|
||||
// json[L"formationData"] = json::value::object();
|
||||
// json[L"formationData"][L"isLeader"] = isLeader;
|
||||
// json[L"formationData"][L"isWingman"] = isWingman;
|
||||
// json[L"formationData"][L"formation"] = json::value::string(formation);
|
||||
// int i = 0;
|
||||
// for (auto itr = wingmen.begin(); itr != wingmen.end(); itr++)
|
||||
// json[L"formationData"][L"wingmenIDs"][i++] = (*itr)->getID();
|
||||
//
|
||||
// if (leader != nullptr)
|
||||
// json[L"formationData"][L"leaderID"] = leader->getID();
|
||||
//
|
||||
// /********** Task data **********/
|
||||
// json[L"taskData"] = json::value::object();
|
||||
// json[L"taskData"][L"currentTask"] = json::value::string(getCurrentTask());
|
||||
// json[L"taskData"][L"targetSpeed"] = getTargetSpeed();
|
||||
// json[L"taskData"][L"targetAltitude"] = getTargetAltitude();
|
||||
// /* Send the active path as a json object */
|
||||
// auto path = json::value::object();
|
||||
// if (activePath.size() > 0) {
|
||||
// int count = 1;
|
||||
// for (auto& destination : activePath)
|
||||
// {
|
||||
// auto json = json::value::object();
|
||||
// json[L"lat"] = destination.lat;
|
||||
// json[L"lng"] = destination.lng;
|
||||
// json[L"alt"] = destination.alt;
|
||||
// path[to_wstring(count++)] = json;
|
||||
// }
|
||||
// }
|
||||
// json[L"taskData"][L"activePath"] = path;
|
||||
//
|
||||
// /********** Options data **********/
|
||||
// json[L"optionsData"] = json::value::object();
|
||||
// json[L"optionsData"][L"ROE"] = json::value::string(ROE);
|
||||
// json[L"optionsData"][L"reactionToThreat"] = json::value::string(reactionToThreat);
|
||||
// return json;
|
||||
//}
|
||||
|
||||
|
||||
json::value Unit::getData(int time)
|
||||
json::value Unit::getData(long long time)
|
||||
{
|
||||
auto json = json::value::object();
|
||||
|
||||
@ -227,17 +151,66 @@ json::value Unit::getData(int time)
|
||||
return json;
|
||||
}
|
||||
|
||||
void Unit::setActivePath(list<Coords> path)
|
||||
void Unit::setActivePath(list<Coords> newPath)
|
||||
{
|
||||
if (state != State::WINGMAN && state != State::FOLLOW)
|
||||
{
|
||||
activePath = path;
|
||||
activePath = newPath;
|
||||
resetActiveDestination();
|
||||
}
|
||||
|
||||
addMeasure(L"activePath", json::value("")); // TODO fix
|
||||
auto path = json::value::object();
|
||||
if (activePath.size() > 0) {
|
||||
int count = 1;
|
||||
for (auto& destination : activePath)
|
||||
{
|
||||
auto json = json::value::object();
|
||||
json[L"lat"] = destination.lat;
|
||||
json[L"lng"] = destination.lng;
|
||||
json[L"alt"] = destination.alt;
|
||||
path[to_wstring(count++)] = json;
|
||||
}
|
||||
}
|
||||
addMeasure(L"activePath", path);
|
||||
}
|
||||
|
||||
void Unit::setCoalitionID(int newCoalitionID)
|
||||
{
|
||||
if (newCoalitionID == 0)
|
||||
coalition = L"neutral";
|
||||
else if (newCoalitionID == 1)
|
||||
coalition = L"red";
|
||||
else
|
||||
coalition = L"blue";
|
||||
addMeasure(L"coalition", json::value(coalition));
|
||||
}
|
||||
|
||||
int Unit::getCoalitionID()
|
||||
{
|
||||
if (coalition == L"neutral")
|
||||
return 0;
|
||||
else if (coalition == L"red")
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
void Unit::setLeader(Unit* newLeader)
|
||||
{
|
||||
leader = newLeader;
|
||||
if (leader != nullptr)
|
||||
addMeasure(L"leaderID", json::value(leader->getID()));
|
||||
}
|
||||
|
||||
void Unit::setWingmen(vector<Unit*> newWingmen) {
|
||||
wingmen = newWingmen;
|
||||
auto wingmenIDs = json::value::object();
|
||||
int i = 0;
|
||||
for (auto itr = wingmen.begin(); itr != wingmen.end(); itr++)
|
||||
wingmenIDs[i++] = (*itr)->getID();
|
||||
addMeasure(L"wingmen", wingmenIDs);
|
||||
}
|
||||
|
||||
wstring Unit::getTargetName()
|
||||
{
|
||||
if (isTargetAlive())
|
||||
|
||||
@ -16,6 +16,7 @@ extern UnitsManager* unitsManager;
|
||||
Aircraft::Aircraft(json::value json, int ID) : AirUnit(json, ID)
|
||||
{
|
||||
log("New Aircraft created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
|
||||
void Aircraft::changeSpeed(wstring change)
|
||||
@ -58,11 +59,13 @@ void Aircraft::changeAltitude(wstring change)
|
||||
}
|
||||
|
||||
void Aircraft::setTargetSpeed(double newTargetSpeed) {
|
||||
setTargetSpeed(newTargetSpeed);
|
||||
targetSpeed = newTargetSpeed;
|
||||
addMeasure(L"targetSpeed", json::value(targetSpeed));
|
||||
goToDestination();
|
||||
}
|
||||
|
||||
void Aircraft::setTargetAltitude(double newTargetAltitude) {
|
||||
setTargetAltitude(newTargetAltitude);
|
||||
targetAltitude = newTargetAltitude;
|
||||
addMeasure(L"targetAltitude", json::value(targetAltitude));
|
||||
goToDestination();
|
||||
}
|
||||
@ -203,6 +203,7 @@ void AirUnit::taskWingmen()
|
||||
|
||||
void AirUnit::AIloop()
|
||||
{
|
||||
log(L"AILoop");
|
||||
/* State machine */
|
||||
switch (state) {
|
||||
case State::IDLE: {
|
||||
|
||||
@ -94,7 +94,7 @@ extern "C" DllExport int coreMissionData(lua_State * L)
|
||||
unitsManager->updateMissionData(missionData[L"unitsData"]);
|
||||
if (missionData.has_object_field(L"airbases"))
|
||||
airbasesData = missionData[L"airbases"];
|
||||
if (missionData.has_object_field(L"bullseye"))
|
||||
if (missionData.has_object_field(L"bullseyes"))
|
||||
bullseyesData = missionData[L"bullseyes"];
|
||||
|
||||
return(0);
|
||||
|
||||
@ -16,6 +16,7 @@ extern UnitsManager* unitsManager;
|
||||
GroundUnit::GroundUnit(json::value json, int ID) : Unit(json, ID)
|
||||
{
|
||||
log("New Ground Unit created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
|
||||
void GroundUnit::AIloop()
|
||||
|
||||
@ -16,6 +16,7 @@ extern UnitsManager* unitsManager;
|
||||
Helicopter::Helicopter(json::value json, int ID) : AirUnit(json, ID)
|
||||
{
|
||||
log("New Helicopter created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
|
||||
void Helicopter::changeSpeed(wstring change)
|
||||
@ -60,10 +61,12 @@ void Helicopter::changeAltitude(wstring change)
|
||||
|
||||
void Helicopter::setTargetSpeed(double newTargetSpeed) {
|
||||
targetSpeed = newTargetSpeed;
|
||||
addMeasure(L"targetSpeed", json::value(targetSpeed));
|
||||
goToDestination();
|
||||
}
|
||||
|
||||
void Helicopter::setTargetAltitude(double newTargetAltitude) {
|
||||
targetAltitude = newTargetAltitude;
|
||||
addMeasure(L"targetAltitude", json::value(targetAltitude));
|
||||
goToDestination();
|
||||
}
|
||||
@ -16,6 +16,7 @@ extern UnitsManager* unitsManager;
|
||||
NavyUnit::NavyUnit(json::value json, int ID) : Unit(json, ID)
|
||||
{
|
||||
log("New Navy Unit created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
|
||||
void NavyUnit::AIloop()
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <chrono>
|
||||
using namespace std::chrono;
|
||||
|
||||
extern UnitsManager* unitsManager;
|
||||
extern Scheduler* scheduler;
|
||||
extern json::value airbasesData;
|
||||
@ -78,9 +81,18 @@ void Server::handle_get(http_request request)
|
||||
{
|
||||
if (path[0] == UNITS_URI)
|
||||
{
|
||||
wstring fragment = uri::decode(request.relative_uri().fragment());
|
||||
log(fragment);
|
||||
//unitsManager->getData(answer);
|
||||
map<utility::string_t, utility::string_t> query = request.relative_uri().split_query(request.relative_uri().query());
|
||||
long long time = 0;
|
||||
if (query.find(L"time") != query.end())
|
||||
{
|
||||
try {
|
||||
time = stoll((*(query.find(L"time"))).second);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
time = 0;
|
||||
}
|
||||
}
|
||||
unitsManager->getData(answer, time);
|
||||
}
|
||||
else if (path[0] == LOGS_URI)
|
||||
{
|
||||
@ -93,6 +105,8 @@ void Server::handle_get(http_request request)
|
||||
else if (path[0] == BULLSEYE_URI)
|
||||
answer[L"bullseyes"] = bullseyesData;
|
||||
|
||||
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
||||
answer[L"time"] = json::value::string(to_wstring(ms.count()));
|
||||
answer[L"sessionHash"] = json::value::string(to_wstring(sessionHash));
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ void UnitsManager::updateMissionData(json::value missionData)
|
||||
}
|
||||
}
|
||||
|
||||
void UnitsManager::getData(json::value& answer, int time)
|
||||
void UnitsManager::getData(json::value& answer, long long time)
|
||||
{
|
||||
auto unitsJson = json::value::object();
|
||||
for (auto const& p : units)
|
||||
|
||||
@ -22,10 +22,12 @@ Weapon::Weapon(json::value json, int ID) : Unit(json, ID)
|
||||
Missile::Missile(json::value json, int ID) : Weapon(json, ID)
|
||||
{
|
||||
log("New Missile created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
|
||||
/* Bomb */
|
||||
Bomb::Bomb(json::value json, int ID) : Weapon(json, ID)
|
||||
{
|
||||
log("New Bomb created with ID: " + to_string(ID));
|
||||
addMeasure(L"category", json::value(getCategory()));
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user