RC1 fixes

This commit is contained in:
Pax1601 2023-12-05 11:26:18 +01:00
parent 24a1681337
commit 8f2f73dc0e
11 changed files with 108 additions and 86 deletions

View File

@ -62,6 +62,16 @@
height: 180px;
}
#hotgroup-panel {
bottom: 40px;
column-gap: 10px;
display: flex;
left: 50%;
position: absolute;
translate: -50%;
z-index: 9998;
}
#info-popup {
position: absolute;
width: fit-content;

View File

@ -994,16 +994,6 @@ nav.ol-panel> :last-child {
}
}
#hotgroup-panel {
bottom: 40px;
column-gap: 10px;
display: flex;
left: 50%;
position: absolute;
translate: -50%;
z-index: 9999;
}
#hotgroup-panel>div {
align-items: center;
background-color: var(--background-steel);

View File

@ -116,6 +116,13 @@ export const minimapBoundaries = [
new LatLng(48.12, 3.70),
new LatLng(50.44, 3.70),
new LatLng(50.44, -3.29)
],
[ // Sinai
new LatLng(34.312222, 28.523333),
new LatLng(25.946944, 28.523333),
new LatLng(25.946944, 36.897778),
new LatLng(34.312222, 36.897778),
new LatLng(34.312222, 28.523333)
]
];
@ -127,6 +134,7 @@ export const mapBounds = {
"Caucasus": { bounds: new LatLngBounds([39.6170191, 27.634935], [47.3907982, 49.3101946]), zoom: 4 },
"Falklands": { bounds: new LatLngBounds([-49.097217, -79.418267], [-56.874517, -43.316433]), zoom: 3 },
"Normandy": { bounds: new LatLngBounds([50.44, -3.29], [48.12, 3.70]), zoom: 5 },
"SinaiMap": { bounds: new LatLngBounds([34.312222, 28.523333], [25.946944, 36.897778]), zoom: 4 },
}
export const mapLayers = {

View File

@ -26,7 +26,7 @@ export class Dropdown {
if (options != null) this.setOptions(options);
this.#value.addEventListener("click", (ev) => { this.#toggle(); });
(this.#container.querySelector(".ol-select-value") as HTMLElement)?.addEventListener("click", (ev) => { this.#toggle(); });
document.addEventListener("click", (ev) => {
if (!(this.#value.contains(ev.target as Node) || this.#options.contains(ev.target as Node) || this.#container.contains(ev.target as Node))) {

View File

@ -30,6 +30,7 @@ import { ContextManager } from "./context/contextmanager";
import { Context } from "./context/context";
var VERSION = "v0.4.9-alpha-rc1";
var DEBUG = true;
export class OlympusApp {
/* Global data */
@ -298,7 +299,7 @@ export class OlympusApp {
shortcutManager.addKeyboardShortcut("toggleDemo", {
"altKey": false,
"callback": () => {
this.getServerManager().toggleDemoEnabled();
if (DEBUG === true) this.getServerManager().toggleDemoEnabled();
},
"code": "KeyT",
"context": "olympus",

View File

@ -16,11 +16,12 @@ export class ServerManager {
#username = "";
#password = "";
#sessionHash: string | null = null;
#lastUpdateTimes: {[key: string]: number} = {}
#lastUpdateTimes: { [key: string]: number } = {}
#demoEnabled = false;
#previousMissionElapsedTime:number = 0; // Track if mission elapsed time is increasing (i.e. is the server paused)
#previousMissionElapsedTime: number = 0; // Track if mission elapsed time is increasing (i.e. is the server paused)
#serverIsPaused: boolean = false;
#intervals: number[] = [];
#requests: { [key: string]: XMLHttpRequest } = {};
constructor() {
this.#lastUpdateTimes[UNITS_URI] = Date.now();
@ -40,9 +41,20 @@ export class ServerManager {
this.#password = newPassword;
}
GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType?: string) {
GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType: string = 'text', force: boolean = false) {
var xmlHttp = new XMLHttpRequest();
/* If a request on this uri is still pending (meaning it's not done or did not yet fail), skip the request, to avoid clogging the TCP workers */
/* If we are forcing the request we don't care if one already exists, just send it. CAREFUL: this makes sense only for low frequency requests, like refreshes, when we
are reasonably confident any previous request will be done before we make a new one on the same URI. */
if (uri in this.#requests && this.#requests[uri].readyState !== 4 && !force) {
console.warn(`GET request on ${uri} URI still pending, skipping...`);
return;
}
if (!force)
this.#requests[uri] = xmlHttp;
/* Assemble the request options string */
var optionsString = '';
if (options?.time != undefined)
@ -52,6 +64,7 @@ export class ServerManager {
/* On the connection */
xmlHttp.open("GET", `${this.#demoEnabled ? this.#DEMO_ADDRESS : this.#REST_ADDRESS}/${uri}${optionsString ? `?${optionsString}` : ''}`, true);
xmlHttp.timeout = 2000;
/* If provided, set the credentials */
if (this.#username && this.#password)
@ -130,7 +143,7 @@ export class ServerManager {
}
getLogs(callback: CallableFunction, refresh: boolean = false) {
this.GET(callback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI]});
this.GET(callback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI] }, 'text', refresh);
}
getMission(callback: CallableFunction) {
@ -138,66 +151,66 @@ export class ServerManager {
}
getUnits(callback: CallableFunction, refresh: boolean = false) {
this.GET(callback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer');
this.GET(callback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer', refresh);
}
getWeapons(callback: CallableFunction, refresh: boolean = false) {
this.GET(callback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer');
this.GET(callback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer', refresh);
}
isCommandExecuted(callback: CallableFunction, commandHash: string) {
this.GET(callback, COMMANDS_URI, { commandHash: commandHash});
this.GET(callback, COMMANDS_URI, { commandHash: commandHash });
}
addDestination(ID: number, path: any, callback: CallableFunction = () => {}) {
addDestination(ID: number, path: any, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "path": path }
var data = { "setPath": command }
this.PUT(data, callback);
}
spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => {}) {
spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "color": color, "location": latlng };
var data = { "smoke": command }
this.PUT(data, callback);
}
spawnExplosion(intensity: number, explosionType: string, latlng: LatLng, callback: CallableFunction = () => {}) {
spawnExplosion(intensity: number, explosionType: string, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "explosionType": explosionType, "intensity": intensity, "location": latlng };
var data = { "explosion": command }
this.PUT(data, callback);
}
spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
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 }
this.PUT(data, callback);
}
spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
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 }
this.PUT(data, callback);
}
spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
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 }
this.PUT(data, callback);
}
spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
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 }
this.PUT(data, callback);
}
attackUnit(ID: number, targetID: number, callback: CallableFunction = () => {}) {
attackUnit(ID: number, targetID: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "targetID": targetID };
var data = { "attackUnit": command }
this.PUT(data, callback);
}
followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }, callback: CallableFunction = () => {}) {
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
@ -207,172 +220,172 @@ export class ServerManager {
this.PUT(data, callback);
}
cloneUnits(units: {ID: number, location: LatLng}[], deleteOriginal: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
cloneUnits(units: { ID: number, location: LatLng }[], deleteOriginal: boolean, spawnPoints: number, callback: CallableFunction = () => { }) {
var command = { "units": units, "deleteOriginal": deleteOriginal, "spawnPoints": spawnPoints };
var data = { "cloneUnits": command }
this.PUT(data, callback);
}
deleteUnit(ID: number, explosion: boolean, explosionType: string, immediate: boolean, callback: CallableFunction = () => {}) {
deleteUnit(ID: number, explosion: boolean, explosionType: string, immediate: boolean, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "explosion": explosion, "explosionType": explosionType, "immediate": immediate };
var data = { "deleteUnit": command }
this.PUT(data, callback);
}
landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng };
var data = { "landAt": command }
this.PUT(data, callback);
}
changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => {}) {
changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "change": speedChange }
var data = { "changeSpeed": command }
this.PUT(data, callback);
}
setSpeed(ID: number, speed: number, callback: CallableFunction = () => {}) {
setSpeed(ID: number, speed: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "speed": speed }
var data = { "setSpeed": command }
this.PUT(data, callback);
}
setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => {}) {
setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "speedType": speedType }
var data = { "setSpeedType": command }
this.PUT(data, callback);
}
changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => {}) {
changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "change": altitudeChange }
var data = { "changeAltitude": command }
this.PUT(data, callback);
}
setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => {}) {
setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "altitudeType": altitudeType }
var data = { "setAltitudeType": command }
this.PUT(data, callback);
}
setAltitude(ID: number, altitude: number, callback: CallableFunction = () => {}) {
setAltitude(ID: number, altitude: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "altitude": altitude }
var data = { "setAltitude": command }
this.PUT(data, callback);
}
createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => {}) {
createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => { }) {
var command = { "ID": ID, "wingmenIDs": wingmenIDs, "isLeader": isLeader }
var data = { "setLeader": command }
this.PUT(data, callback);
}
setROE(ID: number, ROE: string, callback: CallableFunction = () => {}) {
setROE(ID: number, ROE: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "ROE": ROEs.indexOf(ROE) }
var data = { "setROE": command }
this.PUT(data, callback);
}
setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => {}) {
setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "reactionToThreat": reactionsToThreat.indexOf(reactionToThreat) }
var data = { "setReactionToThreat": command }
this.PUT(data, callback);
}
setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => {}) {
setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "emissionsCountermeasures": emissionsCountermeasures.indexOf(emissionCountermeasure) }
var data = { "setEmissionsCountermeasures": command }
this.PUT(data, callback);
}
setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => {}) {
setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "onOff": onOff }
var data = { "setOnOff": command }
this.PUT(data, callback);
}
setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => {}) {
setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "followRoads": followRoads }
var data = { "setFollowRoads": command }
this.PUT(data, callback);
}
setOperateAs(ID: number, operateAs: number, callback: CallableFunction = () => {}) {
setOperateAs(ID: number, operateAs: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "operateAs": operateAs }
var data = { "setOperateAs": command }
this.PUT(data, callback);
}
refuel(ID: number, callback: CallableFunction = () => {}) {
refuel(ID: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID };
var data = { "refuel": command }
this.PUT(data, callback);
}
bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng }
var data = { "bombPoint": command }
this.PUT(data, callback);
}
carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng }
var data = { "carpetBomb": command }
this.PUT(data, callback);
}
bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng }
var data = { "bombBuilding": command }
this.PUT(data, callback);
}
fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng }
var data = { "fireAtArea": command }
this.PUT(data, callback);
}
simulateFireFight(ID: number, latlng: LatLng, altitude: number, callback: CallableFunction = () => {}) {
simulateFireFight(ID: number, latlng: LatLng, altitude: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng, "altitude": altitude }
var data = { "simulateFireFight": command }
this.PUT(data, callback);
}
// TODO: Remove coalition
scenicAAA(ID: number, coalition: string, callback: CallableFunction = () => {}) {
scenicAAA(ID: number, coalition: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "coalition": coalition }
var data = { "scenicAAA": command }
this.PUT(data, callback);
}
// TODO: Remove coalition
missOnPurpose(ID: number, coalition: string, callback: CallableFunction = () => {}) {
missOnPurpose(ID: number, coalition: string, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "coalition": coalition }
var data = { "missOnPurpose": command }
this.PUT(data, callback);
}
landAtPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
landAtPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "location": latlng }
var data = { "landAtPoint": command }
this.PUT(data, callback);
}
setShotsScatter(ID: number, shotsScatter: number, callback: CallableFunction = () => {}) {
setShotsScatter(ID: number, shotsScatter: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "shotsScatter": shotsScatter }
var data = { "setShotsScatter": command }
this.PUT(data, callback);
}
setShotsIntensity(ID: number, shotsIntensity: number, callback: CallableFunction = () => {}) {
setShotsIntensity(ID: number, shotsIntensity: number, callback: CallableFunction = () => { }) {
var command = { "ID": ID, "shotsIntensity": shotsIntensity }
var data = { "setShotsIntensity": command }
this.PUT(data, callback);
}
setAdvacedOptions(ID: number, isActiveTanker: boolean, isActiveAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {
setAdvacedOptions(ID: number, isActiveTanker: boolean, isActiveAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => { }) {
var command = {
"ID": ID,
"isActiveTanker": isActiveTanker,
@ -386,7 +399,7 @@ export class ServerManager {
this.PUT(data, callback);
}
setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number, callback: CallableFunction = () => {}) {
setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: { blue: number, red: number }, eras: string[], setupTime: number, callback: CallableFunction = () => { }) {
var command = {
"restrictSpawns": restrictSpawns,
"restrictToCoalition": restrictToCoalition,
@ -399,7 +412,7 @@ export class ServerManager {
this.PUT(data, callback);
}
reloadDatabases(callback: CallableFunction = () => {}) {
reloadDatabases(callback: CallableFunction = () => { }) {
var data = { "reloadDatabases": {} };
this.PUT(data, callback);
}
@ -430,7 +443,7 @@ export class ServerManager {
}, 10000));
this.#intervals.push(window.setInterval(() => {
if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE){
if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) {
this.getBullseye((data: BullseyesData) => {
this.checkSessionHash(data.sessionHash);
getApp().getMissionManager()?.updateBullseyes(data);
@ -452,7 +465,7 @@ export class ServerManager {
this.#intervals.push(window.setInterval(() => {
if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) {
this.getUnits((buffer: ArrayBuffer) => {
var time = getApp().getUnitsManager()?.update(buffer);
var time = getApp().getUnitsManager()?.update(buffer);
return time;
}, false);
}
@ -461,7 +474,7 @@ export class ServerManager {
this.#intervals.push(window.setInterval(() => {
if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) {
this.getWeapons((buffer: ArrayBuffer) => {
var time = getApp().getWeaponsManager()?.update(buffer);
var time = getApp().getWeaponsManager()?.update(buffer);
return time;
}, false);
}
@ -470,18 +483,18 @@ export class ServerManager {
this.#intervals.push(window.setInterval(() => {
if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) {
this.getUnits((buffer: ArrayBuffer) => {
var time = getApp().getUnitsManager()?.update(buffer);
var time = getApp().getUnitsManager()?.update(buffer);
return time;
}, true);
const elapsedMissionTime = getApp().getMissionManager().getDateAndTime().elapsedTime;
this.#serverIsPaused = ( elapsedMissionTime === this.#previousMissionElapsedTime );
const elapsedMissionTime = getApp().getMissionManager().getDateAndTime().elapsedTime;
this.#serverIsPaused = (elapsedMissionTime === this.#previousMissionElapsedTime);
this.#previousMissionElapsedTime = elapsedMissionTime;
const csp = (getApp().getPanelsManager().get("connectionStatus") as ConnectionStatusPanel);
if ( this.getConnected() ) {
if ( this.getServerIsPaused() ) {
if (this.getConnected()) {
if (this.getServerIsPaused()) {
csp.showServerPaused();
} else {
csp.showConnected();
@ -491,29 +504,29 @@ export class ServerManager {
}
}
}, ( this.getServerIsPaused() ? 500 : 5000 )));
}, (this.getServerIsPaused() ? 500 : 5000)));
// Mission clock and elapsed time
this.#intervals.push(window.setInterval( () => {
if ( !this.getConnected() || this.#serverIsPaused ) {
this.#intervals.push(window.setInterval(() => {
if (!this.getConnected() || this.#serverIsPaused) {
return;
}
const elapsedMissionTime = getApp().getMissionManager().getDateAndTime().elapsedTime;
const csp = (getApp().getPanelsManager().get("connectionStatus") as ConnectionStatusPanel);
const mt = getApp().getMissionManager().getDateAndTime().time;
const mt = getApp().getMissionManager().getDateAndTime().time;
csp.setMissionTime( [ mt.h, mt.m, mt.s ].map( n => zeroAppend( n, 2 )).join( ":" ) );
csp.setElapsedTime( new Date( elapsedMissionTime * 1000 ).toISOString().substring( 11, 19 ) );
csp.setMissionTime([mt.h, mt.m, mt.s].map(n => zeroAppend(n, 2)).join(":"));
csp.setElapsedTime(new Date(elapsedMissionTime * 1000).toISOString().substring(11, 19));
}, 1000));
this.#intervals.push(window.setInterval(() => {
if (!this.getPaused() && getApp().getMissionManager().getCommandModeOptions().commandMode != NONE) {
this.getWeapons((buffer: ArrayBuffer) => {
var time = getApp().getWeaponsManager()?.update(buffer);
var time = getApp().getWeaponsManager()?.update(buffer);
return time;
}, true);
}
@ -540,12 +553,12 @@ export class ServerManager {
});
this.getWeapons((buffer: ArrayBuffer) => {
var time = getApp().getWeaponsManager()?.update(buffer);
var time = getApp().getWeaponsManager()?.update(buffer);
return time;
}, true);
this.getUnits((buffer: ArrayBuffer) => {
var time = getApp().getUnitsManager()?.update(buffer);
var time = getApp().getUnitsManager()?.update(buffer);
return time;
}, true);
}

View File

@ -52,8 +52,7 @@
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "normal", "strength": 10 }'>Big explosion</button>
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "phosphorous"}'>White phosphorous</button>
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "napalm"}'>Napalm</button>
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "secondary"}'>Explosion with secondaries</button>
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "secondary"}'>Explosion with debries</button>
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "fire"}'>Static fire</button>
<button class="explosion-button" title="" data-on-click="contextMenuExplosion" data-on-click-params='{ "explosionType": "depthCharge"}'>Depth charge</button>
</div>
</div>

