Jump to content
Sign in to follow this  
CaptainBravo

enemy artillery ?

Recommended Posts

;1496682']Thanks for the quick response' date=' works pretty well actually. One thing though... dispersion does not seem to be working, or at least not working well enough. With it set to 100m spread, the mortars still land within a 20m circle. A bit too punishing.[/quote']

The dispersion is set by the call to the artillery module, the only thing I can suggest is altering the value until you find something you like. I am not sure if distance from the artillery piece to the target affects it, or if it depends on what artillery type you are using might create different disersion patterns? I know when testing I created a mission where the FO was a uav trying to call in arty on a BM-21 battery on the move. I was using MLRS and had dispersion set to 500 or 600, because trying to hit moving trucks is quite hard. The spread on them was quite huge, but looked awesome from the air watching 10 round barrages landing.

Here is the line I use in the script below just for reference.

[_battery, _Dispersion] call BIS_ARTY_F_SetDispersion;

Edit: You can also change the number of rounds that are fired each time, maybe reduce that to one or two? The other option is to also reduce the skill factor, which adds a little more error randomly into impact point calculation.

Edited by blakeace

Share this post


Link to post
Share on other sites

Realistic artillery is like, certain death. I like the idea of letting good players "get away with it", something I don't achieve with realistic artillery. I like artillery to be a system that keeps my pulse high and my head down, not a system that keeps my body buried. I tried it, it just becomes annoying to die that much. So I made an AI artillery system in Arma1 that I used in my own edit of Domination. Basically, it went like this:

1) Spotters needed to "call it in", but all enemy could "trigger" the arty script. Think of it as a cheap grouplink.

2) Setup parameters based on time and threat level. Predict illum or coordinated illum for night missions, precalculate "aimpoints" based on estimated positions after flight time. Smoke only valid option if distance too close to own troops.

3) Fire a smoke or HE spotround, but make it highly inaccurate. Getting killed by this arty is possible, but unlikely. However, players will see what is going on and be forced to move out.

4) Wait and fire the volleys without any further "adjustment". Players who moved will be rewarded for playing tactically, they're still alive.

Multiplayer considerations:

* Whenever I used "on the fly" calculated randomized impact points, our server would crash. The only option that worked was to store each point in an array and pick them out from there during the "landing".

* Limit the damage, use "less damaging" shells. I for one disagree on the highly destructive power of the M119 shell. That kind of destructive AT power should only happen when coupled with kinetic energy from direct fire, maybe, don't know. It has a definite damage capability, not a decreasing shrapnel capability that decreases properly with distance. To me, the M119 105mm shell "feels like" a 155mm shell wrt damage potential.

* Limit the damage, not only for the issues mentioned above, but for the reason that the game can rarely simulate the amount of forces in a conflict. A 155mm barrage would anhiliate all forces in a given strike area. In real life, you may have reinforcements on standby, or a town is guarded by a battalion instead of a squad. So it makes sense to me at least to "scale things down" for gameplay reasons.

* Limit the amount. In multiplayer, at least for Arma1, I got into trouble if I tried to simulate too much going on during too little time. Realistic count of submunitions for a 155mm DPICM would crash the server, because it had to transmit all those impacts to all clients. Look how "lame" Domination DPICM look, it is a reason for it. Same with smoke. Going realistic amount of smoke canisters doesn't look right on clients, because smoke has a low priority. Try using one arty_smoke instead of all those smoke grenades.

* Limit the zones of destructive fire, also for AI. My guess is that all FDCs follow some kind of ROE, that denies them to fire i.e. into populated areas.

* Sometimes artillery does preemtive firing. It doesn't mean that a spotter has seen someone there, but a planned mission to deny the enemy usage of the area. Nobody goes into an area that is under artillery fire. AI should be prevented too btw.

* Make hit scripts for those in the danger zone when artillery is hitting. When HE is starting, try to force them to get the hell out instead of just standing there waiting to die. One of the reasons I think artillery is overpowered is just because of this, the AI doesn't know how do deal with it. For smoke, have them fire into the smoke, and scan towards the egdes. For illumination, make them hit the deck and be as calm as possible unless fired upon by small arms.

* Using real guns to fire also proved difficult. Although I used scripted approach for all aspects of the missions (simplistic TOF etc), sometimes I wanted that "bang" to be heard. Whenever I had some forced "mass fires" going on, guns would sometimes fire very near eachother wrt timing. When that happened, the shell was sometimes not removed as scripted, and would land in the area together with the scripted shell. You do *not* want a HE shell to land if you call for a smoke screen ;) So, if you want to fire real guns, make sure you have a delay between each gun so that the shell can be safely removed.

