diff --git a/src/g_game.h b/src/g_game.h
index c8abe560c629a607f6e3d1f24895abfc3a281a64..26f60e12530856e265e2edca167821b53be25f85 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -18,6 +18,7 @@
 #include "doomstat.h"
 #include "d_event.h"
 #include "g_demo.h"
+#include "m_cheat.h" // objectplacing
 
 extern char gamedatafilename[64];
 extern char timeattackfolder[64];
@@ -64,7 +65,7 @@ typedef enum {
 	CS_STANDARD,
 	CS_SIMPLE = CS_LMAOGALOG|CS_STANDARD,
 } controlstyle_e;
-#define G_ControlStyle(ssplayer) (cv_directionchar[(ssplayer)-1].value == 3 ? CS_LMAOGALOG : ((cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0)))
+#define G_ControlStyle(ssplayer) (cv_directionchar[(ssplayer)-1].value == 3 ? CS_LMAOGALOG : ((!objectplacing && cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0)))
 #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
 
 extern consvar_t cv_autobrake, cv_autobrake2;
diff --git a/src/m_cheat.c b/src/m_cheat.c
index ab1454503be6ccf116f06bdb95288a7e8b504410..a3f6d3daf3eadb239bc32b3fce02662778352095 100644
--- a/src/m_cheat.c
+++ b/src/m_cheat.c
@@ -1023,8 +1023,8 @@ static void OP_CycleThings(INT32 amt)
 		states[S_OBJPLACE_DUMMY].frame = states[mobjinfo[op_currentthing].spawnstate].frame;
 	}
 	if (players[0].mo->eflags & MFE_VERTICALFLIP) // correct z when flipped
-		players[0].mo->z += players[0].mo->height - mobjinfo[op_currentthing].height;
-	players[0].mo->height = mobjinfo[op_currentthing].height;
+		players[0].mo->z += players[0].mo->height - FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale);
+	players[0].mo->height = FixedMul(mobjinfo[op_currentthing].height, players[0].mo->scale);
 	P_SetPlayerMobjState(players[0].mo, S_OBJPLACE_DUMMY);
 
 	op_currentdoomednum = mobjinfo[op_currentthing].doomednum;
@@ -1107,6 +1107,11 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
 	mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
 
 	mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
+	mt->scale = player->mo->scale;
+	mt->tag = 0;
+	memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
+	memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
+	mt->pitch = mt->roll = 0;
 	return mt;
 }
 
@@ -1297,27 +1302,26 @@ void OP_ObjectplaceMovement(player_t *player)
 {
 	ticcmd_t *cmd = &player->cmd;
 
-	if (!player->climbing && (netgame || !cv_analog[0].value || (player->pflags & PF_SPINNING)))
-		player->drawangle = player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */);
+	player->drawangle = player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */);
 
 	ticruned++;
 	if (!(cmd->angleturn & TICCMD_RECEIVED))
 		ticmiss++;
 
 	if (cmd->buttons & BT_JUMP)
-		player->mo->z += FRACUNIT*cv_speed.value;
+		player->mo->z += player->mo->scale*cv_speed.value;
 	else if (cmd->buttons & BT_SPIN)
-		player->mo->z -= FRACUNIT*cv_speed.value;
+		player->mo->z -= player->mo->scale*cv_speed.value;
 
 	if (cmd->forwardmove != 0)
 	{
-		P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*FRACUNIT/MAXPLMOVE)*cv_speed.value);
+		P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*player->mo->scale/MAXPLMOVE)*cv_speed.value);
 		P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
 		player->mo->momx = player->mo->momy = 0;
 	}
 	if (cmd->sidemove != 0)
 	{
-		P_Thrust(player->mo, player->mo->angle-ANGLE_90, (cmd->sidemove*FRACUNIT/MAXPLMOVE)*cv_speed.value);
+		P_Thrust(player->mo, player->mo->angle-ANGLE_90, (cmd->sidemove*player->mo->scale/MAXPLMOVE)*cv_speed.value);
 		P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
 		player->mo->momx = player->mo->momy = 0;
 	}
@@ -1443,62 +1447,75 @@ void Command_ObjectPlace_f(void)
 	G_SetGameModified(multiplayer);
 
 	// Entering objectplace?
-	if (!objectplacing)
+	if (!objectplacing || COM_Argc() > 1)
 	{
-		objectplacing = true;
-
-		if (players[0].powers[pw_carry] == CR_NIGHTSMODE)
-			return;
-
-		if (!COM_CheckParm("-silent"))
+		if (!objectplacing)
 		{
-			HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE|V_AUTOFADEOUT);
-			HU_SetCEchoDuration(10);
-			HU_DoCEcho(va(M_GetText(
-				"\\\\\\\\\\\\\\\\\\\\\\\\\x82"
-				"   Objectplace Controls:   \x80\\\\"
-				"Weapon Next/Prev: Cycle mapthings\\"
-				"            Jump: Float up       \\"
-				"            Spin: Float down     \\"
-				"       Fire Ring: Place object   \\")));
-		}
+			objectplacing = true;
 
