Jump to content
Sign in to follow this  
Doolittle

True artillery

Recommended Posts

tounge.gif

Thanks Grizzly.  This whole project has been quite fun!  I didn't know/get any of this stuff as of two days ago.  It was a great way to learn.  Wanna know the funny thing??  I took a Physics course over the summer a long while back & in it they wanted me to fire a catapult thing & hit a mark on the floor for lab (we had to calculate where it would hit).  If we fired & missed then our grade went down one letter & we could try again (A to B, B to C, etc.).  Well a whole mess of people were firing it when the teacher wasn't looking and then just marked that spot on the floor (cheated).  I refused to do this.  Oh and by the way I couldn't do it, I mean I couldn't do the lab.  I worked for hours with a partner & then we called the teacher over, fired the metal ball and kerplunk! missed the stupid mark.  So we tried again and missed again!  Well, I ended up dropping the class & I never did take a physics class (I took chemistry instead  wink.gif ).  I graduated last summer (BS in Comp Sci).

Hey!  So now I know the stupid cannon principles & I learned it in a much funner way!!  They need OFP in the classrooms!

Doolittle

Share this post


Link to post
Share on other sites

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (Doolittle @ Oct. 22 2002,17:31)</td></tr><tr><td id="QUOTE">Hey!  So now I know the stupid cannon principles & I learned it in a much funner way!!  They need OFP in the classrooms!<span id='postcolor'>

You're absolutely right, Doolittle. I couldn't care less about Euler's theorems in maths, but once I learned you can actually rotate 3d-velocity vectors in OFP with those I decided to give it a second chance, dig out my book and study it once again smile.gif

Share this post


Link to post
Share on other sites

angle = 1/2 * arcsine ((9.8 * distance) / V^2)

Are you sure?

Now assume a shell that travels 1 meter with the MV of 2 m/s. A quick thought experiment shows that this is in the realm of possibility.

Throw that into your calculation and you get:

angle = 1/2 * arcsine ((9.8 * 1)/2^2)

angle = 1/2 * arcsine (9.8/4)

your calculation must deliver an arcsine below 1 for it to work.

The calculation you want is:

angle = arctangent ((distance*4.9)/V^2)

Share this post


Link to post
Share on other sites

I don't understand how you derived this arctangent formula?  I tried it and it gave the same results for some of the tests, which amazed me.

Here:

102220027203415.jpg

Don't laugh!

I'm trying to make it so that the MUZZLE (or V) vector doesn't change length (er, magnitude?).

Doolittle

Share this post


Link to post
Share on other sites

and yes, there is some sort of drag modelled. Check this out:

_shell = _this select 0

_origin = _this select 1

_target = _this select 2

_MV = _this select 3

_originpos = getpos _origin

_targetpos = getpos _target

_direction = ((_targetpos select 0) - (_originpos select 0)) atan2 ((_targetpos select 1) - (_originpos select 1))

_range = sqrt ((((_originpos select 0) - (_targetpos select 0))^2)+(((_originpos select 1) - (_targetpos select 1))^2))

_elevationangle = atan ((_range * 5)/(_Mv^2))

_zvector = _MV * (sin _Elevationangle)

_latvector = _mv * (cos _elevationangle)

_xvector = _latvector * (sin _direction)

_yvector = _latvector * (cos _direction)

_bang = _shell camcreate [_originpos select 0, _originpos select 1, (_originpos select 2) + 1]

_bang setvelocity [_xvector, _yvector, _zvector]

#vectorloop

@(_xvector != (velocity _bang select 0))

hint format ["%1", velocity _bang select 0]

?getpos _bang select 0 > 0:goto "vectorloop"

exit

give it a gamelogic called "origin", and put in a trigger:

["Heat120", origin, player, 100] exec "nameofscript.sqs"

the hint thing will scream at you as the xvector drops off, and the shell will land a little short -- the shortness increases as you move further away.

the drag looks to be about .05% of overall velocity per second.