"Spot the spotter" - in missions to take out enemy spotters, this is quite hard to do in Arma. A real life spotter (I'm speculating here), would tend to have a long range radio, or stay very close to the RTO. In Arma2, we don't even have models with radios (annoying as hell). He might "behave" in a certain way that would give him away as a spotter. That's also impossible to do. So how do you even spot the spotter?

BIS - for OA, could you please give us RTO units for all sides? Or radios as a special backpack maybe?

But, that's all about the AI artillery. How about the player FO?

Naturally, the player FO shouldn't be point & click arty, but I don't like them having to perform any FDC duties. Being an FO should be a special job, requiring special skills, making the job highly rewarding when it works out. Being an FO should force the player to think, not just click on the map and bang comes in 20 seconds.

Player FO considerations:

* Remove his GPS. Since you cannot remove the magic mapped GPS (which I like for other purposes) which will pinpoint his location.

* Let him designate his own position, prior to setting a target position.

* Any low accuracy fires only requires a map click, but will be centered on the 6 digit grid, with a high dispersion to cover that grid. FDCs disgression.

* High accuracy fires requires observer designation, and could use point & click interface to determine both that and aimpoint. However, the error in own designation is added to the used aimpoint, by using polar designation.

* Another high accuracy method could be 8 or 10 digit grid (8 probably good enough for Arma), but now the player has to type in that grid reference, or dial in the code for it somehow.

* Maintain proper textual communications with FDC, and "semi realistic" flight times.

* ID confirmation code card. A piece of code (renewable at base) holding the phonetic responses in order to verify that you are you.

* Setting a PRF code for incoming Copperheads. If you dialed the wrong number, the shell will hit the designated point instead of the lazed point. Need custom code, the builtin Laser Guided one doesn't support this.

* FDC overrides. Provide a good FDC response and analysis script. Don't let smoke be valid during heavy winds. Don't let WP be valid if it rains. Don't allow low angle HE fires into the woods. Don't allow DPICM into areas we are supposed to enter ourselves (duds). If you enhance the flares to react on winds (continuous setPos on the burning flare), perform auto corrections so the designated point becomes illuminated.

My finale point is this (finally, eh?):

Many fine scripted or real artillery solutions out there, but few that addresses those small details. It's almost always about the gunnery station and proper ballistics. Why, when (I feel) there is so much more to it? The job as an FO could be so much more than a map click interface, but without having to involve human gunnery. Just keep in mind that making it "work" for multiplayer, is a whole different ballgame.

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites

To CarlGustaffa,

Sorry to be honest at the moment to much to try and answer properly (just home from work after horrible day!).

Quickly though, re ai arty, and my scripts. One thats why I at least like the framework modular method, keeps a lot of the important stuff away from having to redo. Also by making the rounds fly from the arty unit to the target, as long as your ai are not just holding a position and moving, looks alright. Re against real players, I generally keep the amount down, surviving massive barrages also as unrealistic I think. Though surviving a small harrassing fire still gives real emersion. One it makes your team keep their spacing. I think though have no proof that the 81mm mortar rounds are less powerful than the M119 105mm rounds in game, to lessen the impact on players?

Re ai FO, that is hard, I have searched for a way to get the ai to keep using the binoculars but have yet to find anything other than fake animations that take the ai totally out of the ai. The best I found was I could get him to intermittently use his binoculars that a sniper could possibly pickup on. I too would love a way to get them to focus with binos, or a radio handset animation or the like.

Re player arty. If you want really real like try using Jones artillery and use my excel program to calculate the trajectories.

What we do if we only want to be half way there is to use the built in BIS arty module use the target cursor. I have mapped my joystick for aiming the guns, and use the map screen to get accurate bearings on where I am aiming the gun. Then we use communications to call in intially 6 figure grid references, we don't use markers. Then call adjustments from that. Generally instead of calling adjustments reletive to the FO we correct them and calll them as North south east west for ease while still getting the sense of using arty realistcally.

If you don't want to even use players on guns, we have used the BIS artillery module to call in arty, but with a twist. An FO calls for strikes back to one of the leaders who then calls the arty using the click on map. That way someone is not stuck on the guns all the time, but stops and recieves fire missions using grid references and corrections which is the best part, we make sure no calls reference markers etc only grids or adjustments, our group also doesn't have map markers on, so unless the FO has a gps he needs to work out where he is and where he wants the rounds.

Edited by blakeace

Share this post


Link to post
Share on other sites

Blakeace, I have a somewhat working ballistics computer in ArmA2 now... I used your algorithms to generate the right firing solutions.

Only issue is that its too slow in ArmA2... much much much to slow.

So I had to calculate ballistics tables. I actually still use your algorithm though. I get a high-low value for the elevation and then I run your algorithm and get the corrected value between the precomputed ones. So a big thanks to you! I still need to figure out how to calculate flight times for low angle artillery.

I'd just use a linear interpolation but I couldnt find one that was accurate enough and this is still pretty quick.

Anyways I am integrating all of this into a somewhat real/somewhat fantasy version of the US AFATDS. I have a version of the M119 that works much like Jones M252, and I am working on getting them to have a better way of aiming, using granular animations to adjust azimuth and elevations.

This is all player controlled stuff by the way, I actually am in a unit with people willing to do it... :P We also do all the cool stuff like polar plots and OT line adjustments and stuff too. Its good fun and we are learning a lot. Lots of real life artillery people I have talked to are impressed! :P

Share this post


Link to post
Share on other sites
Blakeace, I have a somewhat working ballistics computer in ArmA2 now... I used your algorithms to generate the right firing solutions.

Only issue is that its too slow in ArmA2... much much much to slow.

So I had to calculate ballistics tables. I actually still use your algorithm though. I get a high-low value for the elevation and then I run your algorithm and get the corrected value between the precomputed ones. So a big thanks to you! I still need to figure out how to calculate flight times for low angle artillery.

I'd just use a linear interpolation but I couldnt find one that was accurate enough and this is still pretty quick.

Anyways I am integrating all of this into a somewhat real/somewhat fantasy version of the US AFATDS. I have a version of the M119 that works much like Jones M252, and I am working on getting them to have a better way of aiming, using granular animations to adjust azimuth and elevations.

This is all player controlled stuff by the way, I actually am in a unit with people willing to do it... :P We also do all the cool stuff like polar plots and OT line adjustments and stuff too. Its good fun and we are learning a lot. Lots of real life artillery people I have talked to are impressed! :P

Sounds cool look forward to seeing it. I must say my algorithms could be improved to reduce the total amount of calculations, I know they are not very effient, but I was prototyping and haven't got the time to improve on them, or the energy tbh.

Share this post


Link to post
Share on other sites
Sounds cool look forward to seeing it. I must say my algorithms could be improved to reduce the total amount of calculations, I know they are not very effient, but I was prototyping and haven't got the time to improve on them, or the energy tbh.

Its fine, its in the inner loop where the slow down occurs, where it increments I think the deltat? Can not remember off the top of my head, but for every step in elevation it was doing close to 3000 iterations on that. :p

Thanks a lot though, I suck at math so it would have taken me forever to do it any other way and looking at the ballistics table generator in the arty module that they use to precompute it looks about the same as yours (except they start with i believe distance and recalculate back to get the elevation).

Share this post


Link to post
Share on other sites

@CaptainBravo:

"Examples" of some of the mentioned features would be the Dominatrix edit of Domination, found at Dev-Heaven, but it's for Arma1/ACE1.04 (I think 1.04, sorry, long time now).

Fire zones was only done for player arty, if even implemented in that version.

Although not prepped for MP compatibility (particles and say need to be executed on clients), wind "simulation" of flares, something like:

_shelltype = "ARTY_Flare_Small";
_shell = _shelltype createVehicle _pos;
_shell say _sound;
_trail = "#particlesource" createVehicleLocal getpos _shell;
       _trail setParticleRandom [0.25, [0.25, 0.002, 0.25], [0.1, 0, 0.1], 0, 0, [0, 0, 0, 0.2], 0.5, 0.5];
       _trail setDropInterval 0.012;
       _trail setParticleParams [
       ["\ca\Data\ParticleEffects\Universal\Universal.p3d", 16, 7, 48],
		"", "Billboard", 1, 25, 
		[0,0,0.5], [0,0,2.9], 
		1, 1.275, 1.0, 0.57986, 
		[0.5, 8.3], 
		[[0.2, 0.2, 0.2, 0.09],[0.6, 0.6, 0.6, 0.0],[0.0, 0.0, 0.0, 0.0],[1, 1, 1, 0]], [2], 2, 0.2, "", "", _shell, 0];
_trail attachTo [_shell, [0,0,0]];
_trail;
while {!isNull _shell} do {
	_shell setPos [(getPos _shell select 0) + (wind select 0)/30, (getPos _shell select 1) + (wind select 1)/30, getPos _shell select 2];
	sleep 0.075;
};

Part of some stuff I was working on for highly simplified "high angle checks". Quite arbitrary, but gave the effect of FDC automatically using "high angle" to avoid predicted trajectory if it clashed with terrain. For the player, all that was affected was flight time and dispersion, since no actual shell had to be fired. So, not realistic in any means, other than providing some variation on how stuff was executed. Only a couple of subroutines to show what was going on, as it was part of something I abandoned in Arma1. If it can be used, then feel free, although I think most prefer realism on this one rather than this "weird" approach :)

Deals with elliptical distribution patterns (charge varies, not aim), but elliptical distribution filler was not working as I'd predicted. Copperhead footprint is circular but size will vary with overcast. Again, lots of highly simplified stuff. Oh, and disregard the speech communication system. It worked, but it sounded far too broken up. Consider that a proof of concept, nothing else. Works, but not usable :p

