453 Commits

Author SHA1 Message Date
Pax1601
b42280133c Completed custom weapon wizard modal 2025-10-26 16:34:27 +01:00
Pax1601
94d0b4d10e Merge branch 'release-candidate' into weapon-wizard 2025-10-25 15:17:18 +02:00
Pax1601
057603f926 First implementation of weapon wizard 2025-10-23 18:07:55 +02:00
Pax1601
bfd11c49af Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-10-23 18:07:35 +02:00
Pax1601
2a9723b932 Add image overlay import modal and menu option
Introduces ImageOverlayModal for importing image overlays with user-specified corner coordinates. Adds a menu item to trigger the modal and integrates it into the main UI component. Also updates OlNumberInput to support an internalClassName prop for styling flexibility.
2025-10-23 18:06:29 +02:00
Pax1601
f565b9ee6e Add type annotations and key conversions in Map class
Improves type safety by adding explicit type annotations to method parameters and callback functions in the Map class. Updates key handling for object properties to ensure correct types, particularly when interacting with ContextActions, MapOptions, MapHiddenTypes, and destination preview markers.
2025-10-21 17:34:20 +02:00
Pax1601
504c0a0ed9 fix: Map now works with capitalized map names (thanks for creating this need Wirts :P) 2025-10-15 18:50:40 +02:00
Pax1601
c77173f7c9 Enable AAA capability for infantry and fix map layer key case
Set 'canAAA' to true for several infantry units in groundunitdatabase.json, allowing them to engage air targets. Updated map.ts to handle map layer keys in a case-insensitive manner, preventing issues with mismatched key casing.
2025-10-13 22:50:36 +02:00
Pax1601
73af60d91b Updated unit databases and new spawn loadout system 2025-10-12 15:11:55 +02:00
Pax1601
31d7fb6051 Update mist.lua 2025-09-28 12:10:20 +02:00
Pax1601
def15f5565 Merge branch 'python-api' into release-candidate 2025-09-27 18:08:13 +02:00
Pax1601
a257afca4b Add customString and customInteger to Unit data model
Introduced customString and customInteger fields to the Unit class in both backend (C++) and frontend (TypeScript/React). Updated data indexes, interfaces, and API handling to support setting and retrieving these custom fields. Also added UI elements in the unit control menu to display and handle these new properties.
2025-09-27 18:07:37 +02:00
Pax1601
dca8f9189f Merge branch 'python-api' into release-candidate 2025-09-11 21:47:29 +02:00
Pax1601
3eef91fb24 Add cargo weight and draw argument support
Introduces cargo weight and draw argument properties to units across backend, frontend, and Python API. Adds related commands, data extraction, and registration logic, enabling setting and reading of cargo weight and custom draw arguments for units. Includes new API examples and updates to interfaces, data types, and Lua backend for full feature integration.
2025-09-11 21:47:11 +02:00
Pax1601
73a7ea74f3 feat: Added threshold to unit movement 2025-09-09 18:24:53 +02:00
Pax1601
74b446d157 Updated unit database creation files 2025-08-16 17:09:32 +02:00
Pax1601
4e6701ff01 Refactor API callbacks and improve example scripts
Moved register_on_update_callback in api.py for better code organization. Fixed initialization of units_to_delete and corrected simulate_fire_fight usage in example_disembarked_infantry.py. In example_voice_control.py, added cleanup of generated audio files and fixed callback parameter naming for clarity.
2025-08-08 13:14:59 +02:00
Pax1601
5fa1a26843 Add async callbacks and Kronos integration to API
Introduces async callback support for command execution in spawn methods, adds registration/unregistration for update and startup callbacks, and improves logging and signal handling. Adds a new Kronos module and main entry point for initializing and running the API with Kronos integration. Refactors example scripts and updates VSCode launch configurations for new entry points.
2025-08-08 11:06:53 +02:00
Pax1601
151196e5f2 Merge branch 'python-api' into release-candidate 2025-08-08 10:18:01 +02:00
Pax1601
716b0dc48d Refactor unit command methods to use LatLng objects
Updated multiple methods in Unit to accept a LatLng object instead of separate lat/lng floats, improving type safety and consistency. Also made minor improvements and clarifications in the example_disembarked_infantry.py script, and added execution result handling in OlympusCommand.lua for spawned units.
2025-08-08 10:17:46 +02:00
Pax1601
c66c9242b3 Refactor Python API structure and enhance backend command handling
Major refactor of the Python API: moved modules into subdirectories, replaced app.py with api.py, and added new audio and utility modules. Backend C++ code now tracks command execution results, exposes them via the API, and improves command result handling. Also includes updates to the SRS audio handler, random string generation, and VSCode launch configurations.
2025-08-07 17:01:30 +02:00
Pax1601
8404d4d956 Merge pull request #1128 from Rob2816/release-candidate
Added groupID property to dead units
2025-08-07 11:02:19 +02:00
Rob2816
37fa86dce8 Added groupID property to dead units 2025-08-07 10:52:28 +02:00
Pax1601
4bcb5936b4 feat: Add initial API implementation and databases
Introduces a new Python API module with supporting scripts for data extraction, data types, unit management, and utility functions. Adds JSON databases for aircraft, helicopters, ground units, navy units, and mods, as well as configuration and VSCode launch settings. This provides the foundation for interacting with and managing units, spawning, and logging within the application.
2025-08-05 17:26:24 +02:00
Pax1601
4fd9b7e6c2 fix: Development build shown in release version 2025-08-05 11:05:29 +02:00
Pax1601
e4af9b06d3 fix: Ground units spawned in group are on top of each other, no heading when importing units
Units spawned via map, context menu, or unit spawn menu now include a heading property and are offset in latitude to prevent overlap. Also ensures heading is set during import/export. Minor JSX formatting improvements in UnitSpawnMenu.
2025-08-04 20:03:40 +02:00
Pax1601
89bd39cea8 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-08-04 19:37:34 +02:00
Pax1601
cd34eebcba fix: ROE not set correctly when setting defaults
Changed the default ROE value in unit.h from OPEN_FIRE_WEAPON_FREE to OPEN_FIRE. Renamed mods.png to image.png in docs/images. Removed an unnecessary blank line in the audio section of olympus.json. Bumped version in version.json from v2.0.3 to v2.0.4.
2025-08-04 19:37:32 +02:00
Pax1601
07060112bc Merge pull request #1119 from Pax1601/A-4Skyhawk-mods-doc
Example mod files for A-4 Skyhawk
2025-08-02 18:36:44 +02:00
bobprofisker
d6bcbaea7a Example mod files for A-4 Skyhawk
Example mod files that inlcude A-4 Skyhawk mods.json and mods.lua files that go into
2025-08-02 17:32:28 +01:00
Pax1601
42abb15aaf Merge branch 'main' into release-candidate 2025-08-02 15:15:01 +02:00
Pax1601
dcac0fd4f2 Added missing Iraq map 2025-08-02 15:14:48 +02:00
Pax1601
90d6acb7a4 Update README.md 2025-08-02 14:53:52 +02:00
Pax1601
2c6538663d Update README.md 2025-08-02 14:52:20 +02:00
Pax1601
280e6ecdd2 Merge branch 'release-candidate' 2025-08-02 13:03:27 +02:00
Pax1601
3ca78d4c7c Final tweaks before release 2025-08-02 12:46:27 +02:00
Pax1601
e7845dd356 Update servermanager.ts 2025-07-29 19:15:59 +02:00
Pax1601
8ef86e75f0 Disconnected page only shown after 10 seconds disconnected 2025-07-29 18:59:02 +02:00
Pax1601
de1f233848 Fixed unarmed ground units not moving 2025-07-29 17:17:15 +02:00
Pax1601
fd72d4ae2d Merge pull request #1111 from Pax1601/bugfix/wrong-unit-id-type
fix(unit): unit and group id are now of the correct type;
2025-06-02 10:16:59 +02:00
MarcoJayUsai
a112ef4aa2 fix(unit): unit and group id are now of the correct type; added DCS unitId to dead units 2025-05-30 14:01:00 +02:00
Pax1601
71750c43bd Merge pull request #1108 from Pax1601/1104-add-an-option-to-automatically-show-unit-engagement-range-when-selected
1104 add an option to automatically show unit engagement range when selected
2025-05-18 14:06:51 +02:00
MarcoJayUsai
36a80c8708 refactor: temporary engagement ring color is now the same as fixed one 2025-04-29 13:36:40 +02:00
MarcoJayUsai
600b649449 feat(map): added option to toggle display of temporary engagement rings 2025-04-28 16:22:51 +02:00
MarcoJayUsai
5237dc688a refactor: adding back country, group id and original unit id to the unit data for future uses 2025-04-28 16:14:07 +02:00
Pax1601
2ebf30e23d Merge pull request #1107 from Pax1601/bugfix/has-sensors-causing-crashes
fix: temporarily removed radarState due to hasSensors() API causing c…
2025-04-21 11:37:02 +02:00
MarcoJayUsai
dc01620b8c fix: temporarily removed radarState due to hasSensors() API causing crashes 2025-04-21 09:32:04 +02:00
MarcoJayUsai
edc3529b67 feature(map): showing ground units engagement rings when selected and no other global rings are selected 2025-04-15 22:20:15 +02:00
Pax1601
13ec455d74 fix: Searchbar threating input as username/password, inability to spawn explosion on marker 2025-04-14 22:14:40 +02:00
Pax1601
8da9249e52 Merge pull request #1106 from Pax1601/feature/navpoints-custom-icons
fix(navpoints): added missing navpoint tag information from lua
2025-04-10 18:04:30 +02:00
MarcoJayUsai
228bb7767e fix(navpoints): added missing navpoint tag information from lua 2025-04-08 22:50:11 +02:00
Pax1601
e6630171cc Merge pull request #1088 from Pax1601/features/quick-filter-rework-drawings-layers
chore: added expanding tooltip to unit category quick filter buttons
2025-04-05 20:31:36 +02:00
Pax1601
22e37ceec5 Merge branch 'release-candidate' into features/quick-filter-rework-drawings-layers 2025-04-05 20:31:20 +02:00
Pax1601
0ce800d62a Merge pull request #1097 from Pax1601/bugfix/coalition-drawings
Bugfix/coalition drawings
2025-04-05 20:29:43 +02:00
Pax1601
fa49e455c8 Merge pull request #1098 from Pax1601/feature/navpoints-custom-icons
Feature/navpoints custom icons
2025-04-05 20:29:20 +02:00
Pax1601
3964dafb9e fix: Commander mode not working if AWACS reference coalition different from commanded coalition 2025-04-05 20:27:40 +02:00
MarcoJayUsai
24015686ea feature(navpoints): navpoint marked as TGT have a special icon. Styles reworked. 2025-04-03 14:43:38 +02:00
MarcoJayUsai
77ceae21e1 chore: removed comments 2025-04-03 09:25:52 +02:00
Pax1601
874e01b031 Update audiomanager.ts
fix: Audio menu frequencies list not working, radios reset when changing input/output
2025-04-01 21:04:53 +02:00
MarcoJayUsai
e6ef6cd05b fix(drawings): not initializing empty layers 2025-04-01 15:01:51 +02:00
MarcoJayUsai
ddab28f874 fix(drawings): coalition commanders will not see enemy coalition drawings and navpoints 2025-04-01 14:46:56 +02:00
MarcoJayUsai
2d7db0bf5e chore: added expanding tooltip to unit category quick filter buttons 2025-04-01 12:34:07 +02:00
Pax1601
5d274a3efb chore: Bumped version number 2025-03-31 22:43:27 +02:00
Pax1601
84b3e3dac4 feat: Added more docs to ingame wiki 2025-03-31 22:25:16 +02:00
Davide Passoni
78c655e2f7 feat: Added threat rings to spawn tool 2025-03-31 15:59:27 +02:00
Davide Passoni
de495cc71d feat: added unit ranges on spawn menu 2025-03-31 15:36:38 +02:00
Davide Passoni
c034c19176 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-31 15:10:05 +02:00
Davide Passoni
7f8d240bed fix: Removed incorrect help string in compact effect spawn menu 2025-03-31 15:09:56 +02:00
Pax1601
624b29ab84 Merge pull request #1084 from Pax1601/features/quick-filter-rework-drawings-layers
refactor(map): unit category quick filter now will reset view by ctrl…
2025-03-31 15:07:23 +02:00
Davide Passoni
e877d9f8e4 fix: added missing fire effect 2025-03-31 15:06:20 +02:00
MarcoJayUsai
43284c46db refactor(map): unit category quick filter now will reset view by ctrl clicking a shown category
Also added the ability to parse drawings sublayer by reading a tag prefixed to drawing name (e.g. [TAGNAME] DrawingName)
2025-03-31 15:05:23 +02:00
Davide Passoni
cf7aa05ec0 feat: Added error message if admin password wrong
Improved looks of admin panel
2025-03-31 12:55:45 +02:00
Davide Passoni
fd2a63c530 fix: Radio menu names being squashed when too long 2025-03-31 12:23:00 +02:00
Davide Passoni
266326c40c fix: Added callback to close all tooltips on click 2025-03-31 11:29:00 +02:00
Davide Passoni
1bca2e5c26 fix: "Follow roads" toggle available for navy units 2025-03-31 11:14:06 +02:00
Pax1601
64e4e7f301 Merge pull request #1083 from Pax1601/airborne
Airborne
2025-03-31 11:07:20 +02:00
Davide Passoni
2d0e10bc0b fix: not airborne units no longer targeted, racetracks not drawn for airborne units 2025-03-31 11:06:57 +02:00
Pax1601
1248ffb60b feat: added airborne variable 2025-03-31 08:14:17 +02:00
Pax1601
825d60e754 Merge pull request #1073 from Pax1601/drawings-refinements
Drawings refinements
2025-03-30 10:34:50 +02:00
Pax1601
f392b08392 Merge pull request #1075 from Pax1601/1074-qol-unit-type-exclusive-filter
1074 qol unit type exclusive filter
2025-03-30 10:33:46 +02:00
Pax1601
aee1f21cd6 Merge pull request #1077 from Pax1601/1076-qol-add-selected-map-source-to-session-data
feat(map): session data is now saving selected map source
2025-03-30 10:33:04 +02:00
MarcoJayUsai
c1aadece29 feat(map): session data is now saving selected map source 2025-03-29 11:33:01 +01:00
MarcoJayUsai
fbc598e3aa fix(coordinates): MGRS are now separed properly 2025-03-28 22:21:03 +01:00
MarcoJayUsai
b600b2503b fix(state buttons): state buttons hovering styles will be applied instantly 2025-03-28 20:11:35 +01:00
MarcoJayUsai
011ccc0a99 feature(map): added ability to exclusively show unit types 2025-03-28 19:47:40 +01:00
MarcoJayUsai
3814052fd9 feat(navpoints): added header button to quick toggle navpoints drawing 2025-03-28 19:21:59 +01:00
MarcoJayUsai
0558227ce6 refactor(drawings): reduced the zoom of the go to drawing feature 2025-03-28 19:16:09 +01:00
Davide Passoni
0452a8081b feat: Added material to quick reference guide 2025-03-28 17:07:38 +01:00
Davide Passoni
bdf9c83053 feat: Added starred spawns to spawn menu and ability to remove starred spawns 2025-03-27 17:10:27 +01:00
Davide Passoni
3c02802807 feat: Added selection tools to unit list in unit control menu 2025-03-27 16:22:25 +01:00
Davide Passoni
ffddb9cd1e fix: Removed accidental development feature in unit spawn men
Also bumped version to 2.0.1
2025-03-27 15:46:32 +01:00
Davide Passoni
55f75ff149 feat: added nightly link to manager to update without github account
added ability to force beta version
2025-03-27 13:27:50 +01:00
Davide Passoni
c9b143b5e0 feat: Multiple improvements to audio backend 2025-03-27 13:16:39 +01:00
Pax1601
9cbfa2a8aa Merge pull request #1072 from Pax1601/1054-drawings-control-panel-separate-global-mission-drawings-control-from-navpoints-control
1054 drawings control panel separate global mission drawings control from navpoints control
2025-03-26 16:48:39 +01:00
MarcoJayUsai
3635837495 Merge remote-tracking branch 'origin/release-candidate' into 1054-drawings-control-panel-separate-global-mission-drawings-control-from-navpoints-control 2025-03-26 16:17:29 +01:00
MarcoJayUsai
3f1fde2398 feature(drawings): searched drawings (or navpoints) container will auto open if containing a match 2025-03-26 16:13:58 +01:00
Pax1601
c2489d638a Merge pull request #1071 from Pax1601/1053-drawings-control-panel-make-shown-hidden-states-more-obvious
refactor(drawings): changed styles for visible / hidden drawing layers
2025-03-26 16:06:22 +01:00
Davide Passoni
0d246c7c25 feat: Added ability to change command mode, improved local connection detection 2025-03-26 16:05:06 +01:00
MarcoJayUsai
1db8736391 fix(drawings): drawings filtering utility made case insensitive 2025-03-26 15:58:07 +01:00
MarcoJayUsai
3067100562 feature(drawings): added drawings filtering by string and go to drawing feature 2025-03-26 15:51:36 +01:00
MarcoJayUsai
fca63fb103 feature(drawings): Navpoints settings saved in session data 2025-03-26 15:21:17 +01:00
MarcoJayUsai
1262c85802 feature(drawings): Navpoints separated from Drawings
Known issue: navpoints settings are not saved in session, to be fixed.
2025-03-26 14:30:24 +01:00
MarcoJayUsai
d0f5be7269 refactor(drawings): changed styles for visible / hidden drawing layers 2025-03-26 14:01:48 +01:00
Davide Passoni
4062e69661 fix: Incorrect "Development build" string in header 2025-03-26 12:24:19 +01:00
Davide Passoni
bb0ded2b46 fix: "Don't show again" tickbox not being respected 2025-03-26 12:15:28 +01:00
Davide Passoni
49990e01ee fix: Fixed manager not respecting autoconnectwhentrue and srsport settings 2025-03-26 11:40:02 +01:00
Davide Passoni
3d61b7e1a7 Fix: aligned airbase spawn menu to other menus 2025-03-26 10:33:11 +01:00
Davide Passoni
7ae15239b1 fix: Context menu shown when dragging handles 2025-03-26 10:24:46 +01:00
Davide Passoni
589479ba56 fix: Aligned tanker orbit behaviour 2025-03-26 10:15:10 +01:00
Davide Passoni
40aa6fcfdc fix: Quick box selection causes units to be immediately deselected 2025-03-26 09:48:12 +01:00
Pax1601
41b4328eaf fix: Unable to clone units if game master with spawn restrictions on
Other minor graphical fixes
2025-03-25 19:30:00 +01:00
Pax1601
bc65bf546f feat: added support for callsigns 2025-03-25 13:05:40 +01:00
Pax1601
f91daed25e fix: Missing options in preferences causing inconsistent states 2025-03-25 11:51:05 +01:00
Pax1601
a1f6a50a46 fix: Added favicon 2025-03-25 11:44:06 +01:00
Pax1601
8a9c319e45 fix: Scenic state toggles not being respected 2025-03-25 11:41:05 +01:00
Pax1601
8e55051410 fix: Unit targets not being shown 2025-03-25 09:58:37 +01:00
Pax1601
b20134f8f1 fix: sessionData not being saved after mission reload 2025-03-25 09:37:55 +01:00
Pax1601
6af6545f09 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-24 23:03:40 +01:00
Pax1601
9fc1519ef6 fix: Improved audio quality of radio 2025-03-24 23:03:28 +01:00
Pax1601
039c922649 Merge pull request #1043 from Pax1601/features/redgreen-unit
Features/redgreen unit
2025-03-24 23:02:20 +01:00
Pax1601
70b6143fd9 Merge branch 'release-candidate' into features/redgreen-unit 2025-03-24 23:02:04 +01:00
Pax1601
8cce77c4d3 fix: Complete implementation of alarm state 2025-03-24 22:59:41 +01:00
Pax1601
7573720398 fix: Minor fix on commented debug string 2025-03-24 21:17:41 +01:00
Pax1601
2b5b428237 fix: Added setting of forced AlarmState 2025-03-24 21:07:08 +01:00
MarcoJayUsai
1622d663bb feat(alarm state): refactor to separe alarm state from radar state. Kown issue: alarm state is not correctly mantained 2025-03-24 18:42:04 +01:00
Davide Passoni
eff96ce0c2 feat: Control scheme improvement 2025-03-24 16:55:40 +01:00
Pax1601
0b8fb969b2 fix: Added option to upload hidden files 2025-03-23 16:50:34 +01:00
Pax1601
c66086d64f fix: missing else in mod units code 2025-03-23 16:06:38 +01:00
Pax1601
8eaebb5d22 chore: updated setup-node action 2025-03-23 15:40:48 +01:00
Pax1601
c33afa5215 fix: Humans can be exploded 2025-03-22 19:27:41 +01:00
Pax1601
3e19c84c8e Merge pull request #1044 from Pax1601/features/DDM-coordinates
feat(coordinates): added DDM format
2025-03-22 19:09:27 +01:00
Pax1601
3b075ec276 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-22 19:03:05 +01:00
Pax1601
2fd8752050 feat: better handling of mods payloads 2025-03-22 19:03:02 +01:00
MarcoJayUsai
45f828c838 feat(map): added coordinates copy feature 2025-03-22 12:33:34 +01:00
MarcoJayUsai
d35e6063e7 feat(coordinates): added DDM format 2025-03-22 10:21:08 +01:00
MarcoJayUsai
f7e9fc5cbc Merge branch 'release-candidate' into features/redgreen-unit 2025-03-22 09:18:16 +01:00
MarcoJayUsai
b7bf89ce2f chore: removed useless code 2025-03-22 09:15:48 +01:00
MarcoJayUsai
a733c98259 refactor: removed unused code 2025-03-22 09:12:53 +01:00
MarcoJayUsai
efd7c3cec9 chore: removed comments 2025-03-22 09:10:53 +01:00
Davide Passoni
7155429dc7 fix: Added databases copy step in build scripts 2025-03-21 17:40:25 +01:00
Davide Passoni
326fbff982 fix: Incorrect representation of some ground unit markers 2025-03-21 17:12:20 +01:00
MarcoJayUsai
3a44608e2b Merge remote-tracking branch 'origin/release-candidate' into features/redgreen-unit 2025-03-21 16:47:47 +01:00
MarcoJayUsai
f1fcabe7f7 feat(alarm state): alarm state command is now working in DCS 2025-03-21 16:21:35 +01:00
Davide Passoni
3ab10af98b feat: Added unit clustering and other small performance and loadtime improvements 2025-03-21 16:11:57 +01:00
MarcoJayUsai
2a00bab149 feat(alarm state): added unit control panel buttons (WIP) 2025-03-21 12:33:15 +01:00
Pax1601
99e742498d fix: error in spawn menu, fixed smoke not working 2025-03-20 19:30:40 +01:00
Davide Passoni
b3e53d07dd fix: Added missing commander restrictions 2025-03-20 17:30:28 +01:00
Davide Passoni
69e8fed623 fix: Scenic AAA not stopping when target out of range 2025-03-20 16:53:23 +01:00
Davide Passoni
0765459cfd feat: Added wiki modes to audio, drawing and gamemaster menus.
Feat: improved looks of gamemaster menu
2025-03-20 16:51:58 +01:00
Davide Passoni
791b1fc4ab fix: Login modal rendered twice
Also added ability to login by username or by role
2025-03-20 10:49:07 +01:00
Davide Passoni
0ef5de51c4 fix: Drawings visibility not aligned with map option 2025-03-19 17:39:59 +01:00
Davide Passoni
2d26862b6c fix: Error in admin panel inputs fixed, plus improvements to modal panels 2025-03-19 17:23:17 +01:00
Davide Passoni
f058958c13 fix: Coalition of unit bullseye info toggle now working 2025-03-19 16:33:10 +01:00
Davide Passoni
48d64078d8 fix: fixed wiki mode for small screens 2025-03-19 16:23:27 +01:00
MarcoJayUsai
18960ca51e feat(radar state): radar state is now being read from DCS and displayed as a dot (subject to change) 2025-03-19 14:36:40 +01:00
Davide Passoni
4350cd93e5 fix: Minor package updates
Possible breaking change for Vite, to be monitored
2025-03-19 12:59:00 +01:00
Pax1601
3c33d3883e fix: Small fixes to responsive design 2025-03-18 16:14:39 +01:00
MarcoJayUsai
ee15106be1 feat(radar state): initial scaffolding 2025-03-18 14:42:46 +01:00
Pax1601
50f3882b3e fix: "Alt" keybinds getting stuck when switching windows with alt+tab 2025-03-18 13:02:12 +01:00
Pax1601
cf86c4ade9 fix: minor improvements to miss on purpose mode 2025-03-18 12:53:22 +01:00
Pax1601
ddf9883f89 fix: Reverted some changes to miss on purpose mode 2025-03-18 11:05:33 +01:00
Pax1601
8ffcbaa05b Merge branch 'laser-fix' into release-candidate 2025-03-18 11:00:10 +01:00
Pax1601
dd2856a993 fix: Laser and infrared correctly removed 2025-03-18 10:58:35 +01:00
Davide Passoni
c44caa9cea feat: small change to flak mode miss on purpose 2025-03-17 16:54:33 +01:00
Pax1601
3aafa26c70 feat: New predicting algorithm 2025-03-16 22:33:28 +01:00
Pax1601
e2ac37ef18 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-14 18:43:25 +01:00
Pax1601
3d33319a19 fix: minor changes to databases 2025-03-14 18:43:10 +01:00
Davide Passoni
83e3c8b681 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-14 16:46:19 +01:00
Davide Passoni
f0826bbdba fix: Fixed multiple errors in scenic AAA modes 2025-03-14 16:45:46 +01:00
Pax1601
6d5eb05f0b Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-13 20:50:55 +01:00
Pax1601
f77b008701 feat: Updated database for flak 2025-03-13 20:50:51 +01:00
Davide Passoni
5acc0e8ac5 fix: Audio backend working if both port and endpoint added
Added ability to use uri for backend address (remote debugging)
2025-03-13 16:54:16 +01:00
Davide Passoni
760fe18cc7 fix: Autoconnect when local checkbox not reflecting configuration 2025-03-13 09:39:34 +01:00
Pax1601
34f9a8bc40 feat: Improvements on scenic modes 2025-03-12 18:43:14 +01:00
Davide Passoni
23f9eee39f fix: Fixed error in SRS coalition 2025-03-11 16:28:26 +01:00
Davide Passoni
46f2ff4403 feat: added proxyHeader and comments to config file 2025-03-11 16:25:16 +01:00
Davide Passoni
386d5298a2 feat: added admin password and admin modal 2025-03-10 17:16:02 +01:00
Davide Passoni
9a7af84cd4 feat: databases handled by Olympus, only mods database is under user control 2025-03-07 17:16:06 +01:00
Davide Passoni
403280aa22 Merge branch 'release-candidate' of https://github.com/Pax1601/DCSOlympus into release-candidate 2025-03-07 16:39:36 +01:00
Davide Passoni
d90ef540f9 fix: added compatibility checks with v1.0.4 2025-03-07 16:39:33 +01:00
Davide Passoni
f1fb3073d2 Update settings.ejs 2025-03-07 16:14:45 +01:00
Davide Passoni
be879e3660 feat: added ability to change and check SRS port in manager 2025-03-07 16:14:42 +01:00
Pax1601
e9112e5be6 Merge pull request #1014 from Pax1601/features/navpoints
Features/navpoints
2025-03-07 14:48:18 +01:00
Davide Passoni
42cfb36c04 Added checkbox for autoconnection when local 2025-03-07 14:45:01 +01:00
MarcoJayUsai
6e7b5b1cc3 feat(navpoints): added navpoint sublayers 2025-03-07 12:36:10 +01:00
MarcoJayUsai
8e20499b92 feat(drawings): added navpoints 2025-03-07 12:00:43 +01:00
Davide Passoni
16e77087f5 fix: Removed unnecessary entries from sidebar and header, fixed non working main menu links 2025-03-07 11:12:17 +01:00
Davide Passoni
eed91e8486 fix: Update old version of workflow package 2025-03-07 09:42:56 +01:00
Davide Passoni
016c2d45f6 Merge branch 'v2' into release-candidate 2025-03-07 09:29:23 +01:00
Davide Passoni
0a5a507f70 Merge branch 'v2' of https://github.com/Pax1601/DCSOlympus into v2 2025-03-06 17:45:31 +01:00
Davide Passoni
8406619868 feat: started working on wiki entries and tooltips, minor fixes and improvements to presentation 2025-03-06 17:45:20 +01:00
MarcoJayUsai
3142a438f7 fix(drawings): added keys to drawing menu elements 2025-03-06 17:14:05 +01:00
MarcoJayUsai
94fe8488e4 refactor(drawings): added global drawing lines thickness normalization 2025-02-28 14:33:31 +01:00
Davide Passoni
8aac6b7d7e feat: Aligned orbits representation, added visibility option 2025-02-26 12:05:59 +01:00
Davide Passoni
c7ff73f8a6 fix: Saving in progress spinner pushing load/export buttons right 2025-02-26 10:49:48 +01:00
Davide Passoni
2ab072c929 fix: Dropdowns getting reset periodically 2025-02-26 10:46:57 +01:00
Davide Passoni
d4a06e9edb Fixed measure bug, added middle mouse click shortcut 2025-02-26 10:39:08 +01:00
Davide Passoni
b2477112b1 Completed first iteration of drawings management on v2 2025-02-26 09:39:30 +01:00
Davide Passoni
1a93ee68d0 fix: Check for protected units not working for control panel 2025-02-06 17:31:27 +01:00
Davide Passoni
1deeaacf1d feat: added grouped path markers
fix: fixed shortcuts getting stuck
2025-02-06 16:28:23 +01:00
Davide Passoni
52606b8d57 feat: completed measure handling 2025-02-03 17:27:19 +01:00
Davide Passoni
627c4b5584 feat: started working at measuring tool 2025-01-31 17:25:14 +01:00
Davide Passoni
a65a5a5bed fix: Groups emptied correctly when all units are killed 2025-01-31 16:16:56 +01:00
Davide Passoni
4f927faeb4 fix: Fixed wrong server code activation 2025-01-30 16:23:19 +01:00
Davide Passoni
9525982161 feat: added laser code change, target move, and delete
Note: deleted lasers are not removed from table and keep being drawn. Also added a cooler looking server page
2025-01-30 16:20:31 +01:00
Davide Passoni
cc902aec04 feat: started adding editable laser/infrared 2025-01-29 17:25:09 +01:00
Davide Passoni
74e2332b17 fix: fixed error in credentials management 2025-01-29 11:13:55 +01:00
Pax1601
5a4a202805 feat: started implementing infrared and laser 2025-01-29 08:03:32 +01:00
Davide Passoni
79f9905413 feat: completed orbit management 2025-01-28 09:47:44 +01:00
Davide Passoni
c2ea746d48 feat: started adding ability to set and draw racetracks 2025-01-24 17:33:27 +01:00
Davide Passoni
96415fd087 Feat: added backend ability to set spawn heading 2025-01-24 15:01:25 +01:00
Davide Passoni
d1d4116e66 feat: Added unit spawn heading selection 2025-01-24 10:55:57 +01:00
Davide Passoni
6074367300 fix: better color management of unit markers 2025-01-23 12:54:20 +01:00
Davide Passoni
b711872d6c feat: Added indicator for "operate as" units 2025-01-23 12:01:38 +01:00
Davide Passoni
20db9647bd fix: Toolbar button color different when hovering and selected 2025-01-23 10:58:11 +01:00
Davide Passoni
d31aa30da8 feat: added coalition selection for audio manager 2025-01-22 12:53:48 +01:00
Davide Passoni
cde33fdd76 fix: Spawn effect menu uses same logic as unit spawn, fixed airbase spawn menu 2025-01-22 11:21:42 +01:00
Davide Passoni
1374f270eb Feat: text to speech source controls PTT of connected sinks 2025-01-20 17:24:50 +01:00
Davide Passoni
77a7397f1c fix: added missing setting of volume to node 2025-01-20 17:15:49 +01:00
Davide Passoni
e6a564ff61 feat: added volume slider for radios 2025-01-20 17:09:37 +01:00
Davide Passoni
6e5e1914ec feat: Added advanced settings menu 2025-01-20 17:01:44 +01:00
Davide Passoni
5b6f58a38e feat: completed formation menu 2025-01-20 15:07:58 +01:00
Davide Passoni
9bd206a750 Added warning modals 2025-01-13 15:11:49 +01:00
Davide Passoni
0c391df69f feat: added missing carriers data 2025-01-13 11:31:40 +01:00
Davide Passoni
711f6094f0 feat: Improved formation menu 2025-01-13 09:36:43 +01:00
Davide Passoni
0376d020e7 feat: Implemented import/export page 2025-01-07 15:36:36 +01:00
Davide Passoni
c9c34f013f fix: hotgroup button updated when unit dies 2024-12-20 16:21:35 +01:00
Davide Passoni
5797b9d209 feat: added starred spawns to session data 2024-12-20 15:43:54 +01:00
Davide Passoni
71e47bce0b feat: Unit hotgroups saved to sessiondata 2024-12-19 15:43:27 +01:00
Davide Passoni
1c86ba1d4c feat: Drawings added to sessiondata 2024-12-19 14:50:12 +01:00
Davide Passoni
ffeecfbf9e feat: Created coalitionareamanager, fixed areas creation and management 2024-12-18 17:50:11 +01:00
Davide Passoni
416f0d3e36 fix: solved breaking error on production with draggable paths in leaflet 2024-12-18 14:22:19 +01:00
Davide Passoni
2bbcbc5576 feat: added simple radio effect and left/right panner 2024-12-17 18:51:30 +01:00
Davide Passoni
dbd87d5724 Fix: temporary fix for srtm error 2024-12-17 16:06:06 +01:00
Davide Passoni
17cd42a1a0 chore: cleanup of dependencies 2024-12-17 15:38:13 +01:00
Davide Passoni
c2d5d4ea17 feat: Implemented server mode 2024-12-16 17:24:02 +01:00
Davide Passoni
032b74b57b feat: better toolbar descriptions 2024-12-12 17:06:28 +01:00
Davide Passoni
f84b560351 fix: map sources not being loaded correctly in static version 2024-12-12 16:56:11 +01:00
Davide Passoni
8006d639ae fix: magvar used for BE calls
fix: unit summary labels
2024-12-12 16:43:24 +01:00
Davide Passoni
89abcb3330 fix: breaking change with new node version 2024-12-12 15:02:25 +01:00
Davide Passoni
8208316fb9 chore: switch to google cloud text to speech 2024-12-12 14:36:14 +01:00
Davide Passoni
6250f760a9 chore: updated dependencies of server 2024-12-12 13:27:35 +01:00
Davide Passoni
d7edb00254 Merge branch '961-hotkeys-get-stuck' into v2 2024-12-11 18:21:47 +01:00
Davide Passoni
e6d2d906e1 fix: flashing spawn context menu 2024-12-11 18:20:13 +01:00
Pax1601
76efe84be6 Merge pull request #985 from Pax1601/961-hotkeys-get-stuck
961 hotkeys get stuck
2024-12-11 18:08:14 +01:00
Davide Passoni
7fe9b0d19f fix: buttons and actions no longer getting stuck
fix: context menu resizes if accordion is opened
feat: added expanding descriptions for context actions
2024-12-11 18:06:59 +01:00
Davide Passoni
e9896963ca Merge branch 'v2' into 961-hotkeys-get-stuck 2024-12-11 14:38:38 +01:00
Davide Passoni
da2152f0e3 fix: I have a good feeling for relative imports this time 2024-12-11 10:37:19 +01:00
Davide Passoni
dc7fd2c870 fix: will I ever make relative paths work? 2024-12-11 10:22:53 +01:00
Pax1601
e41d3c93a6 fix: error in code for audiomanager address 2024-12-10 20:44:20 +01:00
Pax1601
7684461edb Merge branch 'v2' of https://github.com/Pax1601/DCSOlympus into v2 2024-12-10 20:42:32 +01:00
Pax1601
c618a36072 fix: wrong audio address 2024-12-10 20:40:47 +01:00
Davide Passoni
dd7e34178a chore: more trials for relative image paths 2024-12-10 17:48:34 +01:00
Davide Passoni
95505ec9fa chore: fixed images relative imports for static build 2024-12-10 17:42:57 +01:00
Pax1601
8d7aa5df65 Merge pull request #972 from Pax1601/966-implement-toolbar-and-add-copypaste-as-context-actions
feat: implemented map toolbar
2024-12-10 16:59:26 +01:00
Davide Passoni
8f00e8a9e2 feat: implemented map toolbar 2024-12-10 16:58:51 +01:00
Davide Passoni
ce129691a7 chore: Removed temporary audio backend address 2024-12-09 15:32:04 +01:00
Pax1601
3d204af60f Merge pull request #965 from Pax1601/962-show-action-specific-cursor-when-action-is-active
962 show action specific cursor when action is active
2024-12-09 14:11:30 +01:00
Davide Passoni
00d7b451ec feat: added specific cursors for different context actions and spawns 2024-12-09 14:10:34 +01:00
Davide Passoni
96899121f7 chore: switched all urls to relative paths 2024-12-09 10:18:58 +01:00
Pax1601
a4452aee94 fix: Units are spawned at 0,0 2024-12-07 16:34:00 +01:00
Pax1601
f80321a267 fix: wrong path for units silhouettes 2024-12-07 10:27:36 +01:00
Pax1601
2391977082 fix: wrong images path for units 2024-12-07 10:25:28 +01:00
Pax1601
7a0504227b fix: changed images path to relative 2024-12-07 10:23:04 +01:00
Davide Passoni
4278c6fa9a fix: More missing files commit 2024-12-06 18:02:07 +01:00
Davide Passoni
db4e9870b0 fix: Missing file commit 2024-12-06 18:01:38 +01:00
Davide Passoni
be439be264 feat: updated index position 2024-12-06 17:59:09 +01:00
Davide Passoni
1f60f51898 feat: Moved base vite location 2024-12-06 17:57:09 +01:00
Davide Passoni
a899c5ffca feat: setup app for static compilation
Breaking change!: initDraggablePath disabled because it breaks the app
2024-12-06 17:47:08 +01:00
Davide Passoni
ffade5fb8e (fix): More general address calculation 2024-12-06 17:09:57 +01:00
Davide Passoni
b57d6b305a fix: Default users can be used again 2024-12-06 16:22:02 +01:00
Davide Passoni
786729c006 fix: Login prompt crashing app 2024-12-06 15:25:40 +01:00
Davide Passoni
258d21672c feat: Added custom authentication headers support
bugfix: Fixed incorrect saving of quick access spawn
refactor: Removed compactunitspawnmenu and condensed in single unitspawnmenu class to reuse code
2024-12-05 19:37:38 +01:00
Pax1601
c11a9728e8 Minor fix 2024-12-03 20:34:31 +01:00
Pax1601
c8da3e6da3 Added check on audio interval 2024-12-03 20:14:16 +01:00
Pax1601
f17ee42d63 Implemented session data for audio 2024-12-03 18:54:30 +01:00
Davide Passoni
5e40d7abf1 Started work on persistent session data 2024-12-01 12:40:07 +01:00
Pax1601
42e62be0f5 Started google cloud tests 2024-11-28 20:08:43 +01:00
Davide Passoni
dd641fc2aa Initial tests on sppech synthesis 2024-11-28 17:49:09 +01:00
Davide Passoni
8580c5c62b Fixed error in profiles reset 2024-11-27 17:48:34 +01:00
Davide Passoni
b4841872ca More work on AWACS mode 2024-11-27 17:36:32 +01:00
Davide Passoni
a92d4403d7 Merge branch 'v2' of https://github.com/Pax1601/DCSOlympus into v2 2024-11-27 11:28:33 +01:00
Davide Passoni
8cd18eb921 Adding AWACS graphical mode 2024-11-27 11:28:30 +01:00
Pax1601
8bcf564f07 Merge branch 'v2' of https://github.com/Pax1601/DCSOlympus into v2 2024-11-27 08:10:18 +01:00
Pax1601
264c381bc3 Started automatic AWACS call generation 2024-11-27 08:10:06 +01:00
Davide Passoni
7813f8335a WIP disabled awacs tools 2024-11-25 15:15:54 +01:00
Davide Passoni
1791eaa37d Started adding AWACS panel 2024-11-23 17:18:16 +01:00
Davide Passoni
897afb2fef Multiple bugfixes 2024-11-22 14:56:26 +01:00
Pax1601
5c3960868a Update coordinatespanel.tsx 2024-11-21 21:23:38 +01:00
Pax1601
376a63b363 Minor radio panel changes 2024-11-21 20:55:28 +01:00
Davide Passoni
402a1457aa Major controls rework 2024-11-21 17:35:51 +01:00
Pax1601
73c8ce2fe7 Minor bugfixes 2024-11-20 08:09:00 +01:00
Davide Passoni
38f6788fa8 Added spawn context menu and controls rework 2024-11-19 17:45:46 +01:00
Pax1601
430d8db15d Tweaked kiowa short label 2024-11-16 11:20:09 +01:00
Pax1601
f1eae9685f Minor changes to short labels 2024-11-16 11:18:48 +01:00
Pax1601
17c71eb4ed Updated database with Chinook 2024-11-16 11:16:52 +01:00
Pax1601
4bbe5eb2f8 Possibly fixed unreadable radio when transmitting on two frequencies 2024-11-15 09:08:54 +01:00
Davide Passoni
c8e1f76b38 Fixed IADS creation and added livery/skill selection for units 2024-11-14 17:23:16 +01:00
Davide Passoni
fa215142ad Fixed radios not working, added mouse coordinates panel, started readding tips 2024-11-13 17:13:30 +01:00
Pax1601
b97713f8cc Fixed error in express address 2024-11-12 16:56:51 +01:00
Pax1601
53237c6197 Added different address for express backend 2024-11-12 16:50:01 +01:00
Pax1601
9d225bfc1a Added starred spawns 2024-11-12 16:35:01 +01:00
Davide Passoni
68980651dc Added keybinding menu and server side profiles 2024-11-11 17:07:12 +01:00
Pax1601
62af0f74e7 Readded camera plugin, hotgroups, fixed smoke spawning 2024-11-10 12:27:01 +01:00
Pax1601
fc8b0d9f7a Merge pull request #939 from NimbusPulse/fix/frontend-path-traversal
Frontend: Fix possible path traversal
2024-11-10 09:14:49 +01:00
Pax1601
95e18f6503 Added hotkeys 2024-11-09 18:22:21 +01:00
Pax1601
c2b0849fb6 Added default categories to databases 2024-11-08 20:43:09 +01:00
Pax1601
a89861128c Fixed missing category error 2024-11-08 20:42:31 +01:00
Pax1601
4e84a97367 Added ability to rotate movement path 2024-11-08 19:55:37 +01:00
Davide Passoni
644404c4e6 Readded context menus 2024-11-08 17:04:01 +01:00
Davide Passoni
df939f1ac3 Readded command mode options 2024-11-07 17:39:34 +01:00
Davide Passoni
454c7ad2de Merge branch 'refactoring' of https://github.com/Pax1601/DCSOlympus into refactoring 2024-11-07 10:05:32 +01:00
Davide Passoni
bf7115288b More work adding back missing functions 2024-11-07 10:05:27 +01:00
Pax1601
2530d6dd78 Reimplemented changes before merge 2024-11-06 20:12:41 +01:00
Davide Passoni
6d551c51eb Merge branch 'refactoring' of https://github.com/Pax1601/DCSOlympus into refactoring 2024-11-06 17:33:01 +01:00
Davide Passoni
636803b2ac Large rework of events and state 2024-11-06 17:32:31 +01:00
Pax1601
475b04eff7 Completed adding events 2024-10-29 07:54:58 +01:00
Pax1601
7f5873b5b8 More refactoring of events 2024-10-28 07:53:09 +01:00
Davide Passoni
14c0a2f1e8 Refactored app state 2024-10-21 19:02:33 +02:00
Pax1601
4946807d88 Switched to using constants for colors 2024-10-20 17:01:28 +02:00
Pax1601
7fa39561e3 Multiple small improvements and bugfixes 2024-10-19 10:53:43 +02:00
Davide Passoni
0c5139f5ee Started working on JTAC tools 2024-10-18 20:17:04 +02:00
Pax1601
58f114bba0 Changed shape of distance volume curve 2024-10-15 21:01:22 +02:00
Davide Passoni
065cdf3648 Completed the audio panel 2024-10-15 17:40:39 +02:00
Timm Ortloff
03bd14d3fe databases.js: Fix possible path traversal 2024-10-15 04:20:50 +02:00
Pax1601
6cc1572b11 More tests 2024-10-12 18:34:20 +02:00
Davide Passoni
4947997a0c Added explosions, protection screen and delete unit 2024-10-12 17:13:41 +02:00
Pax1601
44bd054a3d Merge pull request #938 from Pax1601/follow-tool
Follow tool
2024-10-10 14:35:50 +02:00
Davide Passoni
b13689c09a Completed formation tool 2024-10-10 14:35:14 +02:00
Pax1601
e11f4a6c11 Started adding scale sliders 2024-10-10 07:52:33 +02:00
Pax1601
12b9337026 Added limiter to peak meter 2024-10-09 18:41:40 +02:00
Davide Passoni
10a76c47ff Added custom formation tool 2024-10-09 18:30:13 +02:00
Pax1601
b282e5d676 Added handling of urls for audio manager address 2024-10-08 14:29:59 +02:00
Pax1601
ef48147322 Added port read 2024-10-08 14:27:25 +02:00
Pax1601
804743c051 Moved audio sink toggle to unit control panel 2024-10-08 13:59:07 +02:00
Pax1601
84a1375663 Removed unused website folder 2024-10-08 08:32:30 +02:00
Pax1601
88cf20a4d9 Small bugfixes from preview on server 2024-10-08 08:30:26 +02:00
Pax1601
0003363d71 Merge pull request #937 from Pax1601/srs-integration
Added packetID handling
2024-10-07 21:39:29 +02:00
Pax1601
914d4a4a28 Merge branch 'v2' into srs-integration 2024-10-07 21:39:23 +02:00
Pax1601
4078759310 Added packetID handling 2024-10-07 21:36:14 +02:00
Davide Passoni
e94d296de2 Create 633052.jpg 2024-10-07 18:01:04 +02:00
Davide Passoni
01897019b0 More work on audio system, started adding carrier icon 2024-10-07 18:00:44 +02:00
Pax1601
fc00a4eac4 Merge pull request #935 from Pax1601/srs-integration
Srs integration
2024-09-09 12:31:55 +02:00
Davide Passoni
abd561a60d Completed first implementation of SRS integration 2024-09-09 12:30:54 +02:00
Pax1601
d774977387 First version of external sounds 2024-09-09 08:06:03 +02:00
Davide Passoni
5726d6dee2 More work on external audio sources, started adding generic audio packet handling 2024-09-06 18:12:09 +02:00
Pax1601
9c2ce526d3 Added track controls 2024-09-05 22:35:08 +02:00
Pax1601
9bbcdac704 More work on audio 2024-09-04 19:41:05 +02:00
Davide Passoni
a64ccab15f More work on sources 2024-09-03 20:19:11 +02:00
Pax1601
b352bc824c More work on SRS backend for radio playback and recording 2024-09-02 07:51:51 +02:00
Davide Passoni
ba2c48dead First tests and integration of radio panel 2024-08-31 10:12:25 +02:00
Davide Passoni
ebfa7916c6 Added airbase info and spawn menu 2024-08-29 15:31:16 +02:00
Davide Passoni
fd15406f5d Unit control menu only opens automatically if screen is wide 2024-08-08 15:49:22 +02:00
Davide Passoni
19b0eeeffd Fixed error preventing operation on touch screen for position actions 2024-08-08 15:39:38 +02:00
Davide Passoni
6fdfb194a6 Implemented context menu and multiple control tweaks 2024-08-08 15:32:59 +02:00
Pax1601
7cf77a63be Added deep copy of radio and tacan objects 2024-08-07 15:48:25 +02:00
Pax1601
2e77de95cc Fixed wrong awacs/tanker callsign 2024-08-07 15:45:52 +02:00
Pax1601
2476dac810 Fixed minor errors in tanker/AWACS options 2024-08-07 15:41:51 +02:00
Pax1601
0b2ee1df9b Merge pull request #933 from Pax1601/890-add-tanker-advanced-settings
890 add tanker advanced settings
2024-08-07 15:34:40 +02:00
Pax1601
224dc5a688 Completed advanced settings panel for tanker and AWACS
Reformatted files with larger width, reordered unused icons
2024-08-07 15:32:39 +02:00
Davide Passoni
bc5049992a Started working on tanker and AWACS settings 2024-08-05 17:07:58 +02:00
Pax1601
cc686e2320 Merge pull request #920 from Pax1601/v2
V2
2024-08-05 16:14:53 +02:00
Pax1601
040476107a Merge pull request #919 from Pax1601/904-add-unit-loadoutfuelhealth-panel-to-unit-control-panel
904 add unit loadoutfuelhealth panel to unit control panel
2024-08-05 16:07:14 +02:00
Davide Passoni
57f3b84f20 Added fuel and loadout panel, also added search tool 2024-08-05 16:05:51 +02:00
Davide Passoni
b021ddaf11 Started implementing panel, missing loadout summary 2024-08-02 17:33:48 +02:00
Pax1601
e7418a8d6c Merge pull request #917 from Pax1601/910-add-controls-explanation-section
Closes #910 add controls explanation section
2024-08-02 17:04:55 +02:00
Davide Passoni
9174353b09 Styling completed, controls to be added as functionality is added 2024-08-02 17:03:46 +02:00
Pax1601
e1a566d0d3 Merge pull request #914 from Pax1601/906-add-ability-to-draw-coalition-areas
906 add ability to draw coalition areas
2024-08-02 14:33:06 +02:00
Davide Passoni
a3e92580c2 Completed creation of areas 2024-08-02 13:17:42 +02:00
Pax1601
86e0e6b3a3 Started adding controls panel for shortcuts, more work on better polygon creation, added circles creation 2024-08-01 09:02:21 +02:00
Davide Passoni
1e72f15876 More work on coalition areas drawing 2024-07-31 08:34:59 +02:00
Davide Passoni
2d90c359f7 Added ability to draw coalition areas (WIP) 2024-07-26 17:00:09 +02:00
Pax1601
b993786301 Merge pull request #913 from Pax1601/912-implement-build-scripts-for-reactvite
912 implement build scripts for reactvite
2024-07-26 11:17:11 +02:00
Davide Passoni
faccf48ecd Update package.json 2024-07-25 13:08:31 +02:00
Davide Passoni
c0b43c916e Fixed minor errors in build scripts 2024-07-25 12:35:17 +02:00
Davide Passoni
473f16dda0 Updated react and server build scripts to operate with new UI 2024-07-25 11:38:36 +02:00
Davide Passoni
03de0f9175 Updated build scripts for react website 2024-07-25 10:41:56 +02:00
Davide Passoni
aa7db94750 Merge branch 'v2' into 912-implement-build-scripts-for-reactvite 2024-07-25 10:27:35 +02:00
Davide Passoni
bd3ac54ff8 Update map.ts 2024-07-25 10:23:43 +02:00
Davide Passoni
287f634f74 Merge branch 'release-candidate' into v2 2024-07-25 09:14:00 +02:00
Pax1601
81b1bf0335 Fixed public folder 2024-07-09 08:38:55 +02:00
Davide Passoni
867dff6945 Transitioned server to typescript 2024-07-09 08:02:40 +02:00
Pax1601
98862d917c Added check on map zooming to disable box select 2024-07-07 19:12:56 +02:00
Pax1601
1dceb0b421 Added ability to box select with long press 2024-07-07 19:10:02 +02:00
Davide Passoni
fbc22676c5 Added box selection for mobiles and ability to drag markers, units can be moved only via context action 2024-07-05 17:26:53 +02:00
Davide Passoni
61e52efc07 Added ability to hide spawn menu 2024-07-05 12:12:21 +02:00
Pax1601
fa48d1f905 More work on small screens 2024-07-03 19:38:32 +02:00
Davide Passoni
5f3dbbf94e Added settings for linting 2024-07-03 09:57:51 +02:00
Davide Passoni
96b3e2f115 More work on responsive design for small screens 2024-07-02 17:36:53 +02:00
Davide Passoni
00e2da2aab Reformatted project using prettier plugin 2024-07-01 17:43:46 +02:00
Davide Passoni
1acb7d6762 Work on reactive design 2024-07-01 15:51:43 +02:00
Davide Passoni
b3f8eb96ad Added automatic removal of vite proxy 2024-06-28 11:29:44 +02:00
Davide Passoni
36478f26d5 Added ability to preview on proxy 2024-06-28 11:25:30 +02:00
Davide Passoni
e07bf98e62 Re-enabled login page 2024-06-28 11:09:29 +02:00
Davide Passoni
cd38a2f053 Added context buttons, temporary fixes to allow preview 2024-06-28 11:04:18 +02:00
Pax1601
329e9b86fd Merge branch 'v2' of https://github.com/Pax1601/DCSOlympus into v2 2024-06-27 20:02:59 +02:00
Pax1601
1e48df85a7 Fixed callback error on loading of URi 2024-06-27 20:02:53 +02:00
Davide Passoni
8cb8f7e108 More work on context actions 2024-06-27 17:35:10 +02:00
Davide Passoni
222a296b4f Readded map options, simplified ShortcutManager 2024-06-27 14:46:28 +02:00
Davide Passoni
fb96926d1e Merge branch 'release-candidate' into v2 2024-06-27 11:41:52 +02:00
Pax1601
13e75e9dd1 Configuration change 2024-06-14 19:08:10 +02:00
Davide Passoni
79016d72e3 More work on unit context actions 2024-06-11 16:19:29 +02:00
Davide Passoni
b089a8cfd8 Merge branch 'react-transition-test' into v2 2024-06-07 11:46:40 +02:00
Davide Passoni
a9f4353e4a Fixed error in spawn menu (unable to select coalition) and cropped unit images for spawn menu 2024-06-07 11:34:51 +02:00
Davide Passoni
4acbe375a7 Small change in how units are represented in the unit spawn menu 2024-06-07 08:56:00 +02:00
Davide Passoni
a9a6b18943 Added minimap summary panel 2024-06-06 17:14:07 +02:00
Davide Passoni
9c53e0605b Merge branch 'release-candidate' into v2 2024-06-06 12:09:52 +02:00
Davide Passoni
0c93b950c6 Updated launch tasks for auto installation 2024-05-28 10:20:50 +02:00
Pax1601
53a43b5536 More work on new ui 2024-05-18 17:51:22 +02:00
Dogma
3e465509e9 Updated login to include Olympus Logo 2024-05-07 21:52:39 +10:00
Dogma
79c8e743d9 Misc Changes [Login]
- Updated styling
- Added image back in to bg
- Updated card styling
- Updated bg opacity
- Updated callouts
- Modified login elements
- Removed guide buton
2024-05-03 15:23:55 +10:00
Dogma
0f882c9c33 Small Tweak [Login]
- Small update to size of login window
2024-05-03 00:22:54 +10:00
Dogma
3ddafa4fff Additional responsive changes [Login]
- Updated responsive design for login screen to go fill the entire screen when on small screen sizes i.e. mobile
2024-05-03 00:20:10 +10:00
Dogma
5c4b09735a Updated Callout Component
- Added variations of callout component
- Updated error messaging on login
2024-05-02 23:55:49 +10:00
Davide Passoni
f5aca98e49 More work on login connection logic 2024-05-02 10:05:12 +02:00
Dogma
2cb3287d1f Minor update to login
- Fixed up password field not filling container
2024-05-02 16:41:29 +10:00
Dogma
b96254c9f2 Further work on login screen
- Added Cards on right side
- Fixed up placement of privacy notice
- Fixed responsiveness
2024-05-02 16:38:51 +10:00
Dogma
f6fbd5c931 Minor fixes missed in last change
- Woops lol
2024-05-01 21:48:57 +10:00
Dogma
e622067230 Updated UI of Login Screen
- Fixed styling
- Added first layer of responsive design
2024-05-01 21:46:10 +10:00
Pax1601
c4e484706a Started working on login panel 2024-05-01 11:57:51 +02:00
Dogma
37a89e4548 Multiple updates
- Added bottom buttons to sidebar
- Fixed up various UI issues
- Added options panel that now works
2024-04-18 14:59:23 +10:00
Dogma
d0e0d851db Small UI Tweaks
I updated a bunch of things because I can - mainly for consistency etc
2024-04-18 00:28:26 +10:00
Dogma
9df0fb9425 Updated background colours for menu
- Updated colours to include blur effect
- Looks cool, fight me
2024-04-17 23:39:00 +10:00
Dogma
c6300b3e6a Updated IP and Link to be dynamic
IP Address of server and connection status is now sourced from 'olympusapp'  and automatically updates status in the header.
2024-04-17 19:03:59 +10:00
Davide Passoni
6296bdc2d8 Small tweak to setupApp callback 2024-04-16 17:28:52 +02:00
Dogma
627c19e550 Updates to header
- Add Connected message to header
- Updated control panel heading
2024-04-16 22:13:27 +10:00
Dogma
dcacf617d7 Added SAM image to SAM Sites 2024-04-16 21:23:03 +10:00
Dogma
fceb27505d Updated Control Menu UI
- Updated Unit Selected bar to fix padding and font
2024-04-15 23:03:18 +10:00
Dogma
4b431a7f90 Various UI Tweaks
- Various UI Tweaks
- Added hover states to many components
2024-04-15 22:50:18 +10:00
Dogma
413285f03d Main Menu Updated
- Main Menu updated to include dividers and subtext
- Heading of menu updated to fix padding
2024-04-15 22:07:58 +10:00
Dogma
8a3db4083f Updated Main Menu
- Updated iconography
- Included animation
- Adjusted colours etc
2024-04-15 21:41:51 +10:00
Dogma
f847d4713b Update lock to default locked
As above
2024-04-15 21:14:00 +10:00
Dogma
15bec68fc4 Updated Heading Round Buttons
- Updated iconography on some Round Buttons (coalition toggle)
- Added new type: LockStateButton
- New LockStateButton is setup to automatically switch icon whether it's checked or not at the component level and no longer expects icon to be provided.
2024-04-15 21:13:26 +10:00
Dogma
58b5eacdb7 Minor updates to components
- Minor changes to components such as label and number changer
2024-04-15 20:35:27 +10:00
Dogma
95f8eb0976 Various UI Changes
- Various UI Changes and fixes to various components and panels
- Added formatting to Altitude Control to include comma automatically
2024-04-15 19:59:04 +10:00
Dogma
c3fb3fa9c1 Updates to control menu
- Updated UI for control menu
2024-04-14 23:20:30 +10:00
Dogma
73bf1da061 Updated Panel Colours, Main Menu
- Updated the colours of all panels to match new Olympus values
- Updated button colours and included hover state
- Updated Main Menu
2024-04-14 23:08:06 +10:00
Dogma
e040ecfce2 Various Small UI Tweaks
- Adjustments to a number of UI components, including Label Toggle, Spawn menu, Dropdowns etc
2024-04-14 22:36:20 +10:00
Dogma
32f5f01f5c Updated Unit Spawn Menu
- UI Updates to Unit Spawn Menu
2024-04-14 21:48:35 +10:00
Dogma
b4e217548e Updated Font and Unit Summary
- Font updated to Inter
- UI Changes to Unit Summary Component
2024-04-14 21:38:10 +10:00
Dogma
dab1d4a97c Merge branch 'react-transition-test' of https://github.com/Pax1601/DCSOlympus into react-transition-test 2024-04-14 20:40:24 +10:00
Dogma
8d21149db7 Added Olympus Colours
- Added Olympus Colours
- First commit yay
2024-04-14 20:39:02 +10:00
Pax1601
288df71970 Started working on unit spawning 2024-04-14 12:34:38 +02:00
Davide Passoni
40df2ebb7d More work on unit control panel 2024-04-12 17:53:03 +02:00
Davide Passoni
c7ecd2422a Started working on unit control panel, typed props 2024-04-11 17:29:23 +02:00
Pax1601
f18212dac4 More wore on components 2024-04-11 08:10:34 +02:00
Davide Passoni
45e290d656 More work on React components 2024-04-09 18:12:05 +02:00
Pax1601
8e9e6749db More tests on react components 2024-04-08 08:49:05 +02:00
Pax1601
f056cc62a8 More work on flowbite components 2024-04-06 15:42:53 +02:00
Davide Passoni
90ccf57f01 Testing work with flowbite 2024-04-05 17:50:59 +02:00
Pax1601
d72a00a005 Started readding old core frontend code 2024-04-03 08:05:36 +02:00
Pax1601
5d5c650162 Added state and events context 2024-04-02 15:18:10 +02:00
Davide Passoni
42c7a36da7 Started building react app 2024-03-30 08:40:02 +01:00
1619 changed files with 239517 additions and 97145 deletions