How I derived the arctan formula?

Uh I forget.

Share this post


Link to post
Share on other sites

it's a good script but inaccuracy grown with medium or long distance, finally range is limited sad.gif

You should consider Z coords between origin and impact spot, it's ok on Desert Island but for the other islands results are false

Share this post


Link to post
Share on other sites

Yeah, that's the point of the script Aeon, to show that with Z coords approximately the same, there is some inaccuracy.

It's _not_ a working script.

Although this is reinventing the wheel since the "Direct Fire Artillery" people noted this phenomenon last year.

I think I've got a solution though.

Share this post


Link to post
Share on other sites

Okay while you guys figure that out I'm going to release what I have and say "first"!!! tounge.gif

Map With True Working Artillery

Here's the readme.txt:

True Artillery

Vehicle Respawn

Vehicle Abandoned Respawn

by Doolittle

dbircsak@earthlink.net

for Operation Flashpoint 1.85

If you use any of these scripts, give me credit!  They are copyright 2002 Darrell "Doolittle" Bircsak.  None of this code may be used in any product that is sold for money (or bartered) without the author's permission.  Long live Flashpoint!

For the artillery to work, we will use onMapSingleClick to see where the user wants the shell fired.  The "howitzer.sqs" script will then be called on a map click.  On the example map I have placed howitzerW_1, howitzerW_2, howitzerW_3, howitzerE_1, howitzerE_2, and howitzerE_3.  They are objects, I am using an M60 and T80 respectively.  They could very well just be H (Hidden).  The point is we need a reference point for our gun location.  Hopefully you will see how I linked together several guns in "howitzer.sqs".  Note I am also doing some new 1.85 stuff with preprocessFile where basically I am saving a function to memory (CannonFunction).  I did this so that I could get return values from the guns since I wanted to use more than one.  I didn't want to get back three messages that something was out of range.

An artillery barrage can be fired from each side every 15 seconds (_cannontime).

*** *** *** init.sqs *** *** ***

onMapSingleClick "[player, _pos, _units, _shift, _alt] exec ""howitzer.sqs"""

CannonFunction = preprocessFile "cannon.sqf"

howitzerWtime = 0

howitzerEtime = 0

*** *** *** howitzer.sqs *** *** ***

_cannontime = 15

_side = side (_this select 0)

_pos = _this select 1

_units = _this select 2

_shift = _this select 3

_alt = _this select 4

? _side == east : goto "cannonE"

goto "cannonW"

#busy

[_side, "hq"] sidechat "BUSY WITH OTHER MISSION."

exit

#range

[_side, "hq"] sidechat "EXCESSIVE RANGE TO TARGET."

exit

#complete

[_side, "hq"] sidechat "FIRE REQUEST COMPLETE."

exit

#cannonW

? howitzerWtime > time : goto "busy"

_return = [howitzerW_1, _pos, _units, _shift, _alt] call CannonFunction

;If one is out of range, they probably all are

? _return == "RANGE" : goto "range"

_return = [howitzerW_2, _pos, _units, _shift, _alt] call CannonFunction

_return = [howitzerW_3, _pos, _units, _shift, _alt] call CannonFunction

howitzerWtime = time + _cannontime

publicVariable "howitzerWtime"

goto "complete"

#cannonE

? howitzerEtime > time : goto "busy"

_return = [howitzerE_1, _pos, _units, _shift, _alt] call CannonFunction

;If one is out of range, they probably all are

? _return == "RANGE" : goto "range"

_return = [howitzerE_2, _pos, _units, _shift, _alt] call CannonFunction

_return = [howitzerE_3, _pos, _units, _shift, _alt] call CannonFunction

howitzerEtime = time + _cannontime

publicVariable "howitzerEtime"

goto "complete"

*** *** *** cannon.sqf *** *** ***

private ["_muzzle", "_src", "_tgt", "_units", "_shift", "_alt", "_return"];

