diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 26b1c6b6b..5b584a5a4 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,3 +1,13 @@
+February 24, 2007 (Changes by Graf Zahl)
+- Fixed: In the Doom2 cast finale it was impossible to toggle the console.
+- Added APROP_Friendly actor property for ACS.
+- Added a new flag, MF2_DONTREFLECT that prevents missiles from being reflected.
+- Fixed: ALoreShot::DoSpecialDamage must check whether the shooter is still
+  present. If it had been removed before the projectile hits its target
+  a crash could occur.
+- Fixed: GetPlayerInfo was missing breaks and always returned 0 as a result.
+- Added Grubber's submission for printing key bindings in ACS.
+
 February 19, 2007
 - Fixed: $Ambient SNDINFO commands zeroed the AmbientSound structure, which
   is a no-no when using FString.
diff --git a/src/actor.h b/src/actor.h
index 455773883..fcd1ffaae 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -154,6 +154,7 @@ enum
 
 // --- mobj.flags2 ---
 
+	MF2_DONTREFLECT		= 0x00000001,	// this projectile cannot be reflected
 	MF2_WINDTHRUST		= 0x00000002,	// gets pushed around by the wind specials
 	MF2_BOUNCE1			= 0x00000004,
 	MF2_BLASTED			= 0x00000008,	// actor will temporarily take damage from impact
diff --git a/src/c_bind.h b/src/c_bind.h
index 26667453b..161a66e96 100644
--- a/src/c_bind.h
+++ b/src/c_bind.h
@@ -55,4 +55,6 @@ void C_UnbindAll ();
 // Returns string bound to given key (NULL if none)
 const char *C_GetBinding (int key);
 
+extern const char *KeyNames[];
+
 #endif //__C_BINDINGS_H__
diff --git a/src/f_finale.cpp b/src/f_finale.cpp
index d9c6343b1..2d8feedfc 100644
--- a/src/f_finale.cpp
+++ b/src/f_finale.cpp
@@ -44,6 +44,7 @@
 #include "p_conversation.h"
 #include "a_strifeglobal.h"
 #include "templates.h"
+#include "c_bind.h"
 
 static void FadePic ();
 static void GetFinaleText (const char *msgLumpName);