View File

@@ -23,7 +23,7 @@ jobs:
vcpkg integrate install
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
- name: Build
working-directory: .
@@ -31,15 +31,16 @@ jobs:
shell: cmd
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4.6.1
with:
name: development_build_not_a_release
path: ./package
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4.6.1
with:
name: zip_only_package
path: ./zip
include-hidden-files: true

3
.gitignore vendored
View File

@@ -40,3 +40,6 @@ frontend/website/plugins/controltips/index.js
*.pyc
/scripts/**/*.jpg
manager/manager.log
/frontend/server/public
/frontend/server/build
/frontend/react/.vite

View File

@@ -28,9 +28,7 @@ Check the [Wiki](https://github.com/Pax1601/DCSOlympus/wiki) for installation in
### I need troubleshooting guidance, please help? ###
Read through the [Installation Guide](https://github.com/Pax1601/DCSOlympus/wiki) to ensure you have setup Olympus correctly.
Read through [Setup Troubleshooting](https://github.com/Pax1601/DCSOlympus/wiki/Setup-Troubleshooting) for common issues and solutions.
Read through the [Olympus User Guide](https://github.com/Pax1601/DCSOlympus/wiki/2.-User-Guide) to learn how to use Olympus.
Read through [Setup Troubleshooting](https://github.com/Pax1601/DCSOlympus/wiki/3.-Setup-FAQ-and-Troubleshooting) for common issues and solutions.
If you're still having issues after trying the steps above, please post in the community-support channel with the following:

View File

@@ -61,7 +61,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,4,0
FILEVERSION 2,0,0,0
PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -79,12 +79,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DCS Olympus"
VALUE "FileDescription", "DCS Olympus"
VALUE "FileVersion", "1.0.4.0"
VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "core.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "core.dll"
VALUE "ProductName", "DCS Olympus"
VALUE "ProductVersion", "1.0.4.0"
VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -18,6 +18,12 @@ public:
virtual void changeSpeed(string change) = 0;
virtual void changeAltitude(string change) = 0;
virtual double getDestinationReachedThreshold() { return AIR_DEST_DIST_THR; }
virtual void setRacetrackLength(double newValue);
virtual void setRacetrackAnchor(Coords newValue);
virtual void setRacetrackBearing(double newValue);
virtual void setCargoWeight(double newValue);
protected:
virtual void AIloop();

View File

@@ -5,6 +5,11 @@
#include "logger.h"
#include "datatypes.h"
struct CommandResult {
string hash;
string result;
};
namespace CommandPriority {
enum CommandPriorities { LOW, MEDIUM, HIGH, IMMEDIATE };
};
@@ -18,6 +23,7 @@ namespace SetCommandType {
FORMATION = 5,
RTB_ON_BINGO = 6,
SILENCE = 7,
ALARM_STATE = 9,
RTB_ON_OUT_OF_AMMO = 10,
ECM_USING = 13,
PROHIBIT_AA = 14,
@@ -45,6 +51,14 @@ namespace ROE {
};
}
namespace AlarmState {
enum AlarmStates {
AUTO = 0,
GREEN = 1,
RED = 2,
};
}
namespace ReactionToThreat {
enum ReactionsToThreat {
NO_REACTION = 0,
@@ -430,3 +444,138 @@ private:
const unsigned int intensity;
const string explosionType;
};
/* Shine a laser with a specific code */
class FireLaser : public Command
{
public:
FireLaser(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 FireInfrared : public Command
{
public:
FireInfrared(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;
};
/* Change a laser code */
class SetLaserCode : public Command
{
public:
SetLaserCode(unsigned int spotID, unsigned int code, function<void(void)> callback = []() {}) :
Command(callback),
spotID(spotID),
code(code)
{
priority = CommandPriority::LOW;
};
virtual string getString();
virtual unsigned int getLoad() { return 5; }
private:
const unsigned int spotID;
const unsigned int code;
};
/* Delete a spot code */
class DeleteSpot : public Command
{
public:
DeleteSpot(unsigned int spotID, function<void(void)> callback = []() {}) :
Command(callback),
spotID(spotID)
{
priority = CommandPriority::LOW;
};
virtual string getString();
virtual unsigned int getLoad() { return 5; }
private:
const unsigned int spotID;
};
/* Move spot to a new target */
class MoveSpot : public Command
{
public:
MoveSpot(unsigned int spotID, Coords destination, function<void(void)> callback = []() {}) :
Command(callback),
spotID(spotID),
destination(destination)
{
priority = CommandPriority::LOW;
};
virtual string getString();
virtual unsigned int getLoad() { return 5; }
private:
const unsigned int spotID;
const Coords destination;
};
/* Set cargo weight */
class SetCargoWeight : public Command
{
public:
SetCargoWeight(unsigned int ID, double weight, function<void(void)> callback = []() {}) :
Command(callback),
ID(ID),
weight(weight)
{
priority = CommandPriority::LOW;
};
virtual string getString();
virtual unsigned int getLoad() { return 5; }
private:
const unsigned int ID;
const double weight;
};
/* Register draw argument */
class RegisterDrawArgument : public Command
{
public:
RegisterDrawArgument(unsigned int ID, unsigned int argument, bool active, function<void(void)> callback = []() {}) :
Command(callback),
ID(ID),
argument(argument),
active(active)
{
priority = CommandPriority::LOW;
};
virtual string getString();
virtual unsigned int getLoad() { return 5; }
private:
const unsigned int ID;
const unsigned int argument;
const bool active;
};

View File

@@ -7,6 +7,8 @@ namespace DataIndex {
startOfData = 0,
category,
alive,
alarmState,
radarState,
human,
controlled,
coalition,
@@ -14,6 +16,8 @@ namespace DataIndex {
name,
unitName,
callsign,
unitID,
groupID,
groupName,
state,
task,
@@ -51,6 +55,25 @@ namespace DataIndex {
shotsScatter,
shotsIntensity,
health,
racetrackLength,
racetrackAnchor,
racetrackBearing,
timeToNextTasking,
barrelHeight,
muzzleVelocity,
aimTime,
shotsToFire,
shotsBaseInterval,
shotsBaseScatter,
engagementRange,
targetingRange,
aimMethodRange,
acquisitionRange,
airborne,
cargoWeight,
drawArguments,
customString,
customInteger,
lastIndex,
endOfData = 255
};
@@ -140,6 +163,11 @@ namespace DataTypes {
unsigned int ID = 0;
unsigned char detectionMethod = 0;
};
struct DrawArgument {
unsigned int argument = 0;
double value = 0.0;
};
}
#pragma pack(pop)
@@ -148,6 +176,7 @@ bool operator==(const DataTypes::Radio& lhs, const DataTypes::Radio& rhs);
bool operator==(const DataTypes::GeneralSettings& lhs, const DataTypes::GeneralSettings& rhs);
bool operator==(const DataTypes::Ammo& lhs, const DataTypes::Ammo& rhs);
bool operator==(const DataTypes::Contact& lhs, const DataTypes::Contact& rhs);
bool operator==(const DataTypes::DrawArgument& lhs, const DataTypes::DrawArgument& rhs);
struct SpawnOptions {
string unitType;
@@ -155,6 +184,8 @@ struct SpawnOptions {
string loadout;
string skill;
string liveryID;
double heading;
string payload;
};
struct CloneOptions {

View File

@@ -17,7 +17,7 @@ public:
virtual void setOnOff(bool newOnOff, bool force = false);
virtual void setFollowRoads(bool newFollowRoads, bool force = false);
void aimAtPoint(Coords aimTarget);
string aimAtPoint(Coords aimTarget);
protected:
virtual void AIloop();

View File

@@ -13,7 +13,14 @@ public:
void execute(lua_State* L);
void handleRequest(string key, json::value value, string username, json::value& answer);
bool checkSpawnPoints(int spawnPoints, string coalition);
bool isCommandExecuted(string commandHash) { return (find(executedCommandsHashes.begin(), executedCommandsHashes.end(), commandHash) != executedCommandsHashes.end()); }
bool isCommandExecuted(string commandHash) {
for (auto& commandResult : executedCommandResults) {
if (commandResult.hash == commandHash) {
return true;
}
}
return false;
}
void setFrameRate(double newFrameRate) { frameRate = newFrameRate; }
void setRestrictSpawns(bool newRestrictSpawns) { restrictSpawns = newRestrictSpawns; }
@@ -36,7 +43,7 @@ public:
private:
list<Command*> commands;
list<string> executedCommandsHashes;
list<CommandResult> executedCommandResults;
unsigned int load = 0;
double frameRate = 0;

View File

@@ -62,9 +62,12 @@ public:
bool hasFreshData(unsigned long long time);
bool checkFreshness(unsigned char datumIndex, unsigned long long time);
unsigned int computeTotalAmmo();
/********** Setters **********/
virtual void setCategory(string newValue) { updateValue(category, newValue, DataIndex::category); }
virtual void setAlive(bool newValue) { updateValue(alive, newValue, DataIndex::alive); }
virtual void setAlarmState(unsigned char newValue, bool force = false);
virtual void setHuman(bool newValue) { updateValue(human, newValue, DataIndex::human); }
virtual void setControlled(bool newValue) { updateValue(controlled, newValue, DataIndex::controlled); }
virtual void setCoalition(unsigned char newValue) { updateValue(coalition, newValue, DataIndex::coalition); }
@@ -72,6 +75,8 @@ public:
virtual void setName(string newValue) { updateValue(name, newValue, DataIndex::name); }
virtual void setUnitName(string newValue) { updateValue(unitName, newValue, DataIndex::unitName); }
virtual void setCallsign(string newValue) { updateValue(callsign, newValue, DataIndex::callsign); }
virtual void setUnitID(unsigned int newValue) { updateValue(unitID, newValue, DataIndex::unitID); }
virtual void setGroupID(unsigned int newValue) { updateValue(groupID, newValue, DataIndex::groupID); }
virtual void setGroupName(string newValue) { updateValue(groupName, newValue, DataIndex::groupName); }
virtual void setState(unsigned char newValue) { updateValue(state, newValue, DataIndex::state); };
virtual void setTask(string newValue) { updateValue(task, newValue, DataIndex::task); }
@@ -109,10 +114,31 @@ public:
virtual void setShotsScatter(unsigned char newValue) { updateValue(shotsScatter, newValue, DataIndex::shotsScatter); }
virtual void setShotsIntensity(unsigned char newValue) { updateValue(shotsIntensity, newValue, DataIndex::shotsIntensity); }
virtual void setHealth(unsigned char newValue) { updateValue(health, newValue, DataIndex::health); }
virtual void setRacetrackLength(double newValue) { updateValue(racetrackLength, newValue, DataIndex::racetrackLength); }
virtual void setRacetrackAnchor(Coords newValue) { updateValue(racetrackAnchor, newValue, DataIndex::racetrackAnchor); }
virtual void setRacetrackBearing(double newValue) { updateValue(racetrackBearing, newValue, DataIndex::racetrackBearing); }
virtual void setTimeToNextTasking(double newValue) { updateValue(timeToNextTasking, newValue, DataIndex::timeToNextTasking); }
virtual void setBarrelHeight(double newValue) { updateValue(barrelHeight, newValue, DataIndex::barrelHeight); }
virtual void setMuzzleVelocity(double newValue) { updateValue(muzzleVelocity, newValue, DataIndex::muzzleVelocity); }
virtual void setAimTime(double newValue) { updateValue(aimTime, newValue, DataIndex::aimTime); }
virtual void setShotsToFire(unsigned int newValue) { updateValue(shotsToFire, newValue, DataIndex::shotsToFire); }
virtual void setShotsBaseInterval(double newValue) { updateValue(shotsBaseInterval, newValue, DataIndex::shotsBaseInterval); }
virtual void setShotsBaseScatter(double newValue) { updateValue(shotsBaseScatter, newValue, DataIndex::shotsBaseScatter); }
virtual void setEngagementRange(double newValue) { updateValue(engagementRange, newValue, DataIndex::engagementRange); }
virtual void setTargetingRange(double newValue) { updateValue(targetingRange, newValue, DataIndex::targetingRange); }
virtual void setAimMethodRange(double newValue) { updateValue(aimMethodRange, newValue, DataIndex::aimMethodRange); }
virtual void setAcquisitionRange(double newValue) { updateValue(acquisitionRange, newValue, DataIndex::acquisitionRange); }
virtual void setRadarState(bool newValue) { updateValue(radarState, newValue, DataIndex::radarState); }
virtual void setAirborne(bool newValue) { updateValue(airborne, newValue, DataIndex::airborne); }
virtual void setCargoWeight(double newValue) { updateValue(cargoWeight, newValue, DataIndex::cargoWeight); }
virtual void setDrawArguments(vector<DataTypes::DrawArgument> newValue);
virtual void setCustomString(string newValue) { updateValue(customString, newValue, DataIndex::customString); }
virtual void setCustomInteger(unsigned long newValue) { updateValue(customInteger, newValue, DataIndex::customInteger); }
/********** Getters **********/
virtual string getCategory() { return category; };
virtual string getCategory() { return category; }
virtual bool getAlive() { return alive; }
virtual unsigned char getAlarmState() { return alarmState; }
virtual bool getHuman() { return human; }
virtual bool getControlled() { return controlled; }
virtual unsigned char getCoalition() { return coalition; }
@@ -121,6 +147,8 @@ public:
virtual string getCallsign() { return callsign; }
virtual string getUnitName() { return unitName; }
virtual string getGroupName() { return groupName; }
virtual unsigned int getUnitID() { return unitID; }
virtual unsigned int getGroupID() { return groupID; }
virtual unsigned char getState() { return state; }
virtual string getTask() { return task; }
virtual bool getHasTask() { return hasTask; }
@@ -157,6 +185,26 @@ public:
virtual unsigned char getShotsScatter() { return shotsScatter; }
virtual unsigned char getShotsIntensity() { return shotsIntensity; }
virtual unsigned char getHealth() { return health; }
virtual double getRacetrackLength() { return racetrackLength; }
virtual Coords getRacetrackAnchor() { return racetrackAnchor; }
virtual double getRacetrackBearing() { return racetrackBearing; }
virtual double getTimeToNextTasking() { return timeToNextTasking; }
virtual double getBarrelHeight() { return barrelHeight; }
virtual double getMuzzleVelocity() { return muzzleVelocity; }
virtual double getAimTime() { return aimTime; }
virtual unsigned int getShotsToFire() { return shotsToFire; }
virtual double getShotsBaseInterval() { return shotsBaseInterval; }
virtual double getShotsBaseScatter() { return shotsBaseScatter; }
virtual double getEngagementRange() { return engagementRange; }
virtual double getTargetingRange() { return targetingRange; }
virtual double getAimMethodRange() { return aimMethodRange; }
virtual double getAcquisitionRange() { return acquisitionRange; }
virtual bool getRadarState() { return radarState; }
virtual bool getAirborne() { return airborne; }
virtual double getCargoWeight() { return cargoWeight; }
virtual vector<DataTypes::DrawArgument> getDrawArguments() { return drawArguments; }
virtual string getCustomString() { return customString; }
virtual unsigned long getCustomInteger() { return customInteger; }
protected:
unsigned int ID;
@@ -170,8 +218,12 @@ protected:
string name = "";
string unitName = "";
string callsign = "";
unsigned int unitID = NULL;
unsigned int groupID = NULL;
string groupName = "";
unsigned char state = State::NONE;
unsigned char alarmState = AlarmState::AUTO;
bool radarState = false;
string task = "";
bool hasTask = false;
Coords position = Coords(NULL);
@@ -190,10 +242,13 @@ protected:
double desiredAltitude = 1;
bool desiredAltitudeType = 0; /* ASL */
unsigned int leaderID = NULL;
double racetrackLength = NULL;
Coords racetrackAnchor = Coords(NULL);
double racetrackBearing = NULL;
Offset formationOffset = Offset(NULL);
unsigned int targetID = NULL;
Coords targetPosition = Coords(NULL);
unsigned char ROE = ROE::OPEN_FIRE_WEAPON_FREE;
unsigned char ROE = ROE::OPEN_FIRE;
unsigned char reactionToThreat = ReactionToThreat::EVADE_FIRE;
unsigned char emissionsCountermeasures = EmissionCountermeasure::DEFEND;
DataTypes::TACAN TACAN;
@@ -208,16 +263,36 @@ protected:
unsigned char shotsScatter = 2;
unsigned char shotsIntensity = 2;
unsigned char health = 100;
double timeToNextTasking = 0;
double barrelHeight = 0;
double muzzleVelocity = 0;
double aimTime = 0;
unsigned int shotsToFire = 0;
double shotsBaseInterval = 0;
double shotsBaseScatter = 0;
double engagementRange = 0;
double targetingRange = 0;
double aimMethodRange = 0;
double acquisitionRange = 0;
bool airborne = false;
double cargoWeight = 0;
vector<DataTypes::DrawArgument> drawArguments;
string customString = "";
unsigned long customInteger = 0;
/********** Other **********/
unsigned int taskCheckCounter = 0;
unsigned int internalCounter = 0;
Unit* missOnPurposeTarget = nullptr;
bool hasTaskAssigned = false;
double initialFuel = 0;
map<unsigned char, unsigned long long> updateTimeMap;
unsigned long long lastLoopTime = 0;
bool enableTaskFailedCheck = false;
unsigned long nextTaskingMilliseconds = 0;
unsigned int totalShellsFired = 0;
unsigned int shellsFiredAtTasking = 0;
unsigned int oldAmmo = 0;
/********** Private methods **********/
virtual void AIloop() = 0;

View File

@@ -23,8 +23,8 @@ public:
void deleteUnit(unsigned int ID, bool explosion, string explosionType, bool immediate);
void acquireControl(unsigned int ID);
void loadDatabases();
Unit* getClosestUnit(Unit* unit, unsigned char coalition, vector<string> categories, double &distance);
map<Unit*, double> getUnitsInRange(Unit* unit, unsigned char coalition, vector<string> categories, double range);
Unit* getClosestUnit(Unit* unit, unsigned char coalition, vector<string> categories, double &distance, bool airborneOnly = true);
map<Unit*, double> getUnitsInRange(Unit* unit, unsigned char coalition, vector<string> categories, double range, bool airborneOnly = true);
private:
map<unsigned int, Unit*> units;

View File

@@ -113,4 +113,10 @@ class Bomb : public Weapon
{
public:
Bomb(json::value json, unsigned int ID);
};
class Shell : public Weapon
{
public:
Shell(json::value json, unsigned int ID);
};

View File

@@ -154,6 +154,13 @@ void AirUnit::AIloop()
{
srand(static_cast<unsigned int>(time(NULL)) + ID);
/* Reset the anchor */
if (state != State::IDLE) {
setRacetrackAnchor(Coords(NULL));
setRacetrackBearing(NULL);
setRacetrackLength(NULL);
}
/* State machine */
switch (state) {
case State::IDLE: {
@@ -166,21 +173,27 @@ void AirUnit::AIloop()
if (!getHasTask())
{
if (racetrackAnchor == Coords(NULL)) setRacetrackAnchor(position);
if (racetrackBearing == NULL) setRacetrackBearing(heading);
std::ostringstream taskSS;
if (isActiveTanker) {
taskSS << "{ [1] = { id = 'Tanker' }, [2] = { id = 'Orbit', pattern = 'Race-Track', altitude = " <<
desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "' }}";
desiredAltitude << ", lat = " << racetrackAnchor.lat << ", lng = " << racetrackAnchor.lng << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "', heading = " <<
racetrackBearing << ", length = " << (racetrackLength != NULL ? racetrackLength : (50000 * 1.852)) << " }}";
}
else if (isActiveAWACS) {
taskSS << "{ [1] = { id = 'AWACS' }, [2] = { id = 'Orbit', pattern = 'Circle', altitude = " <<
desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "' }}";
taskSS << "{ [1] = { id = 'AWACS' }, [2] = { id = 'Orbit', pattern = 'Race-Track', altitude = " <<
desiredAltitude << ", lat = " << racetrackAnchor.lat << ", lng = " << racetrackAnchor.lng << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "', heading = " <<
racetrackBearing << ", length = " << (racetrackLength != NULL ? racetrackLength : (desiredSpeed * 30)) << " }}";
}
else {
taskSS << "{ id = 'Orbit', pattern = 'Circle', altitude = " <<
desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "'}";
taskSS << "{ id = 'Orbit', pattern = 'Race-Track', altitude = " <<
desiredAltitude << ", lat = " << racetrackAnchor.lat << ", lng = " << racetrackAnchor.lng << ", speed = " << desiredSpeed << ", altitudeType = '" <<
(desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "', heading = " <<
racetrackBearing << ", length = " << (racetrackLength != NULL ? racetrackLength: (desiredSpeed * 30)) << " }";
}
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
@@ -376,4 +389,53 @@ void AirUnit::AIloop()
default:
break;
}
}
void AirUnit::setRacetrackLength(double newRacetrackLength) {
if (racetrackLength != newRacetrackLength) {
racetrackLength = newRacetrackLength;
/* Apply the change */
setHasTask(false);
resetTaskFailedCounter();
AIloop();
triggerUpdate(DataIndex::racetrackLength);
}
}
void AirUnit::setRacetrackAnchor(Coords newRacetrackAnchor) {
if (racetrackAnchor != newRacetrackAnchor) {
racetrackAnchor = newRacetrackAnchor;
/* Apply the change */
setHasTask(false);
resetTaskFailedCounter();
AIloop();
triggerUpdate(DataIndex::racetrackAnchor);
}
}
void AirUnit::setRacetrackBearing(double newRacetrackBearing) {
if (racetrackBearing != newRacetrackBearing) {
racetrackBearing = newRacetrackBearing;
/* Apply the change */
setHasTask(false);
resetTaskFailedCounter();
AIloop();
triggerUpdate(DataIndex::racetrackBearing);
}
}
void AirUnit::setCargoWeight(double newCargoWeight) {
if (cargoWeight != newCargoWeight) {
cargoWeight = newCargoWeight;
triggerUpdate(DataIndex::cargoWeight);
Command* command = dynamic_cast<Command*>(new SetCargoWeight(this->ID, cargoWeight));
scheduler->appendCommand(command);
}
}

View File

@@ -46,9 +46,9 @@ string SpawnGroundUnits::getString()
<< "unitType = " << "\"" << spawnOptions[i].unitType << "\"" << ", "
<< "lat = " << spawnOptions[i].location.lat << ", "
<< "lng = " << spawnOptions[i].location.lng << ", "
<< "heading = " << spawnOptions[i].heading << ", "
<< "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", "
<< "skill = \"" << spawnOptions[i].skill << "\"" << "}, ";
}
std::ostringstream commandSS;
@@ -58,6 +58,7 @@ string SpawnGroundUnits::getString()
<< "coalition = " << "\"" << coalition << "\"" << ", "
<< "country = \"" << country << "\", "
<< "units = " << "{" << unitsSS.str() << "}" << "}";
commandSS << ", \"" << this->getHash() << "\"";
return commandSS.str();
}
@@ -72,6 +73,7 @@ string SpawnNavyUnits::getString()
<< "unitType = " << "\"" << spawnOptions[i].unitType << "\"" << ", "
<< "lat = " << spawnOptions[i].location.lat << ", "
<< "lng = " << spawnOptions[i].location.lng << ", "
<< "heading = " << spawnOptions[i].heading << ", "
<< "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", "
<< "skill = \"" << spawnOptions[i].skill << "\"" << "}, ";
}
@@ -83,6 +85,7 @@ string SpawnNavyUnits::getString()
<< "coalition = " << "\"" << coalition << "\"" << ", "
<< "country = \"" << country << "\", "
<< "units = " << "{" << unitsSS.str() << "}" << "}";
commandSS << ", \"" << this->getHash() << "\"";
return commandSS.str();
}
@@ -97,7 +100,9 @@ string SpawnAircrafts::getString()
<< "lat = " << spawnOptions[i].location.lat << ", "
<< "lng = " << spawnOptions[i].location.lng << ", "
<< "alt = " << spawnOptions[i].location.alt << ", "
<< "heading = " << spawnOptions[i].heading << ", "
<< "loadout = \"" << spawnOptions[i].loadout << "\"" << ", "
<< "payload = " << spawnOptions[i].payload << ", "
<< "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", "
<< "skill = \"" << spawnOptions[i].skill << "\"" << "}, ";
}
@@ -110,6 +115,7 @@ string SpawnAircrafts::getString()
<< "airbaseName = \"" << airbaseName << "\", "
<< "country = \"" << country << "\", "
<< "units = " << "{" << unitsSS.str() << "}" << "}";
commandSS << ", \"" << this->getHash() << "\"";
return commandSS.str();
}
@@ -125,7 +131,9 @@ string SpawnHelicopters::getString()
<< "lat = " << spawnOptions[i].location.lat << ", "
<< "lng = " << spawnOptions[i].location.lng << ", "
<< "alt = " << spawnOptions[i].location.alt << ", "
<< "heading = " << spawnOptions[i].heading << ", "
<< "loadout = \"" << spawnOptions[i].loadout << "\"" << ", "
<< "payload = " << spawnOptions[i].payload << ", "
<< "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", "
<< "skill = \"" << spawnOptions[i].skill << "\"" << "}, ";
}
@@ -138,6 +146,7 @@ string SpawnHelicopters::getString()
<< "airbaseName = \"" << airbaseName << "\", "
<< "country = \"" << country << "\", "
<< "units = " << "{" << unitsSS.str() << "}" << "}";
commandSS << ", \"" << this->getHash() << "\"";
return commandSS.str();
}
@@ -253,4 +262,85 @@ string Explosion::getString()
<< location.lat << ", "
<< location.lng;
return commandSS.str();
}
/* FireLaser command */
string FireLaser::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.fireLaser, "
<< ID << ", "
<< code << ", "
<< destination.lat << ", "
<< destination.lng;
return commandSS.str();
}
/* FireInfrared command */
string FireInfrared::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.fireInfrared, "
<< ID << ", "
<< destination.lat << ", "
<< destination.lng;
return commandSS.str();
}
/* SetLaserCode command */
string SetLaserCode::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.setLaserCode, "
<< spotID << ", "
<< code;
return commandSS.str();
}
/* MoveSpot command */
string MoveSpot::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.moveSpot, "
<< spotID << ", "
<< destination.lat << ", "
<< destination.lng;
return commandSS.str();
}
/* DeleteSpot command */
string DeleteSpot::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.deleteSpot, "
<< spotID;
return commandSS.str();
}
/* SetCargoWeight command */
string SetCargoWeight::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.setCargoWeight, "
<< ID << ", "
<< weight;
return commandSS.str();
}
/* RegisterDrawArgument command */
string RegisterDrawArgument::getString()
{
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.registerDrawArgument, "
<< ID << ", "
<< argument << ", "
<< active;
return commandSS.str();
}

