ArmorStand Entity + Item

This commit is contained in:
ChristianFalegnami 2026-03-15 23:40:01 +01:00
parent 0bee09ecea
commit 60565f7a5e
49 changed files with 1127 additions and 141 deletions

View file

@ -0,0 +1,115 @@
#include "stdafx.h"
#include "ModelPart.h"
#include "ArmorStandModel.h"
#include "../Minecraft.World/ArmorStand.h"
ArmorStandModel::ArmorStandModel() : HumanoidModel()
{
texWidth = 64;
texHeight = 64;
head = new ModelPart(this, 0, 0);
head->addBox(-1.0F, -7.0F, -1.0F, 2, 7, 2, 0.0F);
head->setPos(0.0F, 1.0F, 0.0F);
head->compile(1.0f / 16.0f);
hair = new ModelPart(this, 0, 0);
body = new ModelPart(this, 0, 26);
body->addBox(-6.0F, 0.0F, -1.5F, 12, 3, 3, 0.0F);
body->setPos(0.0F, 0.0F, 0.0F);
body->compile(1.0f / 16.0f);
arm0 = new ModelPart(this, 24, 0); // right
arm0->addBox(-2.0F, -2.0F, -1.0F, 2, 12, 2, 0.0F);
arm0->setPos(-5.0F, 2.0F, 0.0F);
arm0->compile(1.0f / 16.0f);
arm1 = new ModelPart(this, 32, 16); // left
arm1->addBox(0.0F, -2.0F, -1.0F, 2, 12, 2, 0.0F);
arm1->setPos(5.0F, 2.0F, 0.0F);
arm1->compile(1.0f / 16.0f);
leg0 = new ModelPart(this, 8, 0); // right
leg0->addBox(-1.0F, 0.0F, -1.0F, 2, 11, 2, 0.0F);
leg0->setPos(-1.9F, 12.0F, 0.0F);
leg0->compile(1.0f / 16.0f);
leg1 = new ModelPart(this, 40, 16); // left
leg1->addBox(-1.0F, 0.0F, -1.0F, 2, 11, 2, 0.0F);
leg1->setPos(1.9F, 12.0F, 0.0F);
leg1->compile(1.0f / 16.0f);
//sticks
rightBodyStick = new ModelPart(this, 16, 0);
rightBodyStick->addBox(-3.0F, 3.0F, -1.0F, 2, 7, 2, 0.0F);
rightBodyStick->setPos(0.0F, 0.0F, 0.0F);
rightBodyStick->compile(1.0f / 16.0f);
leftBodyStick = new ModelPart(this, 48, 16);
leftBodyStick->addBox(1.0F, 3.0F, -1.0F, 2, 7, 2, 0.0F);
leftBodyStick->setPos(0.0F, 0.0F, 0.0F);
leftBodyStick->compile(1.0f / 16.0f);
shoulderStick = new ModelPart(this, 0, 48);
shoulderStick->addBox(-4.0F, 10.0F, -1.0F, 8, 2, 2, 0.0F);
shoulderStick->setPos(0.0F, 0.0F, 0.0F);
shoulderStick->compile(1.0f / 16.0f);
basePlate = new ModelPart(this, 0, 32);
basePlate->addBox(-6.0F, 11.0F, -6.0F, 12, 1, 12, 0.0F);
basePlate->setPos(0.0F, 12.0F, 0.0F);
basePlate->compile(1.0f / 16.0f);
}
void ArmorStandModel::setupPose(float hX, float hY, float hZ,
float bX, float bY, float bZ,
float lAX, float lAY, float lAZ,
float rAX, float rAY, float rAZ,
float lLX, float lLY, float lLZ,
float rLX, float rLY, float rLZ)
{
head->xRot = hX; head->yRot = hY; head->zRot = hZ;
body->xRot = bX; body->yRot = bY; body->zRot = bZ;
rightBodyStick->xRot = bX; rightBodyStick->yRot = bY; rightBodyStick->zRot = bZ;
leftBodyStick->xRot = bX; leftBodyStick->yRot = bY; leftBodyStick->zRot = bZ;
shoulderStick->xRot = bX; shoulderStick->yRot = bY; shoulderStick->zRot = bZ;
arm1->xRot = lAX; arm1->yRot = lAY; arm1->zRot = lAZ; // left
arm0->xRot = rAX; arm0->yRot = rAY; arm0->zRot = rAZ; // right
leg1->xRot = lLX; leg1->yRot = lLY; leg1->zRot = lLZ; // left
leg0->xRot = rLX; leg0->yRot = rLY; leg0->zRot = rLZ; // right
}
void ArmorStandModel::render(shared_ptr<Entity> entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled)
{
shared_ptr<ArmorStand> stand = dynamic_pointer_cast<ArmorStand>(entity);
if (stand) {
bool armsVisible = stand->showArms();
arm0->visible = armsVisible; // right
arm1->visible = armsVisible; // left
// basePlate->visible = stand->showBasePlate();
}
HumanoidModel::render(entity, time, r, bob, yRot, xRot, scale, usecompiled);
rightBodyStick->render(scale, usecompiled);
leftBodyStick->render(scale, usecompiled);
shoulderStick->render(scale, usecompiled);
basePlate->render(scale, usecompiled);
}
void ArmorStandModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr<Entity> entity, unsigned int uiBitmaskOverrideAnim)
{
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "HumanoidModel.h"
#include "ModelPart.h"
class ArmorStandModel : public HumanoidModel
{
public:
ModelPart *rightBodyStick;
ModelPart *leftBodyStick;
ModelPart *shoulderStick;
ModelPart *basePlate;
bool showArms;
bool showBasePlate;
bool isSmall;
ArmorStandModel();
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr<Entity> entity, unsigned int uiBitmaskOverrideAnim ) override;
void setupPose(float hX, float hY, float hZ,
float bX, float bY, float bZ,
float lAX, float lAY, float lAZ,
float rAX, float rAY, float rAZ,
float lLX, float lLY, float lLZ,
float rLX, float rLY, float rLZ);
virtual void render(shared_ptr<Entity> entity,
float time, float r, float bob,
float yRot, float xRot,
float scale, bool usecompiled) override;
};

View file

@ -0,0 +1,111 @@
#include "stdafx.h"
#include "ArmorStandRenderer.h"
#include "Textures.h"
#include "HumanoidModel.h"
#include "ArmorStandModel.h"
#include "..\Minecraft.World\ArmorStand.h"
class ArmorStandArmorModel : public HumanoidModel {
public:
ArmorStandArmorModel(float scale) : HumanoidModel(scale) {}
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr<Entity> entity, unsigned int uiBitmaskOverrideAnim = 0) override {
}
};
static const float DEG_TO_RAD = 3.14159265f / 180.0f;
ResourceLocation ArmorStandRenderer::LOC_ARMOR_STAND = ResourceLocation(TN_MOB_ARMORSTAND);
ArmorStandRenderer::ArmorStandRenderer()
: HumanoidMobRenderer(new ArmorStandModel(), 0.0f, 1.0f)
{
createArmorParts();
}
ResourceLocation *ArmorStandRenderer::getTextureLocation(shared_ptr<Entity> entity)
{
return &LOC_ARMOR_STAND;
}
void ArmorStandRenderer::createArmorParts()
{
armorParts1 = new ArmorStandArmorModel(1.0f);
armorParts2 = new ArmorStandArmorModel(0.5f);
}
void ArmorStandRenderer::render(shared_ptr<Entity> entity, double x, double y, double z, float rot, float a)
{
HumanoidMobRenderer::render(entity, x, y, z, rot, a);
}
void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale)
{
shared_ptr<ArmorStand> stand = dynamic_pointer_cast<ArmorStand>(mob);
if (!stand) return;
ArmorStandModel *m = static_cast<ArmorStandModel *>(model);
if (!m) return;
Rotations h = stand->getHeadPose();
Rotations b = stand->getBodyPose();
Rotations la = stand->getLeftArmPose();
Rotations ra = stand->getRightArmPose();
Rotations ll = stand->getLeftLegPose();
Rotations rl = stand->getRightLegPose();
m->setupPose(
h.x * DEG_TO_RAD, h.y * DEG_TO_RAD, h.z * DEG_TO_RAD,
b.x * DEG_TO_RAD, b.y * DEG_TO_RAD, b.z * DEG_TO_RAD,
la.x * DEG_TO_RAD, la.y * DEG_TO_RAD, la.z * DEG_TO_RAD,
ra.x * DEG_TO_RAD, ra.y * DEG_TO_RAD, ra.z * DEG_TO_RAD,
ll.x * DEG_TO_RAD, ll.y * DEG_TO_RAD, ll.z * DEG_TO_RAD,
rl.x * DEG_TO_RAD, rl.y * DEG_TO_RAD, rl.z * DEG_TO_RAD
);
HumanoidModel *a1 = static_cast<HumanoidModel*>(armorParts1);
if (a1) {
a1->head->xRot = h.x * DEG_TO_RAD; a1->head->yRot = h.y * DEG_TO_RAD; a1->head->zRot = h.z * DEG_TO_RAD;
if (a1->hair) { a1->hair->xRot = h.x * DEG_TO_RAD; a1->hair->yRot = h.y * DEG_TO_RAD; a1->hair->zRot = h.z * DEG_TO_RAD; }
a1->body->xRot = b.x * DEG_TO_RAD; a1->body->yRot = b.y * DEG_TO_RAD; a1->body->zRot = b.z * DEG_TO_RAD;
a1->arm0->xRot = ra.x * DEG_TO_RAD; a1->arm0->yRot = ra.y * DEG_TO_RAD; a1->arm0->zRot = ra.z * DEG_TO_RAD; // right
a1->arm1->xRot = la.x * DEG_TO_RAD; a1->arm1->yRot = la.y * DEG_TO_RAD; a1->arm1->zRot = la.z * DEG_TO_RAD; // left
a1->leg0->xRot = rl.x * DEG_TO_RAD; a1->leg0->yRot = rl.y * DEG_TO_RAD; a1->leg0->zRot = rl.z * DEG_TO_RAD; // right
a1->leg1->xRot = ll.x * DEG_TO_RAD; a1->leg1->yRot = ll.y * DEG_TO_RAD; a1->leg1->zRot = ll.z * DEG_TO_RAD; // left
}
HumanoidModel *a2 = static_cast<HumanoidModel*>(armorParts2);
if (a2) {
a2->head->xRot = h.x * DEG_TO_RAD; a2->head->yRot = h.y * DEG_TO_RAD; a2->head->zRot = h.z * DEG_TO_RAD;
if (a2->hair) { a2->hair->xRot = h.x * DEG_TO_RAD; a2->hair->yRot = h.y * DEG_TO_RAD; a2->hair->zRot = h.z * DEG_TO_RAD; }
a2->body->xRot = b.x * DEG_TO_RAD; a2->body->yRot = b.y * DEG_TO_RAD; a2->body->zRot = b.z * DEG_TO_RAD;
a2->arm0->xRot = ra.x * DEG_TO_RAD; a2->arm0->yRot = ra.y * DEG_TO_RAD; a2->arm0->zRot = ra.z * DEG_TO_RAD;
a2->arm1->xRot = la.x * DEG_TO_RAD; a2->arm1->yRot = la.y * DEG_TO_RAD; a2->arm1->zRot = la.z * DEG_TO_RAD;
a2->leg0->xRot = rl.x * DEG_TO_RAD; a2->leg0->yRot = rl.y * DEG_TO_RAD; a2->leg0->zRot = rl.z * DEG_TO_RAD;
a2->leg1->xRot = ll.x * DEG_TO_RAD; a2->leg1->yRot = ll.y * DEG_TO_RAD; a2->leg1->zRot = ll.z * DEG_TO_RAD;
}
HumanoidMobRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale);
}

