diff -r a0ea23310430 docs/zandronum-history.txt
--- a/docs/zandronum-history.txt	Mon Sep 02 19:00:03 2013 +0200
+++ b/docs/zandronum-history.txt	Wed Sep 11 23:36:48 2013 +0300
@@ -12,6 +12,11 @@
 ===============================================================================================================
 
 
+1.3
+---
+
++	- Added new dmflag sv_sharekeys. When enabled, any keys picked are shared between players. Also, players joining the game get the keys others have as well. [Dusk]
+
 1.2
 ---
 
diff -r a0ea23310430 src/d_main.cpp
--- a/src/d_main.cpp	Mon Sep 02 19:00:03 2013 +0200
+++ b/src/d_main.cpp	Wed Sep 11 23:36:48 2013 +0300
@@ -514,6 +514,7 @@
 CVAR (Flag, sv_nocoopinfo,			dmflags3, DF3_NO_COOP_INFO);
 CVAR (Flag, sv_unblockplayers,			dmflags3, DF3_UNBLOCK_PLAYERS);
 CVAR (Flag, sv_nomedals,			dmflags3, DF3_NO_MEDALS);
+CVAR (Flag, sv_sharekeys,			dmflags3, DF3_SHARE_KEYS);
 
 //==========================================================================
 //
diff -r a0ea23310430 src/doomdef.h
--- a/src/doomdef.h	Mon Sep 02 19:00:03 2013 +0200
+++ b/src/doomdef.h	Wed Sep 11 23:36:48 2013 +0300
@@ -294,6 +294,9 @@
 
 	// [BB] Enforces clients not to show medals, i.e. behave as if cl_medals == 0.
 	DF3_NO_MEDALS			= 1 << 5,
+
+	// [Dusk] Share keys between all players
+	DF3_SHARE_KEYS			= 1 << 6,
 };
 
 // [RH] Compatibility flags.
diff -r a0ea23310430 src/g_shared/a_pickups.cpp
--- a/src/g_shared/a_pickups.cpp	Mon Sep 02 19:00:03 2013 +0200
+++ b/src/g_shared/a_pickups.cpp	Wed Sep 11 23:36:48 2013 +0300
@@ -31,6 +31,7 @@
 #include "gamemode.h"
 #include "cooperative.h"
 #include "p_acs.h"
+#include "a_keys.h"
 
 static FRandom pr_restore ("RestorePos");
 
@@ -1149,6 +1150,61 @@
 	// [BC] Finally, refresh the HUD.
 	if ( NETWORK_GetState( ) != NETSTATE_SERVER )
 		SCOREBOARD_RefreshHUD( );
+
+	// [Dusk] If it's a key and we wish to share it, tell other players we got it
+	if ( dmflags3 & DF3_SHARE_KEYS &&
+		NETWORK_GetState( ) == NETSTATE_SERVER &&
+		IsKindOf( RUNTIME_CLASS( AKey )) &&
+		toucher->player )
+	{
+		// [Dusk] Announce it too, but only if nobody else has it.
+		bool bAnnounce = true;
+
+		for ( int i = 0; i < MAXPLAYERS; i++ )
+		{
+			if ( playeringame[i] && players[i].mo &&
+				i != toucher->player - players &&
+				players[i].mo->FindInventory( GetClass( )))
+			{
+				bAnnounce = false;
+				break;
+			}
+		}
+
+		if ( bAnnounce )
+		{
+			FString keyname;
+
+			// [Dusk] Determine how to write the key's name. Tag is preferred,
+			// if not present, use the class name.
+			if (( keyname = GetClass()->Meta.GetMetaString( AMETA_StrifeName )).IsEmpty() )
+				keyname = GetClass()->TypeName;
+
+			SERVER_Printf( PRINT_HIGH, "\\cD%s\\c- has located the \\cF%s!\n",
+				toucher->player->userinfo.netname, keyname.GetChars( ));
+
+			// Audio cue
+			if ( S_FindSound( "misc/k_pkup" ))
+				SERVERCOMMANDS_Sound( CHAN_AUTO, "misc/k_pkup", 1.0, ATTN_NONE );
+		}
+
+		for ( int i = 0; i < MAXPLAYERS; i++ )
+		{
+			// [Dusk] See if the player should get this key
+			if ( PLAYER_IsValidPlayerWithMo( i ) == false ||
+				i == toucher->player - players ||
+				players[i].bSpectating ||
+				players[i].mo->FindInventory( GetClass( )))
+			{
+				continue;
+			}
+
+			// [Dusk] Try give the key to the player
+			AInventory* newkey;
+			if (( newkey = players[i].mo->GiveInventoryType( GetClass( ))) != NULL )
+				SERVERCOMMANDS_GiveInventory( i, newkey );
+		}
+	}
 }
 
 //===========================================================================
diff -r a0ea23310430 src/p_user.cpp
--- a/src/p_user.cpp	Mon Sep 02 19:00:03 2013 +0200
+++ b/src/p_user.cpp	Wed Sep 11 23:36:48 2013 +0300
@@ -1567,6 +1567,37 @@
 			PLAYER_SetWeapon( player, pPendingWeapon, true );
 		}
 	}
+
+	// [Dusk] If we are sharing keys, give this player the keys other players have.
+	if (( dmflags3 & DF3_SHARE_KEYS ) && ( NETWORK_GetState( ) == NETSTATE_SERVER ))
+	{
+		for ( int i = 0; i < MAXPLAYERS; ++i )
+		{
+			if (( PLAYER_IsValidPlayerWithMo( i ) == false ) || ( i == player - players ))
+				continue;
+
+			bool bGotKeys = false;
+
+			// [Dusk] Snoop over this guy's pockets and try find keys.
+			for ( AInventory* inv = players[i].mo->Inventory; inv != NULL; inv = inv->Inventory )
+			{
+				AInventory* newkey;
+
+				// [Dusk] If we find any keys, quickly try make a copy before he notices anything.
+				if ( inv->IsKindOf( RUNTIME_CLASS( AKey )) &&
+					( newkey = GiveInventoryType( inv->GetClass() )) != NULL )
+				{
+					SERVERCOMMANDS_GiveInventory( player - players, newkey );
+					bGotKeys = true;
+				}
+			}
+
+			// [Dusk] If we got any keys, stop here. Any following players
+			// won't not have anything this one doesn't have.
+			if ( bGotKeys )
+				break;
+		}
+	}
 }
 
 void APlayerPawn::MorphPlayerThink ()