View File

@ -8,8 +8,8 @@
</div>
<form id="authentication-form">
<div><h5>Username</h5> <input type="text" id="username" name="username" required autocomplete="username" placeholder="Enter username..."></div>
<div><h5>Password</h5> <input type="password" id="password" name="password" minlength="8" required autocomplete="current-password" placeholder="Enter password..."></div>
<div><h5>Name</h5> <input type="text" id="username" name="username" required autocomplete="username" placeholder="Enter name..."></div>
<div><h5>Server password</h5> <input type="password" id="password" name="password" required autocomplete="current-password" placeholder="Enter server password..."></div>
<button type="submit" id="connection-button" class="ol-button-apply">Connect</button>
</form>

View File

@ -117,7 +117,7 @@
<div><button class="ol-button-white" data-on-click="deleteSelectedUnits" title="Immediately remove the unit from the simulation"><img src="/resources/theme/images/icons/trash-can-regular.svg" inject-svg>Delete</button></div>
<div class="hr"><hr></div>
<div><button class="ol-button-warning" data-on-click="explodeSelectedUnits" data-on-click-params='{ "type": "normal" }' title="Normal explosion"><img src="/resources/theme/images/icons/explosion-solid.svg" inject-svg>Blow up</button></div>
<div><button class="ol-button-warning" data-on-click="explodeSelectedUnits" data-on-click-params='{ "type": "secondary" }' title="The unit will keep exploding at random intervals, simulating ammunition cooking"><img src="/resources/theme/images/icons/burst-solid.svg" inject-svg>Cook off</button></div>
<div><button class="ol-button-warning" data-on-click="explodeSelectedUnits" data-on-click-params='{ "type": "secondary" }' title="Small explosion with debries"><img src="/resources/theme/images/icons/burst-solid.svg" inject-svg>Cook off</button></div>
<div><button class="ol-button-warning" data-on-click="explodeSelectedUnits" data-on-click-params='{ "type": "phosphorous" }' title="White phosphorous explosion"><img src="/resources/theme/images/icons/smog-solid.svg" inject-svg>Phosp.</button></div>
<div><button class="ol-button-warning" data-on-click="explodeSelectedUnits" data-on-click-params='{ "type": "napalm" }' title="Napalm"><img src="/resources/theme/images/icons/fire-solid.svg" inject-svg>Napalm</button></div>
</div>