View file

@ -0,0 +1,24 @@
#pragma once
#include "HumanoidMobRenderer.h"
#include "ArmorStandModel.h"
#include "..\Minecraft.World\ArmorStand.h"
class ArmorStandRenderer : public HumanoidMobRenderer
{
private:
static ResourceLocation LOC_ARMOR_STAND;
public:
ArmorStandRenderer();
virtual ~ArmorStandRenderer() {}
virtual void render(shared_ptr<Entity> entity, double x, double y, double z, float rot, float a) override;
virtual ResourceLocation *getTextureLocation(shared_ptr<Entity> entity) override;
protected:
virtual void createArmorParts() override;
virtual void renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale) override;
};

View file

@ -223,6 +223,14 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
// 4J-PB - Some sounds were updated, but we can't do that for the 360 or we have to do a new sound bank
// instead, we'll add the sounds as new ones and change the code to reference them
L"fire.new_ignite",
L"mob.rabbit.idle",
L"mob.rabbit.hurt",
L"mob.rabbit.bunnymurder",
L"mob.rabbit.hop",
};

View file

@ -548,6 +548,10 @@ void IUIScene_CreativeMenu::staticCtor()
ITEM(Item::horseArmorDiamond_Id)
ITEM(Item::horseArmorGold_Id)
ITEM(Item::horseArmorMetal_Id)
ITEM(Item::armor_stand_Id)
for(unsigned int i = 0; i < Enchantment::enchantments.length; ++i)
{
@ -1430,4 +1434,4 @@ void IUIScene_CreativeMenu::BuildFirework(vector<shared_ptr<ItemInstance> > *lis
}
list->push_back(firework);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

View file

@ -24,7 +24,6 @@
#include "PlayerRenderer.h"
#include "GhastRenderer.h"
#include "SquidRenderer.h"
#include "MobRenderer.h"
#include "GiantMobRenderer.h"
#include "EntityRenderer.h"
#include "PaintingRenderer.h"
@ -83,6 +82,8 @@
#include "BatRenderer.h"
#include "CaveSpiderRenderer.h"
#include "RabbitRenderer.h"
#include "ArmorStandRenderer.h"
#include "MobRenderer.h"
double EntityRenderDispatcher::xOff = 0.0;
double EntityRenderDispatcher::yOff = 0.0;
@ -170,6 +171,8 @@ EntityRenderDispatcher::EntityRenderDispatcher()
renderers[eTYPE_HORSE] = new HorseRenderer(new ModelHorse(), .75f);
renderers[eTYPE_LIGHTNINGBOLT] = new LightningBoltRenderer();
renderers[eTYPE_ARMORSTAND] = new ArmorStandRenderer();
glDisable(GL_LIGHTING);
for( auto& it : renderers )

View file

@ -67,6 +67,7 @@ void EntityTracker::addEntity(shared_ptr<Entity> e)
else if (e->instanceof(eTYPE_EXPERIENCEORB)) addEntity(e, 16 * 10, 20, true);
else if (e->instanceof(eTYPE_ENDER_CRYSTAL)) addEntity(e, 16 * 16, INT_MAX, false);
else if (e->instanceof(eTYPE_ITEM_FRAME)) addEntity(e, 16 * 10, INT_MAX, false);
else if (e->instanceof(eTYPE_ARMORSTAND)) addEntity(e, 16 * 4, 1, true);
}
void EntityTracker::addEntity(shared_ptr<Entity> e, int range, int updateInterval)

View file

