예제 #1
0
void cProtocol125::SendSpawnMob(const cMonster & a_Mob)
{
	cCSLock Lock(m_CSPacket);
	WriteByte   (PACKET_SPAWN_MOB);
	WriteInt    (a_Mob.GetUniqueID());
	WriteByte   (a_Mob.GetMobType());
	WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
	WriteByte   (0);
	WriteByte   (0);
	WriteByte   (0);
	AString MetaData = GetEntityMetaData(a_Mob);
	SendData (MetaData.data(), MetaData.size());
	Flush();
}
예제 #2
0
void cProtocol125::SendSpawnMob(const cMonster & a_Mob)
{
	cCSLock Lock(m_CSPacket);
	WriteByte   (PACKET_SPAWN_MOB);
	WriteInt    (a_Mob.GetUniqueID());
	WriteByte   ((Byte)a_Mob.GetMobType());
	WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
	WriteByte   (0);
	WriteByte   (0);
	WriteByte   (0);

	WriteCommonMetadata(a_Mob);
	WriteMobMetadata(a_Mob);
	WriteByte(0x7f);

	Flush();
}
예제 #3
0
void cProtocol132::SendSpawnMob(const cMonster & a_Mob)
{
	cCSLock Lock(m_CSPacket);
	WriteByte   (PACKET_SPAWN_MOB);
	WriteInt    (a_Mob.GetUniqueID());
	WriteByte   (a_Mob.GetMobType());
	WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
	WriteByte   ((Byte)((a_Mob.GetRotation() / 360.f) * 256));
	WriteByte   ((Byte)((a_Mob.GetPitch() / 360.f) * 256));
	WriteByte   ((Byte)((a_Mob.GetHeadYaw() / 360.f) * 256));
	WriteShort  ((short)(a_Mob.GetSpeedX() * 400));
	WriteShort  ((short)(a_Mob.GetSpeedY() * 400));
	WriteShort  ((short)(a_Mob.GetSpeedZ() * 400));
	AString MetaData = GetEntityMetaData(a_Mob);
	SendData (MetaData.data(), MetaData.size());
	Flush();
}
예제 #4
0
void cProtocol132::SendSpawnMob(const cMonster & a_Mob)
{
	cCSLock Lock(m_CSPacket);
	WriteByte   (PACKET_SPAWN_MOB);
	WriteInt    (a_Mob.GetUniqueID());
	WriteByte   ((Byte)a_Mob.GetMobType());
	WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
	WriteByte   ((Byte)((a_Mob.GetYaw()     / 360.f) * 256));
	WriteByte   ((Byte)((a_Mob.GetPitch()   / 360.f) * 256));
	WriteByte   ((Byte)((a_Mob.GetHeadYaw() / 360.f) * 256));
	WriteShort  ((short)(a_Mob.GetSpeedX() * 400));
	WriteShort  ((short)(a_Mob.GetSpeedY() * 400));
	WriteShort  ((short)(a_Mob.GetSpeedZ() * 400));

	WriteCommonMetadata(a_Mob);
	WriteMobMetadata(a_Mob);
	WriteByte(0x7f);

	Flush();
}
예제 #5
0
void cProtocol_1_11_0::SendSpawnMob(const cMonster & a_Mob)
{
	ASSERT(m_State == 3);  // In game mode?

	cPacketizer Pkt(*this, GetPacketId(sendSpawnMob));  // Spawn Mob packet
	Pkt.WriteVarInt32(a_Mob.GetUniqueID());
	// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
	Pkt.WriteBEUInt64(0);
	Pkt.WriteBEUInt64(a_Mob.GetUniqueID());
	Pkt.WriteVarInt32(static_cast<UInt32>(a_Mob.GetMobType()));
	Pkt.WriteBEDouble(a_Mob.GetPosX());
	Pkt.WriteBEDouble(a_Mob.GetPosY());
	Pkt.WriteBEDouble(a_Mob.GetPosZ());
	Pkt.WriteByteAngle(a_Mob.GetPitch());
	Pkt.WriteByteAngle(a_Mob.GetHeadYaw());
	Pkt.WriteByteAngle(a_Mob.GetYaw());
	Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedX() * 400));
	Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedY() * 400));
	Pkt.WriteBEInt16(static_cast<Int16>(a_Mob.GetSpeedZ() * 400));
	WriteEntityMetadata(Pkt, a_Mob);
	Pkt.WriteBEUInt8(0xff);  // Metadata terminator
}
예제 #6
0
void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
{
	using namespace Metadata;

	// Living Enitiy Metadata
	if (a_Mob.HasCustomName())
	{
		// TODO: As of 1.9 _all_ entities can have custom names; should this be moved up?
		a_Pkt.WriteBEUInt8(ENTITY_CUSTOM_NAME);
		a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
		a_Pkt.WriteString(a_Mob.GetCustomName());

		a_Pkt.WriteBEUInt8(ENTITY_CUSTOM_NAME_VISIBLE);  // Custom name always visible
		a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
		a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible());
	}

	a_Pkt.WriteBEUInt8(LIVING_HEALTH);
	a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
	a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));

	switch (a_Mob.GetMobType())
	{
		case mtBat:
		{
			auto & Bat = reinterpret_cast<const cBat &>(a_Mob);
			a_Pkt.WriteBEUInt8(BAT_HANGING);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
			a_Pkt.WriteBEInt8(Bat.IsHanging() ? 1 : 0);
			break;
		}  // case mtBat

		case mtCreeper:
		{
			auto & Creeper = reinterpret_cast<const cCreeper &>(a_Mob);
			a_Pkt.WriteBEUInt8(CREEPER_STATE);  // (idle or "blowing")
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(Creeper.IsBlowing() ? 1 : static_cast<UInt32>(-1));

			a_Pkt.WriteBEUInt8(CREEPER_POWERED);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Creeper.IsCharged());

			a_Pkt.WriteBEUInt8(CREEPER_IGNITED);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Creeper.IsBurnedWithFlintAndSteel());
			break;
		}  // case mtCreeper

		case mtEnderman:
		{
			auto & Enderman = reinterpret_cast<const cEnderman &>(a_Mob);
			a_Pkt.WriteBEUInt8(ENDERMAN_CARRIED_BLOCK);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BLOCKID);
			UInt32 Carried = 0;
			Carried |= static_cast<UInt32>(Enderman.GetCarriedBlock() << 4);
			Carried |= Enderman.GetCarriedMeta();
			a_Pkt.WriteVarInt32(Carried);

			a_Pkt.WriteBEUInt8(ENDERMAN_SCREAMING);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Enderman.IsScreaming());
			break;
		}  // case mtEnderman

		case mtGhast:
		{
			auto & Ghast = reinterpret_cast<const cGhast &>(a_Mob);
			a_Pkt.WriteBEUInt8(GHAST_ATTACKING);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Ghast.IsCharging());
			break;
		}  // case mtGhast

		case mtHorse:
		{
			// XXX This behaves incorrectly with different varients; horses have different entity IDs now

			// Abstract horse
			auto & Horse = reinterpret_cast<const cHorse &>(a_Mob);
			Int8 Flags = 0;
			if (Horse.IsTame())
			{
				Flags |= 0x02;
			}
			if (Horse.IsSaddled())
			{
				Flags |= 0x04;
			}
			if (Horse.IsChested())
			{
				Flags |= 0x08;
			}
			if (Horse.IsEating())
			{
				Flags |= 0x20;
			}
			if (Horse.IsRearing())
			{
				Flags |= 0x40;
			}
			if (Horse.IsMthOpen())
			{
				Flags |= 0x80;
			}
			a_Pkt.WriteBEUInt8(ABSTRACT_HORSE_STATUS);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
			a_Pkt.WriteBEInt8(Flags);

			// This doesn't exist any more; it'll cause horses to all be the normal type
			// a_Pkt.WriteBEUInt8(HORSE_TYPE);
			// a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			// a_Pkt.WriteVarInt32(static_cast<UInt32>(Horse.GetHorseType()));

			// Regular horses
			a_Pkt.WriteBEUInt8(HORSE_VARIANT);  // Color / style
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			int Appearance = 0;
			Appearance = Horse.GetHorseColor();
			Appearance |= Horse.GetHorseStyle() << 8;
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Appearance));

			a_Pkt.WriteBEUInt8(HORSE_ARMOR);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Horse.GetHorseArmour()));

			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Horse.IsBaby());
			break;
		}  // case mtHorse

		case mtMagmaCube:
		{
			auto & MagmaCube = reinterpret_cast<const cMagmaCube &>(a_Mob);
			a_Pkt.WriteBEUInt8(SLIME_SIZE);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(MagmaCube.GetSize()));
			break;
		}  // case mtMagmaCube

		case mtOcelot:
		{
			auto & Ocelot = reinterpret_cast<const cOcelot &>(a_Mob);

			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Ocelot.IsBaby());

			Int8 OcelotStatus = 0;
			if (Ocelot.IsSitting())
			{
				OcelotStatus |= 0x1;
			}
			if (Ocelot.IsTame())
			{
				OcelotStatus |= 0x4;
			}
			a_Pkt.WriteBEUInt8(TAMEABLE_ANIMAL_STATUS);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
			a_Pkt.WriteBEInt8(OcelotStatus);

			a_Pkt.WriteBEUInt8(OCELOT_TYPE);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Ocelot.GetOcelotType()));

			break;
		}  // case mtOcelot

		case mtCow:
		{
			auto & Cow = reinterpret_cast<const cCow &>(a_Mob);

			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Cow.IsBaby());
			break;
		}  // case mtCow

		case mtChicken:
		{
			auto & Chicken = reinterpret_cast<const cChicken &>(a_Mob);

			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Chicken.IsBaby());
			break;
		}  // case mtChicken

		case mtPig:
		{
			auto & Pig = reinterpret_cast<const cPig &>(a_Mob);

			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Pig.IsBaby());

			a_Pkt.WriteBEUInt8(PIG_HAS_SADDLE);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Pig.IsSaddled());

			// PIG_TOTAL_CARROT_ON_A_STICK_BOOST in 1.11.1 only
			break;
		}  // case mtPig

		case mtSheep:
		{
			auto & Sheep = reinterpret_cast<const cSheep &>(a_Mob);

			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Sheep.IsBaby());

			a_Pkt.WriteBEUInt8(SHEEP_STATUS);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
			Int8 SheepMetadata = 0;
			SheepMetadata = static_cast<Int8>(Sheep.GetFurColor());
			if (Sheep.IsSheared())
			{
				SheepMetadata |= 0x10;
			}
			a_Pkt.WriteBEInt8(SheepMetadata);
			break;
		}  // case mtSheep

		case mtRabbit:
		{
			auto & Rabbit = reinterpret_cast<const cRabbit &>(a_Mob);
			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Rabbit.IsBaby());

			a_Pkt.WriteBEUInt8(RABBIT_TYPE);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Rabbit.GetRabbitType()));
			break;
		}  // case mtRabbit

		case mtSkeleton:
		{
			// XXX Skeletons are separate entities; all skeletons are currently treated as regular ones

			// auto & Skeleton = reinterpret_cast<const cSkeleton &>(a_Mob);
			// a_Pkt.WriteBEUInt8(SKELETON_TYPE);
			// a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			// a_Pkt.WriteVarInt32(Skeleton.IsWither() ? 1 : 0);
			break;
		}  // case mtSkeleton

		case mtSlime:
		{
			auto & Slime = reinterpret_cast<const cSlime &>(a_Mob);
			a_Pkt.WriteBEUInt8(SLIME_SIZE);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Slime.GetSize()));
			break;
		}  // case mtSlime

		case mtVillager:
		{
			auto & Villager = reinterpret_cast<const cVillager &>(a_Mob);
			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Villager.IsBaby());

			a_Pkt.WriteBEUInt8(VILLAGER_PROFESSION);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Villager.GetVilType()));
			break;
		}  // case mtVillager

		case mtWitch:
		{
			auto & Witch = reinterpret_cast<const cWitch &>(a_Mob);
			a_Pkt.WriteBEUInt8(WITCH_AGGRESIVE);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Witch.IsAngry());
			break;
		}  // case mtWitch

		case mtWither:
		{
			auto & Wither = reinterpret_cast<const cWither &>(a_Mob);
			a_Pkt.WriteBEUInt8(WITHER_INVULNERABLE_TIMER);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(Wither.GetWitherInvulnerableTicks());

			// TODO: Use boss bar packet for health
			break;
		}  // case mtWither

		case mtWolf:
		{
			auto & Wolf = reinterpret_cast<const cWolf &>(a_Mob);
			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Wolf.IsBaby());

			Int8 WolfStatus = 0;
			if (Wolf.IsSitting())
			{
				WolfStatus |= 0x1;
			}
			if (Wolf.IsAngry())
			{
				WolfStatus |= 0x2;
			}
			if (Wolf.IsTame())
			{
				WolfStatus |= 0x4;
			}
			a_Pkt.WriteBEUInt8(TAMEABLE_ANIMAL_STATUS);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
			a_Pkt.WriteBEInt8(WolfStatus);

			a_Pkt.WriteBEUInt8(WOLF_DAMAGE_TAKEN);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
			a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));  // TODO Not use the current health

			a_Pkt.WriteBEUInt8(WOLF_BEGGING);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Wolf.IsBegging());

			a_Pkt.WriteBEUInt8(WOLF_COLLAR_COLOR);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			a_Pkt.WriteVarInt32(static_cast<UInt32>(Wolf.GetCollarColor()));
			break;
		}  // case mtWolf

		case mtZombie:
		{
			// XXX Zombies were also split into new sublcasses; this doesn't handle that.
			auto & Zombie = reinterpret_cast<const cZombie &>(a_Mob);
			a_Pkt.WriteBEUInt8(ZOMBIE_IS_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(Zombie.IsBaby());

			// These don't exist
			// a_Pkt.WriteBEUInt8(ZOMBIE_TYPE);
			// a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
			// a_Pkt.WriteVarInt32(Zombie.IsVillagerZombie() ? 1 : 0);

			// a_Pkt.WriteBEUInt8(ZOMBIE_CONVERTING);
			// a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			// a_Pkt.WriteBool(Zombie.IsConverting());
			break;
		}  // case mtZombie

		case mtZombiePigman:
		{
			auto & ZombiePigman = reinterpret_cast<const cZombiePigman &>(a_Mob);
			a_Pkt.WriteBEUInt8(AGEABLE_BABY);
			a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
			a_Pkt.WriteBool(ZombiePigman.IsBaby());
			break;
		}  // case mtZombiePigman
	}  // switch (a_Mob.GetType())
}
예제 #7
0
void cProtocol125::WriteMobMetadata(const cMonster & a_Mob)
{
	switch (a_Mob.GetMobType())
	{
		case cMonster::mtCreeper:
		{
			WriteByte(0x10);
			WriteChar(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); // Blowing up?
			WriteByte(0x11);
			WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0); // Lightning-charged?
			break;
		}
		case cMonster::mtBat:
		{
			WriteByte(0x10);
			WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0); // Upside down?
			break;
		}
		case cMonster::mtPig:
		{
			WriteByte(0x10);
			WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0); // Saddled?
			break;
		}
		case cMonster::mtVillager:
		{
			WriteByte(0x50);
			WriteInt(((const cVillager &)a_Mob).GetVilType()); // What sort of TESTIFICATE?
			break;
		}
		case cMonster::mtZombie:
		{
			WriteByte(0xC);
			WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0); // Babby zombie?
			WriteByte(0xD);
			WriteByte(((const cZombie &)a_Mob).IsVillagerZombie() ? 1 : 0); // Converted zombie?
			WriteByte(0xE);
			WriteByte(((const cZombie &)a_Mob).IsConverting() ? 1 : 0); // Converted-but-converting-back zombllager?
			break;
		}
		case cMonster::mtGhast:
		{
			WriteByte(0x10);
			WriteByte(((const cGhast &)a_Mob).IsCharging()); // About to eject un flamé-bol? :P
			break;
		}
		case cMonster::mtWolf:
		{
			Byte WolfStatus = 0;
			if (((const cWolf &)a_Mob).IsSitting())
			{
				WolfStatus |= 0x1;
			}
			if (((const cWolf &)a_Mob).IsAngry())
			{
				WolfStatus |= 0x2;
			}
			if (((const cWolf &)a_Mob).IsTame())
			{
				WolfStatus |= 0x4;
			}
			WriteByte(0x10);
			WriteByte(WolfStatus);

			WriteByte(0x72);
			WriteFloat((float)(a_Mob.GetHealth())); // Tail health-o-meter (only shown when tamed, by the way)
			WriteByte(0x13);
			WriteByte(((const cWolf &)a_Mob).IsBegging() ? 1 : 0); // Ultra cute mode?
			break;
		}
		case cMonster::mtSheep:
		{
			// [1](1111)
			// [] = Is sheared? () = Color, from 0 to 15

			WriteByte(0x10);
			Byte SheepMetadata = 0;
			SheepMetadata = (Byte)((const cSheep &)a_Mob).GetFurColor();

			if (((const cSheep &)a_Mob).IsSheared())
			{
				SheepMetadata |= 0x16;
			}
			WriteByte(SheepMetadata);
			break;
		}
		case cMonster::mtEnderman:
		{
			WriteByte(0x10);
			WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); // Block that he stole from your house
			WriteByte(0x11);
			WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedMeta())); // Meta of block that he stole from your house
			WriteByte(0x12);
			WriteByte(((const cEnderman &)a_Mob).IsScreaming() ? 1 : 0); // Screaming at your face?
			break;
		}
		case cMonster::mtSkeleton:
		{
			WriteByte(0xD);
			WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0); // It's a skeleton, but it's not
			break;
		}
		case cMonster::mtWitch:
		{
			WriteByte(0x15);
			WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything
			break;
		}
		case cMonster::mtWither:
		{
			WriteByte(0x54); // Int at index 20
			WriteInt((Int32)((const cWither &)a_Mob).GetWitherInvulnerableTicks());
			WriteByte(0x66); // Float at index 6
			WriteFloat((float)(a_Mob.GetHealth()));
			break;
		}
		case cMonster::mtSlime:
		case cMonster::mtMagmaCube:
		{
			WriteByte(0x10);
			if (a_Mob.GetMobType() == cMonster::mtSlime)
			{
				WriteByte((Byte)((const cSlime &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME
			}
			else
			{
				WriteByte((Byte)((const cMagmaCube &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME
			}
			break;
		}
		case cMonster::mtHorse:
		{
			int Flags = 0;
			if (((const cHorse &)a_Mob).IsTame())
			{
				Flags |= 0x2;
			}
			if (((const cHorse &)a_Mob).IsSaddled())
			{
				Flags |= 0x4;
			}
			if (((const cHorse &)a_Mob).IsChested())
			{
				Flags |= 0x8;
			}
			if (((const cHorse &)a_Mob).IsBaby())
			{
				Flags |= 0x10; // IsBred flag, according to wiki.vg - don't think it does anything in multiplayer
			}
			if (((const cHorse &)a_Mob).IsEating())
			{
				Flags |= 0x20;
			}
			if (((const cHorse &)a_Mob).IsRearing())
			{
				Flags |= 0x40;
			}
			if (((const cHorse &)a_Mob).IsMthOpen())
			{
				Flags |= 0x80;
			}
			WriteByte(0x50);
			WriteInt(Flags);

			WriteByte(0x13);
			WriteByte((Byte)((const cHorse &)a_Mob).GetHorseType()); // Type of horse (donkey, chestnut, etc.)

			WriteByte(0x54);
			int Appearance = 0;
			Appearance = ((const cHorse &)a_Mob).GetHorseColor(); // Mask FF
			Appearance |= ((const cHorse &)a_Mob).GetHorseStyle() * 256; // Mask FF00, so multiply by 256
			WriteInt(Appearance);	

			WriteByte(0x56);
			WriteInt(((const cHorse &)a_Mob).GetHorseArmour()); // Horshey armour
			break;
		}
		default:
		{
			break;
		}
	}
}