mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'fcs-extension'
This commit is contained in:
commit
8872424abe
BIN
ace_fcs.dll
Normal file
BIN
ace_fcs.dll
Normal file
Binary file not shown.
@ -105,59 +105,28 @@ if (_viewDiff != 0) then {
|
||||
_FCSAzimuth = (atan (_distance / _viewDiff) - (abs _viewDiff / _viewDiff) * 90) + _movingAzimuth;
|
||||
};
|
||||
|
||||
// CALCULATE OFFSET FOR CURRENT WEAPON
|
||||
// CALCULATE OFFSET
|
||||
_FCSMagazines = [];
|
||||
_FCSElevation = [];
|
||||
|
||||
_magazineType = currentMagazine _vehicle;
|
||||
_ammoType = getText (configFile >> "CfgMagazines" >> _magazineType >> "ammo");
|
||||
if !(getText (configFile >> "CfgAmmo" >> _ammoType >> "simulation") == "shotMissile") then {
|
||||
_maxElev = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "Turrets" >> "MainTurret" >> "maxElev");
|
||||
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineType >> "initSpeed");
|
||||
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
||||
_timeToLive = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "timeToLive");
|
||||
_simulationStep = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "simulationStep");
|
||||
{
|
||||
_ammoType = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||
if !(getText (configFile >> "CfgAmmo" >> _ammoType >> "simulation") == "shotMissile") then {
|
||||
_maxElev = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "Turrets" >> "MainTurret" >> "maxElev");
|
||||
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _x >> "initSpeed");
|
||||
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
||||
|
||||
_offset = [_distance, _angleTarget, _maxElev, _initSpeed, _airFriction, _timeToLive, _simulationStep] call FUNC(getAngle);
|
||||
_offset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, _angleTarget, _distance];
|
||||
_offset = parseNumber _offset;
|
||||
|
||||
_FCSMagazines = _FCSMagazines + [_magazineType];
|
||||
_FCSElevation = _FCSElevation + [_offset];
|
||||
};
|
||||
_FCSMagazines = _FCSMagazines + [_x];
|
||||
_FCSElevation = _FCSElevation + [_offset];
|
||||
};
|
||||
} forEach _magazines;
|
||||
|
||||
_vehicle setVariable [QGVAR(Distance), _distance, true];
|
||||
_vehicle setVariable [QGVAR(Magazines), _FCSMagazines, true];
|
||||
_vehicle setVariable [QGVAR(Elevation), _FCSElevation, true];
|
||||
_vehicle setVariable [QGVAR(Azimuth), _FCSAzimuth, true];
|
||||
|
||||
// CALCULATE OFFSETS FOR OTHER WEAPONS IN THE BACKGROUND
|
||||
GVAR(backgroundCalculation) = [_vehicle, _magazines, _distance, _angleTarget, _FCSMagazines, _FCSElevation] spawn {
|
||||
_vehicle = _this select 0;
|
||||
_magazines = _this select 1;
|
||||
_distance = _this select 2;
|
||||
_angleTarget = _this select 3;
|
||||
_FCSMagazines = _this select 4;
|
||||
_FCSElevation = _this select 5;
|
||||
|
||||
{
|
||||
if !(_x in _FCSMagazines) then {
|
||||
_ammoType = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||
if !(getText (configFile >> "CfgAmmo" >> _ammoType >> "simulation") == "shotMissile") then {
|
||||
_maxElev = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "Turrets" >> "MainTurret" >> "maxElev");
|
||||
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _x >> "initSpeed");
|
||||
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
||||
_timeToLive = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "timeToLive");
|
||||
_simulationStep = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "simulationStep");
|
||||
|
||||
_offset = [_distance, _angleTarget, _maxElev, _initSpeed, _airFriction, _timeToLive, _simulationStep] call FUNC(getAngle);
|
||||
|
||||
_FCSMagazines = _FCSMagazines + [_x];
|
||||
_FCSElevation = _FCSElevation + [_offset];
|
||||
};
|
||||
};
|
||||
} forEach _magazines;
|
||||
|
||||
_vehicle setVariable [QGVAR(Magazines), _FCSMagazines, true];
|
||||
_vehicle setVariable [QGVAR(Elevation), _FCSElevation, true];
|
||||
};
|
||||
|
||||
[format ["%1: %2", localize "STR_ACE_FCS_ZeroedTo", _distance]] call EFUNC(common,displayTextStructured);
|
||||
|
117
extensions/ace_fcs.cpp
Normal file
117
extensions/ace_fcs.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* ace_fcs.cpp
|
||||
*
|
||||
* Calculates firing solution.
|
||||
*
|
||||
* Takes:
|
||||
* initSpeed,airFriction,angle,distance as string
|
||||
* Example: "900,-0.0004,2,1050"
|
||||
*
|
||||
* Returns:
|
||||
* Correction to angle
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define MAXELEVATION 20
|
||||
#define SIMULATIONSTEP 0.05
|
||||
#define MAXITERATIONS 120
|
||||
#define PRECISION 0.1
|
||||
#define RADIANS(X) (X / (180 / M_PI))
|
||||
|
||||
static char version[] = "1.0";
|
||||
|
||||
extern "C" {
|
||||
__declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function);
|
||||
};
|
||||
|
||||
std::vector<std::string> splitString(std::string input) {
|
||||
std::istringstream ss(input);
|
||||
std::string token;
|
||||
|
||||
std::vector<std::string> output;
|
||||
while (std::getline(ss, token, ',')) {
|
||||
output.push_back(token);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double traceBullet(double initSpeed, double airFriction, double angle, double angleTarget, double distance) {
|
||||
double velX, velY, posX, posY, posTargetX, posTargetY, velMag;
|
||||
velX = cos(RADIANS(angle)) * initSpeed;
|
||||
velY = sin(RADIANS(angle)) * initSpeed;
|
||||
posX = 0;
|
||||
posY = 0;
|
||||
posTargetX = cos(RADIANS(angleTarget)) * distance;
|
||||
posTargetY = sin(RADIANS(angleTarget)) * distance;
|
||||
|
||||
int i = 0;
|
||||
while (i < MAXITERATIONS) {
|
||||
velMag = sqrt(pow(velX, 2) + pow(velY, 2));
|
||||
velX += SIMULATIONSTEP * (velX * velMag * airFriction);
|
||||
velY += SIMULATIONSTEP * (velY * velMag * airFriction - 9.81);
|
||||
posX += velX * SIMULATIONSTEP;
|
||||
posY += velY * SIMULATIONSTEP;
|
||||
if (posX >= posTargetX) { break; }
|
||||
i++;
|
||||
}
|
||||
|
||||
return posY - posTargetY;
|
||||
}
|
||||
|
||||
double getSolution(double initSpeed, double airFriction, double angleTarget, double distance) {
|
||||
double posTargetX, posTargetY;
|
||||
posTargetX = cos(RADIANS(angleTarget)) * distance;
|
||||
posTargetY = sin(RADIANS(angleTarget)) * distance;
|
||||
|
||||
if (traceBullet(initSpeed, airFriction, MAXELEVATION, angleTarget, distance) < 0) {
|
||||
return MAXELEVATION - angleTarget;
|
||||
}
|
||||
|
||||
double a1 = angleTarget;
|
||||
double a2 = MAXELEVATION;
|
||||
double f1, f2, tmp;
|
||||
f1 = traceBullet(initSpeed, airFriction, a1, angleTarget, distance);
|
||||
if (fabs(f1) <= PRECISION) { return 0; }
|
||||
while (fabs(f1) > PRECISION) {
|
||||
f2 = traceBullet(initSpeed, airFriction, a2, angleTarget, distance);
|
||||
tmp = a2 - f2 * (a2 - a1) / (f2 - f1);
|
||||
a1 = a2;
|
||||
a2 = tmp;
|
||||
f1 = f2;
|
||||
}
|
||||
|
||||
return a2 - angleTarget;
|
||||
}
|
||||
|
||||
// i like to live dangerously. jk, fix strncpy sometime pls.
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4996 )
|
||||
|
||||
void __stdcall RVExtension(char *output, int outputSize, const char *function) {
|
||||
if (!strcmp(function, "version")) {
|
||||
strncpy(output, version, outputSize);
|
||||
} else {
|
||||
std::vector<std::string> argStrings = splitString(function);
|
||||
double initSpeed = std::stod(argStrings[0]);
|
||||
double airFriction = std::stod(argStrings[1]);
|
||||
double angleTarget = std::stod(argStrings[2]);
|
||||
double distance = std::stod(argStrings[3]);
|
||||
|
||||
double result = getSolution(initSpeed, airFriction, angleTarget, distance);
|
||||
std::string resultString = std::to_string(result);
|
||||
|
||||
strcpy(output, resultString.c_str());
|
||||
output[outputSize - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning( pop )
|
8
extensions/stdafx.cpp
Normal file
8
extensions/stdafx.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// ace_fcs.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
16
extensions/stdafx.h
Normal file
16
extensions/stdafx.h
Normal file
@ -0,0 +1,16 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
Loading…
Reference in New Issue
Block a user