#include "Artillery_ColorScheme.hpp";
//indexselect and speechlist must be global to work with spawn? Unless _indexselect is created automatically.
indexselect = [
"o01",
"o02_0","o02_1","o02_2","o02_3","o02_4","o02_5","o02_6","o02_7","o02_8","o02_9","o02_grid","o02_over",
"o03_units",
"o04_guns","o04_message","o04_out","o04_rounds","o04_targetnumber",
"o05_shot",
"o06_splash",
"o07_correct","o07_impact",
"o08_end",
"s01",
"s02_0","s02_1","s02_2","s02_3","s02_4","s02_5","s02_6","s02_7","s02_8","s02_9","s02_grid","s02_out",
"s03_units",
"s04_guns","s04_message","s04_over","s04_rounds","s04_targetnumber",
"s05_shot",
"s06_splash",
"s07_correct","s07_impact",
"s08_end"
];
speechlist = [
["o01","Steel Rain, this is Raptor. Adjust fire, system aided. Over.",5.241],
["o02_0","0",0.525],
["o02_1","1",0.426],
["o02_2","2",0.468],
["o02_3","3",0.546],
["o02_4","4",0.337],
["o02_5","5",0.402],
["o02_6","6",0.644],
["o02_7","7",0.573],
["o02_8","8",0.411],
["o02_9","9",0.456],
["o02_grid","Grid ",1.410],
["o02_over",". Over.",2.263],
["o03_units","Units in the open. Request splash. Over.",2.403],
["o04_guns"," guns in effect.",0.890],
["o04_message","Message to observer: ",1.792],
["o04_out",". Out.",1.170],
["o04_rounds"," rounds. ",0.542],
["o04_targetnumber"," Target number Alpha Bravo ",1.586],
["o05_shot","Shot. Out.",1.652],
["o06_splash","Splash. Out.",2.266],
["o07_correct","Correct and fire for effect. Over.",2.780],
["o07_impact","Impact grid ",1.600],
["o08_end","Record as target. End of mission. Targets supressed. Over.",4.898],
["s01","Raptor this is Steel Rain. Adjust fire, system aided. Out.",4.613],
["s02_0","0",0.371],
["s02_1","1",0.286],
["s02_2","2",0.449],
["s02_3","3",0.255],
["s02_4","4",0.417],
["s02_5","5",0.333],
["s02_6","6",0.299],
["s02_7","7",0.433],
["s02_8","8",0.411],
["s02_9","9",0.369],
["s02_grid","Grid ",0.625],
["s02_out",". Out.",1.269],
["s03_units","Units in the open. Request splash. Out.",2.633],
["s04_guns"," guns in effect.",0.768],
["s04_message","Message to observer: ",1.868],
["s04_over",". Over.",1.204],
["s04_rounds"," rounds.",0.530],
["s04_targetnumber"," Target number Alpha Bravo ",1.519],
["s05_shot","Shot. Over.",2.201],
["s06_splash","Splash. Over.",1.742],
["s07_correct","Correct and fire for effect. Out.",2.408],
["s07_impact","Impact grid ",1.460],
["s08_end","Record as target. End of mission. Targets supressed. Out.",4.837]
];

//Direction from an object to another. Hmm, need one that deals exclusively with markers.
XfDirToObj = {
private ["_o1","_o2","_deg"];
_o1 = _this select 0;_o2 = _this select 1;
_deg = ((position _o2 select 0) - (position _o1 select 0)) atan2 ((position _o2 select 1) - (position _o1 select 1));
if (_deg < 0) then {_deg = _deg + 360};
_deg
};
//Returns the altitude of an object.
XfGetHeight = {
position _this select 2
};
//Returns the displayed name of an object.
XfGetDisplayName = {
private ["_obj_name", "_obj_kind", "_cfg"];
_obj_name = _this select 0;_obj_kind = _this select 1;
_cfg = (switch (_obj_kind) do {case 0: {"CfgVehicles"};case 1: {"CfgWeapons"};case 2: {"CfgMagazines"};});
getText(configFile >> _cfg >> _obj_name >> "displayName")
};
//Creates a global marker.
XfCreateMarkerGlobal = {
private ["_m_name","_m_pos","_m_shape","_m_col","_m_size","_m_text","_m_dir","_m_type","_m_brush"];
_m_name = _this select 0;
_m_pos = _this select 1;
_m_shape = _this select 2;
_m_col = _this select 3;
_m_size = _this select 4;
_m_text = (if (count _this > 5) then {_this select 5} else {""});
_m_dir = (if (count _this > 6) then {_this select 6} else {-888888888888});
_m_type = (if (count _this > 7) then {_this select 7} else {""});
_m_brush = (if (count _this > 8) then {_this select 8} else {""});

_marker = createMarker [_m_name, _m_pos];
if (_m_shape != "") then {_marker setMarkerShape _m_shape};
if (_m_col != "") then {_marker setMarkerColor _m_col};
if (count _m_size > 0) then {_marker setMarkerSize _m_size};
if (_m_text != "") then {_marker setMarkerText _m_text};
if (_m_dir != -888888888888) then {_marker setMarkerDir _m_dir};
if (_m_type != "") then {_marker setMarkerType _m_type};
if (_m_brush != "") then {_marker setMarkerBrush _m_brush};
};
//Creates a local marker. Many markers in the artillery system are local only the artillery observer.
XfCreateMarkerLocal = {
private ["_m_name","_m_pos","_m_shape","_m_col","_m_size","_m_text","_m_dir","_m_type","_m_brush"];
_m_name = _this select 0;
_m_pos = _this select 1;
_m_shape = _this select 2;
_m_col = _this select 3;
_m_size = _this select 4;
_m_text = (if (count _this > 5) then {_this select 5} else {""});
_m_dir = (if (count _this > 6) then {_this select 6} else {-888888888888});
_m_type = (if (count _this > 7) then {_this select 7} else {""});
_m_brush = (if (count _this > 8) then {_this select 8} else {""});

_marker = createMarkerLocal [_m_name, _m_pos];
if (_m_shape != "") then {_marker setMarkerShapeLocal _m_shape};
if (_m_col != "") then {_marker setMarkerColorLocal _m_col};
if (count _m_size > 0) then {_marker setMarkerSizeLocal _m_size};
if (_m_text != "") then {_marker setMarkerTextLocal _m_text};
if (_m_dir != -888888888888) then {_marker setMarkerDirLocal _m_dir};
if (_m_type != "") then {_marker setMarkerTypeLocal _m_type};
if (_m_brush != "") then {_marker setMarkerBrushLocal _m_brush};
};

//Find the dialog
Ari_Display = {
private ["_ret"];
_ret = findDisplay 77899;
_ret
};

//New functions
//Normalize. [_normalized, _min,_max], returns normalized version of _normalized between 0 and 1 based on the _min and _max span.
Ari_Normalize = {
private ["_normalized","_min","_max","_failsafe"];
_normalized = _this select 0;
_min = _this select 1;
_max = _this select 2;
_failsafe = if (_min == _max) then {0.0001} else {_min-_max}; //avoids division by zero errors in the event of equal inputs.
_normalized=1-((_normalized-_min)*(1/_failsafe)+1); // gives from 0-1
//	_normalized = 0.0001 max _normalized;
//	_normalized = 0.9999 min _normalized;
_normalized
};

//Special purpose for artillery. For normal even random distribution, set both curvatures to 1.0
//[[_pos], sizex, sizey, angle, distributioncurve (0.5-2 = towards center, towards egde)]
Ari_PointInEllipse = {
private ["_xc","_yc","_a","_b","_angle","_randangle","_newx","_newy","_ret"];
_xc = (_this select 0) select 0;
_yc = (_this select 0) select 1;
_a = (_this select 1) select 0;
_b = (_this select 1) select 1;
_angle = -(_this select 2); //I have no idea why I have to negate this...
_a = random _a;
_b = random _b;
_randangle = (random 360);
_newx = _xc + (_a * cos _randangle * cos _angle ) - ( _b * sin _randangle * sin _angle );
_newy = _yc + (_a * cos _randangle * sin _angle ) + ( _b * sin _randangle * cos _angle );
_ret = [_newx, _newy];
if (true) then {[_ret] call Ari_TestEllipse};
_ret
};