@@ -709,6 +710,11 @@ bool F_CastResponder (event_t* ev)
 {
 	if (ev->type != EV_KeyDown)
 		return false;
+			
+	const char *cmd = C_GetBinding (ev->data1);
+
+	if (cmd != NULL && !stricmp (cmd, "toggleconsole"))
+		return false;		
 				
 	if (castdeath)
 		return true;					// already in dying frames
diff --git a/src/g_strife/a_loremaster.cpp b/src/g_strife/a_loremaster.cpp
index de3b12a83..c9f433272 100644
--- a/src/g_strife/a_loremaster.cpp
+++ b/src/g_strife/a_loremaster.cpp
@@ -149,17 +149,20 @@ END_DEFAULTS
 int ALoreShot::DoSpecialDamage (AActor *target, int damage)
 {
 	FVector3 thrust;
-
-	thrust.X = float(this->target->x - target->x);
-	thrust.Y = float(this->target->y - target->y);
-	thrust.Z = float(this->target->z - target->z);
-
-	thrust.MakeUnit();
-	thrust *= float((255*50*FRACUNIT) / (target->Mass ? target->Mass : 1));
-
-	target->momx += fixed_t(thrust.X);
-	target->momy += fixed_t(thrust.Y);
-	target->momz += fixed_t(thrust.Z);
+	
+	if (this->target != NULL)
+	{
+		thrust.X = float(this->target->x - target->x);
+		thrust.Y = float(this->target->y - target->y);
+		thrust.Z = float(this->target->z - target->z);
+	
+		thrust.MakeUnit();
+		thrust *= float((255*50*FRACUNIT) / (target->Mass ? target->Mass : 1));
+	
+		target->momx += fixed_t(thrust.X);
+		target->momy += fixed_t(thrust.Y);
+		target->momz += fixed_t(thrust.Z);
+	}
 	return damage;
 }
 
diff --git a/src/p_acs.cpp b/src/p_acs.cpp
index b2646985c..63b911278 100644
--- a/src/p_acs.cpp
+++ b/src/p_acs.cpp
@@ -64,6 +64,7 @@
 #include "gstrings.h"
 #include "gi.h"
 #include "sc_man.h"
+#include "c_bind.h"
 
 extern FILE *Logfile;
 
@@ -2074,6 +2075,7 @@ void DLevelScript::DoSetFont (int fontnum)
 #define APROP_ChaseGoal		13
 #define APROP_Frightened	14
 #define APROP_Gravity		15
+#define APROP_Friendly		16
 #define APROP_SeeSound		5	// Sounds can only be set, not gotten
 #define APROP_AttackSound	6
 #define APROP_PainSound		7
@@ -2157,6 +2159,13 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
 			actor->flags4 &= ~MF4_FRIGHTENED;
 		break;
 		
+	case APROP_Friendly:
+		if (value)
+			actor->flags |= MF_FRIENDLY;
+		else
+			actor->flags &= ~MF_FRIENDLY;
+		break;
+		
 	case APROP_Gravity:
 		actor->gravity = value;
 		break;
@@ -2215,6 +2224,7 @@ int DLevelScript::GetActorProperty (int tid, int property)
 	case APROP_Ambush:		return !!(actor->flags & MF_AMBUSH);
 	case APROP_ChaseGoal:	return !!(actor->flags5 & MF5_CHASEGOAL);
 	case APROP_Frightened:	return !!(actor->flags4 & MF4_FRIGHTENED);
+	case APROP_Friendly:	return !!(actor->flags & MF_FRIENDLY);
 	case APROP_JumpZ:		if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
 							{
 								return static_cast<APlayerPawn *>(actor)->JumpZ;	// [GRB]
@@ -3749,6 +3759,25 @@ int DLevelScript::RunScript ()
 			}
 			break;
 
+		// [GRB] Print key name(s) for a command
+		case PCD_PRINTBIND:
+			lookup = FBehavior::StaticLookupString (STACK(1));
+			if (lookup != NULL)
+			{
+				int key1 = 0, key2 = 0;
+
+				C_GetKeysForCommand ((char *)lookup, &key1, &key2);
+
+				if (key2)
+					work = work + KeyNames[key1] + " or " + KeyNames[key2];
+				else if (key1)
+					work += KeyNames[key1];
+				else
+					work += "???";
+			}
+			--sp;
+			break;
+
 		case PCD_ENDPRINT:
 		case PCD_ENDPRINTBOLD:
 		case PCD_MOREHUDMESSAGE:
@@ -4987,15 +5016,15 @@ int DLevelScript::RunScript ()
 				userinfo_t *userinfo = &players[STACK(2)].userinfo;
 				switch (STACK(1))
 				{
-				case PLAYERINFO_TEAM:			STACK(2) = userinfo->team;
-				case PLAYERINFO_AIMDIST:		STACK(2) = userinfo->aimdist;
-				case PLAYERINFO_COLOR:			STACK(2) = userinfo->color;
-				case PLAYERINFO_GENDER:			STACK(2) = userinfo->gender;
-				case PLAYERINFO_NEVERSWITCH:	STACK(2) = userinfo->neverswitch;
-				case PLAYERINFO_MOVEBOB:		STACK(2) = userinfo->MoveBob;
-				case PLAYERINFO_STILLBOB:		STACK(2) = userinfo->StillBob;
-				case PLAYERINFO_PLAYERCLASS:	STACK(2) = userinfo->PlayerClass;
-				default:						STACK(2) = 0;
+				case PLAYERINFO_TEAM:			STACK(2) = userinfo->team; break;
+				case PLAYERINFO_AIMDIST:		STACK(2) = userinfo->aimdist; break;
+				case PLAYERINFO_COLOR:			STACK(2) = userinfo->color; break;
+				case PLAYERINFO_GENDER:			STACK(2) = userinfo->gender; break;
+				case PLAYERINFO_NEVERSWITCH:	STACK(2) = userinfo->neverswitch; break;
+				case PLAYERINFO_MOVEBOB:		STACK(2) = userinfo->MoveBob; break;
+				case PLAYERINFO_STILLBOB:		STACK(2) = userinfo->StillBob; break;
+				case PLAYERINFO_PLAYERCLASS:	STACK(2) = userinfo->PlayerClass; break;
+				default:						STACK(2) = 0; break;
 				}
 			}
 			sp -= 1;
diff --git a/src/p_acs.h b/src/p_acs.h
index 67d8171e6..5f466d26c 100644
--- a/src/p_acs.h
+++ b/src/p_acs.h
@@ -538,6 +538,7 @@ public:
 /*330*/	PCD_NEGATEBINARY,
 		PCD_GETACTORPITCH,
 		PCD_SETACTORPITCH,
+		PCD_PRINTBIND,
 
 		PCODE_COMMAND_COUNT
 	};
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index b3b01b1b7..4a8bb592c 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -2383,6 +2383,8 @@ int AActor::SpecialMissileHit (AActor *victim)
 
 bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
 {
+	if (flags2 & MF2_DONTREFLECT) return true;
+
 	// Change angle for reflection
 	if (thing->flags4&MF4_SHIELDREFLECT)
 	{
diff --git a/src/thingdef.cpp b/src/thingdef.cpp
index f67e2608b..d19fb9961 100644
--- a/src/thingdef.cpp
+++ b/src/thingdef.cpp
@@ -129,6 +129,7 @@ static flagdef ActorFlags[]=
 	DEFINE_FLAG(MF, NOLIFTDROP, AActor, flags),
 	DEFINE_FLAG(MF, STEALTH, AActor, flags),
 	DEFINE_FLAG(MF, ICECORPSE, AActor, flags),
+	DEFINE_FLAG(MF2, DONTREFLECT, AActor, flags2),
 	DEFINE_FLAG(MF2, WINDTHRUST, AActor, flags2),
 	DEFINE_FLAG(MF2, HERETICBOUNCE , AActor, flags2),
 	DEFINE_FLAG(MF2, BLASTED, AActor, flags2),