diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 5c0f7b3c78..ac1362295a 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,3 +1,20 @@
+December 25, 2009  (Changes by Graf Zahl)
+- Reintroduced Doom.exe's player_t::usedown variable so that respawning a
+  player does not immediately activate switches. oldbuttons was not usable
+  for this. This also required that CopyPlayer preserves this info.
+- Fixed: When restarting the music there was a NULL pointer check missing
+  so it crashed when the game was started wi
+- Fixed: If the Use key is used to respawn the player it must be cleared
+  so that it doesn't trigger any subsequent actions after respawning.
+- Fixed: Resurrecting a monster did not restore flags5 and flags6.
+- Fixed: Projectiles which killed a non-monster were unable to determine
+  what precisely they hit because MF_CORPSE is only valid for monsters.
+  A new flag, MF6_KILLED that gets set for all objects that die, was added
+  for this case.
+- Added a generic A_Weave function that exposes all possible options of
+  A_BishopMissileWeave and A_CStaffMissileSlither. These 2 functions are
+  no longer needed from DECORATE and therefore deprecated.
+
 December 24, 2009
 - The options menu no longer scales up so quickly, so it can fit wider text
   onscreen. In addition, it now uses the whole height available to it. Also,
diff --git a/src/actor.h b/src/actor.h
index 5a8acbfc8f..be6046f0e4 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -318,6 +318,7 @@ enum
 	MF6_LINEDONE		= 0x00008000,	// From MBF: Object has already run a line effect
 	MF6_NOTRIGGER		= 0x00010000,	// actor cannot trigger any line actions
 	MF6_SHATTERING		= 0x00020000,	// marks an ice corpse for forced shattering
+	MF6_KILLED			= 0x00040000,	// Something that was killed (but not necessarily a corpse)
 
 // --- mobj.renderflags ---
 
diff --git a/src/c_console.cpp b/src/c_console.cpp
index aafc76f364..324fad660c 100644
--- a/src/c_console.cpp
+++ b/src/c_console.cpp
@@ -81,7 +81,6 @@ static bool C_TabCompleteList ();
 static bool TabbedLast;		// True if last key pressed was tab
 static bool TabbedList;		// True if tab list was shown
 CVAR (Bool, con_notablist, false, CVAR_ARCHIVE)
-CVAR (Bool, con_ticker, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 
 static FTextureID conback;
 static DWORD conshade;
@@ -1105,23 +1104,17 @@ static void C_DrawNotifyText ()
 
 void C_InitTicker (const char *label, unsigned int max, bool showpercent)
 {
-	if (con_ticker)
-	{
-		TickerPercent = showpercent;
-		TickerMax = max;
-		TickerLabel = label;
-		TickerAt = 0;
-		maybedrawnow (true, false);
-	}
+	TickerPercent = showpercent;
+	TickerMax = max;
+	TickerLabel = label;
+	TickerAt = 0;
+	maybedrawnow (true, false);
 }
 
 void C_SetTicker (unsigned int at, bool forceUpdate)
 {
-	if (con_ticker)
-	{
-		TickerAt = at > TickerMax ? TickerMax : at;
-		maybedrawnow (true, TickerVisible ? forceUpdate : false);
-	}
+	TickerAt = at > TickerMax ? TickerMax : at;
+	maybedrawnow (true, TickerVisible ? forceUpdate : false);
 }
 
 void C_DrawConsole (bool hw2d)
diff --git a/src/d_player.h b/src/d_player.h
index b23d0616da..3c9ad954cb 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -276,6 +276,7 @@ public:
 	bool		centering;
 	BYTE		turnticks;
 	bool		attackdown;
+	bool		usedown;
 	DWORD		oldbuttons;
 	int			health;					// only used between levels, mo->health
 										// is used during levels
diff --git a/src/g_game.cpp b/src/g_game.cpp
index 2f3a62c070..dc576c2fcf 100644
--- a/src/g_game.cpp
+++ b/src/g_game.cpp
@@ -1316,7 +1316,7 @@ void G_PlayerReborn (int player)
 
     p->skill = b_skill;	//Added by MC:
 
-	p->oldbuttons = ~0, p->attackdown = true;	// don't do anything immediately
+	p->oldbuttons = ~0, p->attackdown = true; p->usedown = true;	// don't do anything immediately
 	p->original_oldbuttons = ~0;
 	p->playerstate = PST_LIVE;
 
diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp
index d4de94f600..68b5ce9d67 100644
--- a/src/g_hexen/a_bishop.cpp
+++ b/src/g_hexen/a_bishop.cpp
@@ -72,25 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
 
 DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
 {
-	fixed_t newX, newY;
-	int weaveXY, weaveZ;
-	int angle;
-
-	// since these values are now user configurable we have to do a proper range check to avoid array overflows.
-	weaveXY = self->WeaveIndexXY & 63;
-	weaveZ = self->WeaveIndexZ & 63;
-	angle = (self->angle + ANG90) >> ANGLETOFINESHIFT;
-	newX = self->x - FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
-	newY = self->y - FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
-	weaveXY = (weaveXY + 2) & 63;
-	newX += FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
-	newY += FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
-	P_TryMove (self, newX, newY, true);
-	self->z -= FloatBobOffsets[weaveZ];
-	weaveZ = (weaveZ + 2) & 63;
-	self->z += FloatBobOffsets[weaveZ];	
-	self->WeaveIndexXY = weaveXY;
-	self->WeaveIndexZ = weaveZ;
+	A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT);
 }
 
 //============================================================================
diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp
index a29d3afd6f..829e451276 100644
--- a/src/g_hexen/a_clericstaff.cpp
+++ b/src/g_hexen/a_clericstaff.cpp
@@ -153,20 +153,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
 
 DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
 {
-	fixed_t newX, newY;
-	int weaveXY;
-	int angle;
-
-	// since these values are now user configurable we have to do a proper range check to avoid array overflows.
-	weaveXY = self->WeaveIndexXY & 63;
-	angle = (self->angle+ANG90)>>ANGLETOFINESHIFT;
-	newX = self->x-FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]);
-	newY = self->y-FixedMul(finesine[angle], FloatBobOffsets[weaveXY]);
-	weaveXY = (weaveXY+3)&63;
-	newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]);
-	newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY]);
-	P_TryMove (self, newX, newY, true);
-	self->WeaveIndexXY = weaveXY;
+	A_Weave(self, 3, 0, FRACUNIT, 0);
 }
 
 //============================================================================
diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp
index a3fee85576..60302c6800 100644
--- a/src/g_hexen/a_hexenspecialdecs.cpp
+++ b/src/g_hexen/a_hexenspecialdecs.cpp
@@ -348,6 +348,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset2)
 {
 	self->flags |= MF_SHOOTABLE;
 	self->flags &= ~MF_CORPSE;
+	self->flags6 &= ~MF6_KILLED;
 	self->health = 5;
 }
 
diff --git a/src/p_enemy.h b/src/p_enemy.h
index a7386ccf5c..ce5703e73a 100644
--- a/src/p_enemy.h
+++ b/src/p_enemy.h
@@ -54,6 +54,7 @@ void P_NewChaseDir (AActor *actor);
 AInventory *P_DropItem (AActor *source, const PClass *type, int special, int chance);
 void P_TossItem (AActor *item);
 bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params);
+void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist);
 
 DECLARE_ACTION(A_Look)
 DECLARE_ACTION(A_Wander)
diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp
index 3b1521f8c6..075d978bc6 100644
--- a/src/p_interaction.cpp
+++ b/src/p_interaction.cpp
@@ -396,6 +396,8 @@ void AActor::Die (AActor *source, AActor *inflictor)
 		// be revived by an Arch-Vile. Batman Doom needs this.
 		flags |= MF_CORPSE;
 	}
+	flags6 |= MF6_KILLED;
+
 	// [RH] Allow the death height to be overridden using metadata.
 	fixed_t metaheight = 0;
 	if (DamageType == NAME_Fire)
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 496bd7587a..067ee62b46 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -1206,7 +1206,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
 	
 	FState *nextstate=NULL;
 	
