feat: Guardians

This commit is contained in:
Lord_Cambion 2026-04-10 14:03:32 +02:00
parent c7127b219d
commit 61b6e6adca
32 changed files with 1154 additions and 23 deletions

View file

@ -426,6 +426,10 @@ void IUIScene_CreativeMenu::staticCtor()
ITEM_AUX(Item::spawnEgg_Id, 62); // Magma Cube
ITEM_AUX(Item::spawnEgg_Id, 65); // Bat
ITEM_AUX(Item::spawnEgg_Id, 66); // Witch
ITEM_AUX(Item::spawnEgg_Id, 67); // Endermite
ITEM_AUX(Item::spawnEgg_Id, 68); // Guardian
ITEM_AUX(Item::spawnEgg_Id, 4); // Elder Guardian
ITEM_AUX(Item::spawnEgg_Id, 90); // Pig
ITEM_AUX(Item::spawnEgg_Id, 91); // Sheep
ITEM_AUX(Item::spawnEgg_Id, 92); // Cow
@ -435,7 +439,6 @@ void IUIScene_CreativeMenu::staticCtor()
ITEM_AUX(Item::spawnEgg_Id, 96); // Mooshroom
ITEM_AUX(Item::spawnEgg_Id, 98); // Ozelot
ITEM_AUX(Item::spawnEgg_Id, 100); // Horse
ITEM_AUX(Item::spawnEgg_Id, 67); // Endermite
ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_DONKEY + 1) << 12) ); // Donkey
ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_MULE + 1) << 12)); // Mule

View file

@ -12,6 +12,7 @@ private:
eControl_Achievements,
eControl_HelpAndOptions,
eControl_UnlockOrDLC,
eControl_MiniGames,
#ifndef _DURANGO
eControl_Exit,
#else
@ -38,7 +39,9 @@ private:
UI_MAP_ELEMENT( m_buttons[(int)eControl_HelpAndOptions], "Button4")
UI_MAP_ELEMENT( m_buttons[(int)eControl_UnlockOrDLC], "Button5")
#ifndef _DURANGO
UI_MAP_ELEMENT( m_buttons[(int)eControl_MiniGames], "Button7")
UI_MAP_ELEMENT( m_buttons[(int)eControl_Exit], "Button6")
#else
UI_MAP_ELEMENT( m_buttons[(int)eControl_XboxHelp], "Button6")
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

View file

@ -85,6 +85,8 @@
#include "ArmorStandRenderer.h"
#include "EndermiteRenderer.h"
#include "GuardianRenderer.h"
#include "GuardianModel.h"
#include "MobRenderer.h"
double EntityRenderDispatcher::xOff = 0.0;
@ -128,6 +130,9 @@ EntityRenderDispatcher::EntityRenderDispatcher()
renderers[eTYPE_VILLAGER] = new VillagerRenderer();
renderers[eTYPE_VILLAGERGOLEM] = new VillagerGolemRenderer();
renderers[eTYPE_BAT] = new BatRenderer();
renderers[eTYPE_GUARDIAN] = new GuardianRenderer(new GuardianModel(), 0.5f);
renderers[eTYPE_ELDER_GUARDIAN] = new GuardianRenderer(new GuardianModel(), 0.5f);
renderers[eTYPE_MOB] = new MobRenderer(new HumanoidModel(), 0.5f);

View file

@ -407,6 +407,7 @@ void EntityRenderer::registerTerrainTextures(IconRegister *iconRegister)
{
}
ResourceLocation *EntityRenderer::getTextureLocation(shared_ptr<Entity> mob)
{
return nullptr;

View file

@ -75,4 +75,6 @@ public:
virtual Model *getNewModel() { return newModel; }
virtual Model *getNewModelSlim() { return newModelSlim; }
virtual void SetItemFrame(bool bSet) {}
virtual bool shouldRender(shared_ptr<Entity> entity, float camX, float camY, float camZ) { return true; }
};

View file

