Added basic simulated firefight state

This commit is contained in:
Pax1601 2023-09-15 09:36:27 +02:00
parent 9acd358080
commit 8977ba9b6d
20 changed files with 461 additions and 44 deletions

View File

@ -369,6 +369,10 @@
content: url("/resources/theme/images/icons/crosshairs-solid.svg");
}
#simulate-fire-fight::before {
content: url("/resources/theme/images/icons/crosshairs-solid.svg");
}
#follow::before {
content: url("/resources/theme/images/icons/follow.svg");
}

View File

@ -20,7 +20,7 @@ export const IRST = 8;
export const RWR = 16;
export const DLINK = 32;
export const states: string[] = ["none", "idle", "reach-destination", "attack", "follow", "land", "refuel", "AWACS", "tanker", "bomb-point", "carpet-bomb", "bomb-building", "fire-at-area"];
export const states: string[] = ["none", "idle", "reach-destination", "attack", "follow", "land", "refuel", "AWACS", "tanker", "bomb-point", "carpet-bomb", "bomb-building", "fire-at-area", "simulate-fire-fight"];
export const ROEs: string[] = ["free", "designated", "", "return", "hold"];
export const reactionsToThreat: string[] = ["none", "manoeuvre", "passive", "evade"];
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];

View File

@ -579,8 +579,10 @@ export class Map extends L.Map {
}
}
else if (selectedUnitTypes.length === 1 && ["GroundUnit", "NavyUnit"].includes(selectedUnitTypes[0])) {
if (selectedUnits.every((unit: Unit) => { return ["Gun Artillery", "Rocket Artillery", "Infantry", "IFV", "Tank", "Cruiser", "Destroyer", "Frigate"].includes(unit.getType()) }))
if (selectedUnits.every((unit: Unit) => { return ["Gun Artillery", "Rocket Artillery", "Infantry", "IFV", "Tank", "Cruiser", "Destroyer", "Frigate"].includes(unit.getType()) })) {
options["fire-at-area"] = { text: "Fire at area", tooltip: "Fire at a large area" };
options["simulate-fire-fight"] = { text: "Simulate fire fight", tooltip: "Simulate a fire fight by shooting randomly in a certain large area" };
}
else
getInfoPopup().setText(`Selected units can not perform point actions.`);
}
@ -604,6 +606,10 @@ export class Map extends L.Map {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates());
}
else if (option === "simulate-fire-fight") {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsSimulateFireFight(this.getMouseCoordinates());
}
});
}
}, 150);

View File