@ -48,6 +48,7 @@ void LivingEntityRenderer::render(shared_ptr<Entity> _mob, double x, double y, d
{
return;
}
app.DebugPrintf("LivingEntityRenderer::render called for type %d\n", _mob->GetType());
glPushMatrix();
glDisable(GL_CULL_FACE);

View file

@ -5676,6 +5676,8 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|Xbox 360'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'">false</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="ArmorStandModel.h" />
<ClInclude Include="ArmorStandRenderer.h" />
<ClInclude Include="ArrowRenderer.h" />
<ClInclude Include="BatModel.h" />
<ClInclude Include="BatRenderer.h" />
@ -28417,6 +28419,8 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|Xbox 360'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="ArmorStandModel.cpp" />
<ClCompile Include="ArmorStandRenderer.cpp" />
<ClCompile Include="ArrowRenderer.cpp" />
<ClCompile Include="BatModel.cpp" />
<ClCompile Include="BatRenderer.cpp" />

View file

@ -3799,6 +3799,12 @@
<ClInclude Include="RabbitRenderer.h">
<Filter>net\minecraft\client\renderer\entity</Filter>
</ClInclude>
<ClInclude Include="ArmorStandModel.h">
<Filter>net\minecraft\client\model</Filter>
</ClInclude>
<ClInclude Include="ArmorStandRenderer.h">
<Filter>net\minecraft\client\renderer\entity</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -5961,6 +5967,12 @@
<ClCompile Include="RabbitRenderer.cpp">
<Filter>net\minecraft\client\renderer\entity</Filter>
</ClCompile>
<ClCompile Include="ArmorStandModel.cpp">
<Filter>net\minecraft\client\model</Filter>
</ClCompile>
<ClCompile Include="ArmorStandRenderer.cpp">
<Filter>net\minecraft\client\renderer\entity</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="Xbox\4JLibs\libs\4J_Render_d.lib">

View file

@ -542,7 +542,7 @@ void PreStitchedTextureMap::loadUVs()
//ADD_ICON(12, 5, L"unused")
//ADD_ICON(12, 6, L"unused")
ADD_ICON(12, 7, L"minecart_tnt")
//ADD_ICON(12, 8, L"unused")
ADD_ICON(12, 8, L"armorStand")
ADD_ICON(12, 9, L"fireworks")
ADD_ICON(12, 10, L"fireworks_charge")
ADD_ICON(12, 11, L"fireworks_charge_overlay")

View file

@ -169,6 +169,10 @@ const wchar_t *Textures::preLoaded[TN_COUNT] =
L"item/trapped",
L"item/trapped_double",
L"mob/armorstand/wood",
//L"item/christmas",
//L"item/christmas_double",

View file

@ -158,6 +158,8 @@ typedef enum _TEXTURE_NAME
TN_TILE_TRAP_CHEST,
TN_TILE_LARGE_TRAP_CHEST,
TN_MOB_ARMORSTAND,
//TN_TILE_XMAS_CHEST,
//TN_TILE_LARGE_XMAS_CHEST,

View file

@ -675,6 +675,11 @@ shared_ptr<Packet> TrackedEntity::getAddEntityPacket()
yHeadRotp = Mth::floor(e->getYHeadRot() * 256 / 360);
return std::make_shared<AddMobPacket>(dynamic_pointer_cast<LivingEntity>(e), yRotp, xRotp, xp, yp, zp, yHeadRotp);
}
else if (e->instanceof(eTYPE_ARMORSTAND))
{
yHeadRotp = Mth::floor(e->getYHeadRot() * 256 / 360);
return std::make_shared<AddMobPacket>(dynamic_pointer_cast<LivingEntity>(e), yRotp, xRotp, xp, yp, zp, yHeadRotp);
}
else if (e->instanceof(eTYPE_FISHINGHOOK))
{
shared_ptr<Entity> owner = dynamic_pointer_cast<FishingHook>(e)->owner;

View file

@ -8931,4 +8931,17 @@ All Ender Chests in a world are linked. Items placed into an Ender Chest are acc
<data name="IDS_ITEM_DOOR_DARK">
<value>Dark Oak Door</value>
</data>
<data name="IDS_ITEM_ARMOR_STAND">
<value>Armor Stand</value>
</data>
<data name="IDS_DESC_ARMOR_STAND">
<value>Can be equipped to display armor and other decorative items such as mob heads.</value>
</data>
<data name="IDS_RABBIT">
<value>Rabbit</value>
</data>
<data name="IDS_DESC_RABBIT">
<value>A harmless creature. May drop a rabbit hide or a rabbit's foot when killed.</value>
</data>
</root>

View file

@ -1,7 +1,7 @@
#pragma once
// Auto-generated by StringTable builder — do not edit manually.
// Source language: en-US
// Total strings: 2315
// Total strings: 2319
#define IDS_NULL 0
#define IDS_OK 1
@ -2194,127 +2194,131 @@
#define IDS_ITEM_DOOR_JUNGLE 2188
#define IDS_ITEM_DOOR_ACACIA 2189
#define IDS_ITEM_DOOR_DARK 2190
#define IDS_LANG_SYSTEM 2191
#define IDS_LANG_ENGLISH 2192
#define IDS_LANG_GERMAN 2193
#define IDS_LANG_SPANISH 2194
#define IDS_LANG_SPANISH_SPAIN 2195
#define IDS_LANG_SPANISH_LATIN_AMERICA 2196
#define IDS_LANG_FRENCH 2197
#define IDS_LANG_ITALIAN 2198
#define IDS_LANG_PORTUGUESE 2199
#define IDS_LANG_PORTUGUESE_PORTUGAL 2200
#define IDS_LANG_PORTUGUESE_BRAZIL 2201
#define IDS_LANG_JAPANESE 2202
#define IDS_LANG_KOREAN 2203
#define IDS_LANG_CHINESE_TRADITIONAL 2204
#define IDS_LANG_CHINESE_SIMPLIFIED 2205
#define IDS_LANG_DANISH 2206
#define IDS_LANG_FINISH 2207
#define IDS_LANG_DUTCH 2208
#define IDS_LANG_POLISH 2209
#define IDS_LANG_RUSSIAN 2210
#define IDS_LANG_SWEDISH 2211
#define IDS_LANG_NORWEGIAN 2212
#define IDS_LANG_GREEK 2213
#define IDS_LANG_TURKISH 2214
#define IDS_LEADERBOARD_KILLS_EASY 2215
#define IDS_LEADERBOARD_KILLS_NORMAL 2216
#define IDS_LEADERBOARD_KILLS_HARD 2217
#define IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL 2218
#define IDS_LEADERBOARD_MINING_BLOCKS_EASY 2219
#define IDS_LEADERBOARD_MINING_BLOCKS_NORMAL 2220
#define IDS_LEADERBOARD_MINING_BLOCKS_HARD 2221
#define IDS_LEADERBOARD_FARMING_PEACEFUL 2222
#define IDS_LEADERBOARD_FARMING_EASY 2223
#define IDS_LEADERBOARD_FARMING_NORMAL 2224
#define IDS_LEADERBOARD_FARMING_HARD 2225
#define IDS_LEADERBOARD_TRAVELLING_PEACEFUL 2226
#define IDS_LEADERBOARD_TRAVELLING_EASY 2227
#define IDS_LEADERBOARD_TRAVELLING_NORMAL 2228
#define IDS_LEADERBOARD_TRAVELLING_HARD 2229
#define IDS_TIPS_GAMETIP_0 2230
#define IDS_TIPS_GAMETIP_1 2231
#define IDS_TIPS_GAMETIP_48 2232
#define IDS_TIPS_GAMETIP_44 2233
#define IDS_TIPS_GAMETIP_45 2234
#define IDS_TIPS_TRIVIA_4 2235
#define IDS_TIPS_TRIVIA_17 2236
#define IDS_HOW_TO_PLAY_MULTIPLAYER 2237
#define IDS_HOW_TO_PLAY_SOCIALMEDIA 2238
#define IDS_HOW_TO_PLAY_CREATIVE 2239
#define IDS_TUTORIAL_TASK_FLY 2240
#define IDS_TOOLTIPS_SELECTDEVICE 2241
#define IDS_TOOLTIPS_CHANGEDEVICE 2242
#define IDS_TOOLTIPS_VIEW_GAMERCARD 2243
#define IDS_TOOLTIPS_VIEW_GAMERPROFILE 2244
#define IDS_TOOLTIPS_INVITE_PARTY 2245
#define IDS_CONFIRM_START_CREATIVE 2246
#define IDS_CONFIRM_START_SAVEDINCREATIVE 2247
#define IDS_CONFIRM_START_SAVEDINCREATIVE_CONTINUE 2248
#define IDS_CONFIRM_START_HOST_PRIVILEGES 2249
#define IDS_CONNECTION_LOST_LIVE 2250
#define IDS_CONNECTION_LOST_LIVE_NO_EXIT 2251
#define IDS_AWARD_AVATAR1 2252
#define IDS_AWARD_AVATAR2 2253
#define IDS_AWARD_AVATAR3 2254
#define IDS_AWARD_THEME 2255
#define IDS_UNLOCK_ACHIEVEMENT_TEXT 2256
#define IDS_UNLOCK_AVATAR_TEXT 2257
#define IDS_UNLOCK_GAMERPIC_TEXT 2258
#define IDS_UNLOCK_THEME_TEXT 2259
#define IDS_UNLOCK_ACCEPT_INVITE 2260
#define IDS_UNLOCK_GUEST_TEXT 2261
#define IDS_LEADERBOARD_GAMERTAG 2262
#define IDS_GROUPNAME_POTIONS_480 2263
#define IDS_RETURNEDTOTITLESCREEN_TEXT 2264
#define IDS_TRIALOVER_TEXT 2265
#define IDS_FATAL_ERROR_TEXT 2266
#define IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT 2267
#define IDS_NO_MULTIPLAYER_PRIVILEGE_HOST_TEXT 2268
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL 2269
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL 2270
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE 2271
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE 2272
#define IDS_SAVE_ICON_MESSAGE 2273
#define IDS_GAMEOPTION_HOST_PRIVILEGES 2274
#define IDS_CHECKBOX_DISPLAY_SPLITSCREENGAMERTAGS 2275
#define IDS_ACHIEVEMENTS 2276
#define IDS_LABEL_GAMERTAGS 2277
#define IDS_IN_GAME_GAMERTAGS 2278
#define IDS_SOCIAL_DEFAULT_DESCRIPTION 2279
#define IDS_TITLE_UPDATE_NAME 2280
#define IDS_PLATFORM_NAME 2281
#define IDS_BACK_BUTTON 2282
#define IDS_HOST_OPTION_DISABLES_ACHIEVEMENTS 2283
#define IDS_KICK_PLAYER_DESCRIPTION 2284
#define IDS_USING_TRIAL_TEXUREPACK_WARNING 2285
#define IDS_WORLD_SIZE_TITLE_SMALL 2286
#define IDS_WORLD_SIZE_TITLE_MEDIUM 2287
#define IDS_WORLD_SIZE_TITLE_LARGE 2288
#define IDS_WORLD_SIZE_TITLE_CLASSIC 2289
#define IDS_WORLD_SIZE 2290
#define IDS_GAMEOPTION_WORLD_SIZE 2291
#define IDS_DISABLE_SAVING 2292
#define IDS_GAMEOPTION_DISABLE_SAVING 2293
#define IDS_RICHPRESENCE_GAMESTATE 2294
#define IDS_RICHPRESENCE_IDLE 2295
#define IDS_RICHPRESENCE_MENUS 2296
#define IDS_RICHPRESENCE_MULTIPLAYER 2297
#define IDS_RICHPRESENCE_MULTIPLAYEROFFLINE 2298
#define IDS_RICHPRESENCE_MULTIPLAYER_1P 2299
#define IDS_RICHPRESENCE_MULTIPLAYER_1POFFLINE 2300
#define IDS_RICHPRESENCESTATE_BLANK 2301
#define IDS_RICHPRESENCESTATE_RIDING_PIG 2302
#define IDS_RICHPRESENCESTATE_RIDING_MINECART 2303
#define IDS_RICHPRESENCESTATE_BOATING 2304
#define IDS_RICHPRESENCESTATE_FISHING 2305
#define IDS_RICHPRESENCESTATE_CRAFTING 2306
#define IDS_RICHPRESENCESTATE_FORGING 2307
#define IDS_RICHPRESENCESTATE_NETHER 2308
#define IDS_RICHPRESENCESTATE_CD 2309
#define IDS_RICHPRESENCESTATE_MAP 2310
#define IDS_RICHPRESENCESTATE_ENCHANTING 2311
#define IDS_RICHPRESENCESTATE_BREWING 2312
#define IDS_RICHPRESENCESTATE_ANVIL 2313
#define IDS_RICHPRESENCESTATE_TRADING 2314
#define IDS_ITEM_ARMOR_STAND 2191
#define IDS_DESC_ARMOR_STAND 2192
#define IDS_RABBIT 2193
#define IDS_DESC_RABBIT 2194
#define IDS_LANG_SYSTEM 2195
#define IDS_LANG_ENGLISH 2196
#define IDS_LANG_GERMAN 2197
#define IDS_LANG_SPANISH 2198
#define IDS_LANG_SPANISH_SPAIN 2199
#define IDS_LANG_SPANISH_LATIN_AMERICA 2200
#define IDS_LANG_FRENCH 2201
#define IDS_LANG_ITALIAN 2202
#define IDS_LANG_PORTUGUESE 2203
#define IDS_LANG_PORTUGUESE_PORTUGAL 2204
#define IDS_LANG_PORTUGUESE_BRAZIL 2205
#define IDS_LANG_JAPANESE 2206
#define IDS_LANG_KOREAN 2207
#define IDS_LANG_CHINESE_TRADITIONAL 2208
#define IDS_LANG_CHINESE_SIMPLIFIED 2209
#define IDS_LANG_DANISH 2210
#define IDS_LANG_FINISH 2211
#define IDS_LANG_DUTCH 2212
#define IDS_LANG_POLISH 2213
#define IDS_LANG_RUSSIAN 2214
#define IDS_LANG_SWEDISH 2215
#define IDS_LANG_NORWEGIAN 2216
#define IDS_LANG_GREEK 2217
#define IDS_LANG_TURKISH 2218
#define IDS_LEADERBOARD_KILLS_EASY 2219
#define IDS_LEADERBOARD_KILLS_NORMAL 2220
#define IDS_LEADERBOARD_KILLS_HARD 2221
#define IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL 2222
#define IDS_LEADERBOARD_MINING_BLOCKS_EASY 2223
#define IDS_LEADERBOARD_MINING_BLOCKS_NORMAL 2224
#define IDS_LEADERBOARD_MINING_BLOCKS_HARD 2225
#define IDS_LEADERBOARD_FARMING_PEACEFUL 2226
#define IDS_LEADERBOARD_FARMING_EASY 2227
#define IDS_LEADERBOARD_FARMING_NORMAL 2228
#define IDS_LEADERBOARD_FARMING_HARD 2229
#define IDS_LEADERBOARD_TRAVELLING_PEACEFUL 2230
#define IDS_LEADERBOARD_TRAVELLING_EASY 2231
#define IDS_LEADERBOARD_TRAVELLING_NORMAL 2232
#define IDS_LEADERBOARD_TRAVELLING_HARD 2233
#define IDS_TIPS_GAMETIP_0 2234
#define IDS_TIPS_GAMETIP_1 2235
#define IDS_TIPS_GAMETIP_48 2236
#define IDS_TIPS_GAMETIP_44 2237
#define IDS_TIPS_GAMETIP_45 2238
#define IDS_TIPS_TRIVIA_4 2239
#define IDS_TIPS_TRIVIA_17 2240
#define IDS_HOW_TO_PLAY_MULTIPLAYER 2241
#define IDS_HOW_TO_PLAY_SOCIALMEDIA 2242
#define IDS_HOW_TO_PLAY_CREATIVE 2243
#define IDS_TUTORIAL_TASK_FLY 2244
#define IDS_TOOLTIPS_SELECTDEVICE 2245
#define IDS_TOOLTIPS_CHANGEDEVICE 2246
#define IDS_TOOLTIPS_VIEW_GAMERCARD 2247
#define IDS_TOOLTIPS_VIEW_GAMERPROFILE 2248
#define IDS_TOOLTIPS_INVITE_PARTY 2249
#define IDS_CONFIRM_START_CREATIVE 2250
#define IDS_CONFIRM_START_SAVEDINCREATIVE 2251
#define IDS_CONFIRM_START_SAVEDINCREATIVE_CONTINUE 2252
#define IDS_CONFIRM_START_HOST_PRIVILEGES 2253
#define IDS_CONNECTION_LOST_LIVE 2254
#define IDS_CONNECTION_LOST_LIVE_NO_EXIT 2255
#define IDS_AWARD_AVATAR1 2256
#define IDS_AWARD_AVATAR2 2257
#define IDS_AWARD_AVATAR3 2258
#define IDS_AWARD_THEME 2259
#define IDS_UNLOCK_ACHIEVEMENT_TEXT 2260
#define IDS_UNLOCK_AVATAR_TEXT 2261
#define IDS_UNLOCK_GAMERPIC_TEXT 2262
#define IDS_UNLOCK_THEME_TEXT 2263
#define IDS_UNLOCK_ACCEPT_INVITE 2264
#define IDS_UNLOCK_GUEST_TEXT 2265
#define IDS_LEADERBOARD_GAMERTAG 2266
#define IDS_GROUPNAME_POTIONS_480 2267
#define IDS_RETURNEDTOTITLESCREEN_TEXT 2268
#define IDS_TRIALOVER_TEXT 2269
#define IDS_FATAL_ERROR_TEXT 2270
#define IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT 2271
#define IDS_NO_MULTIPLAYER_PRIVILEGE_HOST_TEXT 2272
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL 2273
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL 2274
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE 2275
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE 2276
#define IDS_SAVE_ICON_MESSAGE 2277
#define IDS_GAMEOPTION_HOST_PRIVILEGES 2278
#define IDS_CHECKBOX_DISPLAY_SPLITSCREENGAMERTAGS 2279
#define IDS_ACHIEVEMENTS 2280
#define IDS_LABEL_GAMERTAGS 2281
#define IDS_IN_GAME_GAMERTAGS 2282
#define IDS_SOCIAL_DEFAULT_DESCRIPTION 2283
#define IDS_TITLE_UPDATE_NAME 2284
#define IDS_PLATFORM_NAME 2285
#define IDS_BACK_BUTTON 2286
#define IDS_HOST_OPTION_DISABLES_ACHIEVEMENTS 2287
#define IDS_KICK_PLAYER_DESCRIPTION 2288
#define IDS_USING_TRIAL_TEXUREPACK_WARNING 2289
#define IDS_WORLD_SIZE_TITLE_SMALL 2290
#define IDS_WORLD_SIZE_TITLE_MEDIUM 2291
#define IDS_WORLD_SIZE_TITLE_LARGE 2292
#define IDS_WORLD_SIZE_TITLE_CLASSIC 2293
#define IDS_WORLD_SIZE 2294
#define IDS_GAMEOPTION_WORLD_SIZE 2295
#define IDS_DISABLE_SAVING 2296
#define IDS_GAMEOPTION_DISABLE_SAVING 2297
#define IDS_RICHPRESENCE_GAMESTATE 2298
#define IDS_RICHPRESENCE_IDLE 2299
#define IDS_RICHPRESENCE_MENUS 2300
#define IDS_RICHPRESENCE_MULTIPLAYER 2301
#define IDS_RICHPRESENCE_MULTIPLAYEROFFLINE 2302
#define IDS_RICHPRESENCE_MULTIPLAYER_1P 2303
#define IDS_RICHPRESENCE_MULTIPLAYER_1POFFLINE 2304
#define IDS_RICHPRESENCESTATE_BLANK 2305
#define IDS_RICHPRESENCESTATE_RIDING_PIG 2306
#define IDS_RICHPRESENCESTATE_RIDING_MINECART 2307
#define IDS_RICHPRESENCESTATE_BOATING 2308
#define IDS_RICHPRESENCESTATE_FISHING 2309
#define IDS_RICHPRESENCESTATE_CRAFTING 2310
#define IDS_RICHPRESENCESTATE_FORGING 2311
#define IDS_RICHPRESENCESTATE_NETHER 2312
#define IDS_RICHPRESENCESTATE_CD 2313
#define IDS_RICHPRESENCESTATE_MAP 2314
#define IDS_RICHPRESENCESTATE_ENCHANTING 2315
#define IDS_RICHPRESENCESTATE_BREWING 2316
#define IDS_RICHPRESENCESTATE_ANVIL 2317
#define IDS_RICHPRESENCESTATE_TRADING 2318

View file

@ -0,0 +1,392 @@
#include "stdafx.h"
#include "com.mojang.nbt.h"
#include "net.minecraft.world.entity.ai.attributes.h"
#include "net.minecraft.world.entity.ai.navigation.h"
#include "net.minecraft.world.entity.ai.goal.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.item.h"
#include "net.minecraft.world.entity.player.h"
#include "net.minecraft.world.damagesource.h"
#include "SynchedEntityData.h"
#include "SharedMonsterAttributes.h"
#include "ArmorStand.h"
#include "..\Minecraft.Client\Textures.h"
#include "MobCategory.h"
const Rotations ArmorStand::DEFAULT_HEAD_POSE ( 0, 0, 0);
const Rotations ArmorStand::DEFAULT_BODY_POSE ( 0, 0, 0);
const Rotations ArmorStand::DEFAULT_LEFT_ARM_POSE (-10, 0,-10);
const Rotations ArmorStand::DEFAULT_RIGHT_ARM_POSE (-15, 0, 10);
const Rotations ArmorStand::DEFAULT_LEFT_LEG_POSE ( -1, 0, -1);
const Rotations ArmorStand::DEFAULT_RIGHT_LEG_POSE ( 1, 0, 1);
ArmorStand::ArmorStand(Level *level)
: Mob(level)
{
lastHit = 0;
disabledSlots = 0;
invisible = false;
for (int i = 0; i < 5; i++) {
equipment[i] = nullptr;
}
this->defineSynchedData();
registerAttributes();
setHealth(getMaxHealth());
this->setSize(0.5f, 1.975f);
}
void ArmorStand::registerAttributes()
{
LivingEntity::registerAttributes();
getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(20.0);
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.0);
getAttribute(SharedMonsterAttributes::KNOCKBACK_RESISTANCE)->setBaseValue(1.0);
}
void ArmorStand::defineSynchedData()
{
LivingEntity::defineSynchedData();
entityData->define(DATA_CLIENT_FLAGS, static_cast<byte>(0));
entityData->define(DATA_HEAD_POSE_X, DEFAULT_HEAD_POSE.x);
entityData->define(DATA_HEAD_POSE_Y, DEFAULT_HEAD_POSE.y);
entityData->define(DATA_HEAD_POSE_Z, DEFAULT_HEAD_POSE.z);
entityData->define(DATA_BODY_POSE_X, DEFAULT_BODY_POSE.x);
entityData->define(DATA_BODY_POSE_Y, DEFAULT_BODY_POSE.y);
entityData->define(DATA_BODY_POSE_Z, DEFAULT_BODY_POSE.z);
entityData->define(DATA_LEFT_ARM_X, DEFAULT_LEFT_ARM_POSE.x);
entityData->define(DATA_LEFT_ARM_Y, DEFAULT_LEFT_ARM_POSE.y);
entityData->define(DATA_LEFT_ARM_Z, DEFAULT_LEFT_ARM_POSE.z);
entityData->define(DATA_RIGHT_ARM_X, DEFAULT_RIGHT_ARM_POSE.x);
entityData->define(DATA_RIGHT_ARM_Y, DEFAULT_RIGHT_ARM_POSE.y);
entityData->define(DATA_RIGHT_ARM_Z, DEFAULT_RIGHT_ARM_POSE.z);
entityData->define(DATA_LEFT_LEG_X, DEFAULT_LEFT_LEG_POSE.x);
entityData->define(DATA_LEFT_LEG_Y, DEFAULT_LEFT_LEG_POSE.y);
entityData->define(DATA_LEFT_LEG_Z, DEFAULT_LEFT_LEG_POSE.z);
entityData->define(DATA_RIGHT_LEG_X, DEFAULT_RIGHT_LEG_POSE.x);
entityData->define(DATA_RIGHT_LEG_Y, DEFAULT_RIGHT_LEG_POSE.y);
entityData->define(DATA_RIGHT_LEG_Z, DEFAULT_RIGHT_LEG_POSE.z);
}
void ArmorStand::tick()
{
float lockedRot = this->yRot;
LivingEntity::tick();
this->yRot = lockedRot;
this->yRotO = lockedRot;
this->yBodyRot = lockedRot;
this->yBodyRotO = lockedRot;
this->yHeadRot = lockedRot;
this->yHeadRotO = lockedRot;
}
bool ArmorStand::interact(shared_ptr<Player> player)
{
if (level->isClientSide) return true;
if (isMarker()) return false;
float dX = this->x - player->x;
float dZ = this->z - player->z;
float distHoriz = sqrt(dX * dX + dZ * dZ);
float pitchRad = player->xRot * (3.14159265f / 180.0f);
float lookYDiff = -tan(pitchRad) * distHoriz;
float hitY = (player->y + 1.62f + lookYDiff) - this->y;
int targetSlot = SLOT_WEAPON;
if (hitY >= 0.1f && hitY < 0.55f) {
targetSlot = SLOT_BOOTS;
} else if (hitY >= 0.55f && hitY < 0.9f) {
targetSlot = SLOT_LEGGINGS;
} else if (hitY >= 0.9f && hitY < 1.6f) {
targetSlot = SLOT_CHEST;
} else if (hitY >= 1.6f) {
targetSlot = SLOT_HELM;
}
shared_ptr<ItemInstance> playerItem = player->getCarriedItem();
if (playerItem != nullptr) {
int correctSlot = getEquipmentSlotForItem(playerItem);
if (isSlotDisabled(correctSlot)) return false;
shared_ptr<ItemInstance> standItem = getItemInSlot(correctSlot);
if (standItem != nullptr) {
bool added = player->inventory->add(standItem);
if (!added) spawnAtLocation(standItem, 0.0f);
}
shared_ptr<ItemInstance> toPlace = ItemInstance::clone(playerItem);
toPlace->count = 1;
setEquippedSlot(correctSlot, toPlace);
playerItem->remove(1);
return true;
} else {
shared_ptr<ItemInstance> standItem = getItemInSlot(targetSlot);
if (standItem != nullptr) {
bool added = player->inventory->add(standItem);
if (!added) spawnAtLocation(standItem, 0.0f);
setEquippedSlot(targetSlot, nullptr);
return true;
}
}
return false;
}
bool ArmorStand::hurt(DamageSource *source, float damage)
{
if (isInvulnerable()) return false;
if (level->isClientSide || removed) return false;
if (isMarker()) return false;
if (dynamic_cast<EntityDamageSource *>(source) != nullptr)
{
shared_ptr<Entity> attacker = source->getEntity();
if (attacker != nullptr && attacker->instanceof(eTYPE_PLAYER))
{
shared_ptr<Player> player = dynamic_pointer_cast<Player>(attacker);
if (player->abilities.instabuild)
{
remove();
return true;
}
}
}
long long now = (long long)tickCount;
if (now - lastHit > 5)
{
level->broadcastEntityEvent(shared_from_this(), (byte)32);
lastHit = now;
}
else
{
remove();
spawnAtLocation(Item::armor_stand_Id, 1);
for (int i = 0; i < 5; i++) {
if (equipment[i] != nullptr) {
spawnAtLocation(equipment[i], 0.0f);
}
}
}
return true;
}
bool ArmorStand::isPickable()
{
return !removed && !isMarker();
}
void ArmorStand::handleEntityEvent(byte eventId)
{
if (eventId == 32)
lastHit = (long long)tickCount;
else
LivingEntity::handleEntityEvent(eventId);
}
byte ArmorStand::setBit(byte oldBit, int offset, bool value)
{
if (value) oldBit = (byte)(oldBit | offset);
else oldBit = (byte)(oldBit & ~offset);
return oldBit;
}
bool ArmorStand::isSmall() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_SMALL) != 0; }
bool ArmorStand::showArms() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_SHOW_ARMS) != 0; }
bool ArmorStand::showBasePlate() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_NO_BASEPLATE) == 0; }
bool ArmorStand::isMarker() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_MARKER) != 0; }
void ArmorStand::setSmall(bool v) { entityData->set(DATA_CLIENT_FLAGS, setBit(entityData->getByte(DATA_CLIENT_FLAGS), FLAG_SMALL, v)); }
void ArmorStand::setShowArms(bool v) { entityData->set(DATA_CLIENT_FLAGS, setBit(entityData->getByte(DATA_CLIENT_FLAGS), FLAG_SHOW_ARMS, v)); }
void ArmorStand::setNoBasePlate(bool v) { entityData->set(DATA_CLIENT_FLAGS, setBit(entityData->getByte(DATA_CLIENT_FLAGS), FLAG_NO_BASEPLATE, v)); }
void ArmorStand::setMarker(bool v) { entityData->set(DATA_CLIENT_FLAGS, setBit(entityData->getByte(DATA_CLIENT_FLAGS), FLAG_MARKER, v)); }
Rotations ArmorStand::readRotation(int slotX) const
{
return Rotations(
entityData->getFloat(slotX),
entityData->getFloat(slotX + 1),
entityData->getFloat(slotX + 2)
);
}
void ArmorStand::writeRotation(int slotX, const Rotations &r)
{
entityData->set(slotX, r.x);
entityData->set(slotX + 1, r.y);
entityData->set(slotX + 2, r.z);
}
Rotations ArmorStand::getHeadPose() const { return readRotation(DATA_HEAD_POSE_X); }
Rotations ArmorStand::getBodyPose() const { return readRotation(DATA_BODY_POSE_X); }
Rotations ArmorStand::getLeftArmPose() const { return readRotation(DATA_LEFT_ARM_X); }
Rotations ArmorStand::getRightArmPose() const { return readRotation(DATA_RIGHT_ARM_X); }
Rotations ArmorStand::getLeftLegPose() const { return readRotation(DATA_LEFT_LEG_X); }
Rotations ArmorStand::getRightLegPose() const { return readRotation(DATA_RIGHT_LEG_X); }
void ArmorStand::setHeadPose (const Rotations &r) { writeRotation(DATA_HEAD_POSE_X, r); }
void ArmorStand::setBodyPose (const Rotations &r) { writeRotation(DATA_BODY_POSE_X, r); }
void ArmorStand::setLeftArmPose (const Rotations &r) { writeRotation(DATA_LEFT_ARM_X, r); }
void ArmorStand::setRightArmPose(const Rotations &r) { writeRotation(DATA_RIGHT_ARM_X, r); }
void ArmorStand::setLeftLegPose (const Rotations &r) { writeRotation(DATA_LEFT_LEG_X, r); }
void ArmorStand::setRightLegPose(const Rotations &r) { writeRotation(DATA_RIGHT_LEG_X, r); }
void ArmorStand::readAdditionalSaveData(CompoundTag *tag)
{
LivingEntity::readAdditionalSaveData(tag);
invisible = tag->getBoolean(L"Invisible");
disabledSlots = tag->getInt(L"DisabledSlots");
setInvisible(invisible);
setSmall (tag->getBoolean(L"Small"));
setShowArms (tag->getBoolean(L"ShowArms"));
setNoBasePlate(tag->getBoolean(L"NoBasePlate"));
setMarker (tag->getBoolean(L"Marker"));
if (tag->contains(L"Pose"))
{
CompoundTag *pose = tag->getCompound(L"Pose");
auto loadRot = [&](const wchar_t *key, const Rotations &def) -> Rotations {
if (!pose->contains(key)) return def;
ListTag<FloatTag> *list = (ListTag<FloatTag> *)pose->getList(key);
if (!list || list->size() < 3) return def;
return Rotations(list->get(0)->data, list->get(1)->data, list->get(2)->data);
};
setHeadPose (loadRot(L"Head", DEFAULT_HEAD_POSE));
setBodyPose (loadRot(L"Body", DEFAULT_BODY_POSE));
setLeftArmPose (loadRot(L"LeftArm", DEFAULT_LEFT_ARM_POSE));
setRightArmPose(loadRot(L"RightArm", DEFAULT_RIGHT_ARM_POSE));
setLeftLegPose (loadRot(L"LeftLeg", DEFAULT_LEFT_LEG_POSE));
setRightLegPose(loadRot(L"RightLeg", DEFAULT_RIGHT_LEG_POSE));
}
if (tag->contains(L"ArmorStandEquipment"))
{
ListTag<CompoundTag> *eqList = (ListTag<CompoundTag> *)tag->getList(L"ArmorStandEquipment");
if (eqList) {
for (int i = 0; i < 5 && i < eqList->size(); i++) {
CompoundTag *itemTag = eqList->get(i);
if (itemTag->contains(L"id")) {
equipment[i] = ItemInstance::fromTag(itemTag);
} else {
equipment[i] = nullptr;
}
}
}
}
}
void ArmorStand::addAdditonalSaveData(CompoundTag *tag)
{
LivingEntity::addAdditonalSaveData(tag);
tag->putBoolean(L"Invisible", isInvisible());
tag->putBoolean(L"Small", isSmall());
tag->putBoolean(L"ShowArms", showArms());
tag->putBoolean(L"NoBasePlate", !showBasePlate());
tag->putInt (L"DisabledSlots", disabledSlots);
if (isMarker()) tag->putBoolean(L"Marker", true);
auto saveRot = [](const Rotations &r) -> ListTag<FloatTag> * {
ListTag<FloatTag> *list = new ListTag<FloatTag>();
list->add(new FloatTag(L"", r.x));
list->add(new FloatTag(L"", r.y));
list->add(new FloatTag(L"", r.z));
return list;
};
CompoundTag *pose = new CompoundTag();
pose->put(L"Head", saveRot(getHeadPose()));
pose->put(L"Body", saveRot(getBodyPose()));
pose->put(L"LeftArm", saveRot(getLeftArmPose()));
pose->put(L"RightArm", saveRot(getRightArmPose()));
pose->put(L"LeftLeg", saveRot(getLeftLegPose()));
pose->put(L"RightLeg", saveRot(getRightLegPose()));
tag->put(L"Pose", pose);
ListTag<CompoundTag> *eqList = new ListTag<CompoundTag>();
for (int i = 0; i < 5; i++) {
CompoundTag *itemTag = new CompoundTag();
if (equipment[i] != nullptr) {
equipment[i]->save(itemTag);
}
eqList->add(itemTag);
}
tag->put(L"ArmorStandEquipment", eqList);
}
shared_ptr<ItemInstance> ArmorStand::getCarriedItem()
{
return equipment[SLOT_WEAPON];
}
shared_ptr<ItemInstance> ArmorStand::getCarried(int slot)
{
if (slot == SLOT_WEAPON) return getCarriedItem();
else if (slot >= SLOT_BOOTS && slot <= SLOT_HELM) return getArmor(slot - 1);
return nullptr;
}
shared_ptr<ItemInstance> ArmorStand::getArmor(int pos)
{
if (pos >= 0 && pos < 4) {
return equipment[pos + 1];
}
return nullptr;
}
void ArmorStand::setEquippedSlot(int slot, shared_ptr<ItemInstance> item)
{
if (slot >= 0 && slot < 5) {
equipment[slot] = item;
}
}
ItemInstanceArray ArmorStand::getEquipmentSlots()
{
return equipment;
}
int ArmorStand::getEquipmentSlotForItem(shared_ptr<ItemInstance> item) const
{
if (!item) return SLOT_WEAPON;
int id = item->id;
const int HELMET_IDS[] = {298, 302, 306, 310, 314};
const int CHEST_IDS[] = {299, 303, 307, 311, 315};
const int LEGS_IDS[] = {300, 304, 308, 312, 316};
const int BOOTS_IDS[] = {301, 305, 309, 313, 317};
const int HEAD_IDS[] = {397, 144, 145, 146, 86};
for (int helm : HELMET_IDS) if (id == helm) return SLOT_HELM;
for (int chest : CHEST_IDS) if (id == chest) return SLOT_CHEST;
for (int legs : LEGS_IDS) if (id == legs) return SLOT_LEGGINGS;
for (int boots : BOOTS_IDS) if (id == boots) return SLOT_BOOTS;
for (int head : HEAD_IDS) if (id == head) return SLOT_HELM;
return SLOT_WEAPON;
}
bool ArmorStand::isSlotDisabled(int slot) const
{
if (slot == SLOT_WEAPON && !showArms()) return true;
return false;
}
shared_ptr<ItemInstance> ArmorStand::getItemInSlot(int slot)
{
if (slot == SLOT_WEAPON) {
return getCarriedItem();
} else if (slot >= SLOT_BOOTS && slot <= SLOT_HELM) {
return getArmor(slot - 1);
}
return nullptr;
}

