diff --git a/backend/core/src/groundunit.cpp b/backend/core/src/groundunit.cpp index 4cb8b6bf..717696ea 100644 --- a/backend/core/src/groundunit.cpp +++ b/backend/core/src/groundunit.cpp @@ -40,16 +40,6 @@ GroundUnit::GroundUnit(json::value json, unsigned int ID) : Unit(json, ID) void GroundUnit::setDefaults(bool force) { - if (!getAlive() || !getControlled() || getHuman() || !getIsLeader()) return; - - /* Set the default IDLE state */ - setState(State::IDLE); - - /* Set the default options */ - setROE(ROE::WEAPON_FREE, force); - setOnOff(onOff, force); - setFollowRoads(followRoads, force); - /* Load gun values from database */ if (database.has_object_field(to_wstring(name))) { json::value databaseEntry = database[to_wstring(name)]; @@ -74,6 +64,16 @@ void GroundUnit::setDefaults(bool force) if (databaseEntry.has_number_field(L"acquisitionRange")) setAcquisitionRange(databaseEntry[L"acquisitionRange"].as_number().to_double()); } + + if (!getAlive() || !getControlled() || getHuman() || !getIsLeader()) return; + + /* Set the default IDLE state */ + setState(State::IDLE); + + /* Set the default options */ + setROE(ROE::WEAPON_FREE, force); + setOnOff(onOff, force); + setFollowRoads(followRoads, force); } void GroundUnit::setState(unsigned char newState) diff --git a/backend/core/src/navyunit.cpp b/backend/core/src/navyunit.cpp index 916b00b4..f2112b59 100644 --- a/backend/core/src/navyunit.cpp +++ b/backend/core/src/navyunit.cpp @@ -37,6 +37,31 @@ NavyUnit::NavyUnit(json::value json, unsigned int ID) : Unit(json, ID) void NavyUnit::setDefaults(bool force) { + /* Load gun values from database */ + if (database.has_object_field(to_wstring(name))) { + json::value databaseEntry = database[to_wstring(name)]; + if (databaseEntry.has_number_field(L"barrelHeight")) + setBarrelHeight(databaseEntry[L"barrelHeight"].as_number().to_double()); + if (databaseEntry.has_number_field(L"muzzleVelocity")) + setMuzzleVelocity(databaseEntry[L"muzzleVelocity"].as_number().to_double()); + if (databaseEntry.has_number_field(L"aimTime")) + setAimTime(databaseEntry[L"aimTime"].as_number().to_double()); + if (databaseEntry.has_number_field(L"shotsToFire")) + setShotsToFire(databaseEntry[L"shotsToFire"].as_number().to_uint32()); + if (databaseEntry.has_number_field(L"engagementRange")) + setEngagementRange(databaseEntry[L"engagementRange"].as_number().to_double()); + if (databaseEntry.has_number_field(L"shotsBaseInterval")) + setShotsBaseInterval(databaseEntry[L"shotsBaseInterval"].as_number().to_double()); + if (databaseEntry.has_number_field(L"shotsBaseScatter")) + setShotsBaseScatter(databaseEntry[L"shotsBaseScatter"].as_number().to_double()); + if (databaseEntry.has_number_field(L"targetingRange")) + setTargetingRange(databaseEntry[L"targetingRange"].as_number().to_double()); + if (databaseEntry.has_number_field(L"aimMethodRange")) + setAimMethodRange(databaseEntry[L"aimMethodRange"].as_number().to_double()); + if (databaseEntry.has_number_field(L"acquisitionRange")) + setAcquisitionRange(databaseEntry[L"acquisitionRange"].as_number().to_double()); + } + if (!getAlive() || !getControlled() || getHuman() || !getIsLeader()) return; /* Set the default IDLE state */ diff --git a/frontend/react/src/index.css b/frontend/react/src/index.css index 0367ad24..d76df5df 100644 --- a/frontend/react/src/index.css +++ b/frontend/react/src/index.css @@ -45,3 +45,7 @@ direction: rtl !important; } +.range-circle { + filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.8)); +} + diff --git a/frontend/react/src/unit/unit.ts b/frontend/react/src/unit/unit.ts index ec4a0a0d..dbd588a7 100644 --- a/frontend/react/src/unit/unit.ts +++ b/frontend/react/src/unit/unit.ts @@ -170,6 +170,7 @@ export abstract class Unit extends CustomMarker { #contactsPolylines: Polyline[] = []; #engagementCircle: RangeCircle; #acquisitionCircle: RangeCircle; + #temporaryEngagementCircle: RangeCircle; #miniMapMarker: CircleMarker | null = null; #targetPositionMarker: TargetMarker; #targetPositionPolyline: Polyline; @@ -442,6 +443,17 @@ export abstract class Unit extends CustomMarker { interactive: false, bubblingMouseEvents: false, }); + this.#temporaryEngagementCircle = new RangeCircle(this.getPosition(), { + radius: 0, + weight: 3, + opacity: 0.8, + fillOpacity: 0.02, + dashArray: "4 8", + interactive: false, + bubblingMouseEvents: false, + color: '#f6b13b', + stroke: true + }); this.#racetrackPolylines = [ new Polyline([], { color: colors.WHITE, weight: 3, smoothFactor: 1, dashArray: "5, 5" }), @@ -511,6 +523,10 @@ export abstract class Unit extends CustomMarker { }); if (this.getSelected()) this.drawLines(); + + if (mapOptions.showUnitsEngagementRings || mapOptions.showUnitsAcquisitionRings) { + this.hideTemporaryEngagementRing(); + } }); CommandModeOptionsChangedEvent.on((commandModeOptions) => { @@ -921,12 +937,14 @@ export abstract class Unit extends CustomMarker { /* If selected, update the marker to show the selected effects, else clear all the drawings that are only shown for selected units. */ if (selected) { this.#updateMarker(); + this.showTemporaryEngagementRing(); } else { this.#clearContacts(); this.#clearPath(); this.#clearTargetPosition(); this.#clearRacetrack(); this.#clearSpots(); + this.hideTemporaryEngagementRing(); } /* When the group leader is selected, if grouping is active, all the other group members are also selected */ @@ -1604,6 +1622,25 @@ export abstract class Unit extends CustomMarker { if (!this.#human) getApp().getServerManager().setRacetrack(this.ID, length, anchor, bearing, callback); } + /** Show temporary engagement ring when unit is selected */ + showTemporaryEngagementRing() { + console.log(`Show temporary engagement ring for ${this.getUnitName()}, engagement range: ${this.#engagementRange}`); + + + if (!getApp().getMap().getOptions().showUnitsEngagementRings + && !getApp().getMap().getOptions().showUnitsAcquisitionRings + && this.#engagementRange > 0) { + this.#temporaryEngagementCircle.setLatLng(this.getPosition()); + this.#temporaryEngagementCircle.setRadius(this.#engagementRange); + this.#temporaryEngagementCircle.addTo(getApp().getMap()); + } + } + + /** Hide temporary engagement ring */ + hideTemporaryEngagementRing() { + this.#temporaryEngagementCircle.removeFrom(getApp().getMap()); + } + /***********************************************/ onAdd(map: Map): this { super.onAdd(map);