View File

@ -510,10 +510,11 @@ function Olympus.removeFire (smokeName)
end
function Olympus.secondaries(vec3)
trigger.action.explosion(vec3, 1)
for i = 1, 10 do
timer.scheduleFunction(Olympus.randomDebries, vec3, timer.getTime() + math.random(0, 180))
end
Olympus.randomDebrie(vec3)
--trigger.action.explosion(vec3, 1)
--for i = 1, 10 do
-- timer.scheduleFunction(Olympus.randomDebries, vec3, timer.getTime() + math.random(0, 180))
--end
end
function Olympus.randomDebries(vec3)

View File

@ -228,7 +228,7 @@ void GroundUnit::AIloop()
Geodesic::WGS84().Inverse(getPosition().lat, getPosition().lng, scatteredTargetPosition.lat, scatteredTargetPosition.lng, distance, bearing1, bearing2);
/* Compute the scattered position applying a random scatter to the shot */
double scatterDistance = distance * tan(10 /* degs */ * (ShotsScatter::LOW - shotsScatter) / 57.29577) * RANDOM_MINUS_ONE_TO_ONE;
double scatterDistance = distance * tan(10 /* degs */ * (ShotsScatter::LOW - shotsScatter) / 57.29577 + 2 /* degs */) * RANDOM_MINUS_ONE_TO_ONE;
Geodesic::WGS84().Direct(scatteredTargetPosition.lat, scatteredTargetPosition.lng, bearing1 + 90, scatterDistance, scatteredTargetPosition.lat, scatteredTargetPosition.lng);
/* Recover the data from the database */