Post by Sa8Gecko on Jun 23, 2009 5:37:38 GMT -5
! caution ! use it for test only
What's MRSI, if you don't know?
MRSI means 'multiple round simultaneous impact': an artillery piece fires various shells at different muzzle velocities and elevations and all these shells land on the target at the same time.
first, download this file:
rapidshare.com/files/247670628/Arty.pbo
and place it in your ArmA addon directory: this file will change the standard M119 howitzer, giving it a muzzle speed of 334 m/s, zero drag, raising a little the max elevation to be equal of the real counterpart, and setting a shell lifetime of 70 seconds. Using this file will probably get you kicked out of any server you try to join in MP, so remove it before playing on-line.
Now, the script:
It must be placed in the mission folder, so first you have to start the editor and save a mission, then put the script in the mission folder. Call it as you like, for example 'mrsi.sqf' (without the quotes!)
In the editor put a M119 howitzer, that you'll call for example 'arty': place it on a flat, horizontal surface. It's important, so be sure you place it right. Then place a target object, that you'll name, for example, 'target' (what a fantasy...). You could be the target, but I won't do that.
The script must be called with the following syntax:
where 'var' is the name of the returned script handler. It can be done without, anyway. You can use more than one M119, either with the same target or a different one. If you place the artillery pieces one near the other, that is at about 10 meters distance, and you order them to fire at the same target, the effect will be even more noticeable.
Place the target away from the arty pieces. You can place it anywhere in a range of about 11400 meters from the artillery pieces.
Place yourself near the target, but not too near, if you haven't chose to be the target itself, possibly on the same side of the arty piece(s).
The script can be called with a trigger.
Once done, start the mission.
Please note:
the shells are not created out of thin air. They exit from the arty muzzle and go the whole way to the target, if they don't meet some obstacle before. We at MCAR have not the habit to make those cheap tricks.
Some explanations about how the script works:
- the M119 in this script is assumed it can fire at three different muzzle speed: 210,265 and 334 m/s. This way various trajectories to the target (parabolas) are possible. For each muzzle speed there are usually two trajectories possible: not always cause the max elevation of the piece is set to 71.28 degrees, but usually there is at least one, if the target is not out of range for that particular speed. So every possible trajectory is elaborated, and the various elevation angles, time to target and muzzle speed are stored.
- this won't give you six shells to the target. Infact the ranges at the various speed don't overlap too much, and while all speed allow to hit a target nearer that about 4500 meters from the arty piece, 334 m/s is too high a speed for the indirect parabola, as it would exceed max elevation.
- then, you can't fire two shells in a time less that what it takes to reload them. You're not using autocannons. So if there are two possible trajectories which will rewuire the two shells to be fired one too near the other in time, one is eliminated.
- once all the possible firing solutions are sorted out, the arty start firing, starting obviously with the shell which parabola would take the greater time to complete.
- each muzzle speed has been tweaked a little so that all the shells would not land on the same spot, that is: right on target. You don't believe me? delete the random factors in the eventhandler a*signment in the script and replace them with the correct values of 210, 265 and 334. It doesn't matter if you placed the target on a mountain top or everywhere else: if there's a parabola to it, it will be hit. You can try to put the target among high palaces or in a narrow valley surrounded by high mountains: if there's an indirect (howitzer like) trajectory, it will be hit. Of course the shell fired in direct mode could miss it, because it impacted an obstacle before... but if there's no obstacle, it won't miss.
Disclaimer, and credits:
the script has been done by me, Sa8Gecko, as a spin-off of an arty script on which I was requested to give some help by a member of FWW2 mod. So if you in the future would examine one of their script and find it similar to this one in some parts, now you know the answer. You can use this script in your addon or your missions if you like it, but give me credits. I usually don't mind about that, but since I've the intention of using it for a PzH 2000 self-propelled howitzer (if I get some time), I won't like to be accused of stealing my own work in the future.
A final note: you can try to port this script to OFP, but it won't work right away. OFP's physic engine is even stranger than ArmA's...
What's MRSI, if you don't know?
MRSI means 'multiple round simultaneous impact': an artillery piece fires various shells at different muzzle velocities and elevations and all these shells land on the target at the same time.
first, download this file:
rapidshare.com/files/247670628/Arty.pbo
and place it in your ArmA addon directory: this file will change the standard M119 howitzer, giving it a muzzle speed of 334 m/s, zero drag, raising a little the max elevation to be equal of the real counterpart, and setting a shell lifetime of 70 seconds. Using this file will probably get you kicked out of any server you try to join in MP, so remove it before playing on-line.
Now, the script:
private["_a1","_a2","_v0y1","_v0y2","_outOfRange","_fpar","_spd","_dist","_g","_diffZ","_spArr","_ctrl","_i","_j","_k","_fpar2"];
private["_arty","_target","_ax","_ay","_az","_tx","_ty","_tz","_dz","_EHfiredIdx","_delta"];
_outOfRange=0;
_EHfiredIdx=0;
_arty=_this select 0;
_target=_this select 1;
dostop _arty;
_arty setbehaviour "combat";
sleep 1;
_arty dowatch (getpos _target);
_arty sidechat "calculating firing solutions...";
_g=9.8;
_delta=0.001;
_spArr=[210,265,334];
_i=0;
_ax =(getposASL _arty) select 0;
_ay =(getposASL _arty) select 1;
_az =(getposASL _arty) select 2;
_tx =(getposASL _target) select 0;
_ty =(getposASL _target) select 1;
_tz =(getposASL _target) select 2;
_diffZ= _tz - _az - 1.13;
_dist = sqrt((_tx-_ax)^2+(_ty-_ay)^2);
_fpar=[];
_fpar2=[];
/* calculation of the various angles and times to target for each shell muzzle speed as in _spArr */
while {_i<3} do {
_spd=_spArr select _i;
_fpar set [(_i*6+2),_spd];
_fpar set [(_i*6+5),_spd];
//player globalchat format ["%1, %2",_dist,_spd];
_v0y1= (sqrt(2)/2)*sqrt( ((_spd^2)*(_dist^2) + (_dist^2)*_g*_diffZ + 2*(_diffZ^2)*(_spd^2) + sqrt((_spd^4)*(_dist^4) - 2*(_spd^2)*(_dist^4)*_g*_diffZ - (_dist^6)*(_g^2)))/(_dist^2+_diffZ^2));
_a1 = asin (_v0y1/_spd);
if( format["%1",_a1]=="-1.#IND") then {
_arty sidechat format["target is out of range for %1 m/s",_spd];
_fpar set [(_i*6),-1];
_fpar set [(_i*6+1),-1];
_fpar set [(_i*6+3),-1];
_fpar set [(_i*6+4),-1];
} else {
_v0y2= (sqrt(2)/2)*sqrt( ((_spd^2)*(_dist^2) + (_dist^2)*_g*_diffZ + 2*(_diffZ^2)*(_spd^2) - sqrt((_spd^4)*(_dist^4) - 2*(_spd^2)*(_dist^4)*_g*_diffZ - (_dist^6)*(_g^2)))/(_dist^2+_diffZ^2));
_a2 = asin (_v0y2/_spd);
if (((2*_v0y2)/_g + (-_v0y2 + sqrt(_v0y2^2 - 2*_g*_diffZ))/_g) / (_dist/sqrt(_spd^2-_v0y2^2)) > 1.1) then {
_arty sidechat format ["target is unreachable for %1 m/s, direct mode",_spd];
_fpar set [(_i*6),_a1];
_fpar set [(_i*6+1),_dist/sqrt(_spd^2-_v0y1^2)];
_fpar set [(_i*6+3),-1];
_fpar set [(_i*6+4),-1];
} else {
_fpar set [_i*6,_a1];
_fpar set [_i*6+1,_dist/sqrt(_spd^2-_v0y1^2)];
_fpar set [_i*6+3,_a2];
_fpar set [_i*6+4,_dist/sqrt(_spd^2-_v0y2^2)];
};
};
// player globalchat format["spd %1, a1 %2, tf1 %3, a2 %4, tf2 %5",_spd,_fpar select (_i*6),_fpar select (_i*6+1),_fpar select (_i*6+3),_fpar select (_i*6+4)];
_i=_i+1;
};
//player globalchat format ["%1",_fpar];
/* re-ordering of the array _fpar in ascending order regard to the times to target
and delete of parameters not valid*/
_i=0;
_k=0;
/* deletion of non-valid parameters, like target out of range or angle too step */
while{_i<((count _spArr)*2)} do {
if((_fpar select (_i*3))!=-1 && (_fpar select (_i*3))<71.25) then {
_fpar2 set [_k*3,_fpar select (_i*3)];
_fpar2 set [_k*3+1,_fpar select (_i*3+1)];
_fpar2 set [_k*3+2,_fpar select (_i*3+2)];
_k=_k+1;
};
_i=_i+1;
};
_fpar= + _fpar2;
if (count _fpar2<3) then {
_arty sidechat "No firing solutions available. Aborting...";
_outOfRange=1;
breakTo "exit";
};
_k=_k-1;
_ctrl=0;
/* _ctrl is set to 0 every time there's an exchange of place between two consecutive members of
the array _fpar2. At the start of each cycle in the main loop is set to 1: if at the end _ctrl has
remained equal to 1, it means no exchange has happened and the array is ordered. */
while{_ctrl==0 && ((count _fpar2)>3)} do {
_j=0;
_ctrl=1;
while {_j<_k} do {
if((_fpar2 select (3*_j+1))>(_fpar2 select (3*(_j+1)+1))) then {
_fpar set [(3*_j+1),_fpar2 select (3*(_j+1)+1)];
_fpar set [(3*_j),_fpar2 select (3*(_j+1))];
_fpar set [(3*_j+2),_fpar2 select (3*(_j+1)+2)];
_fpar set [(3*(_j+1)+1),_fpar2 select (3*_j+1)];
_fpar set [(3*(_j+1)),_fpar2 select (3*_j)];
_fpar set [(3*(_j+1)+2),_fpar2 select (3*_j+2)];
_fpar2=+_fpar;
_ctrl=0;
};
_j=_j+1;
};
// player sidechat format["%1",_k];
_k=_k-1;
};
//player sidechat format ["%1",_fpar2];
_k=(count _fpar2)/3;
_i=0;
/* if the time difference between two consecutive members of _fpar2 is less than 7.5,
the element having the greater time is deleted, because there would be no enough time to reload */
while {_i<_k-1 && ((count _fpar2)>3)} do {
if ((_fpar2 select ((_i+1)*3+1))-(_fpar2 select (_i*3+1))<7.5) then {
_fpar2 set [(_i+1)*3,-1];
_fpar2 set [(_i+1)*3+1,-1];
_fpar2 set [(_i+1)*3+2,-1];
_fpar2=_fpar2-[-1];
_k=_k-1;
_i=_i-1;
};
_i=_i+1;
};
//player sidechat format ["%1",_fpar2];
/* the array is ordered and ready to be used... */
_k=(count _fpar2)/3 -1;
_arty sidechat format ["Number of shells to target: %1",_k+1];
while {_k>=0} do {
_high = _dist*tan(_fpar2 select _k*3) -_tz +_az +1.13 +.15/cos(_fpar2 select _k*3);
_arty dowatch [_tx,_ty,_high];
_arty removeAllEventHandlers "fired";
switch (_fpar2 select _k*3+2) do {
case 210: {
_EHfiredIdx = _arty addEventHandler ["fired","_sh= nearestObject [_this select 0,_this select 4];_spd=((random 1)+209.5);_sh setVelocity [((random 1)+209.5)*(((_this select 0) weaponDirection 'M119') select 0),((random 1)+209.5)*(((_this select 0) weaponDirection 'M119') select 1),((random 1)+209.5)*(((_this select 0) weaponDirection 'M119') select 2)];"];
};
case 265: {
_EHfiredIdx = _arty addEventHandler ["fired","_sh= nearestObject [_this select 0,_this select 4];_spd=((random 1)+264.5);_sh setVelocity [((random 1)+264.5)*(((_this select 0) weaponDirection 'M119') select 0),((random 1)+264.5)*(((_this select 0) weaponDirection 'M119') select 1),((random 1)+264.5)*(((_this select 0) weaponDirection 'M119') select 2)];"];
};
case 334: {
_EHfiredIdx = _arty addEventHandler ["fired","_sh= nearestObject [_this select 0,_this select 4];_spd=((random 1)+333.5);_sh setVelocity [((random 1)+333.5)*(((_this select 0) weaponDirection 'M119') select 0),((random 1)+333.5)*(((_this select 0) weaponDirection 'M119') select 1),((random 1)+333.5)*(((_this select 0) weaponDirection 'M119') select 2)];"];
};
};
sleep 4;
while {true} do {
_wd= _arty weaponDirection "M119";
_dz= sin(_fpar2 select _k*3) - (_wd select 2);
if (abs(_dz)<_delta ) exitWith {
_arty fire "M119";
};
_high=_high+_dz*_dist;
_arty dowatch [_tx,_ty,_high];
sleep 0.05;
};
if(_k==(count _fpar2)/3-1) then {
_arty sidechat "commence firing...";
[_fpar2 select (_k*3+1),_arty] spawn {if(((_this select 0)-1)>1)then{sleep ((_this select 0)-1);};(_this select 1) sidechat "SPLASH";true};
};
if (_k>0) then {
sleep ((_fpar2 select (_k*3+1))-(_fpar2 select ((_k-1)*3+1))-4);
};
_k=_k-1;
};
scopeName "exit";
_outOfRange
It must be placed in the mission folder, so first you have to start the editor and save a mission, then put the script in the mission folder. Call it as you like, for example 'mrsi.sqf' (without the quotes!)
In the editor put a M119 howitzer, that you'll call for example 'arty': place it on a flat, horizontal surface. It's important, so be sure you place it right. Then place a target object, that you'll name, for example, 'target' (what a fantasy...). You could be the target, but I won't do that.
The script must be called with the following syntax:
var=[arty,target] execVM "mrsi.sqf"
where 'var' is the name of the returned script handler. It can be done without, anyway. You can use more than one M119, either with the same target or a different one. If you place the artillery pieces one near the other, that is at about 10 meters distance, and you order them to fire at the same target, the effect will be even more noticeable.
Place the target away from the arty pieces. You can place it anywhere in a range of about 11400 meters from the artillery pieces.
Place yourself near the target, but not too near, if you haven't chose to be the target itself, possibly on the same side of the arty piece(s).
The script can be called with a trigger.
Once done, start the mission.
Please note:
the shells are not created out of thin air. They exit from the arty muzzle and go the whole way to the target, if they don't meet some obstacle before. We at MCAR have not the habit to make those cheap tricks.
Some explanations about how the script works:
- the M119 in this script is assumed it can fire at three different muzzle speed: 210,265 and 334 m/s. This way various trajectories to the target (parabolas) are possible. For each muzzle speed there are usually two trajectories possible: not always cause the max elevation of the piece is set to 71.28 degrees, but usually there is at least one, if the target is not out of range for that particular speed. So every possible trajectory is elaborated, and the various elevation angles, time to target and muzzle speed are stored.
- this won't give you six shells to the target. Infact the ranges at the various speed don't overlap too much, and while all speed allow to hit a target nearer that about 4500 meters from the arty piece, 334 m/s is too high a speed for the indirect parabola, as it would exceed max elevation.
- then, you can't fire two shells in a time less that what it takes to reload them. You're not using autocannons. So if there are two possible trajectories which will rewuire the two shells to be fired one too near the other in time, one is eliminated.
- once all the possible firing solutions are sorted out, the arty start firing, starting obviously with the shell which parabola would take the greater time to complete.
- each muzzle speed has been tweaked a little so that all the shells would not land on the same spot, that is: right on target. You don't believe me? delete the random factors in the eventhandler a*signment in the script and replace them with the correct values of 210, 265 and 334. It doesn't matter if you placed the target on a mountain top or everywhere else: if there's a parabola to it, it will be hit. You can try to put the target among high palaces or in a narrow valley surrounded by high mountains: if there's an indirect (howitzer like) trajectory, it will be hit. Of course the shell fired in direct mode could miss it, because it impacted an obstacle before... but if there's no obstacle, it won't miss.
Disclaimer, and credits:
the script has been done by me, Sa8Gecko, as a spin-off of an arty script on which I was requested to give some help by a member of FWW2 mod. So if you in the future would examine one of their script and find it similar to this one in some parts, now you know the answer. You can use this script in your addon or your missions if you like it, but give me credits. I usually don't mind about that, but since I've the intention of using it for a PzH 2000 self-propelled howitzer (if I get some time), I won't like to be accused of stealing my own work in the future.
A final note: you can try to port this script to OFP, but it won't work right away. OFP's physic engine is even stranger than ArmA's...