Jump to content
Sign in to follow this  
madrussian

Fun with Mortar Projectiles

Recommended Posts

I need to detect and stop the impact of a mortar.  Create a “dud” if you will.  Any ideas?

 

Some background:

  • I originally wrote a simple mortar script which randomly creates a bunch of explosions directly on the ground.
  • I’m replacing that script with an improved script using real mortars that travel through the air from origin to target.  I create them via createVehicle, position at the virtual artillery source via setPosASL, use kinematic equations to determine a firing solution (aka trajectory), and sent on their way via setVelocity.
  • Finished the script and everything works great, mortars fly to exactly where I want them.

 

Here’s where the trouble starts.  The whole reason I wanted real flying mortars is for that whistle sound, so the players have some warning that a round is incoming.

  • Fortunately, the whistle sound works great for the player whose machine created the mortar.
  • Unfortunately, the whistle sound is entirely missing for every other player, defeating the entire point of the new script.

 

So my idea now is to send a mortar round on every machine, hoping that all players will hear the whistle.

  • Fortunately, this works!  All players hear the whistle!
  • Now I just need to send one real mortar round (for the player that called in the mortar), and a bunch of “duds” for the other players.  I need help with the “duds”. :smile_o:

 

So here’s the question:

 

Anyone know how to stop the impact of a mortar (preferably via simple command or EH)?

 

(P.S - I’d like to keep this clean and avoid looping scripts, but happy to hear any & all ideas.)

Share this post


Link to post
Share on other sites

Easiest approach would be to add all mortar shells to a global array and check on every frame if Z velocity is negative and n meters above ground.

 

This could work out:

//init.sqf or wherever you seem fit
GOM_fnc_artyShells = [];