-		// Save all the player's data.
-		op_oldflags1 = players[0].mo->flags;
-		op_oldflags2 = players[0].mo->flags2;
-		op_oldeflags = players[0].mo->eflags;
-		op_oldpflags = players[0].pflags;
-		op_oldmomx = players[0].mo->momx;
-		op_oldmomy = players[0].mo->momy;
-		op_oldmomz = players[0].mo->momz;
-		op_oldheight = players[0].mo->height;
-		op_oldstate = S_PLAY_STND;
-		op_oldcolor = players[0].mo->color; // save color too in case of super/fireflower
-
-		// Remove ALL flags and motion.
-		P_UnsetThingPosition(players[0].mo);
-		players[0].pflags = 0;
-		players[0].mo->flags2 = 0;
-		players[0].mo->eflags = 0;
-		players[0].mo->flags = (MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP);
-		players[0].mo->momx = players[0].mo->momy = players[0].mo->momz = 0;
-		P_SetThingPosition(players[0].mo);
+			if (players[0].powers[pw_carry] == CR_NIGHTSMODE)
+				return;
+
+			if (!COM_CheckParm("-silent"))
+			{
+				HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE|V_AUTOFADEOUT);
+				HU_SetCEchoDuration(10);
+				HU_DoCEcho(va(M_GetText(
+					"\\\\\\\\\\\\\\\\\\\\\\\\\x82"
+					"   Objectplace Controls:   \x80\\\\"
+					"Weapon Next/Prev: Cycle mapthings\\"
+					"            Jump: Float up       \\"
+					"            Spin: Float down     \\"
+					"       Fire Ring: Place object   \\")));
+			}
 
-		// Take away color so things display properly
-		players[0].mo->color = 0;
+			// Save all the player's data.
+			op_oldflags1 = players[0].mo->flags;
+			op_oldflags2 = players[0].mo->flags2;
+			op_oldeflags = players[0].mo->eflags;
+			op_oldpflags = players[0].pflags;
+			op_oldmomx = players[0].mo->momx;
+			op_oldmomy = players[0].mo->momy;
+			op_oldmomz = players[0].mo->momz;
+			op_oldheight = players[0].mo->height;
+			op_oldstate = S_PLAY_STND;
+			op_oldcolor = players[0].mo->color; // save color too in case of super/fireflower
+
+			// Remove ALL flags and motion.
+			P_UnsetThingPosition(players[0].mo);
+			players[0].pflags = 0;
+			players[0].mo->flags2 = 0;
+			players[0].mo->eflags = 0;
+			players[0].mo->flags = (MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP);
+			players[0].mo->momx = players[0].mo->momy = players[0].mo->momz = 0;
+			P_SetThingPosition(players[0].mo);
+
+			// Take away color so things display properly
+			players[0].mo->color = 0;
+
+			// Like the classics, recover from death by entering objectplace
+			if (players[0].mo->health <= 0)
+			{
+				players[0].mo->health = 1;
+				players[0].deadtimer = 0;
+				op_oldflags1 = mobjinfo[MT_PLAYER].flags;
+				++players[0].lives;
+				players[0].playerstate = PST_LIVE;
+				P_RestoreMusic(&players[0]);
+			}
+			else
+				op_oldstate = (statenum_t)(players[0].mo->state-states);
+		}
 
-		// Like the classics, recover from death by entering objectplace
-		if (players[0].mo->health <= 0)
+		if (COM_Argc() > 1)
 		{
-			players[0].mo->health = 1;
-			players[0].deadtimer = 0;
-			op_oldflags1 = mobjinfo[MT_PLAYER].flags;
-			++players[0].lives;
-			players[0].playerstate = PST_LIVE;
-			P_RestoreMusic(&players[0]);
+			UINT16 mapthingnum = atoi(COM_Argv(1));
+			mobjtype_t type = P_GetMobjtype(mapthingnum);
+			if (type == MT_UNKNOWN)
+				CONS_Printf(M_GetText("No mobj type delegated to thing type %d.\n"), mapthingnum);
+			else
+				op_currentthing = type;
 		}
-		else
-			op_oldstate = (statenum_t)(players[0].mo->state-states);
 
 		// If no thing set, then cycle a little
 		if (!op_currentthing)
@@ -1506,8 +1523,8 @@ void Command_ObjectPlace_f(void)
 			op_currentthing = 1;
 			OP_CycleThings(1);
 		}
-		else // Cycle things sets this for the former.
-			players[0].mo->height = mobjinfo[op_currentthing].height;
+		else
+			OP_CycleThings(0); // sets all necessary height values without cycling op_currentthing
 
 		P_SetPlayerMobjState(players[0].mo, S_OBJPLACE_DUMMY);
 	}
diff --git a/src/p_local.h b/src/p_local.h
index 4077fecf6b36c2aa880b6d6cfa7c3ab546682377..cf3a66e9dc30d68ca3745845be5d57f1e7e19c9b 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -274,6 +274,8 @@ extern tic_t itemrespawntime[ITEMQUESIZE];
 extern size_t iquehead, iquetail;
 extern consvar_t cv_gravity, cv_movebob;
 
+mobjtype_t P_GetMobjtype(UINT16 mthingtype);
+
 void P_RespawnSpecials(void);
 
 mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index fcba1f690d58e115de9b1c5c5305c6d2a3afc2c7..1e8fe02c1070708779c151fea774240bb0ae5e9f 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -11249,7 +11249,7 @@ void P_PrecipitationEffects(void)
  * \param mthingtype Mapthing number in question.
  * \return Mobj type; MT_UNKNOWN if nothing found.
  */
-static mobjtype_t P_GetMobjtype(UINT16 mthingtype)
+mobjtype_t P_GetMobjtype(UINT16 mthingtype)
 {
 	mobjtype_t i;
 	for (i = 0; i < NUMMOBJTYPES; i++)