diff --git a/src/p_acs.cpp b/src/p_acs.cpp
index 9281bfad0e..1a60a0c4fb 100644
--- a/src/p_acs.cpp
+++ b/src/p_acs.cpp
@@ -5350,7 +5350,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
 
 		case ACSF_PlaySound:
 		case ACSF_PlayActorSound:
-			// PlaySound(tid, "SoundName", channel, volume, looping, attenuation)
+			// PlaySound(tid, "SoundName", channel, volume, looping, attenuation, local)
 			{
 				FSoundID sid;
 
@@ -5371,6 +5371,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
 					float vol = argCount > 3 ? ACSToFloat(args[3]) : 1.f;
 					INTBOOL looping = argCount > 4 ? args[4] : false;
 					float atten = argCount > 5 ? ACSToFloat(args[5]) : ATTN_NORM;
+					INTBOOL local = argCount > 6 ? args[6] : false;
 
 					if (args[0] == 0)
 					{
@@ -5387,11 +5388,11 @@ doplaysound:			if (funcIndex == ACSF_PlayActorSound)
 						{
 							if (!looping)
 							{
-								S_Sound(spot, chan, sid, vol, atten);
+								S_PlaySound(spot, chan, sid, vol, atten, local);
 							}
 							else if (!S_IsActorPlayingSomething(spot, chan & 7, sid))
 							{
-								S_Sound(spot, chan | CHAN_LOOP, sid, vol, atten);
+								S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, local);
 							}
 						}
 					}
diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp
index c6bc8215b0..73cade49a4 100644
--- a/src/p_actionfunctions.cpp
+++ b/src/p_actionfunctions.cpp
@@ -1032,16 +1032,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlaySound)
 	PARAM_FLOAT_OPT	(volume)		{ volume = 1; }
 	PARAM_BOOL_OPT	(looping)		{ looping = false; }
 	PARAM_FLOAT_OPT	(attenuation)	{ attenuation = ATTN_NORM; }
+	PARAM_BOOL_OPT	(local)			{ local = false; }
 
 	if (!looping)
 	{
-		S_Sound (self, channel, soundid, (float)volume, (float)attenuation);
+		S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local);
 	}
 	else
 	{
 		if (!S_IsActorPlayingSomething (self, channel&7, soundid))
 		{
-			S_Sound (self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation);
+			S_PlaySound(self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation, local);
 		}
 	}
 	return 0;
diff --git a/src/s_sound.cpp b/src/s_sound.cpp
index 524b121756..a51a7101be 100644
--- a/src/s_sound.cpp
+++ b/src/s_sound.cpp
@@ -1301,6 +1301,32 @@ void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, fl
 	S_StartSound (NULL, sec, NULL, NULL, channel, sfxid, volume, attenuation);
 }
 
+//==========================================================================
+//
+// S_PlaySound - Subfunction used by ACS and DECORATE
+//
+// Has a local parameter to make the sound audible only to the source
+//
+//==========================================================================
+
+void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local)
+{
+	if (a == nullptr)
+		return;
+
+	if (!local)
+	{
+		S_Sound(a, chan, sid, vol, atten);
+	}
+	else
+	{
+		if (a->CheckLocalView(consoleplayer))
+		{
+			S_Sound(chan, sid, vol, ATTN_NONE);
+		}
+	}
+}
+
 //==========================================================================
 //
 // S_LoadSound
diff --git a/src/s_sound.h b/src/s_sound.h
index 9b917e25c8..d6d2a5403e 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -241,6 +241,9 @@ void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, f
 void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation);
 void S_Sound(const DVector3 &pos, int channel, FSoundID sfxid, float volume, float attenuation);
 
+// [Nash] Used by ACS and DECORATE
+void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local);
+
 // sound channels
 // channel 0 never willingly overrides
 // other channels (1-7) always override a playing sound on that channel
diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt
index eecc843d39..71e82f613d 100644
--- a/wadsrc/static/actors/actor.txt
+++ b/wadsrc/static/actors/actor.txt
@@ -191,7 +191,7 @@ ACTOR Actor native //: Thinker
 	action native A_ComboAttack();
 	action native A_BulletAttack();
 	action native A_WolfAttack(int flags = 0, sound whattoplay = "weapons/pistol", float snipe = 1.0, int maxdamage = 64, int blocksize = 128, int pointblank = 2, int longrange = 4, float runspeed = 160.0, class<Actor> pufftype = "BulletPuff");
-	action native A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, float volume = 1.0, bool looping = false, float attenuation = ATTN_NORM);
+	action native A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, float volume = 1.0, bool looping = false, float attenuation = ATTN_NORM, bool local = false);
 	native void A_PlayWeaponSound(sound whattoplay);
 	action native A_FLoopActiveSound();
 	action native A_LoopActiveSound();