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:
parent
79f9905413
commit
5a4a202805
@ -430,3 +430,43 @@ private:
|
||||
const unsigned int intensity;
|
||||
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;
|
||||
};
|
||||
|
||||
@ -257,4 +257,29 @@ string Explosion::getString()
|
||||
<< location.lat << ", "
|
||||
<< location.lng;
|
||||
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)
|
||||
{
|
||||
setCommandModeOptions(value);
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
faClone,
|
||||
faExplosion,
|
||||
faHand,
|
||||
faLightbulb,
|
||||
faLocationCrosshairs,
|
||||
faLocationDot,
|
||||
faMapLocation,
|
||||
@ -887,6 +888,32 @@ export namespace ContextActions {
|
||||
{ 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(
|
||||
"simulate-fire-fight",
|
||||
"Simulate fire fight",
|
||||
|
||||
@ -67,8 +67,9 @@ export class TemporaryUnitMarker extends CustomMarker {
|
||||
el.append(unitIcon);
|
||||
|
||||
// Short label
|
||||
let shortLabel: null | HTMLDivElement = null;
|
||||
if (blueprint.category == "aircraft" || blueprint.category == "helicopter") {
|
||||
var shortLabel = document.createElement("div");
|
||||
shortLabel = document.createElement("div");
|
||||
shortLabel.classList.add("unit-short-label");
|
||||
shortLabel.innerText = blueprint?.shortLabel || "";
|
||||
el.append(shortLabel);
|
||||
@ -88,7 +89,8 @@ export class TemporaryUnitMarker extends CustomMarker {
|
||||
const rotateHandle = (heading) => {
|
||||
el.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));
|
||||
|
||||
@ -192,6 +192,9 @@ export class OlympusApp {
|
||||
|
||||
this.getServerManager().setActiveCommandMode(GAME_MASTER);
|
||||
}
|
||||
else if (this.getState() !== OlympusState.LOGIN) {
|
||||
this.setState(OlympusState.LOGIN, LoginSubState.CREDENTIALS);
|
||||
}
|
||||
} else if (this.getState() !== OlympusState.LOGIN) {
|
||||
this.setState(OlympusState.LOGIN, LoginSubState.CREDENTIALS);
|
||||
}
|
||||
|
||||
@ -450,6 +450,18 @@ export class ServerManager {
|
||||
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 = () => {}) {
|
||||
var command = { ID: ID, location: latlng, altitude: altitude };
|
||||
var data = { simulateFireFight: command };
|
||||
|
||||
@ -915,6 +915,8 @@ export abstract class Unit extends CustomMarker {
|
||||
contextActionSet.addContextAction(this, ContextActions.CENTER_MAP);
|
||||
contextActionSet.addContextAction(this, ContextActions.CLONE);
|
||||
contextActionSet.addContextAction(this, ContextActions.ATTACK);
|
||||
contextActionSet.addContextAction(this, ContextActions.FIRE_LASER);
|
||||
contextActionSet.addContextAction(this, ContextActions.FIRE_INFRARED);
|
||||
|
||||
contextActionSet.addDefaultContextAction(this, ContextActions.MOVE);
|
||||
}
|
||||
@ -1325,6 +1327,14 @@ export abstract class Unit extends CustomMarker {
|
||||
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) {
|
||||
getGroundElevation(this.getPosition(), (response: string) => {
|
||||
var unitGroundElevation: number | null = null;
|
||||
|
||||
@ -895,6 +895,61 @@ export class UnitsManager {
|
||||
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.
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @param latlng Location to fire at
|
||||
|
||||
@ -566,6 +566,30 @@ function Olympus.randomDebries(vec3)
|
||||
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
|
||||
-- Spawn table contains the following parameters
|
||||
-- category: (string), either Aircraft, Helicopter, GroundUnit or NavyUnit
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user