mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
feat: started implementing infrared and laser
This commit is contained in:
@@ -430,3 +430,43 @@ private:
|
|||||||
const unsigned int intensity;
|
const unsigned int intensity;
|
||||||
const string explosionType;
|
const string explosionType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Shine a laser with a specific code */
|
||||||
|
class Laser : public Command
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Laser(unsigned int ID, unsigned int code, Coords destination, function<void(void)> callback = []() {}) :
|
||||||
|
Command(callback),
|
||||||
|
ID(ID),
|
||||||
|
destination(destination),
|
||||||
|
code(code)
|
||||||
|
{
|
||||||
|
priority = CommandPriority::LOW;
|
||||||
|
};
|
||||||
|
virtual string getString();
|
||||||
|
virtual unsigned int getLoad() { return 5; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const unsigned int ID;
|
||||||
|
const unsigned int code;
|
||||||
|
const Coords destination;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Shine a infrared light */
|
||||||
|
class Infrared : public Command
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Infrared(unsigned int ID, Coords destination, function<void(void)> callback = []() {}) :
|
||||||
|
Command(callback),
|
||||||
|
ID(ID),
|
||||||
|
destination(destination)
|
||||||
|
{
|
||||||
|
priority = CommandPriority::LOW;
|
||||||
|
};
|
||||||
|
virtual string getString();
|
||||||
|
virtual unsigned int getLoad() { return 5; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const unsigned int ID;
|
||||||
|
const Coords destination;
|
||||||
|
};
|
||||||
|
|||||||
@@ -258,3 +258,28 @@ string Explosion::getString()
|
|||||||
<< location.lng;
|
<< location.lng;
|
||||||
return commandSS.str();
|
return commandSS.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Laser command */
|
||||||
|
string Laser::getString()
|
||||||
|
{
|
||||||
|
std::ostringstream commandSS;
|
||||||
|
commandSS.precision(10);
|
||||||
|
commandSS << "Olympus.laser, "
|
||||||
|
<< ID << ", "
|
||||||
|
<< code << ", "
|
||||||
|
<< destination.lat << ", "
|
||||||
|
<< destination.lng;
|
||||||
|
return commandSS.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Infrared command */
|
||||||
|
string Infrared::getString()
|
||||||
|
{
|
||||||
|
std::ostringstream commandSS;
|
||||||
|
commandSS.precision(10);
|
||||||
|
commandSS << "Olympus.infrared, "
|
||||||
|
<< ID << ", "
|
||||||
|
<< destination.lat << ", "
|
||||||
|
<< destination.lng;
|
||||||
|
return commandSS.str();
|
||||||
|
}
|
||||||
@@ -695,6 +695,37 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************/
|
/************************/
|
||||||
|
else if (key.compare("fireLaser") == 0)
|
||||||
|
{
|
||||||
|
unsigned int ID = value[L"ID"].as_integer();
|
||||||
|
Unit* unit = unitsManager->getUnit(ID);
|
||||||
|
if (unit != nullptr) {
|
||||||
|
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;
|
||||||
|
unsigned int code = value[L"code"].as_integer();
|
||||||
|
|
||||||
|
log("Adding laser with code " + to_string(code) + " from unit " + unit->getUnitName() + " to (" + to_string(lat) + ", " + to_string(lng) + ")");
|
||||||
|
|
||||||
|
command = dynamic_cast<Command*>(new Laser(ID, code, loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/************************/
|
||||||
|
else if (key.compare("fireInfrared") == 0)
|
||||||
|
{
|
||||||
|
unsigned int ID = value[L"ID"].as_integer();
|
||||||
|
Unit* unit = unitsManager->getUnit(ID);
|
||||||
|
if (unit != nullptr) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
log("Adding infrared from unit " + unit->getUnitName() + " to (" + to_string(lat) + ", " + to_string(lng) + ")");
|
||||||
|
|
||||||
|
command = dynamic_cast<Command*>(new Infrared(ID, loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/************************/
|
||||||
else if (key.compare("setCommandModeOptions") == 0)
|
else if (key.compare("setCommandModeOptions") == 0)
|
||||||
{
|
{
|
||||||
setCommandModeOptions(value);
|
setCommandModeOptions(value);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
faClone,
|
faClone,
|
||||||
faExplosion,
|
faExplosion,
|
||||||
faHand,
|
faHand,
|
||||||
|
faLightbulb,
|
||||||
faLocationCrosshairs,
|
faLocationCrosshairs,
|
||||||
faLocationDot,
|
faLocationDot,
|
||||||
faMapLocation,
|
faMapLocation,
|
||||||
@@ -887,6 +888,32 @@ export namespace ContextActions {
|
|||||||
{ type: ContextActionType.ENGAGE, code: "KeyV", ctrlKey: false, shiftKey: false }
|
{ type: ContextActionType.ENGAGE, code: "KeyV", ctrlKey: false, shiftKey: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const FIRE_LASER = new ContextAction(
|
||||||
|
"fire-laser",
|
||||||
|
"Shine laser at point",
|
||||||
|
"Click on a point to shine a laser with the given code from the unit to the ground.",
|
||||||
|
faLightbulb,
|
||||||
|
ContextActionTarget.POINT,
|
||||||
|
(units: Unit[], _, targetPosition: LatLng | null) => {
|
||||||
|
if (targetPosition)
|
||||||
|
getApp().getUnitsManager().fireLaser(targetPosition, getApp().getMap().getKeepRelativePositions(), getApp().getMap().getDestinationRotation(), units);
|
||||||
|
},
|
||||||
|
{ type: ContextActionType.ENGAGE, code: "KeyL", ctrlKey: true, shiftKey: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
export const FIRE_INFRARED = new ContextAction(
|
||||||
|
"fire-infrared",
|
||||||
|
"Shine infrared at point",
|
||||||
|
"Click on a point to shine a infrared beam from the unit to the ground.",
|
||||||
|
faLightbulb,
|
||||||
|
ContextActionTarget.POINT,
|
||||||
|
(units: Unit[], _, targetPosition: LatLng | null) => {
|
||||||
|
if (targetPosition)
|
||||||
|
getApp().getUnitsManager().fireInfrared(targetPosition, getApp().getMap().getKeepRelativePositions(), getApp().getMap().getDestinationRotation(), units);
|
||||||
|
},
|
||||||
|
{ type: ContextActionType.ENGAGE, code: "KeyL", ctrlKey: true, shiftKey: false }
|
||||||
|
);
|
||||||
|
|
||||||
export const SIMULATE_FIRE_FIGHT = new ContextAction(
|
export const SIMULATE_FIRE_FIGHT = new ContextAction(
|
||||||
"simulate-fire-fight",
|
"simulate-fire-fight",
|
||||||
"Simulate fire fight",
|
"Simulate fire fight",
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ export class TemporaryUnitMarker extends CustomMarker {
|
|||||||
el.append(unitIcon);
|
el.append(unitIcon);
|
||||||
|
|
||||||
// Short label
|
// Short label
|
||||||
|
let shortLabel: null | HTMLDivElement = null;
|
||||||
if (blueprint.category == "aircraft" || blueprint.category == "helicopter") {
|
if (blueprint.category == "aircraft" || blueprint.category == "helicopter") {
|
||||||
var shortLabel = document.createElement("div");
|
shortLabel = document.createElement("div");
|
||||||
shortLabel.classList.add("unit-short-label");
|
shortLabel.classList.add("unit-short-label");
|
||||||
shortLabel.innerText = blueprint?.shortLabel || "";
|
shortLabel.innerText = blueprint?.shortLabel || "";
|
||||||
el.append(shortLabel);
|
el.append(shortLabel);
|
||||||
@@ -88,7 +89,8 @@ export class TemporaryUnitMarker extends CustomMarker {
|
|||||||
const rotateHandle = (heading) => {
|
const rotateHandle = (heading) => {
|
||||||
el.style.transform = `rotate(${heading}deg)`;
|
el.style.transform = `rotate(${heading}deg)`;
|
||||||
unitIcon.style.transform = `rotate(-${heading}deg)`;
|
unitIcon.style.transform = `rotate(-${heading}deg)`;
|
||||||
shortLabel.style.transform = `rotate(-${heading}deg)`;
|
if (shortLabel)
|
||||||
|
shortLabel.style.transform = `rotate(-${heading}deg)`;
|
||||||
};
|
};
|
||||||
|
|
||||||
SpawnHeadingChangedEvent.on((heading) => rotateHandle(heading));
|
SpawnHeadingChangedEvent.on((heading) => rotateHandle(heading));
|
||||||
|
|||||||
@@ -192,6 +192,9 @@ export class OlympusApp {
|
|||||||
|
|
||||||
this.getServerManager().setActiveCommandMode(GAME_MASTER);
|
this.getServerManager().setActiveCommandMode(GAME_MASTER);
|
||||||
}
|
}
|
||||||
|
else if (this.getState() !== OlympusState.LOGIN) {
|
||||||
|
this.setState(OlympusState.LOGIN, LoginSubState.CREDENTIALS);
|
||||||
|
}
|
||||||
} else if (this.getState() !== OlympusState.LOGIN) {
|
} else if (this.getState() !== OlympusState.LOGIN) {
|
||||||
this.setState(OlympusState.LOGIN, LoginSubState.CREDENTIALS);
|
this.setState(OlympusState.LOGIN, LoginSubState.CREDENTIALS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -450,6 +450,18 @@ export class ServerManager {
|
|||||||
this.PUT(data, callback);
|
this.PUT(data, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fireLaser(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||||
|
var command = { ID: ID, location: latlng, code: 1688 };
|
||||||
|
var data = { fireLaser: command };
|
||||||
|
this.PUT(data, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
fireInfrared(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||||
|
var command = { ID: ID, location: latlng };
|
||||||
|
var data = { fireInfrared: 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 command = { ID: ID, location: latlng, altitude: altitude };
|
||||||
var data = { simulateFireFight: command };
|
var data = { simulateFireFight: command };
|
||||||
|
|||||||
@@ -915,6 +915,8 @@ export abstract class Unit extends CustomMarker {
|
|||||||
contextActionSet.addContextAction(this, ContextActions.CENTER_MAP);
|
contextActionSet.addContextAction(this, ContextActions.CENTER_MAP);
|
||||||
contextActionSet.addContextAction(this, ContextActions.CLONE);
|
contextActionSet.addContextAction(this, ContextActions.CLONE);
|
||||||
contextActionSet.addContextAction(this, ContextActions.ATTACK);
|
contextActionSet.addContextAction(this, ContextActions.ATTACK);
|
||||||
|
contextActionSet.addContextAction(this, ContextActions.FIRE_LASER);
|
||||||
|
contextActionSet.addContextAction(this, ContextActions.FIRE_INFRARED);
|
||||||
|
|
||||||
contextActionSet.addDefaultContextAction(this, ContextActions.MOVE);
|
contextActionSet.addDefaultContextAction(this, ContextActions.MOVE);
|
||||||
}
|
}
|
||||||
@@ -1325,6 +1327,14 @@ export abstract class Unit extends CustomMarker {
|
|||||||
getApp().getServerManager().fireAtArea(this.ID, latlng);
|
getApp().getServerManager().fireAtArea(this.ID, latlng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fireLaser(latlng: LatLng) {
|
||||||
|
getApp().getServerManager().fireLaser(this.ID, latlng);
|
||||||
|
}
|
||||||
|
|
||||||
|
fireInfrared(latlng: LatLng) {
|
||||||
|
getApp().getServerManager().fireInfrared(this.ID, latlng);
|
||||||
|
}
|
||||||
|
|
||||||
simulateFireFight(latlng: LatLng, targetGroundElevation: number | null) {
|
simulateFireFight(latlng: LatLng, targetGroundElevation: number | null) {
|
||||||
getGroundElevation(this.getPosition(), (response: string) => {
|
getGroundElevation(this.getPosition(), (response: string) => {
|
||||||
var unitGroundElevation: number | null = null;
|
var unitGroundElevation: number | null = null;
|
||||||
|
|||||||
@@ -895,6 +895,61 @@ export class UnitsManager {
|
|||||||
this.#protectionCallback = callback;
|
this.#protectionCallback = callback;
|
||||||
} else callback(units);
|
} else callback(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Instruct the selected units to fire at specific coordinates
|
||||||
|
*
|
||||||
|
* @param latlng Location to fire at
|
||||||
|
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||||
|
*/
|
||||||
|
fireLaser(latlng: LatLng, mantainRelativePosition: boolean, rotation: number = 0, units: Unit[] | null = null) {
|
||||||
|
if (units === null) units = this.getSelectedUnits();
|
||||||
|
units = units.filter((unit) => !unit.getHuman());
|
||||||
|
|
||||||
|
let callback = (units) => {
|
||||||
|
/* Compute the target for each unit. If mantainRelativePosition is true, compute the target so to hold the relative positions */
|
||||||
|
var unitTargets: { [key: number]: LatLng } = {};
|
||||||
|
if (mantainRelativePosition) unitTargets = this.computeGroupDestination(latlng, rotation);
|
||||||
|
else
|
||||||
|
units.forEach((unit: Unit) => {
|
||||||
|
unitTargets[unit.ID] = latlng;
|
||||||
|
});
|
||||||
|
units.forEach((unit: Unit) => unit.fireLaser(unitTargets[unit.ID]));
|
||||||
|
this.#showActionMessage(units, `unit shining laser at point`);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (getApp().getMap().getOptions().protectDCSUnits && !units.every((unit) => unit.isControlledByOlympus())) {
|
||||||
|
getApp().setState(OlympusState.UNIT_CONTROL, UnitControlSubState.PROTECTION);
|
||||||
|
this.#protectionCallback = callback;
|
||||||
|
} else callback(units);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Instruct the selected units to fire at specific coordinates
|
||||||
|
*
|
||||||
|
* @param latlng Location to fire at
|
||||||
|
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||||
|
*/
|
||||||
|
fireInfrared(latlng: LatLng, mantainRelativePosition: boolean, rotation: number = 0, units: Unit[] | null = null) {
|
||||||
|
if (units === null) units = this.getSelectedUnits();
|
||||||
|
units = units.filter((unit) => !unit.getHuman());
|
||||||
|
|
||||||
|
let callback = (units) => {
|
||||||
|
/* Compute the target for each unit. If mantainRelativePosition is true, compute the target so to hold the relative positions */
|
||||||
|
var unitTargets: { [key: number]: LatLng } = {};
|
||||||
|
if (mantainRelativePosition) unitTargets = this.computeGroupDestination(latlng, rotation);
|
||||||
|
else
|
||||||
|
units.forEach((unit: Unit) => {
|
||||||
|
unitTargets[unit.ID] = latlng;
|
||||||
|
});
|
||||||
|
units.forEach((unit: Unit) => unit.fireInfrared(unitTargets[unit.ID]));
|
||||||
|
this.#showActionMessage(units, `unit shining infrared at point`);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (getApp().getMap().getOptions().protectDCSUnits && !units.every((unit) => unit.isControlledByOlympus())) {
|
||||||
|
getApp().setState(OlympusState.UNIT_CONTROL, UnitControlSubState.PROTECTION);
|
||||||
|
this.#protectionCallback = callback;
|
||||||
|
} else callback(units);
|
||||||
|
}
|
||||||
|
|
||||||
/** Instruct the selected units to simulate a fire fight at specific coordinates
|
/** Instruct the selected units to simulate a fire fight at specific coordinates
|
||||||
*
|
*
|
||||||
* @param latlng Location to fire at
|
* @param latlng Location to fire at
|
||||||
|
|||||||
@@ -566,6 +566,30 @@ function Olympus.randomDebries(vec3)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Shines a laser from a unit to a point
|
||||||
|
function Olympus.fireLaser(ID, code, lat, lng)
|
||||||
|
Olympus.debug("Olympus.fireLaser " .. ID .. " -> (" .. lat .. ", " .. lng .. ") code " .. code, 2)
|
||||||
|
|
||||||
|
local vec3 = mist.utils.makeVec3GL(coord.LLtoLO(lat, lng))
|
||||||
|
|
||||||
|
local unit = Olympus.getUnitByID(ID)
|
||||||
|
if unit ~= nil and unit:isExist() then
|
||||||
|
local ray = Spot.createLaser(unit, {x = 0, y = 1, z = 0}, vec3, code)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Shines a infrared light from a unit to a point
|
||||||
|
function Olympus.fireInfrared(ID, lat, lng)
|
||||||
|
Olympus.debug("Olympus.fireInfrared " .. ID .. " -> (" .. lat .. ", " .. lng .. ")", 2)
|
||||||
|
|
||||||
|
local vec3 = mist.utils.makeVec3GL(coord.LLtoLO(lat, lng))
|
||||||
|
|
||||||
|
local unit = Olympus.getUnitByID(ID)
|
||||||
|
if unit ~= nil and unit:isExist() then
|
||||||
|
local ray = Spot.createInfraRed(unit, {x = 0, y = 1, z = 0}, vec3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Spawns a new unit or group
|
-- Spawns a new unit or group
|
||||||
-- Spawn table contains the following parameters
|
-- Spawn table contains the following parameters
|
||||||
-- category: (string), either Aircraft, Helicopter, GroundUnit or NavyUnit
|
-- category: (string), either Aircraft, Helicopter, GroundUnit or NavyUnit
|
||||||
|
|||||||
Reference in New Issue
Block a user