@ -0,0 +1,147 @@
#include "stdafx.h"
#include "GuardianModel.h"
#include "..\Minecraft.World\Mth.h"
#include "ModelPart.h"
#include "..\Minecraft.World\Guardian.h"
GuardianModel::GuardianModel() : Model()
{
texWidth = 64;
texHeight = 64;
guardianBody = new ModelPart(this);
guardianBody->texOffs(0, 0)->addBox(-6.0f, 10.0f, -8.0f, 12, 12, 16);
guardianBody->texOffs(0, 28)->addBox(-8.0f, 10.0f, -6.0f, 2, 12, 12);
ModelPart *rightSide = new ModelPart(this);
rightSide->texOffs(0, 28)->mirror()->addBox(6.0f, 10.0f, -6.0f, 2, 12, 12);
guardianBody->addChild(rightSide);
guardianBody->texOffs(16, 40)->addBox(-6.0f, 8.0f, -6.0f, 12, 2, 12);
guardianBody->texOffs(16, 40)->addBox(-6.0f, 22.0f, -6.0f, 12, 2, 12);
for (int i = 0; i < 12; i++)
{
guardianSpines[i] = new ModelPart(this, 0, 0);
guardianSpines[i]->addBox(-1.0f, -4.5f, -1.0f, 2, 9, 2);
guardianBody->addChild(guardianSpines[i]);
}
guardianEye = new ModelPart(this, 8, 0);
guardianEye->addBox(-1.0f, 15.0f, 0.0f, 2, 2, 1);
guardianBody->addChild(guardianEye);
guardianTail[0] = new ModelPart(this, 40, 0);
guardianTail[0]->addBox(-2.0f, 14.0f, 7.0f, 4, 4, 8);
guardianTail[1] = new ModelPart(this, 0, 54);
guardianTail[1]->addBox(0.0f, 14.0f, 0.0f, 3, 3, 7);
guardianTail[2] = new ModelPart(this);
guardianTail[2]->texOffs(41, 32)->addBox(0.0f, 14.0f, 0.0f, 2, 2, 6);
guardianTail[2]->texOffs(25, 19)->addBox(1.0f, 10.5f, 3.0f, 1, 9, 9);
guardianBody->addChild(guardianTail[0]);
guardianTail[0]->addChild(guardianTail[1]);
guardianTail[1]->addChild(guardianTail[2]);
}
void GuardianModel::setupAnim(float time, float r, float bob, float yRot, float xRot,
float scale, shared_ptr<Entity> entity,
unsigned int uiBitmaskOverrideAnim)
{
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(entity);
if (!guardian) return;
float afloat[] = { 1.75f, 0.25f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.5f, 1.25f, 0.75f, 0.0f, 0.0f };
float afloat1[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.25f,1.75f, 1.25f, 0.75f, 0.0f, 0.0f, 0.0f, 0.0f };
float afloat2[] = { 0.0f, 0.0f, 0.25f,1.75f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f,1.25f};
float afloat3[] = { 0.0f, 0.0f, 8.0f, -8.0f,-8.0f, 8.0f, 8.0f, -8.0f, 0.0f, 0.0f, 8.0f,-8.0f };
float afloat4[] = {-8.0f, -8.0f, -8.0f, -8.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, 8.0f, 8.0f, 8.0f };
float afloat5[] = { 8.0f, -8.0f, 0.0f, 0.0f,-8.0f,-8.0f, 8.0f, 8.0f, 8.0f, -8.0f, 0.0f, 0.0f };
// Body orientation
guardianBody->yRot = yRot / (180.0f / (float)PI);
guardianBody->xRot = xRot / (180.0f / (float)PI);
guardianEye->z = -8.25f;
if (guardian->hasTargetedEntity())
{
shared_ptr<LivingEntity> target = guardian->getTargetedEntity();
if (target)
{
double d0 = (guardian->y + guardian->getEyeHeight())
- (target->y + target->getEyeHeight());
guardianEye->y = (d0 > 0.0) ? 0.0f : 1.0f;
double dx = target->x - guardian->x;
double dz = target->z - guardian->z;
float targetYaw = (float)(atan2(dz, dx) * 180.0 / PI) - 90.0f;
float diff = Mth::wrapDegrees(targetYaw - guardian->yRot);
float clamped = diff / 45.0f;
if (clamped < -2.0f) clamped = -2.0f;
if (clamped > 2.0f) clamped = 2.0f;
guardianEye->x = clamped;
}
}
else
{
guardianEye->y = 0.0f;
guardianEye->x = 0.0f;
}
float f1 = (1.0f - guardian->getSpikesAnimation(0.0f)) * 0.55f;
for (int i = 0; i < 12; ++i)
{
guardianSpines[i]->xRot = (float)PI * afloat[i];
guardianSpines[i]->yRot = (float)PI * afloat1[i];
guardianSpines[i]->zRot = (float)PI * afloat2[i];
float wave = 1.0f + Mth::cos(bob * 1.5f + (float)i) * 0.01f - f1;
guardianSpines[i]->x = afloat3[i] * wave;
guardianSpines[i]->y = 16.0f + afloat4[i] * wave;
guardianSpines[i]->z = afloat5[i] * wave;
}
float tailAnim = guardian->getTailAnimation(0.0f);
guardianTail[0]->yRot = Mth::sin(tailAnim) * (float)PI * 0.05f;
guardianTail[1]->yRot = Mth::sin(tailAnim) * (float)PI * 0.1f;
guardianTail[1]->x = -1.5f;
guardianTail[1]->y = 0.5f;
guardianTail[1]->z = 14.0f;
guardianTail[2]->yRot = Mth::sin(tailAnim) * (float)PI * 0.15f;
guardianTail[2]->x = 0.5f;
guardianTail[2]->y = 0.5f;
guardianTail[2]->z = 6.0f;
}
void GuardianModel::render(shared_ptr<Entity> entity, float time, float r, float bob,
float yRot, float xRot, float scale, bool usecompiled)
{
setupAnim(time, r, bob, yRot, xRot, scale, entity);
guardianBody->render(scale, usecompiled);
}

View file