View File

@@ -22,6 +22,8 @@ Scheduler* scheduler = nullptr;
/* Data jsons */
json::value missionData = json::value::object();
json::value drawingsByLayer = json::value::object();
json::value executionResults = json::value::object();
mutex mutexLock;
string sessionHash;
@@ -161,3 +163,28 @@ extern "C" DllExport int coreMissionData(lua_State * L)
return(0);
}
extern "C" DllExport int coreDrawingsData(lua_State* L)
{
log("Olympus coreDrawingsData called successfully");
/* Lock for thread safety */
lock_guard<mutex> guard(mutexLock);
lua_getglobal(L, "Olympus");
lua_getfield(L, -1, "drawingsByLayer");
luaTableToJSON(L, -1, drawingsByLayer);
return(0);
}
extern "C" DllExport int coreSetExecutionResults(lua_State* L)
{
/* Lock for thread safety */
lock_guard<mutex> guard(mutexLock);
lua_getglobal(L, "Olympus");
lua_getfield(L, -1, "executionResults");
luaTableToJSON(L, -1, executionResults, true);
return(0);
}

View File

@@ -12,19 +12,24 @@ bool operator==(const DataTypes::Radio& lhs, const DataTypes::Radio& rhs)
bool operator==(const DataTypes::GeneralSettings& lhs, const DataTypes::GeneralSettings& rhs)
{
return lhs.prohibitAA == rhs.prohibitAA && lhs.prohibitAfterburner == rhs.prohibitAfterburner && lhs.prohibitAG == rhs.prohibitAG &&
return lhs.prohibitAA == rhs.prohibitAA && lhs.prohibitAfterburner == rhs.prohibitAfterburner && lhs.prohibitAG == rhs.prohibitAG &&
lhs.prohibitAirWpn == rhs.prohibitAirWpn && lhs.prohibitJettison == rhs.prohibitJettison;
}
bool operator==(const DataTypes::Ammo& lhs, const DataTypes::Ammo& rhs)
{
return lhs.category == rhs.category && lhs.guidance == rhs.guidance && lhs.missileCategory == rhs.missileCategory &&
return lhs.category == rhs.category && lhs.guidance == rhs.guidance && lhs.missileCategory == rhs.missileCategory &&
lhs.quantity == rhs.quantity && strcmp(lhs.name, rhs.name) == 0;
}
bool operator==(const DataTypes::DrawArgument& lhs, const DataTypes::DrawArgument& rhs)
{
return lhs.argument == rhs.argument && lhs.value == rhs.value;
}
bool operator==(const DataTypes::Contact& lhs, const DataTypes::Contact& rhs)
{
return lhs.detectionMethod == rhs.detectionMethod && lhs.ID == rhs.ID;
return lhs.detectionMethod == rhs.detectionMethod && lhs.ID == rhs.ID;
}

View File

