Jump to content
Sign in to follow this  
SilentSpike

Setting up an ambient mortar script

Recommended Posts

I currently have a working mission where a circular area is positioned on the map randomly (or pseudo randomly depending on chosen parameter) at the start. The rest of it then takes place in this area and I would like to set up a script to continuously run in the background, dropping mortar rounds at random positions a specified distance from the center of the chosen position.

I know I can find the random positions to my liking with this:

[_zonePos, [_zoneRad + 5, _zoneRad + 100] call BIS_fnc_randomInt, floor(random(360))] call BIS_fnc_relPos;

However there are a few things I don't know how to set up, mainly:

  1. How to transfer the values of _zonePos and _zoneRad from my initial script to the one handling this. This needs to be done as both are parameters that can be altered randomly or by the user.
  2. How to set up the loop which will run the mortar code at defined intervals
  3. How to detect if the position chosen for each mortar is on land (though I reckon I could find this out easily enough)
  4. How to realisticly script a mortar round (I also reckon I could crack this by taking a look at some other scripts out there)

The first two items are mainly what I'm looking for help with, but if anyone can help with the others then it'd be greatly appreciated.

Share this post


Link to post
Share on other sites

To tell if the position is on land: https://community.bistudio.com/wiki/surfaceIsWater

To "realistically" script a mortar, I'd say just actually create a mortar and have it shoot on the position. Otherwise it's not hard to script the rounds themselves.

Also, your _zoneRad means a safe zone? Because the random positions will be a donut shape 5 to 100m around it.

Not at home so just off the top of my head

Create a mortar named Mortar1 make a fnc:


fnc_randomMortar = 
{
_zonePos = _this select 0;
_zoneRad = _this select 1;
_numberRounds = _this select 2;

_randomTarget = [_zonePos, [_zoneRad + 5, _zoneRad + 100] call BIS_fnc_randomInt, floor(random(360))] call BIS_fnc_relPos;

Mortar1 doArtilleryFire [_randomTarget, "8Rnd_82mm_Mo_shells", _numberRounds];

}; 

then call the fnc and a sleep in a loop:

while (true) do{[x,y,z] call fnc_randomMortar; sleep 20};

where: x is the centre position (_zonePos)

y is the radius of the centre of the donut (zoneRad)

z is a number (number of rounds fired per burst)

the mortar will eventually run out, (32 rounds i think?), so if you want it to never end just add magazines to mortar1 in the function

Share this post


Link to post
Share on other sites

Yeah, I'm looking for a donut shape around the zone. It's a multiplayer game mode type deal I'm making for fun and to learn how to script - so it's simply to deter the players from leaving the area.

Thank you for the help, that looks perfect.

---------- Post added at 12:14 ---------- Previous post was at 10:18 ----------

Okay, so I thought I had everything set up correctly, but I keep getting the error "Type bool, expected code" on the "while (true) do{" line. Here's the entire script:

//---Function for random ambient mortars around zone
fnc_randomMortar =  
{
   _zonePos = getPos MarkerTrigger;
   _zoneRad = (triggerArea MarkerTrigger) select 0;
   _numberRounds = _this select 0;
   _mortarUnit = _this select 1;
   private ["_randomTarget"];
   if (paramsArray select 6 == 1) then {
       _randomTarget = [_zonePos, [_zoneRad + 5, _zoneRad + 100] call BIS_fnc_randomInt, floor(random 360)] call BIS_fnc_relPos; 
   } else {
       _randomTarget = [_zonePos, floor(random(_zoneRad+100)), floor(random 360)] call BIS_fnc_relPos;
   };

   if !(surfaceIsWater _randomTarget) then {
       _mortarUnit doArtilleryFire [_randomTarget, "8Rnd_82mm_Mo_shells", _numberRounds];
       _mortarUnit addMagazine "8Rnd_82mm_Mo_shells";
   };
};  

//---Looping function to fire mortars in succession
while (true) do{
   [floor(random 3) + 1,Mortar1] call fnc_randomMortar; 
   sleep random(20);
   [floor(random 3) + 1,Mortar2] call fnc_randomMortar; 
   sleep random(20);
   [floor(random 3) + 1,Mortar3] call fnc_randomMortar; 
   sleep random(20);
   [floor(random 3) + 1,Mortar4] call fnc_randomMortar; 
   sleep random(20);
};

If anyone can see something I can't I'd be glad to know what I've done wrong.

As a side question, I used "private ["_randomTarget"];" to define the _randomTargert variable outside of the if statement so I could use it later, is this necessary and is there a more correct way of doing it?

Edited by SilentSpike

Share this post


Link to post
Share on other sites