//mortar init or other way to add the spawned shell to the array
this addEventHandler ["Fired",{GOM_fnc_artyShells pushBack (_this#6)}]; 

addMissionEventHandler ["EachFrame",{
	{
		if (velocity _x # 2 < 0 AND getPosATL _x # 2 < 50) then {
			hintSilent format ["Deleting %1\nVelocity: %2\nATL: %3",_x,velocity _x,getPosATL _x];
			deleteVehicle _x;
			GOM_fnc_artyShells deleteAt _forEachIndex;
		};
	} forEach GOM_fnc_artyShells;

}];

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

What I've done in my version of a "virtual" mortar is extract the sound from another source and save it as a separat file. The shell is created on a single machine (the server in my case) and the sound is broadcasted from server to clients using playSound3D. Quite effectful. I'll see about posting the snippet and sound later. 

  • Like 2

Share this post


Link to post
Share on other sites

Great ideas! :drinking2:

 

I'm off to run some quick experiments, and will report back.  In the mean time, a couple of my (previous) observations regarding your current suggestions:

  • Both of you mentioned deleting these mortar shells... Are you guys able to successfully delete them?  Using deleteVehicle for me has no effect on them, and they still make impact.  As an alternative to deletion, I end up having to teleport them somewhere far far away.  <- EDIT: Correction, deleteVehicle does delete this type of projectile if they are local.  Apparently, I was trying to delete them non-locally.  (The deleteVehicle command is suppose to be "Argument Global, Effect Global", but at least in the case of these mortar projectiles, calling deleteVehicle on a non-local projectile seems to have no effect.)
  • I looked into playSound3D previously, and quickly realized I'd have a number of issues.  First off (according to KK's comment on the ref), the sound will not move along with the shell as it travels.  Secondly, seems like the engine's whistle sound changes pitch as it moves, and I don't see any way to dynamically change pitch over the course of the played sound with playSound3D.  (You can set the pitch of the played sound once but that's it.)  Third, as it is a global command, seems the new sound will clash with the engine created whistle for that one player (who's machine ran the createVehicle)?  Curious mrcurry, if you experienced any of those?

 

Also a handful of tidbits for anyone interested (from my experiments so far):

 

  1. When an actual vehicle fires a shell and you grab the projectile via addEventHandler "Fired", that projectile is accessible to that machine.  But if you try to broadcast it to another machine (via remoteExec), the projectile is not accessible on that new machine.  In contrast, when you use createVehicle to create the projectile shell and broadcast it to another machine (again via remoteExec), it's accessible on both machines. <- EDIT: In this case "accessible" on the non-local machine is pretty limited.  You pretty much just have a reference to the non-local projectile, and few commands will do any real operation on it.  (For instance, I could not delete them, etc.)
  2. createVehicle and createVehicleLocal both seem to do the exact same thing when creating shell ammo types as found in CfgAmmo.  Either way, the object created is definitely present and accounted for on all machines (owned by the machine that created to it). <- EDIT: By "present and accounted for", I mean to say that the impact (at least) has a global effect!
  3. Using allowDamage false and hideObject true on projectile shells seems to do nothing to stop the impact.

  4. Attaching the "dud" shell to a carrier object (like a "Land_Wrench_F") via attachTo (then sending the carrier obj along the same trajectory) will keep it from exploding, but it totally mucks up the engine's whistle sound (removes the desired whistle and leaves the unpleasant metallic part, also messes up the pitch, etc), which again defeats the point.

 

Share this post


Link to post
Share on other sites

does the config based mortar ammo not work or has none defined (soundFly)?

Share this post


Link to post
Share on other sites

The round I'm sending is "Sh_82mm_AMOS" (vanilla game mortar).

 

Here's "soundFly" and falling bomb sound configs with default game loaded:

 

configfile >> "CfgAmmo" >> "Sh_82mm_AMOS" >>

soundFly[] = {"",0.0316228,4};

soundFakeFall[] = {"soundFakeFall0",0.25,"soundFakeFall1",0.25,"soundFakeFall2",0.25,"soundFakeFall3",0.25};

soundFakeFall0[] = {"a3\Sounds_F\weapons\falling_bomb\fall_01",3.16228,1,1000};

soundFakeFall1[] = {"a3\Sounds_F\weapons\falling_bomb\fall_02",3.16228,1,1000};

soundFakeFall2[] = {"a3\Sounds_F\weapons\falling_bomb\fall_03",3.16228,1,1000};

soundFakeFall3[] = {"a3\Sounds_F\weapons\falling_bomb\fall_04",3.16228,1,1000};

 

Here's "soundFly" with CUP loaded (falling bomb sound entries are the same):

 

configfile >> "CfgAmmo" >> "Sh_82mm_AMOS" >>

soundFly[] = {"CUP\Weapons\CUP_Weapons_Ammunition\data\sound\shorter.wss",2,1,500};

 

(Most of my experimentation was run with CUP loaded.)

 

I did listen to the the four falling bomb sounds (soundFakeFall) individually in test mission using playSound3D, and they do sound pretty good.  The game engine though, changes the pitch of some of these sounds (or is it changing pitch of soundFly sound?) as projectile travels (Doppler Effect I presume) which is awesome, and I think I have no hope of duplicating that dynamic change of pitch.  Thus I was simply hoping to create "dud" rounds that sound perfect because they are, of course, the real thing.

 

@.kju

Any idea how soundFly fits in and what it means to have an empty string for soundFly?

 

Share this post


Link to post
Share on other sites
13 hours ago, madrussian said:

Third, as it is a global command, seems the new sound will clash with the engine created whistle for that one player (who's machine ran the createVehicle)?  Curious mrcurry, if you experienced any of those?

No I never did, in my version playSound3D is executed only once on the server just above the impact. The sound itself does most of the work infact. My use case is more for cinematic effect so the shells are just spawned some 100m off the ground with an incoming velocity vector and 

 

Here's a sound sample, I got 3-4 of these with slight variation and randomize the selection:

https://www.dropbox.com/s/e7rjvoo7o4dyyp5/mortar1.ogg?dl=0

Share this post


Link to post
Share on other sites

@madrussian not the expert as to what parameter is used in regards to sounds - especially with BI WIP to change "everything" to soundSets.

LAxemann would be the better/best person to talk to.

Share this post


Link to post
Share on other sites

 

Hey thanks for the help here.  Managed to get my mortar/artillery system working great!  Every client gets the dynamic whistle sound of real flying rounds! :smile_o:

 

I ended up going with dummy rounds for each client (aka "whistlers"), and used per-frame handler to delete them prior to impact (as Grumpy Old Man suggested, thanks for the idea).  Also added in a object/terrain intersection check, based on meters-per-frame velocity (just for the projectiles under 50m):

Spoiler

 


_projectiles = missionNamespace getVariable ["BUB_Sup_Arti_Projectiles", []];
_whistlers = missionNamespace getVariable ["BUB_Sup_Arti_Whistlers", []];

_lowWhistlers = _whistlers select { (((velocity _x) select 2) < 0) and (((getPosATL _x) select 2) < 50) };

if ((count _lowWhistlers) > 0) then {
	_velocityMPS = vectorMagnitude (velocity (_lowWhistlers select 0));
	_velocityMPF = _velocityMPS / diag_fps;
	_checkDist = _velocityMPF * 2.25;
	
	//["_velocityMPS","diag_fps","_velocityMPF","_checkDist"] call MRU_SystemChat;
	
	_groundImpactingWhistlers = _lowWhistlers select { (((getPosATL _x) select 2) < _checkDist) };
	_intersectingWhistlers = [];
	_objImpactingWhistlers = [];
	{
		_whistler = _x;
		_objs = lineIntersectsWith [getPosASL _whistler, (getPosASL _whistler) vectorAdd ((vectorNormalized (velocity _whistler)) vectorMultiply _checkDist), objNull, objNull];
		if ((count _objs) > 0) then {
			_intersectingWhistlers pushBack _whistler;
			_objs = _objs - _projectiles - _whistlers;
			if ((count _objs) > 0) then {
				_objImpactingWhistlers pushBack _whistler;
			};
		};
	} foreach (_lowWhistlers - _groundImpactingWhistlers);

	{
		_whistler = _x;
		//systemChat "Remove _whistler via setVelocity [0,0,0] & deleteVehicle!";
		_whistler setVelocity [0,0,0];
		//_helper = createVehicle ["Sign_Arrow_F", ASLtoATL (getPosASL _whistler), [], 0, "CAN_COLLIDE"];
		deleteVehicle _whistler;

		_allRemovedWhistlers = missionNamespace getVariable ["BUB_Sup_Arti_AllRemovedWhistlers", []];
		_allRemovedWhistlers pushBack _whistler;
		BUB_Sup_Arti_AllRemovedWhistlers = _allRemovedWhistlers;	
		_idx = _whistlers find _whistler;
		_whistlers deleteAt _idx;
		_projectiles deleteAt _idx;
	} foreach (_groundImpactingWhistlers + _objImpactingWhistlers);
};
	
if ((count _whistlers) > 0) then {
	_impactedWhistlers = _whistlers select { isNull _x };

	if ((count _impactedWhistlers) > 0) then {
		_allImpactedWhistlers = missionNamespace getVariable ["BUB_Sup_Arti_AllImpactedWhistlers", []];
		_allImpactedWhistlers append _impactedWhistlers;
		BUB_Sup_Arti_AllImpactedWhistlers = _allImpactedWhistlers;
		
		while { ({isNull _x} count _whistlers) > 0 } do {
			_idx = -1;
			{
				if (isNull _x) exitWith { _idx = _foreachIndex };
			} foreach _whistlers;
			if (_idx >= 0) then {
				_hint = "Warning - Artillery whistler impacted and (probably) should not have!  Please report to mission creator...";
				hint _hint; systemChat _hint;
				_whistlers deleteAt _idx;
				_projectiles deleteAt _idx;
			};
		};
	};
};

BUB_Sup_Arti_Whistlers = _whistlers;

if ((count BUB_Sup_Arti_Whistlers) == 0) then {
	BUB_Sup_Arti_Projectiles = nil;
	BUB_Sup_Arti_Whistlers = nil;
	BUB_Sup_Arti_WhistlerEH = nil;
	removeMissionEventHandler ["EachFrame", _thisEventHandler];
};

 

 

 

Performance remains great as far as I can tell, and so far in many playthroughs no client's fake whistlers make impact, meaning it's working!

 

I do wish mortar/artillery rounds would simply make the whistle sound for all clients out of the box.  Or at least I wish we had a way to simply create duds via a quick script command, and not have to go through all these hoops.  Oh well, maybe with upcoming Enfusion engine...

 

@mrcurry  Very nice!  I ended up using playSound3D for the firing sound at the source, as well.  Interestingly, when I went in to locate the sounds from the game files, I was surprised to see they each have multiple parts based on distance (for close, medium, far, etc).  Learned that if you play them in isolation, they all sound a bit funny.  Only when you play them all simultaneously together (with some tweaks for distance per sound), do you get the appropriate firing "sound".  (I suppose it's that way for all weapons.)

 

[Also, edited one of my earlier posts for clarification.  See those edits in blue.]

Share this post


Link to post
Share on other sites

Hey not to narco-post on this thread, but can someone provide me with a simplified script just to have the whistle sound emitted before impact for mortar fire?

 

I'm very novice when it comes to scripting. I have a mission set up with two mortar teams and I'd like to have the cinematic effect of the whistling before projectile impact. I'm not familiar how to use eventHandler in conjunction with playsound3d, or any of this scripting stuff for that matter. I saw mrcurry had figured it out but his dropbox link is down.

 

Any help would be appreciated.

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  

×