@ -0,0 +1,25 @@
#pragma once
#include "Model.h"
class ModelPart;
class GuardianModel : public Model
{
public:
ModelPart *guardianBody;
ModelPart *guardianEye;
ModelPart *guardianSpines[12];
ModelPart *guardianTail[3];
GuardianModel();
int getTextureHeight() { return 64; }
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot,
float scale, shared_ptr<Entity> entity,
unsigned int uiBitmaskOverrideAnim = 0) override;
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,239 @@
#include "stdafx.h"
#include "GuardianRenderer.h"
#include "GuardianModel.h"
#include "..\Minecraft.World\Mth.h"
#include "..\Minecraft.World\net.minecraft.world.entity.animal.h"
#include "../Minecraft.World/Guardian.h"
#include "..\Minecraft.World\Level.h"
#include "Tesselator.h"
ResourceLocation GuardianRenderer::GUARDIAN_LOCATION = ResourceLocation(TN_MOB_GUARDIAN);
ResourceLocation GuardianRenderer::GUARDIAN_ELDER_LOCATION = ResourceLocation(TN_MOB_GUARDIAN_ELDER);
ResourceLocation GuardianRenderer::GUARDIAN_BEAM_LOCATION = ResourceLocation(TN_MOB_GUARDIAN_BEAM);
GuardianRenderer::GuardianRenderer(Model *model, float shadow)
: MobRenderer(model, shadow)
{
guardianModel = static_cast<GuardianModel *>(model);
}
ResourceLocation *GuardianRenderer::getTextureLocation(shared_ptr<Entity> mob)
{
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(mob);
if (guardian && guardian->isElder())
return &GUARDIAN_ELDER_LOCATION;
return &GUARDIAN_LOCATION;
}
bool GuardianRenderer::shouldRender(shared_ptr<Entity> mob, float camX, float camY, float camZ)
{
if (MobRenderer::shouldRender(mob, camX, camY, camZ))
return true;
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(mob);
if (!guardian || !guardian->hasTargetedEntity())
return false;
shared_ptr<LivingEntity> target = guardian->getTargetedEntity();
if (!target)
return false;
double tx, ty, tz, gx, gy, gz;
getInterpolatedPos(target, (double)target->bbHeight * 0.5, 1.0f, tx, ty, tz);
getInterpolatedPos(guardian, (double)guardian->getEyeHeight(), 1.0f, gx, gy, gz);
auto inRange = [&](double x, double y, double z) {
double dx = x - camX, dy = y - camY, dz = z - camZ;
return (dx*dx + dy*dy + dz*dz) < (64.0 * 64.0);
};
return inRange(gx, gy, gz) || inRange(tx, ty, tz);
}
void GuardianRenderer::getInterpolatedPos(shared_ptr<LivingEntity> entity, double yOffset,
float partialTicks,
double &outX, double &outY, double &outZ)
{
outX = entity->xo + (entity->x - entity->xo) * (double)partialTicks;
outY = yOffset + entity->yo + (entity->y - entity->yo) * (double)partialTicks;
outZ = entity->zo + (entity->z - entity->zo) * (double)partialTicks;
}
void GuardianRenderer::setupRotations(shared_ptr<LivingEntity> _mob, float bob,
float bodyRot, float a)
{
shared_ptr<Guardian> mob = dynamic_pointer_cast<Guardian>(_mob);
float bodyXRot = mob->xBodyRotO + (mob->xBodyRot - mob->xBodyRotO) * a;
glTranslatef(0, 1.2f, 0);
glRotatef(180.0f - bodyRot, 0, 1, 0);
glRotatef(bodyXRot, 1, 0, 0);
glTranslatef(0, -1.2f, 0);
}
void GuardianRenderer::render(shared_ptr<Entity> _mob, double x, double y, double z,
float rot, float a)
{
MobRenderer::render(_mob, x, y, z, rot, a);
shared_ptr<Guardian> mob = dynamic_pointer_cast<Guardian>(_mob);
if (!mob || !mob->hasTargetedEntity()) return;
shared_ptr<Entity> target = mob->level->getEntity(mob->getTargetedEntityId());
if (!target) {
target = mob->level->getNearestPlayer(mob->x, mob->y, mob->z, 64.0);
if (!target || target->entityId != mob->getTargetedEntityId()) return;
}
float f = mob->getAttackAnimationScale(a);
float time = (float)mob->tickCount + a;
float texVOff = -time * 0.2f - floor(-time * 0.1f);
float eyeHeight = mob->getEyeHeight();
if (mob && mob->isElder())
eyeHeight = mob->bbHeight * 0.5f * 2.35f;
double targetX = target->xo + (target->x - target->xo) * a;
double targetZ = target->zo + (target->z - target->zo) * a;
double targetYBase = target->yo + (target->y - target->yo) * a;
double targetY = targetYBase - (target->bbHeight * 0.5f);
double mobX = mob->xo + (mob->x - mob->xo) * a;
double mobY = mob->yo + (mob->y - mob->yo) * a + eyeHeight;
double mobZ = mob->zo + (mob->z - mob->zo) * a;
double dx = targetX - mobX;
double dy = targetY - mobY;
double dz = targetZ - mobZ;
double distOrizzontale = sqrt(dx * dx + dz * dz);
double distanzaTotale = sqrt(dx * dx + dy * dy + dz * dz);
bindTexture(&GUARDIAN_BEAM_LOCATION);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true);
glPushMatrix();
glTranslatef((float)x, (float)y + eyeHeight, (float)z);
glRotatef((float)(atan2(dx, dz) * 180.0 / PI), 0, 1, 0);
glRotatef((float)(-atan2(dy, distOrizzontale) * 180.0 / PI), 1, 0, 0);
Tesselator* t = Tesselator::getInstance();
double r1 = 0.2;
double r2 = r1 * 1.41;
double rotBeam = time * 0.05 * (1.0 - 2.5);
float f7 = f * f;
int red = (int)fmin(255, 64 + (int)(f7 * 240.0f));
int green = (int)fmin(255, 32 + (int)(f7 * 192.0f));
int blue = (int)fmax(0, fmin(255, 128 - (int)(f7 * 64.0f)));
double vMin = 0.0 + texVOff;
double vMax = distanzaTotale * (0.5 / r1) + texVOff;
double d12 = cos(rotBeam + PI) * r1;
double d13 = sin(rotBeam + PI) * r1;
double d14 = cos(rotBeam + 0.0) * r1;
double d15 = sin(rotBeam + 0.0) * r1;
double d16 = cos(rotBeam + (PI / 2.0)) * r1;
double d17 = sin(rotBeam + (PI / 2.0)) * r1;
double d18 = cos(rotBeam + (PI * 3.0 / 2.0)) * r1;
double d19 = sin(rotBeam + (PI * 3.0 / 2.0)) * r1;
t->begin();
t->color(red, green, blue, 255);
t->vertexUV(d12, d13, distanzaTotale, 0.4999, vMax);
t->vertexUV(d12, d13, 0.0, 0.4999, vMin);
t->vertexUV(d14, d15, 0.0, 0.0, vMin);
t->vertexUV(d14, d15, distanzaTotale, 0.0, vMax);
t->vertexUV(d16, d17, distanzaTotale, 0.4999, vMax);
t->vertexUV(d16, d17, 0.0, 0.4999, vMin);
t->vertexUV(d18, d19, 0.0, 0.0, vMin);
t->vertexUV(d18, d19, distanzaTotale, 0.0, vMax);
t->end();
glDepthMask(false);
double d24 = (mob->tickCount % 2 == 0) ? 0.5 : 0.0;
t->begin();
t->color(red, green, blue, 64);
double g1 = cos(rotBeam + 2.356) * r2;
double g2 = sin(rotBeam + 2.356) * r2;
double g3 = cos(rotBeam + 0.785) * r2;
double g4 = sin(rotBeam + 0.785) * r2;
double g5 = cos(rotBeam + 3.926) * r2;
double g6 = sin(rotBeam + 3.926) * r2;
double g7 = cos(rotBeam + 5.497) * r2;
double g8 = sin(rotBeam + 5.497) * r2;
t->vertexUV(g1, g2, distanzaTotale, 0.5, d24 + 0.5);
t->vertexUV(g1, g2, 0.0, 0.5, d24);
t->vertexUV(g3, g4, 0.0, 1.0, d24);
t->vertexUV(g3, g4, distanzaTotale, 1.0, d24 + 0.5);
t->vertexUV(g7, g8, distanzaTotale, 1.0, d24 + 0.5);
t->vertexUV(g7, g8, 0.0, 1.0, d24);
t->vertexUV(g5, g6, 0.0, 0.5, d24);
t->vertexUV(g5, g6, distanzaTotale, 0.5, d24 + 0.5);
t->end();
glDepthMask(true);
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glEnable(GL_CULL_FACE);
glPopMatrix();
}
void GuardianRenderer::renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale)
{
shared_ptr<Guardian> guardian = dynamic_pointer_cast<Guardian>(mob);
if (guardian && guardian->isElder())
{
glPushMatrix();
glTranslatef(0.0f, -2.0f, 0.0f);
glScalef(2.35f, 2.35f, 2.35f);
LivingEntityRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale);
glPopMatrix();
}
else
{
LivingEntityRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale);
}
}