View file

@ -0,0 +1,128 @@
#pragma once
#include "Mob.h"
#include "SynchedEntityData.h"
struct Rotations
{
float x, y, z;
Rotations() : x(0), y(0), z(0) {}
Rotations(float x, float y, float z) : x(x), y(y), z(z) {}
};
class ArmorStand : public Mob
{
public:
eINSTANCEOF GetType() { return eTYPE_ARMORSTAND; }
static Entity *create(Level *level) { return new ArmorStand(level); }
static const Rotations DEFAULT_HEAD_POSE;
static const Rotations DEFAULT_BODY_POSE;
static const Rotations DEFAULT_LEFT_ARM_POSE;
static const Rotations DEFAULT_RIGHT_ARM_POSE;
static const Rotations DEFAULT_LEFT_LEG_POSE;
static const Rotations DEFAULT_RIGHT_LEG_POSE;
private:
static const int DATA_CLIENT_FLAGS = 10;
static const int DATA_HEAD_POSE_X = 11;
static const int DATA_HEAD_POSE_Y = 12;
static const int DATA_HEAD_POSE_Z = 13;
static const int DATA_BODY_POSE_X = 14;
static const int DATA_BODY_POSE_Y = 15;
static const int DATA_BODY_POSE_Z = 16;
static const int DATA_LEFT_ARM_X = 17;
static const int DATA_LEFT_ARM_Y = 18;
static const int DATA_LEFT_ARM_Z = 19;
static const int DATA_RIGHT_ARM_X = 20;
static const int DATA_RIGHT_ARM_Y = 21;
static const int DATA_RIGHT_ARM_Z = 22;
static const int DATA_LEFT_LEG_X = 23;
static const int DATA_LEFT_LEG_Y = 24;
static const int DATA_LEFT_LEG_Z = 25;
static const int DATA_RIGHT_LEG_X = 26;
static const int DATA_RIGHT_LEG_Y = 27;
static const int DATA_RIGHT_LEG_Z = 28;
static const int FLAG_SMALL = 1;
static const int FLAG_SHOW_ARMS = 4;
static const int FLAG_NO_BASEPLATE = 8;
static const int FLAG_MARKER = 16;
public:
long long lastHit;
private:
int disabledSlots;
bool invisible;
public:
ArmorStand(Level *level);
virtual ~ArmorStand() {}
bool isSmall() const;
bool showArms() const;
bool showBasePlate() const;
bool isMarker() const;
void setSmall(bool v);
void setShowArms(bool v);
void setNoBasePlate(bool v);
void setMarker(bool v);
Rotations getHeadPose() const;
Rotations getBodyPose() const;
Rotations getLeftArmPose() const;
Rotations getRightArmPose() const;
Rotations getLeftLegPose() const;
Rotations getRightLegPose() const;
void setHeadPose (const Rotations &r);
void setBodyPose (const Rotations &r);
void setLeftArmPose (const Rotations &r);
void setRightArmPose(const Rotations &r);
void setLeftLegPose (const Rotations &r);
void setRightLegPose(const Rotations &r);
virtual bool useNewAi() override { return false; }
virtual void tick() override;
virtual bool hurt(DamageSource *source, float damage) override;
virtual bool interact(shared_ptr<Player> player) override;
virtual bool isPickable() override;
virtual bool isPushable() override { return false; }
virtual void push(shared_ptr<Entity> entity) override {}
virtual void push(double xa, double ya, double za) override {}
virtual bool isAttackable() override { return true; }
virtual bool isBaby() override { return isSmall(); }
virtual bool shouldShowName() override { return false; }
virtual wstring getAName() override { return L""; }
virtual wstring getDisplayName() override { return L""; }
virtual wstring getNetworkName() override { return L""; }
virtual shared_ptr<ItemInstance> getCarriedItem() override;
virtual shared_ptr<ItemInstance> getCarried(int slot) override;
virtual shared_ptr<ItemInstance> getArmor(int pos) override;
virtual void setEquippedSlot(int slot, shared_ptr<ItemInstance> item) override;
virtual ItemInstanceArray getEquipmentSlots() override;
virtual void readAdditionalSaveData(CompoundTag *tag) override;
virtual void addAdditonalSaveData(CompoundTag *tag) override;
virtual void handleEntityEvent(byte eventId) override;
protected:
virtual void defineSynchedData() override;
virtual void registerAttributes() override;
virtual int getHurtSound() override { return -1; }
virtual int getDeathSound() override { return -1; }
virtual float getSoundVolume() override { return 0.0f; }
virtual bool makeStepSound() override { return false; }
private:
byte setBit(byte oldBit, int offset, bool value);
Rotations readRotation(int slotX) const;
void writeRotation(int slotX, const Rotations &r);
int getEquipmentSlotForItem(shared_ptr<ItemInstance> item) const;
bool isSlotDisabled(int slot) const;
shared_ptr<ItemInstance> getItemInSlot(int slot);
};