//Just to test the above by creating a shitload of artillery impact positions.
Ari_TestEllipse = {
[format ["marker%1", time], _this select 0, "ICON", "ColorBlack", [0.143,0.143], "", 0, "Select"] call XfCreateMarkerLocal;
};

//Should be able to handle all kinds of objects, but not verified.
Ari_DirPositionToPosition = {
private ["_o1","_o2","_p1","_p2","_deg"];
_o1 = _this select 0;
_o2 = _this select 1;
if (typeName _o1 == "ARRAY") then {
	_p1 = _o1; //is a position array.
} else {
	if (typeName _o1 == "OBJECT") then {
		_p1 = getPos _o1; //is an object
	} else {
		_p1 = getMarkerPos _o1; //only one possibility left
	};
};
if (typeName _o2 == "ARRAY") then {
	_p2 = _o2; //is a position array.
} else {
	if (typeName _o2 == "OBJECT") then {
		_p2 = getPos _o2; //is an object
	}
	else { 
		_p2 = getMarkerPos _o2; //only one possibility left
	};
};
_deg = ((_p2 select 0) - (_p1 select 0)) atan2 ((_p2 select 1) - (_p1 select 1));
if (_deg < 0) then {_deg = _deg + 360};
_deg
};

//Polar rotation. Used on lateral shifts instead of polar addition.
Ari_PolarRotate = {
private ["_coords1", "_coords2", "_dir", "_shift","_newx", "_newy","_angle","_dist"];
_coords1 = _this select 0;
_coords2 = _this select 1;
_shift = _this select 2;
_dir = [_coords1, _coords2] call Ari_DirPositionToPosition;
_dist = _coords1 distance _coords2;
_angle = atan (_shift / _dist);
_dir = _dir + _angle;
_coords2 = [_coords1, _dir, _dist] call Ari_PolarAdd;
_coords2
};

//Polar addition. [_base_coords, _direction, _distance], returns new coordinates.
Ari_PolarAdd = {
private ["_coords", "_dir", "_dist","_newx", "_newy","_diff","_angle"];
_coords = _this select 0;
_dir = _this select 1;
_dist = _this select 2;
_newx = (_coords select 0) + _dist * sin _dir;
_newy = (_coords select 1) + _dist * cos _dir;
_coords = [_newx, _newy];
_coords
};

//Function that converts an nnnnnn grid number into audiable and visible text used in Ari_Speak above.
//ex. _returnarray = ["S","069138"] call _numberToLookup; "S" indicates steel rain voice, instead of "O" for observer.
Ari_NumberToLookup = { //Currently only works for prebuilt arrays of strings
private ["_i","_gridarray","_ret","_string","_who","_retdelay","_delay"];
_ret = [];
_retdelay = 0;
_who = _this select 0;
_gridarray = toArray (_this select 1);
for "_i" from 0 to count _gridarray - 1 do {
	switch (_gridarray select _i) do {
		case 48 : {_string = format ["%1", _who + "02_0"]};
		case 49 : {_string = format ["%1", _who + "02_1"]};
		case 50 : {_string = format ["%1", _who + "02_2"]};
		case 51 : {_string = format ["%1", _who + "02_3"]};
		case 52 : {_string = format ["%1", _who + "02_4"]};
		case 53 : {_string = format ["%1", _who + "02_5"]};
		case 54 : {_string = format ["%1", _who + "02_6"]};
		case 55 : {_string = format ["%1", _who + "02_7"]};
		case 56 : {_string = format ["%1", _who + "02_8"]};
		case 57 : {_string = format ["%1", _who + "02_9"]};
	};
	_ret = _ret + [_string];
};
_ret;
};

//Routine that performs the actual speaking and writing depending on how it's called, like i.e.:
//_speech = ["o02_5","o04_guns"] spawn Ari_Speak; waitUntil {scriptDone _speech};
Ari_Speak = {
private ["_i","_array","_string","_delay","_index","_who","_indexselect"];
_array = _this;
_index = 0;
_string = "";
_delay = 0;
_indexselect = [];
/*
//Probably not a good idea to create this array every time something is said.
for "_i" from 0 to count speechlist - 1 do {
	_indexselect = _indexselect + [(speechlist select _i) select 0];
};
*/
for "_i" from 0 to count _array - 1 do {
	_index = indexselect find (_array select _i);
//		_index = ((speechlist select _i) select 0) find (_array select _i);
	_string = _string + format ["%1", format["%1", (speechlist select _index) select 1]];
	_delay = _delay + ((speechlist select _index) select 2);
	player say ((speechlist select _index) select 0);
};
_who = (if (toArray (_array select 0) select 0 == 111) then {"O: "} else {"S: "});
if (_who == "O: ") then {
	[format ["%1%2",_who, _string]] call Ari_Newline;
	player sideChat format ["%1",_string];
} else {
	[format ["%1%2",_who, _string]] call Ari_Newline;
	[west,"Airbase"] sideChat format ["%1", _string];
};
sleep _delay;
};

//Routine that checks if a high angle trajectory is needed to overcome obstacles enroute to the target.
//If it returns true, high angle will be activated, target zones recalculated with higher dispersion and time of flight.
Ari_HighAngleCheck = {
private ["_posb","_post","_altb","_altt","_b2t","_ret","_i","_steps", "_stepdist", "_stepdir","_pos", "_alt","_posobject","_farside","_height","_hit","_mkrname"];
_ret = false;
_hit = false;
_posb = getPos oAri_Firebase;
_post = getPos oAri_TargetActual;
_altb = getPosASL oAri_Firebase select 2;
_altt = getPosASL oAri_TargetActual select 2;
_curvature = 1.41; //1 is linear, 2 is square root
_pos = [];
_alt = 0;
_b2t = _posb distance _post;
_steps = 1000 min ceil (_b2t/iAri_CollisionAccuracy);
//move out the old markers
if (debug) then {
	for "_i" from 0 to 1000 do {
		_mkrname = format ["colmkr%1", _i];
		_mkrname setMarkerPosLocal [-10000,-10000];
		_mkrname setMarkerSizeLocal [0.3,0.3];
	};
};
_stepdir = [_posb, _post] call Ari_DirPositionToPosition;
_stepdist = _b2t / _steps;
_posobject = "HeliHEmpty" createVehicle [0,0];
for "_i" from 1 to _steps do {
	if (debug) then {
		_mkrname = format ["colmkr%1", _i];
		_mkrname setMarkerPosLocal [-10000,-10000];
		_mrkname setMarkerSizeLocal [0.3,0.3];
	};
	if (_hit) exitWith {};
	_pos = [(_posb select 0) + (_stepdist * _i) * sin _stepdir, (_posb select 1) + (_stepdist * _i) * cos _stepdir];
	if (!surfaceIsWater _pos) then {
		_posobject setPos _pos;
		_alt = getPosASL _posobject select 2;
		_farside = if(_pos distance _posb >= _pos distance _post) then {true} else {false};
//Values tuned to about 2500m maximum height at maximum distance before going into high angle firemode. Extremely simplified.
//For a relatively short distance shot at low angle, highest point is about 200-250 meters. No simulation of charge though.
//			_height = (0.014*_b2t) * ((_pos distance (if(_farside) then {_post} else {_posb}))^1.41) / (_stepdist*1400);
		_height = (0.012*_b2t) * ((_pos distance (if(_farside) then {_post} else {_posb}))^1.41) / (_stepdist*400);
		_height = _height + _altb;
//Whups, forgot to deal with elevation difference. Quicky as follows.
		_height = _height + ((_altt - _altb) * (_i / _steps));
		_height = _height + ((iAri_AirBurst) * (_i / _steps));
		if (_height < _alt && (_i < _steps - 1 && _i > 2)) then {
			_hit = true;
[format ["DEBUG: Hit at ASL %1: %1", format ["%1",_height]]] call Ari_NewLine;
		};
		_ms = [_height, 5, _b2t] call Ari_Normalize;
		_ms = (0.2 + _ms);
		if (!_hit) then {
			if (debug) then {
				_mkrname setMarkerPosLocal _pos;
				_mkrname setMarkerTextLocal format ["%1", _height];
				_mkrname setMarkerSizeLocal [0.3, 0.3];
			};
		} else {
			if (debug) then {
				_mkrname setMarkerPosLocal _pos;
				_mkrname setMarkerTextLocal format ["%1", _height];
				_mkrname setMarkerSizeLocal [1.2, 1.2];
			};
		};
	};
};
deleteVehicle _posobject;
//Force high angle for copperhead and airburst modes	
if ((iAri_Munition == 5) || (iAri_Munition == 9)) then { //Copperhead or Copperhead+Illum
	_hit = true;
};
if ((iAri_Munition != 4) && (iAri_Airburst > 0)) then { //Airburst height in non illum missions
	_hit = true;
};
_ret = _hit;
_ret
};