View file

@ -0,0 +1,42 @@
#pragma once
#include "MobRenderer.h"
class GuardianModel;
class GuardianRenderer : public MobRenderer
{
private:
GuardianModel *guardianModel;
static ResourceLocation GUARDIAN_LOCATION;
static ResourceLocation GUARDIAN_ELDER_LOCATION;
static ResourceLocation GUARDIAN_BEAM_LOCATION;
void getInterpolatedPos(shared_ptr<LivingEntity> entity, double yOffset,
float partialTicks,
double &outX, double &outY, double &outZ);
public:
GuardianRenderer(Model *model, float shadow);
virtual bool shouldRender(shared_ptr<Entity> mob, float camX, float camY, float camZ) override;
virtual void render(shared_ptr<Entity> mob, double x, double y, double z,
float rot, float a) override;
protected:
virtual void setupRotations(shared_ptr<LivingEntity> mob, float bob,
float bodyRot, float a) override;
virtual void renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale) override;
virtual ResourceLocation *getTextureLocation(shared_ptr<Entity> mob) override;
};

View file

@ -31,6 +31,17 @@ void MobRenderer::render(shared_ptr<Entity> _mob, double x, double y, double z,
renderLeash(mob, x, y, z, rot, a);
}
bool MobRenderer::shouldRender(shared_ptr<Entity> entity, float camX, float camY, float camZ)
{
double dx = entity->x - camX;
double dy = entity->y - camY;
double dz = entity->z - camZ;
double distSq = dx*dx + dy*dy + dz*dz;
return entity->shouldRenderAtSqrDistance(distSq);
}
bool MobRenderer::shouldShowName(shared_ptr<LivingEntity> mob)
{
return LivingEntityRenderer::shouldShowName(mob) && (mob->shouldShowName() || dynamic_pointer_cast<Mob>(mob)->hasCustomName());

View file

@ -14,6 +14,7 @@ class MobRenderer : public LivingEntityRenderer
public:
MobRenderer(Model *model, float shadow);
virtual void render(shared_ptr<Entity> mob, double x, double y, double z, float rot, float a);
virtual bool shouldRender(shared_ptr<Entity> entity, float camX, float camY, float camZ) override;
protected:
virtual bool shouldShowName(shared_ptr<LivingEntity> mob);

View file

@ -191,6 +191,9 @@ const wchar_t *Textures::preLoaded[TN_COUNT] =
L"mob/endermite",
L"mob/guardian",
L"mob/guardian_elder",
L"mob/guardian_beam",
#ifdef _LARGE_WORLDS
L"misc/additionalmapicons",

View file

@ -177,6 +177,9 @@ typedef enum _TEXTURE_NAME
TN_MOB_ENDERMITE,
TN_MOB_GUARDIAN,
TN_MOB_GUARDIAN_ELDER,
TN_MOB_GUARDIAN_BEAM,
#ifdef _LARGE_WORLDS

View file

@ -622,6 +622,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_MODEL
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandModel.h"
"${CMAKE_CURRENT_SOURCE_DIR}/EndermiteModel.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/EndermiteModel.h"
"${CMAKE_CURRENT_SOURCE_DIR}/GuardianModel.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GuardianModel.h"
)
source_group("net/minecraft/client/model" FILES ${_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_MODEL})
@ -899,6 +901,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_RENDERER_ENTITY
"${CMAKE_CURRENT_SOURCE_DIR}/RabbitRenderer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandRenderer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/EndermiteRenderer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GuardianRenderer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GuardianRenderer.h"
)
source_group("net/minecraft/client/renderer/entity" FILES ${_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_RENDERER_ENTITY})

View file

@ -389,4 +389,9 @@ void glTexGen(int coord, int mode, FloatBuffer *vec)
void glCullFace(int dir)
{
RenderManager.StateSetFaceCullCW( dir == GL_BACK);
}
}
void glTexParameterf(int target, int param, float value)
{
RenderManager.TextureSetParam(param, (int)value);
}

View file

@ -114,7 +114,7 @@ void glFogf(int,float);
void glFog(int,FloatBuffer *);
void glColorMaterial(int,int);
void glMultiTexCoord2f(int, float, float);
void glTexParameterf(int target, int param, float value);
//1.8.2
void glClientActiveTexture(int);
void glActiveTexture(int);

View file

@ -168,9 +168,11 @@ enum eINSTANCEOF
eTYPE_BLAZE = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x6,
eTYPE_WITCH = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x7,
eTYPE_WITHERBOSS = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x8,
eTYPE_GUARDIAN = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x9,
eTYPE_ENDERMITE = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x10,
eTYPE_ELDER_GUARDIAN = eTYPE_MONSTER | eTYPE_VALID_IN_SPAWNER_FLAG | 0x11,
eTYPE_AMBIENT = eTYPE_MOB | BIT_AMBIENT_MOB,

View file