View file

@ -0,0 +1,57 @@
#include "stdafx.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.entity.player.h"
#include "net.minecraft.world.entity.h"
#include "net.minecraft.world.item.h"
#include "Mth.h"
#include "ArmorStandItem.h"
#include "..\Minecraft.World\ArmorStand.h"
bool ArmorStandItem::useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player,
Level *level, int x, int y, int z, int face,
float clickX, float clickY, float clickZ,
bool bTestUseOnOnly)
{
int px = x;
int py = y;
int pz = z;
if (face == 0) py--; // bottom
if (face == 1) py++; // top
if (face == 2) pz--; // North
if (face == 3) pz++; // South
if (face == 4) px--; // West
if (face == 5) px++; // East
//if (face != 1) return false;
if (level->getTile(px, py, pz) != 0) return false;
if (level->getTile(px, py + 1, pz) != 0) return false;
if (bTestUseOnOnly) return true;
if (level->isClientSide) return true;
//rotation
float targetRot = player->yRot + 180.0f;
float snapped = (float)(Mth::floor((targetRot + 22.5f) / 45.0f) * 45.0f);
shared_ptr<ArmorStand> stand = std::make_shared<ArmorStand>(level);
stand->moveTo(px + 0.5, py, pz + 0.5, snapped, 0.0f);
stand->yRot = snapped;
stand->yBodyRot = snapped;
stand->yHeadRot = snapped;
stand->yRotO = snapped;
stand->yBodyRotO = snapped;
stand->yHeadRotO = snapped;
level->addEntity(stand);
if (!player->abilities.instabuild)
itemInstance->count--;
return true;
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "Item.h"
class ArmorStandItem : public Item
{
public:
ArmorStandItem(int id) : Item(id) {}
virtual ~ArmorStandItem() {}
virtual bool useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player,
Level *level, int x, int y, int z, int face,
float clickX, float clickY, float clickZ,
bool bTestUseOnOnly = false) override;
};

