#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(model); } ResourceLocation *GuardianRenderer::getTextureLocation(shared_ptr mob) { shared_ptr guardian = dynamic_pointer_cast(mob); if (guardian && guardian->isElder()) return &GUARDIAN_ELDER_LOCATION; return &GUARDIAN_LOCATION; } bool GuardianRenderer::shouldRender(shared_ptr mob, float camX, float camY, float camZ) { if (MobRenderer::shouldRender(mob, camX, camY, camZ)) return true; shared_ptr guardian = dynamic_pointer_cast(mob); if (!guardian || !guardian->hasTargetedEntity()) return false; shared_ptr 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 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 _mob, float bob, float bodyRot, float a) { shared_ptr mob = dynamic_pointer_cast(_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 _mob, double x, double y, double z, float rot, float a) { MobRenderer::render(_mob, x, y, z, rot, a); shared_ptr mob = dynamic_pointer_cast(_mob); if (!mob || !mob->hasTargetedEntity()) return; shared_ptr 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 mob, float wp, float ws, float bob, float headRotMinusBodyRot, float headRotx, float scale) { shared_ptr guardian = dynamic_pointer_cast(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); } }