@ -46,7 +46,7 @@ void EntityIO::staticCtor()
{
setId(ItemEntity::create, eTYPE_ITEMENTITY, L"Item", 1);
setId(ExperienceOrb::create, eTYPE_EXPERIENCEORB, L"XPOrb", 2);
setId(Guardian::create, eTYPE_ELDER_GUARDIAN, L"ElderGuardian", 4, eMinecraftColour_Armour_Default_Leather_Colour, eMinecraftColour_Sky_IceMountains, IDS_PIGZOMBIE);
setId(LeashFenceKnotEntity::create, eTYPE_LEASHFENCEKNOT, L"LeashKnot", 8);
setId(Painting::create, eTYPE_PAINTING, L"Painting", 9);
setId(Arrow::create, eTYPE_ARROW, L"Arrow", 10);
@ -95,6 +95,12 @@ void EntityIO::staticCtor()
setId(WitherBoss::create, eTYPE_WITHERBOSS, L"WitherBoss", 64);
setId(Bat::create, eTYPE_BAT, L"Bat", 65, eMinecraftColour_Mob_Bat_Colour1, eMinecraftColour_Mob_Bat_Colour2, IDS_BAT);
setId(Witch::create, eTYPE_WITCH, L"Witch", 66, eMinecraftColour_Mob_Witch_Colour1, eMinecraftColour_Mob_Witch_Colour2, IDS_WITCH);
setId(Endermite::create, eTYPE_ENDERMITE, L"Endermite", 67,
eMinecraftColour_Mob_Endermite_Colour1,
eMinecraftColour_Mob_Endermite_Colour2, IDS_ENDERMITE);
setId(Guardian::create, eTYPE_GUARDIAN, L"Guardian", 68, eMinecraftColour_Mob_Witch_Colour1, eMinecraftColour_Mob_Witch_Colour2, IDS_WITCH);
setId(Pig::create, eTYPE_PIG, L"Pig", 90, eMinecraftColour_Mob_Pig_Colour1, eMinecraftColour_Mob_Pig_Colour2, IDS_PIG);
@ -114,9 +120,7 @@ void EntityIO::staticCtor()
setId(ArmorStand::create, eTYPE_ARMORSTAND, L"ArmorStand", 102);
setId(Endermite::create, eTYPE_ENDERMITE, L"Endermite", 67,
eMinecraftColour_Mob_Endermite_Colour1,
eMinecraftColour_Mob_Endermite_Colour2, IDS_ENDERMITE);//change IDS_Endermite later
//change IDS_Endermite later
setId(Villager::create, eTYPE_VILLAGER, L"Villager", 120, eMinecraftColour_Mob_Villager_Colour1, eMinecraftColour_Mob_Villager_Colour2, IDS_VILLAGER);

View file

@ -0,0 +1,480 @@
#include "stdafx.h"
#include "com.mojang.nbt.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.phys.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.item.h"
#include "net.minecraft.world.entity.h"
#include "net.minecraft.world.entity.player.h"
#include "net.minecraft.world.entity.ai.attributes.h"
#include "net.minecraft.world.entity.monster.h"
#include "net.minecraft.world.damagesource.h"
#include "SharedConstants.h"
#include "Guardian.h"
#include "..\Minecraft.Client\Textures.h"
#include "..\Minecraft.World\Mth.h"
#include "..\Minecraft.World\net.minecraft.world.entity.animal.h"
#include "MobEffect.h"
#include "MobEffectInstance.h"
void Guardian::_init()
{
clientSideTailAnimation = 0.0f;
clientSideTailAnimationO = 0.0f;
clientSideSpikesAnimation = 0.0f;
clientSideSpikesAnimationO = 0.0f;
clientSideAttackTime = 0.0f;
clientSideTouchedGround = false;
xBodyRot = xBodyRotO = 0.0f;
zBodyRot = zBodyRotO = 0.0f;
tx = ty = tz = 0.0f;
attackTimer = 0;
}
Guardian::Guardian(Level *level) : WaterAnimal(level)
{
this->defineSynchedData();
registerAttributes();
setHealth(getMaxHealth());
_init();
if (isElder()) {
this->setSize(1.9975f, 1.9975f);
}
else {
this->setSize(0.85f, 0.85f);
}
}
void Guardian::registerAttributes()
{
WaterAnimal::registerAttributes();
getAttributes()->registerAttribute(SharedMonsterAttributes::ATTACK_DAMAGE);
getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(6.0);
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.5);
getAttribute(SharedMonsterAttributes::FOLLOW_RANGE)->setBaseValue(16.0);
getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(30.0);
}
void Guardian::defineSynchedData()
{
WaterAnimal::defineSynchedData();
entityData->define(16, (byte)0);
entityData->define(17, 0);
}
// NBT
void Guardian::readAdditionalSaveData(CompoundTag *tag)
{
WaterAnimal::readAdditionalSaveData(tag);
setElder(tag->getBoolean(L"Elder"));
}
void Guardian::addAdditonalSaveData(CompoundTag *tag)
{
WaterAnimal::addAdditonalSaveData(tag);
tag->putBoolean(L"Elder", isElder());
}
bool Guardian::isElder()
{
return (entityData->getByte(16) & 4) != 0;
}
void Guardian::setElder(bool elder)
{
byte flags = entityData->getByte(16);
if (elder)
{
entityData->set(16, (byte)(flags | 4));
this->setSize(1.9975f, 1.9975f);
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.30000001192092896);
getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(8.0);
getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(80.0);
setHealth(getMaxHealth());
}
else
{
entityData->set(16, (byte)(flags & ~4));
this->setSize(0.85f, 0.85f);
}
}
void Guardian::setElderClient()
{
setElder(true);
clientSideSpikesAnimation = clientSideSpikesAnimationO = 1.0f;
}
bool Guardian::isMoving()
{
return (entityData->getByte(16) & 2) != 0;
}
void Guardian::setMoving(bool moving)
{
byte flags = entityData->getByte(16);
if (moving)
entityData->set(16, (byte)(flags | 2));
else
entityData->set(16, (byte)(flags & ~2));
}
int Guardian::getTargetedEntityId()
{
return entityData->getInteger(17);
}
void Guardian::setTargetedEntityId(int id)
{
entityData->set(17, id);
entityData->markDirty(17);
}
bool Guardian::hasTargetedEntity()
{
return entityData->getInteger(17) != 0;
}
shared_ptr<LivingEntity> Guardian::getTargetedEntity()
{
if (!hasTargetedEntity())
return nullptr;
if (level->isClientSide)
{
if (targetedEntity != nullptr)
return targetedEntity;
shared_ptr<Entity> entity = level->getEntity(getTargetedEntityId());
if (entity != nullptr && dynamic_pointer_cast<LivingEntity>(entity))
{
targetedEntity = dynamic_pointer_cast<LivingEntity>(entity);
return targetedEntity;
}
return nullptr;
}
shared_ptr<Entity> e = level->getEntity(getTargetedEntityId());
return dynamic_pointer_cast<LivingEntity>(e);
}
int Guardian::getAttackDuration()
{
// Java func_175464_ck
return isElder() ? 60 : 80;
}
float Guardian::getAttackAnimationScale(float partialTicks)
{
return (clientSideAttackTime + partialTicks) / (float)getAttackDuration();
}
// Java func_175471_a
float Guardian::getTailAnimation(float partialTicks)
{
return clientSideSpikesAnimationO + (clientSideSpikesAnimation - clientSideSpikesAnimationO) * partialTicks;
}
// Java func_175469_o
float Guardian::getSpikesAnimation(float partialTicks)
{
return isMoving() ? 1.0f : 0.0f;
}
int Guardian::getAmbientSound() { return -1; }
int Guardian::getHurtSound() { return -1; }
int Guardian::getDeathSound() { return -1; }
float Guardian::getSoundVolume() { return 1.0f; }
int Guardian::getDeathLoot() { return 0; }
bool Guardian::makeStepSound() { return false; }
void Guardian::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel)
{
//loot (prismarine, sponge)
}
float Guardian::getEyeHeight()
{
return bbHeight * 0.5f;
}
bool Guardian::isInWater()
{
return level->checkAndHandleWater(bb->grow(0, -0.6f, 0), Material::water, shared_from_this());
}
float Guardian::rotlerp(float a, float b, float max)
{
float f = Mth::wrapDegrees(b - a);
if (f > max) f = max;
if (f < -max) f = -max;
return a + f;
}
void Guardian::lookAt(shared_ptr<Entity> e, float yMax, float xMax)
{
double d0 = e->x - x;
double d1 = e->z - z;
double d2;
if (dynamic_pointer_cast<LivingEntity>(e))
{
shared_ptr<LivingEntity> living = dynamic_pointer_cast<LivingEntity>(e);
d2 = living->y + living->getEyeHeight() - (y + getEyeHeight());
}
else
{
d2 = (e->bb->y0 + e->bb->y1) / 2.0 - (y + getEyeHeight());
}
double d3 = sqrt(d0 * d0 + d1 * d1);
float f = (float)(atan2(d1, d0) * 180.0 / PI) - 90.0f;
float f1 = (float)(-(atan2(d2, d3) * 180.0 / PI));
xRot = rotlerp(xRot, f1, xMax);
yRot = rotlerp(yRot, f, yMax);
}
void Guardian::serverAiStep()
{
WaterAnimal::serverAiStep();
if (isElder() && !level->isClientSide)
{
if (((tickCount + entityId) % 1200 == 0))
{
auto& players = level->players;
for (int i = 0; i < (int)players.size(); i++)
{
shared_ptr<Player> player = players[i];
if (!player) continue;
if (distanceToSqr(player) >= 2500.0)
continue;
if (player->abilities.invulnerable)
continue;
MobEffectInstance *existing = player->getEffect(MobEffect::digSlowdown);
if (existing == nullptr || existing->getAmplifier() < 2 || existing->getDuration() < 1200)
{
player->addEffect(new MobEffectInstance(MobEffect::digSlowdown->id, 6000, 2));
}
}
}
}
if (!hasTargetedEntity())
{
shared_ptr<Player> nearest = level->getNearestPlayer(x, y, z, 16.0);
if (nearest != nullptr && canSee(nearest) && !nearest->abilities.invulnerable)
{
setTargetedEntityId(nearest->entityId);
attackTimer = 0;
}
}
shared_ptr<LivingEntity> target = getTargetedEntity();
if (target != nullptr)
{
if (!target->isAlive() || distanceToSqr(target) > 256.0 || !canSee(target))
{
setTargetedEntityId(0);
target = nullptr;
}
}
if (target != nullptr)
{
lookAt(target, 90.0f, 90.0f);
setMoving(false);
tx = ty = tz = 0.0f;
attackTimer++;
if (attackTimer == 1)
{
level->broadcastEntityEvent(shared_from_this(), 21);
}
else if (attackTimer >= getAttackDuration())
{
float dmg = 1.0f;
if (isElder()) dmg += 2.0f;
target->hurt(DamageSource::mobAttack(dynamic_pointer_cast<LivingEntity>(shared_from_this())), dmg);
target->hurt(DamageSource::magic,
(float)getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->getValue());
setTargetedEntityId(0);
attackTimer = 0;
}
}
else
{
attackTimer = 0;
setTargetedEntityId(0);
noActionTime++;
if (noActionTime > 100 || random->nextInt(50) == 0 ||
(tx == 0.0f && ty == 0.0f && tz == 0.0f))
{
float angle = random->nextFloat() * (float)PI * 2.0f;
tx = Mth::cos(angle) * 0.2f;
ty = -0.1f + random->nextFloat() * 0.2f;
tz = Mth::sin(angle) * 0.2f;
noActionTime = 0;
}
setMoving(true);
}
if (isMoving())
{
xd += (tx - xd) * 0.1f;
yd += (ty - yd) * 0.1f;
zd += (tz - zd) * 0.1f;
double horizontalMovement = sqrt(xd * xd + zd * zd);
yBodyRot += ((-static_cast<float>(atan2(xd, zd)) * 180.0f / (float)PI) - yBodyRot) * 0.1f;
yRot = yBodyRot;
zBodyRot = zBodyRot + (float)PI * 0.05f;
xBodyRot += ((-static_cast<float>(atan2(horizontalMovement, yd)) * 180.0f / (float)PI) - xBodyRot) * 0.1f;
}
}
void Guardian::aiStep()
{
if (level->isClientSide)
{
clientSideTailAnimationO = clientSideTailAnimation;
if (!isInWater())
{
clientSideTailAnimation = 2.0f;
clientSideTouchedGround = yd < 0.0 &&
level->hasChunkAt(Mth::floor(x), Mth::floor(y - 1), Mth::floor(z));
}
else if (isMoving())
{
if (clientSideTailAnimation < 0.5f)
clientSideTailAnimation = 4.0f;
else
clientSideTailAnimation += (0.5f - clientSideTailAnimation) * 0.1f;
}
else
{
clientSideTailAnimation += (0.125f - clientSideTailAnimation) * 0.2f;
}
clientSideSpikesAnimationO = clientSideSpikesAnimation;
clientSideSpikesAnimation += clientSideTailAnimation;
if (hasTargetedEntity() && clientSideAttackTime < (float)getAttackDuration())
clientSideAttackTime++;
else if (!hasTargetedEntity())
clientSideAttackTime = 0.0f;
}
if (isInWater())
{
setAirSupply(300);
}
else if (onGround)
{
yd += 0.5;
xd += (random->nextFloat() * 2.0f - 1.0f) * 0.4f;
zd += (random->nextFloat() * 2.0f - 1.0f) * 0.4f;
yRot = random->nextFloat() * 360.0f;
onGround = false;
hasImpulse = true;
}
if (hasTargetedEntity())
yRot = yHeadRot;
xBodyRotO = xBodyRot;
zBodyRotO = zBodyRot;
WaterAnimal::aiStep();
}
void Guardian::updateSize(bool elder)
{
if (elder)
this->setSize(1.9975f, 1.9975f);
else
setSize(0.85f, 0.85f);
}
void Guardian::travel(float xa, float ya)
{
if (level->isClientSide)
{
if (isInWater())
{
move(xd, yd, zd);
xd *= 0.9f;
yd *= 0.9f;
zd *= 0.9f;
}
else
{
WaterAnimal::travel(xa, ya);
}
}
else
{
if (isInWater())
{
moveRelative(xa, ya, 0.1f);
move(xd, yd, zd);
xd *= 0.9f;
yd *= 0.9f;
zd *= 0.9f;
}
else
{
WaterAnimal::travel(xa, ya);
}
}
}
MobGroupData *Guardian::finalizeMobSpawn(MobGroupData *groupData, int extraData)
{
WaterAnimal::finalizeMobSpawn(groupData, extraData);
if (extraData == 1)
setElder(true);
return groupData;
}