-	if (target != NULL && target->flags & (MF_SHOOTABLE|MF_CORPSE))
+	if (target != NULL && ((target->flags & MF_SHOOTABLE) || (target->flags6 & MF6_KILLED)) )
 	{
 		if (target->flags & MF_NOBLOOD) nextstate = mo->FindState(NAME_Crash);
 		if (nextstate == NULL) nextstate = mo->FindState(NAME_Death, NAME_Extreme);
@@ -5472,7 +5472,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
 
 void AActor::Crash()
 {
-	if ((flags & MF_CORPSE) &&
+	if ((flags6 & MF6_KILLED) &&
 		!(flags3 & MF3_CRASHED) &&
 		!(flags & MF_ICECORPSE))
 	{
diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp
index d9ee189e59..5e9a18f9c6 100644
--- a/src/p_saveg.cpp
+++ b/src/p_saveg.cpp
@@ -244,6 +244,8 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
 	// needs to come from the save for bots.
 	userinfo_t uibackup = dst->userinfo;
 	int chasecam = dst->cheats & CF_CHASECAM;	// Remember the chasecam setting
+	bool attackdown = dst->attackdown;
+	bool usedown = dst->usedown;
 	*dst = *src;
 	dst->cheats |= chasecam;
 
@@ -270,6 +272,9 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
 	{
 		dst->mo->player = dst;
 	}
+	// These 2 variables may not be overwritten.
+	dst->attackdown = attackdown;
+	dst->usedown = usedown;
 }
 
 static void SpawnExtraPlayers ()
diff --git a/src/p_things.cpp b/src/p_things.cpp
index 0b166cdc3b..109b2d698b 100644
--- a/src/p_things.cpp
+++ b/src/p_things.cpp
@@ -466,6 +466,8 @@ bool P_Thing_Raise(AActor *thing)
 	thing->flags2 = info->flags2;
 	thing->flags3 = info->flags3;
 	thing->flags4 = info->flags4;
+	thing->flags5 = info->flags5;
+	thing->flags6 = info->flags6;
 	thing->health = info->health;
 	thing->target = NULL;
 	thing->lastenemy = NULL;
diff --git a/src/p_user.cpp b/src/p_user.cpp
index 6f951ad24c..9146b2bb69 100644
--- a/src/p_user.cpp
+++ b/src/p_user.cpp
@@ -222,6 +222,7 @@ player_t::player_t()
   centering(0),
   turnticks(0),
   attackdown(0),
+  usedown(0),
   oldbuttons(0),
   health(0),
   inventorytics(0),
@@ -2287,10 +2288,15 @@ void P_PlayerThink (player_t *player)
 			}
 		}
 		// check for use
-		if ((cmd->ucmd.buttons & BT_USE) && !(player->oldbuttons & BT_USE))
+		if ((cmd->ucmd.buttons & BT_USE) && !player->usedown)
 		{
+			player->usedown = true;
 			P_UseLines (player);
 		}
+		else
+		{
+			player->usedown = false;
+		}
 		// Morph counter
 		if (player->morphTics)
 		{
diff --git a/src/s_sound.cpp b/src/s_sound.cpp
index d63bd60e0b..8e5284f465 100644
--- a/src/s_sound.cpp
+++ b/src/s_sound.cpp
@@ -2307,6 +2307,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
 	}
 
 	if (!mus_playing.name.IsEmpty() &&
+		mus_playing.handle != NULL &&
 		stricmp (mus_playing.name, musicname) == 0 &&
 		mus_playing.handle->m_Looping == looping)
 	{
diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index 1c00e7ae55..2c3d3fe63a 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -3019,6 +3019,58 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake)
 	P_StartQuake(self, 0, intensity, duration, damrad, tremrad, sound);
 }
 
+//===========================================================================
+//
+// A_Weave
+//
+//===========================================================================
+
+void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist)
+{
+	fixed_t newX, newY;
+	int weaveXY, weaveZ;
+	int angle;
+	fixed_t dist;
+
+	weaveXY = self->WeaveIndexXY & 63;
+	weaveZ = self->WeaveIndexZ & 63;
+	angle = (self->angle + ANG90) >> ANGLETOFINESHIFT;
+
+	if (xydist != 0 && xyspeed != 0)
+	{
+		dist = FixedMul(FloatBobOffsets[weaveXY], xydist);
+		newX = self->x - FixedMul (finecosine[angle], dist);
+		newY = self->y - FixedMul (finesine[angle], dist);
+		weaveXY = (weaveXY + xyspeed) & 63;
+		dist = FixedMul(FloatBobOffsets[weaveXY], xydist);
+		newX += FixedMul (finecosine[angle], dist);
+		newY += FixedMul (finesine[angle], dist);
+		P_TryMove (self, newX, newY, true);
+		self->WeaveIndexXY = weaveXY;
+	}
+
+	if (zdist != 0 && zspeed != 0)
+	{
+		self->z -= FixedMul(FloatBobOffsets[weaveZ], zdist);
+		weaveZ = (weaveZ + zspeed) & 63;
+		self->z += FixedMul(FloatBobOffsets[weaveZ], zdist);
+		self->WeaveIndexZ = weaveZ;
+	}
+}
+
+DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Weave)
+{
+	ACTION_PARAM_START(4);
+	ACTION_PARAM_INT(xspeed, 0);
+	ACTION_PARAM_INT(yspeed, 1);
+	ACTION_PARAM_FIXED(xdist, 2);
+	ACTION_PARAM_FIXED(ydist, 3);
+	A_Weave(self, xspeed, yspeed, xdist, ydist);
+}
+
+
+
+
 //===========================================================================
 //
 // A_LineEffect