//Routine that updates the marker sizes which are used for dispersion calculations.
//Will rerun itself if a change in high angle mode is detected.
Ari_UpdateTargetAreaPos = {
private ["_actualpos", "_difference", "_sizex", "_sizey","_normalizeddist","_dispersion","_bAri_HighAngleOld","_normalizedtimeofflight","_timeofflight"];
"mAri_TargetAreaExpected" setMarkerPosLocal getMarkerPos "mAri_TargetExpected";
_difference = [(aAri_ObserverActual select 0) - (getMarkerPos "mAri_Observer" select 0), (aAri_ObserverActual select 1) - (getMarkerPos "mAri_Observer" select 1)];
_actualpos = [(getMarkerPos "mAri_TargetExpected" select 0) - (_difference select 0),  (getMarkerPos "mAri_TargetExpected" select 1) - (_difference select 1)];
"mAri_TargetAreaActual" setMarkerPosLocal _actualpos;
_normalizeddist = [getMarkerPos "mAri_FirebaseLocation" distance getMarkerPos "mAri_TargetAreaActual",iAri_RangeNear,iAri_RangeFar] call Ari_Normalize;
_normalizedtimeofflight = _normalizeddist;
_timeofflight = (1 - _normalizedtimeofflight) * iAri_TimeOfFlightNear + (_normalizedtimeofflight * iAri_TimeOfFlightFar);
iAri_TimeOfFlight = if(!bAri_HighAngle) then {_timeofflight} else {_timeofflight*iAri_HighAngleMultiplier};
oAri_TargetActual setPos getMarkerPos "mAri_TargetAreaActual";
if (iAri_Munition != 4) then {
	"mAri_TargetAreaExpected" setMarkerDirLocal (["mAri_FirebaseLocation","mAri_TargetExpected"] call Ari_DirPositionToPosition);
	"mAri_TargetAreaActual" setMarkerDirLocal ([getMarkerPos "mAri_FirebaseLocation", _actualpos] call Ari_DirPositionToPosition);
	_dispersion = (1 - _normalizeddist) * iAri_MinDispersion + (_normalizeddist * iAri_MaxDispersion);
	_sizey = _dispersion;
	_sizey = if(!bAri_HighAngle) then {_sizey} else {_sizey*iAri_HighAngleMultiplier};
	_factor = _sizey;
	_sizex = iAri_DispersionSqueeze*_sizey;
	_sizey = _sizey + _factor*(iAri_Dispersion^2.5);
	_sizex = _sizex + (2*_factor*iAri_Dispersion);
	_sizey = _sizex max _sizey;
	_sizey = _sizey;
	if (iAri_Munition == 5 || iAri_Munition == 9) then {
		_sizex = (1-overcast)*iAri_FootprintCopperhead;
		_sizey = (1-overcast)*iAri_FootprintCopperhead;
	};
} else {
	switch (iAri_IllumMode) do {
		case 0 : { //just to avoid error messages when a illum mode haven't been selected.
			_sizex = 0.1;
			_sizey = 0.1;
		};
		case 1 : {
			_sizex = 50;
			_sizey = 50;
		};
		case 2 : {
			_sizex = 50;
			_sizey = 100 + 500 * iAri_IllumShape;
		};
		case 3 : {
			_sizex = 100 + 500 * iAri_IllumShape;
			_sizey = 50;
		};
		case 4 : {
			_sizex = 200 + 400 * ((1-cos(3*iAri_IllumShape*180))/2);
			_sizey = 200 + 400 * ((1-cos(iAri_IllumShape*180))/2);
		};
	};
	"mAri_TargetAreaActual" setMarkerDirLocal ([getMarkerPos "mAri_Observer", getMarkerPos "mAri_TargetAreaActual"] call Ari_DirPositionToPosition);
	"mAri_TargetAreaExpected" setMarkerDirLocal ([getMarkerPos "mAri_Observer", getMarkerPos "mAri_TargetAreaExpected"] call Ari_DirPositionToPosition);
};
"mAri_TargetAreaExpected" setMarkerSizeLocal [_sizex,_sizey];
"mAri_TargetAreaActual" setMarkerSizeLocal [_sizex,_sizey];
//simplified endcheck for debugging purposes
if (getPos oAri_TargetActual select 0 > -9000 && getPos oAri_Observer select 0 > -9000) then {
	aAri_FinalTargetArea = [getMarkerPos "mAri_TargetAreaActual", markerDir "mAri_TargetAreaActual", markerSize "mAri_TargetAreaActual"];
// run again if bAri_HighAngle was changed.
	_bAri_HighAngleOld = bAri_HighAngle;
	bAri_HighAngle = [] call Ari_HighAngleCheck;
	if ((_bAri_HighAngleOld && !bAri_HighAngle) || (!_bAri_HighAngleOld && bAri_HighAngle)) then {
		[] call Ari_UpdateTargetAreaPos;
	};
};
[] call Ari_Monitor;
};

//Artillery actions
Ari_Button_Designate_Positions = {
//	This one is activated using spawn since regular call can't sleep.
private ["_updatewhat","_control","_ari_display","_old_pos"];
_updatewhat = _this select 0;
switch (_updatewhat) do {
	case 1: {
		_old_pos = getPos oAri_Observer select 0;
		onMapSingleClick "oAri_Observer setPos [_pos select 0, _pos select 1, 0]";
		waitUntil {_old_pos != getPos oAri_Observer select 0 || !alive player};
		"mAri_Observer" setMarkerPos getPos oAri_Observer;
		aAri_ObserverActual = getPos player;
		"mAri_RangeObserver" setMarkerPos getPos oAri_Observer;
		[] call Ari_UpdateTargetAreaPos;
		sleep 0.123;
		if(getMarkerPos "mAri_Observer" select 0 > -9000) then {[] call Ari_Display displayCtrl 110301 ctrlSetTextColor [__GREEN]};
	};
	case 2: {
		_old_pos = getPos oAri_TargetExpected select 0;
		onMapSingleClick "oAri_TargetExpected setPos [_pos select 0, _pos select 1, 0]";
		waitUntil {_old_pos != getPos oAri_TargetExpected select 0 || !alive player};
		"mAri_TargetExpected" setMarkerPos getPos oAri_TargetExpected;
		[format [""]] call Ari_NewLine;
		[] call Ari_UpdateTargetAreaPos;
		sleep 0.123;
		if(getMarkerPos "mAri_Target" select 0 > -9000) then {[] call Ari_Display displayCtrl 110302 ctrlSetTextColor [__GREEN]};
	};
};
onMapSingleClick ""; //Just making sure
sleep 0.123;
};

