Merge branch '370-write-better-method-of-determining-if-a-command-has-been-completed' into 345-allow-for-copy-and-paste-in-rts-mode

This commit is contained in:
Pax1601 2023-09-04 17:31:58 +02:00
commit 3d076a605b
13 changed files with 180 additions and 108 deletions

View File

@ -112,6 +112,8 @@ class DemoDataGenerator {
app.get('/demo/bullseyes', (req, res) => this.bullseyes(req, res));
app.get('/demo/airbases', (req, res) => this.airbases(req, res));
app.get('/demo/mission', (req, res) => this.mission(req, res));
app.get('/demo/commands', (req, res) => this.command(req, res));
app.put('/demo', (req, res) => this.put(req, res));
app.use('/demo', basicAuth({
users: {
@ -457,7 +459,17 @@ class DemoDataGenerator {
}
res.send(JSON.stringify(ret));
}
command(req, res) {
var ret = {commandExecuted: Math.random() > 0.5};
res.send(JSON.stringify(ret));
}
put(req, res) {
var ret = {commandHash: Math.random().toString(36).slice(2, 19)}
res.send(JSON.stringify(ret));
}
}
module.exports = DemoDataGenerator;

View File

@ -44,4 +44,9 @@ interface LogData {
logs: {[key: string]: string},
sessionHash: string;
time: number;
}
interface ServerRequestOptions {
time?: number;
commandHash?: string;
}

View File

@ -1,5 +1,13 @@
import { LatLng, LatLngBounds } from "leaflet";
export const UNITS_URI = "units";
export const WEAPONS_URI = "weapons";
export const LOGS_URI = "logs";
export const AIRBASES_URI = "airbases";
export const BULLSEYE_URI = "bullseyes";
export const MISSION_URI = "mission";
export const COMMANDS_URI = "commands";
export const NONE = "None";
export const GAME_MASTER = "Game master";
export const BLUE_COMMANDER = "Blue commander";

View File

@ -412,10 +412,13 @@ export class AircraftSpawnMenu extends UnitSpawnMenu {
for (let i = 1; i < unitsCount + 1; i++) {
units.push(unitTable);
}
if (getUnitsManager().spawnUnits("Aircraft", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
getMap().getMapContextMenu().hide();
}
getUnitsManager().spawnUnits("Aircraft", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
if (res.commandHash !== undefined)
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
});
getMap().getMapContextMenu().hide();
}
}
}
@ -447,10 +450,13 @@ export class HelicopterSpawnMenu extends UnitSpawnMenu {
for (let i = 1; i < unitsCount + 1; i++) {
units.push(unitTable);
}
if (getUnitsManager().spawnUnits("Helicopter", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
getMap().getMapContextMenu().hide();
}
getUnitsManager().spawnUnits("Helicopter", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
if (res.commandHash !== undefined)
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
});
getMap().getMapContextMenu().hide();
}
}
}
@ -481,10 +487,13 @@ export class GroundUnitSpawnMenu extends UnitSpawnMenu {
units.push(JSON.parse(JSON.stringify(unitTable)));
unitTable.location.lat += 0.0001;
}
if (getUnitsManager().spawnUnits("GroundUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
getMap().getMapContextMenu().hide();
}
getUnitsManager().spawnUnits("GroundUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
if (res.commandHash !== undefined)
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
});
getMap().getMapContextMenu().hide();
}
}
}
@ -515,10 +524,13 @@ export class NavyUnitSpawnMenu extends UnitSpawnMenu {
units.push(JSON.parse(JSON.stringify(unitTable)));
unitTable.location.lat += 0.0001;
}
if (getUnitsManager().spawnUnits("NavyUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
getMap().getMapContextMenu().hide();
}
getUnitsManager().spawnUnits("NavyUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
if (res.commandHash !== undefined)
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
});
getMap().getMapContextMenu().hide();
}
}
}

View File