View file

@ -186,6 +186,8 @@ enum eINSTANCEOF
eTYPE_REMOTEPLAYER = eTYPE_PLAYER | 0x2,
eTYPE_LOCALPLAYER = eTYPE_PLAYER | 0x3,
eTYPE_ARMORSTAND = eTYPE_LIVINGENTITY | 0x10,
eTYPE_GLOBAL_ENTITY = eTYPE_ENTITY | BIT_GLOBAL_ENTITY,
eTYPE_LIGHTNINGBOLT = eTYPE_GLOBAL_ENTITY | 0x1,
@ -200,9 +202,8 @@ enum eINSTANCEOF
eTYPE_MINECART_CHEST = eTYPE_MINECART_CONTAINER | 0x2,
eTYPE_MINECART_HOPPER = eTYPE_MINECART_CONTAINER | 0x5,
eTYPE_FIREBALL = eTYPE_ENTITY | eTYPE_PROJECTILE | BIT_FIREBALL, //0x2,
eTYPE_FIREBALL = eTYPE_ENTITY | eTYPE_PROJECTILE | BIT_FIREBALL, //0x2,
eTYPE_DRAGON_FIREBALL = eTYPE_FIREBALL | 0x1,
eTYPE_WITHER_SKULL = eTYPE_FIREBALL | 0x2,
@ -442,6 +443,7 @@ public:
classes->push_back( SUBCLASS(eTYPE_SERVERPLAYER )->addParent( eTYPE_PLAYER ) );
classes->push_back( SUBCLASS(eTYPE_REMOTEPLAYER )->addParent( eTYPE_PLAYER ) );
classes->push_back( SUBCLASS(eTYPE_LOCALPLAYER )->addParent( eTYPE_PLAYER ) );
classes->push_back( SUBCLASS(eTYPE_ARMORSTAND )->addParent( eTYPE_MOB ) );
classes->push_back( SUBCLASS(eTYPE_MINECART )->addParent( eTYPE_ENTITY ) );
classes->push_back( SUBCLASS(eTYPE_MINECART_RIDEABLE )->addParent( eTYPE_MINECART ) );
classes->push_back( SUBCLASS(eTYPE_MINECART_SPAWNER )->addParent( eTYPE_MINECART ) );

