Anfliegende Raketen für Mission skripten

    • Tut- Complete
    • Anfliegende Raketen für Mission skripten

      Glaube, das passt hier am besten.
      Ich habe heute Nachmittag eine Funktion geschrieben, die eine Rakete von Punkt A nach B schießt, aber dabei B um genau X meter nach links oder rechts vefehlt. Könnte eventuell für Missionsbauer, oder Leute die Beispiele für Vektorrechnung in Arma brauchen, interessant sein.

      Quellcode

      1. // init.sqf
      2. commy_fnc_fireMissile = {
      3. if (!isServer) exitWith {};
      4. params [
      5. ["_origin", objNull, [objNull, []], [3]],
      6. ["_target", objNull, [objNull, []], [3]],
      7. ["_missBy", 10, [0]]
      8. ];
      9. private _type = "R_PG32V_F";
      10. if (_target isEqualType objNull) then {
      11. _target = getPosWorld _target;
      12. };
      13. if (_origin isEqualType objNull) then {
      14. private _size = sizeOf typeOf _origin;
      15. _origin = eyePos _origin;
      16. _origin = _origin vectorAdd ((_origin vectorFromTo _target) vectorMultiply _size);
      17. };
      18. private _tdir = _origin vectorFromTo _target;
      19. private _tlat = vectorNormalized (_tdir vectorCrossProduct [0,0,1]);
      20. private _distance = _origin vectorDistance _target;
      21. private _drop = commy_missileDropData param [_distance / 10, 0];
      22. _missBy = _missBy * selectRandom [1, -1];
      23. private _aimedAt = _target vectorAdd (_tlat vectorMultiply _missBy) vectorAdd [0,0,_drop];
      24. private _vdir = _origin vectorFromTo _aimedAt;
      25. private _vlat = vectorNormalized (_vdir vectorCrossProduct [0,0,1]);
      26. private _vup = _vlat vectorCrossProduct _vdir;
      27. private _speed = getNumber (configFile >> "CfgAmmo" >> _type >> "maxSpeed");
      28. private _vel = _vdir vectorMultiply _speed;
      29. private _rocket = _type createVehicle ASLToAGL _origin;
      30. _rocket setVectorDirAndUp [_vdir, _vup];
      31. _rocket setVelocity _vel;
      32. };
      33. commy_missileDropData = [0,0.029541,0.0899658,0.193573,0.294281,0.459351,0.656891,0.829224,1.08679,1.30298,1.61295,1.95139,2.31268,2.6059,3.01685,3.44354,3.79141,4.26172,4.74542,5.12485,5.63748,6.16766,6.71738,7.13129,7.69009,8.26553,8.85703,9.30579,9.90268,10.5035,11.1243,11.7513,12.2142,12.8335,13.4676,14.1161,14.7581,15.4034,15.8833,16.5442,17.1971,17.8524,18.506,19.1793,19.6863,20.3409,21.0113,21.69,22.3591,23.058,23.6893,24.4043,25.0551,25.7137,26.2387,26.9708,27.6198,28.2621,28.9265,29.6129,30.2961,30.9687,31.6378,32.3071,32.9912,33.6827,34.3344,35.0044,35.6927,36.5342,37.2082,37.875,38.5564,39.2343,39.9013,40.572,41.25,41.9244,42.5989,43.4411,44.1302,44.7975,45.4685,46.1723,46.8287,47.6675,48.1926,49.0496,49.728,50.3991,51.2343,51.9163,52.5947,53.2585,53.9405,54.8013,55.4688,56.1509,56.8221,57.6974,58.3467,59.0215,59.8641,60.5462,61.2173,62.0562,62.731,63.4131,64.252,64.9232,65.6162,66.4551,67.1226,67.9652,68.6546,69.4935,70.1683,70.8504,71.682,72.4589,73.203,73.8778,74.735,75.3988,76.2378,76.9344,77.7624,78.4409,79.2907,79.9692,80.7534,81.5121,82.2672,83.1536,83.7153,84.6637,85.4625,86.1957,86.9361,87.7896,88.6176,89.2851,90.1313,90.9885,91.6597,92.5022,93.3594,94.0269,94.8658,95.7084,96.3941,97.2367,98.0756,98.9364,99.6039,100.45,100.691];
      Alles anzeigen
      Die Argumente der Funktion sind:
      - Ursprung der Rakete (PosASL oder ein Objekt)
      - "Ziel" der Rakete (PosASL oder Objekt)
      - Wieviel Meter am Ziel vorbeigeschossen wird (Zahl in m - optional, Standard: 10m)

      Sie kann für eine Mission definiert werden, indem man den obigen Codeblock in die init.sqf kopiert.

      Die Funktion ist flexibel und kann auf verschiedene Weise in einer Mission verwendet werden. Zum Beispiel in einem sich wiederholendem Trigger (Methode vielleicht auch interessant für den ein oder anderen):



      Für Copy-Paste:

      Quellcode

      1. // Condition
      2. this && {alive heli1 &&
      3. time > thisTrigger getVariable ["commy_timeout", 0]}
      4. // On Activation
      5. [heli1, selectRandom thisList, 15] call commy_fnc_fireMissile;
      6. thisTrigger setVariable ["commy_timeout", time + 10];


      Das wird dafür sorgen dass, so lange heli1 lebt, alle 10 Sekunden eine Rakete auf eine zufällige Einheit im Trigger aus Richtung von heli1 abgeschossen wird, und das Ziel um 15 Meter nach rechts oder links verfehlt.
      Natürlich kann man das Verfehlen abstellen, indem man die Distanz, die der Funktion übergeben wird, Richtung Null verkleinert ;)

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von commy2 () aus folgendem Grund: eyePos, mathe

    • Das ursprüngliche Skript berücksichtigte nicht die Schwerkraft, wodurch langsame Raketen auf hohen Reichtweiten immer "zu kurz kamen". Ich habe das ganze mal mit einem empirisch ermitteltem "commy_missileDropData" Array erweitert, das über die Distanz zum Ziel einen "Drop" vorraussagt. Die Rakete wird beim Abschuss diesen Drop mit einkalkulieren.

      Das Array gilt nur für einen Raketentyp, weshalb ich dieses Argument entfernt habe. Wenn man trotzdem eine andere Raketenart verwenden möchte, hier ist das Skript zum ermitteln des "DropData" Arrays:

      Quellcode

      1. commy_fnc_debug_drop = {
      2. if (!isNil "commy_debug_result") exitWith {};
      3. params [["_type", "R_PG32V_F", [""]]];
      4. private _speed = getNumber (configFile >> "CfgAmmo" >> _type >> "maxSpeed");
      5. commy_debug_rocket = _type createVehicle ASLToAGL [0,0,300];
      6. commy_debug_rocket setVelocity (vectorDir commy_debug_rocket vectorMultiply _speed);
      7. commy_debug_startTime = time;
      8. commy_debug_result = [];
      9. systemChat "test begin";
      10. addMissionEventHandler ["EachFrame", {
      11. if (isNull commy_debug_rocket) exitWith {
      12. removeMissionEventHandler ["EachFrame", _thisEventHandler];
      13. // pad with missed distances
      14. private _lastElement = 0;
      15. {
      16. if (isNil "_x") then {
      17. commy_debug_result set [_forEachIndex, _lastElement];
      18. } else {
      19. _lastElement = _x;
      20. };
      21. } forEach commy_debug_result;
      22. copyToClipboard format ["commy_missileDropData = %1;", commy_debug_result];
      23. systemChat "test done";
      24. commy_debug_result = nil;
      25. };
      26. commy_debug_result set [
      27. (getPosWorld commy_debug_rocket vectorDistance [0,0,300]) / 10,
      28. 300 - (getPosWorld commy_debug_rocket select 2)
      29. ];
      30. }];
      31. };
      Alles anzeigen
    • Habe eine kleine mathematische Ungenauigkeit im ersten Post behoben. War mir zu wenig für einen Post, deshalb hier ein Skript zum Abfeuern einer gelenkten Rakete, die 100%ig ihr Ziel trifft.

      Quellcode

      1. commy_fnc_fireGuidedMissile = {
      2. if (!isNil "commy_missile") exitWith {};
      3. params [
      4. ["_origin", objNull, [objNull, []], 3],
      5. ["_target", objNull, [objNull]]
      6. ];
      7. private _type = "M_Titan_AA";
      8. if (_origin isEqualType objNull) then {
      9. private _size = sizeOf typeOf _origin;
      10. _origin = eyePos _origin;
      11. _origin = _origin vectorAdd ((_origin vectorFromTo getPosWorld _target) vectorMultiply _size);
      12. };
      13. commy_missile = _type createVehicle ASLToAGL _origin;
      14. commy_target = _target;
      15. private _fnc_guide = {
      16. private _missile = commy_missile;
      17. private _target = commy_target;
      18. if (isNull _missile) exitWith {
      19. removeMissionEventHandler ["EachFrame", _thisEventHandler];
      20. commy_missile = nil;
      21. };
      22. private _vdir = getPosWorld _missile vectorFromTo getPosWorld _target;
      23. private _vlat = vectorNormalized (_vdir vectorCrossProduct [0,0,1]);
      24. private _vup = _vlat vectorCrossProduct _vdir;
      25. private _speed = vectorMagnitude velocity _missile;
      26. private _vel = _vdir vectorMultiply _speed;
      27. _missile setVectorDirAndUp [_vdir, _vup];
      28. _missile setVelocity _vel;
      29. };
      30. call _fnc_guide;
      31. addMissionEventHandler ["EachFrame", _fnc_guide];
      32. };
      33. [player, heli1] call commy_fnc_fireGuidedMissile;
      Alles anzeigen