Ari_Check_Ranges_Action = {
if (!bAri_ShowRanges) then {
	bAri_ShowRanges = true;
	[] call Ari_Display displayCtrl 110202 ctrlSetTextColor [__GREEN];
	"mAri_RangeObserver" setMarkerSizeLocal [iAri_RangeObserver,iAri_RangeObserver];
	"mAri_RangeNear" setMarkerSizeLocal [iAri_RangeNear,iAri_RangeNear];
	if (iAri_Munition == 5) then {
		"mAri_RangeFar" setMarkerSizeLocal [iAri_RangeFarCopperhead,iAri_RangeFarCopperhead];
		"mAri_RangeNear" setMarkerSizeLocal [iAri_RangeNearCopperhead,iAri_RangeNearCopperhead];
	} else {
		"mAri_RangeFar" setMarkerSizeLocal [iAri_RangeFar,iAri_RangeFar];
		"mAri_RangeNear" setMarkerSizeLocal [iAri_RangeNear,iAri_RangeNear];
	};
} else {
	bAri_ShowRanges = false;
	[] call Ari_Display displayCtrl 110202 ctrlSetTextColor [__RED];
	"mAri_RangeNear" setMarkerSizeLocal [0,0];
	"mAri_RangeFar" setMarkerSizeLocal [0,0];
	"mAri_RangeObserver" setMarkerSizeLocal [0,0];
};
};

Ari_Check_Nightfilter_Action = {
if (!bAri_NightFilter) then {
	bAri_NightFilter = true;
	[] call Ari_Display displayCtrl 110201 ctrlSetTextColor [__GREEN];
	'mAri_NightFilter1' setMarkerSize [15000,15000];
	'mAri_NightFilter2' setMarkerSize [15000,15000];
} else {
	bAri_NightFilter = false;
	[] call Ari_Display displayCtrl 110201 ctrlSetTextColor [__RED];
	'mAri_NightFilter1' setMarkerSize [0,0];
	'mAri_NightFilter2' setMarkerSize [0,0];
};
};

Ari_Slider_AdjustHeightAction = {
private ["_height"];
_height = (_this select 0)/10;
//M513, M514: 20m
//M732: 7m
// ? : 2m
//HC Smoke and APICM to use different slider eventually for airburst if those VT fuses are not used for those munitions!!!
//Impact
//	if (iAri_Munition == 1 || iAri_Munition == 6) then {
	if (_height > 0 && _height < 0.25) then {iAri_Airburst = 0} else {
		if (_height >= 0.25 && _height < 0.5) then {iAri_Airburst = 2} else {
			if (_height >= 0.5 && _height < 0.75) then {iAri_Airburst = 7} else {
				if (_height >= 0.75 && _height <= 1) then {iAri_Airburst = 20};
			};
		};
	};
//	} else {
//Doesn't work to well, since data isn't updated automatically.
//		if (iAri_Munition == 2 || iAri_Munition == 3 || iAri_Munition == 7 || iAri_Munition == 8) then {
//			iAri_AirBurst = 20 + round(_height * 80);
//		};
//	};
[] call Ari_Display displayCtrl 110405 ctrlSetText format ["Airburst height: %1m",iAri_Airburst];
[] call Ari_UpdateTargetAreaPos;
[] call Ari_HighAngleCheck;
};

Ari_Slider_AdjustDispersionAction = {
private ["_dispersion"];
_dispersion = _this select 0;
_show = round (20 * _dispersion);
[] call Ari_Display displayCtrl 110406 ctrlSetText format ["Adjust dispersion: %1",_show];
iAri_Dispersion = 0.77*((_dispersion/10)^1.5);
[] call Ari_UpdateTargetAreaPos;
[] call Ari_HighAngleCheck;
};

//iAri_Dispersion = 0.77*(([0-10]/10)^1.5);

//value = round (20 * [0-10])


Ari_Slider_AdjustAltitudeAction = {
private ["_altitude"];
_altitude = _this select 0;
iAri_IllumAltitude = _altitude;
_altitude = 350 + round (40 * _altitude);
[] call Ari_Display displayCtrl 110409 ctrlSetText format ["Illum altitude: %1m",_altitude];
iAri_Airburst = round (_altitude);
[] call Ari_UpdateTargetAreaPos;
[] call Ari_HighAngleCheck;
};

Ari_Slider_AdjustShapeAction = {
private ["_shape"];
_shape = (_this select 0)/10;
iAri_IllumShape = _shape;
[] call Ari_UpdateTargetAreaPos;
[] call Ari_HighAngleCheck;
};

Ari_UpdateComboSelectors = {
//Nothing yet
};

//Update the command interface
Ari_NewLine = {
private ["_newmsg","_str","_debug","_array"];
_newmsg = _this select 0;
_debug = false;
_array = toArray _newmsg;
if (count _array > 5) then {//D                         E                          B                          U                          G :)
	if ((_array select 0) == 68 && (_array select 1) == 69 && (_array select 2) == 66 && (_array select 3) == 85 && (_array select 4) == 71) then {
		_debug = true;
	};
};
_array = nil;
if (_debug) then {
	if (debug) then {
		sAri_l9 = sAri_l8;
		sAri_l8 = sAri_l7;
		sAri_l7 = sAri_l6;
		sAri_l6 = sAri_l5;
		sAri_l5 = sAri_l4;
		sAri_l4 = sAri_l3;
		sAri_l3 = sAri_l2;
		sAri_l2 = sAri_l1;
		sAri_l1 = sAri_l0;
		sAri_l0 = format ["C:\FX>%1", _newmsg];
		_str = composeText [
			parseText (sAri_l9), linebreak,
			parseText (sAri_l8), linebreak,
			parseText (sAri_l7), linebreak,
			parseText (sAri_l6), linebreak,
			parseText (sAri_l5), linebreak,
			parseText (sAri_l4), linebreak,
			parseText (sAri_l3), linebreak,
			parseText (sAri_l2), linebreak,
			parseText (sAri_l1), linebreak,
			parseText (sAri_l0), linebreak
		];
		[] call Ari_Display displayCtrl 110702 ctrlSetStructuredText _str;
	};
} else {
//		if (sAri_l0 == "C:\FO>") then {
//			sAri_l0 = format ["C:\FO>%1", _newmsg];
//		} else {
		sAri_l9 = sAri_l8;
		sAri_l8 = sAri_l7;
		sAri_l7 = sAri_l6;
		sAri_l6 = sAri_l5;
		sAri_l5 = sAri_l4;
		sAri_l4 = sAri_l3;
		sAri_l3 = sAri_l2;
		sAri_l2 = sAri_l1;
		sAri_l1 = sAri_l0;
		sAri_l0 = format ["%1", _newmsg];
		_str = composeText [
			parseText (sAri_l9), linebreak,
			parseText (sAri_l8), linebreak,
			parseText (sAri_l7), linebreak,
			parseText (sAri_l6), linebreak,
			parseText (sAri_l5), linebreak,
			parseText (sAri_l4), linebreak,
			parseText (sAri_l3), linebreak,
			parseText (sAri_l2), linebreak,
			parseText (sAri_l1), linebreak,
			parseText (sAri_l0), linebreak
		];
//		};
	[] call Ari_Display displayCtrl 110702 ctrlSetStructuredText _str;
};
};