@ -425,8 +425,8 @@ export class Map extends L.Map {
}
}
addTemporaryMarker(latlng: L.LatLng, name: string, coalition: string) {
var marker = new TemporaryUnitMarker(latlng, name, coalition);
addTemporaryMarker(latlng: L.LatLng, name: string, coalition: string, commandHash?: string) {
var marker = new TemporaryUnitMarker(latlng, name, coalition, commandHash);
marker.addTo(this);
this.#temporaryMarkers.push(marker);
}

View File

@ -2,15 +2,33 @@ import { CustomMarker } from "./custommarker";
import { DivIcon, LatLng } from "leaflet";
import { SVGInjector } from "@tanem/svg-injector";
import { getMarkerCategoryByName, getUnitDatabaseByCategory } from "../other/utils";
import { isCommandExecuted } from "../server/server";
import { getMap } from "..";
export class TemporaryUnitMarker extends CustomMarker {
#name: string;
#coalition: string;
#commandHash: string|undefined = undefined;
#timer: number = 0;
constructor(latlng: LatLng, name: string, coalition: string) {
constructor(latlng: LatLng, name: string, coalition: string, commandHash?: string) {
super(latlng, {interactive: false});
this.#name = name;
this.#coalition = coalition;
this.#commandHash = commandHash;
if (this.#commandHash !== undefined) {
this.#timer = window.setInterval(() => {
if (this.#commandHash !== undefined) {
isCommandExecuted((res: any) => {
if (res.commandExecuted) {
this.removeFrom(getMap());
window.clearInterval(this.#timer);
}
}, this.#commandHash)
}
}, 1000);
}
}
createIcon() {

View File

@ -1,19 +1,13 @@
import { LatLng } from 'leaflet';
import { getConnectionStatusPanel, getInfoPopup, getLogPanel, getMissionHandler, getServerStatusPanel, getUnitsManager, getWeaponsManager, setLoginStatus } from '..';
import { GeneralSettings, Radio, TACAN } from '../@types/unit';
import { NONE, ROEs, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
import { AIRBASES_URI, BULLSEYE_URI, COMMANDS_URI, LOGS_URI, MISSION_URI, NONE, ROEs, UNITS_URI, WEAPONS_URI, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
var connected: boolean = false;
var paused: boolean = false;
var REST_ADDRESS = "http://localhost:30000/olympus";
var DEMO_ADDRESS = window.location.href + "demo";
const UNITS_URI = "units";
const WEAPONS_URI = "weapons";
const LOGS_URI = "logs";
const AIRBASES_URI = "airbases";
const BULLSEYE_URI = "bullseyes";
const MISSION_URI = "mission";
var username = "";
var password = "";
@ -38,13 +32,15 @@ export function setCredentials(newUsername: string, newPassword: string) {
password = newPassword;
}
export function GET(callback: CallableFunction, uri: string, options?: { time?: number }, responseType?: string) {
export function GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType?: string) {
var xmlHttp = new XMLHttpRequest();
/* Assemble the request options string */
var optionsString = '';
if (options?.time != undefined)
optionsString = `time=${options.time}`;
if (options?.commandHash != undefined)
optionsString = `commandHash=${options.commandHash}`;
/* On the connection */
xmlHttp.open("GET", `${demoEnabled ? DEMO_ADDRESS : REST_ADDRESS}/${uri}${optionsString ? `?${optionsString}` : ''}`, true);
@ -92,8 +88,9 @@ export function POST(request: object, callback: CallableFunction) {
xmlHttp.setRequestHeader("Content-Type", "application/json");
if (username && password)
xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(`${username}:${password}`));
xmlHttp.onreadystatechange = () => {
callback();
xmlHttp.onload = (res: any) => {
var res = JSON.parse(xmlHttp.responseText);
callback(res);
};
xmlHttp.send(JSON.stringify(request));
}
@ -140,185 +137,189 @@ export function getWeapons(callback: CallableFunction, refresh: boolean = false)
GET(callback, WEAPONS_URI, { time: refresh ? 0 : lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer');
}
export function addDestination(ID: number, path: any) {
export function isCommandExecuted(callback: CallableFunction, commandHash: string) {
GET(callback, COMMANDS_URI, { commandHash: commandHash});
}
export function addDestination(ID: number, path: any, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "path": path }
var data = { "setPath": command }
POST(data, () => { });
POST(data, callback);
}
export function spawnSmoke(color: string, latlng: LatLng) {
export function spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "color": color, "location": latlng };
var data = { "smoke": command }
POST(data, () => { });
POST(data, callback);
}
export function spawnExplosion(intensity: number, latlng: LatLng) {
export function spawnExplosion(intensity: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "intensity": intensity, "location": latlng };
var data = { "explosion": command }
POST(data, () => { });
POST(data, callback);
}
export function spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number) {
export function spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
var data = { "spawnAircrafts": command }
POST(data, () => { });
POST(data, callback);
}
export function spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number) {
export function spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
var data = { "spawnHelicopters": command }
POST(data, () => { });
POST(data, callback);
}
export function spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number) {
export function spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };;
var data = { "spawnGroundUnits": command }
POST(data, () => { });
POST(data, callback);
}
export function spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number) {
export function spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
var data = { "spawnNavyUnits": command }
POST(data, () => { });
POST(data, callback);
}
export function attackUnit(ID: number, targetID: number) {
export function attackUnit(ID: number, targetID: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "targetID": targetID };
var data = { "attackUnit": command }
POST(data, () => { });
POST(data, callback);
}
export function followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }) {
export function followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }, callback: CallableFunction = () => {}) {
// X: front-rear, positive front
// Y: top-bottom, positive bottom
// Z: left-right, positive right
var command = { "ID": ID, "targetID": targetID, "offsetX": offset["x"], "offsetY": offset["y"], "offsetZ": offset["z"] };
var data = { "followUnit": command }
POST(data, () => { });
POST(data, callback);
}
export function cloneUnits(units: {ID: number, location: LatLng}[]) {
export function cloneUnits(units: {ID: number, location: LatLng}[], callback: CallableFunction = () => {}) {
var command = { "units": units };
var data = { "cloneUnit": command }
POST(data, () => { });
POST(data, callback);
}
export function deleteUnit(ID: number, explosion: boolean, immediate: boolean) {
export function deleteUnit(ID: number, explosion: boolean, immediate: boolean, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "explosion": explosion, "immediate": immediate };
var data = { "deleteUnit": command }
POST(data, () => { });
POST(data, callback);
}
export function landAt(ID: number, latlng: LatLng) {
export function landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng };
var data = { "landAt": command }
POST(data, () => { });
POST(data, callback);
}
export function changeSpeed(ID: number, speedChange: string) {
export function changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "change": speedChange }
var data = { "changeSpeed": command }
POST(data, () => { });
POST(data, callback);
}
export function setSpeed(ID: number, speed: number) {
export function setSpeed(ID: number, speed: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "speed": speed }
var data = { "setSpeed": command }
POST(data, () => { });
POST(data, callback);
}
export function setSpeedType(ID: number, speedType: string) {
export function setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "speedType": speedType }
var data = { "setSpeedType": command }
POST(data, () => { });
POST(data, callback);
}
export function changeAltitude(ID: number, altitudeChange: string) {
export function changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "change": altitudeChange }
var data = { "changeAltitude": command }
POST(data, () => { });
POST(data, callback);
}
export function setAltitudeType(ID: number, altitudeType: string) {
export function setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "altitudeType": altitudeType }
var data = { "setAltitudeType": command }
POST(data, () => { });
POST(data, callback);
}
export function setAltitude(ID: number, altitude: number) {
export function setAltitude(ID: number, altitude: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "altitude": altitude }
var data = { "setAltitude": command }
POST(data, () => { });
POST(data, callback);
}
export function createFormation(ID: number, isLeader: boolean, wingmenIDs: number[]) {
export function createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => {}) {
var command = { "ID": ID, "wingmenIDs": wingmenIDs, "isLeader": isLeader }
var data = { "setLeader": command }
POST(data, () => { });
POST(data, callback);
}
export function setROE(ID: number, ROE: string) {
export function setROE(ID: number, ROE: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "ROE": ROEs.indexOf(ROE) }
var data = { "setROE": command }
POST(data, () => { });
POST(data, callback);
}
export function setReactionToThreat(ID: number, reactionToThreat: string) {
export function setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "reactionToThreat": reactionsToThreat.indexOf(reactionToThreat) }
var data = { "setReactionToThreat": command }
POST(data, () => { });
POST(data, callback);
}
export function setEmissionsCountermeasures(ID: number, emissionCountermeasure: string) {
export function setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "emissionsCountermeasures": emissionsCountermeasures.indexOf(emissionCountermeasure) }
var data = { "setEmissionsCountermeasures": command }
POST(data, () => { });
POST(data, callback);
}
export function setOnOff(ID: number, onOff: boolean) {
export function setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "onOff": onOff }
var data = { "setOnOff": command }
POST(data, () => { });
POST(data, callback);
}
export function setFollowRoads(ID: number, followRoads: boolean) {
export function setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "followRoads": followRoads }
var data = { "setFollowRoads": command }
POST(data, () => { });
POST(data, callback);
}
export function refuel(ID: number) {
export function refuel(ID: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID };
var data = { "refuel": command }
POST(data, () => { });
POST(data, callback);
}
export function bombPoint(ID: number, latlng: LatLng) {
export function bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "bombPoint": command }
POST(data, () => { });
POST(data, callback);
}
export function carpetBomb(ID: number, latlng: LatLng) {
export function carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "carpetBomb": command }
POST(data, () => { });
POST(data, callback);
}
export function bombBuilding(ID: number, latlng: LatLng) {
export function bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "bombBuilding": command }
POST(data, () => { });
POST(data, callback);
}
export function fireAtArea(ID: number, latlng: LatLng) {
export function fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "fireAtArea": command }
POST(data, () => { });
POST(data, callback);
}
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings) {
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {
var command = {
"ID": ID,
"isTanker": isTanker,
@ -329,10 +330,10 @@ export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolea
};
var data = { "setAdvancedOptions": command };
POST(data, () => { });
POST(data, callback);
}
export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number) {
export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number, callback: CallableFunction = () => {}) {
var command = {
"restrictSpawns": restrictSpawns,
"restrictToCoalition": restrictToCoalition,
@ -342,7 +343,7 @@ export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoaliti
};
var data = { "setCommandModeOptions": command };
POST(data, () => { });
POST(data, callback);
}
export function startUpdate() {

View File

@ -686,40 +686,46 @@ export class UnitsManager {
input.click();
}
spawnUnits(category: string, units: any, coalition: string = "blue", immediate: boolean = true, airbase: string = "", country: string = "") {
spawnUnits(category: string, units: any, coalition: string = "blue", immediate: boolean = true, airbase: string = "", country: string = "", callback: CallableFunction = () => {}) {
var spawnPoints = 0;
var spawnFunction = () => {};
var spawnsRestricted = getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER;
if (category === "Aircraft") {
if (airbase == "" && getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
if (airbase == "" && spawnsRestricted) {
getInfoPopup().setText("Aircrafts can be air spawned during the SETUP phase only");
return false;
}
spawnPoints = units.reduce((points: number, unit: any) => { return points + aircraftDatabase.getSpawnPointsByName(unit.unitType) }, 0);
spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints);
spawnPoints = units.reduce((points: number, unit: any) => {return points + aircraftDatabase.getSpawnPointsByName(unit.unitType)}, 0);
spawnFunction = () => spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints, callback);
} else if (category === "Helicopter") {
if (airbase == "" && getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
if (airbase == "" && spawnsRestricted) {
getInfoPopup().setText("Helicopters can be air spawned during the SETUP phase only");
return false;
}
spawnPoints = units.reduce((points: number, unit: any) => { return points + helicopterDatabase.getSpawnPointsByName(unit.unitType) }, 0);
spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints);
spawnPoints = units.reduce((points: number, unit: any) => {return points + helicopterDatabase.getSpawnPointsByName(unit.unitType)}, 0);
spawnFunction = () => spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints, callback);
} else if (category === "GroundUnit") {
if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
if (spawnsRestricted) {
getInfoPopup().setText("Ground units can be spawned during the SETUP phase only");
return false;
}
spawnPoints = units.reduce((points: number, unit: any) => { return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType) }, 0);
spawnGroundUnits(units, coalition, country, immediate, spawnPoints);
spawnPoints = units.reduce((points: number, unit: any) => {return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
spawnFunction = () => spawnGroundUnits(units, coalition, country, immediate, spawnPoints, callback);
} else if (category === "NavyUnit") {
if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
if (spawnsRestricted) {
getInfoPopup().setText("Navy units can be spawned during the SETUP phase only");
return false;
}
spawnPoints = units.reduce((points: number, unit: any) => { return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType) }, 0);
spawnNavyUnits(units, coalition, country, immediate, spawnPoints);
spawnPoints = units.reduce((points: number, unit: any) => {return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
spawnFunction = () => spawnNavyUnits(units, coalition, country, immediate, spawnPoints, callback);
}
if (spawnPoints <= getMissionHandler().getAvailableSpawnPoints()) {
getMissionHandler().setSpentSpawnPoints(spawnPoints);
spawnFunction();
return true;
} else {
getInfoPopup().setText("Not enough spawn points available!");

View File

@ -98,9 +98,11 @@ public:
unsigned int getPriority() { return priority; }
virtual string getString() = 0;
virtual unsigned int getLoad() = 0;
const string getHash() { return hash; }
protected:
unsigned int priority = CommandPriority::LOW;
const string hash = random_string(16);
};
/* Simple low priority move command (from user click) */

View File

@ -11,9 +11,10 @@ public:
void appendCommand(Command* command);
void execute(lua_State* L);
void handleRequest(string key, json::value value, string username);
void handleRequest(string key, json::value value, string username, json::value& answer);
bool checkSpawnPoints(int spawnPoints, string coalition);
bool isCommandExecuted(string commandHash) { return (find(executedCommandsHashes.begin(), executedCommandsHashes.end(), commandHash) != executedCommandsHashes.end()); }
void setFrameRate(double newFrameRate) { frameRate = newFrameRate; }
void setRestrictSpawns(bool newRestrictSpawns) { restrictSpawns = newRestrictSpawns; }
void setRestrictToCoalition(bool newRestrictToCoalition) { restrictToCoalition = newRestrictToCoalition; }
@ -35,6 +36,7 @@ public:
private:
list<Command*> commands;
list<string> executedCommandsHashes;
unsigned int load;
double frameRate;

View File

@ -60,6 +60,7 @@ void Scheduler::execute(lua_State* L)
log("Command '" + commandString + "' executed correctly, current load " + to_string(getLoad()));
load = command->getLoad();
commands.remove(command);
executedCommandsHashes.push_back(command->getHash());
delete command;
return;
}
@ -134,7 +135,7 @@ bool Scheduler::checkSpawnPoints(int spawnPoints, string coalition)
}
}
void Scheduler::handleRequest(string key, json::value value, string username)
void Scheduler::handleRequest(string key, json::value value, string username, json::value& answer)
{
Command* command = nullptr;
@ -572,6 +573,7 @@ void Scheduler::handleRequest(string key, json::value value, string username)
{
appendCommand(command);
log("New command appended correctly to stack. Current server load: " + to_string(getLoad()));
answer[L"commandHash"] = json::value(to_wstring(command->getHash()));
}
}

View File

@ -142,6 +142,9 @@ void Server::handle_get(http_request request)
else
answer[L"mission"][L"commandModeOptions"][L"commandMode"] = json::value(L"Observer");
}
else if (URI.compare(COMMANDS_URI) && query.find(L"commandHash") != query.end()) {
answer[L"commandExectued"] = json::value(scheduler->isCommandExecuted(to_string(query[L"commandHash"])));
}
/* Common data */
answer[L"time"] = json::value::string(to_wstring(ms.count()));
@ -222,7 +225,7 @@ void Server::handle_put(http_request request)
std::exception_ptr eptr;
try {
scheduler->handleRequest(to_string(key), value, username);
scheduler->handleRequest(to_string(key), value, username, answer);
}
catch (...) {
eptr = std::current_exception(); // capture

View File

@ -10,5 +10,6 @@
#define AIRBASES_URI "airbases"
#define BULLSEYE_URI "bullseyes"
#define MISSION_URI "mission"
#define COMMANDS_URI "commands"
#define FRAMERATE_TIME_INTERVAL 0.05