@ -319,6 +319,12 @@ export function fireAtArea(ID: number, latlng: LatLng, callback: CallableFunctio
POST(data, callback);
}
export function simulateFireFight(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng }
var data = { "simulateFireFight": command }
POST(data, callback);
}
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {
var command = {
"ID": ID,

View File

@ -1,7 +1,7 @@
import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point } from 'leaflet';
import { getMap, getMissionHandler, getUnitsManager, getWeaponsManager } from '..';
import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM } from '../other/utils';
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads, bombPoint, carpetBomb, bombBuilding, fireAtArea } from '../server/server';
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads, bombPoint, carpetBomb, bombBuilding, fireAtArea, simulateFireFight } from '../server/server';
import { CustomMarker } from '../map/markers/custommarker';
import { SVGInjector } from '@tanem/svg-injector';
import { UnitDatabase } from './databases/unitdatabase';
@ -717,6 +717,10 @@ export class Unit extends CustomMarker {
fireAtArea(this.ID, latlng);
}
simulateFireFight(latlng: LatLng) {
simulateFireFight(this.ID, latlng);
}
/***********************************************/
onAdd(map: Map): this {
super.onAdd(map);

View File

@ -605,6 +605,18 @@ export class UnitsManager {
this.#showActionMessage(selectedUnits, `unit bombing point`);
}
/** Instruct the selected units to simulate a fire fight at specific coordinates
*
* @param latlng Location to fire at
*/
selectedUnitsSimulateFireFight(latlng: LatLng) {
var selectedUnits = this.getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true });
for (let idx in selectedUnits) {
selectedUnits[idx].simulateFireFight(latlng);
}
this.#showActionMessage(selectedUnits, `unit simulating fire fight`);
}
/*********************** Control operations on selected units ************************/
/** See getUnitsCategories for more info
*

View File

@ -1,6 +1,6 @@
local version = "v0.4.4-alpha"
local debug = false -- True enables debug printing using DCS messages
local debug = true -- True enables debug printing using DCS messages
-- .dll related variables
Olympus.OlympusDLL = nil
@ -229,13 +229,24 @@ function Olympus.buildTask(groupName, options)
-- Fire at a specific point
elseif options['id'] == 'FireAtPoint' and options['lat'] and options['lng'] and options['radius'] then
local point = coord.LLtoLO(options['lat'], options['lng'], 0)
task = {
id = 'FireAtPoint',
params = {
point = {x = point.x, y = point.z},
radius = options['radius']
}
}
if options['alt'] then
task = {
id = 'FireAtPoint',
params = {
point = {x = point.x, y = point.z},
radius = options['radius'],
altitude = options['alt']
}
}
else
task = {
id = 'FireAtPoint',
params = {
point = {x = point.x, y = point.z},
radius = options['radius']
}
}
end
end
end
return task

View File

@ -0,0 +1,21 @@
import sys
import json
import inspect
import difflib
from slpp import slpp as lua
SEARCH_FOLDER = "D:\\Eagle Dynamics\\DCS World OpenBeta"
sys.path.append("..\\..\\..\\dcs-master\\dcs-master")
from dcs.vehicles import *
with open("gundata.h", "w") as f:
for unit in vehicle_map.values():
if unit in Artillery.__dict__.values() or unit in Armor.__dict__.values() or unit in Infantry.__dict__.values():
f.write('{"' + unit.id + '", {0.9, 860}}, \n')
# Done!
print("Done!")

109
scripts/python/gundata.h Normal file
View File

@ -0,0 +1,109 @@
{"2B11 mortar", {0.9, 860}},
{"SAU Gvozdika", {0.9, 860}},
{"SAU Msta", {0.9, 860}},
{"SAU Akatsia", {0.9, 860}},
{"SAU 2-C9", {0.9, 860}},
{"M-109", {0.9, 860}},
{"SpGH_Dana", {0.9, 860}},
{"AAV7", {0.9, 860}},
{"BMD-1", {0.9, 860}},
{"BMP-1", {0.9, 860}},
{"BMP-2", {0.9, 860}},
{"BMP-3", {0.9, 860}},
{"BRDM-2", {0.9, 860}},
{"BTR_D", {0.9, 860}},
{"Cobra", {0.9, 860}},
{"LAV-25", {0.9, 860}},
{"M1043 HMMWV Armament", {0.9, 860}},
{"M1045 HMMWV TOW", {0.9, 860}},
{"M1126 Stryker ICV", {0.9, 860}},
{"M-113", {0.9, 860}},
{"M1134 Stryker ATGM", {0.9, 860}},
{"M-2 Bradley", {0.9, 860}},
{"MCV-80", {0.9, 860}},
{"MTLB", {0.9, 860}},
{"Marder", {0.9, 860}},
{"TPZ", {0.9, 860}},
{"Grad_FDDM", {0.9, 860}},
{"Paratrooper RPG-16", {0.9, 860}},
{"Paratrooper AKS-74", {0.9, 860}},
{"Infantry AK Ins", {0.9, 860}},
{"Soldier AK", {0.9, 860}},
{"Infantry AK", {0.9, 860}},
{"Soldier M249", {0.9, 860}},
{"Soldier M4", {0.9, 860}},
{"Soldier M4 GRG", {0.9, 860}},
{"Soldier RPG", {0.9, 860}},
{"MLRS FDDM", {0.9, 860}},
{"Infantry AK ver2", {0.9, 860}},
{"Infantry AK ver3", {0.9, 860}},
{"Grad-URAL", {0.9, 860}},
{"Uragan_BM-27", {0.9, 860}},
{"Smerch", {0.9, 860}},
{"Smerch_HE", {0.9, 860}},
{"MLRS", {0.9, 860}},
{"Challenger2", {0.9, 860}},
{"Leclerc", {0.9, 860}},
{"M-60", {0.9, 860}},
{"M1128 Stryker MGS", {0.9, 860}},
{"M-1 Abrams", {0.9, 860}},
{"T-55", {0.9, 860}},
{"T-72B", {0.9, 860}},
{"T-80UD", {0.9, 860}},
{"T-90", {0.9, 860}},
{"Leopard1A3", {0.9, 860}},
{"Merkava_Mk4", {0.9, 860}},
{"JTAC", {0.9, 860}},
{"Infantry Animated", {0.9, 860}},
{"HL_DSHK", {0.9, 860}},
{"HL_KORD", {0.9, 860}},
{"tt_DSHK", {0.9, 860}},
{"tt_KORD", {0.9, 860}},
{"HL_B8M1", {0.9, 860}},
{"tt_B8M1", {0.9, 860}},
{"M4_Sherman", {0.9, 860}},
{"M2A1_halftrack", {0.9, 860}},
{"BTR-80", {0.9, 860}},
{"T-72B3", {0.9, 860}},
{"PT_76", {0.9, 860}},
{"BTR-82A", {0.9, 860}},
{"Chieftain_mk3", {0.9, 860}},
{"Pz_IV_H", {0.9, 860}},
{"Leopard-2A5", {0.9, 860}},
{"Leopard-2", {0.9, 860}},
{"leopard-2A4", {0.9, 860}},
{"leopard-2A4_trs", {0.9, 860}},
{"Sd_Kfz_251", {0.9, 860}},
{"T155_Firtina", {0.9, 860}},
{"VAB_Mephisto", {0.9, 860}},
{"ZTZ96B", {0.9, 860}},
{"ZBD04A", {0.9, 860}},
{"PLZ05", {0.9, 860}},
{"TYPE-59", {0.9, 860}},
{"Tiger_I", {0.9, 860}},
{"Tiger_II_H", {0.9, 860}},
{"Pz_V_Panther_G", {0.9, 860}},
{"Jagdpanther_G1", {0.9, 860}},
{"JagdPz_IV", {0.9, 860}},
{"Stug_IV", {0.9, 860}},
{"SturmPzIV", {0.9, 860}},
{"Wespe124", {0.9, 860}},
{"Sd_Kfz_234_2_Puma", {0.9, 860}},
{"soldier_mauser98", {0.9, 860}},
{"Stug_III", {0.9, 860}},
{"Elefant_SdKfz_184", {0.9, 860}},
{"Pak40", {0.9, 860}},
{"LeFH_18-40-105", {0.9, 860}},
{"Cromwell_IV", {0.9, 860}},
{"M4A4_Sherman_FF", {0.9, 860}},
{"soldier_wwii_br_01", {0.9, 860}},
{"Centaur_IV", {0.9, 860}},
{"Churchill_VII", {0.9, 860}},
{"Daimler_AC", {0.9, 860}},
{"Tetrarch", {0.9, 860}},
{"M12_GMC", {0.9, 860}},
{"soldier_wwii_us", {0.9, 860}},
{"M10_GMC", {0.9, 860}},
{"M8_Greyhound", {0.9, 860}},
{"M2A1-105", {0.9, 860}},
{"M4_Tractor", {0.9, 860}},

View File

@ -37,6 +37,7 @@
<ClInclude Include="include\airunit.h" />
<ClInclude Include="include\commands.h" />
<ClInclude Include="include\datatypes.h" />
<ClInclude Include="include\gundata.h" />
<ClInclude Include="include\measure.h" />
<ClInclude Include="include\groundunit.h" />
<ClInclude Include="include\helicopter.h" />

View File

@ -54,6 +54,9 @@
<ClInclude Include="include\weaponsmanager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\gundata.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\aircraft.cpp">

View File

@ -95,21 +95,26 @@ namespace ECMUse {
class Command
{
public:
Command(function<void(void)> callback) : callback(callback) {};
unsigned int getPriority() { return priority; }
virtual string getString() = 0;
virtual unsigned int getLoad() = 0;
const string getHash() { return hash; }
void executeCallback() { callback(); }
protected:
unsigned int priority = CommandPriority::LOW;
const string hash = random_string(16);
function<void(void)> callback;
};
/* Simple low priority move command (from user click) */
class Move : public Command
{
public:
Move(string groupName, Coords destination, double speed, string speedType, double altitude, string altitudeType, string taskOptions, string category):
Move(string groupName, Coords destination, double speed, string speedType, double altitude,
string altitudeType, string taskOptions, string category, function<void(void)> callback = []() {}) :
Command(callback),
groupName(groupName),
destination(destination),
speed(speed),
@ -139,7 +144,8 @@ private:
class Smoke : public Command
{
public:
Smoke(string color, Coords location) :
Smoke(string color, Coords location, function<void(void)> callback = [](){}) :
Command(callback),
color(color),
location(location)
{
@ -157,7 +163,8 @@ private:
class SpawnGroundUnits : public Command
{
public:
SpawnGroundUnits(string coalition, vector<SpawnOptions> spawnOptions, string country, bool immediate) :
SpawnGroundUnits(string coalition, vector<SpawnOptions> spawnOptions, string country, bool immediate, function<void(void)> callback = [](){}) :
Command(callback),
coalition(coalition),
spawnOptions(spawnOptions),
country(country),
@ -179,7 +186,8 @@ private:
class SpawnNavyUnits : public Command
{
public:
SpawnNavyUnits(string coalition, vector<SpawnOptions> spawnOptions, string country, bool immediate) :
SpawnNavyUnits(string coalition, vector<SpawnOptions> spawnOptions, string country, bool immediate, function<void(void)> callback = [](){}) :
Command(callback),
coalition(coalition),
spawnOptions(spawnOptions),
country(country),
@ -201,7 +209,8 @@ private:
class SpawnAircrafts : public Command
{
public:
SpawnAircrafts(string coalition, vector<SpawnOptions> spawnOptions, string airbaseName, string country, bool immediate) :
SpawnAircrafts(string coalition, vector<SpawnOptions> spawnOptions, string airbaseName, string country, bool immediate, function<void(void)> callback = [](){}) :
Command(callback),
coalition(coalition),
spawnOptions(spawnOptions),
airbaseName(airbaseName),
@ -221,12 +230,12 @@ private:
const bool immediate;
};
/* Spawn helicopter command */
class SpawnHelicopters : public Command
{
public:
SpawnHelicopters(string coalition, vector<SpawnOptions> spawnOptions, string airbaseName, string country, bool immediate) :
SpawnHelicopters(string coalition, vector<SpawnOptions> spawnOptions, string airbaseName, string country, bool immediate, function<void(void)> callback = [](){}) :
Command(callback),
coalition(coalition),
spawnOptions(spawnOptions),
airbaseName(airbaseName),
@ -250,7 +259,8 @@ private:
class Clone : public Command
{
public:
Clone(vector<CloneOptions> cloneOptions, bool deleteOriginal) :
Clone(vector<CloneOptions> cloneOptions, bool deleteOriginal, function<void(void)> callback = [](){}) :
Command(callback),
cloneOptions(cloneOptions),
deleteOriginal(deleteOriginal)
{
@ -268,7 +278,8 @@ private:
class Delete : public Command
{
public:
Delete(unsigned int ID, bool explosion, bool immediate ) :
Delete(unsigned int ID, bool explosion, bool immediate, function<void(void)> callback = [](){}) :
Command(callback),
ID(ID),
explosion(explosion),
immediate(immediate)
@ -289,7 +300,8 @@ private:
class SetTask : public Command
{
public:
SetTask(string groupName, string task) :
SetTask(string groupName, string task, function<void(void)> callback = [](){}) :
Command(callback),
groupName(groupName),
task(task)
{
@ -307,7 +319,8 @@ private:
class ResetTask : public Command
{
public:
ResetTask(string groupName) :
ResetTask(string groupName, function<void(void)> callback = [](){}) :
Command(callback),
groupName(groupName)
{
priority = CommandPriority::HIGH;
@ -323,7 +336,8 @@ private:
class SetCommand : public Command
{
public:
SetCommand(string groupName, string command) :
SetCommand(string groupName, string command, function<void(void)> callback = [](){}) :
Command(callback),
groupName(groupName),
command(command)
{
@ -341,7 +355,8 @@ private:
class SetOption : public Command
{
public:
SetOption(string groupName, unsigned int optionID, unsigned int optionValue) :
SetOption(string groupName, unsigned int optionID, unsigned int optionValue, function<void(void)> callback = [](){}) :
Command(callback),
groupName(groupName),
optionID(optionID),
optionValue(optionValue),
@ -351,7 +366,8 @@ public:
priority = CommandPriority::HIGH;
};
SetOption(string groupName, unsigned int optionID, bool optionBool) :
SetOption(string groupName, unsigned int optionID, bool optionBool, function<void(void)> callback = [](){}) :
Command(callback),
groupName(groupName),
optionID(optionID),
optionValue(0),
@ -375,7 +391,8 @@ private:
class SetOnOff : public Command
{
public:
SetOnOff(string groupName, bool onOff) :
SetOnOff(string groupName, bool onOff, function<void(void)> callback = [](){}) :
Command(callback),
groupName(groupName),
onOff(onOff)
{
@ -393,7 +410,8 @@ private:
class Explosion : public Command
{
public:
Explosion(unsigned int intensity, Coords location) :
Explosion(unsigned int intensity, Coords location, function<void(void)> callback = [](){}) :
Command(callback),
location(location),
intensity(intensity)
{

View File

@ -64,7 +64,8 @@ namespace State
BOMB_POINT,
CARPET_BOMB,
BOMB_BUILDING,
FIRE_AT_AREA
FIRE_AT_AREA,
SIMULATE_FIRE_FIGHT
};
};
@ -125,4 +126,9 @@ struct SpawnOptions {
struct CloneOptions {
unsigned int ID;
Coords location;
};
struct GunDataItem {
double barrelHeight;
double muzzleVelocity;
};

116
src/core/include/gundata.h Normal file
View File

@ -0,0 +1,116 @@
#pragma once
#include "framework.h"
#include "datatypes.h"
map<string, GunDataItem> gunData = {
{"2B11 mortar", {0.9, 860}},
{"SAU Gvozdika", {0.9, 860}},
{"SAU Msta", {0.9, 860}},
{"SAU Akatsia", {0.9, 860}},
{"SAU 2-C9", {0.9, 860}},
{"M-109", {0.9, 860}},
{"SpGH_Dana", {0.9, 860}},
{"AAV7", {0.9, 860}},
{"BMD-1", {0.9, 860}},
{"BMP-1", {0.9, 860}},
{"BMP-2", {0.9, 860}},
{"BMP-3", {0.9, 860}},
{"BRDM-2", {0.9, 860}},
{"BTR_D", {0.9, 860}},
{"Cobra", {0.9, 860}},
{"LAV-25", {0.9, 860}},
{"M1043 HMMWV Armament", {0.9, 860}},
{"M1045 HMMWV TOW", {0.9, 860}},
{"M1126 Stryker ICV", {0.9, 860}},
{"M-113", {0.9, 860}},
{"M1134 Stryker ATGM", {0.9, 860}},
{"M-2 Bradley", {0.9, 860}},
{"MCV-80", {0.9, 860}},
{"MTLB", {0.9, 860}},
{"Marder", {0.9, 860}},
{"TPZ", {0.9, 860}},
{"Grad_FDDM", {0.9, 860}},
{"Paratrooper RPG-16", {0.9, 860}},
{"Paratrooper AKS-74", {0.9, 860}},
{"Infantry AK Ins", {0.9, 860}},
{"Soldier AK", {0.4, 860}},
{"Infantry AK", {0.9, 860}},
{"Soldier M249", {0.9, 860}},
{"Soldier M4", {0.9, 860}},
{"Soldier M4 GRG", {0.9, 860}},
{"Soldier RPG", {0.9, 860}},
{"MLRS FDDM", {0.9, 860}},
{"Infantry AK ver2", {0.9, 860}},
{"Infantry AK ver3", {0.9, 860}},
{"Grad-URAL", {0.9, 860}},
{"Uragan_BM-27", {0.9, 860}},
{"Smerch", {0.9, 860}},
{"Smerch_HE", {0.9, 860}},
{"MLRS", {0.9, 860}},
{"Challenger2", {0.9, 860}},
{"Leclerc", {0.9, 860}},
{"M-60", {0.9, 860}},
{"M1128 Stryker MGS", {0.9, 860}},
{"M-1 Abrams", {0.9, 860}},
{"T-55", {0.9, 860}},
{"T-72B", {0.9, 860}},
{"T-80UD", {0.9, 860}},
{"T-90", {0.9, 860}},
{"Leopard1A3", {0.9, 860}},
{"Merkava_Mk4", {0.9, 860}},
{"JTAC", {0.9, 860}},
{"Infantry Animated", {0.9, 860}},
{"HL_DSHK", {0.9, 860}},
{"HL_KORD", {0.9, 860}},
{"tt_DSHK", {0.9, 860}},
{"tt_KORD", {0.9, 860}},
{"HL_B8M1", {0.9, 860}},
{"tt_B8M1", {0.9, 860}},
{"M4_Sherman", {0.9, 860}},
{"M2A1_halftrack", {0.9, 860}},
{"BTR-80", {0.9, 860}},
{"T-72B3", {0.9, 860}},
{"PT_76", {0.9, 860}},
{"BTR-82A", {0.9, 860}},
{"Chieftain_mk3", {0.9, 860}},
{"Pz_IV_H", {0.9, 860}},
{"Leopard-2A5", {0.9, 860}},
{"Leopard-2", {0.9, 860}},
{"leopard-2A4", {0.9, 860}},
{"leopard-2A4_trs", {0.9, 860}},
{"Sd_Kfz_251", {0.9, 860}},
{"T155_Firtina", {0.9, 860}},
{"VAB_Mephisto", {0.9, 860}},
{"ZTZ96B", {0.9, 860}},
{"ZBD04A", {0.9, 860}},
{"PLZ05", {0.9, 860}},
{"TYPE-59", {0.9, 860}},
{"Tiger_I", {0.9, 860}},
{"Tiger_II_H", {0.9, 860}},
{"Pz_V_Panther_G", {0.9, 860}},
{"Jagdpanther_G1", {0.9, 860}},
{"JagdPz_IV", {0.9, 860}},
{"Stug_IV", {0.9, 860}},
{"SturmPzIV", {0.9, 860}},
{"Wespe124", {0.9, 860}},
{"Sd_Kfz_234_2_Puma", {0.9, 860}},
{"soldier_mauser98", {0.9, 860}},
{"Stug_III", {0.9, 860}},
{"Elefant_SdKfz_184", {0.9, 860}},
{"Pak40", {0.9, 860}},
{"LeFH_18-40-105", {0.9, 860}},
{"Cromwell_IV", {0.9, 860}},
{"M4A4_Sherman_FF", {0.9, 860}},
{"soldier_wwii_br_01", {0.9, 860}},
{"Centaur_IV", {0.9, 860}},
{"Churchill_VII", {0.9, 860}},
{"Daimler_AC", {0.9, 860}},
{"Tetrarch", {0.9, 860}},
{"M12_GMC", {0.9, 860}},
{"soldier_wwii_us", {0.9, 860}},
{"M10_GMC", {0.9, 860}},
{"M8_Greyhound", {0.9, 860}},
{"M2A1-105", {0.9, 860}},
{"M4_Tractor", {0.9, 860}},
};

View File

@ -54,6 +54,7 @@ public:
void resetTask();
bool checkTaskFailed();
void resetTaskFailedCounter();
void setHasTaskAssigned(bool newHasTaskAssigned);
void triggerUpdate(unsigned char datumIndex);
@ -185,6 +186,7 @@ protected:
/********** Other **********/
unsigned int taskCheckCounter = 0;
bool hasTaskAssigned = false;
double initialFuel = 0;
map<unsigned char, unsigned long long> updateTimeMap;
unsigned long long lastLoopTime = 0;

View File

@ -162,7 +162,7 @@ void AirUnit::AIloop()
desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "'}";
}
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -267,7 +267,7 @@ void AirUnit::AIloop()
<< "z = " << formationOffset.z
<< "},"
<< "}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -283,7 +283,7 @@ void AirUnit::AIloop()
taskSS << "{"
<< "id = 'Refuel'"
<< "}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -297,8 +297,10 @@ void AirUnit::AIloop()
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'Bombing', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << "}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -308,8 +310,10 @@ void AirUnit::AIloop()
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'CarpetBombing', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << "}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -320,8 +324,10 @@ void AirUnit::AIloop()
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'AttackMapObject', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << "}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}

View File

@ -4,7 +4,8 @@
#include "commands.h"
#include "scheduler.h"
#include "defines.h"
#include "unitsManager.h"
#include "unitsmanager.h"
#include "gundata.h"
#include <GeographicLib/Geodesic.hpp>
using namespace GeographicLib;
@ -49,6 +50,10 @@ void GroundUnit::setState(unsigned char newState)
setTargetPosition(Coords(NULL));
break;
}
case State::SIMULATE_FIRE_FIGHT: {
setTargetPosition(Coords(NULL));
break;
}
default:
break;
}
@ -70,12 +75,16 @@ void GroundUnit::setState(unsigned char newState)
resetActiveDestination();
break;
}
case State::SIMULATE_FIRE_FIGHT: {
clearActivePath();
resetActiveDestination();
break;
}
default:
break;
}
if (newState != state)
resetTask();
resetTask();
log(unitName + " setting state from " + to_string(state) + " to " + to_string(newState));
state = newState;
@ -122,8 +131,42 @@ void GroundUnit::AIloop()
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 1000}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
}
case State::SIMULATE_FIRE_FIGHT: {
setTask("Simulating fire fight");
if (!getHasTask() || ((double)(rand()) / (double)(RAND_MAX)) < 0.01) {
double dist;
double bearing1;
double bearing2;
Geodesic::WGS84().Inverse(position.lat, position.lng, targetPosition.lat, targetPosition.lng, dist, bearing1, bearing2);
double r = 5; /* m */
/* Default gun values */
double barrelHeight = 1.0; /* m */
double muzzleVelocity = 860; /* m/s */
if (gunData.find(name) != gunData.end()) {
barrelHeight = gunData[name].barrelHeight;
muzzleVelocity = gunData[name].muzzleVelocity;
}
double barrelElevation = r * (9.81 * dist / (2 * muzzleVelocity * muzzleVelocity) - barrelHeight / dist); /* m */
double lat = 0;
double lng = 0;
double randomBearing = bearing1 + (((double)(rand()) / (double)(RAND_MAX) - 0.5) * 2) * 45;
Geodesic::WGS84().Direct(position.lat, position.lng, randomBearing, r, lat, lng);
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << lat << ", lng = " << lng << ", alt = " << barrelElevation + barrelHeight << ", radius = 0.001}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -161,4 +204,4 @@ void GroundUnit::setFollowRoads(bool newFollowRoads, bool force)
Unit::setFollowRoads(newFollowRoads, force);
resetActiveDestination(); /* Reset active destination to apply option*/
}
}
}

View File

@ -49,6 +49,10 @@ void NavyUnit::setState(unsigned char newState)
setTargetPosition(Coords(NULL));
break;
}
case State::SIMULATE_FIRE_FIGHT: {
setTargetPosition(Coords(NULL));
break;
}
default:
break;
}
@ -68,6 +72,13 @@ void NavyUnit::setState(unsigned char newState)
case State::FIRE_AT_AREA: {
clearActivePath();
resetActiveDestination();
resetTask();
break;
}
case State::SIMULATE_FIRE_FIGHT: {
clearActivePath();
resetActiveDestination();
resetTask();
break;
}
default:
@ -118,8 +129,23 @@ void NavyUnit::AIloop()
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 1000}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
}
case State::SIMULATE_FIRE_FIGHT: {
setTask("Simulating fire fight");
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 1}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}

View File

@ -61,6 +61,7 @@ void Scheduler::execute(lua_State* L)
load = command->getLoad();
commands.remove(command);
executedCommandsHashes.push_back(command->getHash());
command->executeCallback(); /* Execute the command callback (this is a lambda function that can be used to execute a function when the command is run) */
delete command;
return;
}
@ -561,6 +562,18 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
unit->setTargetPosition(loc);
log(username + " tasked unit " + unit->getName() + " to fire at area", true);
}
else if (key.compare("simulateFireFight") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
unitsManager->acquireControl(ID);
double lat = value[L"location"][L"lat"].as_double();
double lng = value[L"location"][L"lng"].as_double();
Coords loc; loc.lat = lat; loc.lng = lng;
Unit* unit = unitsManager->getGroupLeader(ID);
unit->setState(State::SIMULATE_FIRE_FIGHT);
unit->setTargetPosition(loc);
log(username + " tasked unit " + unit->getName() + " to simulate a fire fight", true);
}
else if (key.compare("setCommandModeOptions") == 0) {
setCommandModeOptions(value);
log(username + " updated the Command Mode Options", true);

View File

@ -146,8 +146,10 @@ void Unit::runAILoop() {
/* If the unit is alive, controlled, is the leader of the group and it is not a human, run the AI Loop that performs the requested commands and instructions (moving, attacking, etc) */
if (getAlive() && getControlled() && !getHuman() && getIsLeader()) {
if (checkTaskFailed() && state != State::IDLE && state != State::LAND)
if (checkTaskFailed() && state != State::IDLE && state != State::LAND) {
log(unitName + " has no task, switching to IDLE state");
setState(State::IDLE);
}
AIloop();
}
@ -397,7 +399,7 @@ void Unit::resetActiveDestination()
void Unit::resetTask()
{
Command* command = dynamic_cast<Command*>(new ResetTask(groupName));
Command* command = dynamic_cast<Command*>(new ResetTask(groupName, [this]() { this->setHasTaskAssigned(false); }));
scheduler->appendCommand(command);
setHasTask(false);
resetTaskFailedCounter();
@ -660,7 +662,7 @@ void Unit::goToDestination(string enrouteTask)
{
if (activeDestination != NULL)
{
Command* command = dynamic_cast<Command*>(new Move(groupName, activeDestination, getDesiredSpeed(), getDesiredSpeedType() ? "GS" : "CAS", getDesiredAltitude(), getDesiredAltitudeType() ? "AGL" : "ASL", enrouteTask, getCategory()));
Command* command = dynamic_cast<Command*>(new Move(groupName, activeDestination, getDesiredSpeed(), getDesiredSpeedType() ? "GS" : "CAS", getDesiredAltitude(), getDesiredAltitudeType() ? "AGL" : "ASL", enrouteTask, getCategory(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
@ -732,7 +734,7 @@ bool Unit::checkTaskFailed()
return false;
else {
if (taskCheckCounter > 0)
taskCheckCounter--;
taskCheckCounter -= hasTaskAssigned;
return taskCheckCounter == 0;
}
}
@ -741,6 +743,14 @@ void Unit::resetTaskFailedCounter() {
taskCheckCounter = TASK_CHECK_INIT_VALUE;
}
void Unit::setHasTaskAssigned(bool newHasTaskAssigned) {
hasTaskAssigned = newHasTaskAssigned;
if (hasTaskAssigned)
log(unitName + " was assigned a new task");
else
log(unitName + " no task assigned");
}
void Unit::triggerUpdate(unsigned char datumIndex) {
updateTimeMap[datumIndex] = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}