View file

@ -0,0 +1,79 @@
#pragma once
using namespace std;
#include "WaterAnimal.h"
class Level;
class Player;
class Guardian : public WaterAnimal
{
public:
eINSTANCEOF GetType() { return eTYPE_GUARDIAN; }
static Entity *create(Level *level) { return new Guardian(level); }
void _init();
float clientSideTailAnimation;
float clientSideTailAnimationO;
float clientSideSpikesAnimation;
float clientSideSpikesAnimationO;
float clientSideAttackTime;
bool clientSideTouchedGround;
float xBodyRot, xBodyRotO;
float zBodyRot, zBodyRotO;
Guardian(Level *level);
protected:
virtual void registerAttributes();
virtual void defineSynchedData();
virtual int getAmbientSound();
virtual int getHurtSound();
virtual int getDeathSound();
virtual float getSoundVolume();
virtual int getDeathLoot();
virtual bool makeStepSound();
virtual void dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel);
virtual void serverAiStep();
public:
virtual bool isInWater();
virtual void aiStep();
virtual void travel(float xa, float ya);
virtual void readAdditionalSaveData(CompoundTag *tag);
virtual void addAdditonalSaveData(CompoundTag *tag);
virtual float getEyeHeight();
void updateSize(bool isElder);
bool isElder();
void setElder(bool elder);
void setElderClient();
bool isMoving();
void setMoving(bool moving);
int getTargetedEntityId();
void setTargetedEntityId(int entityId);
bool hasTargetedEntity();
shared_ptr<LivingEntity> getTargetedEntity();
virtual MobGroupData *finalizeMobSpawn(MobGroupData *groupData, int extraData = 0) override;
int getAttackDuration();
float getTailAnimation(float partialTicks);
float getSpikesAnimation(float partialTicks);
float getAttackAnimationScale(float partialTicks);
protected:
void lookAt(shared_ptr<Entity> e, float yMax, float xMax);
private:
float rotlerp(float a, float b, float max);
float tx, ty, tz;
int attackTimer;
shared_ptr<LivingEntity> targetedEntity;
};