[/color]Okay, so I thought I had everything set up correctly, but I keep getting the error "Type bool, expected code" on the "while (true) do{" line. Here's the entire script:

The error results from the brackets, (true) is boolean, it should be {true} to be code, like this:

while {true} do{

for your _randomtarget issue you could just define the variable with putting

_randomtarget = [];

on top of your script and delete the private = ["_randomtarget"]; part

Other than that it should work just fine

Share this post


Link to post
Share on other sites

Thanks, thought I actually tried using {} earlier and got the same error, but I'll give it another go now that I've came back to it.

Share this post


Link to post
Share on other sites

So I've got the script working, however there are issues with dynamically placing the mortar units since their placement is not always reliably suitable (even with isFlatEmpty, etc.). I've been trying to find scripts that simulate the mortar rounds themselves to see how it's done and so far the closest I've come across is this.

I edited the script to produce this:

fnc_randomMortar = {

   _start = (_this select 0);
   _iterations = (_this select 1);
   _nummrt = (_this select 2);
   _timebetween = (_this select 3);
   _target = (_this select 4);

   sleep _start;

for "_i" from 0 to _iterations step 1 do

{

	for "_i" from 0 to _nummrt step 1 do
	{
		_mrtcall = createVehicle ["Sh_82mm_AMOS", _target, [], 100, "NONE"];
		sleep 8;
	};

sleep _timebetween;

};
};

However, it doesn't seem to produce any effect. Here's what I'm using to call it:

if (isServer) then {
   _zonePos = getPos MarkerTrigger;
   _zoneRad = (triggerArea MarkerTrigger) select 0;

   while {true} do{
       _randomTarget = [];
       if (paramsArray select 6 == 1) then {
           _randomTarget = [_zonePos, [_zoneRad + 5, _zoneRad + 100] call BIS_fnc_randomInt, floor(random 360)] call BIS_fnc_relPos; 
       } else {
           _randomTarget = [_zonePos, floor(random(_zoneRad+100)), floor(random 360)] call BIS_fnc_relPos;
       };

       [0, floor(random 2) + 1, floor(random 3) + 1, 20, _randomTarget] call fnc_randomMortar;
   };
};

Can anyone give me an example function to pseudo fire a mortar round onto position '_target'? I'm not yet versed enough to know the best way of doing that. However I should be able to set up the rest from there.

Edited by SilentSpike

Share this post


Link to post
Share on other sites
The error results from the brackets

Yep sorry, this is what happens when I write in notepad at work.

As for making it explode, I think you might need to give it some velocity so it hits the ground.

Also change the _target height if you want that brief glimpse of the round before impacting, but I don't think it's necessary for an explosion.

Guessing it spawns flat to ground so you might wish to change that also: https://community.bistudio.com/wiki/setVectorDirAndUp

 _mrtcall = createVehicle ["Sh_82mm_AMOS", _target, [], 100, "NONE"];
_mrtcall  setVelocity [0,0,-70]; 

cheers

Share this post


Link to post
Share on other sites

Thanks once again! Setting the velocity and giving it some height did make it explode, not sure why the original script never did that. However, I thought of an even easier way to do all this after setting that up and can confirm that simply creating "ModuleOrdnanceMortar_F" on the target position will do the job even better. :D

---------- Post added at 10:54 ---------- Previous post was at 10:37 ----------

Here's the final function, just in case anyone else finds some use in it:

fnc_randomMortar = {
/* Function to drop mortar rounds onto a position
[a,b,c,d]
a = Number of itterations
b = Rounds per itteration
c = Time between itterations
d = Target position
e = Dispersion radius around target */

   _iterations = (_this select 0);
   _nummrt = (_this select 1);
   _timebetween = (_this select 2);
   _target = (_this select 3);
   _dRadius = (_this select 4);

for "_i" from 1 to _iterations step 1 do

{

	for "_i" from 1 to _nummrt step 1 do
	{
		_mrtcall = createVehicle ["ModuleOrdnanceMortar_F", _target, [], _dRadius, "NONE"];
		sleep 8;
           deletevehicle _mrtcall;
	};

sleep _timebetween;

};
};

Share this post


Link to post
Share on other sites

No worries man. Good to see it nice and simple in the end. While loops are an unnecessary drain, best to be avoided.

Never heard of the "module...mortarF" before, must be a new thing. Time to update my scripts.

Cheers.

Share this post


Link to post
Share on other sites

I am calling the function in a while loop for my missions purposes, but I left that outside of the function. Should really have renamed the function actually.

As for the mortarF module, it came from the zeus DLC. One side effect is that it will tell players enemy mortars are inbound (via audio) if they're in the target area, but that works fine for my mission.

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  

×