View file

@ -16,6 +16,7 @@
#include "com.mojang.nbt.h"
#include "EntityIO.h"
unordered_map<wstring, entityCreateFn> *EntityIO::idCreateMap = new unordered_map<wstring, entityCreateFn>;
unordered_map<eINSTANCEOF, wstring, eINSTANCEOFKeyHash, eINSTANCEOFKeyEq> *EntityIO::classIdMap = new unordered_map<eINSTANCEOF, wstring, eINSTANCEOFKeyHash, eINSTANCEOFKeyEq>;
unordered_map<int, entityCreateFn> *EntityIO::numCreateMap = new unordered_map<int, entityCreateFn>;
@ -72,6 +73,8 @@ void EntityIO::staticCtor()
setId(MinecartHopper::create, eTYPE_MINECART_HOPPER, L"MinecartHopper", 46);
setId(MinecartSpawner::create, eTYPE_MINECART_SPAWNER, L"MinecartSpawner", 47);
setId(Mob::create, eTYPE_MOB, L"Mob", 48);
setId(Monster::create, eTYPE_MONSTER, L"Monster", 49);
@ -106,7 +109,9 @@ void EntityIO::staticCtor()
setId(EntityHorse::create, eTYPE_HORSE, L"EntityHorse", 100, eMinecraftColour_Mob_Horse_Colour1, eMinecraftColour_Mob_Horse_Colour2, IDS_HORSE);
setId(Rabbit::create, eTYPE_RABBIT, L"Rabbit", 101,
eMinecraftColour_Mob_Rabbit_Colour1,
eMinecraftColour_Mob_Rabbit_Colour2, IDS_HORSE);//change IDS_RABBIT later
eMinecraftColour_Mob_Rabbit_Colour2, IDS_RABBIT);//change IDS_RABBIT later
setId(ArmorStand::create, eTYPE_ARMORSTAND, L"ArmorStand", 102),
setId(Villager::create, eTYPE_VILLAGER, L"Villager", 120, eMinecraftColour_Mob_Villager_Colour1, eMinecraftColour_Mob_Villager_Colour2, IDS_VILLAGER);