//Update the monitor console. Updates once every second. Debug tool only to monitor FDCs current settings and actions.
Ari_Monitor = {
private ["_tmp","_str","_m9l","_m9c","_m9r","_m8l","_m8c","_m8r","_m7l","_m7c","_m7r","_m6l","_m6c","_m6r","_m5l","_m5c","_m5r","_m4l","_m4c","_m4r","_m3l","_m3c","_m3r","_m2l","_m2c","_m2r","_m1l","_m1c","_m1r","_m0l","_m0c","_m0r"];
_m9l = format ["Dispersion:"];
_m9c = "";
_m9r = format ["%1",  round (iAri_Dispersion *100 ) / 100];
_m8l = format ["Hight Angle:"];
_m8c = "";
_m8r = format ["%1", bAri_HighAngle];
_m7l = format ["B:%1", round (getPosASL oAri_Firebase select 2)];
_m7c = format ["O:%1", round (getPosASL oAri_Observer select 2)];
_m7r = format ["T:%1", round (getPosASL oAri_TargetActual select 2)];
_m6l = format ["Mun:%1", iAri_Munition];
_m6c = "";
_m6r = format ["Guns:%1", iAri_NoGuns];
_m5l = format ["Ill:%1", iAri_IllumMode];
_m5c = "";
_m5r = format ["Rnds:%1", iAri_NoRounds];
_m4l = format ["TOF: %1s", round iAri_TimeOfFlight];
_m4c = "";
_m4r = "";
_m3l = "";
_m3c = "";
_m3r = "";
_m2l = "";
_m2c = "";
_m2r = "";
_m1l = "";
_m1c = "";
_m1r = "";
_m0l = "";
_m0c = "";
_m0r = "";
_str = composeText [
	parseText ("<t align='left'>" + format ["%1",_m9l] + "</t>"), 
	parseText ("<t align='center'>" + format ["%1",_m9c] + "</t>"),
	parseText ("<t align='right'>" + format ["%1",_m9r] + "</t>"), linebreak,
	parseText ("<t align='left'>" + format ["%1",_m8l] + "</t>"), 
	parseText ("<t align='center'>" + format ["%1",_m8c] + "</t>"),
	parseText ("<t align='right'>" + format ["%1",_m8r] + "</t>"), linebreak,
	parseText ("<t align='left'>" + format ["%1",_m7l] + "</t>"), 
	parseText ("<t align='center'>" + format ["%1",_m7c] + "</t>"),
	parseText ("<t align='right'>" + format ["%1",_m7r] + "</t>"), linebreak,
	parseText ("<t align='left'>" + format ["%1",_m6l] + "</t>"), 
	parseText ("<t align='center'>" + format ["%1",_m6c] + "</t>"),
	parseText ("<t align='right'>" + format ["%1",_m6r] + "</t>"), linebreak,
	parseText ("<t align='left'>" + format ["%1",_m5l] + "</t>"), 
	parseText ("<t align='center'>" + format ["%1",_m5c] + "</t>"),
	parseText ("<t align='right'>" + format ["%1",_m5r] + "</t>"), linebreak,
	parseText ("<t align='left'>" + format ["%1",_m4l] + "</t>"), 
	parseText ("<t align='center'>" + format ["%1",_m4c] + "</t>"),
	parseText ("<t align='right'>" + format ["%1",_m4r] + "</t>"), linebreak,
	linebreak
];
[] call Ari_Display displayCtrl 110701 ctrlSetStructuredText _str;
};

Anyway, just posting this so that I'm not considered a "knowitall" who haven't even tried :D Btw, wrongly I mix distribution with dispersion. Also note that the functions shown only deals with precalculations, actual firing/delivery and dialog control is done in other scripts not needed here. The "computer display" I used have nothing in common whatsoever with the real device, was more a debug monitor than anything else.

@blakeace:

I'm not a big fan of the builtin artillery, due to problems with multiplayer compatibility. One of the reasons I gave up on my project was that I realized that you cannot simulate proper airbursts without creating new shell classes for each of the VT fuzes. And my idea was based on scripts and dialogs alone, to make it addon free.

I'm just feeding this to provide ideas to someone with more time on their hand :)

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites

Carl, you wouldn't have to add a new shell class to do VT fuses. I simulated them totally in script.

Just add an event handler to the gun and catch the shell as it comes out and watch its altitude or whatever to determine when to make it airburst.

To make them airburst with the actual shell (for myself this is a big deal because it still retains ownership of the shell can counts kills for the player) you have to make it impact another object. I used the Bomb object, its generic and it doesn't add in any of its own damage, though it does add in shrapnel gib models.

That can all be via script. You just need to tell the script when to turn on (VT) and when to not turn on (Quick fuse).

Also, on then note of Copperhead seeker patterns. I was thinking about modelling the actual pattern, which is more of a tear drop shape, extending from a certain altitude out and down depending on then angle of the attack............. Then again thats bat-shiz crazy and maybe I should hold off and make that in a VBS module not an ArmA2 module... :P

Edited by NouberNou

Share this post


Link to post
Share on other sites
I'm not a big fan of the builtin artillery, due to problems with multiplayer compatibility

In which parts, as far as I know we have yet to have a problem with the BIS arty module? Except remembering to add a HE mag for the MLRS for some reason which the other arty pieces don't require?

I would like the ai to move after a HE barrage though, rather than keep standing there. I might have to look at creating a trigger after a barrage with a random move for all units inside. Though that pos will stuff any existing waypoints up? Will have to investigate.

Its fine, its in the inner loop where the slow down occurs, where it increments I think the deltat? Can not remember off the top of my head, but for every step in elevation it was doing close to 3000 iterations on that.