@@ -40,15 +40,40 @@ GroundUnit::GroundUnit(json::value json, unsigned int ID) : Unit(json, ID)
void GroundUnit::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 */
setState(State::IDLE);
/* Set the default options */
setROE(ROE::WEAPON_FREE, force);
setROE(ROE::OPEN_FIRE_WEAPON_FREE, force);
setOnOff(onOff, force);
setFollowRoads(followRoads, force);
setFollowRoads(followRoads, force);
}
void GroundUnit::setState(unsigned char newState)
@@ -83,12 +108,14 @@ void GroundUnit::setState(unsigned char newState)
/************ Perform any action required when ENTERING a state ************/
switch (newState) {
case State::IDLE: {
setTask("Idle");
setEnableTaskCheckFailed(false);
clearActivePath();
resetActiveDestination();
break;
}
case State::REACH_DESTINATION: {
setTask("Reaching destination");
setEnableTaskCheckFailed(true);
resetActiveDestination();
break;
@@ -100,6 +127,7 @@ void GroundUnit::setState(unsigned char newState)
break;
}
case State::FIRE_AT_AREA: {
setTask("Firing at area");
setTargetPosition(currentTargetPosition);
setEnableTaskCheckFailed(true);
clearActivePath();
@@ -107,6 +135,7 @@ void GroundUnit::setState(unsigned char newState)
break;
}
case State::SIMULATE_FIRE_FIGHT: {
setTask("Simulating fire fight");
setTargetPosition(currentTargetPosition);
setEnableTaskCheckFailed(false);
clearActivePath();
@@ -114,12 +143,14 @@ void GroundUnit::setState(unsigned char newState)
break;
}
case State::SCENIC_AAA: {
setTask("Scenic AAA");
setEnableTaskCheckFailed(false);
clearActivePath();
resetActiveDestination();
break;
}
case State::MISS_ON_PURPOSE: {
setTask("Miss on purpose");
setEnableTaskCheckFailed(false);
clearActivePath();
resetActiveDestination();
@@ -131,6 +162,7 @@ void GroundUnit::setState(unsigned char newState)
setHasTask(false);
resetTaskFailedCounter();
nextTaskingMilliseconds = 0;
log(unitName + " setting state from " + to_string(state) + " to " + to_string(newState));
state = newState;
@@ -143,17 +175,26 @@ void GroundUnit::setState(unsigned char newState)
void GroundUnit::AIloop()
{
srand(static_cast<unsigned int>(time(NULL)) + ID);
unsigned long timeNow = std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
double currentAmmo = computeTotalAmmo();
/* Out of ammo */
if (shotsToFire > 0 && currentAmmo < shotsToFire && state != State::IDLE && state != State::REACH_DESTINATION)
setState(State::IDLE);
/* Account for unit reloading */
if (currentAmmo < oldAmmo)
totalShellsFired += oldAmmo - currentAmmo;
oldAmmo = currentAmmo;
switch (state) {
case State::IDLE: {
setTask("Idle");
if (getHasTask())
resetTask();
break;
}
case State::REACH_DESTINATION: {
setTask("Reaching destination");
string enrouteTask = "";
bool looping = false;
@@ -200,12 +241,15 @@ void GroundUnit::AIloop()
break;
}
case State::FIRE_AT_AREA: {
setTask("Firing at area");
if (!getHasTask()) {
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 100}";
if (targetPosition.alt == NULL) {
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 100}";
}
else {
taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", alt = " << targetPosition.alt << ", radius = 100}";
}
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
@@ -214,115 +258,163 @@ void GroundUnit::AIloop()
break;
}
case State::SIMULATE_FIRE_FIGHT: {
setTask("Simulating fire fight");
string taskString = "";
if (internalCounter == 0 && targetPosition != Coords(NULL) && scheduler->getLoad() < 30) {
/* Get the distance and bearing to the target */
Coords scatteredTargetPosition = targetPosition;
double distance;
double bearing1;
double bearing2;
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 + 2 / 57.29577 /* 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 */
double aimTime = 2; /* s */
bool indirectFire = false;
double shotsBaseInterval = 15; /* s */
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_number_field(L"aimTime"))
aimTime = databaseEntry[L"aimTime"].as_number().to_double();
if (databaseEntry.has_boolean_field(L"indirectFire"))
indirectFire = databaseEntry[L"indirectFire"].as_bool();
if (databaseEntry.has_number_field(L"shotsBaseInterval"))
shotsBaseInterval = databaseEntry[L"shotsBaseInterval"].as_number().to_double();
if ((totalShellsFired - shellsFiredAtTasking >= shotsToFire || timeNow >= nextTaskingMilliseconds) && targetPosition != Coords(NULL)) {
if (scheduler->getLoad() > 100) {
taskString = "Excessive load, skipping tasking of unit";
setTargetPosition(Coords(NULL));
if (getHasTask())
resetTask();
}
/* If the unit is of the indirect fire type, like a mortar, simply shoot at the target */
if (indirectFire) {
log(unitName + "(" + name + ")" + " simulating fire fight with indirect fire");
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << scatteredTargetPosition.lat << ", lng = " << scatteredTargetPosition.lng << ", radius = 100}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
}
/* Otherwise use the aim method */
else {
log(unitName + "(" + name + ")" + " simulating fire fight with aim at point method");
aimAtPoint(scatteredTargetPosition);
}
/* Get the distance and bearing to the target */
Coords scatteredTargetPosition = targetPosition;
double distance;
double bearing1;
double bearing2;
Geodesic::WGS84().Inverse(getPosition().lat, getPosition().lng, scatteredTargetPosition.lat, scatteredTargetPosition.lng, distance, bearing1, bearing2);
/* Wait an amout of time depending on the shots intensity */
internalCounter = static_cast<unsigned int>(((ShotsIntensity::HIGH - shotsIntensity) * shotsBaseInterval + aimTime) / FRAMERATE_TIME_INTERVAL);
/* Apply a scatter to the aim */
bearing1 += RANDOM_MINUS_ONE_TO_ONE * (ShotsScatter::LOW - shotsScatter + 1) * 10;
/* Compute the scattered position applying a random scatter to the shot */
double scatterDistance = distance * tan(10 /* degs */ * (ShotsScatter::LOW - shotsScatter) / 57.29577 + 2 / 57.29577 /* degs */) * RANDOM_MINUS_ONE_TO_ONE;
Geodesic::WGS84().Direct(scatteredTargetPosition.lat, scatteredTargetPosition.lng, bearing1, scatterDistance, scatteredTargetPosition.lat, scatteredTargetPosition.lng);
/* Recover the data from the database */
bool indirectFire = false;
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_boolean_field(L"indirectFire"))
indirectFire = databaseEntry[L"indirectFire"].as_bool();
}
/* If the unit is of the indirect fire type, like a mortar, simply shoot at the target */
if (indirectFire) {
taskString += "Simulating fire fight with indirect fire";
log(unitName + "(" + name + ")" + " simulating fire fight with indirect fire");
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << scatteredTargetPosition.lat << ", lng = " << scatteredTargetPosition.lng << ", radius = 0.01}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
shellsFiredAtTasking = totalShellsFired;
setHasTask(true);
}
/* Otherwise use the aim method */
else {
taskString += "Simulating fire fight with aim point method. ";
log(unitName + "(" + name + ")" + " simulating fire fight with aim at point method");
string aimTaskString = aimAtPoint(scatteredTargetPosition);
taskString += aimTaskString;
}
/* Wait an amout of time depending on the shots intensity */
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(2 * aimTime * 1000);
}
}
if (targetPosition == Coords(NULL))
setState(State::IDLE);
/* Fallback if something went wrong */
if (internalCounter == 0)
internalCounter = static_cast<unsigned int>(3 / FRAMERATE_TIME_INTERVAL);
internalCounter--;
if (timeNow >= nextTaskingMilliseconds)
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(3 * 1000);
setTimeToNextTasking(((nextTaskingMilliseconds - timeNow) / 1000.0));
if (taskString.length() > 0)
setTask(taskString);
break;
}
case State::SCENIC_AAA: {
setTask("Scenic AAA");
string taskString = "";
/* Only perform scenic functions when the scheduler is "free" */
if (((!getHasTask() && scheduler->getLoad() < 30) || internalCounter == 0)) {
double distance = 0;
unsigned char unitCoalition = coalition == 0 ? getOperateAs() : coalition;
unsigned char targetCoalition = unitCoalition == 2 ? 1 : 2;
Unit* target = unitsManager->getClosestUnit(this, targetCoalition, { "Aircraft", "Helicopter" }, distance);
/* Recover the data from the database */
double aimTime = 2; /* s */
double shotsBaseInterval = 15; /* s */
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_number_field(L"aimTime"))
aimTime = databaseEntry[L"aimTime"].as_number().to_double();
if (databaseEntry.has_number_field(L"shotsBaseInterval"))
shotsBaseInterval = databaseEntry[L"shotsBaseInterval"].as_number().to_double();
if (totalShellsFired - shellsFiredAtTasking >= shotsToFire || timeNow >= nextTaskingMilliseconds) {
if (scheduler->getLoad() > 100) {
taskString = "Excessive load, skipping tasking of unit";
setTargetPosition(Coords(NULL));
if (getHasTask())
resetTask();
}
else {
double distance = 0;
unsigned char unitCoalition = coalition == 0 ? getOperateAs() : coalition;
unsigned char targetCoalition = unitCoalition == 2 ? 1 : 2;
Unit* target = unitsManager->getClosestUnit(this, targetCoalition, { "Aircraft", "Helicopter" }, distance);
/* Only run if an enemy air unit is closer than 20km to avoid useless load */
if (target != nullptr && distance < 20000 /* m */) {
double r = 15; /* m */
double barrelElevation = r * tan(acos(((double)(rand()) / (double)(RAND_MAX))));
/* Recover the data from the database */
bool flak = false;
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_boolean_field(L"flak"))
flak = databaseEntry[L"flak"].as_bool();
}
double lat = 0;
double lng = 0;
double randomBearing = ((double)(rand()) / (double)(RAND_MAX)) * 360;
Geodesic::WGS84().Direct(position.lat, position.lng, randomBearing, r, lat, lng);
/* Only run if an enemy air unit is closer than 20km to avoid useless load */
double activationDistance = 20000;
if (2 * engagementRange > activationDistance)
activationDistance = 2 * engagementRange;
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << lat << ", lng = " << lng << ", alt = " << position.alt + barrelElevation << ", radius = 0.001}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
if (target != nullptr && distance < activationDistance /* m */) {
double r = 15; /* m */
double barrelElevation = position.alt + barrelHeight + r * tan(acos(((double)(rand()) / (double)(RAND_MAX))));
/* Wait an amout of time depending on the shots intensity */
internalCounter = static_cast<unsigned int>(((ShotsIntensity::HIGH - shotsIntensity) * shotsBaseInterval + aimTime) / FRAMERATE_TIME_INTERVAL);
double lat = 0;
double lng = 0;
double randomBearing = ((double)(rand()) / (double)(RAND_MAX)) * 360;
Geodesic::WGS84().Direct(position.lat, position.lng, randomBearing, r, lat, lng);
if (flak) {
lat = position.lat + RANDOM_MINUS_ONE_TO_ONE * (1 + (ShotsScatter::LOW - shotsScatter)) * 0.01;
lng = position.lng + RANDOM_MINUS_ONE_TO_ONE * (1 + (ShotsScatter::LOW - shotsScatter)) * 0.01;
barrelElevation = target->getPosition().alt + RANDOM_MINUS_ONE_TO_ONE * (ShotsScatter::LOW - shotsScatter) * 1000;
taskString += "Flak box mode";
}
else {
taskString += "Scenic AAA. Bearing: " + to_string((int)round(randomBearing)) + "deg";
}
taskString += ". Aim point elevation " + to_string((int)round(barrelElevation - position.alt)) + "m AGL";
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << lat << ", lng = " << lng << ", alt = " << barrelElevation << ", radius = 0.001 }";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
shellsFiredAtTasking = totalShellsFired;
setHasTask(true);
/* Wait an amout of time depending on the shots intensity */
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(2 * aimTime * 1000);
}
else {
setTargetPosition(Coords(NULL));
if (target == nullptr)
taskString += "Scenic AAA. No valid target.";
else
taskString += "Scenic AAA. Target outside max range: " + to_string((int)round(distance)) + "m.";
if (getHasTask())
resetTask();
}
}
}
if (internalCounter == 0)
internalCounter = static_cast<unsigned int>(3 / FRAMERATE_TIME_INTERVAL);
internalCounter--;
if (timeNow >= nextTaskingMilliseconds)
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(3 * 1000);
setTimeToNextTasking((nextTaskingMilliseconds - timeNow) / 1000.0);
if (taskString.length() > 0)
setTask(taskString);
break;
}
case State::MISS_ON_PURPOSE: {
setTask("Missing on purpose");
string taskString = "";
/* Check that the unit can perform AAA duties */
bool canAAA = false;
@@ -332,150 +424,157 @@ void GroundUnit::AIloop()
canAAA = databaseEntry[L"canAAA"].as_bool();
}
/* Recover the data from the database */
bool flak = false;
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_boolean_field(L"flak"))
flak = databaseEntry[L"flak"].as_bool();
}
if (canAAA) {
/* Only perform scenic functions when the scheduler is "free" */
/* Only run this when the internal counter reaches 0 to avoid excessive computations when no nearby target */
if (scheduler->getLoad() < 30 && internalCounter == 0) {
double distance = 0;
unsigned char unitCoalition = coalition == 0 ? getOperateAs() : coalition;
unsigned char targetCoalition = unitCoalition == 2 ? 1 : 2;
/* Default gun values */
double barrelHeight = 1.0; /* m */
double muzzleVelocity = 860; /* m/s */
double aimTime = 10; /* s */
unsigned int shotsToFire = 10;
double shotsBaseInterval = 15; /* s */
double shotsBaseScatter = 2; /* degs */
double engagementRange = 10000; /* m */
double targetingRange = 0; /* m */
double aimMethodRange = 0; /* m */
double acquisitionRange = 0; /* m */
/* 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"))
barrelHeight = databaseEntry[L"barrelHeight"].as_number().to_double();
if (databaseEntry.has_number_field(L"muzzleVelocity"))
muzzleVelocity = databaseEntry[L"muzzleVelocity"].as_number().to_double();
if (databaseEntry.has_number_field(L"aimTime"))
aimTime = databaseEntry[L"aimTime"].as_number().to_double();
if (databaseEntry.has_number_field(L"shotsToFire"))
shotsToFire = databaseEntry[L"shotsToFire"].as_number().to_uint32();
if (databaseEntry.has_number_field(L"engagementRange"))
engagementRange = databaseEntry[L"engagementRange"].as_number().to_double();
if (databaseEntry.has_number_field(L"shotsBaseInterval"))
shotsBaseInterval = databaseEntry[L"shotsBaseInterval"].as_number().to_double();
if (databaseEntry.has_number_field(L"shotsBaseScatter"))
shotsBaseScatter = databaseEntry[L"shotsBaseScatter"].as_number().to_double();
if (databaseEntry.has_number_field(L"targetingRange"))
targetingRange = databaseEntry[L"targetingRange"].as_number().to_double();
if (databaseEntry.has_number_field(L"aimMethodRange"))
aimMethodRange = databaseEntry[L"aimMethodRange"].as_number().to_double();
if (databaseEntry.has_number_field(L"acquisitionRange"))
acquisitionRange = databaseEntry[L"acquisitionRange"].as_number().to_double();
}
/* Get all the units in range and select one at random */
double range = max(max(engagementRange, aimMethodRange), acquisitionRange);
map<Unit*, double> targets = unitsManager->getUnitsInRange(this, targetCoalition, { "Aircraft", "Helicopter" }, range);
Unit* target = nullptr;
unsigned int index = static_cast<unsigned int>((RANDOM_ZERO_TO_ONE * (targets.size() - 1)));
for (auto const& p : targets) {
if (index-- == 0) {
target = p.first;
distance = p.second;
}
}
/* Only do if we have a valid target close enough for AAA */
if (target != nullptr) {
/* Approximate the flight time */
if (muzzleVelocity != 0)
aimTime += distance / muzzleVelocity;
/* If the target is in targeting range and we are in highest precision mode, target it */
if (distance < targetingRange && shotsScatter == ShotsScatter::LOW) {
/* Send the command */
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'AttackUnit', unitID = " << target->getID() << " }";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
internalCounter = static_cast<unsigned int>((aimTime + (ShotsIntensity::HIGH - shotsIntensity) * shotsBaseInterval + 2) / FRAMERATE_TIME_INTERVAL);
}
/* Else, do miss on purpose */
else {
/* Compute where the target will be in aimTime seconds, plus the effect of scatter. */
double scatterDistance = distance * tan(shotsBaseScatter * (ShotsScatter::LOW - shotsScatter) / 57.29577) * (RANDOM_ZERO_TO_ONE - 0.1);
double aimDistance = target->getHorizontalVelocity() * aimTime + scatterDistance;
double aimLat = 0;
double aimLng = 0;
Geodesic::WGS84().Direct(target->getPosition().lat, target->getPosition().lng, target->getTrack() * 57.29577, aimDistance, aimLat, aimLng); /* TODO make util to convert degrees and radians function */
double aimAlt = target->getPosition().alt + target->getVerticalVelocity() * aimTime + distance * tan(shotsBaseScatter * (ShotsScatter::LOW - shotsScatter) / 57.29577) * RANDOM_ZERO_TO_ONE; // Force to always miss high never low
/* Send the command */
if (distance < engagementRange) {
/* If the unit is closer than the engagement range, use the fire at point method */
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << aimLat << ", lng = " << aimLng << ", alt = " << aimAlt << ", radius = 0.001, expendQty = " << shotsToFire << " }";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
setTargetPosition(Coords(aimLat, aimLng, target->getPosition().alt));
internalCounter = static_cast<unsigned int>((aimTime + (ShotsIntensity::HIGH - shotsIntensity) * shotsBaseInterval + 2) / FRAMERATE_TIME_INTERVAL);
}
else if (distance < aimMethodRange) {
/* If the unit is closer than the aim method range, use the aim method range */
aimAtPoint(Coords(aimLat, aimLng, aimAlt));
setTargetPosition(Coords(aimLat, aimLng, target->getPosition().alt));
internalCounter = static_cast<unsigned int>((aimTime + (ShotsIntensity::HIGH - shotsIntensity) * shotsBaseInterval + 2) / FRAMERATE_TIME_INTERVAL);
}
else {
/* Else just wake the unit up with an impossible command */
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << 0 << ", lng = " << 0 << ", alt = " << 0 << ", radius = 0.001, expendQty = " << 0 << " }";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
setHasTask(true);
setTargetPosition(Coords(NULL));
/* Don't wait too long before checking again */
internalCounter = static_cast<unsigned int>(5 / FRAMERATE_TIME_INTERVAL);
}
}
missOnPurposeTarget = target;
}
else {
if (totalShellsFired - shellsFiredAtTasking >= shotsToFire || timeNow >= nextTaskingMilliseconds) {
if (scheduler->getLoad() > 100) {
taskString = "Excessive load, skipping tasking of unit";
setTargetPosition(Coords(NULL));
if (getHasTask())
resetTask();
}
else {
double distance = 0;
unsigned char unitCoalition = coalition == 0 ? getOperateAs() : coalition;
unsigned char targetCoalition = unitCoalition == 2 ? 1 : 2;
/* Get all the units in range and select one at random */
double range = max(max(engagementRange, aimMethodRange), acquisitionRange);
map<Unit*, double> targets = unitsManager->getUnitsInRange(this, targetCoalition, { "Aircraft", "Helicopter" }, range);
Unit* target = nullptr;
unsigned int index = static_cast<unsigned int>((RANDOM_ZERO_TO_ONE * (targets.size() - 1)));
for (auto const& p : targets) {
if (index-- == 0) {
target = p.first;
distance = p.second;
}
}
/* Only do if we have a valid target close enough for AAA */
if (target != nullptr) {
taskString += "Missing on purpose. Valid target at range: " + to_string((int)round(distance)) + "m";
// Very simplified algorithm ignoring drag
double correctedAimTime = aimTime + distance / muzzleVelocity;
/* If the target is in targeting range and we are in highest precision mode, target it */
if (distance < targetingRange && shotsScatter == ShotsScatter::LOW) {
taskString += ". Range is less than targeting range (" + to_string((int)round(targetingRange)) + "m) and scatter is LOW, aiming at target.";
/* Send the command */
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'AttackUnit', unitID = " << target->getID() << " }";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
shellsFiredAtTasking = totalShellsFired;
setHasTask(true);
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(2 * aimTime * 1000);
}
/* Else, do miss on purpose */
else {
/* Compute where the target will be in aimTime seconds. */
double aimDistance = target->getHorizontalVelocity() * correctedAimTime;
double aimLat = 0;
double aimLng = 0;
Geodesic::WGS84().Direct(target->getPosition().lat, target->getPosition().lng, target->getTrack() * 57.29577, aimDistance, aimLat, aimLng); /* TODO make util to convert degrees and radians function */
double aimAlt = target->getPosition().alt + target->getVerticalVelocity();
if (flak) {
aimLat += RANDOM_MINUS_ONE_TO_ONE * (1 + (ShotsScatter::LOW - shotsScatter)) * 0.01;
aimLng += RANDOM_MINUS_ONE_TO_ONE * (1 + (ShotsScatter::LOW - shotsScatter)) * 0.01;
aimAlt += RANDOM_MINUS_ONE_TO_ONE * (1 + (ShotsScatter::LOW - shotsScatter)) * 1000;
}
/* Send the command */
if (distance < engagementRange) {
taskString += ". Range is less than engagement range (" + to_string((int)round(engagementRange)) + "m), using FIRE AT POINT method";
/* If the unit is closer than the engagement range, use the fire at point method */
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << aimLat << ", lng = " << aimLng << ", alt = " << aimAlt << ", radius = 0.001 }";
taskString += ". Aiming altitude " + to_string((int)round((aimAlt - position.alt) / 0.3048)) + "ft AGL";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
shellsFiredAtTasking = totalShellsFired;
setHasTask(true);
setTargetPosition(Coords(aimLat, aimLng, target->getPosition().alt));
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(2 * aimTime * 1000);
}
else if (distance < aimMethodRange) {
taskString += ". Range is less than aim method range (" + to_string((int)round(aimMethodRange / 0.3048)) + "ft), using AIM method.";
/* If the unit is closer than the aim method range, use the aim method range */
string aimMethodTask = aimAtPoint(Coords(aimLat, aimLng, aimAlt));
taskString += aimMethodTask;
setTargetPosition(Coords(aimLat, aimLng, target->getPosition().alt));
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(2 * aimTime * 1000);
}
else {
taskString += ". Target is not in range of weapon, waking up unit to get ready for tasking.";
/* Else just wake the unit up with an impossible command */
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << 0 << ", lng = " << 0 << ", alt = " << 0 << ", radius = 0.001, expendQty = " << 0 << " }";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
shellsFiredAtTasking = totalShellsFired;
setHasTask(true);
setTargetPosition(Coords(NULL));
/* Don't wait too long before checking again */
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>(5 * 1000);
}
}
missOnPurposeTarget = target;
}
else {
taskString += "Missing on purpose. No target in range.";
setTargetPosition(Coords(NULL));
if (getHasTask())
resetTask();
}
}
}
/* If no valid target was detected */
if (internalCounter == 0) {
if (timeNow >= nextTaskingMilliseconds) {
double alertnessTimeConstant = 10; /* s */
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_number_field(L"alertnessTimeConstant"))
alertnessTimeConstant = databaseEntry[L"alertnessTimeConstant"].as_number().to_double();
}
internalCounter = static_cast<unsigned int>((5 + RANDOM_ZERO_TO_ONE * alertnessTimeConstant * 0 /* TODO: remove to enable alertness again */) / FRAMERATE_TIME_INTERVAL);
nextTaskingMilliseconds = timeNow + static_cast<unsigned long>((5 + RANDOM_ZERO_TO_ONE * alertnessTimeConstant) * 1000L);
missOnPurposeTarget = nullptr;
setTargetPosition(Coords(NULL));
}
internalCounter--;
}
else {
setState(State::IDLE);
}
setTimeToNextTasking((nextTaskingMilliseconds - timeNow) / 1000.0);
if (taskString.length() > 0)
setTask(taskString);
break;
}
default:
@@ -484,7 +583,8 @@ void GroundUnit::AIloop()
}
void GroundUnit::aimAtPoint(Coords aimTarget) {
string GroundUnit::aimAtPoint(Coords aimTarget) {
string taskString = "";
double dist;
double bearing1;
double bearing2;
@@ -493,20 +593,6 @@ void GroundUnit::aimAtPoint(Coords aimTarget) {
/* Aim point distance */
double r = 15; /* m */
/* Default gun values */
double barrelHeight = 1.0; /* m */
double muzzleVelocity = 860; /* m/s */
double shotsBaseScatter = 5; /* degs */
if (database.has_object_field(to_wstring(name))) {
json::value databaseEntry = database[to_wstring(name)];
if (databaseEntry.has_number_field(L"barrelHeight") && databaseEntry.has_number_field(L"muzzleVelocity")) {
barrelHeight = databaseEntry[L"barrelHeight"].as_number().to_double();
muzzleVelocity = databaseEntry[L"muzzleVelocity"].as_number().to_double();
}
if (databaseEntry.has_number_field(L"shotsBaseScatter"))
shotsBaseScatter = databaseEntry[L"shotsBaseScatter"].as_number().to_double();
}
/* Compute the elevation angle of the gun*/
double deltaHeight = (aimTarget.alt - (position.alt + barrelHeight));
double alpha = 9.81 / 2 * dist * dist / (muzzleVelocity * muzzleVelocity);
@@ -521,18 +607,23 @@ void GroundUnit::aimAtPoint(Coords aimTarget) {
double lng = 0;
Geodesic::WGS84().Direct(position.lat, position.lng, bearing1, r, lat, lng);
log(unitName + "(" + name + ")" + " shooting with aim at point method. Barrel elevation: " + to_string(barrelElevation * 57.29577) + "°, bearing: " + to_string(bearing1) + "°");
taskString = +"Barrel elevation: " + to_string((int) round(barrelElevation)) + "m, bearing: " + to_string((int) round(bearing1)) + "deg";
log(unitName + "(" + name + ")" + " shooting with aim at point method. Barrel elevation: " + to_string(barrelElevation) + "m, bearing: " + to_string(bearing1) + "<EFBFBD>");
std::ostringstream taskSS;
taskSS.precision(10);
taskSS << "{id = 'FireAtPoint', lat = " << lat << ", lng = " << lng << ", alt = " << position.alt + barrelElevation + barrelHeight << ", radius = 0.001}";
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
scheduler->appendCommand(command);
shellsFiredAtTasking = totalShellsFired;
setHasTask(true);
}
else {
log("Target out of range for " + unitName + "(" + name + ")");
taskString = +"Target out of range";
}
return taskString;
}
void GroundUnit::changeSpeed(string change)

View File

@@ -37,13 +37,38 @@ 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 */
setState(State::IDLE);
/* Set the default options */
setROE(ROE::WEAPON_FREE, force);
setROE(ROE::OPEN_FIRE_WEAPON_FREE, force);
setOnOff(onOff, force);
setFollowRoads(followRoads, force);
}

View File

@@ -52,10 +52,11 @@ void Scheduler::execute(lua_State* L)
if (command->getPriority() == priority)
{
string commandString = "Olympus.protectedCall(" + command->getString() + ")";
if (dostring_in(L, "server", (commandString)))
string resultString = "";
if (dostring_in(L, "server", (commandString), resultString))
log("Error executing command " + commandString);
else
log("Command '" + commandString + "' executed correctly, current load " + to_string(getLoad()));
log("Command '" + commandString + "' executed correctly, current load " + to_string(getLoad()) + ", result string: " + resultString);
/* Adjust the load depending on the fps */
double fpsMultiplier = 20;
@@ -64,7 +65,10 @@ void Scheduler::execute(lua_State* L)
load = static_cast<unsigned int>(command->getLoad() * fpsMultiplier);
commands.remove(command);
executedCommandsHashes.push_back(command->getHash());
CommandResult commandResult = {
command->getHash(), resultString
};
executedCommandResults.push_back(commandResult);
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;
@@ -164,6 +168,12 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
string WP = to_string(i);
double lat = path[i][L"lat"].as_double();
double lng = path[i][L"lng"].as_double();
if (path[i].has_number_field(L"threshold")) {
double threshold = path[i][L"threshold"].as_double();
Coords dest; dest.lat = lat; dest.lng = lng; dest.threshold = threshold;
newPath.push_back(dest);
continue;
}
Coords dest; dest.lat = lat; dest.lng = lng;
newPath.push_back(dest);
}
@@ -179,7 +189,7 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
string color = to_string(value[L"color"]);
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;
command = dynamic_cast<Command*>(new Smoke(color, loc));
log(username + " added a " + color + " smoke at (" + to_string(lat) + ", " + to_string(lng) + ")", true);
@@ -192,9 +202,11 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
string airbaseName = to_string(value[L"airbaseName"]);
string country = to_string(value[L"country"]);
int spawnPoints = value[L"spawnPoints"].as_number().to_int32();
if (!checkSpawnPoints(spawnPoints, coalition)) return;
if (!checkSpawnPoints(spawnPoints, coalition)) {
log(username + " insufficient spawn points ", true);
return;
}
vector<SpawnOptions> spawnOptions;
for (auto unit : value[L"units"].as_array()) {
@@ -202,13 +214,21 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
double alt = unit[L"altitude"].as_double();
double heading = 0;
if (unit.has_number_field(L"heading"))
heading = unit[L"heading"].as_double();
Coords location; location.lat = lat; location.lng = lng; location.alt = alt;
string loadout = to_string(unit[L"loadout"]);
string liveryID = to_string(unit[L"liveryID"]);
string skill = to_string(unit[L"skill"]);
spawnOptions.push_back({unitType, location, loadout, skill, liveryID});
log(username + " spawned a " + coalition + " " + unitType , true);
string payload = "nil";
if (unit.has_string_field(L"payload"))
payload = to_string(unit[L"payload"]);
spawnOptions.push_back({ unitType, location, loadout, skill, liveryID, heading, payload });
log(username + " spawned a " + coalition + " " + unitType, true);
}
if (key.compare("spawnAircrafts") == 0)
@@ -224,18 +244,25 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
string country = to_string(value[L"country"]);
int spawnPoints = value[L"spawnPoints"].as_number().to_int32();
if (!checkSpawnPoints(spawnPoints, coalition)) return;
if (!checkSpawnPoints(spawnPoints, coalition)) {
log(username + " insufficient spawn points ", true);
return;
}
vector<SpawnOptions> spawnOptions;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"unitType"]);
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
double heading = 0;
if (unit.has_number_field(L"heading"))
heading = unit[L"heading"].as_double();
Coords location; location.lat = lat; location.lng = lng;
string liveryID = to_string(unit[L"liveryID"]);
string skill = to_string(unit[L"skill"]);
spawnOptions.push_back({ unitType, location, "", skill, liveryID});
spawnOptions.push_back({ unitType, location, "", skill, liveryID, heading });
log(username + " spawned a " + coalition + " " + unitType, true);
}
@@ -345,18 +372,43 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
unit->setDesiredAltitudeType(to_string(value[L"altitudeType"]));
log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") altitude type: " + to_string(value[L"altitudeType"]), true);
}
}/************************/
else if (key.compare("setRacetrack") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
unitsManager->acquireControl(ID);
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr) {
unit->setRacetrackLength(value[L"length"].as_double());
double lat = value[L"location"][L"lat"].as_double();
double lng = value[L"location"][L"lng"].as_double();
Coords location; location.lat = lat; location.lng = lng;
unit->setRacetrackAnchor(location);
unit->setRacetrackBearing(value[L"bearing"].as_double());
log(username + " set " + unit->getUnitName() + "(" + unit->getName() + ") racetrack length: " + to_string(value[L"length"].as_double()) + " racetrack bearing: " + to_string(value[L"bearing"].as_double()), true);
}
}
/************************/
else if (key.compare("cloneUnits") == 0)
{
vector<CloneOptions> cloneOptions;
bool deleteOriginal = value[L"deleteOriginal"].as_bool();
string coalition = to_string(value[L"coalition"]);
int spawnPoints = value[L"spawnPoints"].as_number().to_int32();
if (coalition.compare("all") != 0 && !checkSpawnPoints(spawnPoints, coalition)) {
log(username + " insufficient spawn points ", true);
return;
}
for (auto unit : value[L"units"].as_array()) {
unsigned int ID = unit[L"ID"].as_integer();
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
Coords location; location.lat = lat; location.lng = lng;
cloneOptions.push_back({ ID, location });
log(username + " cloning unit with ID " + to_string(ID), true);
@@ -376,6 +428,20 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") ROE to " + to_string(ROE), true);
}
}
else if (key.compare("setAlarmState") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
unitsManager->acquireControl(ID);
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr) {
unsigned char alarmState = value[L"alarmState"].as_number().to_uint32();
unit->setAlarmState(alarmState);
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") alarm state to " + to_string(alarmState), true);
}
else {
log("Error while setting setAlarmState. Unit does not exist.");
}
}
/************************/
else if (key.compare("setReactionToThreat") == 0)
{
@@ -483,6 +549,29 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
}
}
/************************/
else if (key.compare("setEngagementProperties") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
unitsManager->acquireControl(ID);
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr)
{
/* Engagement properties tasking */
unit->setBarrelHeight(value[L"barrelHeight"].as_number().to_double());
unit->setMuzzleVelocity(value[L"muzzleVelocity"].as_number().to_double());
unit->setAimTime(value[L"aimTime"].as_number().to_double());
unit->setShotsToFire(value[L"shotsToFire"].as_number().to_uint32());
unit->setShotsBaseInterval(value[L"shotsBaseInterval"].as_number().to_double());
unit->setShotsBaseScatter(value[L"shotsBaseScatter"].as_number().to_double());
unit->setEngagementRange(value[L"engagementRange"].as_number().to_double());
unit->setTargetingRange(value[L"targetingRange"].as_number().to_double());
unit->setAimMethodRange(value[L"aimMethodRange"].as_number().to_double());
unit->setAcquisitionRange(value[L"acquisitionRange"].as_number().to_double());
log(username + " updated unit " + unit->getUnitName() + "(" + unit->getName() + ") engagementProperties", true);
}
}
/************************/
else if (key.compare("setFollowRoads") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
@@ -503,7 +592,7 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr) {
unit->setOnOff(onOff);
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") onOff to: " + (onOff? "true": "false"), true);
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") onOff to: " + (onOff ? "true" : "false"), true);
}
}
/************************/
@@ -570,6 +659,11 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
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;
if (value[L"location"].has_number_field(L"alt")) {
loc.alt = value[L"location"][L"alt"].as_double();
}
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr) {
unit->setTargetPosition(loc);
@@ -622,7 +716,7 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
unitsManager->acquireControl(ID);
unsigned char operateAs = value[L"operateAs"].as_number().to_uint32();
Unit* unit = unitsManager->getGroupLeader(ID);
if (unit != nullptr)
if (unit != nullptr)
unit->setOperateAs(operateAs);
}
/************************/
@@ -669,7 +763,66 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
}
}
/************************/
else if (key.compare("setCommandModeOptions") == 0)
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("Firing laser with code " + to_string(code) + " from unit " + unit->getUnitName() + " to (" + to_string(lat) + ", " + to_string(lng) + ")");
command = dynamic_cast<Command*>(new FireLaser(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("Firing infrared from unit " + unit->getUnitName() + " to (" + to_string(lat) + ", " + to_string(lng) + ")");
command = dynamic_cast<Command*>(new FireInfrared(ID, loc));
}
}
/************************/
else if (key.compare("setLaserCode") == 0)
{
unsigned int spotID = value[L"spotID"].as_integer();
unsigned int code = value[L"code"].as_integer();
log("Setting laser code " + to_string(code) + " to spot with ID " + to_string(spotID));
command = dynamic_cast<Command*>(new SetLaserCode(spotID, code));
}
/************************/
else if (key.compare("moveSpot") == 0)
{
unsigned int spotID = value[L"spotID"].as_integer();
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("Moving spot with ID " + to_string(spotID) + " to (" + to_string(lat) + ", " + to_string(lng) + ")");
command = dynamic_cast<Command*>(new MoveSpot(spotID, loc));
}
/************************/
else if (key.compare("deleteSpot") == 0)
{
unsigned int spotID = value[L"spotID"].as_integer();
log("Deleting spot with ID " + to_string(spotID));
command = dynamic_cast<Command*>(new DeleteSpot(spotID));
}
/************************/
else if (key.compare("setCommandModeOptions") == 0)
{
setCommandModeOptions(value);
log(username + " updated the Command Mode Options", true);
@@ -679,6 +832,53 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
unitsManager->loadDatabases();
}
/************************/
else if (key.compare("setCargoWeight") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
Unit* unit = unitsManager->getUnit(ID);
if (unit != nullptr) {
double weight = value[L"weight"].as_double();
unit->setCargoWeight(weight);
log(username + " set weight to unit " + unit->getUnitName() + "(" + unit->getName() + "), " + to_string(weight), true);
}
}
/************************/
else if (key.compare("registerDrawArgument") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
Unit* unit = unitsManager->getUnit(ID);
if (unit != nullptr) {
int argument = value[L"argument"].as_integer();
bool active = value[L"active"].as_bool();
command = dynamic_cast<Command*>(new RegisterDrawArgument(ID, argument, active));
log(username + " registered draw argument " + to_string(argument) + " for unit " + unit->getUnitName() + "(" + unit->getName() + "), value:" + to_string(active), true);
}
}
/************************/
else if (key.compare("setCustomString") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
Unit* unit = unitsManager->getUnit(ID);
if (unit != nullptr) {
string customString = to_string(value[L"customString"]);
unit->setCustomString(customString);
log(username + " set custom string to unit " + unit->getUnitName() + "(" + unit->getName() + "), " + customString, true);
}
}
/************************/
else if (key.compare("setCustomInteger") == 0)
{
unsigned int ID = value[L"ID"].as_integer();
Unit* unit = unitsManager->getUnit(ID);
if (unit != nullptr) {
double customNumber = value[L"customInteger"].as_double();
unit->setCustomInteger(customNumber);
log(username + " set custom number to unit " + unit->getUnitName() + "(" + unit->getName() + "), " + to_string(customNumber), true);
}
}
/************************/
else
{
log("Unknown command: " + key);

View File

@@ -17,6 +17,8 @@ extern UnitsManager* unitsManager;
extern WeaponsManager* weaponsManager;
extern Scheduler* scheduler;
extern json::value missionData;
extern json::value drawingsByLayer;
extern json::value executionResults;
extern mutex mutexLock;
extern string sessionHash;
extern string instancePath;
@@ -128,6 +130,9 @@ void Server::handle_get(http_request request)
/* Bullseyes data */
else if (URI.compare(BULLSEYE_URI) == 0 && missionData.has_object_field(L"bullseyes"))
answer[L"bullseyes"] = missionData[L"bullseyes"];
/* Spots (laser/IR) data */
else if (URI.compare(SPOTS_URI) == 0 && missionData.has_object_field(L"spots"))
answer[L"spots"] = missionData[L"spots"];
/* Mission data */
else if (URI.compare(MISSION_URI) == 0 && missionData.has_object_field(L"mission")) {
answer[L"mission"] = missionData[L"mission"];
@@ -145,6 +150,14 @@ void Server::handle_get(http_request request)
}
else if (URI.compare(COMMANDS_URI) == 0 && query.find(L"commandHash") != query.end()) {
answer[L"commandExecuted"] = json::value(scheduler->isCommandExecuted(to_string(query[L"commandHash"])));
if (executionResults.has_field(query[L"commandHash"]))
answer[L"commandResult"] = executionResults[query[L"commandHash"]];
else
answer[L"commandResult"] = json::value::null();
}
/* Drawings data*/
else if (URI.compare(DRAWINGS_URI) == 0 && drawingsByLayer.has_object_field(L"drawings")) {
answer[L"drawings"] = drawingsByLayer[L"drawings"];
}
/* Common data */

View File

@@ -41,6 +41,11 @@ void Unit::update(json::value json, double dt)
if (json.has_string_field(L"unitName"))
setUnitName(to_string(json[L"unitName"]));
if (json.has_number_field(L"groupID"))
setGroupID(json[L"groupID"].as_number().to_uint32());
if (json.has_number_field(L"unitID"))
setUnitID(json[L"unitID"].as_number().to_uint32());
if (json.has_string_field(L"groupName"))
setGroupName(to_string(json[L"groupName"]));
@@ -49,8 +54,8 @@ void Unit::update(json::value json, double dt)
if (json.has_number_field(L"coalitionID"))
setCoalition(json[L"coalitionID"].as_number().to_int32());
//if (json.has_number_field(L"Country"))
// setCountry(json[L"Country"].as_number().to_int32());
if (json.has_number_field(L"country"))
setCountry(json[L"country"].as_number().to_int32());
/* All units which contain the name "Olympus" are automatically under AI control */
if (getUnitName().find("Olympus") != string::npos)
@@ -83,6 +88,9 @@ void Unit::update(json::value json, double dt)
if (json.has_boolean_field(L"isAlive"))
setAlive(json[L"isAlive"].as_bool());
if (json.has_boolean_field(L"radarState"))
setRadarState(json[L"radarState"].as_bool());
if (json.has_boolean_field(L"isHuman"))
setHuman(json[L"isHuman"].as_bool());
@@ -120,6 +128,20 @@ void Unit::update(json::value json, double dt)
setAmmo(ammo);
}
if (json.has_object_field(L"drawArguments")) {
vector<DataTypes::DrawArgument> drawArguments;
for (auto const& el : json[L"drawArguments"].as_object()) {
DataTypes::DrawArgument drawArgumentItem;
auto drawArgumentJson = el.second;
if (drawArgumentJson.has_number_field(L"argument"))
drawArgumentItem.argument = drawArgumentJson[L"argument"].as_number().to_uint32();
if (drawArgumentJson.has_number_field(L"value"))
drawArgumentItem.value = drawArgumentJson[L"value"].as_number().to_double();
drawArguments.push_back(drawArgumentItem);
}
setDrawArguments(drawArguments);
}
if (json.has_object_field(L"contacts")) {
vector<DataTypes::Contact> contacts;
for (auto const& el : json[L"contacts"].as_object()) {
@@ -145,12 +167,15 @@ void Unit::update(json::value json, double dt)
if (json.has_number_field(L"health"))
setHealth(static_cast<unsigned char>(json[L"health"].as_number().to_uint32()));
if (json.has_boolean_field(L"airborne"))
setAirborne(json[L"airborne"].as_bool());
runAILoop();
}
void Unit::setDefaults(bool force)
{
setAlarmState(AlarmState::AUTO, force);
}
void Unit::runAILoop() {
@@ -208,6 +233,7 @@ void Unit::refreshLeaderData(unsigned long long time) {
case DataIndex::operateAs: updateValue(operateAs, leader->operateAs, datumIndex); break;
case DataIndex::shotsScatter: updateValue(shotsScatter, leader->shotsScatter, datumIndex); break;
case DataIndex::shotsIntensity: updateValue(shotsIntensity, leader->shotsIntensity, datumIndex); break;
case DataIndex::alarmState: updateValue(alarmState, leader->alarmState, datumIndex); break;
}
}
}
@@ -243,6 +269,10 @@ void Unit::getData(stringstream& ss, unsigned long long time)
appendString(ss, datumIndex, category);
datumIndex = DataIndex::alive;
appendNumeric(ss, datumIndex, alive);
datumIndex = DataIndex::unitID;
appendNumeric(ss, datumIndex, unitID);
datumIndex = DataIndex::groupID;
appendNumeric(ss, datumIndex, groupID);
}
else {
for (unsigned char datumIndex = DataIndex::startOfData + 1; datumIndex < DataIndex::lastIndex; datumIndex++)
@@ -251,6 +281,8 @@ void Unit::getData(stringstream& ss, unsigned long long time)
switch (datumIndex) {
case DataIndex::category: appendString(ss, datumIndex, category); break;
case DataIndex::alive: appendNumeric(ss, datumIndex, alive); break;
case DataIndex::alarmState: appendNumeric(ss, datumIndex, alarmState); break;
case DataIndex::radarState: appendNumeric(ss, datumIndex, radarState); break;
case DataIndex::human: appendNumeric(ss, datumIndex, human); break;
case DataIndex::controlled: appendNumeric(ss, datumIndex, controlled); break;
case DataIndex::coalition: appendNumeric(ss, datumIndex, coalition); break;
@@ -258,6 +290,8 @@ void Unit::getData(stringstream& ss, unsigned long long time)
case DataIndex::name: appendString(ss, datumIndex, name); break;
case DataIndex::unitName: appendString(ss, datumIndex, unitName); break;
case DataIndex::callsign: appendString(ss, datumIndex, callsign); break;
case DataIndex::unitID: appendNumeric(ss, datumIndex, unitID); break;
case DataIndex::groupID: appendNumeric(ss, datumIndex, groupID); break;
case DataIndex::groupName: appendString(ss, datumIndex, groupName); break;
case DataIndex::state: appendNumeric(ss, datumIndex, state); break;
case DataIndex::task: appendString(ss, datumIndex, task); break;
@@ -295,6 +329,25 @@ void Unit::getData(stringstream& ss, unsigned long long time)
case DataIndex::shotsScatter: appendNumeric(ss, datumIndex, shotsScatter); break;
case DataIndex::shotsIntensity: appendNumeric(ss, datumIndex, shotsIntensity); break;
case DataIndex::health: appendNumeric(ss, datumIndex, health); break;
case DataIndex::racetrackLength: appendNumeric(ss, datumIndex, racetrackLength); break;
case DataIndex::racetrackAnchor: appendNumeric(ss, datumIndex, racetrackAnchor); break;
case DataIndex::racetrackBearing: appendNumeric(ss, datumIndex, racetrackBearing); break;
//case DataIndex::timeToNextTasking: appendNumeric(ss, datumIndex, timeToNextTasking); break; Useful for debugging, but useless in production and very data hungry
case DataIndex::barrelHeight: appendNumeric(ss, datumIndex, barrelHeight); break;
case DataIndex::muzzleVelocity: appendNumeric(ss, datumIndex, muzzleVelocity); break;
case DataIndex::aimTime: appendNumeric(ss, datumIndex, aimTime); break;
case DataIndex::shotsToFire: appendNumeric(ss, datumIndex, shotsToFire); break;
case DataIndex::shotsBaseInterval: appendNumeric(ss, datumIndex, shotsBaseInterval); break;
case DataIndex::shotsBaseScatter: appendNumeric(ss, datumIndex, shotsBaseScatter); break;
case DataIndex::engagementRange: appendNumeric(ss, datumIndex, engagementRange); break;
case DataIndex::targetingRange: appendNumeric(ss, datumIndex, targetingRange); break;
case DataIndex::aimMethodRange: appendNumeric(ss, datumIndex, aimMethodRange); break;
case DataIndex::acquisitionRange: appendNumeric(ss, datumIndex, acquisitionRange); break;
case DataIndex::airborne: appendNumeric(ss, datumIndex, airborne); break;
case DataIndex::cargoWeight: appendNumeric(ss, datumIndex, cargoWeight); break;
case DataIndex::drawArguments: appendVector(ss, datumIndex, drawArguments); break;
case DataIndex::customString: appendString(ss, datumIndex, customString); break;
case DataIndex::customInteger: appendNumeric(ss, datumIndex, customInteger); break;
}
}
}
@@ -453,6 +506,17 @@ void Unit::setROE(unsigned char newROE, bool force)
}
}
void Unit::setAlarmState(unsigned char newAlarmState, bool force)
{
if (alarmState != newAlarmState || force) {
alarmState = newAlarmState;
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ALARM_STATE, static_cast<unsigned int>(newAlarmState)));
scheduler->appendCommand(command);
triggerUpdate(DataIndex::alarmState);
}
}
void Unit::setReactionToThreat(unsigned char newReactionToThreat, bool force)
{
if (reactionToThreat != newReactionToThreat || force) {
@@ -655,6 +719,24 @@ void Unit::setGeneralSettings(DataTypes::GeneralSettings newGeneralSettings, boo
}
}
void Unit::setDrawArguments(vector<DataTypes::DrawArgument> newDrawArguments)
{
if (drawArguments.size() == newDrawArguments.size()) {
bool equal = true;
for (int i = 0; i < drawArguments.size(); i++) {
if (drawArguments.at(i) != newDrawArguments.at(i))
{
equal = false;
break;
}
}
if (equal)
return;
}
drawArguments = newDrawArguments;
triggerUpdate(DataIndex::drawArguments);
}
void Unit::setDesiredSpeed(double newDesiredSpeed)
{
if (desiredSpeed != newDesiredSpeed) {
@@ -721,6 +803,7 @@ void Unit::goToDestination(string enrouteTask)
}
}
// NOTE: if the current active path has a threshold set, that value will be used instead of the passed one
bool Unit::isDestinationReached(double threshold)
{
if (activeDestination != NULL)
@@ -730,7 +813,7 @@ bool Unit::isDestinationReached(double threshold)
{
double dist = 0;
Geodesic::WGS84().Inverse(p->getPosition().lat, p->getPosition().lng, activeDestination.lat, activeDestination.lng, dist);
if (dist < threshold)
if (dist < (activeDestination.threshold == 0? threshold: activeDestination.threshold))
{
log(unitName + " destination reached");
return true;
@@ -811,3 +894,11 @@ void Unit::setHasTaskAssigned(bool newHasTaskAssigned) {
void Unit::triggerUpdate(unsigned char datumIndex) {
updateTimeMap[datumIndex] = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}
unsigned int Unit::computeTotalAmmo()
{
unsigned int totalShells = 0;
for (auto const& ammoItem : ammo)
totalShells += ammoItem.quantity;
return totalShells;
}

View File

@@ -151,7 +151,7 @@ void UnitsManager::deleteUnit(unsigned int ID, bool explosion, string explosionT
}
}
Unit* UnitsManager::getClosestUnit(Unit* unit, unsigned char coalition, vector<string> categories, double &distance) {
Unit* UnitsManager::getClosestUnit(Unit* unit, unsigned char coalition, vector<string> categories, double &distance, bool airborneOnly) {
Unit* closestUnit = nullptr;
distance = 0;
@@ -167,6 +167,9 @@ Unit* UnitsManager::getClosestUnit(Unit* unit, unsigned char coalition, vector<s
/* Check if the unit belongs to the desired coalition, is alive, and is of the category requested */
if (requestedCategory && p.second->getCoalition() == coalition && p.second->getAlive()) {
/* Check if the unit is airborne */
if (airborneOnly && !p.second->getAirborne())
continue;
/* Compute the distance from the unit to the tested unit */
double dist;
double bearing1;
@@ -194,10 +197,13 @@ Unit* UnitsManager::getClosestUnit(Unit* unit, unsigned char coalition, vector<s
return closestUnit;
}
map<Unit*, double> UnitsManager::getUnitsInRange(Unit* unit, unsigned char coalition, vector<string> categories, double range) {
map<Unit*, double> UnitsManager::getUnitsInRange(Unit* unit, unsigned char coalition, vector<string> categories, double range, bool airborneOnly) {
map<Unit*, double> unitsInRange;
for (auto const& p : units) {
if (airborneOnly && !p.second->getAirborne())
continue;
/* Check if the units category is of the correct type */
bool requestedCategory = false;
for (auto const& category : categories) {

View File

@@ -113,4 +113,11 @@ Bomb::Bomb(json::value json, unsigned int ID) : Weapon(json, ID)
{
log("New Bomb created with ID: " + to_string(ID));
setCategory("Bomb");
};
/* Shell */
Shell::Shell(json::value json, unsigned int ID) : Weapon(json, ID)
{
log("New Shell created with ID: " + to_string(ID));
setCategory("Shell");
};

View File

@@ -41,6 +41,8 @@ void WeaponsManager::update(json::value& json, double dt)
weapons[ID] = dynamic_cast<Weapon*>(new Missile(p.second, ID));
else if (category.compare("Bomb") == 0)
weapons[ID] = dynamic_cast<Weapon*>(new Bomb(p.second, ID));
else if (category.compare("Shell") == 0)
weapons[ID] = dynamic_cast<Weapon*>(new Shell(p.second, ID));
/* Initialize the weapon if creation was successfull */
if (weapons.count(ID) != 0) {

View File

@@ -61,7 +61,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,4,0
FILEVERSION 2,0,0,0
PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -79,12 +79,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DCS Olympus"
VALUE "FileDescription", "DCS Olympus"
VALUE "FileVersion", "1.0.4.0"
VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "dcstools.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "dcstools.dll"
VALUE "ProductName", "DCS Olympus"
VALUE "ProductVersion", "1.0.4.0"
VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -7,6 +7,7 @@ void DllExport LogWarning(lua_State* L, string message);
void DllExport LogError(lua_State* L, string message);
void DllExport Log(lua_State* L, string message, unsigned int level);
int DllExport dostring_in(lua_State* L, string target, string command);
int DllExport dostring_in(lua_State* L, string target, string command, string& result);
void DllExport getAllUnits(lua_State* L, map<unsigned int, json::value>& unitJSONs);
unsigned int DllExport TACANChannelToFrequency(unsigned int channel, char XY);

View File

@@ -101,7 +101,24 @@ int dostring_in(lua_State* L, string target, string command)
lua_getfield(L, -1, "dostring_in");
lua_pushstring(L, target.c_str());
lua_pushstring(L, command.c_str());
return lua_pcall(L, 2, 0, 0);
int res = lua_pcall(L, 2, 0, 0);
return res;
}
int dostring_in(lua_State* L, string target, string command, string &result)
{
lua_getglobal(L, "net");
lua_getfield(L, -1, "dostring_in");
lua_pushstring(L, target.c_str());
lua_pushstring(L, command.c_str());
int res = lua_pcall(L, 2, 0, 0);
// Get the first result in the stack
if (lua_isstring(L, -1)) {
result = lua_tostring(L, -1);
}
return res;
}
unsigned int TACANChannelToFrequency(unsigned int channel, char XY)

View File

@@ -61,7 +61,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,4,0
FILEVERSION 2,0,0,0
PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -79,12 +79,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DCS Olympus"
VALUE "FileDescription", "DCS Olympus"
VALUE "FileVersion", "1.0.4.0"
VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "logger.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "logger.dll"
VALUE "ProductName", "DCS Olympus"
VALUE "ProductVersion", "1.0.4.0"
VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -61,7 +61,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,4,0
FILEVERSION 2,0,0,0
PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -79,12 +79,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DCS Olympus"
VALUE "FileDescription", "DCS Olympus"
VALUE "FileVersion", "1.0.4.0"
VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "luatools.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "luatools.dll"
VALUE "ProductName", "DCS Olympus"
VALUE "ProductVersion", "1.0.4.0"
VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -61,7 +61,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,4,0
FILEVERSION 2,0,0,0
PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -79,12 +79,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DCS Olympus"
VALUE "FileDescription", "DCS Olympus"
VALUE "FileVersion", "1.0.4.0"
VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "olympus.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "olympus.dll"
VALUE "ProductName", "DCS Olympus"
VALUE "ProductVersion", "1.0.4.0"
VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -11,12 +11,16 @@ typedef int(__stdcall* f_coreFrame)(lua_State* L);
typedef int(__stdcall* f_coreUnitsData)(lua_State* L);
typedef int(__stdcall* f_coreWeaponsData)(lua_State* L);
typedef int(__stdcall* f_coreMissionData)(lua_State* L);
typedef int(__stdcall* f_coreDrawingsData)(lua_State* L);
typedef int(__stdcall* f_coreSetExecutionResults)(lua_State* L);
f_coreInit coreInit = nullptr;
f_coreDeinit coreDeinit = nullptr;
f_coreFrame coreFrame = nullptr;
f_coreUnitsData coreUnitsData = nullptr;
f_coreWeaponsData coreWeaponsData = nullptr;
f_coreMissionData coreMissionData = nullptr;
f_coreDrawingsData coreDrawingsData = nullptr;
f_coreSetExecutionResults coreExecutionResults = nullptr;
string modPath;
@@ -108,6 +112,20 @@ static int onSimulationStart(lua_State* L)
goto error;
}
coreDrawingsData = (f_coreDrawingsData)GetProcAddress(hGetProcIDDLL, "coreDrawingsData");
if (!coreDrawingsData)
{
LogError(L, "Error getting coreDrawingsData ProcAddress from DLL");
goto error;
}
coreExecutionResults = (f_coreSetExecutionResults)GetProcAddress(hGetProcIDDLL, "coreSetExecutionResults");
if (!coreExecutionResults)
{
LogError(L, "Error getting coreSetExecutionResults ProcAddress from DLL");
goto error;
}
coreInit(L, modPath.c_str());
LogInfo(L, "Module loaded and started successfully.");
@@ -155,6 +173,8 @@ static int onSimulationStop(lua_State* L)
coreUnitsData = nullptr;
coreWeaponsData = nullptr;
coreMissionData = nullptr;
coreDrawingsData = nullptr;
}
hGetProcIDDLL = NULL;
@@ -193,6 +213,24 @@ static int setMissionData(lua_State* L)
return 0;
}
static int setDrawingsData(lua_State* L)
{
if (coreDrawingsData)
{
coreDrawingsData(L);
}
return 0;
}
static int setExecutionResults(lua_State* L)
{
if (coreExecutionResults)
{
coreExecutionResults(L);
}
return 0;
}
static const luaL_Reg Map[] = {
{"onSimulationStart", onSimulationStart},
{"onSimulationFrame", onSimulationFrame},
@@ -200,6 +238,8 @@ static const luaL_Reg Map[] = {
{"setUnitsData", setUnitsData },
{"setWeaponsData", setWeaponsData },
{"setMissionData", setMissionData },
{"setDrawingsData", setDrawingsData },
{"setExecutionResults", setExecutionResults },
{NULL, NULL}
};

View File

@@ -10,8 +10,10 @@
#define LOGS_URI "logs"
#define AIRBASES_URI "airbases"
#define BULLSEYE_URI "bullseyes"
#define SPOTS_URI "spots"
#define MISSION_URI "mission"
#define COMMANDS_URI "commands"
#define DRAWINGS_URI "drawings"
#define FRAMERATE_TIME_INTERVAL 0.05

View File

@@ -6,6 +6,7 @@ struct Coords {
double lat = 0;
double lng = 0;
double alt = 0;
double threshold = 0; // used for proximity checks only, not part of the actual coordinates
};
struct Offset {

View File

@@ -1,5 +1,6 @@
#include "framework.h"
#include "utils.h"
#include <chrono>
// Get current date/time, format is YYYY-MM-DD.HH:mm:ss
const std::string CurrentDateTime()
@@ -44,7 +45,11 @@ std::string to_string(const std::wstring& wstr)
std::string random_string(size_t length)
{
srand(static_cast<unsigned int>(time(NULL)));
// Use nanoseconds since epoch as a seed for random number generation
auto now = std::chrono::high_resolution_clock::now();
auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
srand(static_cast<unsigned int>(nanos));
auto randchar = []() -> char
{
const char charset[] =
@@ -59,9 +64,9 @@ std::string random_string(size_t length)
return str;
}
bool operator== (const Coords& a, const Coords& b) { return a.lat == b.lat && a.lng == b.lng && a.alt == b.alt; }
bool operator== (const Coords& a, const Coords& b) { return a.lat == b.lat && a.lng == b.lng && a.alt == b.alt && a.threshold == b.threshold; }
bool operator!= (const Coords& a, const Coords& b) { return !(a == b); }
bool operator== (const Coords& a, const double& b) { return a.lat == b && a.lng == b && a.alt == b; }
bool operator== (const Coords& a, const double& b) { return a.lat == b && a.lng == b && a.alt == b && a.threshold == b; }
bool operator!= (const Coords& a, const double& b) { return !(a == b); }
bool operator== (const Offset& a, const Offset& b) { return a.x == b.x && a.y == b.y && a.z == b.z; }

View File

@@ -61,7 +61,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,4,0
FILEVERSION 2,0,0,0
PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
@@ -79,12 +79,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DCS Olympus"
VALUE "FileDescription", "DCS Olympus"
VALUE "FileVersion", "1.0.4.0"
VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "utils.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "utils.dll"
VALUE "ProductName", "TODO: <Product name>"
VALUE "ProductVersion", "1.0.4.0"
VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
{
}

File diff suppressed because it is too large Load Diff

BIN
docs/images/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/images/mods1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

720
docs/mods.json Normal file
View File

@@ -0,0 +1,720 @@
{
"A-4E-C": {
"loadouts": [
{
"name": "FFAR Mk1 HE *76, Fuel 300G",
"items": [
{ "name": "FFAR Mk1 HE", "quantity": 76 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "FFAR Mk1 HE *76, Fuel 300G",
"roles": ["CAS"]
},
{
"name": "Mk-82 SE *12",
"items": [{ "name": "Mk-82 Snakeye", "quantity": 12 }],
"enabled": true,
"code": "Mk-82 SE *12",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-82 *6, Fuel 150G *2",
"items": [
{ "name": "Mk-82", "quantity": 6 },
{ "name": "Fuel Tank 150G", "quantity": 2 }
],
"enabled": true,
"code": "Mk-82 *6, Fuel 150G *2",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-82 SE *6, Fuel 150G *2",
"items": [
{ "name": "Mk-82 Snakeye", "quantity": 6 },
{ "name": "Fuel Tank 150G", "quantity": 2 }
],
"enabled": true,
"code": "Mk-82 SE *6, Fuel 150G *2",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-83 *3, Fuel 300G *2",
"items": [
{ "name": "Mk-83", "quantity": 3 },
{ "name": "Fuel Tank 300G", "quantity": 2 }
],
"enabled": true,
"code": "Mk-83 *3, Fuel 300G *2",
"roles": ["Strike"]
},
{
"name": "Mk-84 *3",
"items": [{ "name": "Mk-84", "quantity": 3 }],
"enabled": true,
"code": "Mk-84 *3",
"roles": ["Strike"]
},
{
"name": "Mk-83 *5",
"items": [{ "name": "Mk-83", "quantity": 5 }],
"enabled": true,
"code": "Mk-83 *5",
"roles": ["Strike"]
},
{
"name": "Mk-84 *3, Mk-82 *2",
"items": [
{ "name": "Mk-84", "quantity": 3 },
{ "name": "Mk-82", "quantity": 2 }
],
"enabled": true,
"code": "Mk-84 *3, Mk-82 *2",
"roles": ["Strike"]
},
{
"name": "Mk-82 SE *8, Mk-81 SE *10",
"items": [
{ "name": "Mk-82 Snakeye", "quantity": 8 },
{ "name": "Mk-81 Snakeye", "quantity": 10 }
],
"enabled": true,
"code": "Mk-82 SE *8, Mk-81 SE *10",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-81 *18",
"items": [{ "name": "Mk-81", "quantity": 18 }],
"enabled": true,
"code": "Mk-81 *18",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-77 mod 0 *2, Mk-77 mod 1 *4",
"items": [
{ "name": "Mk-77 mod 0", "quantity": 2 },
{ "name": "Mk-77 mod 1", "quantity": 4 }
],
"enabled": true,
"code": "Mk-77 mod 0 *2, Mk-77 mod 1 *4",
"roles": ["Strike"]
},
{
"name": "Mk-82 *6, LAU-10 *4",
"items": [
{ "name": "Mk-82", "quantity": 6 },
{ "name": "LAU-10", "quantity": 4 }
],
"enabled": true,
"code": "Mk-82 *6, LAU-10 *4",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-4 HIPEG *2, Fuel 300G",
"items": [
{ "name": "Mk-4 HIPEG", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "Mk-4 HIPEG *2, Fuel 300G",
"roles": ["CAS"]
},
{
"name": "LAU-10 *2, FFAR Mk1 HE *38, Fuel 300G",
"items": [
{ "name": "LAU-10", "quantity": 2 },
{ "name": "FFAR Mk1 HE", "quantity": 38 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "LAU-10 *2, FFAR Mk1 HE *38, Fuel 300G",
"roles": ["CAS"]
},
{
"name": "FFAR Mk5 HEAT *76, Fuel 300G",
"items": [
{ "name": "FFAR Mk5 HEAT", "quantity": 76 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "FFAR Mk5 HEAT *76, Fuel 300G",
"roles": ["CAS"]
},
{
"name": "AGM-45B *2, LAU-10 *2, Fuel 300G",
"items": [
{ "name": "AGM-45B", "quantity": 2 },
{ "name": "LAU-10", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "AGM-45B *2, LAU-10 *2, Fuel 300G",
"roles": ["SEAD"]
},
{
"name": "AGM-45B *4, Fuel 300G",
"items": [
{ "name": "AGM-45B", "quantity": 4 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "AGM-45B *4, Fuel 300G",
"roles": ["SEAD"]
},
{
"name": "CBU-2/A *2, Fuel 300G",
"items": [
{ "name": "CBU-2/A", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "CBU-2/A *2, Fuel 300G",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-4 HIPEG *3, Mk-82SE *2",
"items": [
{ "name": "Mk-4 HIPEG", "quantity": 3 },
{ "name": "Mk-82 Snakeye", "quantity": 2 }
],
"enabled": true,
"code": "Mk-4 HIPEG *3, Mk-82SE *2",
"roles": ["CAS"]
},
{
"name": "Mk-81 SE *6, LAU-10 *2, Fuel 150G *2",
"items": [
{ "name": "Mk-81 Snakeye", "quantity": 6 },
{ "name": "LAU-10", "quantity": 2 },
{ "name": "Fuel Tank 150G", "quantity": 2 }
],
"enabled": true,
"code": "Mk-81 SE *6, LAU-10 *2, Fuel 150G *2",
"roles": ["CAS"]
},
{
"name": "AGM-45B *4",
"items": [{ "name": "AGM-45B", "quantity": 4 }],
"enabled": true,
"code": "AGM-45B *4",
"roles": ["SEAD"]
},
{
"name": "Mk-83 *5, Mk-82 *2",
"items": [
{ "name": "Mk-83", "quantity": 5 },
{ "name": "Mk-82", "quantity": 2 }
],
"enabled": true,
"code": "Mk-83 *5, Mk-82 *2",
"roles": ["Strike"]
},
{
"name": "Mk-81 SE *18",
"items": [{ "name": "Mk-81 Snakeye", "quantity": 18 }],
"enabled": true,
"code": "Mk-81 SE *18",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-81 SE *12, Fuel 300G",
"items": [
{ "name": "Mk-81 Snakeye", "quantity": 12 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "Mk-81 SE *12, Fuel 300G",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-84 *2, Fuel 300G",
"items": [
{ "name": "Mk-84", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "Mk-84 *2, Fuel 300G",
"roles": ["Strike"]
},
{
"name": "CBU-2/A *2, Mk-82 SE *2, Fuel 300G",
"items": [
{ "name": "CBU-2/A", "quantity": 2 },
{ "name": "Mk-82 Snakeye", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "CBU-2/A *2, Mk-82 SE *2, Fuel 300G",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-4 HIPEG *3, LAU-10 *2",
"items": [
{ "name": "Mk-4 HIPEG", "quantity": 3 },
{ "name": "LAU-10", "quantity": 2 }
],
"enabled": true,
"code": "Mk-4 HIPEG *3, LAU-10 *2",
"roles": ["CAS"]
},
{
"name": "Mk-81 SE *10, LAU-10 *2, Fuel 300G",
"items": [
{ "name": "Mk-81 Snakeye", "quantity": 10 },
{ "name": "LAU-10", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "Mk-81 SE *10, LAU-10 *2, Fuel 300G",
"roles": ["CAS"]
},
{
"name": "AGM-45B *2",
"items": [{ "name": "AGM-45B", "quantity": 2 }],
"enabled": true,
"code": "AGM-45B *2",
"roles": ["SEAD"]
},
{
"name": "GAR-8 *2, Fuel 150G",
"items": [
{ "name": "GAR-8", "quantity": 2 },
{ "name": "Fuel Tank 150G", "quantity": 1 }
],
"enabled": true,
"code": "GAR-8 *2, Fuel 150G",
"roles": ["CAP"]
},
{
"name": "AGM-45B *2, Fuel 300G *2",
"items": [
{ "name": "AGM-45B", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 2 }
],
"enabled": true,
"code": "AGM-45B *2, Fuel 300G *2",
"roles": ["SEAD"]
},
{
"name": "Mk-82 *12",
"items": [{ "name": "Mk-82", "quantity": 12 }],
"enabled": true,
"code": "Mk-82 *12",
"roles": ["CAS", "Strike"]
},
{
"name": "CBU-2/A *2, Mk-20 *2, Fuel 300G",
"items": [
{ "name": "CBU-2/A", "quantity": 2 },
{ "name": "Mk-20", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "CBU-2/A *2, Mk-20 *2, Fuel 300G",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-4 HIPEG *3",
"items": [{ "name": "Mk-4 HIPEG", "quantity": 3 }],
"enabled": true,
"code": "Mk-4 HIPEG *3",
"roles": ["CAS"]
},
{
"name": "AGM-45B *2, LAU-10 *2",
"items": [
{ "name": "AGM-45B", "quantity": 2 },
{ "name": "LAU-10", "quantity": 2 }
],
"enabled": true,
"code": "AGM-45B *2, LAU-10 *2",
"roles": ["SEAD"]
},
{
"name": "FFAR M156 WP *38, M257 Illumination *14, Fuel 300G",
"items": [
{ "name": "FFAR M156 WP", "quantity": 38 },
{ "name": "M257 Illumination", "quantity": 14 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "FFAR M156 WP *38, M257 Illumination *14, Fuel 300G",
"roles": ["CAS"]
},
{
"name": "FFAR M156 WP *38, M257 Illumination *14, Mk-82 SE *6",
"items": [
{ "name": "FFAR M156 WP", "quantity": 38 },
{ "name": "M257 Illumination", "quantity": 14 },
{ "name": "Mk-82 Snakeye", "quantity": 6 }
],
"enabled": true,
"code": "FFAR M156 WP *38, M257 Illumination *14, Mk-82 SE *6",
"roles": ["CAS"]
},
{
"name": "FFAR M156 WP *38, Mk-82 SE *2, Mk-4 HIPEG",
"items": [
{ "name": "FFAR M156 WP", "quantity": 38 },
{ "name": "Mk-82 Snakeye", "quantity": 2 },
{ "name": "Mk-4 HIPEG", "quantity": 1 }
],
"enabled": true,
"code": "FFAR M156 WP *38, Mk-82 SE *2, Mk-4 HIPEG",
"roles": ["CAS"]
},
{
"name": "Mk-4 HIPEG *2, FFAR M156 WP *19, LAU-10, M257 Illumination *7",
"items": [
{ "name": "Mk-4 HIPEG", "quantity": 2 },
{ "name": "FFAR M156 WP", "quantity": 19 },
{ "name": "LAU-10", "quantity": 1 },
{ "name": "M257 Illumination", "quantity": 7 }
],
"enabled": true,
"code": "Mk-4 HIPEG *2, FFAR M156 WP *19, LAU-10, M257 Illumination *7",
"roles": ["CAS"]
},
{
"name": "Fuel 300G *3 (Ferry)",
"items": [{ "name": "Fuel Tank 300G", "quantity": 3 }],
"enabled": true,
"code": "Fuel 300G *3 (Ferry)",
"roles": ["Ferry"]
},
{
"name": "CBU-2/A *2, LAU-10 *2, Fuel 300G",
"items": [
{ "name": "CBU-2/A", "quantity": 2 },
{ "name": "LAU-10", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "CBU-2/A *2, LAU-10 *2, Fuel 300G",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-82 *8, Fuel 150G *2",
"items": [
{ "name": "Mk-82", "quantity": 8 },
{ "name": "Fuel Tank 150G", "quantity": 2 }
],
"enabled": true,
"code": "Mk-82 *8, Fuel 150G *2",
"roles": ["CAS", "Strike"]
},
{
"name": "Mk-82 SE *8, Fuel 150G *2",
"items": [
{ "name": "Mk-82 Snakeye", "quantity": 8 },
{ "name": "Fuel Tank 150G", "quantity": 2 }
],
"enabled": true,
"code": "Mk-82 SE *8, Fuel 150G *2",
"roles": ["CAS", "Strike"]
},
{
"name": "GAR-8 *2, Fuel 300G",
"items": [
{ "name": "GAR-8", "quantity": 2 },
{ "name": "Fuel Tank 300G", "quantity": 1 }
],
"enabled": true,
"code": "GAR-8 *2, Fuel 300G",
"roles": ["CAP"]
}
],
"name": "A-4E-C",
"coalition": "blue",
"era": "Mid Cold War",
"category": "aircraft",
"label": "A-4E-C Skyhawk",
"shortLabel": "A4E",
"filename": "a-4.png",
"enabled": true,
"type": "Aircraft",
"description": "1 jet engine, straight wing, 1 crew, attack aircraft. Skyhawk",
"abilities": "",
"canTargetPoint": true,
"canRearm": false,
"length": 53,
"liveries": {
"aggressor usmc topgun mig-17": {
"name": "USMC Aggressor TOPGUN 56 (MiG-17), 1982",
"countries": ["AUSAF"]
},
"aggressor usn topgun": {
"name": "USN Aggressor TOPGUN, 1982",
"countries": ["AUSAF"]
},
"aggressor usn vf-126 bandits": {
"name": "USN Aggressor VF-126 Bandits, 1976",
"countries": ["AUSAF"]
},
"aggressor usn vf-127 royal blues": {
"name": "USN Aggressor VF-127 Royal Blues, 1982",
"countries": ["AUSAF"]
},
"aggressor usn vfa-127 cyclons (forest)": {
"name": "USN Aggressor VFA-127 Cyclons (Forest), 1986",
"countries": ["AUSAF"]
},
"aggressor usn vfa-127 cyclons (sea)": {
"name": "USN Aggressor VFA-127 Cyclons (Sea), 1987",
"countries": ["AUSAF"]
},
"blue angels no 1": {
"name": "Blue Angels no. 1, 1986",
"countries": ["USA"]
},
"blue angels no 2": {
"name": "Blue Angels no. 2, 1986",
"countries": ["USA"]
},
"blue angels no 3": {
"name": "Blue Angels no. 3, 1986",
"countries": ["USA"]
},
"blue angels no 4": {
"name": "Blue Angels no. 4, 1986",
"countries": ["USA"]
},
"blue angels no 5": {
"name": "Blue Angels no. 5, 1986",
"countries": ["USA"]
},
"blue angels no 6": {
"name": "Blue Angels no. 6, 1986",
"countries": ["USA"]
},
"community a-4e": {
"name": "Community A-4E I: Autumn Splinter, 2018 (Fictional)",
"countries": "All"
},
"community a-4e ii": {
"name": "Community A-4E II: Winter Splinter, 2019 (Fictional)",
"countries": "All"
},
"community a-4e iii": {
"name": "Community A-4E III: Forever Free, 2021 (Fictional)",
"countries": "All"
},
"community a-4e iv": {
"name": "Community A-4E IV: Sea Otter, 2021 (Fictional)",
"countries": "All"
},
"community a-4e v-1": {
"name": "Community A-4E V: Blue Team, 2022 (Fictional)",
"countries": "All"
},
"community a-4e v-2": {
"name": "Community A-4E V: Red Team, 2022 (Fictional)",
"countries": "All"
},
"international argentina": {
"name": "Argentina ARA 309, 1982",
"countries": ["ARG"]
},
"international argentina brigada iv": {
"name": "Argentina FAA Falklands Brigada IV, 1982",
"countries": ["ARG"]
},
"international argentina brigada v": {
"name": "Argentina FAA Falklands Brigada V, 1982",
"countries": ["ARG"]
},
"international australia": {
"name": "Australian Navy, 1972",
"countries": ["AUS"]
},
"international australia squadron 805": {
"name": "Australian Navy Squadron 805, 1972",
"countries": ["AUS"]
},
"international brazil": {
"name": "Brazil Marinha do Brasil VF-1 Falcoes, 1998",
"countries": ["BRA"]
},
"international brazil loviz": {
"name": "Brazil Marinha do Brasil VF-1 LoViz, 2018",
"countries": ["BRA"]
},
"international brazil vf-1 15 anos": {
"name": "Brazil Marinha do Brasil VF-1 15 ANOS, 2013",
"countries": ["BRA"]
},
"international finnish air force": {
"name": "Finland FiAF, 1984 (Fictional)",
"countries": ["FIN"]
},
"international israel": {
"name": "Israel IAF Knights of the North Squadron, 1973",
"countries": ["ISR"]
},
"international kuwait": {
"name": "Kuwait KAF Free Kuwait, 1991",
"countries": ["KWT"]
},
"international malaysia tudm": {
"name": "Malaysia TUDM M32-29 No.9 Squadron, 2004",
"countries": ["MYS"]
},
"international new zealand 50th": {
"name": "RNZAF Golden T-Bird No.2, Squadron Ohakea, 1986",
"countries": ["AUS"]
},
"international new zealand kahu": {
"name": "RNZAF Kahu, 1988",
"countries": ["AUS"]
},
"international new zealand kiwi red": {
"name": "RNZAF Kiwi Red, 2011",
"countries": ["AUS"]
},
"international new zealand sqn 75": {
"name": "RNZAF Squadron 75, 1982",
"countries": ["AUS"]
},
"trainer bae systems": {
"name": "BAE Systems, 2013",
"countries": ["UK"]
},
"trainer raf epts raspberry ripple": {
"name": "RAF Empire Pilots Test School Raspberry Ripple, 2021 (Fictional)",
"countries": ["UK"]
},
"trainer usmc nwef": {
"name": "USMC Naval Weapons Evaluation Facility, 1974",
"countries": ["USA"]
},
"trainer usmc ptmc": {
"name": "USMC Pacific Missile Test Center, 1978",
"countries": ["USA"]
},
"trainer usmc vmat-102": {
"name": "USMC VMAT-102, 1980",
"countries": ["USA"]
},
"trainer usn bare metal 1956": {
"name": "USN Bare Metal, 1956",
"countries": ["USA"]
},
"trainer usn nfws gray": {
"name": "USN Naval Fighter Weapons School (Gray), 1980",
"countries": ["USA"]
},
"trainer usn nfws green": {
"name": "USN Naval Fighter Weapons School (Green), 1980",
"countries": ["USA"]
},
"trainer usn vc-1 flecompron one": {
"name": "USN VC-1 FLECOMPRON One, 1974",
"countries": ["USA"]
},
"trainer usn vc-10 challengers": {
"name": "USN VC-10 Challengers, 1988",
"countries": ["USA"]
},
"trainer usn vc-5 checkertails": {
"name": "USN VC-5 Checkertails, 1991",
"countries": ["USA"]
},
"trainer usn vc-8 redtails": {
"name": "USN VC-8 Redtails, 1985",
"countries": ["USA"]
},
"trainer usn vt-7 eagles": {
"name": "USN VT-7 Eagles, 1972",
"countries": ["USA"]
},
"trainer usn vx-5 vampires": {
"name": "USN VX-5 Vampires, 1986 (Fictional)",
"countries": ["USA"]
},
"unmarked": {
"name": "0 Unmarked",
"countries": "All"
},
"usmc vma-121 green knights": {
"name": "USMC VMA-121 Green Knights, 1968",
"countries": ["USA"]
},
"usmc vma-124 memphis marines": {
"name": "USMC VMA-124 Memphis Marines, 1973",
"countries": ["USA"]
},
"usmc vma-131 diamondbacks": {
"name": "USMC VMA-131 Diamondbacks, 1976",
"countries": ["USA"]
},
"usmc vma-142 flying gators": {
"name": "USMC VMA-142 Flying Gators, 1973",
"countries": ["USA"]
},
"usmc vma-211 avengers": {
"name": "USMC VMA-211 Avengers, 1972",
"countries": ["USA"]
},
"usmc vma-311 tomcats": {
"name": "USMC VMA-311 Tomcats, 1972",
"countries": ["USA"]
},
"usmc vma-322 fighting gamecocks": {
"name": "USMC VMA-322 Fighting Gamecocks, 1972",
"countries": ["USA"]
},
"usn va-106 gladiators": {
"name": "USN VA-106 Gladiators, 1967",
"countries": ["USA"]
},
"usn va-144 roadrunners": {
"name": "USN VA-144 Roadrunners, 1970",
"countries": ["USA"]
},
"usn va-153 blue tail flies": {
"name": "USN VA-153 Blue Tail Flies, 1972",
"countries": ["USA"]
},
"usn va-163 saints": {
"name": "USN VA-163 Saints, 1969",
"countries": ["USA"]
},
"usn va-164 ghostriders": {
"name": "USN VA-164 Ghostriders LADY JESSIE, 1988",
"countries": ["USA"]
},
"usn va-195 dambusters": {
"name": "USN VA-195 Dambusters, 1972",
"countries": ["USA"]
},
"usn va-212 rampant raiders": {
"name": "USN VA-212 Rampant Raiders, 1972",
"countries": ["USA"]
},
"usn va-45 blackbirds": {
"name": "USN VA-45 Blackbirds, 1972",
"countries": ["USA"]
},
"usn va-46 clansmen": {
"name": "USN VA-46 Clansmen, 1967",
"countries": ["USA"]
},
"usn va-55 warhorses": {
"name": "USN VA-55 Warhorses, 1972",
"countries": ["USA"]
},
"usn va-64 black lancers": {
"name": "USN VA-64 Black Lancers, 1972",
"countries": ["USA"]
},
"usn va-83 rampagers": {
"name": "USN VA-83 Rampagers, 1966",
"countries": ["USA"]
},
"usn vc-7 tallyhoers": {
"name": "USN VC-7 TallyHOers, 1972",
"countries": ["USA"]
}
}
}
}

296
docs/mods.lua Normal file
View File

@@ -0,0 +1,296 @@
-- Enter here any mods required by your mission as in the example below.
-- Possible categories are:
-- Aircraft
-- Helicopter
-- GroundUnit
-- NavyUnit
Olympus.modsList = {
["A-4E-C"] = "Aircraft",
["Bronco-OV-10A"] = "Aircraft"
}
-- Enter here any unitPayloads you want to use for your mods. Remember to add the payload to the database in mods.json!
-- DO NOT ADD PAYLOADS TO "ORIGINAL" DCS UNITS HERE! To add payloads to original DCS units, use the "unitPayload.lua" table instead and add them under the correct unit section.
Olympus.modsUnitPayloads = {
["A-4E-C"] = {
["FFAR Mk1 HE *76, Fuel 300G"] = {
[5] = { ["CLSID"] = "{LAU3_FFAR_MK1HE}" },
[4] = { ["CLSID"] = "{LAU3_FFAR_MK1HE}" },
[2] = { ["CLSID"] = "{LAU3_FFAR_MK1HE}" },
[1] = { ["CLSID"] = "{LAU3_FFAR_MK1HE}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
},
["Mk-82 SE *12"] = {
[3] = { ["CLSID"] = "{Mk-82 Snakeye_MER_6_C}" },
[2] = { ["CLSID"] = "{Mk-82 Snakeye_TER_2_L}" },
[4] = { ["CLSID"] = "{Mk-82 Snakeye_TER_2_R}" },
[1] = { ["CLSID"] = "{Mk82SNAKEYE}" },
[5] = { ["CLSID"] = "{Mk82SNAKEYE}" }
},
["Mk-82 *6, Fuel 150G *2"] = {
[3] = { ["CLSID"] = "{Mk-82_MER_6_C}" },
[4] = { ["CLSID"] = "{DFT-150gal}" },
[2] = { ["CLSID"] = "{DFT-150gal}" }
},
["Mk-82 SE *6, Fuel 150G *2"] = {
[3] = { ["CLSID"] = "{Mk-82 Snakeye_MER_6_C}" },
[4] = { ["CLSID"] = "{DFT-150gal}" },
[2] = { ["CLSID"] = "{DFT-150gal}" }
},
["Mk-83 *3, Fuel 300G *2"] = {
[3] = { ["CLSID"] = "{Mk-83_TER_3_C}" },
[2] = { ["CLSID"] = "{DFT-300gal_LR}" },
[4] = { ["CLSID"] = "{DFT-300gal_LR}" }
},
["Mk-84 *3"] = {
[3] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" },
[2] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" },
[4] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }
},
["Mk-83 *5"] = {
[3] = { ["CLSID"] = "{Mk-83_TER_3_C}" },
[2] = { ["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}" },
[4] = { ["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}" }
},
["Mk-84 *3, Mk-82 *2"] = {
[3] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" },
[2] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" },
[4] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" },
[1] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" },
[5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }
},
["Mk-82 SE *8, Mk-81 SE *10"] = {
[4] = { ["CLSID"] = "{Mk-81SE_MER_5_R}" },
[2] = { ["CLSID"] = "{Mk-81SE_MER_5_L}" },
[3] = { ["CLSID"] = "{Mk-82 Snakeye_MER_6_C}" },
[1] = { ["CLSID"] = "{Mk82SNAKEYE}" },
[5] = { ["CLSID"] = "{Mk82SNAKEYE}" }
},
["Mk-81 *18"] = {
[4] = { ["CLSID"] = "{Mk-81_MER_5_R}" },
[2] = { ["CLSID"] = "{Mk-81_MER_5_L}" },
[3] = { ["CLSID"] = "{Mk-81_MER_6_C}" },
[1] = { ["CLSID"] = "{90321C8E-7ED1-47D4-A160-E074D5ABD902}" },
[5] = { ["CLSID"] = "{90321C8E-7ED1-47D4-A160-E074D5ABD902}" }
},
["Mk-77 mod 0 *2, Mk-77 mod 1 *4"] = {
[5] = { ["CLSID"] = "{mk77mod1}" },
[4] = { ["CLSID"] = "{mk77mod0}" },
[2] = { ["CLSID"] = "{mk77mod0}" },
[1] = { ["CLSID"] = "{mk77mod1}" },
[3] = { ["CLSID"] = "{Mk-77 mod 1_TER_2_C}" }
},
["Mk-82 *6, LAU-10 *4"] = {
[3] = { ["CLSID"] = "{Mk-82_MER_6_C}" },
[4] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[2] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["Mk-4 HIPEG *2, Fuel 300G"] = {
[3] = { ["CLSID"] = "{DFT-400gal}" },
[2] = { ["CLSID"] = "{Mk4 HIPEG}" },
[4] = { ["CLSID"] = "{Mk4 HIPEG}" }
},
["LAU-10 *2, FFAR Mk1 HE *38, Fuel 300G"] = {
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[4] = { ["CLSID"] = "{LAU3_FFAR_MK1HE}" },
[2] = { ["CLSID"] = "{LAU3_FFAR_MK1HE}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
},
["FFAR Mk5 HEAT *76, Fuel 300G"] = {
[5] = { ["CLSID"] = "{LAU3_FFAR_MK5HEAT}" },
[4] = { ["CLSID"] = "{LAU3_FFAR_MK5HEAT}" },
[2] = { ["CLSID"] = "{LAU3_FFAR_MK5HEAT}" },
[1] = { ["CLSID"] = "{LAU3_FFAR_MK5HEAT}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
},
["AGM-45B *2, LAU-10 *2, Fuel 300G"] = {
[2] = { ["CLSID"] = "{AGM_45A}" },
[4] = { ["CLSID"] = "{AGM_45A}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
},
["AGM-45B *4, Fuel 300G"] = {
[2] = { ["CLSID"] = "{AGM_45A}" },
[4] = { ["CLSID"] = "{AGM_45A}" },
[5] = { ["CLSID"] = "{AGM_45A}" },
[1] = { ["CLSID"] = "{AGM_45A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
},
["CBU-2/A *2, Fuel 300G"] = {
[4] = { ["CLSID"] = "{CBU-2/A}" },
[2] = { ["CLSID"] = "{CBU-2/A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
},
["Mk-4 HIPEG *3, Mk-82SE *2"] = {
[3] = { ["CLSID"] = "{Mk4 HIPEG}" },
[2] = { ["CLSID"] = "{Mk4 HIPEG}" },
[4] = { ["CLSID"] = "{Mk4 HIPEG}" },
[1] = { ["CLSID"] = "{Mk82SNAKEYE}" },
[5] = { ["CLSID"] = "{Mk82SNAKEYE}" }
},
["Mk-81 SE *6, LAU-10 *2, Fuel 150G *2"] = {
[4] = { ["CLSID"] = "{DFT-150gal}" },
[2] = { ["CLSID"] = "{DFT-150gal}" },
[3] = { ["CLSID"] = "{Mk-81SE_MER_6_C}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["AGM-45B *4"] = {
[2] = { ["CLSID"] = "{AGM_45A}" },
[4] = { ["CLSID"] = "{AGM_45A}" },
[5] = { ["CLSID"] = "{AGM_45A}" },
[1] = { ["CLSID"] = "{AGM_45A}" }
},
["Mk-83 *5, Mk-82 *2"] = {
[3] = { ["CLSID"] = "{Mk-83_TER_3_C}" },
[2] = { ["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}" },
[4] = { ["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}" },
[5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" },
[1] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }
},
["Mk-81 SE *18"] = {
[4] = { ["CLSID"] = "{Mk-81SE_MER_5_R}" },
[2] = { ["CLSID"] = "{Mk-81SE_MER_5_L}" },
[3] = { ["CLSID"] = "{Mk-81SE_MER_6_C}" },
[1] = { ["CLSID"] = "{MK-81SE}" },
[5] = { ["CLSID"] = "{MK-81SE}" }
},
["Mk-81 SE *12, Fuel 300G"] = {
[3] = { ["CLSID"] = "{DFT-300gal}" },
[2] = { ["CLSID"] = "{Mk-81SE_MER_5_L}" },
[1] = { ["CLSID"] = "{MK-81SE}" },
[4] = { ["CLSID"] = "{Mk-81SE_MER_5_R}" },
[5] = { ["CLSID"] = "{MK-81SE}" }
},
["Mk-84 *2, Fuel 300G"] = {
[3] = { ["CLSID"] = "{DFT-300gal}" },
[2] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" },
[4] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }
},
["CBU-2/A *2, Mk-82 SE *2, Fuel 300G"] = {
[4] = { ["CLSID"] = "{CBU-2/A}" },
[2] = { ["CLSID"] = "{CBU-2/A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" },
[5] = { ["CLSID"] = "{Mk82SNAKEYE}" },
[1] = { ["CLSID"] = "{Mk82SNAKEYE}" }
},
["Mk-4 HIPEG *3, LAU-10 *2"] = {
[3] = { ["CLSID"] = "{Mk4 HIPEG}" },
[2] = { ["CLSID"] = "{Mk4 HIPEG}" },
[4] = { ["CLSID"] = "{Mk4 HIPEG}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["Mk-81 SE *10, LAU-10 *2, Fuel 300G"] = {
[4] = { ["CLSID"] = "{Mk-81SE_MER_5_R}" },
[2] = { ["CLSID"] = "{Mk-81SE_MER_5_L}" },
[3] = { ["CLSID"] = "{DFT-300gal}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["AGM-45B *2"] = {
[2] = { ["CLSID"] = "{AGM_45A}" },
[4] = { ["CLSID"] = "{AGM_45A}" }
},
["GAR-8 *2, Fuel 150G"] = {
[2] = { ["CLSID"] = "{GAR-8}" },
[4] = { ["CLSID"] = "{GAR-8}" },
[3] = { ["CLSID"] = "{DFT-150gal}" }
},
["AGM-45B *2, Fuel 300G *2"] = {
[4] = { ["CLSID"] = "{DFT-300gal_LR}" },
[2] = { ["CLSID"] = "{DFT-300gal_LR}" },
[1] = { ["CLSID"] = "{AGM_45A}" },
[5] = { ["CLSID"] = "{AGM_45A}" }
},
["Mk-82 *12"] = {
[3] = { ["CLSID"] = "{Mk-82_MER_6_C}" },
[2] = { ["CLSID"] = "{Mk-82_TER_2_L}" },
[4] = { ["CLSID"] = "{Mk-82_TER_2_R}" },
[1] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" },
[5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }
},
["CBU-2/A *2, Mk-20 *2, Fuel 300G"] = {
[4] = { ["CLSID"] = "{CBU-2/A}" },
[2] = { ["CLSID"] = "{CBU-2/A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" },
[5] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" },
[1] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }
},
["Mk-4 HIPEG *3"] = {
[3] = { ["CLSID"] = "{Mk4 HIPEG}" },
[2] = { ["CLSID"] = "{Mk4 HIPEG}" },
[4] = { ["CLSID"] = "{Mk4 HIPEG}" }
},
["AGM-45B *2, LAU-10 *2"] = {
[2] = { ["CLSID"] = "{AGM_45A}" },
[4] = { ["CLSID"] = "{AGM_45A}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["FFAR M156 WP *38, M257 Illumination *14, Fuel 300G"] = {
[2] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[3] = { ["CLSID"] = "{DFT-300gal}" },
[4] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[5] = { ["CLSID"] = "{647C5F26-BDD1-41e6-A371-8DE1E4CC0E94}" },
[1] = { ["CLSID"] = "{647C5F26-BDD1-41e6-A371-8DE1E4CC0E94}" }
},
["FFAR M156 WP *38, M257 Illumination *14, Mk-82 SE *6"] = {
[2] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[3] = { ["CLSID"] = "{Mk-82 Snakeye_MER_6_C}" },
[4] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[5] = { ["CLSID"] = "{647C5F26-BDD1-41e6-A371-8DE1E4CC0E94}" },
[1] = { ["CLSID"] = "{647C5F26-BDD1-41e6-A371-8DE1E4CC0E94}" }
},
["FFAR M156 WP *38, Mk-82 SE *2, Mk-4 HIPEG"] = {
[2] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[3] = { ["CLSID"] = "{Mk4 HIPEG}" },
[4] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[5] = { ["CLSID"] = "{Mk82SNAKEYE}" },
[1] = { ["CLSID"] = "{Mk82SNAKEYE}" }
},
["Mk-4 HIPEG *2, FFAR M156 WP *19, LAU-10, M257 Illumination *7"] = {
[2] = { ["CLSID"] = "{LAU3_FFAR_WP156}" },
[3] = { ["CLSID"] = "{Mk4 HIPEG}" },
[4] = { ["CLSID"] = "{Mk4 HIPEG}" },
[5] = { ["CLSID"] = "{647C5F26-BDD1-41e6-A371-8DE1E4CC0E94}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["Fuel 300G *3 (Ferry)"] = {
[4] = { ["CLSID"] = "{DFT-300gal_LR}" },
[3] = { ["CLSID"] = "{DFT-300gal}" },
[2] = { ["CLSID"] = "{DFT-300gal_LR}" }
},
["CBU-2/A *2, LAU-10 *2, Fuel 300G"] = {
[4] = { ["CLSID"] = "{CBU-2/A}" },
[2] = { ["CLSID"] = "{CBU-2/A}" },
[3] = { ["CLSID"] = "{DFT-300gal}" },
[5] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" },
[1] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }
},
["Mk-82 *8, Fuel 150G *2"] = {
[3] = { ["CLSID"] = "{Mk-82_MER_6_C}" },
[4] = { ["CLSID"] = "{DFT-150gal}" },
[2] = { ["CLSID"] = "{DFT-150gal}" },
[5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" },
[1] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }
},
["Mk-82 SE *8, Fuel 150G *2"] = {
[3] = { ["CLSID"] = "{Mk-82 Snakeye_MER_6_C}" },
[4] = { ["CLSID"] = "{DFT-150gal}" },
[2] = { ["CLSID"] = "{DFT-150gal}" },
[5] = { ["CLSID"] = "{Mk82SNAKEYE}" },
[1] = { ["CLSID"] = "{Mk82SNAKEYE}" }
},
["GAR-8 *2, Fuel 300G"] = {
[2] = { ["CLSID"] = "{GAR-8}" },
[4] = { ["CLSID"] = "{GAR-8}" },
[3] = { ["CLSID"] = "{DFT-300gal}" }
}
}
}

265
docs/old_wiki.md Normal file
View File

@@ -0,0 +1,265 @@
# Important notice
The latest DCS update (DCS 2.9.18.12722) introduces a new "permission" system for mods and mission scripts. You can find more info [here](https://forum.dcs.world/topic/376636-changes-to-the-behaviour-of-netdostring_in/ )
This will improve security and modularity but by default blocks Olympus and many other similar mods.
To reallow Olympus, follow these steps for every DCS instance you have installed on your system:
1) create a text file named Saved Games\DCS\Config\autoexec.cfg. The file extension .cfg is very important, make sure it is correctly set;
2) using Notepad or any similar text editor, write this content into autoexec.cfg and save:
```
if not net then net = {} end
net.allow_unsafe_api = { -- this defines the secure zones where net.dostring_in() can be called from
"userhooks",
}
net.allow_dostring_in = { -- and this defines the zones that should be addressed from net.dostring_in()
"server",
}
```
That's all! Other mods/scripts may require you to further edit this file. Please refer to their specific instructions, and make sure to only enable the minimum set of permissions required by the mods you use.
# Welcome to DCS Olympus' Wiki!
Here you will find all up-to-date information about DCS Olympus.
<img src="https://github.com/Pax1601/DCSOlympus/assets/7738284/0744a6d3-ff01-4e3c-a2e2-8a92f45913fe" align="right" height="240"/>
### User guides
* [User guide](https://github.com/Pax1601/DCSOlympus/wiki/2.-User-Guide)
* [New user FAQs](https://github.com/Pax1601/DCSOlympus/wiki/3.-New-User-FAQs)
### Join in the discussion
<img align="left" width="30" src="https://github.com/Pax1601/DCSOlympus/assets/103559271/0ecff279-a87c-4e2d-a4c7-da98c74adf38" />
[**Join our Discord**](https://discord.gg/kNAQkhUHnQ)
# Quick install instructions
To learn how to install DCS Olympus please **carefully** read the instructions [here](https://github.com/Pax1601/DCSOlympus/wiki#installation-guide).
The **mandatory** steps are summarized as follows:
1. **Completely uninstall v1.0.3**, depending on your original installation method as described [in section 1.2](https://github.com/Pax1601/DCSOlympus/wiki#12-removing-v103);
2. **Remove your url reservation** using the `netsh delete` command as described [in paragraph 1.2.3](https://github.com/Pax1601/DCSOlympus/wiki#123-removing-the-net-shell-netsh-rule);
3. Download the manager version of DCS Olympus from here [DCSOlympus_v1.0.4_manager.zip](https://github.com/Pax1601/DCSOlympus/releases/download/v1.0.4/DCSOlympus_v1.0.4_manager.zip);
4. Unzip the file from the step above in your **Documents** folder;
5. In the folder you just created, execute the **installer.bat** file by double-clicking on it;
6. Follow the manager instructions as described [in section 2.4](https://github.com/Pax1601/DCSOlympus/wiki#24-run-the-olympus-manager).
7. Enjoy!
# Installation guide
A full video of this process [is available on YouTube](https://www.youtube.com/watch?v=5y7ZgRrO6Fs).
**If you have already installed v1.0.3, you must uninstall it first - see 1.0**, and *then* install 1.0.4.
If youve never installed Olympus before, then you can go to [2.0].
## [1.0] Uninstalling Olympus v1.0.3
### [1.1] Checking your units' databases
If you didn't change anything in your units databases then don't worry there is nothing to do in this step, skip ahead to the next section.
If you did make changes to the Olympus database, like adding units or mods youll want to make a copy of these so you dont lose them.
For most people they live in your `Saved Games\DCS.openbeta\Mods\Services\Olympus\client\public\databases` folder
If you went really crazy and fully added some new planes, weapons and weapons loadouts make copies of any files you changed as well before we uninstall everything.
### [1.2] Removing v1.0.3
#### [1.2.1] Uninstallation method
There were two ways you could have installed v1.0.3.
A. If you installed via an installer, go to [1.2.2] Case A: Uninstalling 1.0.3 if you installed via an installer;
B. If you manually unzipped the files into the correct locations, go to [1.2.3] Case B Uninstalling 1.0.3 if you installed via a zip.
##### [1.2.2] Case A: Uninstalling 1.0.3 if you installed via an installer
Youll need to remove it via Windows installed apps.
1. Open the Start Menu.
2. Click Settings, which looks like a cogwheel.
3. Click Apps.
4. Select Apps & features from the left-hand side menu.
5. Find the Olympus program in the list that appears.
6. Click the uninstall button that shows under the selected program or app.
If you didnt see Olympus in your list and you were expecting it to, check very carefully before proceeding and/or consider if you maybe installed via the zip and forgot.
Once uninstalled go to [1.2.4] Removing the DCS Hooks and Scripts.
##### [1.2.3] Case B Uninstalling 1.0.3 if you installed via a zip
Olympus needs to be removed from your DCS Saved Games folder which most commonly is found in:
`\Users\[user]\Saved Games\DCS.openbeta\Mods\Services\Olympus`
1. Remove this Olympus folder and its contents.
**Note:** The folder name and location can vary. It needs to be correct for your system. If you installed to a custom folder location, go there instead.
2. Check your `\Users\[user]\Saved Games\` folder.
3. Remove any duplicate folders related to Olympus if they exist here.
Once uninstalled, go to [1.2.4] Removing the DCS Hooks and Scripts
**Note:** If you installed Olympus on multiple DCS instances you will obviously have to do this step for each instance.
### [1.2.4] Removing the DCS Hooks and Scripts
In case something went wrong during the uninstall process, we need to remove the Olympus Hook. To do this, navigate to:
`\Users\[user]\Saved Games\DCS.openbeta\Scripts\Hooks\`
You *may* have a file called OlympusHook.lua, delete this file and *only this file*.
Once done go to [1.2.3] Removing the net shell (netsh) rule.
### [1.2.3] Removing the net shell (netsh) rule
People who setup Olympus to be accessible from other machines - e.g. people using Olympus on a server, or PC acting like a server - will probably have setup a `netsh` rule. Weve removed the requirement for this in v1.0.4, so let's tidy this up to allow Olympus to work properly and for security.
The best way to check is to open up command prompt and enter:
`netsh http show urlacl`
You are going to see a lot of results. You are looking for things Olympus related, e.g. you may have a rule, or similar rules, which say:
`http://*:3001/olympus user=OlympusUser`
where **3001** may have a different value and **OlympusUser** will be your user.
If you see any, you should remove them using the following command:
`netsh http delete urlacl url="http://*:3001/olympus/"`
Take care to ensure you replace the relevant text with what it should say for your entry.
If you got this far, you have successfully removed Olympus v1.0.3 from your system.
## [2.0] Installing Olympus v1.0.4
**If you have jumped ahead and you havent already uninstalled Olympus 1.0.3, you must go back and remove it first. Do not skip this step, otherwise... Well youve been warned.**
There is also a video showing you this same information which is probably a lot easier to follow, [youtube link] though this guide has a little extra information within it for more niche setups.
### [2.1] Downloading the manager
Go to the Github page and take a look at the [releases page](https://github.com/Pax1601/DCSOlympus/releases) and download the manager version if you want to install Olympus on either your own machine or as a server.
Ignore the archive version, which is for a tiny, tiny, subset of people who automatically deploy Olympus - who shouldnt need instructions to know what to do with it, so there arent any.
### [2.2] Extracting the manager
**DO NOT extract the download into your DCS Saved games folder or your actual DCS install**, that isnt where it should go.
Find a suitable location for the file on your computer. We recommend making a folder inside your Downloads folder, but it can be extracted anywhere really.
Once youve done that, take a look at the extracted files and locate the `installer.bat` script. Note, there is another filed called `install` inside the Manager folders, ignore it.
### [2.3] The installer script
Run the script by double clicking on it and follow the relevant prompts. *Read, don't just click blindly.* You might be keen to see this new version but you may ruin things for yourself by skipping ahead too quickly.
The install will download a few prerequisites automatically, such as Node and the Olympus application. **This might take some time**, depending on your internet connection and whether you already had any of the prerequisites. Dont worry if you didnt have all the pre-requisites as the installer script will get them for you - it just takes a little longer.
### [2.4] Run the Olympus Manager
#### [2.4.1] How the manager is set up
Before we get to the manager, it is useful to understand how Olympus is set up.
Each computer with DCS installed on it has an *instance* of DCS. Most users will have only one instance, which is the one they load when running DCS. Some server owners run two DCS servers from one machine: e.g. they have "DCS Server 1" and "DCS Server 2" but these are installed in two different folders on that same machine.
DCS Olympus now works by having the central manager application, which manages each instance of DCS. So, in the case where a server owner runs two servers on one machine, they will have two instances in their manager, allowing them to do things like set ports and passwords independently on each instance. Again, most people will have only one instance and this is expected.
There are also some core important changes to how Olympus works now, so you shouldnt need to ever run DCS as an admin for Olympus to work or do local firewall exceptions to use it on just your PC.
To install an Olympus instance, either run the shortcut on your desktop or find it and run it from within the relevant Olympus folder you made earlier.
Once that opens up, youll see a bunch of useful things, like User and Troubleshooting guides.
### [2.4.2] Basic or Expert Mode
We call the default install mode Basic mode but there is nothing basic about it - it just means its easy to use. In fact, its what we use to install Olympus ourselves. The eagle-eyed will have noticed there is also an Expert mode for those who need to fettle more. This isnt a challenge or a fun hard game mode, it just doesnt guide you through things logically and makes it easier to pick the wrong settings. Expert mode is primarily for managing complicated setups.
So let's keep going with basic mode. Click Add Olympus.
### [2.4.3] Detecting DCS Saved Games Folders
The manager will detect where your DCS Saved Games folders are and give you the option to install to them. Naturally, you should pick the folder into which you want to install it. Most people likely have just one folder and not be given a choice. If you do later try install again over this folder, its like a factory reset of the install.
### [2.4.4] Singleplayer Olympus or multiplayer
All this really means is do you want to only use and control Olympus from this computer, if you do pick Singleplayer.
If you want others to be able to control this instance of Olympus from other computers - including other devices - pick Multiplayer.
You can always reinstall again if you change your mind.
### [2.4.5] Set port and address settings
We can now set these port settings for you, or if you want to pick different defaults, you can do that instead.
We recommend you pick Auto apply settings and click Next.
However, by choosing Manually set the next screen will give you options to pick manually a frontend or backend port.
### [2.4.6] Manually setting Olympus port and address settings
**If you picked Auto apply settings, go to [2.4.7] Pick some passwords.**
You will be prompted to pick ports for the front and backend port. The green tick indicates this port is *probably* free for use and not taken by another running process or Olympus instance. Note: you might have to click on the screen to see this update.
However, if a port isn't in use because the application which uses it isn't running currently, it may cause issues when it does. If you have any problems, just come back here and pick a free port.
**Leave the option unchecked** for Enable direct backend API connection its no longer needed for Olympus unless you are doing some real niche custom modding things, well probably tell you in Discord if you should enable this otherwise leave it unchecked.
### [2.4.7] Pick some passwords
This step is so obvious, I dont think we are going to tell you how to do this.
Remember to pick secure, long, passwords if you will be using this over the internet and not just on your PC. [Obligatory XKCD](https://xkcd.com/936/)
All passwords must also be different within each instance.
If you have Olympus already installed, with chosen passwords, you can click Next to keep the same passwords.
### [2.4.8] Install the new camera control plugin
Weve got a new camera control plugin which lets you move the DCS camera around in missions to wherever you are looking within DCS, which is really neat.
Obviously, we recommend you install this because its cool but here you get the option if you dont want to.
Importantly, **if you want to use the camera control functionality**, even with other peoples Olympus servers or machines, **youll need to install the plugin for yourself** by saying install here as it connects to your local DCS. This isnt a server-side thing.
For more information on the camera plugin, including troubleshooting and removal of the plugin, see [2.0] Live Camera Plugin on [4. Setup FAQ and Troubleshooting](https://github.com/Pax1601/DCSOlympus/wiki/4.-Setup-FAQ-and-Troubleshooting).
### [2.4.9] Allow GitHubs Electron
You *might* get a prompt to Allow Electron to run - but not everyone will. Its something we use to build Olympus. Electron is made by GitHub, which you can have a read about on the internet.
If you see the prompt, click Allow and you will finish your Olympus install.
## [3.0] Enjoy Olympus
### [3.1] Getting a mission running
Okay, hopefully that worked for you and you can launch Olympus. Follow the instructions on screen. You dont need the manager open to run Olympus with DCS.
Remember: to load up a mission and **remember to unpause the game/server** or Olympus cant do anything!
### [3.2] Change settings / uninstall Olympus
Once youve installed an Olympus instance, youll see it listed here. Clicking Edit Settings will walk you back through the wizard again to amend the relevant settings. You can also see Open logs that will open the two logs people need to help troubleshoot issues.
It may appear that only one log window has been opened, but sometimes one log window sits over the other, so move the one you can see in case it's hiding the second.
You can also uninstall that specific Olympus instance as well. This doesnt remove every instance of Olympus from your machine, just that specific one. If you want to remove them all youll have to repeat this process for each installed instance.
## [4.0] Troubleshooting and further steps
If you do have problems, or want to change any settings, you can Return to the main window and instead click Change settings. This is also how you find the super important logs you must share with us if you want help from people in our [DCS Olympus Development Discord server](https://discord.gg/tuDd94xC4A). See the #troubleshooting channel.

View File

@@ -1,25 +1,3 @@
# Contents
See GitHub Contents on the right of the page.
<!--- [Introduction](#introduction)
- [What is Olympus?](#what-is-olympus)
- [The Team](#the-team)
- [Basics](#basics)
- [Installing Olympus](#installing-olympus)
- [Running Olympus](#running-olympus)
- [User Interface](#user-interface)
- [Overview](#overview)
- [Map Options](#map-options)
- [Show/hide options](#showhide-options)
- [Game Master Options](#game-master-options)
- [Airfields](#airfields)
- [Cursor Location Info](#cursor-location-info)
- [Connection Status](#connection-status)
- [Selected unit Information](#selected-unit-information)
- [Selected Units Window](#selected-units-window)
- [Selected Unit](#selected-unit)
- [Using the Map](#using-the-map)
- [Spawning Units](#spawning-units)-->
# Introduction
## What is Olympus?
@@ -45,86 +23,13 @@ The user interface is key to this experience, and we have done our best to make
# Basics
## Installing Olympus
**NOTE: the installation process has been greatly modified in version v1.0.4. These instructions are NOT applicable to v1.0.3. Users are suggested to update to the latest version.**
**NOTE: Olympus is offered in two different packages: an autoinstaller package and an archive package. The autoinstaller package is marked with the prefix ```autoinstaller_```. THESE INSTRUCTION ARE ONLY APPLICABLE TO THE AUTOINSTALLER VERSION. The archived version is intended for automatic tools like [SpecialK's Server Bot](https://github.com/Special-K-s-Flightsim-Bots/DCSServerBot).**
Download the latest release autoinstaller package from the [Github releases page](https://github.com/Pax1601/DCSOlympus/releases). After downloading the package, unpack it and follow these steps:
1) **Close any applications which may interfere with installation**, including Digital Combat Simulator (DCS) and previous versions of Olympus.
<br>
2) **If you DO NOT have Olympus v1.0.3 already installed, SKIP THIS STEP. If you have already installed Olympus v1.0.3, do the following**:
NOTE: If you made any changes to your unit databases or mods.lua file (e.g. to support a third party mod) make a backup of the edited files before proceeding or changes will be lost;
a) **If you installed DCS Olympus v1.0.3 using the installer**, simply remove it using Windows's "Add or remove programs" application.
b) **If you installed DCS Olympus v1.0.3 using the archived version**, remove it by deleting the "...<DCS Saved Games folder>\Mods\Services\Olympus" folder. Do this for every DCS instance you installed Olympus in.
Remember to delete any shortcuts you created. Don't worry, they will be created automatically again by the installation script provided in this package.
<br>
3) **Create a folder named "DCS Olympus"** in your "Saved Games" directory and **extract all the contents of the downloaded package into it**.
NOTE:
a) Do not extract the contents of the package directly in your Saved Games folder or in your DCS Saved Games folder.
b) Unlike previous version of Olympus, it is no longer necessary to copy the packaged files into each DCS instance folder.
<br>
4) **Execute the "installer.bat"** script by double-clicking on it. It is located in the folder you created in step 3. Wait for the installation script to complete. **Installation may take a couple of minutes, after which the Manager will start automatically**.
NOTE: depending on your Windows configuration, the script may be called "installer" (without .bat at the end).
<br>
5) The Olympus Manager will open. This will allow you to add/remove Olympus to individual DCS instances.
**Use the Olympus Manager and follow the instructions to install and setup Olympus** (see the dedicated section below for more information).
<br>
6) **Start DCS and run a mission. Make sure it is UNPAUSED**.
<br>
7) **Open Olympus via the shortcut and login using any username and the Game Master password set using the Manager. (NOTE: not your DCS server password)**.
Local installation: run the client from the provided desktop shortcut.
Dedicated server: users must first start the Olympus server from the provided desktop shortcut or using the "Expert view" mode of the Manager.
Then log in using any browser and visiting ```http:\\server_IP:frontend_port``` (frontend port is 3000 by default, but can be edited using the Manager)
<br>
8) You can use the manager at any time to change the ports and/or passwords. If you do, **REMEMBER TO RESTART OLYMPUS AND DCS**.
NOTES:
a) when launching the Manager you will be prompted to allow Electron to create a firewall rule. This is optional and can be denied without effect on the operation of the Manager;
b) if you are using Olympus on a dedicated server with a router, you must enable port forwarding on the frontend port (3000 by default);
c) unlike Olympus v1.0.3, **running the netsh command is no longer required. It is also no longer required to create firewall rules or port forwarding for the backend port. (Optional) If you already performed this steps in the past you can delete the firewall and netsh rules**.
Once you have installed Olympus, it will run whenever you are playing a DCS local mission or hosting a multiplayer server. To control the action, open the Olympus client via the icon on your desktop or start menu.
## Using the Manager
The Olympus Manager is used to install, update, and configure your Olympus installation. If you own a dedicated server and run multiple Olympus instances at the same time, the Manager allows you to conveniently handle them from a single location.
**REMEMBER, after installing Olympus with step 4) of the installation process above, you will still need to add it to your DCS instance!**
When you start the Manager for the first time, it will allow to choose between Basic and Expert mode. Basic mode is suggested for local only users, while Expert mode is tailored for dedicated server owners. You can change the mode at any time with the link in the toolbar at the top of the manager. Note that the choice of the Manager mode has no impact on the functionality of Olympus. Server owners can use Basic mode, or vice versa.
### Basic mode
Basic mode gives you access to an installation Wizard. To start it, click on "Add Olympus". If you have more than one DCS instance installed, the Wizard will allow you to select the one you want to add Olympus to. If only one instance is detected, this step will be skipped.
**Should the Wizard fail at detecting your DCS instance, you can manually add it. To do so, open the ```<Olympus installation folder>\manager\options.json``` file and add the location of your DCS instance, between double quotes, in ```additionalDCSInstances```. Multiple values should be separated by a comma. Use double backslashes as separators**
Once the DCS instance is selected, you will be prompted with a series of questions which will allow you configure your installation. The meaning of all the questions and the options is explained in the Manager itself, move your mouse cursor on the info icons for more information.
### Expert mode
Expert mode operates more as a dashboard rather than a Wizard. All DCS instances are presented to the user, and you will be able to install/configure/remove Olympus from a single page.
The meaning of all the options is also explained by moving your mouse cursor on the info icon.
In Expert mode, users are also capable of starting the Olympus client and server directly from the Manager. This is convenient if you have multiple installations. Once a client/server instance is running, the Manager allows you to monitor its state directly from the Expert view.
## Updating Olympus
The Manager allows you to update Olympus automatically. When the Manager is started, it checks if a new version is available. If that is the case, you will be given the option to automatically update Olympus. The new package will be downloaded and installed without requiring any inputs from the user.
The Manager will be closed and reopened after the process is completed. Once this is done, you will presented with a warning: just like installing Olympus will not automatically add it to your DCS instance, updating it will not update it in your DCS instance. By clicking on "Accept", all your Olympus instances will be automatically updated.
## Logging into Olympus
To login to Olympus, you need to enter a username and password.
**The username field is used for logging purposes only and can be anything you choose. The password is the one you set during the installation.**
If you forget a password or need to change them for security purposes, use the manager to configure it again, then restart the Olympus client\server and DCS mission.
If you forget a password or need to change them for security purposes, use ```configurator.exe``` in ```DCS.openbeta/Mods/Services/Olympus```, then restart the Olympus client and DCS mission.
Please note that at the moment, ```configurator.exe``` is a feature which is not present in local installations created via the installer, but is present when Olympus is installed via any of the other methods. In order to reset the Olympus client passwords for local installations, you will need to reinstall Olympus. This will be addressed in a future update.

6
frontend/build.bat Normal file
View File

@@ -0,0 +1,6 @@
cd react
call npm run build-release
cd ..
cd server
robocopy ./databases ./public/databases /E

25
frontend/react/.gitignore vendored Normal file
View File

@@ -0,0 +1,25 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.vite

View File

@@ -0,0 +1,6 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint"
]
}

View File

@@ -7,14 +7,14 @@
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/public/",
"sourceMapPathOverrides": {
"src/*": "${workspaceFolder}/src/*"
},
"preLaunchTask": "watch",
"port": 9222
}
"webRoot": "${workspaceFolder}",
"preLaunchTask": "npm: dev",
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
]
},
]
}

12
frontend/react/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"html",
"typescriptreact"
],
"prettier.printWidth": 160,
}

30
frontend/react/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,30 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "dev",
"problemMatcher": [
{
"pattern": [
{
"regexp": ".*",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".*",
"endsPattern": ".*",
}
}
],
"label": "npm: dev",
"detail": "vite --port=8080",
"isBackground": true,
"dependsOn": ["check-setup"]
}
]
}

8
frontend/react/README.md Normal file
View File

@@ -0,0 +1,8 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

View File

@@ -0,0 +1,36 @@
import eslintPluginReadableTailwind from "eslint-plugin-readable-tailwind";
import eslintParserTypeScript from "@typescript-eslint/parser";
import eslintConfigPrettier from "eslint-config-prettier";
export default [
{
files: ["**/*.{ts,tsx,cts,mts}"],
languageOptions: {
parser: eslintParserTypeScript,
},
},
{
files: ["**/*.tsx"],
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
plugins: {
"readable-tailwind": eslintPluginReadableTailwind,
},
rules: {
"readable-tailwind/multiline": [
"warn",
{ group: "newLine", lineBreakStyle: "windows" },
],
"readable-tailwind/sort-classes": ["warn", { order: "improved" }],
"readable-tailwind/no-unnecessary-whitespace": [
"warn",
{ allowMultiline: true },
],
},
},
];

20
frontend/react/index.html Normal file
View File

@@ -0,0 +1,20 @@
<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/icon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Olympus {{OLYMPUS_VERSION_NUMBER}}</title>
</head>
<body>
<div id="root" class="h-screen w-screen"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@@ -0,0 +1,67 @@
{
"name": "react",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --port=8080",
"build-release": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@eslint/js": "^9.6.0",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/free-regular-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@tanem/svg-injector": "^10.1.68",
"@turf/clusters": "^7.1.0",
"@turf/turf": "^6.5.0",
"@types/dom-webcodecs": "^0.1.12",
"@types/leaflet": "^1.9.8",
"@types/node": "^22.5.1",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@types/react-leaflet": "^3.0.0",
"@types/turf": "^3.5.32",
"@typescript-eslint/parser": "^7.14.1",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.19",
"axios": "^1.8.1",
"buffer": "^6.0.3",
"chart.js": "^4.4.7",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.6",
"eslint-plugin-readable-tailwind": "^1.5.2",
"globals": "^15.7.0",
"js-sha256": "^0.11.0",
"jsstore": "^4.8.2",
"leaflet": "^1.9.4",
"leaflet-control-mini-map": "^0.4.0",
"leaflet-path-drag": "^1.9.5",
"magvar": "^1.1.5",
"opus-decoder": "^0.7.6",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"react": "^18.2.0",
"react-chartjs-2": "^5.3.0",
"react-circular-progressbar": "^2.1.0",
"react-clock": "^5.1.0",
"react-dom": "^18.2.0",
"react-icons": "^5.0.1",
"react-leaflet": "^4.2.1",
"tailwindcss": "^3.4.3",
"turf": "^3.0.14",
"typescript-eslint": "^7.14.1",
"usng": "^0.3.0",
"vite": "^6.2.2",
"vite-plugin-externals": "^0.6.2",
"vite-plugin-file": "^1.0.5",
"web-audio-peak-meter": "^3.1.0"
}
}

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="designated.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="5.9428571"
inkscape:cx="-29.026442"
inkscape:cy="16.237981"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 7.5000002,0 c 0.498,0 0.9375,0.4395 0.9375,0.9375 V 1.2598 C 11.1621,1.6699 13.3301,3.8379002 13.7402,6.5625002 h 0.3223 c 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 H 13.7402 C 13.3301,11.1914 11.1621,13.3594 8.4375002,13.7695 v 0.293 c 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 v -0.293 C 3.8086002,13.3594 1.6406,11.1914 1.2305,8.4375002 h -0.293 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 h 0.293 C 1.6406,3.8379002 3.8086002,1.6699 6.5625002,1.2598 V 0.9375 c 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 z m -4.3652,8.4375002 c 0.3515,1.7284998 1.6992,3.0761998 3.4277,3.4276998 V 11.25 c 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 0.498,0 0.9375,0.4395 0.9375,0.9375 v 0.6152 C 10.1367,11.5137 11.4844,10.166 11.8359,8.4375002 H 11.25 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 h 0.5859 c -0.3515,-1.6992 -1.6992,-3.0469 -3.3983998,-3.3984 v 0.5859 c 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 v -0.5859 c -1.7285,0.3515 -3.0762,1.6992 -3.4277,3.3984 h 0.6152 c 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 z m 4.3652,0 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="9.3896503"
height="9.3896503"
viewBox="0 0 9.3896503 9.3896503"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="hold.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="1.1989183"
inkscape:cy="4.311899"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 9.103975,1.603975 c 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 l -3.0762,3.0761 -3.1055,-3.0761 c -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 -0.3809,0.3515 -0.3809,0.9668 0,1.3183 l 3.0761,3.0762 -3.0761,3.1055 c -0.3809,0.3515 -0.3809,0.9668 0,1.3183 0.3515,0.3809 0.9668,0.3809 1.3183,0 l 3.1055,-3.0761 3.0762,3.0761 c 0.3515,0.3809 0.9668,0.3809 1.3183,0 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 l -3.0761,-3.1055 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="13.126647"
height="15.015483"
viewBox="0 0 13.126647 15.015483"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="free.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="43.789474"
inkscape:cx="4.5330529"
inkscape:cy="6.7710337"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 10.796771,3.75 c 0,1.31836 -0.7618,2.46094 -1.8750496,3.13476 v 0.61525 c 0,0.5273 -0.43945,0.9375 -0.9375,0.9375 h -2.8125 c -0.52734,0 -0.9375,-0.4102 -0.9375,-0.9375 V 6.88476 c -1.14258,-0.67382 -1.875,-1.8164 -1.875,-3.13476 0,-2.05078 1.875,-3.75 4.21875,-3.75 2.31445,0 4.2187996,1.69922 4.2187996,3.75 z M 4.9373514,5.15625 c 0.49804,0 0.9375,-0.41016 0.9375,-0.9375 0,-0.49805 -0.43946,-0.9375 -0.9375,-0.9375 -0.52735,0 -0.9375,0.43945 -0.9375,0.9375 0,0.52734 0.41015,0.9375 0.9375,0.9375 z m 4.21872,-0.9375 c 0,-0.49805 -0.43943,-0.9375 -0.93748,-0.9375 -0.52734,0 -0.9375,0.43945 -0.9375,0.9375 0,0.52734 0.41016,0.9375 0.9375,0.9375 0.49805,0 0.93748,-0.41016 0.93748,-0.9375 z M 0.10336144,8.02731 c 0.23438,-0.4687 0.79102,-0.6445 1.25976996,-0.4101 l 5.21484,2.6074 5.1854996,-2.6074 c 0.4688,-0.2344 1.0254,-0.0586 1.2598,0.4101 0.2344,0.4688 0.0586,1.0254 -0.4101,1.2598 l -3.9551196,1.9629 3.9551196,1.9922 c 0.4687,0.2344 0.6445,0.791 0.4101,1.2597 -0.2344,0.4688 -0.791,0.6446 -1.2598,0.4102 l -5.1854996,-2.6074 -5.21484,2.6074 c -0.46874996,0.2344 -1.02538996,0.0586 -1.25976996,-0.4102 -0.234374,-0.4687 -0.058593,-1.0253 0.41016,-1.2597 L 4.4685914,11.25001 0.51352144,9.28711 c -0.468753,-0.2344 -0.644534,-0.791 -0.41016,-1.2598 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="19"
height="15"
viewBox="0 0 19 15"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="state_attack.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="27.733333"
inkscape:cx="3.6959135"
inkscape:cy="10.258414"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
style="fill:none;stroke:#262626;stroke-width:3.6454;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3.9375571,11.604826 5.4120513,13.142064 8.1100626,10.334251 10.243372,12.373445 9.1610315,11.30679 15.074691,5.314696 14.525677,2.506882 11.81198,1.8794375 5.8198901,7.8087875 4.6748047,6.7891902 6.6826265,8.7499543 Z"
id="path2232" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.74012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 3.7087499,11.821755 1.4744947,1.537239 2.926818,-3.024743 c 0.958603,0.899307 1.0509689,0.972539 1.0509689,0.972539 L 14.845884,5.5316249 14.29687,2.7238111 11.583172,2.0963666 5.8198909,7.8087874 c 0,0 -0.1141197,-0.012794 0.8627356,0.9411669 z"
id="path2232-9"
sodipodi:nodetypes="cccccccccc" />
<path
style="fill:#262222;fill-opacity:1;stroke-width:0.0124914"
d="m 12.8516,4.8268957 c 0.213183,-0.2131845 0.213183,-0.5329611 0,-0.7461455 -0.213185,-0.2131845 -0.532961,-0.2131845 -0.746145,0 L 8.1881937,7.9980144 c -0.2131847,0.2131845 -0.2131847,0.5329612 0,0.7461458 0.1065924,0.106592 0.2398327,0.1598881 0.3730732,0.1598881 0.1332405,0 0.26648,-0.053296 0.3730723,-0.1598881 z"
fill="#FFFFFF"
id="path4-5" />
<path
style="fill:none;stroke:#262626;stroke-width:1.19854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 4.6748047,6.7891902 10.243372,12.373445"
id="path2082" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
version="1.1"
id="svg14"
sodipodi:docname="follow.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs18" />
<sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1017"
id="namedview16"
showgrid="false"
inkscape:zoom="12.142857"
inkscape:cx="22.433158"
inkscape:cy="14.663012"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg14" />
<path
d="m 8.6152043,0.96068491 c -0.070984,-0.1658027 -0.2358263,-0.272592 -0.4178212,-0.272592 -0.1818565,0 -0.346698,0.106789 -0.4178225,0.272592 L 6.5262355,3.8523252 C 6.4294515,4.0771272 6.3784085,4.3160075 6.3784085,4.560499 V 6.7242759 L 2.2854009,9.0848093 V 8.5565855 c 0,-0.3737975 -0.304161,-0.6745171 -0.682098,-0.6745171 -0.378076,0 -0.68223699,0.3007196 -0.68223699,0.6745171 v 1.5736425 0.899265 0.674379 c 0,0.373797 0.30416099,0.674518 0.68223699,0.674518 0.377937,0 0.682098,-0.300721 0.682098,-0.674518 v -0.224747 h 4.0930076 v 0.918844 L 4.7156289,13.83966 c -0.09944,0.08425 -0.156335,0.207925 -0.156335,0.337121 v 0.449631 c 0,0.24736 0.204588,0.449631 0.454779,0.449631 h 2.7286708 v -1.798527 c 0,-0.247222 0.2045879,-0.449495 0.4546394,-0.449495 0.2501899,0 0.4547778,0.202273 0.4547778,0.449495 v 1.798527 h 2.7286701 c 0.250191,0 0.454779,-0.202271 0.454779,-0.449631 v -0.449631 c 0,-0.129196 -0.05676,-0.252876 -0.156195,-0.337121 l -1.662919,-1.441691 v -0.918844 h 4.093006 v 0.224747 c 0,0.373797 0.304162,0.674518 0.682098,0.674518 0.378076,0 0.682238,-0.300721 0.682238,-0.674518 V 11.029493 10.130228 8.5565855 c 0,-0.3737975 -0.304162,-0.6745171 -0.682238,-0.6745171 -0.377936,0 -0.682098,0.3007196 -0.682098,0.6745171 V 9.0848093 L 10.016496,6.7242759 V 4.560499 c 0,-0.2444915 -0.051184,-0.4833718 -0.1478275,-0.7081738 z"
fill="#202831"
id="path2"
style="fill:#000000;fill-opacity:1;stroke-width:1.38669" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
version="1.1"
id="svg7234"
sodipodi:docname="land-at-point.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata6">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs7238" />
<sodipodi:namedview
id="namedview7236"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="18.495262"
inkscape:cx="12.030108"
inkscape:cy="17.220627"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg7234"
inkscape:pageshadow="2"
width="512px" />
<path
inkscape:connector-curvature="0"
d="m 3.4418938,1.8579231 c 0,-0.4470615 0.3331285,-0.8082476 0.7454662,-0.8082476 h 8.945519 c 0.412333,0 0.745462,0.3611861 0.745462,0.8082476 0,0.4470624 -0.333129,0.8082443 -0.745462,0.8082443 H 9.4055765 v 1.616493 h 0.7454615 c 2.059333,0 3.727303,1.80845 3.727303,4.04123 v 1.616491 c 0,0.4470596 -0.333129,0.8082466 -0.745462,0.8082466 H 9.4055765 7.9146585 c -0.468246,0 -0.910858,-0.239949 -1.192738,-0.646596 L 5.0586105,7.6974974 C 4.9770785,7.5787864 4.865263,7.4878614 4.7394601,7.4322944 L 1.5596118,6.0532234 C 1.3382988,5.9572434 1.1705709,5.7501304 1.1123358,5.4975524 L 0.57653646,3.1687964 c -0.0605718,-0.255102 0.1188069,-0.502629 0.36108,-0.502629 H 1.5782493 c 0.2352817,0 0.45659,0.118712 0.5963664,0.323301 l 0.894552,1.293192 H 7.9146585 V 2.6661674 H 4.18736 c -0.4123377,0 -0.7454662,-0.3611819 -0.7454662,-0.8082443 z m 5.9636827,7.2742113 h 2.9818415 v -0.808244 c 0,-1.338658 -1.001708,-2.424737 -2.23638,-2.424737 H 9.4055765 Z m 5.7447015,2.6621596 c 0.291199,0.315723 0.291199,0.828456 0,1.144173 l -0.09085,0.09851 c -0.559097,0.606184 -1.318536,0.947164 -2.108255,0.947164 H 6.4237353 c -0.4123284,0 -0.7454616,-0.361187 -0.7454616,-0.808246 0,-0.447061 0.3331332,-0.808248 0.7454616,-0.808248 h 6.5274377 c 0.396023,0 0.775745,-0.169226 1.055293,-0.472318 l 0.09085,-0.09851 c 0.291199,-0.31572 0.764099,-0.31572 1.055293,0 z"
id="path1174-3"
style="fill:#202831;fill-opacity:1;stroke-width:0.0290252" />
<path
style="fill:none;stroke:#000000;stroke-width:1.07268px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="M 0.90212206,15.260973 H 15.104269"
id="path855" />
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="19"
height="15"
viewBox="0 0 19 15"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="miss-on-purpose.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
width="19"
height="15"
viewBox="0 0 19 15"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="miss-on-purpose.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10" /><sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
@@ -50,4 +50,4 @@
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52495;stroke-opacity:1" /><path
d="m 184.66044,8.5185895 c 12.17907,0 22.01865,9.8395825 22.01865,22.0186445 v 7.15606 C 271.15243,47.257643 322.07055,98.244571 331.6349,162.6491 h 7.15606 c 12.17906,0 22.01864,9.83958 22.01864,22.01864 0,12.17907 -9.83958,22.01865 -22.01864,22.01865 h -7.15606 c -9.56435,64.47334 -60.55128,115.39146 -124.95581,124.95581 v 7.15606 c 0,12.17906 -9.83958,22.01864 -22.01865,22.01864 -12.17906,0 -22.01864,-9.83958 -22.01864,-22.01864 V 331.6422 C 98.168455,322.07785 47.250339,271.15973 37.68599,206.68639 h -7.156059 c -12.179063,0 -22.0186444,-9.83958 -22.0186444,-22.01865 0,-12.17906 9.8395814,-22.01864 22.0186444,-22.01864 H 37.68599 C 47.250339,98.175761 98.168455,47.257643 162.6418,37.693294 v -7.15606 c 0,-12.179062 9.83958,-22.0186445 22.01864,-22.0186445 z M 82.411363,206.68639 c 8.601033,40.11522 40.184027,71.6294 80.230437,80.23043 v -14.1745 c 0,-12.17906 9.83958,-22.01864 22.01864,-22.01864 12.17907,0 22.01865,9.83958 22.01865,22.01864 v 14.1745 c 40.11522,-8.60103 71.6294,-40.18402 80.23044,-80.23043 h -14.17451 c -12.17906,0 -22.01864,-9.83958 -22.01864,-22.01865 0,-12.17906 9.83958,-22.01864 22.01864,-22.01864 h 14.17451 C 278.30849,122.53388 246.79431,91.019701 206.67909,82.418665 v 14.174506 c 0,12.179059 -9.83958,22.018639 -22.01865,22.018639 -12.17906,0 -22.01864,-9.83958 -22.01864,-22.018639 V 82.418665 C 122.52658,91.019701 91.012396,122.53388 82.411363,162.6491 h 14.174502 c 12.179065,0 22.018645,9.83958 22.018645,22.01864 0,12.17907 -9.83958,22.01865 -22.018645,22.01865 z M 184.66044,162.6491 a 22.018645,22.018645 0 1 1 0,44.03729 22.018645,22.018645 0 1 1 0,-44.03729 z"
id="path2"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.688083" /></g></svg>
style="fill:#ffffff;fill-opacity:1;stroke-width:0.688083" /></g></svg>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="19"
height="15"
viewBox="0 0 19 15"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="state_refuel.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="19.610428"
inkscape:cx="9.1532933"
inkscape:cy="9.2042866"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
style="fill:none;stroke:#262626;stroke-width:2.80114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 14.109032,5.6203217 14.096876,4.2589893"
id="path3134"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#262626;stroke-width:4.752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 11.2162,7.8446415 c 0.611292,0.23067 1.379382,0.1813438 1.567963,1.1668564 l 0.01216,0.9116069 0.948071,1.1060822 c 0.556356,0.0066 1.240492,0.262304 1.17901,-0.935916 L 15.032793,5.7783334 C 15.029293,5.1839171 14.968765,4.6085103 14.485828,4.173906 L 13.075877,2.7761093"
id="path2668"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:none;stroke:#262626;stroke-width:5.05323;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 5.5156203,2.6788713 v 9.4807077 l -0.9723803,0.02431 7.122686,0.01216 -1.069619,-0.03646 V 2.6302523 Z"
id="path2480"
sodipodi:nodetypes="ccccccc" />
<path
d="M 11.606497,11.523453 H 4.6132695 c -0.1923136,0 -0.3496607,0.157348 -0.3496607,0.349662 v 0.699322 c 0,0.192314 0.1573471,0.349662 0.3496607,0.349662 h 6.9932275 c 0.192314,0 0.349661,-0.157348 0.349661,-0.349662 v -0.699322 c 0,-0.192314 -0.157347,-0.349662 -0.349661,-0.349662 z M 15.04192,4.0778511 13.27176,2.3076902 c -0.135494,-0.1354933 -0.358404,-0.1354933 -0.493897,0 l -0.246948,0.2469485 c -0.135494,0.1354943 -0.135494,0.3584027 0,0.493897 l 0.823889,0.8238892 V 5.229548 c 0,0.6140934 0.456745,1.1211021 1.048985,1.206332 v 3.5140965 c 0,0.2884715 -0.236022,0.5244925 -0.524492,0.5244925 -0.288471,0 -0.524493,-0.236021 -0.524493,-0.5244925 V 9.2506542 c 0,-1.0620966 -0.861041,-1.9231375 -1.923138,-1.9231375 h -0.17483 V 3.1315803 c 0,-0.7714404 -0.627205,-1.3986455 -1.3986454,-1.3986455 h -3.496614 c -0.7714405,0 -1.3986455,0.6272051 -1.3986455,1.3986455 V 10.82413 H 11.256836 V 8.3765006 h 0.17483 c 0.482971,0 0.874154,0.3911839 0.874154,0.8741536 v 0.6075366 c 0,0.8238902 0.590054,1.5734762 1.409573,1.6587062 0.939715,0.09397 1.73738,-0.644688 1.73738,-1.5669205 V 5.0678294 c 0,-0.3715144 -0.148606,-0.7277319 -0.410853,-0.9899783 z M 9.8581906,5.9288713 h -3.496614 v -2.797291 h 3.496614 z"
id="path2270"
style="fill:#fffffd;fill-opacity:1;stroke-width:0.0218539" />
<rect
style="fill:#262626;fill-opacity:1;stroke:none;stroke-width:0.100774;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:5.6;stroke-opacity:1;paint-order:stroke fill markers"
id="rect3805"
width="3.496614"
height="2.7972908"
x="6.3615766"
y="3.1315804" />
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="19"
height="15"
viewBox="0 0 19 15"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="scenic-aaa.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10" /><sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="32"
inkscape:cx="12.515625"
inkscape:cy="8.203125"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" /><path
d="m 11.193211,6.498903 c -0.0366,-0.086393 -0.121536,-0.1420355 -0.215249,-0.1420355 -0.09371,0 -0.178642,0.055645 -0.21525,0.1420355 l -0.645747,1.5067452 c -0.04979,0.1171426 -0.07614,0.2416063 -0.07614,0.3689989 V 9.5021428 L 7.9322576,10.732138 v -0.275284 c 0,-0.194749 -0.1566776,-0.351427 -0.3514268,-0.351427 -0.1947493,0 -0.3514276,0.156678 -0.3514276,0.351427 v 0.819998 0.468569 0.351428 c 0,0.194748 0.1566783,0.351427 0.3514276,0.351427 0.1947492,0 0.3514268,-0.156679 0.3514268,-0.351427 v -0.117143 h 2.1085644 v 0.47882 l -0.856604,0.751175 c -0.05125,0.04393 -0.08053,0.108354 -0.08053,0.175714 V 13.6197 c 0,0.128857 0.105428,0.234285 0.234285,0.234285 h 1.405709 v -0.93714 c 0,-0.128856 0.105431,-0.234285 0.234285,-0.234285 0.128856,0 0.234284,0.105431 0.234284,0.234285 v 0.93714 h 1.405711 c 0.128857,0 0.234284,-0.10543 0.234284,-0.234285 v -0.234285 c 0,-0.06736 -0.02928,-0.131785 -0.08053,-0.175714 l -0.856607,-0.751175 v -0.47882 h 2.108564 v 0.117143 c 0,0.19475 0.156679,0.351428 0.351427,0.351428 0.19475,0 0.351428,-0.156678 0.351428,-0.351428 v -0.351428 -0.468569 -0.819998 c 0,-0.194749 -0.156678,-0.351427 -0.351428,-0.351427 -0.194748,0 -0.351427,0.156678 -0.351427,0.351427 v 0.275284 L 11.915102,9.5021428 V 8.3746471 c 0,-0.1273926 -0.02637,-0.2518568 -0.07614,-0.3689989 z"
id="path1154-7"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.0146427;stroke-opacity:1" /><path
d="M 5.375668,1.2470443 C 5.30062,1.1962303 5.2005546,1.2056133 5.1364508,1.2689323 5.0723498,1.3322513 5.0629648,1.4331009 5.1145628,1.5073675 l 0.8755666,1.2766078 -0.7786288,0.25329 c -0.077394,0.025017 -0.1297722,0.096937 -0.1297722,0.1782399 0,0.081303 0.052378,0.1532245 0.1297722,0.1782407 L 6.0174912,3.6548524 5.6039425,4.4412997 c -0.038302,0.072703 -0.025016,0.1618233 0.033618,0.2196734 0.058635,0.057852 0.1469701,0.071921 0.2196742,0.033618 L 6.6436816,4.2810428 6.9047879,5.0870331 c 0.025017,0.077395 0.096937,0.1297722 0.1782406,0.1297722 0.081303,0 0.1532244,-0.052378 0.1782406,-0.1297722 l 0.261106,-0.8059907 0.7864472,0.4135487 c 0.072703,0.038302 0.1618234,0.025016 0.2196734,-0.033618 0.057853,-0.058635 0.071921,-0.1469701 0.033618,-0.2196735 L 8.1485644,3.6548524 8.9545554,3.3937462 c 0.077394,-0.025016 0.1297715,-0.096938 0.1297715,-0.1782407 0,-0.081302 -0.052379,-0.1532236 -0.1297715,-0.1782399 L 8.1219841,2.767559 8.3228958,2.2172025 C 8.347912,2.1484097 8.3307157,2.0717956 8.2791193,2.0202001 8.2275229,1.9686037 8.1509111,1.9514074 8.0821168,1.9764236 L 7.5317596,2.1773344 7.2612725,1.3439827 C 7.236256,1.2665882 7.1643354,1.2142105 7.0830319,1.2142105 c -0.081303,0 -0.1532246,0.052378 -0.1782408,0.1297722 L 6.6522839,2.1226115 Z"
id="path10424"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.00781758;stroke-opacity:1" /><path
d="m 0.9232391,10.130493 c -0.075048,-0.05081 -0.1751134,-0.04143 -0.2392172,0.02189 -0.064101,0.06332 -0.073486,0.164168 -0.021888,0.238435 l 0.8755666,1.276608 -0.7786288,0.25329 c -0.077394,0.02502 -0.1297722,0.09694 -0.1297722,0.178239 0,0.0813 0.052378,0.153225 0.1297722,0.178241 l 0.8059906,0.261107 -0.4135487,0.786447 c -0.038302,0.0727 -0.025016,0.161823 0.033618,0.219673 0.058635,0.05785 0.1469701,0.07192 0.2196742,0.03362 l 0.7864469,-0.41355 0.2611063,0.80599 c 0.025017,0.0774 0.096937,0.129773 0.1782406,0.129773 0.081303,0 0.1532244,-0.05238 0.1782406,-0.129773 l 0.261106,-0.80599 0.7864472,0.413548 c 0.072703,0.0383 0.1618234,0.02502 0.2196734,-0.03362 0.057853,-0.05863 0.071921,-0.14697 0.033618,-0.219673 l -0.4135493,-0.786445 0.805991,-0.261106 c 0.077394,-0.02502 0.1297715,-0.09694 0.1297715,-0.178241 0,-0.0813 -0.052379,-0.153224 -0.1297715,-0.17824 L 3.6695552,11.651007 3.8704669,11.100651 c 0.025016,-0.06879 0.00782,-0.145407 -0.043776,-0.197003 -0.051596,-0.0516 -0.1282082,-0.06879 -0.1970025,-0.04378 L 3.0793307,11.060783 2.8088436,10.227431 c -0.025017,-0.07739 -0.096937,-0.129772 -0.1782406,-0.129772 -0.081303,0 -0.1532246,0.05238 -0.1782408,0.129772 L 2.199855,11.00606 Z"
id="path10424-2"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.00781758;stroke-opacity:1" /><path
d="m 3.8607391,5.442993 c -0.075048,-0.05081 -0.1751134,-0.04143 -0.2392172,0.02189 -0.064101,0.06332 -0.073486,0.164168 -0.021888,0.238435 l 0.8755666,1.276608 -0.7786288,0.25329 c -0.077394,0.02502 -0.1297722,0.09694 -0.1297722,0.178239 0,0.0813 0.052378,0.153225 0.1297722,0.178241 L 4.5025623,7.850803 4.0890136,8.63725 c -0.038302,0.0727 -0.025016,0.161823 0.033618,0.219673 0.058635,0.05785 0.1469701,0.07192 0.2196742,0.03362 l 0.7864469,-0.41355 0.2611063,0.80599 c 0.025017,0.0774 0.096937,0.129773 0.1782406,0.129773 0.081303,0 0.1532244,-0.05238 0.1782406,-0.129773 l 0.261106,-0.80599 0.7864472,0.413548 c 0.072703,0.0383 0.1618234,0.02502 0.2196734,-0.03362 0.057853,-0.05863 0.071921,-0.14697 0.033618,-0.219673 L 6.6336355,7.850803 7.4396265,7.589697 c 0.077394,-0.02502 0.1297715,-0.09694 0.1297715,-0.178241 0,-0.0813 -0.052379,-0.153224 -0.1297715,-0.17824 L 6.6070552,6.963507 6.8079669,6.413151 C 6.8329829,6.344361 6.8157869,6.267744 6.7641909,6.216148 6.7125949,6.164548 6.6359827,6.147358 6.5671884,6.172368 L 6.0168307,6.373283 5.7463436,5.539931 C 5.7213266,5.462541 5.6494066,5.410159 5.568103,5.410159 c -0.081303,0 -0.1532246,0.05238 -0.1782408,0.129772 L 5.137355,6.31856 Z"
id="path10424-2-4"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.00781758;stroke-opacity:1" /><path
d="m 13.173239,2.1617426 c -0.07505,-0.050814 -0.175113,-0.041431 -0.239217,0.021888 -0.0641,0.063319 -0.07349,0.1641686 -0.02189,0.2384352 l 0.875566,1.2766078 -0.778628,0.25329 c -0.07739,0.025017 -0.129773,0.096937 -0.129773,0.1782399 0,0.081303 0.05238,0.1532245 0.129773,0.1782407 l 0.80599,0.2611065 -0.413549,0.7864473 c -0.0383,0.072703 -0.02502,0.1618233 0.03362,0.2196734 0.05864,0.057852 0.146971,0.071921 0.219675,0.033618 l 0.786447,-0.4135483 0.261106,0.8059903 c 0.02502,0.077395 0.09694,0.1297722 0.17824,0.1297722 0.0813,0 0.153225,-0.052378 0.178241,-0.1297722 l 0.261106,-0.8059907 0.786447,0.4135487 c 0.0727,0.038302 0.161824,0.025016 0.219674,-0.033618 0.05785,-0.058635 0.07192,-0.1469701 0.03362,-0.2196735 l -0.41355,-0.7864472 0.805991,-0.2611062 c 0.07739,-0.025016 0.129772,-0.096938 0.129772,-0.1782407 0,-0.081302 -0.05238,-0.1532236 -0.129772,-0.1782399 L 15.919555,3.6822573 16.120467,3.1319008 c 0.02502,-0.068793 0.0078,-0.1454069 -0.04378,-0.1970024 -0.0516,-0.051596 -0.128208,-0.068793 -0.197002,-0.043776 L 15.329331,3.0920327 15.058843,2.258681 c -0.02502,-0.077395 -0.09694,-0.1297722 -0.17824,-0.1297722 -0.0813,0 -0.153225,0.052378 -0.178241,0.1297722 l -0.252507,0.7786288 z"
id="path10424-1"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.00781758;stroke-opacity:1" /></svg>

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="19"
height="15"
viewBox="0 0 19 15"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="simulate-fire-fight.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10" /><sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="39.220856"
inkscape:cx="4.2961836"
inkscape:cy="7.4067736"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" /><path
d="m 7.2492654,5.8221874 c 0.6167358,0 1.2091907,0.1723947 1.7190901,0.4831906 V 13.59209 H 4.3064157 V 9.3599202 L 3.0049573,11.559776 C 2.7330108,12.021113 2.1356998,12.174082 1.6743618,11.902135 1.2130242,11.630189 1.060054,11.032878 1.3320006,10.571539 L 3.1822081,7.4441541 C 3.7770914,6.4389231 4.857593,5.8221874 6.0255062,5.8221874 Z M 4.6949108,3.1027222 c -4.536e-4,-2.59041913 3.8844965,-2.59041913 3.88495,0 4.539e-4,2.5904193 -3.8844964,2.5904193 -3.88495,0 z"
id="path10805"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:4.77275;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
sodipodi:nodetypes="scccccsccsssss" /><path
d="m 18.380988,10.005352 c 0,0.213672 -0.17482,0.388495 -0.388493,0.388495 h -2.823873 c -0.133542,0.233097 -0.386068,0.388495 -0.672584,0.388495 h -2.653906 l 0.128689,0.388494 h 1.359733 c 0.213672,0 0.388495,0.174824 0.388495,0.388499 v 0.388494 c 0,0.213673 -0.174823,0.388497 -0.388495,0.388497 h -2.051738 c -0.16754,0 -0.315653,-0.106835 -0.36907,-0.264664 L 10.4824,10.782342 H 9.8340985 v 1.165487 c 0,0.213673 -0.174823,0.388497 -0.388495,0.388497 h -0.388495 c -0.2136724,0 -0.3884952,-0.174824 -0.3884952,-0.388497 V 10.879466 L 6.432339,11.437928 C 6.1871018,11.49863 5.9491484,11.314095 5.9491484,11.061573 V 9.6168567 c 0,-0.2136722 0.1748227,-0.3884949 0.3884947,-0.3884949 H 8.6686133 V 8.839867 c 0,-0.4297729 0.3472172,-0.7769901 0.7769902,-0.7769901 h 3.4964555 c 0.429773,0 0.77699,0.3472172 0.77699,0.7769901 h 0.776989 c 0.286516,0 0.539038,0.1553976 0.672584,0.3884948 H 17.604 c 0,-0.2136721 0.174823,-0.3884948 0.388495,-0.3884948 0.213673,0 0.388493,0.1748227 0.388493,0.3884948 v 0.3884949 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.61478;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path14144-2" /></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="designated.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="5.9428571"
inkscape:cx="-29.026442"
inkscape:cy="16.237981"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
style="stroke: none"
d="m 7.5000002,0 c 0.498,0 0.9375,0.4395 0.9375,0.9375 V 1.2598 C 11.1621,1.6699 13.3301,3.8379002 13.7402,6.5625002 h 0.3223 c 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 H 13.7402 C 13.3301,11.1914 11.1621,13.3594 8.4375002,13.7695 v 0.293 c 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 v -0.293 C 3.8086002,13.3594 1.6406,11.1914 1.2305,8.4375002 h -0.293 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 h 0.293 C 1.6406,3.8379002 3.8086002,1.6699 6.5625002,1.2598 V 0.9375 c 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 z m -4.3652,8.4375002 c 0.3515,1.7284998 1.6992,3.0761998 3.4277,3.4276998 V 11.25 c 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 0.498,0 0.9375,0.4395 0.9375,0.9375 v 0.6152 C 10.1367,11.5137 11.4844,10.166 11.8359,8.4375002 H 11.25 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 h 0.5859 c -0.3515,-1.6992 -1.6992,-3.0469 -3.3983998,-3.3984 v 0.5859 c 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 v -0.5859 c -1.7285,0.3515 -3.0762,1.6992 -3.4277,3.3984 h 0.6152 c 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 z m 4.3652,0 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 z"
fill="#5ca7ff"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="14.063629"
height="14.9414"
viewBox="0 0 14.063629 14.9414"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="return.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="3.218149"
inkscape:cy="7.1304087"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 7.0324294,0 c 0.1172,0 0.2637,0.0293 0.3809,0.0879 l 5.5077996,2.3437 c 0.6445,0.293 1.1425,0.9082 1.1425,1.67 -0.0292,2.9296 -1.2304,8.2324 -6.2694996,10.664 -0.498,0.2344 -1.0547,0.2344 -1.5527,0 -5.0391,-2.4316 -6.24020004,-7.7344 -6.24020004,-10.664 -0.0293,-0.7618 0.4687,-1.377 1.11320004,-1.67 l 5.5078,-2.3437 C 6.7394294,0.0293 6.8859294,0 7.0324294,0 Z m 0,1.9629 V 13.0371 C 11.075429,11.0742 12.159429,6.7676 12.188629,4.1602 Z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="13.126647"
height="15.015483"
viewBox="0 0 13.126647 15.015483"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="free.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="43.789474"
inkscape:cx="4.5330529"
inkscape:cy="6.7710337"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 10.796771,3.75 c 0,1.31836 -0.7618,2.46094 -1.8750496,3.13476 v 0.61525 c 0,0.5273 -0.43945,0.9375 -0.9375,0.9375 h -2.8125 c -0.52734,0 -0.9375,-0.4102 -0.9375,-0.9375 V 6.88476 c -1.14258,-0.67382 -1.875,-1.8164 -1.875,-3.13476 0,-2.05078 1.875,-3.75 4.21875,-3.75 2.31445,0 4.2187996,1.69922 4.2187996,3.75 z M 4.9373514,5.15625 c 0.49804,0 0.9375,-0.41016 0.9375,-0.9375 0,-0.49805 -0.43946,-0.9375 -0.9375,-0.9375 -0.52735,0 -0.9375,0.43945 -0.9375,0.9375 0,0.52734 0.41015,0.9375 0.9375,0.9375 z m 4.21872,-0.9375 c 0,-0.49805 -0.43943,-0.9375 -0.93748,-0.9375 -0.52734,0 -0.9375,0.43945 -0.9375,0.9375 0,0.52734 0.41016,0.9375 0.9375,0.9375 0.49805,0 0.93748,-0.41016 0.93748,-0.9375 z M 0.10336144,8.02731 c 0.23438,-0.4687 0.79102,-0.6445 1.25976996,-0.4101 l 5.21484,2.6074 5.1854996,-2.6074 c 0.4688,-0.2344 1.0254,-0.0586 1.2598,0.4101 0.2344,0.4688 0.0586,1.0254 -0.4101,1.2598 l -3.9551196,1.9629 3.9551196,1.9922 c 0.4687,0.2344 0.6445,0.791 0.4101,1.2597 -0.2344,0.4688 -0.791,0.6446 -1.2598,0.4102 l -5.1854996,-2.6074 -5.21484,2.6074 c -0.46874996,0.2344 -1.02538996,0.0586 -1.25976996,-0.4102 -0.234374,-0.4687 -0.058593,-1.0253 0.41016,-1.2597 L 4.4685914,11.25001 0.51352144,9.28711 c -0.468753,-0.2344 -0.644534,-0.791 -0.41016,-1.2598 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="9.3896503"
height="9.3896503"
viewBox="0 0 9.3896503 9.3896503"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="hold.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="1.1989183"
inkscape:cy="4.311899"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 9.103975,1.603975 c 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 l -3.0762,3.0761 -3.1055,-3.0761 c -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 -0.3809,0.3515 -0.3809,0.9668 0,1.3183 l 3.0761,3.0762 -3.0761,3.1055 c -0.3809,0.3515 -0.3809,0.9668 0,1.3183 0.3515,0.3809 0.9668,0.3809 1.3183,0 l 3.1055,-3.0761 3.0762,3.0761 c 0.3515,0.3809 0.9668,0.3809 1.3183,0 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 l -3.0761,-3.1055 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="1.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="16.808938"
inkscape:cx="4.2536893"
inkscape:cy="-1.2195892"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<g
id="rect1107">
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="m 1.7050781,9.2421875 -0.328125,0.3300781 v 3.9511724 l 0.328125,0.330078 H 4.5351562 L 4.8652344,13.523438 V 9.5722656 L 4.5351562,9.2421875 Z M 2.0351563,9.9003906 H 4.2070312 V 13.193359 H 2.0351563 Z"
id="path1" />
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 1.7056587,9.5718069 H 4.5356138 V 13.523144 H 1.7056587 Z"
id="path2" />
</g>
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 6.0058594,5.4882812 5.6757812,5.8183594 v 7.6992186 l 0.3300782,0.328125 h 2.8300781 l 0.328125,-0.328125 V 5.8183594 L 8.8359375,5.4882812 Z m 0.328125,0.6582032 h 2.171875 V 13.1875 h -2.171875 z"
id="rect1107-7" />
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 10.304688,1.3828125 9.9746094,1.7128906 V 13.605469 l 0.3300786,0.330078 h 2.830078 l 0.330078,-0.330078 V 1.7128906 L 13.134766,1.3828125 Z m 0.330078,0.6601563 h 2.169922 V 13.277344 h -2.169922 z"
id="rect1107-9" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="2.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="16.808938"
inkscape:cx="4.2536893"
inkscape:cy="-1.2195892"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<g
id="rect1107">
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="m 1.7050781,9.2421875 -0.328125,0.3300781 v 3.9511724 l 0.328125,0.330078 H 4.5351562 L 4.8652344,13.523438 V 9.5722656 L 4.5351562,9.2421875 Z M 2.0351563,9.9003906 H 4.2070312 V 13.193359 H 2.0351563 Z"
id="path1" />
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 1.7056587,9.5718069 H 4.5356138 V 13.523144 H 1.7056587 Z"
id="path2" />
</g>
<g
id="rect1107-7">
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 6.0058594,5.4882812 5.6757812,5.8183594 v 7.6992186 l 0.3300782,0.328125 h 2.8300781 l 0.328125,-0.328125 V 5.8183594 L 8.8359375,5.4882812 Z m 0.328125,0.6582032 h 2.171875 V 13.1875 h -2.171875 z"
id="path3" />
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="m 6.0053182,5.817802 h 2.8299551 v 7.699343 H 6.0053182 Z"
id="path4" />
</g>
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-linejoin:bevel;stroke-dashoffset:5.6;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 10.304688,1.3828125 9.9746094,1.7128906 V 13.605469 l 0.3300786,0.330078 h 2.830078 l 0.330078,-0.330078 V 1.7128906 L 13.134766,1.3828125 Z m 0.330078,0.6601563 h 2.169922 V 13.277344 h -2.169922 z"
id="rect1107-9" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
fill="none"
version="1.1"
viewBox="0 0 15 15"
id="svg8"
sodipodi:docname="3.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs12" />
<sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="55.466667"
inkscape:cx="7.4909856"
inkscape:cy="7.4909856"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<rect
x="1.7057"
y="9.5718"
width="2.83"
height="3.9513"
style="paint-order:stroke fill markers;stroke-dashoffset:5.6;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:.659;"
id="rect2"
fill="#5ca7ff"
stroke="#5ca7ff" />
<rect
x="6.0053"
y="5.8178"
width="2.83"
height="7.6993"
style="paint-order:stroke fill markers;stroke-dashoffset:5.6;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:.659;"
id="rect4"
fill="#5ca7ff"
stroke="#5ca7ff" />
<rect
x="10.305"
y="1.7128"
width="2.83"
height="11.894"
style="paint-order:stroke fill markers;stroke-dashoffset:5.6;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:.659;"
id="rect6"
fill="#5ca7ff"
stroke="#5ca7ff" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="designated.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="5.9428571"
inkscape:cx="-29.026442"
inkscape:cy="16.237981"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 7.5000002,0 c 0.498,0 0.9375,0.4395 0.9375,0.9375 V 1.2598 C 11.1621,1.6699 13.3301,3.8379002 13.7402,6.5625002 h 0.3223 c 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 H 13.7402 C 13.3301,11.1914 11.1621,13.3594 8.4375002,13.7695 v 0.293 c 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 v -0.293 C 3.8086002,13.3594 1.6406,11.1914 1.2305,8.4375002 h -0.293 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 h 0.293 C 1.6406,3.8379002 3.8086002,1.6699 6.5625002,1.2598 V 0.9375 c 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 z m -4.3652,8.4375002 c 0.3515,1.7284998 1.6992,3.0761998 3.4277,3.4276998 V 11.25 c 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 0.498,0 0.9375,0.4395 0.9375,0.9375 v 0.6152 C 10.1367,11.5137 11.4844,10.166 11.8359,8.4375002 H 11.25 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 h 0.5859 c -0.3515,-1.6992 -1.6992,-3.0469 -3.3983998,-3.3984 v 0.5859 c 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 v -0.5859 c -1.7285,0.3515 -3.0762,1.6992 -3.4277,3.3984 h 0.6152 c 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 z m 4.3652,0 c -0.5273,0 -0.9375,-0.4102 -0.9375,-0.9375 0,-0.498 0.4102,-0.9375 0.9375,-0.9375 0.498,0 0.9375,0.4395 0.9375,0.9375 0,0.5273 -0.4395,0.9375 -0.9375,0.9375 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="13.126647"
height="15.015483"
viewBox="0 0 13.126647 15.015483"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="free.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="43.789474"
inkscape:cx="4.5330529"
inkscape:cy="6.7710337"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 10.796771,3.75 c 0,1.31836 -0.7618,2.46094 -1.8750496,3.13476 v 0.61525 c 0,0.5273 -0.43945,0.9375 -0.9375,0.9375 h -2.8125 c -0.52734,0 -0.9375,-0.4102 -0.9375,-0.9375 V 6.88476 c -1.14258,-0.67382 -1.875,-1.8164 -1.875,-3.13476 0,-2.05078 1.875,-3.75 4.21875,-3.75 2.31445,0 4.2187996,1.69922 4.2187996,3.75 z M 4.9373514,5.15625 c 0.49804,0 0.9375,-0.41016 0.9375,-0.9375 0,-0.49805 -0.43946,-0.9375 -0.9375,-0.9375 -0.52735,0 -0.9375,0.43945 -0.9375,0.9375 0,0.52734 0.41015,0.9375 0.9375,0.9375 z m 4.21872,-0.9375 c 0,-0.49805 -0.43943,-0.9375 -0.93748,-0.9375 -0.52734,0 -0.9375,0.43945 -0.9375,0.9375 0,0.52734 0.41016,0.9375 0.9375,0.9375 0.49805,0 0.93748,-0.41016 0.93748,-0.9375 z M 0.10336144,8.02731 c 0.23438,-0.4687 0.79102,-0.6445 1.25976996,-0.4101 l 5.21484,2.6074 5.1854996,-2.6074 c 0.4688,-0.2344 1.0254,-0.0586 1.2598,0.4101 0.2344,0.4688 0.0586,1.0254 -0.4101,1.2598 l -3.9551196,1.9629 3.9551196,1.9922 c 0.4687,0.2344 0.6445,0.791 0.4101,1.2597 -0.2344,0.4688 -0.791,0.6446 -1.2598,0.4102 l -5.1854996,-2.6074 -5.21484,2.6074 c -0.46874996,0.2344 -1.02538996,0.0586 -1.25976996,-0.4102 -0.234374,-0.4687 -0.058593,-1.0253 0.41016,-1.2597 L 4.4685914,11.25001 0.51352144,9.28711 c -0.468753,-0.2344 -0.644534,-0.791 -0.41016,-1.2598 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="9.3896503"
height="9.3896503"
viewBox="0 0 9.3896503 9.3896503"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="hold.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="1.1989183"
inkscape:cy="4.311899"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 9.103975,1.603975 c 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 l -3.0762,3.0761 -3.1055,-3.0761 c -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 -0.3809,0.3515 -0.3809,0.9668 0,1.3183 l 3.0761,3.0762 -3.0761,3.1055 c -0.3809,0.3515 -0.3809,0.9668 0,1.3183 0.3515,0.3809 0.9668,0.3809 1.3183,0 l 3.1055,-3.0761 3.0762,3.0761 c 0.3515,0.3809 0.9668,0.3809 1.3183,0 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 l -3.0761,-3.1055 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="14.063629"
height="14.9414"
viewBox="0 0 14.063629 14.9414"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="return.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="3.218149"
inkscape:cy="7.1304087"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 7.0324294,0 c 0.1172,0 0.2637,0.0293 0.3809,0.0879 l 5.5077996,2.3437 c 0.6445,0.293 1.1425,0.9082 1.1425,1.67 -0.0292,2.9296 -1.2304,8.2324 -6.2694996,10.664 -0.498,0.2344 -1.0547,0.2344 -1.5527,0 -5.0391,-2.4316 -6.24020004,-7.7344 -6.24020004,-10.664 -0.0293,-0.7618 0.4687,-1.377 1.11320004,-1.67 l 5.5078,-2.3437 C 6.7394294,0.0293 6.8859294,0 7.0324294,0 Z m 0,1.9629 V 13.0371 C 11.075429,11.0742 12.159429,6.7676 12.188629,4.1602 Z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="1.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771428"
inkscape:cx="2.6712741"
inkscape:cy="12.283654"
inkscape:window-width="2560"
inkscape:window-height="1377"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
style="opacity:1;fill:none;stroke-width:2.13035;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;stroke-dashoffset:0"
id="path940"
sodipodi:type="arc"
sodipodi:cx="7.614182"
sodipodi:cy="12.730443"
sodipodi:rx="11.467682"
sodipodi:ry="10.686775"
sodipodi:start="4.1887902"
sodipodi:end="5.2359878"
sodipodi:arc-type="slice"
d="m 1.880341,3.4754242 a 11.467682,10.686775 0 0 1 11.467682,2e-7 L 7.614182,12.730443 Z"
fill="#5ca7ff"
stroke="#5ca7ff" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="2.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771428"
inkscape:cx="2.6712741"
inkscape:cy="12.283654"
inkscape:window-width="2560"
inkscape:window-height="1377"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
style="opacity:1;fill:none;stroke-width:2.13035;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path940"
sodipodi:type="arc"
sodipodi:cx="7.614182"
sodipodi:cy="12.730443"
sodipodi:rx="11.467682"
sodipodi:ry="10.686775"
sodipodi:start="4.3633231"
sodipodi:end="5.0614548"
sodipodi:arc-type="slice"
d="m 3.6920035,2.6881593 a 11.467682,10.686775 0 0 1 7.8443565,-2e-7 L 7.614182,12.730443 Z"
fill="#5ca7ff"
stroke="#5ca7ff" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="3.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
width="30px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771428"
inkscape:cx="2.6712741"
inkscape:cy="12.283654"
inkscape:window-width="2560"
inkscape:window-height="1377"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
style="opacity:1;fill:none;stroke-width:2.13035;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path940"
sodipodi:type="arc"
sodipodi:cx="7.614182"
sodipodi:cy="12.730443"
sodipodi:rx="11.467682"
sodipodi:ry="10.686775"
sodipodi:start="4.5378561"
sodipodi:end="4.8869219"
sodipodi:arc-type="slice"
d="m 5.6228404,2.2060238 a 11.467682,10.686775 0 0 1 3.9826836,10e-8 L 7.614182,12.730443 Z"
fill="#5ca7ff"
stroke="#5ca7ff" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="23.317165"
height="17.896727"
viewBox="0 0 23.317165 17.896727"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="evade.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview14"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="33.617877"
inkscape:cx="16.761915"
inkscape:cy="9.1469191"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="path4"
inkscape:showpageshadow="0"
inkscape:deskcolor="#505050" />
<defs
id="defs16" />
<path
d="m 0.02182384,14.515426 c -0.0453,0.1119 -0.01864,0.2398 0.06662,0.325 0.08526,0.0853 0.21314,0.1119 0.32505,0.0666 l 1.95830996,-0.7833 c 0.15188,-0.0613 0.2891,-0.1505 0.405,-0.2664 l 1.02578,-1.0258 3.03735,0.7993 -0.2504,0.2504 c -0.1772,0.1772 -0.1772,0.4623 0,0.6395 0.1772,0.1772 0.4623,0.1772 0.6394,0 l 0.7461,-0.746 0.4263,-0.4263 0.3197,-0.3198 c 0.1772,-0.1771 0.1772,-0.4622 0,-0.6394 -0.1772,-0.1772 -0.4623,-0.1772 -0.6395,0 l -0.1065,0.1066 -1.9184,-1.9184 0.4356,-0.4356 1.4628,0.0959 c 0.0866,0.0066 0.1718,-0.0253 0.2331,-0.0866 l 0.2132,-0.2130999 c 0.1172,-0.1173 0.1172,-0.3091 0,-0.4263 l -1.2789,-1.2789 -0.8526,0.8526 c -0.1173,0.1172 -0.3091,0.1172 -0.4263,0 -0.1173,-0.1173 -0.1173,-0.3091 0,-0.4263 l 0.8526,-0.8526 -1.2789,-1.2789 c -0.1173,-0.1173 -0.3091,-0.1173 -0.4263,0 l -0.2132,0.2131 c -0.0613,0.0613 -0.0933,0.1465 -0.0866,0.2331 l 0.0959,1.4628 -0.4356,0.4356 -1.91834,-1.9183 0.10657,-0.1066 c 0.17717,-0.1772 0.17717,-0.4623 0,-0.6395 -0.17717,-0.1771 -0.46228,-0.1771 -0.63945,0 l -0.31972,0.3198 -0.4263,0.4263 -0.74602996,0.746 c -0.17717,0.1772 -0.17717,0.4623 0,0.6394 0.17717,0.1772 0.46228,0.1772 0.63944996,0 l 0.25041,-0.2504 0.79936,3.0373999 -1.02578,1.0258 c -0.11590996,0.1159 -0.20516996,0.2531 -0.26644996,0.405 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
<g
id="path4">
<path
style="color:#000000;fill:#000000;stroke-linecap:round;stroke-dasharray:2, 2;-inkscape-stroke:none"
d="M 9.09163,5.31113 C 9.52102,4.92078 10.0419,4.48075 10.6248,4.02913 m 1.6233,-1.1672 c 0.5514,-0.36616 1.1277,-0.71785 1.7123,-1.03361 m 1.8146,-0.838 c 0.6645,-0.249206 1.3176,-0.42323 1.9345,-0.490428 m 1.9608,0.245768 c 0.2155,0.095942 0.419,0.218495 0.6086,0.37019 0.3338,0.26698 0.642,0.56583 0.9205,0.8947 m 1.0464,1.69552 c 0.2526,0.58814 0.4328,1.23087 0.5286,1.92301 m 0.0433,1.99609 c -0.0542,0.62718 -0.1704,1.28349 -0.3551,1.96621 m -0.661,1.88542 c -0.249,0.5812 -0.5452,1.1777 -0.8919,1.7881 m -1.0681,1.6909 c -0.3638,0.5236 -0.764,1.0559 -1.2023,1.596 m -1.1572,1.3449"
id="path1" />
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-dasharray:2, 2;-inkscape-stroke:none"
d="m 17.644531,0.00390625 -0.242187,0.03125 -0.253907,0.04296875 -0.255859,0.05273437 -0.255859,0.0625 -0.259766,0.0703125 -0.257812,0.078125 -0.259766,0.0859375 -0.253906,0.0917969 a 0.5,0.5 0 0 0 -0.300781,0.64062495 0.5,0.5 0 0 0 0.640625,0.3007813 l 0.242187,-0.087891 0.234375,-0.078125 0.232422,-0.070312 0.230469,-0.0625 0.224609,-0.054687 0.222656,-0.046875 0.21875,-0.035156 0.222656,-0.0292968 A 0.5,0.5 0 0 0 18.205078,0.43554688 0.5,0.5 0 0 0 17.644531,0.00390625 Z m 1.853516,0.27148438 a 0.5,0.5 0 0 0 -0.28125,0.25976562 0.5,0.5 0 0 0 0.242187,0.66406245 l 0.07422,0.033203 0.06445,0.033203 0.06445,0.035156 0.0625,0.037109 0.0625,0.039063 0.06055,0.041016 0.06055,0.042969 0.05859,0.046875 0.115234,0.091797 0.111328,0.097656 0.111328,0.099609 0.107422,0.1015625 0.105469,0.1054688 0.101563,0.1074218 0.101562,0.109375 0.101563,0.1171875 a 0.5,0.5 0 0 0 0.705078,0.050781 0.5,0.5 0 0 0 0.04883,-0.7050782 l -0.109375,-0.1269531 -0.117188,-0.1289062 -0.11914,-0.125 -0.123047,-0.1210938 -0.125,-0.1191406 -0.126953,-0.11523437 -0.13086,-0.11328125 -0.134765,-0.10937501 -0.08398,-0.0644531 -0.08594,-0.0625 -0.08789,-0.0585938 -0.08789,-0.0566406 -0.0918,-0.0527344 -0.0918,-0.0507813 -0.0918,-0.046875 -0.08789,-0.0390625 A 0.5,0.5 0 0 0 19.498047,0.27539063 Z M 14.099609,1.3496094 A 0.5,0.5 0 0 0 13.71875,1.390625 l -0.220703,0.1210937 -0.222656,0.1269532 -0.222657,0.1289062 -0.220703,0.1308594 -0.216797,0.1347656 -0.216796,0.1347657 -0.214844,0.1386718 -0.210938,0.1367188 a 0.5,0.5 0 0 0 -0.142578,0.6933594 0.5,0.5 0 0 0 0.69336,0.1425781 l 0.205078,-0.1347656 0.205078,-0.1328125 0.208984,-0.1289063 0.208985,-0.1289062 0.208984,-0.125 0.212891,-0.1230469 0.210937,-0.1210938 0.216797,-0.1171875 A 0.5,0.5 0 0 0 14.398438,1.5878906 0.5,0.5 0 0 0 14.099609,1.3496094 Z m 7.957032,1.8945312 a 0.5,0.5 0 0 0 -0.273438,0.6503907 l 0.08789,0.2167968 0.07813,0.2109375 0.07227,0.2167969 0.06445,0.2226562 0.05859,0.2265625 0.05273,0.2324219 0.04492,0.2363281 0.03711,0.2480469 a 0.5,0.5 0 0 0 0.572265,0.4179688 0.5,0.5 0 0 0 0.416016,-0.5703125 l -0.04102,-0.265625 -0.05078,-0.2695313 -0.05859,-0.2636719 -0.06641,-0.2578125 -0.07422,-0.2558593 -0.08398,-0.2480469 -0.08984,-0.2441406 -0.09375,-0.2304688 A 0.5,0.5 0 0 0 22.056641,3.2441406 Z M 10.316406,3.6347656 10.099609,3.8046875 9.8867188,3.9765625 9.6796875,4.1445312 9.4785156,4.3105469 9.1015625,4.6328125 8.7597656,4.9375 A 0.5,0.5 0 0 0 8.71875,5.6425781 0.5,0.5 0 0 0 9.4238281,5.6855469 L 9.7597656,5.3867187 10.123047,5.0761719 10.314453,4.9160156 10.513672,4.7539062 10.71875,4.5898437 10.933594,4.4238281 a 0.5,0.5 0 0 0 0.08594,-0.703125 0.5,0.5 0 0 0 -0.703125,-0.085937 z m 12.550781,3.4921875 a 0.5,0.5 0 0 0 -0.546875,0.4492188 l -0.02344,0.2304687 -0.02734,0.2285157 -0.0332,0.2304687 -0.03906,0.2324219 -0.04492,0.2363281 -0.05078,0.2402344 -0.05859,0.2421875 -0.06445,0.2480469 a 0.5,0.5 0 0 0 0.359375,0.6093752 0.5,0.5 0 0 0 0.609375,-0.3574221 l 0.06641,-0.2597656 0.0625,-0.2636719 0.05664,-0.2597656 0.04883,-0.2578125 0.04297,-0.2558594 0.03711,-0.2519531 0.0293,-0.2519532 0.02344,-0.2421875 a 0.5,0.5 0 0 0 -0.447266,-0.546875 z m -1.248046,3.8847659 a 0.5,0.5 0 0 0 -0.275391,0.265625 l -0.09375,0.214844 -0.09766,0.21289 -0.101563,0.214844 -0.105469,0.216797 -0.111328,0.21875 -0.115234,0.21875 -0.119141,0.220703 -0.126953,0.226562 a 0.5,0.5 0 0 0 0.19336,0.679688 0.5,0.5 0 0 0 0.679687,-0.191406 l 0.128906,-0.232422 0.126953,-0.232422 0.121094,-0.232422 0.117188,-0.230469 0.111328,-0.228515 0.109375,-0.228516 0.101562,-0.226562 0.09766,-0.220704 a 0.5,0.5 0 0 0 -0.257813,-0.658203 0.5,0.5 0 0 0 -0.382812,-0.0078 z m -1.488282,3.537109 a 0.5,0.5 0 0 0 -0.697265,0.117188 l -0.277344,0.390625 -0.287109,0.390625 -0.302735,0.392578 -0.318359,0.40039 a 0.5,0.5 0 0 0 0.08008,0.703125 0.5,0.5 0 0 0 0.703125,-0.08008 l 0.324219,-0.40625 0.3125,-0.408203 0.298828,-0.40625 L 20.25,15.244141 a 0.5,0.5 0 0 0 -0.119141,-0.695313 z"
id="path3" />
</g>
<path
d="m 14.783034,12.805026 -0.1001,0.8985 0.9106,-0.2539 0.0806,0.6152 -0.8301,0.0586 0.5444,0.7251 -0.5542,0.2954 -0.3808,-0.7642 -0.3345,0.7593 -0.5762,-0.2905 0.5396,-0.7251 -0.8252,-0.0635 0.0952,-0.6103 0.8911,0.2539 -0.1001,-0.8985 z"
fill="#5ca7ff"
id="path6"
style="stroke: none" />
<path
d="m 13.384534,7.2113261 -0.1001,0.8984 0.9107,-0.2539 0.0805,0.6152 -0.83,0.0586 0.5444,0.7251 -0.5542,0.2954 -0.3809,-0.7641 -0.3344,0.7593 -0.5762,-0.2906 0.5395,-0.7251 -0.8252,-0.0634 0.0953,-0.6104 0.8911,0.2539 -0.1001,-0.8984 z"
fill="#5ca7ff"
id="path8"
style="stroke: none" />
<path
d="m 18.977834,7.2113261 -0.1001,0.8984 0.9106,-0.2539 0.0806,0.6152 -0.8301,0.0586 0.5445,0.7251 -0.5542,0.2954 -0.3809,-0.7641 -0.3345,0.7593 -0.5761,-0.2906 0.5395,-0.7251 -0.8252,-0.0634 0.0952,-0.6104 0.8911,0.2539 -0.1001,-0.8984 z"
fill="#5ca7ff"
id="path10"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="23.317165"
height="17.896727"
viewBox="0 0 23.317165 17.896727"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="manoeuvre.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview14"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="11.757812"
inkscape:cy="9.4020431"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg12"
inkscape:showpageshadow="0"
inkscape:deskcolor="#505050" />
<defs
id="defs16" />
<path
d="m 0.02182384,14.515426 c -0.0453,0.1119 -0.01864,0.2398 0.06662,0.325 0.08526,0.0853 0.21314,0.1119 0.32505,0.0666 l 1.95830996,-0.7833 c 0.15188,-0.0613 0.2891,-0.1505 0.405,-0.2664 l 1.02578,-1.0258 3.03735,0.7993 -0.2504,0.2504 c -0.1772,0.1772 -0.1772,0.4623 0,0.6395 0.1772,0.1772 0.4623,0.1772 0.6394,0 l 0.7461,-0.746 0.4263,-0.4263 0.3197,-0.3198 c 0.1772,-0.1771 0.1772,-0.4622 0,-0.6394 -0.1772,-0.1772 -0.4623,-0.1772 -0.6395,0 l -0.1065,0.1066 -1.9184,-1.9184 0.4356,-0.4356 1.4628,0.0959 c 0.0866,0.0066 0.1718,-0.0253 0.2331,-0.0866 l 0.2132,-0.2130999 c 0.1172,-0.1173 0.1172,-0.3091 0,-0.4263 l -1.2789,-1.2789 -0.8526,0.8526 c -0.1173,0.1172 -0.3091,0.1172 -0.4263,0 -0.1173,-0.1173 -0.1173,-0.3091 0,-0.4263 l 0.8526,-0.8526 -1.2789,-1.2789 c -0.1173,-0.1173 -0.3091,-0.1173 -0.4263,0 l -0.2132,0.2131 c -0.0613,0.0613 -0.0933,0.1465 -0.0866,0.2331 l 0.0959,1.4628 -0.4356,0.4356 -1.91834,-1.9183 0.10657,-0.1066 c 0.17717,-0.1772 0.17717,-0.4623 0,-0.6395 -0.17717,-0.1771 -0.46228,-0.1771 -0.63945,0 l -0.31972,0.3198 -0.4263,0.4263 -0.74602996,0.746 c -0.17717,0.1772 -0.17717,0.4623 0,0.6394 0.17717,0.1772 0.46228,0.1772 0.63944996,0 l 0.25041,-0.2504 0.79936,3.0373999 -1.02578,1.0258 c -0.11590996,0.1159 -0.20516996,0.2531 -0.26644996,0.405 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
<path
style="color:#000000;fill:#5ca7ff;stroke-linecap:round;stroke-dasharray:2, 2;-inkscape-stroke:none"
d="m 17.644531,0.00390625 -0.242187,0.03125 -0.253907,0.04296875 -0.255859,0.05273437 -0.255859,0.0625 -0.259766,0.0703125 -0.257812,0.078125 -0.259766,0.0859375 -0.253906,0.0917969 a 0.5,0.5 0 0 0 -0.300781,0.64062495 0.5,0.5 0 0 0 0.640625,0.3007813 l 0.242187,-0.087891 0.234375,-0.078125 0.232422,-0.070312 0.230469,-0.0625 0.224609,-0.054687 0.222656,-0.046875 0.21875,-0.035156 0.222656,-0.0292968 A 0.5,0.5 0 0 0 18.205078,0.43554688 0.5,0.5 0 0 0 17.644531,0.00390625 Z m 1.853516,0.27148438 a 0.5,0.5 0 0 0 -0.28125,0.25976562 0.5,0.5 0 0 0 0.242187,0.66406245 l 0.07422,0.033203 0.06445,0.033203 0.06445,0.035156 0.0625,0.037109 0.0625,0.039063 0.06055,0.041016 0.06055,0.042969 0.05859,0.046875 0.115234,0.091797 0.111328,0.097656 0.111328,0.099609 0.107422,0.1015625 0.105469,0.1054688 0.101563,0.1074218 0.101562,0.109375 0.101563,0.1171875 a 0.5,0.5 0 0 0 0.705078,0.050781 0.5,0.5 0 0 0 0.04883,-0.7050782 l -0.109375,-0.1269531 -0.117188,-0.1289062 -0.11914,-0.125 -0.123047,-0.1210938 -0.125,-0.1191406 -0.126953,-0.11523437 -0.13086,-0.11328125 -0.134765,-0.10937501 -0.08398,-0.0644531 -0.08594,-0.0625 -0.08789,-0.0585938 -0.08789,-0.0566406 -0.0918,-0.0527344 -0.0918,-0.0507813 -0.0918,-0.046875 -0.08789,-0.0390625 A 0.5,0.5 0 0 0 19.498047,0.27539063 Z M 14.099609,1.3496094 A 0.5,0.5 0 0 0 13.71875,1.390625 l -0.220703,0.1210937 -0.222656,0.1269532 -0.222657,0.1289062 -0.220703,0.1308594 -0.216797,0.1347656 -0.216796,0.1347657 -0.214844,0.1386718 -0.210938,0.1367188 a 0.5,0.5 0 0 0 -0.142578,0.6933594 0.5,0.5 0 0 0 0.69336,0.1425781 l 0.205078,-0.1347656 0.205078,-0.1328125 0.208984,-0.1289063 0.208985,-0.1289062 0.208984,-0.125 0.212891,-0.1230469 0.210937,-0.1210938 0.216797,-0.1171875 A 0.5,0.5 0 0 0 14.398438,1.5878906 0.5,0.5 0 0 0 14.099609,1.3496094 Z m 7.957032,1.8945312 a 0.5,0.5 0 0 0 -0.273438,0.6503907 l 0.08789,0.2167968 0.07813,0.2109375 0.07227,0.2167969 0.06445,0.2226562 0.05859,0.2265625 0.05273,0.2324219 0.04492,0.2363281 0.03711,0.2480469 a 0.5,0.5 0 0 0 0.572265,0.4179688 0.5,0.5 0 0 0 0.416016,-0.5703125 l -0.04102,-0.265625 -0.05078,-0.2695313 -0.05859,-0.2636719 -0.06641,-0.2578125 -0.07422,-0.2558593 -0.08398,-0.2480469 -0.08984,-0.2441406 -0.09375,-0.2304688 A 0.5,0.5 0 0 0 22.056641,3.2441406 Z M 10.316406,3.6347656 10.099609,3.8046875 9.8867188,3.9765625 9.6796875,4.1445312 9.4785156,4.3105469 9.1015625,4.6328125 8.7597656,4.9375 A 0.5,0.5 0 0 0 8.71875,5.6425781 0.5,0.5 0 0 0 9.4238281,5.6855469 L 9.7597656,5.3867187 10.123047,5.0761719 10.314453,4.9160156 10.513672,4.7539062 10.71875,4.5898437 10.933594,4.4238281 a 0.5,0.5 0 0 0 0.08594,-0.703125 0.5,0.5 0 0 0 -0.703125,-0.085937 z m 12.550781,3.4921875 a 0.5,0.5 0 0 0 -0.546875,0.4492188 l -0.02344,0.2304687 -0.02734,0.2285157 -0.0332,0.2304687 -0.03906,0.2324219 -0.04492,0.2363281 -0.05078,0.2402344 -0.05859,0.2421875 -0.06445,0.2480469 a 0.5,0.5 0 0 0 0.359375,0.6093752 0.5,0.5 0 0 0 0.609375,-0.3574221 l 0.06641,-0.2597656 0.0625,-0.2636719 0.05664,-0.2597656 0.04883,-0.2578125 0.04297,-0.2558594 0.03711,-0.2519531 0.0293,-0.2519532 0.02344,-0.2421875 a 0.5,0.5 0 0 0 -0.447266,-0.546875 z m -1.248046,3.8847659 a 0.5,0.5 0 0 0 -0.275391,0.265625 l -0.09375,0.214844 -0.09766,0.21289 -0.101563,0.214844 -0.105469,0.216797 -0.111328,0.21875 -0.115234,0.21875 -0.119141,0.220703 -0.126953,0.226562 a 0.5,0.5 0 0 0 0.19336,0.679688 0.5,0.5 0 0 0 0.679687,-0.191406 l 0.128906,-0.232422 0.126953,-0.232422 0.121094,-0.232422 0.117188,-0.230469 0.111328,-0.228515 0.109375,-0.228516 0.101562,-0.226562 0.09766,-0.220704 a 0.5,0.5 0 0 0 -0.257813,-0.658203 0.5,0.5 0 0 0 -0.382812,-0.0078 z m -1.488282,3.537109 a 0.5,0.5 0 0 0 -0.697265,0.117188 l -0.277344,0.390625 -0.287109,0.390625 -0.302735,0.392578 -0.318359,0.40039 a 0.5,0.5 0 0 0 0.08008,0.703125 0.5,0.5 0 0 0 0.703125,-0.08008 l 0.324219,-0.40625 0.3125,-0.408203 0.298828,-0.40625 L 20.25,15.244141 a 0.5,0.5 0 0 0 -0.119141,-0.695313 z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="9.3896503"
height="9.3896503"
viewBox="0 0 9.3896503 9.3896503"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="none.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="4.984976"
inkscape:cy="4.311899"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 9.103975,1.603975 c 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 l -3.0762,3.0761 -3.1055,-3.0761 c -0.3515,-0.3809 -0.9668,-0.3809 -1.3183,0 -0.3809,0.3515 -0.3809,0.9668 0,1.3183 l 3.0761,3.0762 -3.0761,3.1055 c -0.3809,0.3515 -0.3809,0.9668 0,1.3183 0.3515,0.3809 0.9668,0.3809 1.3183,0 l 3.1055,-3.0761 3.0762,3.0761 c 0.3515,0.3809 0.9668,0.3809 1.3183,0 0.3809,-0.3515 0.3809,-0.9668 0,-1.3183 l -3.0761,-3.1055 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="23.2749"
height="12.9971"
viewBox="0 0 23.2749 12.9971"
fill="none"
version="1.1"
id="svg14"
sodipodi:docname="passive.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview16"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="23.771429"
inkscape:cx="11.589543"
inkscape:cy="6.7518028"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg14"
inkscape:showpageshadow="0"
inkscape:deskcolor="#505050" />
<defs
id="defs18" />
<path
d="M 0.1977,6.4546 C 0.07745,6.5055 0,6.6237 0,6.7542 0,6.8846 0.07745,7.0028 0.1977,7.0538 l 2.09719,0.8987 c 0.16304,0.0694 0.33629,0.106 0.51361,0.106 h 1.5693 l 1.712,2.9349 H 5.7067 c -0.2711,0 -0.4892,0.2181 -0.4892,0.4891 0,0.2711 0.2181,0.4892 0.4892,0.4892 H 6.848 7.5002 7.9893 c 0.2711,0 0.4892,-0.2181 0.4892,-0.4892 0,-0.271 -0.2181,-0.4891 -0.4892,-0.4891 H 7.8263 V 8.0585 h 0.6664 l 1.0456,1.1923 c 0.0611,0.0713 0.1508,0.1121 0.2445,0.1121 h 0.3261 c 0.1794,0 0.3261,-0.1467 0.3261,-0.3261 V 7.0802 H 9.1306 c -0.1793,0 -0.326,-0.1467 -0.326,-0.326 0,-0.1794 0.1467,-0.3261 0.326,-0.3261 H 10.435 V 4.4715 c 0,-0.1794 -0.1467,-0.3261 -0.3261,-0.3261 H 9.7828 c -0.0937,0 -0.1834,0.0407 -0.2445,0.112 L 8.4927,5.4498 H 7.8263 V 2.5149 h 0.163 c 0.2711,0 0.4892,-0.2181 0.4892,-0.4891 0,-0.2711 -0.2181,-0.4892 -0.4892,-0.4892 H 7.5002 6.848 5.7067 c -0.2711,0 -0.4892,0.2181 -0.4892,0.4892 0,0.271 0.2181,0.4891 0.4892,0.4891 H 6.0898 L 4.3778,5.4498 H 2.8085 c -0.17732,0 -0.35057,0.0367 -0.51361,0.106 z"
fill="#5ca7ff"
id="path2"
style="stroke: none" />
<path
style="color:#000000;fill:#5ca7ff;stroke-dasharray:2, 2;-inkscape-stroke:none"
d="m 12.839844,6.0488281 v 1 h 2 v -1 z m 4,0 v 1 h 2 v -1 z m 4,0 v 1 h 2 v -1 z"
id="path4" />
<path
d="m 16.4116,9 -0.1,0.8984 0.9106,-0.2539 0.0806,0.6152 -0.8301,0.0586 0.5444,0.7251 -0.5542,0.2955 L 16.0821,10.5747 15.7476,11.334 15.1714,11.0434 15.711,10.3183 14.8858,10.2549 14.981,9.6445 15.8721,9.8984 15.772,9 Z"
fill="#5ca7ff"
id="path6"
style="stroke: none" />
<path
d="m 21.4116,10.6582 -0.1,0.8984 0.9106,-0.2539 0.0806,0.6153 -0.8301,0.0585 0.5444,0.7251 -0.5542,0.2955 -0.3808,-0.7642 -0.3345,0.7593 -0.5762,-0.2906 0.5396,-0.7251 -0.8252,-0.0634 0.0952,-0.6104 0.8911,0.2539 -0.1001,-0.8984 z"
fill="#5ca7ff"
id="path8"
style="stroke: none" />
<path
d="m 21.4116,0 -0.1,0.8984 0.9106,-0.2539 0.0806,0.6152 -0.8301,0.0586 0.5444,0.7251 L 21.4629,2.3389 21.0821,1.5747 20.7476,2.334 20.1714,2.0434 20.711,1.3183 19.8858,1.2549 19.981,0.6445 20.8721,0.8984 20.772,0 Z"
fill="#5ca7ff"
id="path10"
style="stroke: none" />
<path
d="m 16.4116,1.6582 -0.1,0.8984 0.9106,-0.2539 0.0806,0.6153 -0.8301,0.0585 0.5444,0.7251 L 16.4629,3.9971 16.0821,3.2329 15.7476,3.9922 15.1714,3.7016 15.711,2.9765 14.8858,2.9131 14.981,2.3027 15.8721,2.5566 15.772,1.6582 Z"
fill="#5ca7ff"
id="path12"
style="stroke: none" />
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
fill="none"
version="1.1"
viewBox="0 0 16 16"
id="svg7226"
sodipodi:docname="airbase.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs7230" />
<sodipodi:namedview
id="namedview7228"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="36.990523"
inkscape:cx="13.692696"
inkscape:cy="7.4208196"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg7226" />
<metadata
id="metadata7218">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="color:#000000;fill:#000000;stroke-linecap:square;-inkscape-stroke:none"
d="M 5.921875,4.6113281 5.3164062,5.0527344 5.5371094,5.3554687 9.5761719,10.880859 9.796875,11.183594 10.400391,10.740234 10.179688,10.439453 6.1425781,4.9140625 Z"
id="line7222" />
<path
style="color:#000000;fill:#000000;stroke-linecap:square;-inkscape-stroke:none"
d="m 5.5449219,8.1777344 -0.050781,0.7480469 0.375,0.025391 4.8906254,0.3242187 0.373047,0.025391 0.05078,-0.7480469 L 10.810547,8.5292969 5.9179687,8.203125 Z"
id="line7224" />
<path
style="color:#000000;fill:#000000;stroke-linejoin:round;-inkscape-stroke:none;paint-order:stroke fill markers"
d="m 8.0019531,0.08203125 c -4.3734295,0 -7.9472656,3.57383615 -7.9472656,7.94726565 0,4.3734291 3.5738361,7.9472661 7.9472656,7.9472661 4.3734299,0 7.9472659,-3.573837 7.9472659,-7.9472661 0,-4.3734295 -3.573836,-7.94726565 -7.9472659,-7.94726565 z m 0,2.69726565 c 2.9157129,0 5.2499999,2.3342873 5.2499999,5.25 0,2.9157131 -2.334287,5.2500001 -5.2499999,5.2500001 -2.9157126,0 -5.25,-2.334287 -5.25,-5.2500001 0,-2.9157127 2.3342874,-5.25 5.25,-5.25 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15.75"
height="14"
viewBox="0 0 15.75 14"
fill="none"
version="1.1"
id="svg7234"
sodipodi:docname="aircraft.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7238" />
<sodipodi:namedview
id="namedview7236"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="26.15625"
inkscape:cx="7.8757467"
inkscape:cy="7.2640382"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg7234" />
<path
stroke-width="0"
d="m 13.1797,5.25 c 0.9297,0 2.5703,0.793 2.5703,1.75 0,0.9844 -1.6406,1.75 -2.5703,1.75 H 9.9805 L 7.2461,13.5625 C 7.082,13.8359 6.7812,14 6.4805,14 H 4.9492 C 4.6484,14 4.4297,13.7266 4.5117,13.4531 L 5.8516,8.75 H 3.0625 L 1.85938,10.3359 C 1.77734,10.4453 1.66797,10.5 1.53125,10.5 H 0.38281 C 0.16406,10.5 0,10.3359 0,10.1172 0,10.0898 0,10.0625 0,10.0352 L 0.875,7 0,3.9922 C 0,3.9648 0,3.9375 0,3.8828 0,3.6914 0.16406,3.5 0.38281,3.5 h 1.14844 c 0.13672,0 0.24609,0.082 0.32813,0.1914 L 3.0625,5.25 H 5.8516 L 4.5117,0.57422 C 4.4297,0.30078 4.6484,0 4.9492,0 H 6.4805 C 6.7812,0 7.082,0.19141 7.2461,0.46484 L 9.9805,5.25 Z"
fill="black"
id="path7232" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg6"
version="1.1"
fill="none"
viewBox="0 0 12.952619 10.362093"
height="10.362093"
width="12.952619"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<path
stroke-width="0"
fill="black"
id="path3711"
d="m 6.4763089,0 c 0.358221,0 0.6476303,0.2894099 0.6476303,0.6476303 v 1.2952618 h 2.428616 c 0.8054918,0 1.4571708,0.6516785 1.4571708,1.4571695 v 5.5048619 c 0,0.805491 -0.651679,1.4571685 -1.4571708,1.4571685 H 3.4000627 c -0.8054909,0 -1.4571694,-0.6516775 -1.4571694,-1.4571685 V 3.4000616 c 0,-0.805491 0.6516785,-1.4571695 1.4571694,-1.4571695 H 5.8286776 V 0.6476303 C 5.8286776,0.2894099 6.1180887,0 6.4763089,0 Z M 4.2096006,7.7715699 c -0.1780979,0 -0.3238152,0.145716 -0.3238152,0.3238146 0,0.178099 0.1457173,0.323817 0.3238152,0.323817 h 0.6476303 c 0.1780991,0 0.3238164,-0.145718 0.3238164,-0.323817 0,-0.1780986 -0.1457173,-0.3238146 -0.3238164,-0.3238146 z m 1.9428933,0 c -0.178099,0 -0.3238163,0.145716 -0.3238163,0.3238146 0,0.178099 0.1457173,0.323817 0.3238163,0.323817 h 0.64763 c 0.178099,0 0.3238153,-0.145718 0.3238153,-0.323817 0,-0.1780986 -0.1457163,-0.3238146 -0.3238153,-0.3238146 z m 1.9428923,0 c -0.178098,0 -0.323815,0.145716 -0.323815,0.3238146 0,0.178099 0.145717,0.323817 0.323815,0.323817 h 0.647631 c 0.178098,0 0.323816,-0.145718 0.323816,-0.323817 0,-0.1780986 -0.145718,-0.3238146 -0.323816,-0.3238146 z M 5.3429549,5.1810458 a 0.8095391,0.8095391 0 1 0 -1.6190782,0 0.8095391,0.8095391 0 1 0 1.6190782,0 z m 3.0762473,0.809538 a 0.80953865,0.80953865 0 1 0 0,-1.6190771 0.80953865,0.80953865 0 1 0 0,1.6190771 z M 0.9714467,4.5334156 h 0.323815 V 8.4192015 H 0.9714467 C 0.4351272,8.4192015 0,7.9840739 0,7.4477529 V 5.504861 C 0,4.9685428 0.4351272,4.5334156 0.9714467,4.5334156 Z m 11.0097253,0 c 0.536319,0 0.971446,0.4351272 0.971446,0.9714454 v 1.9428919 c 0,0.536321 -0.435127,0.9714486 -0.971446,0.9714486 H 11.657355 V 4.5334156 Z" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><!--!Font
Awesome Free 6.5.0 by @fontawesome - https://fontawesome.com License -
https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
<path
d="M64 32C64 14.3 49.7 0 32 0S0 14.3 0 32V64 368 480c0 17.7 14.3 32 32 32s32-14.3 32-32V352l64.3-16.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30V66.1c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L64 48V32z" />
</svg>

After

Width:  |  Height:  |  Size: 577 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="15.75"
height="14"
viewBox="0 0 15.75 14"
fill="none"
version="1.1"
id="svg7234"
sodipodi:docname="helicopter.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata6">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs7238" />
<sodipodi:namedview
id="namedview7236"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="6.5390625"
inkscape:cx="26.041618"
inkscape:cy="10.30219"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg7234" />
<path
inkscape:connector-curvature="0"
d="m 3.173155,1.0409694 c 0,-0.46651814 0.3476271,-0.84342412 0.7779063,-0.84342412 h 9.3348367 c 0.430278,0 0.777906,0.37690598 0.777906,0.84342412 0,0.4665187 -0.347628,0.8434202 -0.777906,0.8434202 H 9.3963807 V 3.571233 h 0.7779053 c 2.148956,0 3.889518,1.8871557 3.889518,4.2171087 v 1.686841 c 0,0.4665172 -0.347628,0.8434233 -0.777906,0.8434233 H 9.3963807 7.8405774 c -0.4886243,0 -0.9505011,-0.250391 -1.2446479,-0.6747365 L 4.8602324,7.1346873 C 4.7751488,7.0108098 4.6584662,6.9159274 4.5271922,6.8579429 L 1.2089503,5.4188529 C 0.97800953,5.318696 0.80298167,5.1025686 0.7422081,4.8389987 L 0.18309237,2.4088928 C 0.11988251,2.1426888 0.30706869,1.8843896 0.55988607,1.8843896 H 1.2283992 c 0.245524,0 0.4764649,0.1238773 0.6223221,0.3373706 L 2.7842066,3.571233 H 7.8405774 V 1.8843896 H 3.9510613 c -0.4302792,0 -0.7779063,-0.3769015 -0.7779063,-0.8434202 z m 6.2232257,7.5907923 h 3.1116153 v -0.84342 c 0,-1.3969171 -1.045307,-2.5302639 -2.33371,-2.5302639 H 9.3963807 Z m 5.9947173,2.7780193 c 0.303871,0.329462 0.303871,0.864511 0,1.193968 l -0.09481,0.102794 c -0.583429,0.632565 -1.375917,0.988385 -2.200006,0.988385 H 6.2847694 c -0.4302775,0 -0.7779054,-0.376906 -0.7779054,-0.843421 0,-0.466518 0.3476279,-0.843424 0.7779054,-0.843424 h 6.8115166 c 0.413259,0 0.809506,-0.176591 1.101221,-0.492874 l 0.09481,-0.102793 c 0.30387,-0.329461 0.79735,-0.329461 1.101219,0 z"
id="path1174-3"
style="fill-opacity:1;stroke-width:0.02531246"
fill="black" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
sodipodi:docname="human.svg"
id="svg6"
version="1.1"
fill="none"
viewBox="0 0 12.14064 10.677204"
height="10.677204"
width="12.14064"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
fit-margin-bottom="0"
fit-margin-right="0"
fit-margin-left="0"
fit-margin-top="0"
inkscape:document-rotation="0"
inkscape:current-layer="svg6"
inkscape:window-maximized="1"
inkscape:window-y="-8"
inkscape:window-x="1912"
inkscape:window-height="1009"
inkscape:window-width="1920"
inkscape:cy="6.71199"
inkscape:cx="5.7558661"
inkscape:zoom="78.441714"
showgrid="false"
inkscape:pagecheckerboard="0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="namedview8"
inkscape:showpageshadow="0"
inkscape:deskcolor="#505050" />
<path
fill="black"
id="path916"
stroke-width="0"
d="m 5.9808108,5.7908995 c 1.6415273,0 2.9733343,-1.2969197 2.9733343,-2.8954494 C 8.9541451,1.2969203 7.6223381,0 5.9808108,0 4.3392825,0 3.0074758,1.2969203 3.0074758,2.8954501 c 0,1.5985297 1.3318067,2.8954494 2.973335,2.8954494 z M 8.6237741,6.4343342 H 7.4860601 C 7.0276691,6.6394281 6.5176619,6.7560505 5.9808108,6.7560505 5.4439597,6.7560505 4.9360143,6.6394281 4.475561,6.4343342 H 3.3378464 c -1.4598251,0 -2.64296517,1.152148 -2.64296517,2.5737386 v 0.321716 c 0,0.532843 0.44393577,0.9651492 0.99111197,0.9651492 h 8.5896338 c 0.547177,0 0.991112,-0.4323062 0.991112,-0.9651492 v -0.321716 c 0,-1.4215906 -1.18314,-2.5737386 -2.6429649,-2.5737386 z" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="15.767666"
height="14.022505"
viewBox="0 0 15.767666 14.022505"
fill="none"
version="1.1"
id="svg7279"
sodipodi:docname="navyunit.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7283" />
<sodipodi:namedview
id="namedview7281"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="26.15625"
inkscape:cx="7.9139785"
inkscape:cy="7.2640382"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg7279" />
<path
stroke-width="0"
d="m 5.2724978,0.875 c 0,-0.46484 0.3828,-0.875 0.875,-0.875 h 3.5 C 10.112298,0 10.522498,0.41016 10.522498,0.875 V 1.75 h 1.3125 c 0.7109,0 1.3125,0.6016 1.3125,1.3125 v 3.5 l 1.2031,0.4102 c 0.6289,0.2187 0.793,1.039 0.3008,1.4765 l -2.7617,2.543 c -0.4375,0.2461 -0.9297,0.4101 -1.3672,0.4101 -0.5469002,0 -1.1211002,-0.2187 -1.6406002,-0.5468 -0.6016,-0.4375 -1.3946,-0.4375 -1.9961,0 -0.4649,0.3007 -1.0391,0.5468 -1.6406,0.5468 -0.4375,0 -0.9297,-0.164 -1.3672,-0.4101 l -2.76175,-2.543 C 0.62405778,8.0117 0.78811778,7.1914 1.4170278,6.9727 l 1.23047,-0.4102 v -3.5 c 0,-0.7109 0.5742,-1.3125 1.3125,-1.3125 h 1.3125 z m -0.875,5.1133 2.9258,-0.9844 c 0.3554,-0.1094 0.7656,-0.1094 1.1211,0 L 11.397498,5.9883 V 3.5 H 4.3974978 Z m 3.9922,5.5508 c 0.6289,0.4375 1.3672,0.7109 2.1328002,0.7109 0.7109,0 1.5039,-0.2734 2.1055,-0.7109 0.3281,-0.2188 0.7656,-0.1914 1.0664,0.0547 0.4101,0.3281 0.9023,0.5742 1.3945,0.6835 0.4648,0.1094 0.7656,0.5743 0.6563,1.0665 -0.1094,0.4648 -0.6016,0.7656 -1.0665,0.6562 -0.6562,-0.1641 -1.2304,-0.4648 -1.5859,-0.6836 -0.793,0.4102 -1.668,0.6836 -2.5703,0.6836 -0.8750002,0 -1.6680002,-0.2461 -2.2148002,-0.4922 -0.1641,-0.082 -0.3008,-0.164 -0.4102,-0.2187 -0.1367,0.0547 -0.2734,0.1367 -0.4375,0.2187 -0.5469,0.2461 -1.3398,0.4922 -2.1875,0.4922 -0.9023,0 -1.8047,-0.2734 -2.5977,-0.6836 -0.3554,0.2188 -0.92964,0.5195 -1.58589,0.6836 -0.46485002,0.1094 -0.95703002,-0.1914 -1.06641002,-0.6562 -0.10938,-0.4649 0.19141,-0.9571 0.65625,-1.0665 0.49219002,-0.1093 1.01172002,-0.3554 1.39455002,-0.6835 0.3008,-0.2461 0.7383,-0.2735 1.0664,-0.0547 0.6016,0.4375 1.3945,0.7109 2.1328,0.7109 0.7383,0 1.5039,-0.2734 2.1055,-0.7109 0.3007,-0.2188 0.7109,-0.2188 1.0117,0 z"
fill="black"
id="path7277" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16"
width="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="olympus.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="35.929863"
inkscape:cx="5.5803162"
inkscape:cy="7.0554123"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font
Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License -
https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
<path
fill="#000000"
d="m 0.12088324,6.9633961 c 0,-3.8330142 3.10734636,-6.95276438 6.94656096,-6.95276438 h 0.744276 c 2.9522888,0 5.6192728,2.14909138 6.1185578,4.96803198 0.07132,0.4031484 0.210875,0.7969952 0.468272,1.1164118 l 1.30248,1.6312018 c 0.192271,0.2418893 0.297709,0.5395986 0.297709,0.8497136 0,0.7504767 -0.607824,1.358301 -1.358301,1.358301 h -0.626431 v 1.9847321 c 0,1.094704 -0.890029,1.984732 -1.984732,1.984732 h -1.984732 v 0.992367 c 0,0.548902 -0.443463,0.992365 -0.9923651,0.992365 H 3.0979803 c -0.5489022,0 -0.9923651,-0.443463 -0.9923651,-0.992365 V 12.64159 c 0,-0.51789 -0.2139791,-1.007871 -0.530297,-1.420323 C 0.63567188,10.00872 0.12088324,8.5108657 0.12088324,6.9633961 Z M 7.0674442,1.9953635 c -0.272899,0 -0.4961817,0.2232826 -0.4961817,0.4961818 0,1.0233783 -1.2373571,1.5350675 -1.9599237,0.8125014 -0.1922716,-0.1922715 -0.5085876,-0.1922715 -0.7008591,0 -0.1922697,0.1922691 -0.1922697,0.5085874 0,0.7008565 0.7225667,0.7225673 0.2108786,1.9599243 -0.8124994,1.9599243 -0.2729008,0 -0.4961835,0.2232826 -0.4961835,0.496183 0,0.2729016 0.2232827,0.4961822 0.4961835,0.4961822 1.023378,0 1.5350661,1.237357 0.8124994,1.9599243 -0.1922697,0.1922714 -0.1922697,0.5085874 0,0.7008589 0.1922715,0.1922691 0.5085875,0.1922691 0.7008591,0 0.7225666,-0.7225673 1.9599237,-0.2108781 1.9599237,0.8124991 0,0.272901 0.2232827,0.496184 0.4961817,0.496184 0.2729008,0 0.4961834,-0.223283 0.4961834,-0.496184 0,-1.0233772 1.2373571,-1.5350664 1.9599238,-0.8124991 0.1922696,0.1922691 0.5085876,0.1922691 0.7008586,0 0.19227,-0.1922715 0.19227,-0.5085875 0,-0.7008589 -0.7225662,-0.7225673 -0.210878,-1.9599243 0.8125,-1.9599243 0.272901,0 0.496182,-0.2232806 0.496182,-0.4961822 0,-0.2729004 -0.223281,-0.496183 -0.496182,-0.496183 -1.023378,0 -1.5350662,-1.237357 -0.8125,-1.9599243 0.19227,-0.1922691 0.19227,-0.5085874 0,-0.7008565 -0.192271,-0.1922715 -0.508589,-0.1922715 -0.7008586,0 C 8.8009847,4.0266128 7.5636276,3.5149236 7.5636276,2.4915453 7.5636276,2.2186461 7.340345,1.9953635 7.0674442,1.9953635 Z M 6.3231699,4.9724603 a 0.74427515,0.74427515 0 1 1 0,1.4885502 0.74427515,0.74427515 0 1 1 0,-1.4885502 z m 1.2404577,2.4809166 a 0.49618347,0.49618347 0 1 1 0.9923669,0 0.49618347,0.49618347 0 1 1 -0.9923669,0 z"
id="path1"
style="stroke-width:0.0310115" />
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Some files were not shown because too many files have changed in this diff Show More