View file

@ -2033,3 +2033,34 @@ bool LivingEntity::isAlliedTo(Team *other)
}
return false;
}
float LivingEntity::getEyeHeight()
{
return getHeadHeight();
}
Vec3 *LivingEntity::getPositionEyes(float partialTicks)
{
if (partialTicks == 1.0f)
{
return Vec3::newTemp(x, y + (double)getEyeHeight(), z);
}
else
{
double d0 = xo + (x - xo) * (double)partialTicks;
double d1 = yo + (y - yo) * (double)partialTicks + (double)getEyeHeight();
double d2 = zo + (z - zo) * (double)partialTicks;
return Vec3::newTemp(d0, d1, d2);
}
}
HitResult *LivingEntity::rayTrace(double blockReachDistance, float partialTicks)
{
Vec3 *vec3 = this->getPositionEyes(partialTicks);
Vec3 *vec31 = this->getViewVector(partialTicks);
Vec3 *vec32 = vec3->add(vec31->x * blockReachDistance, vec31->y * blockReachDistance, vec31->z * blockReachDistance);
return this->level->clip(vec3, vec32, false, false);
}

View file

@ -320,4 +320,9 @@ public:
virtual Team *getTeam();
virtual bool isAlliedTo(shared_ptr<LivingEntity> other);
virtual bool isAlliedTo(Team *other);
public:
virtual float getEyeHeight();
virtual Vec3 *getPositionEyes(float partialTicks);
virtual HitResult *rayTrace(double blockReachDistance, float partialTicks);
};