private ["_x", "_y", "_dist", "_dir", "_tmp", "_angle", "_hyp", "_vx", "_vz", "_vy", "_type", "_obj"];

_muzzle = 180;

_src = getPos (_this select 0);

_tgt = _this select 1;

_units = _this select 2;

_shift = _this select 3;

_alt = _this select 4;

_x = ((_tgt select 0) - (_src select 0));

_z = ((_tgt select 1) - (_src select 1));

_dist = sqrt ((_x * _x) + (_z * _z));

_dir = _z atan2 _x;

_tmp = ((9.8 * _dist) / (_muzzle * _muzzle));

if (_tmp > -1 && _tmp < 1) then {

_angle = (asin _tmp) / 2;

_dir = _dir - 1 + random 2;

_angle = _angle - 1 + random 2;

_vy = _muzzle * sin _angle;

_hyp = _muzzle * cos _angle;

_vx = _hyp * cos _dir;

_vz = _hyp * sin _dir;

_type = "Shell105";

if (_shift) then {_type = "Heat105"};

if (_alt) then {_type = "SmokeShell"};

_obj = _type camCreate [_src select 0, _src select 1, 3];

_obj setVelocity [_vx, _vz, _vy];

_obj setDir -(_dir - 90);

"Cannon30HE" camCreate [_src select 0, _src select 1, 0];

_return = "COMPLETE";

} else {

_return = "RANGE";

};

_return

Mission makers need only include the top lines from init.sqs, all of vehicle.sqs, killed.sqs, and getout.sqs.  All vehicles that you want to respawn, put [this] exec "vehicle.sqs" in their Initialization field!!  See the included mission for example.

For vehicle respawn we are also going to use a new 1.85 function, addEventHandler.  I'm also going to use a trick here.  I am going to "remember" where each vehicle starts on the map by saving that location inside the handler string that gets sent when the "Killed" event happens.  The "getout.sqs" is the script that handles if a vehicle has been left somewhere like off on some far away mountain.  A nice thing OFP does is drop any dead bodies out of the vehicle.  Like if someone was driving a jeep and the driver was killed but the jeep still worked, usually that jeep would then sit there for the rest of the game.  Well this "getout.sqs" script will see that no one is inside and using it anymore, so it will destroy the vehicle.  This is when the "killed.sqs" script will take over and respawn it back at base!  I wish every map maker would put this in!

Vehicle's will respawn in 180 seconds, they will destruct in 120 seconds if empty for that amount of time.

*** *** *** vehicle.sqs *** *** ***

_obj = _this select 0

;Respawn vehicle part

_pos = getPos _obj

_dir = getDir _obj

_handler = format ["[_this, %1, %2] exec ""killed.sqs""", _pos, _dir]

_obj addEventHandler ["Killed", _handler]

;Destroy abandoned vehicle part

_obj addEventHandler ["GetOut", "_this exec ""getout.sqs"""]

*** *** *** killed.sqs *** *** ***

_obj = (_this select 0) select 0

~180

;Killed is also called with setDammage (this script runs twice & the second time nothing happens)

? alive _obj : exit

_pos = _this select 1

_dir = _this select 2

_obj setPos _pos

_obj setDir _dir

_obj setVelocity [0, 0, 0]

;We do this weird thing below so that the vehicle will not crumple again!

_obj setDammage 0.3

~0.5

_obj setDammage 0.1

~0.5

_obj setDammage 0

_obj setFuel 1

;Rearm!

_weapons = weapons _obj

removeAllWeapons _obj

"_obj addMagazine _x" forEach _weapons

*** *** *** getout.sqs *** *** ***

_obj = _this select 0

? !alive _obj : exit

? count crew _obj > 0 : exit

~120

;Has anyone gotten in since we started that timer?

? !alive _obj : exit

? count crew _obj > 0 : exit

;Did the vehicle die and is it now just sitting at a respawn spot?

? fuel _obj == 1 : exit