View file

@ -257,8 +257,10 @@ Item* Item::door_jungle = nullptr;
Item* Item::door_acacia = nullptr;
Item* Item::door_dark = nullptr;
//TU31
Item* Item::mutton_raw = nullptr;
Item* Item::mutton_cooked = nullptr;
Item* Item::armor_stand = nullptr;
void Item::staticCtor()
{
@ -511,6 +513,9 @@ void Item::staticCtor()
Item::door_jungle = (new DoorItem(173, Material::wood, L"doorJungle"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorJungle")->setDescriptionId(IDS_ITEM_DOOR_JUNGLE)->setUseDescriptionId(IDS_DESC_DOOR_WOOD);
Item::door_acacia = (new DoorItem(174, Material::wood, L"doorAcacia"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorAcacia")->setDescriptionId(IDS_ITEM_DOOR_ACACIA)->setUseDescriptionId(IDS_DESC_DOOR_WOOD);
Item::door_dark = (new DoorItem(175, Material::wood, L"doorDark"))->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorDark")->setDescriptionId(IDS_ITEM_DOOR_DARK)->setUseDescriptionId(IDS_DESC_DOOR_WOOD);
Item::armor_stand = (new ArmorStandItem(160))->setBaseItemTypeAndMaterial(eBaseItemType_undefined, eMaterial_undefined)->setIconName(L"armorStand")->setDescriptionId(IDS_ITEM_ARMOR_STAND)->setUseDescriptionId(IDS_DESC_ARMOR_STAND);
}
@ -1164,3 +1169,4 @@ const int Item::pumpkinPie_Id ;
const int Item::enchantedBook_Id ;
const int Item::netherQuartz_Id ;
#endif

View file

@ -422,9 +422,12 @@ public:
static Item* door_jungle;
static Item* door_acacia;
static Item* door_dark;
//TU31
static Item* mutton_raw;
static Item* mutton_cooked;
static Item* armor_stand;
static const int shovel_iron_Id = 256;
static const int pickAxe_iron_Id = 257;
@ -631,8 +634,7 @@ public:
static const int lead_Id = 420;
static const int nameTag_Id = 421;
static const int mutton_raw_Id = 423;
static const int mutton_cooked_Id = 424;
// TU25
static const int door_spruce_Id = 427;
@ -641,6 +643,11 @@ public:
static const int door_acacia_Id = 430;
static const int door_dark_Id = 431;
//TU31
static const int mutton_raw_Id = 423;
static const int mutton_cooked_Id = 424;
static const int armor_stand_Id = 416;
public:
const int id;
@ -781,4 +788,4 @@ public:
virtual bool isValidRepairItem(shared_ptr<ItemInstance> source, shared_ptr<ItemInstance> repairItem);
virtual void registerIcons(IconRegister *iconRegister);
virtual attrAttrModMap *getDefaultAttributeModifiers();
};
};

View file

@ -2408,6 +2408,8 @@
<ClInclude Include="ArmorItem.h" />
<ClInclude Include="ArmorRecipes.h" />
<ClInclude Include="ArmorSlot.h" />
<ClInclude Include="ArmorStand.h" />
<ClInclude Include="ArmorStandItem.h" />
<ClInclude Include="Arrays.h" />
<ClInclude Include="ArrayWithLength.h" />
<ClInclude Include="ArrowDamageEnchantment.h" />
@ -3487,6 +3489,8 @@
<ClCompile Include="ArmorItem.cpp" />
<ClCompile Include="ArmorRecipes.cpp" />
<ClCompile Include="ArmorSlot.cpp" />
<ClCompile Include="ArmorStand.cpp" />
<ClCompile Include="ArmorStandItem.cpp" />
<ClCompile Include="Arrow.cpp" />
<ClCompile Include="ArrowDamageEnchantment.cpp" />
<ClCompile Include="ArrowFireEnchantment.cpp" />

View file

@ -3203,6 +3203,7 @@
<ClInclude Include="Rose.h">
<Filter>Header Files</Filter>
</ClInclude>
<<<<<<< Updated upstream
<ClInclude Include="SandTile.h">
<Filter>net\minecraft\world\level\tile</Filter>
</ClInclude>
@ -3211,6 +3212,13 @@
</ClInclude>
<ClInclude Include="TreeTile2.h">
<Filter>net\minecraft\world\level\tile</Filter>
=======
<ClInclude Include="ArmorStand.h">
<Filter>net\minecraft\world\entity\item</Filter>
</ClInclude>
<ClInclude Include="ArmorStandItem.h">
<Filter>net\minecraft\world\entity\item</Filter>
>>>>>>> Stashed changes
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -5647,6 +5655,7 @@
<ClCompile Include="Rose.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<<<<<<< Updated upstream
<ClCompile Include="SandTile.cpp">
<Filter>net\minecraft\world\level\tile</Filter>
</ClCompile>
@ -5655,6 +5664,13 @@
</ClCompile>
<ClCompile Include="TreeTile2.cpp">
<Filter>net\minecraft\world\level\tile</Filter>
=======
<ClCompile Include="ArmorStand.cpp">
<Filter>net\minecraft\world\entity\item</Filter>
</ClCompile>
<ClCompile Include="ArmorStandItem.cpp">
<Filter>net\minecraft\world\entity\item</Filter>
>>>>>>> Stashed changes
</ClCompile>
</ItemGroup>
</Project>

View file

@ -59,7 +59,7 @@ protected:
private:
shared_ptr<LivingEntity> target;
Sensing *sensing;
protected:
ItemInstanceArray equipment;
protected:
@ -155,7 +155,7 @@ public:
virtual float getHeadSizeScale();
virtual int getMaxSpawnClusterSize();
virtual int getMaxFallDistance();
virtual shared_ptr<ItemInstance> getCarriedItem();
virtual shared_ptr<ItemInstance> getCarriedItem() override;
virtual shared_ptr<ItemInstance> getCarried(int slot);
virtual shared_ptr<ItemInstance> getArmor(int pos);
virtual void setEquippedSlot(int slot, shared_ptr<ItemInstance> item);

View file

@ -125,9 +125,10 @@ shared_ptr<AgableMob> Rabbit::getBreedOffspring(shared_ptr<AgableMob> target) {
}
int Rabbit::getAmbientSound() { return eSoundType_MOB_BAT_IDLE; }
int Rabbit::getHurtSound() { return eSoundType_MOB_BAT_HURT; }
int Rabbit::getDeathSound() { return eSoundType_MOB_BAT_DEATH; }
int Rabbit::getAmbientSound() { return eSoundType_MOB_RABBIT_IDLE; }
int Rabbit::getHurtSound() { return eSoundType_MOB_RABBIT_HURT; }
int Rabbit::getDeathSound() { return eSoundType_MOB_RABBIT_DEATH; }
int Rabbit::getHopSound() { return eSoundType_MOB_RABBIT_HOP; }
void Rabbit::readAdditionalSaveData(CompoundTag *tag) {
Animal::readAdditionalSaveData(tag);

View file

@ -44,6 +44,7 @@ protected:
virtual int getAmbientSound() override;
virtual int getHurtSound() override;
virtual int getDeathSound() override;
virtual int getHopSound() ;
virtual float getSoundVolume() override { return 0.6f; }
virtual bool makeStepSound() override { return true; }

View file

@ -213,6 +213,12 @@ enum eSOUND_TYPE
eSoundType_FIRE_NEWIGNITE,
eSoundType_MOB_RABBIT_IDLE,
eSoundType_MOB_RABBIT_HURT,
eSoundType_MOB_RABBIT_DEATH,
eSoundType_MOB_RABBIT_HOP,
eSoundType_MAX
};

View file

@ -31,4 +31,7 @@
#include "MobGroupData.h"
#include "OwnableEntity.h"
#include "EntitySelector.h"
#include "LivingEntity.h"
#include "LivingEntity.h"
//TU31
#include "ArmorStand.h"

View file

@ -12,3 +12,4 @@
#include "MinecartSpawner.h"
#include "MinecartTNT.h"
#include "PrimedTnt.h"
#include "ArmorStandItem.h"