View file

@ -6,10 +6,16 @@
#include "Mth.h"
#include "LevelData.h"
void OceanMonumentFeature::_init()
{
spacing = 32;
separation = 5;
monumentEnemies.push_back(new Biome::MobSpawnerData(eTYPE_GUARDIAN, 1, 2, 4));
}
std::vector<Biome::MobSpawnerData*>* OceanMonumentFeature::getMonumentEnemies()
{
return &monumentEnemies;
}
OceanMonumentFeature::OceanMonumentFeature() : StructureFeature() { _init(); }

View file

@ -14,7 +14,7 @@ class OceanMonumentFeature : public StructureFeature
{
public:
// static void staticCtor(); // Removed, merged into _init
std::vector<Biome::MobSpawnerData*> monumentEnemies;
private:
int spacing;
int separation;
@ -22,6 +22,7 @@ private:
void _init();
public:
vector<Biome::MobSpawnerData*>* getMonumentEnemies();
OceanMonumentFeature();
OceanMonumentFeature(std::unordered_map<std::wstring, std::wstring> options);
~OceanMonumentFeature();
@ -49,4 +50,5 @@ public:
};
};

View file

@ -8,7 +8,8 @@
#include <algorithm>
#include <random>
#include <vector>
#include "Squid.h"
#include "Guardian.h"
@ -176,18 +177,16 @@ bool OceanMonumentPieces::Piece::intersectsXZ(BoundingBox* chunkBB, int x0, int
bool OceanMonumentPieces::Piece::spawnElderGuardian(Level* level, BoundingBox* bb, int x, int y, int z)
{
int wx = getWorldX(x, z);
int wy = getWorldY(y);
int wz = getWorldZ(x, z);
if (bb->isInside(wx, wy, wz))
{
Squid *guardian = new Squid(level);
//guardian->setElder(true);
Guardian* guardian = new Guardian(level);
guardian->setElder(true);
guardian->heal(guardian->getMaxHealth());
/*entityguardian.setLocationAndAngles((double)i + 0.5D, (double)j, (double)k + 0.5D, 0.0F, 0.0F);
entityguardian.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityguardian)), (IEntityLivingData)null);
worldIn.spawnEntityInWorld(entityguardian);*/
guardian->setPos((double)wx + 0.5, (double)wy, (double)wz + 0.5);
level->addEntity(shared_ptr<Entity>(guardian));
return true;
}
return false;
@ -1080,7 +1079,7 @@ bool OceanMonumentPieces::SimpleTopRoom::postProcess(Level* level, Random* rando
if (random->nextInt(3) != 0)
{
int k = 2 + (random->nextInt(4) == 0 ? 0 : 1);
generateBox(level, chunkBB, i, k, j, i, 3, j, Tile::sponge_Id, 1, false);
generateBox(level, chunkBB, i, k, j, i, 3, j, Tile::sponge_Id, 1, Tile::sponge_Id, 1, false);
}
}

View file

@ -846,9 +846,16 @@ vector<Biome::MobSpawnerData *> *RandomLevelSource::getMobsAt(MobCategory *mobCa
{
return nullptr;
}
if (mobCategory == MobCategory::monster && scatteredFeature->isSwamphut(x, y, z))
if (mobCategory == MobCategory::monster)
{
return scatteredFeature->getSwamphutEnemies();
if (scatteredFeature->isSwamphut(x, y, z))
{
return scatteredFeature->getSwamphutEnemies();
}
if (oceanMonument->isInsideFeature(x, y, z))
{
return oceanMonument->getMonumentEnemies();
}
}
return biome->getMobs(mobCategory);
}

View file

@ -10,7 +10,8 @@
#include "HitResult.h"
#include "SpawnEggItem.h"
#include "Difficulty.h"
#include <Guardian.h>
#include "AABB.h"
SpawnEggItem::SpawnEggItem(int id) : Item(id)
{
@ -335,7 +336,19 @@ shared_ptr<Entity> SpawnEggItem::spawnMobAt(Level *level, int auxVal, double x,
mob->yBodyRot = mob->yRot;
mob->finalizeMobSpawn(nullptr, extraData);
level->addEntity(newEntity);
if (mobId == 4)
{
shared_ptr<Guardian> g = dynamic_pointer_cast<Guardian>(newEntity);
if (g)
g->setElder(true);
}
mob->playAmbientSound();
}
}

View file

@ -781,6 +781,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ANIMAL
"${CMAKE_CURRENT_SOURCE_DIR}/WaterAnimal.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Wolf.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Wolf.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Rabbit.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Rabbit.h"
"${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.entity.animal.h"
)
source_group("net/minecraft/world/entity/animal" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ANIMAL})
@ -845,6 +847,9 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ITEM
"${CMAKE_CURRENT_SOURCE_DIR}/MinecartTNT.h"
"${CMAKE_CURRENT_SOURCE_DIR}/PrimedTnt.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/PrimedTnt.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStand.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStand.h"
"${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.entity.item.h"
)
source_group("net/minecraft/world/entity/item" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ITEM})
@ -885,6 +890,12 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_MONSTER
"${CMAKE_CURRENT_SOURCE_DIR}/Witch.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Zombie.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Zombie.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Endermite.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Endermite.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Guardian.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Guardian.h"
"${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.entity.monster.h"
)
source_group("net/minecraft/world/entity/monster" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_MONSTER})
@ -1997,10 +2008,7 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_TILE
"${CMAKE_CURRENT_SOURCE_DIR}/SeaLanternTile.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/PrismarineTile.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/TallGrass2.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Rabbit.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Endermite.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStand.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/FishFoodItem.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandItem.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/SavannaTreeFeature.cpp"

View file

@ -28,3 +28,4 @@
//TU 31
#include "Endermite.h"
#include "Guardian.h"