Yep that is the real hog there, would be much faster using a system of halves(can't think of the real name atm). Where you select half way and see which half is correct then half that etc until it is refined down to the right value. May look at it over summer. That would reduce the amount of calculations massively.

Share this post


Link to post
Share on other sites
Anyways I am integrating all of this into a somewhat real/somewhat fantasy version of the US AFATDS. I have a version of the M119 that works much like Jones M252, and I am working on getting them to have a better way of aiming, using granular animations to adjust azimuth and elevations.
Carl, you wouldn't have to add a new shell class to do VT fuses. I simulated them totally in script.

Your map tools rather got my attention and I recalled that you were working on this. Can I ask, is this project script-based (as Jones' initial release was) rather than add-on based? The former offers big advantages to those of us running public servers as it can be included in the mission and used by anyone who joins without mods.

Share this post


Link to post
Share on other sites

@NouberNou: You can blow off a bomb at any altitude you want, but in order to get reasonable effects, I found no other way than have several classes of HE for the various fuses. I.e. if a bomb was found suitable for M513/M514, it wouldn't work for M732. I made the shell for M513/M514 fuse (20m airburst) very potent against infantry in the open, but vehicles was hardly affected at all. Similarly, the 7m and 2m airburst had much higher damage but also much higher damage falloff radius. Also, using addon I made sounds that provided a much brighter snap on shells going off higher (no obstructions).

Kill count is not important to me. Problems with multiplayer is that scripts uses effects that then will only be local to the server or player controlling it. Particle effects, say sounds etc. I quickly gave up proper footprint :) A footprint size based on cloud cover (cloud altitude) was good enough for me to have some variation factor. Never bothered with PRF either.

Edit: MLRS and GRAD are for me overkill in any scenario. I use them only for targets. They might fire as to give away their position to the players and make a good show etc, but I would never use them as real artillery pieces that we are supposed to use. For firing and damage effects, I'd rather have 40-60mm mortars over rockets.

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites
Your map tools rather got my attention and I recalled that you were working on this. Can I ask, is this project script-based (as Jones' initial release was) rather than add-on based? The former offers big advantages to those of us running public servers as it can be included in the mission and used by anyone who joins without mods.

Sadly a majority of it is addon based. Putting something in like AFATDS though could theoretically be done in script though. Dialogs do not need addons to have them work.

The artillery units doing low angle fire and having the different adjustment methods need to be addons though. You do not aim using the artillery map, you receive azimuth and elevation from the BCS, and you have to choose the correct shell charge number for the range. The initial velocity of the M119 is almost double what it is in real life for the highest charge which is rarely fired. Actual max muzzle velocity is 633m/s for the HE cartridge.

Share this post


Link to post
Share on other sites

@NouberNou

Its fine, its in the inner loop where the slow down occurs, where it increments I think the deltat? Can not remember off the top of my head, but for every step in elevation it was doing close to 3000 iterations on that.

My first response

Yep that is the real hog there, would be much faster using a system of halves(can't think of the real name atm). Where you select half way and see which half is correct then half that etc until it is refined down to the right value. May look at it over summer. That would reduce the amount of calculations massively.

One reason why you shouldn't post stuff when really tired! The inner loop is actually emulating the projectiles path. deltat actually specifies the change in time between reading positions of the flight. The smaller value you have in deltat will generally give more accurate results. One thing you could try is to make the value of deltat larger until the accuracy drops off too much. Larger values mean the emulation process takes less time. Eg double the time jump, halve the number of calculations.

Share this post


Link to post
Share on other sites
@NouberNou

My first response

One reason why you shouldn't post stuff when really tired! The inner loop is actually emulating the projectiles path. deltat actually specifies the change in time between reading positions of the flight. The smaller value you have in deltat will generally give more accurate results. One thing you could try is to make the value of deltat larger until the accuracy drops off too much. Larger values mean the emulation process takes less time. Eg double the time jump, halve the number of calculations.

Yea I tried that, but again its too slow. I think the scripting engine in ArmA2 is not geared to do those types of operations nearly as fast as something like Excel is. My solution as it stands now is pretty ok, with the look up tables and then the calculation run on a very tiny elevation range. I might add in a manual input mode on the calculator though where it actually computes the whole solution... just with lots of warning text!

Share this post


Link to post
Share on other sites

Ok lads, I hate to break away from the (fascinating) math portion of this thread :) but I've kinda constructed a poor-man's AI artillery thingy.

It works with the virtual artillery piece module. As part of the init, I launch an sqf that monitors the location of a USMC FR team. If it is alive, and within ~600m of the target town (I played the mission as blufor, and this represents the maximum distance at which I could really act as FO for blue arty), the script picks a position within 400m of the center of the town. The mission has a mix of tracked/wheeled vehicles in/around a town, as well as infantry units.

If the spot is on water, it doesn't do anything. If the spot is within 100m of a HOUSE type building, it launches a SADARM. If there isn't a HOUSE within 100m, then it does a HE barrage. All of this is also regulated with a timer that has it fire every few minutes, as long as all the conditions are met (FR presence, etc.)

The SOM virtual arty does a good of landing the shells in a random way, but there are usually units nearby so it looks believable. As player, it hasn't killed me (yet), but I did get my bell rung good by it and several units in my squad were killed.

Not saying this would be appropriate for every application, but with some tweaking, the methodology could be made to "target" enemy concentrations.

Thanks for the great thread! Very informative.

Share this post


Link to post
Share on other sites
Ok lads, I hate to break away from the (fascinating) math portion of this thread :) but I've kinda constructed a poor-man's AI artillery thingy.

It works with the virtual artillery piece module. As part of the init, I launch an sqf that monitors the location of a USMC FR team. If it is alive, and within ~600m of the target town (I played the mission as blufor, and this represents the maximum distance at which I could really act as FO for blue arty), the script picks a position within 400m of the center of the town. The mission has a mix of tracked/wheeled vehicles in/around a town, as well as infantry units.

If the spot is on water, it doesn't do anything. If the spot is within 100m of a HOUSE type building, it launches a SADARM. If there isn't a HOUSE within 100m, then it does a HE barrage. All of this is also regulated with a timer that has it fire every few minutes, as long as all the conditions are met (FR presence, etc.)

The SOM virtual arty does a good of landing the shells in a random way, but there are usually units nearby so it looks believable. As player, it hasn't killed me (yet), but I did get my bell rung good by it and several units in my squad were killed.

Not saying this would be appropriate for every application, but with some tweaking, the methodology could be made to "target" enemy concentrations.

Thanks for the great thread! Very informative.

Trexian,

Could you please post this as an example mission? I'm struggling to get the stuff in this thread working.

And captainbravo,

Do you still have the example mission that was posted early? Could you re-post it please? All the links that are in this thread are down.

Share this post


Link to post
Share on other sites

Sure thing, 'zilla. It is that RiverAndRock mission at OFPEC, but a Red version. As I recall, I had a version working rather well, so I'll try to get back to that this weekend and post it.

Share this post


Link to post
Share on other sites

Hey Manzilla,

I will post example mission when back at comp at home along with new enemy artillery version I am using which has some newer features (cannot remember by who at the moment)

---------- Post added at 05:46 PM ---------- Previous post was at 05:21 PM ----------

OK Manzilla you are in luck. I have found both enemy artillery examples on an old USB.

http://www.filefront.com/15938367/AI_Art.rar

Share this post


Link to post
Share on other sites

sorry for broken links folks

"Mission Control thinks it is impossible for such a thing to happen, but it has.

We are skeptical ourselves and we are running cross-checking routines"

Share this post


Link to post
Share on other sites

i have a strange problem im setting up the arty and units just like ashram1-1 tells in his post. it works the first time i try it every time i set it up have done it alot of times now. The problem happens every time i try and preview the mission for the second time. then i just get the message the mortar are out of range. so i have setup the mission 6 times now from scratch the first time i preview it works, but on the second preview it dont. this happend every time i make the mission.

Share this post


Link to post
Share on other sites

You might want to check out your "ArmA 2\AddOns\missions\Scenarios\SP_Counterattack.Chernarus\grpCdfMortar.fsm".

Share this post


Link to post
Share on other sites

Ashram, Great Script!!!

Nouber Nou, The FO script compliments this script wonderfully! Great job to you as well...

My hat goes off to ya both. I am new to editing and mission making and your simple way of showing things along with providing examples was very clear for me to understand. and believe me, I have a hard time understanding most of the scripting. Although I am learning fast with the help of folks like you two.

I now have a very nice arty option for missions if I need it. Keep up the good work.

Hey CaptainBravo! They do work together! :yay:

both are great scripts nd work great! I wish we could combine both :D

---------- Post added at 12:40 AM ---------- Previous post was Yesterday at 11:49 PM ----------

you might also want to give the mortars extra ammo with

this addmagazine "2b14_82mm";

multiple times in their init boxes

death from above!

Ashram, I am getting the following error when I try to add ammo..

No entry 'bil\config.bin/CfgMagazines.2b14_82mm'.

Any suggestion?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×