mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-08 22:12:56 +00:00
feat: Guardians
This commit is contained in:
parent
c7127b219d
commit
61b6e6adca
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
BIN
Minecraft.Client/Common/res/1_2_2/mob/guardian.png
Normal file
BIN
Minecraft.Client/Common/res/1_2_2/mob/guardian.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1,016 B |
BIN
Minecraft.Client/Common/res/1_2_2/mob/guardian_beam.png
Normal file
BIN
Minecraft.Client/Common/res/1_2_2/mob/guardian_beam.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 B |
BIN
Minecraft.Client/Common/res/1_2_2/mob/guardian_elder.png
Normal file
BIN
Minecraft.Client/Common/res/1_2_2/mob/guardian_elder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 965 B |
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -407,6 +407,7 @@ void EntityRenderer::registerTerrainTextures(IconRegister *iconRegister)
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
ResourceLocation *EntityRenderer::getTextureLocation(shared_ptr<Entity> mob)
|
||||
{
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
};
|
||||
|
|
|
|||
147
Minecraft.Client/GuardianModel.cpp
Normal file
147
Minecraft.Client/GuardianModel.cpp
Normal 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);
|
||||
}
|
||||
25
Minecraft.Client/GuardianModel.h
Normal file
25
Minecraft.Client/GuardianModel.h
Normal 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;
|
||||
};
|
||||
239
Minecraft.Client/GuardianRenderer.cpp
Normal file
239
Minecraft.Client/GuardianRenderer.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
42
Minecraft.Client/GuardianRenderer.h
Normal file
42
Minecraft.Client/GuardianRenderer.h
Normal 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;
|
||||
};
|
||||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
480
Minecraft.World/Guardian.cpp
Normal file
480
Minecraft.World/Guardian.cpp
Normal 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;
|
||||
}
|
||||
79
Minecraft.World/Guardian.h
Normal file
79
Minecraft.World/Guardian.h
Normal 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;
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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:
|
|||
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -28,3 +28,4 @@
|
|||
|
||||
//TU 31
|
||||
#include "Endermite.h"
|
||||
#include "Guardian.h"
|
||||
|
|
|
|||
Loading…
Reference in a new issue