;Do this so that there is no massive explosion!

_obj setFuel 0

removeAllWeapons _obj

_obj setDammage 1

The End

Share this post


Link to post
Share on other sites

okay cool, but:

A. The targeting scheme still falls short. we can fix this with a better routine.

B. Some folks might want it to accomodate Z shifts.

C. Adjusting fire would be better with an interface (left/right, add/drop, up/down) than another map click.

D. You've got the same problem I ran into with my artillery suite (see OFPEC editing tutorials section): camcreated shells don't make audible explosions on the other side.

E. With a MV of 180, your range is limited to 3000 yards or so (shell timeout).

It's a start. smile.gif

Share this post


Link to post
Share on other sites

Truth of it is, all that stuff took a lot of my time this week & I need to get away for a while. It was fun fun fun but I need to get back to real life or something close too it. I originally learned/started all this because I wanted people to make vehicles that respawned when someone left them out there...now that I accomplished that successfully, hopefully it will catch on (the use of the script) and I am going back to playing now!! But it was fun working it out with you Dinger.

The artillery turned out pretty cool, specially launching the smoke shells. It's fun to fire & have it fall short & try to calculate where to click to get it..and then you get it dead on and it's like YEEE HAW.

Doolittle

Share this post


Link to post
Share on other sites

Dinger, I just looked at your Artillery Suite tonight and I must say I was very impressed. You've put nuts time in on the artillery concept. Well done!

Are you, or anyone, working on a better trajectory calculator that takes into account OFP's air drag and also different heights between target and gun? I hope someone is...

Doolittle

Share this post


Link to post
Share on other sites

One second before death.  (Yes, those are Laser Guided Bombs.)

110820025064869.jpg

With 1.88 we'll be able to createVehicle SHELLS!  Finally!  Generating an M2StaticMG to fake an explosion at point of impact was so...er, not good.  Especially when using a PHONE as the projectile (hey, it's little & looks like a shell when flying through air).  So to get ready for 1.88 I was messing around.  In that pic you see 1000 LGBs traveling toward me fired from artillery on the other side of the island.  (I can see planes carpet bombing islands soon. Imagine a Cessna flying over with a zillion bombs dropping behind it...)

Doolittle

Share this post


Link to post
Share on other sites

Is it possible to make the shell make a wailing sound when it approaches? That would be very impressive - I once saw an artillery barrage during my service in the army, the sound the shell makes before it impacts is really nasty.

Share this post


Link to post
Share on other sites

The shells actually do make a sound automatically when flying.

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE"> class Shell: Default

{

model=shell;

simulation=shotShell;

simulationStep=0.05;

cost=1000;

soundHit[]={Explosions\explosion_large1,db40,1};

soundFly[]={objects\bulletnoise,db-30,4};

indirectHitRange=8;

minRange=20;minRangeProbab=0.90;

midRange=150;midRangeProbab=0.95;

maxRange=600;maxRangeProbab=0.40;

visibleFire=16; // how much is visible when this weapon is fired

audibleFire=16;

visibleFireTime=10; // how long is it visible

};

<span id='postcolor'>

The only problem is it's very hard to hear unless it's right by you.

Doolittle

Share this post


Link to post
Share on other sites

AAAAH! THe shell timeout was something i was checking the forums for.... using the 2S19 addon i could get indirect firing artillery for ranges up to 2500 meters....

i use a script, that calculates the dstance between target area and artillery site, and after that creates an enemy camo netting near (about 800m) the 2S19's in a specific height so that howitzers target the camo and fire at will....

Player will be able to adjust firing direction/length by moving the camo via action menu or user dialog...

i know this is just a workaround, Artillery is not as deadly/perfect as in RL, the camo netting can be seen if you know where to look.... BUT: it works fine for me.

And it adds a real firing/moving/fighting/acting artillery site to my games that has to be repaired/resupplied/reinforced and can be destroyed.

The max. range of 2500m is not ea real limitation to me, because of current OFP map sizes....

Share this post


Link to post
Share on other sites

sure, i'll do that.... but i won't be able to do that before monday - i'm away over the weekend....

Share this post


Link to post
Share on other sites

as promised, here's the code. it's quite ugly, but it works

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote </td></tr><tr><td id="QUOTE">_gun = _this select 0

_target = _this select 1

_xnew = getpos _target select 0

_ynew = getpos _target select 1

_dist1 = _target distance _gun

hint format ["%1", _dist1]

~5

if (_dist > 2500) then {hint "Target out of Range!";exit}

"_x dotarget _target" foreach (units group _gun)

~5

hint format ["Entfernung zum Ziel: %1 m", _dist1]

_dir = (getdir _gun)

?(_dist1 > 1100): _height = 20

?(_dist1 > 1200): _height = 40

?(_dist1 > 1300): _height = 60

?(_dist1 > 1400): _height = 60

?(_dist1 > 1500): _height = 70

?(_dist1 > 1600): _height = 80

?(_dist1 > 1700): _height = 100

?(_dist1 > 1800): _height = 125

?(_dist1 > 1900): _height = 150

?(_dist1 > 2000): _height = 200

?(_dist1 > 2100): _height = 225

?(_dist1 > 2200): _height = 350

?(_dist1 > 2300): _height = 375

?(_dist1 > 2400): _height = 400

_newdist = 800

_dx = _newdist * sin _dir

_dy = _newdist * cos _dir

_target setpos [(getpos _gun select 0)+_dx,(getpos _gun select 1)+_dy, _height];

~5

"_x dofire _target" foreach (units group _gun)

exit

<span id='postcolor'>

"_gun" is the 2S19 howitzer, "_target" is an empty object ("camo netting west") which causes the howitzers to target and fire at.

Depending on distance to target, the camo netting is placed in a specific height. The height of the camo is adjusted via action menu....

There's some inaccuracy in this method, but that doesn't matter to me.

Share this post


Link to post
Share on other sites

Could you post a working mission with this script?

I understand the basis of the script but i always feel like a nerd when i try to put that on working code (but otherways, when, at the 64.512Th attempt, i finally make it work, i feel something similar to an orgasm ;-))

Share this post


Link to post
Share on other sites

I just wanted to say that all this math is really impressive. It's a great exercise in setvelocity.

However, it's much more efficient to use scripts to determine time of flight and createvehicle the shells about 50m over the target zone, using setvelocity from there. THis way you don't have to worry about making all those calculations and you still get the same effect.

If you use the flysound to generate the screaming sound, it's going to loop and sound terrible when it does. By creating a shell close to the target you guarantee there will be no looping.

So, while all this math is great, the best solution is using createvehilce near the target IMHO.

Share this post


Link to post
Share on other sites

yea but using real shells is more realistic. besides, using createvehicle doesn't give you the chance to get hit by an incoming round when you're in an aircraft. i know the odds are like one in a kajillion, but there's still a chance--and THAT'S realism biggrin.gif

Share this post


Link to post
Share on other sites

</span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (Tanelorn @ Dec. 12 2002,03:13)</td></tr><tr><td id="QUOTE">I just wanted to say that all this math is really impressive. It's a great exercise in setvelocity.

However, it's much more efficient to use scripts to determine time of flight and createvehicle the shells about 50m over the target zone, using setvelocity from there. THis way you don't have to worry about making all those calculations and you still get the same effect.

If you use the flysound to generate the screaming sound, it's going to loop and sound terrible when it does. By creating a shell close to the target you guarantee there will be no looping.

So, while all this math is great, the best solution is using createvehilce near the target IMHO.<span id='postcolor'>

Hmmmm....

Not sure I agree.

Try to imaginate an interface (with dialogs) which permits player to set azimuth and elevation of artillery, then fire.

The whole calculation has to be made in order to know where it would fall.

That's for player handled artillery.

Whis'

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  

×