Merge branch 'main' into fix/fourkit

This commit is contained in:
/home/neo 2026-04-18 11:33:49 +03:00 committed by GitHub
commit be4bfdbdcc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
64 changed files with 2880 additions and 1574 deletions

View file

@ -0,0 +1,36 @@
#include "stdafx.h"
#include "AbstractArmorLayer.h"
#include "LivingEntityRenderer.h"
#include "HumanoidModel.h"
AbstractArmorLayer::AbstractArmorLayer(LivingEntityRenderer* renderer)
: armorModel1(nullptr),
armorModel2(nullptr),
renderer(renderer),
colorR(1.0f),
colorG(1.0f),
colorB(1.0f),
colorA(1.0f),
hasColor(false)
{
}
HumanoidModel* AbstractArmorLayer::getArmorModel(int slot) {
if (slot == 2)
return armorModel1;
return armorModel2;
}
int AbstractArmorLayer::colorsOnDamage() {
return 0;
}
void AbstractArmorLayer::resetColor() {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
hasColor = false;
}
void AbstractArmorLayer::createArmorModels() {
// default: no-op
}

View file

@ -0,0 +1,27 @@
#pragma once
#include <memory>
using namespace std;
class LivingEntityRenderer;
class HumanoidModel;
class LivingEntity;
class AbstractArmorLayer {
public:
HumanoidModel* armorModel1;
HumanoidModel* armorModel2;
LivingEntityRenderer* renderer;
float colorR;
float colorG;
float colorB;
float colorA;
bool hasColor;
explicit AbstractArmorLayer(LivingEntityRenderer* renderer);
virtual ~AbstractArmorLayer() {}
virtual HumanoidModel* getArmorModel(int slot);
virtual void createArmorModels();
virtual int colorsOnDamage();
virtual void resetColor();
};

View file

@ -0,0 +1,70 @@
#include "stdafx.h"
#include "ArmorStandArmorModel.h"
#include "ModelPart.h"
#include "../Minecraft.World/ArmorStand.h"
static const float DEG_TO_RAD = 0.017453292f;
ArmorStandArmorModel::ArmorStandArmorModel(float scale, int texWidth, int texHeight)
: HumanoidModel(scale, 0.0f, texWidth, texHeight)
{
}
ArmorStandArmorModel::~ArmorStandArmorModel() {}
void ArmorStandArmorModel::setupAnim(float time, float r, float bob,
float yRot, float xRot, float scale,
shared_ptr<Entity> entity,
unsigned int uiBitmaskOverrideAnim)
{
if (!entity) return;
if (!entity->instanceof(eTYPE_ARMORSTAND)) return;
shared_ptr<ArmorStand> stand = dynamic_pointer_cast<ArmorStand>(entity);
if (!stand) return;
Rotations h = stand->getHeadPose();
Rotations b = stand->getBodyPose();
Rotations la = stand->getLeftArmPose();
Rotations ra = stand->getRightArmPose();
Rotations ll = stand->getLeftLegPose();
Rotations rl = stand->getRightLegPose();
head->xRot = DEG_TO_RAD * h.getX();
head->yRot = DEG_TO_RAD * h.getY();
head->zRot = DEG_TO_RAD * h.getZ();
head->setPos(0.0f, 1.0f, 0.0f);
body->xRot = DEG_TO_RAD * b.getX();
body->yRot = DEG_TO_RAD * b.getY();
body->zRot = DEG_TO_RAD * b.getZ();
arm0->xRot = DEG_TO_RAD * la.getX();
arm0->yRot = DEG_TO_RAD * la.getY();
arm0->zRot = DEG_TO_RAD * la.getZ();
arm1->xRot = DEG_TO_RAD * ra.getX();
arm1->yRot = DEG_TO_RAD * ra.getY();
arm1->zRot = DEG_TO_RAD * ra.getZ();
leg1->xRot = DEG_TO_RAD * ll.getX();
leg1->yRot = DEG_TO_RAD * ll.getY();
leg1->zRot = DEG_TO_RAD * ll.getZ();
leg1->setPos(1.9f, 11.0f, 0.0f);
leg0->xRot = DEG_TO_RAD * rl.getX();
leg0->yRot = DEG_TO_RAD * rl.getY();
leg0->zRot = DEG_TO_RAD * rl.getZ();
leg0->setPos(-1.9f, 11.0f, 0.0f);
ModelPart::copyModelPart(head, hair);
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "HumanoidModel.h"
class Entity;
class ArmorStandArmorModel : public HumanoidModel {
public:
ArmorStandArmorModel(float scale,
int texWidth = 64,
int texHeight = 32);
virtual ~ArmorStandArmorModel();
virtual void setupAnim(float time, float r, float bob,
float yRot, float xRot, float scale,
shared_ptr<Entity> entity,
unsigned int uiBitmaskOverrideAnim = 0) override;
};

View file

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

View file

@ -1,23 +1,23 @@
#pragma once
#include "HumanoidModel.h"
#include "HumanoidModel.h"
#include "ModelPart.h"
class ArmorStandModel : public HumanoidModel
{
public:
ModelPart *rightBodyStick;
ModelPart *leftBodyStick;
ModelPart *shoulderStick;
ModelPart *basePlate;
ModelPart* rightBodyStick;
ModelPart* leftBodyStick;
ModelPart* shoulderStick;
ModelPart* basePlate;
bool showArms;
bool showBasePlate;
bool isSmall;
ArmorStandModel(float scale = 0.0f);
virtual ~ArmorStandModel() {}
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot,
float scale, shared_ptr<Entity> entity,
unsigned int uiBitmaskOverrideAnim = 0) override;
ArmorStandModel();
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr<Entity> entity, unsigned int uiBitmaskOverrideAnim ) override;
void setupPose(float hX, float hY, float hZ,
float bX, float bY, float bZ,
float lAX, float lAY, float lAZ,

View file

@ -1,61 +1,99 @@
#include "stdafx.h"
#include "ArmorStandRenderer.h"
#include "Textures.h"
#include "HumanoidModel.h"
#include "ArmorStandModel.h"
#include "..\Minecraft.World\ArmorStand.h"
class ArmorStandArmorModel : public HumanoidModel {
public:
ArmorStandArmorModel(float scale) : HumanoidModel(scale) {}
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr<Entity> entity, unsigned int uiBitmaskOverrideAnim = 0) override {
}
};
#include "ArmorStandArmorModel.h"
#include "HumanoidModel.h"
#include "ItemInHandLayer.h"
#include "CustomHeadLayer.h"
#include "Textures.h"
#include "HumanoidMobRenderer.h"
#include "../Minecraft.World/ArmorStand.h"
#include "../Minecraft.World/ArmorItem.h"
static const float DEG_TO_RAD = 3.14159265f / 180.0f;
ResourceLocation ArmorStandRenderer::LOC_ARMOR_STAND = ResourceLocation(TN_MOB_ARMORSTAND);
ResourceLocation ArmorStandRenderer::LOC_ARMOR_STAND =
ResourceLocation(TN_MOB_ARMORSTAND);
ArmorStandRenderer::ArmorStandRenderer()
: HumanoidMobRenderer(new ArmorStandModel(), 0.0f, 1.0f)
ArmorStandRenderer::ArmorStandArmorLayer::ArmorStandArmorLayer(
LivingEntityRenderer* renderer)
: HumanoidArmorLayer(renderer)
{
createArmorParts();
delete armorModel1;
delete armorModel2;
armorModel1 = new ArmorStandArmorModel(0.5f);
armorModel2 = new ArmorStandArmorModel(1.0f);
}
void ArmorStandRenderer::ArmorStandArmorLayer::createArmorModels()
{
delete armorModel1;
delete armorModel2;
armorModel1 = new ArmorStandArmorModel(0.5f);
armorModel2 = new ArmorStandArmorModel(1.0f);
}
ResourceLocation *ArmorStandRenderer::getTextureLocation(shared_ptr<Entity> entity)
ArmorStandRenderer::ArmorStandRenderer()
: LivingEntityRenderer(new ArmorStandModel(0.0f), 0.0f)
{
addLayer(new ArmorStandArmorLayer(this));
addLayer(new ItemInHandLayer(this));
ArmorStandModel* m = static_cast<ArmorStandModel*>(getModel());
addLayer(new CustomHeadLayer(m->head));
}
ArmorStandRenderer::~ArmorStandRenderer()
{
}
ResourceLocation* ArmorStandRenderer::getTextureLocation(shared_ptr<Entity> entity)
{
return &LOC_ARMOR_STAND;
}
void ArmorStandRenderer::createArmorParts()
bool ArmorStandRenderer::shouldShowName(shared_ptr<LivingEntity> entity)
{
armorParts1 = new ArmorStandArmorModel(1.0f);
armorParts2 = new ArmorStandArmorModel(0.5f);
if (!entity) return false;
return entity->isCustomNameVisible();
}
void ArmorStandRenderer::render(shared_ptr<Entity> entity, double x, double y, double z, float rot, float a)
{
HumanoidMobRenderer::render(entity, x, y, z, rot, a);
}
void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale)
void ArmorStandRenderer::setupRotations(shared_ptr<LivingEntity> mob,
float bob, float bodyRot, float a)
{
glRotatef(180.0f - bodyRot, 0.0f, 1.0f, 0.0f);
}
void ArmorStandRenderer::render(shared_ptr<Entity> entity,
double x, double y, double z,
float rot, float a)
{
LivingEntityRenderer::render(entity, x, y, z, rot, a);
}
void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRotMinusBodyRot,
float headRotx, float scale)
{
shared_ptr<ArmorStand> stand = dynamic_pointer_cast<ArmorStand>(mob);
if (!stand) return;
ArmorStandModel *m = static_cast<ArmorStandModel *>(model);
ArmorStandModel* m = static_cast<ArmorStandModel*>(getModel());
if (!m) return;
Rotations h = stand->getHeadPose();
Rotations b = stand->getBodyPose();
@ -66,46 +104,118 @@ void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob, float wp, flo
m->setupPose(
h.x * DEG_TO_RAD, h.y * DEG_TO_RAD, h.z * DEG_TO_RAD,
b.x * DEG_TO_RAD, b.y * DEG_TO_RAD, b.z * DEG_TO_RAD,
la.x * DEG_TO_RAD, la.y * DEG_TO_RAD, la.z * DEG_TO_RAD,
ra.x * DEG_TO_RAD, ra.y * DEG_TO_RAD, ra.z * DEG_TO_RAD,
ll.x * DEG_TO_RAD, ll.y * DEG_TO_RAD, ll.z * DEG_TO_RAD,
rl.x * DEG_TO_RAD, rl.y * DEG_TO_RAD, rl.z * DEG_TO_RAD
h.getX() * DEG_TO_RAD, h.getY() * DEG_TO_RAD, h.getZ() * DEG_TO_RAD,
b.getX() * DEG_TO_RAD, b.getY() * DEG_TO_RAD, b.getZ() * DEG_TO_RAD,
la.getX() * DEG_TO_RAD, la.getY() * DEG_TO_RAD, la.getZ() * DEG_TO_RAD,
ra.getX() * DEG_TO_RAD, ra.getY() * DEG_TO_RAD, ra.getZ() * DEG_TO_RAD,
ll.getX() * DEG_TO_RAD, ll.getY() * DEG_TO_RAD, ll.getZ() * DEG_TO_RAD,
rl.getX() * DEG_TO_RAD, rl.getY() * DEG_TO_RAD, rl.getZ() * DEG_TO_RAD
);
HumanoidModel *a1 = static_cast<HumanoidModel*>(armorParts1);
if (a1) {
a1->head->xRot = h.x * DEG_TO_RAD; a1->head->yRot = h.y * DEG_TO_RAD; a1->head->zRot = h.z * DEG_TO_RAD;
if (a1->hair) { a1->hair->xRot = h.x * DEG_TO_RAD; a1->hair->yRot = h.y * DEG_TO_RAD; a1->hair->zRot = h.z * DEG_TO_RAD; }
a1->body->xRot = b.x * DEG_TO_RAD; a1->body->yRot = b.y * DEG_TO_RAD; a1->body->zRot = b.z * DEG_TO_RAD;
a1->arm0->xRot = ra.x * DEG_TO_RAD; a1->arm0->yRot = ra.y * DEG_TO_RAD; a1->arm0->zRot = ra.z * DEG_TO_RAD; // right
a1->arm1->xRot = la.x * DEG_TO_RAD; a1->arm1->yRot = la.y * DEG_TO_RAD; a1->arm1->zRot = la.z * DEG_TO_RAD; // left
a1->leg0->xRot = rl.x * DEG_TO_RAD; a1->leg0->yRot = rl.y * DEG_TO_RAD; a1->leg0->zRot = rl.z * DEG_TO_RAD; // right
a1->leg1->xRot = ll.x * DEG_TO_RAD; a1->leg1->yRot = ll.y * DEG_TO_RAD; a1->leg1->zRot = ll.z * DEG_TO_RAD; // left
}
HumanoidModel *a2 = static_cast<HumanoidModel*>(armorParts2);
if (a2) {
a2->head->xRot = h.x * DEG_TO_RAD; a2->head->yRot = h.y * DEG_TO_RAD; a2->head->zRot = h.z * DEG_TO_RAD;
if (a2->hair) { a2->hair->xRot = h.x * DEG_TO_RAD; a2->hair->yRot = h.y * DEG_TO_RAD; a2->hair->zRot = h.z * DEG_TO_RAD; }
a2->body->xRot = b.x * DEG_TO_RAD; a2->body->yRot = b.y * DEG_TO_RAD; a2->body->zRot = b.z * DEG_TO_RAD;
a2->arm0->xRot = ra.x * DEG_TO_RAD; a2->arm0->yRot = ra.y * DEG_TO_RAD; a2->arm0->zRot = ra.z * DEG_TO_RAD;
a2->arm1->xRot = la.x * DEG_TO_RAD; a2->arm1->yRot = la.y * DEG_TO_RAD; a2->arm1->zRot = la.z * DEG_TO_RAD;
a2->leg0->xRot = rl.x * DEG_TO_RAD; a2->leg0->yRot = rl.y * DEG_TO_RAD; a2->leg0->zRot = rl.z * DEG_TO_RAD;
a2->leg1->xRot = ll.x * DEG_TO_RAD; a2->leg1->yRot = ll.y * DEG_TO_RAD; a2->leg1->zRot = ll.z * DEG_TO_RAD;
}
HumanoidMobRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale);
ArmorStandArmorLayer* al = getArmorLayer();
if (al)
{
auto applyPose = [&](HumanoidModel* am)
{
if (!am) return;
am->head->xRot = h.getX() * DEG_TO_RAD;
am->head->yRot = h.getY() * DEG_TO_RAD;
am->head->zRot = h.getZ() * DEG_TO_RAD;
if (am->hair) {
am->hair->xRot = h.getX() * DEG_TO_RAD;
am->hair->yRot = h.getY() * DEG_TO_RAD;
am->hair->zRot = h.getZ() * DEG_TO_RAD;
}
am->body->xRot = b.getX() * DEG_TO_RAD;
am->body->yRot = b.getY() * DEG_TO_RAD;
am->body->zRot = b.getZ() * DEG_TO_RAD;
am->arm1->xRot = la.getX() * DEG_TO_RAD;
am->arm1->yRot = la.getY() * DEG_TO_RAD;
am->arm1->zRot = la.getZ() * DEG_TO_RAD;
am->arm0->xRot = ra.getX() * DEG_TO_RAD;
am->arm0->yRot = ra.getY() * DEG_TO_RAD;
am->arm0->zRot = ra.getZ() * DEG_TO_RAD;
am->leg0->xRot = rl.getX() * DEG_TO_RAD;
am->leg0->yRot = rl.getY() * DEG_TO_RAD;
am->leg0->zRot = rl.getZ() * DEG_TO_RAD;
am->leg1->xRot = ll.getX() * DEG_TO_RAD;
am->leg1->yRot = ll.getY() * DEG_TO_RAD;
am->leg1->zRot = ll.getZ() * DEG_TO_RAD;
};
applyPose(static_cast<HumanoidModel*>(al->armorModel1));
applyPose(static_cast<HumanoidModel*>(al->armorModel2));
}
LivingEntityRenderer::renderModel(mob, wp, ws, bob,
headRotMinusBodyRot, headRotx, scale);
for (size_t i = 0; i < renderLayers.size(); ++i) {
if (renderLayers[i]) {
renderLayers[i]->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true);
}
}
}
int ArmorStandRenderer::prepareArmor(shared_ptr<LivingEntity> mob, int layer, float a)
{
if (!armorLayer) return -1;
shared_ptr<ItemInstance> itemInstance = mob->getArmor(3 - layer);
if (itemInstance != nullptr)
{
Item *item = itemInstance->getItem();
ArmorItem *armorItem = dynamic_cast<ArmorItem *>(item);
if (armorItem != nullptr)
{
bindTexture(HumanoidMobRenderer::getArmorLocation(armorItem, layer));
HumanoidModel *am = armorLayer->getArmorModel(layer);
am->head->visible = (layer == 0);
if (am->hair) am->hair->visible = (layer == 0);
am->body->visible = (layer == 1 || layer == 2);
am->arm0->visible = (layer == 1);
am->arm1->visible = (layer == 1);
am->leg0->visible = (layer == 2 || layer == 3);
am->leg1->visible = (layer == 2 || layer == 3);
setArmor(am);
am->attackTime = model->attackTime;
am->riding = model->riding;
am->young = mob->isBaby();
if (armorItem->getMaterial() == ArmorItem::ArmorMaterial::CLOTH)
{
int color = armorItem->getColor(itemInstance);
float red = static_cast<float>((color >> 16) & 0xFF) / 255.0f;
float green = static_cast<float>((color >> 8) & 0xFF) / 255.0f;
float blue = static_cast<float>(color & 0xFF) / 255.0f;
glColor3f(red, green, blue);
if (itemInstance->isEnchanted()) return 0x1f;
return 0x10;
}
glColor3f(1.0f, 1.0f, 1.0f);
if (itemInstance->isEnchanted()) return 15;
return 1;
}
}
return -1;
}

View file

@ -1,24 +1,54 @@
#pragma once
#include "HumanoidMobRenderer.h"
#include "ArmorStandModel.h"
#include "..\Minecraft.World\ArmorStand.h"
#include "LivingEntityRenderer.h"
#include "HumanoidArmorLayer.h"
#include "ResourceLocation.h"
class ArmorStandRenderer : public HumanoidMobRenderer
{
private:
static ResourceLocation LOC_ARMOR_STAND;
#include <vector>
class ArmorStandModel;
class LivingEntity;
class Entity;
class RenderLayer;
class ArmorStandRenderer : public LivingEntityRenderer {
public:
ArmorStandRenderer();
virtual ~ArmorStandRenderer() {}
virtual void render(shared_ptr<Entity> entity, double x, double y, double z, float rot, float a) override;
virtual ResourceLocation *getTextureLocation(shared_ptr<Entity> entity) override;
class ArmorStandArmorLayer : public HumanoidArmorLayer {
public:
explicit ArmorStandArmorLayer(LivingEntityRenderer* renderer);
virtual ~ArmorStandArmorLayer() {}
virtual void createArmorModels() override;
};
protected:
virtual void createArmorParts() override;
std::vector<RenderLayer*> renderLayers;
ArmorStandArmorLayer* armorLayer;
virtual void renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotx, float scale) override;
public:
void addLayer(RenderLayer* layer) {
renderLayers.push_back(layer);
}
void addLayer(ArmorStandArmorLayer* layer) {
armorLayer = layer;
}
ArmorStandArmorLayer* getArmorLayer() {
return armorLayer;
}
static ResourceLocation LOC_ARMOR_STAND;
ArmorStandRenderer();
virtual ~ArmorStandRenderer();
virtual ResourceLocation* getTextureLocation(shared_ptr<Entity> entity) override;
virtual bool shouldShowName(shared_ptr<LivingEntity> mob) override;
virtual void setupRotations(shared_ptr<LivingEntity> mob,
float bob, float bodyRot, float a) override;
virtual void render(shared_ptr<Entity> entity,
double x, double y, double z,
float rot, float a) override;
virtual void renderModel(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRotMinusBodyRot,
float headRotx, float scale) override;
virtual int prepareArmor(shared_ptr<LivingEntity> mob, int layer, float a) override;
};

View file

@ -4300,20 +4300,22 @@ void ClientConnection::handleSetPlayerTeamPacket(shared_ptr<SetPlayerTeamPacket>
void ClientConnection::handleParticleEvent(shared_ptr<LevelParticlesPacket> packet)
{
wstring particleName = packet->getName();
ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)Integer::parseInt(particleName);
const ParticleType* type = packet->getType();
if (type == nullptr) return;
for (int i = 0; i < packet->getCount(); i++)
{
double xVarience = random->nextGaussian() * packet->getXDist();
double yVarience = random->nextGaussian() * packet->getYDist();
double zVarience = random->nextGaussian() * packet->getZDist();
double xa = random->nextGaussian() * packet->getMaxSpeed();
double ya = random->nextGaussian() * packet->getMaxSpeed();
double za = random->nextGaussian() * packet->getMaxSpeed();
ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)type->getId();
level->addParticle(particleId, packet->getX() + xVarience, packet->getY() + yVarience, packet->getZ() + zVarience, xa, ya, za);
}
for (int i = 0; i < packet->getCount(); i++)
{
double xVarience = random->nextGaussian() * packet->getXDist();
double yVarience = random->nextGaussian() * packet->getYDist();
double zVarience = random->nextGaussian() * packet->getZDist();
double xa = random->nextGaussian() * packet->getMaxSpeed();
double ya = random->nextGaussian() * packet->getMaxSpeed();
double za = random->nextGaussian() * packet->getMaxSpeed();
level->addParticle(particleId, packet->getX() + xVarience, packet->getY() + yVarience, packet->getZ() + zVarience, xa, ya, za);
}
}
void ClientConnection::handleUpdateAttributes(shared_ptr<UpdateAttributesPacket> packet)

View file

@ -242,6 +242,34 @@ CMinecraftApp::CMinecraftApp()
}
void CMinecraftApp::GetSkinAdjustments(_SkinAdjustments* out,
unsigned int skinId)
{
_SkinAdjustments adj;
EnterCriticalSection(&csAdditionalSkinBoxes);
if (!m_SkinAdjustmentsMap.empty())
{
auto it = m_SkinAdjustmentsMap.find(skinId);
if (it != m_SkinAdjustmentsMap.end())
adj = it->second;
}
LeaveCriticalSection(&csAdditionalSkinBoxes);
*out = adj;
}
void CMinecraftApp::SetSkinAdjustments(unsigned int skinId,
const _SkinAdjustments& adj)
{
EnterCriticalSection(&csAdditionalSkinBoxes);
m_SkinAdjustmentsMap[skinId] = adj;
LeaveCriticalSection(&csAdditionalSkinBoxes);
}
void CMinecraftApp::DebugPrintf(const char *szFormat, ...)
{

View file

@ -24,6 +24,8 @@ using namespace std;
#include "../ArchiveFile.h"
#include "lce_filesystem/FolderFile.h"
typedef struct _JoinFromInviteData
{
DWORD dwUserIndex; // dwUserIndex
@ -53,6 +55,7 @@ class Model;
class ModelPart;
class StringTable;
class Merchant;
struct _SkinAdjustments;
class CMinecraftAudio;
@ -64,7 +67,7 @@ class CMinecraftApp
{
private:
static int s_iHTMLFontSizesA[eHTMLSize_COUNT];
unordered_map<unsigned int, _SkinAdjustments> m_SkinAdjustmentsMap;
public:
CMinecraftApp();
@ -82,6 +85,8 @@ public:
// storing credits text from the DLC
std::vector <wstring > m_vCreditText; // hold the credit text lines so we can avoid duplicating them
void GetSkinAdjustments(_SkinAdjustments* out,unsigned int skinId);
void SetSkinAdjustments(unsigned int skinId, const _SkinAdjustments& adj);
// In builds prior to TU5, the size of the GAME_SETTINGS struct was 204 bytes. We added a few new values to the internal struct in TU5, and even though we
// changed the size of the ucUnused array to be decreased by the size of the values we added, the packing of the struct has introduced some extra

View file

@ -15,7 +15,11 @@ DLCSkinFile::DLCSkinFile(const wstring &path) : DLCFile(DLCManager::e_DLCType_Sk
m_bIsFree = false;
m_uiAnimOverrideBitmask=0L;
}
void DLCSkinFile::getSkinAdjustments(_SkinAdjustments* adj)
{
memcpy(adj, &m_skinAdjustments, sizeof(_SkinAdjustments));
}
void DLCSkinFile::addData(PBYTE pbData, DWORD dwBytes)
{
app.AddMemoryTextureFile(m_path,pbData,dwBytes);

View file

@ -1,6 +1,7 @@
#pragma once
#include "DLCFile.h"
#include "../../../Minecraft.Client/HumanoidModel.h"
#include "../../../Minecraft.World/Entity.h"
class DLCSkinFile : public DLCFile
{
@ -12,11 +13,12 @@ private:
unsigned int m_uiAnimOverrideBitmask;
bool m_bIsFree;
vector<SKIN_BOX *> m_AdditionalBoxes;
_SkinAdjustments m_skinAdjustments;
public:
DLCSkinFile(const wstring &path);
void getSkinAdjustments(_SkinAdjustments* adj);
void addData(PBYTE pbData, DWORD dwBytes) override;
void addParameter(DLCManager::EDLCParameterType type, const wstring &value) override;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,78 @@
#include "stdafx.h"
#include "CustomHeadLayer.h"
#include "ModelPart.h"
#include "../Minecraft.World/ItemInstance.h"
#include "../Minecraft.World/Item.h"
#include "../Minecraft.World/Tile.h"
#include "../Minecraft.World/LivingEntity.h"
CustomHeadLayer::CustomHeadLayer(ModelPart* headPart)
: headPart(headPart)
{
}
int CustomHeadLayer::colorsOnDamage() {
return 1;
}
void CustomHeadLayer::render(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRot, float headRotX,
float scale, bool useCompiled)
{
ItemInstanceArray slots = mob->getEquipmentSlots();
if (slots.length < 5) return;
shared_ptr<ItemInstance> helmet = slots[4];
if (!helmet) return;
Item* item = helmet->getItem();
if (!item) return;
bool hasHatLayer = false;
if (mob->instanceof(eTYPE_PLAYER)) {
_SkinAdjustments adj;
mob->getSkinAdjustments(&adj);
hasHatLayer = (adj.data[0] & 0x100) != 0;
}
glPushMatrix();
headPart->translateTo(0.0625f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
int itemId = item->id;
if (itemId == Tile::skull_Id) {
glScalef(1.1875f, -1.1875f, -1.1875f);
if (hasHatLayer)
glTranslatef(0.0f, 0.0625f, 0.0f);
} else if (itemId < 0x100) {
glTranslatef(0.0f, -0.25f, 0.0f);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
glScalef(0.625f, -0.625f, -0.625f);
if (hasHatLayer)
glTranslatef(0.0f, 0.1875f, 0.0f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
if (itemId > 0 && itemId < Tile::TILE_NUM_COUNT && Tile::tiles[itemId]) {
}
}
glPopMatrix();
}

View file

@ -0,0 +1,20 @@
#pragma once
#include "RenderLayer.h"
class ModelPart;
class LivingEntity;
class CustomHeadLayer : public RenderLayer {
public:
ModelPart* headPart;
explicit CustomHeadLayer(ModelPart* headPart);
virtual ~CustomHeadLayer() {}
virtual int colorsOnDamage() override;
virtual void render(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRot, float headRotX,
float scale, bool useCompiled) override;
};

View file

@ -180,3 +180,7 @@ void GameMode::handleDebugOptions(unsigned int uiVal, shared_ptr<Player> player)
{
player->SetDebugOptions(uiVal);
}
bool GameMode::isSpectator()
{
return gameType == GameType::SPECTATOR;
}

View file

@ -0,0 +1,47 @@
#include "stdafx.h"
#include "HumanoidArmorLayer.h"
#include "HumanoidModel.h"
#include "ModelPart.h"
HumanoidArmorLayer::HumanoidArmorLayer(LivingEntityRenderer* renderer)
: AbstractArmorLayer(renderer)
{
armorModel1 = new HumanoidModel(0.5f);
armorModel2 = new HumanoidModel(1.0f);
}
void HumanoidArmorLayer::createArmorModels() {
delete armorModel1;
delete armorModel2;
armorModel1 = new HumanoidModel(0.5f);
armorModel2 = new HumanoidModel(1.0f);
}
void HumanoidArmorLayer::setPartVisibility(HumanoidModel* m, unsigned int slot) {
m->setAllVisible(false);
switch (slot) {
case 0: break;
case 1:
m->leg0->visible = true;
m->leg1->visible = true;
break;
case 2:
m->body->visible = true;
m->leg0->visible = true;
m->leg1->visible = true;
break;
case 3:
m->arm1->visible = true;
m->arm0->visible = true;
break;
case 4:
m->head->visible = true;
if (m->hair) m->hair->visible = true;
break;
default: break;
}
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "AbstractArmorLayer.h"
class LivingEntityRenderer;
class LivingEntity;
class HumanoidArmorLayer : public AbstractArmorLayer {
public:
explicit HumanoidArmorLayer(LivingEntityRenderer* renderer);
virtual ~HumanoidArmorLayer() {}
virtual void createArmorModels() override;
virtual void setPartVisibility(HumanoidModel* model, unsigned int slot);
};

View file

@ -967,4 +967,39 @@ void HumanoidModel::render(HumanoidModel *model, float scale, bool usecompiled)
pants0->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants0))>0);
if (pants1)
pants1->render(scale, usecompiled,(m_uiAnimOverrideBitmask&(1<<eAnim_DisableRenderPants1))>0);
}
void HumanoidModel::setAllVisible(bool v) {
head->visible = v;
hair->visible = v;
body->visible = v;
arm1->visible = v;
arm0->visible = v;
leg0->visible = v;
leg1->visible = v;
}
void HumanoidModel::translateToHandItem(float scale) {
arm1->translateTo(scale);
}
bool HumanoidModel::IsBodyPartDisabled(animbits bit) {
return (m_uiAnimOverrideBitmask & (1u << bit)) != 0;
}
void HumanoidModel::copyPropertiesFrom(HumanoidModel* other) {
if (!other) return;
idle = other->idle;
sneaking = other->sneaking;
bowAndArrow = other->bowAndArrow;
eating = other->eating;
eating_t = other->eating_t;
eating_swing = other->eating_swing;
holdingLeftHand = other->holdingLeftHand;
holdingRightHand = other->holdingRightHand;
m_uiAnimOverrideBitmask = other->m_uiAnimOverrideBitmask;
m_fYOffset = other->m_fYOffset;
}

View file

@ -1,78 +1,93 @@
#pragma once
#pragma once
#include "Model.h"
class HumanoidModel : public Model
{
public:
ModelPart *head, *hair, *body, *jacket, *arm0, *sleeve0, *arm1, *sleeve1, *leg0, *pants0, *leg1, *pants1, *ear, *cloak;
//ModelPart *hat;
int holdingLeftHand;
ModelPart *head, *hair, *body, *jacket, *arm0, *sleeve0, *arm1, *sleeve1, *leg0, *pants0, *leg1, *pants1, *ear, *cloak;
int holdingLeftHand;
int holdingRightHand;
bool idle;
bool sneaking;
bool bowAndArrow;
bool eating; // 4J added
float eating_t; // 4J added
float eating_swing; // 4J added
unsigned int m_uiAnimOverrideBitmask; // 4J added
float m_fYOffset; // 4J added
enum animbits
{
eAnim_ArmsDown =0,
eAnim_ArmsOutFront,
eAnim_NoLegAnim,
eAnim_HasIdle,
eAnim_ForceAnim, // Claptrap looks bad if the user turns off custom skin anim
// 4J-PB - DaveK wants Fish characters to move both legs in the same way
eAnim_SingleLegs,
eAnim_SingleArms,
eAnim_StatueOfLiberty, // Dr Who Weeping Angel
eAnim_DontRenderArmour, // Dr Who Daleks
eAnim_NoBobbing, // Dr Who Daleks
eAnim_DisableRenderHead,
eAnim_DisableRenderArm0,
eAnim_DisableRenderArm1,
eAnim_DisableRenderTorso,
eAnim_DisableRenderLeg0,
eAnim_DisableRenderLeg1,
eAnim_DisableRenderHair,
eAnim_SmallModel,
eAnim_DisableRenderJacket,
eAnim_DisableRenderSleeve0,
eAnim_DisableRenderSleeve1,
eAnim_DisableRenderPants0,
eAnim_DisableRenderPants1
};
bool idle;
bool sneaking;
bool bowAndArrow;
bool eating;
float eating_t;
float eating_swing;
unsigned int m_uiAnimOverrideBitmask;
float m_fYOffset;
static const unsigned int m_staticBitmaskIgnorePlayerCustomAnimSetting= (1<<HumanoidModel::eAnim_ForceAnim) |
(1<<HumanoidModel::eAnim_DisableRenderArm0) |
(1<<HumanoidModel::eAnim_DisableRenderArm1) |
(1<<HumanoidModel::eAnim_DisableRenderTorso) |
(1<<HumanoidModel::eAnim_DisableRenderLeg0) |
(1<<HumanoidModel::eAnim_DisableRenderLeg1) |
(1<<HumanoidModel::eAnim_DisableRenderHair) |
(1<<HumanoidModel::eAnim_DisableRenderJacket) |
(1<<HumanoidModel::eAnim_DisableRenderSleeve0) |
(1<<HumanoidModel::eAnim_DisableRenderSleeve1) |
(1<<HumanoidModel::eAnim_DisableRenderPants0) |
(1<<HumanoidModel::eAnim_DisableRenderPants1);
enum animbits
{
eAnim_ArmsDown = 0,
eAnim_ArmsOutFront,
eAnim_NoLegAnim,
eAnim_HasIdle,
eAnim_ForceAnim,
eAnim_SingleLegs,
eAnim_SingleArms,
eAnim_StatueOfLiberty,
eAnim_DontRenderArmour,
eAnim_NoBobbing,
eAnim_DisableRenderHead,
eAnim_DisableRenderArm0,
eAnim_DisableRenderArm1,
eAnim_DisableRenderTorso,
eAnim_DisableRenderLeg0,
eAnim_DisableRenderLeg1,
eAnim_DisableRenderHair,
eAnim_SmallModel,
eAnim_DisableRenderJacket,
eAnim_DisableRenderSleeve0,
eAnim_DisableRenderSleeve1,
eAnim_DisableRenderPants0,
eAnim_DisableRenderPants1
};
static const unsigned int m_staticBitmaskIgnorePlayerCustomAnimSetting =
(1 << HumanoidModel::eAnim_ForceAnim) |
(1 << HumanoidModel::eAnim_DisableRenderArm0) |
(1 << HumanoidModel::eAnim_DisableRenderArm1) |
(1 << HumanoidModel::eAnim_DisableRenderTorso) |
(1 << HumanoidModel::eAnim_DisableRenderLeg0) |
(1 << HumanoidModel::eAnim_DisableRenderLeg1) |
(1 << HumanoidModel::eAnim_DisableRenderHair) |
(1 << HumanoidModel::eAnim_DisableRenderJacket) |
(1 << HumanoidModel::eAnim_DisableRenderSleeve0) |
(1 << HumanoidModel::eAnim_DisableRenderSleeve1) |
(1 << HumanoidModel::eAnim_DisableRenderPants0) |
(1 << HumanoidModel::eAnim_DisableRenderPants1);
void _init(float g, float yOffset, int texWidth, int texHeight,
bool slimHands, bool mirror, bool force32);
void _init(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror, bool force32); // 4J added
HumanoidModel();
HumanoidModel(float g);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror, bool force32);
virtual void render(shared_ptr<Entity> entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled);
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr<Entity> entity, unsigned int uiBitmaskOverrideAnim = 0);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight, bool slimHands, bool mirror, bool force32);
virtual void render(shared_ptr<Entity> entity, float time, float r, float bob,
float yRot, float xRot, float scale, bool usecompiled);
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot,
float scale, shared_ptr<Entity> entity,
unsigned int uiBitmaskOverrideAnim = 0);
void renderHair(float scale, bool usecompiled);
void renderEars(float scale, bool usecompiled);
void renderCloak(float scale, bool usecompiled);
void render(HumanoidModel *model, float scale, bool usecompiled);
void renderCloak(float scale, bool usecompiled);
void render(HumanoidModel* model, float scale, bool usecompiled);
// Add new bits to models
ModelPart * AddOrRetrievePart(SKIN_BOX *pBox);
};
ModelPart* AddOrRetrievePart(SKIN_BOX* pBox);
void setAllVisible(bool visible);
void translateToHandItem(float scale);
void copyPropertiesFrom(HumanoidModel* other);
bool IsBodyPartDisabled(animbits bit);
};

View file

@ -0,0 +1,63 @@
#include "stdafx.h"
#include "ItemInHandLayer.h"
#include "LivingEntityRenderer.h"
#include "ModelPart.h"
#include "../Minecraft.World/ItemInstance.h"
#include "../Minecraft.World/Item.h"
#include "../Minecraft.World/LivingEntity.h"
#include "../Minecraft.World/Tile.h"
ItemInHandLayer::ItemInHandLayer(LivingEntityRenderer* renderer)
: renderer(renderer)
{
}
int ItemInHandLayer::colorsOnDamage() {
return 0;
}
void ItemInHandLayer::render(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRot, float headRotX,
float scale, bool useCompiled)
{
ItemInstanceArray slots = mob->getEquipmentSlots();
if (slots.length == 0) return;
shared_ptr<ItemInstance> item = slots[0];
if (!item) return;
Item* heldItem = item->getItem();
if (!heldItem) return;
glPushMatrix();
glTranslatef(-0.0625f, 0.4375f, 0.0625f);
int itemId = heldItem->id;
if (itemId > 0 && itemId < 0x100) {
if (Tile::tiles[itemId]) {
int shape = Tile::tiles[itemId]->getRenderShape();
if (shape == Tile::SHAPE_BLOCK) {
glTranslatef(0.0f, 0.1875f, -0.3125f);
glRotatef(20.0f, 1.0f, 0.0f, 0.0f);
glRotatef(45.0f, 0.0f, 1.0f, 0.0f);
glScalef(-0.375f, -0.375f, 0.375f);
}
}
} else {
glTranslatef(0.25f, 0.1875f, -0.1875f);
glScalef(0.375f, 0.375f, 0.375f);
glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glRotatef(20.0f, 0.0f, 0.0f, 1.0f);
}
// TODO: renderItem
glPopMatrix();
}

View file

@ -0,0 +1,20 @@
#pragma once
#include "RenderLayer.h"
class LivingEntityRenderer;
class LivingEntity;
class ItemInHandLayer : public RenderLayer {
public:
LivingEntityRenderer* renderer;
explicit ItemInHandLayer(LivingEntityRenderer* renderer);
virtual ~ItemInHandLayer() {}
virtual int colorsOnDamage() override;
virtual void render(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRot, float headRotX,
float scale, bool useCompiled) override;
};

View file

@ -157,7 +157,7 @@ void LocalPlayer::serverAiStep()
// mapPlayerChunk(8);
}
bool LocalPlayer::isEffectiveAi()
bool LocalPlayer::isEffectiveAi() const
{
return true;
}

View file

@ -95,7 +95,7 @@ public:
virtual void serverAiStep();
protected:
bool isEffectiveAi();
bool isEffectiveAi() const;
public:
virtual void aiStep();

View file

@ -321,3 +321,14 @@ void ModelPart::mimic(ModelPart *o)
yRot = o->yRot;
zRot = o->zRot;
}
void ModelPart::copyModelPart(ModelPart* src, ModelPart* dst) {
if (!src || !dst) return;
dst->x = src->x;
dst->y = src->y;
dst->z = src->z;
dst->xRot = src->xRot;
dst->yRot = src->yRot;
dst->zRot = src->zRot;
}

View file

@ -60,4 +60,5 @@ public:
void compile(float scale);
int getfU() {return xTexOffs;}
int getfV() {return yTexOffs;}
static void copyModelPart(ModelPart* src, ModelPart* dst);
};

View file

@ -0,0 +1,39 @@
#include "stdafx.h"
#include "ParticleType.h"
ParticleType::ParticleType(const std::string& name, int id, bool overrideLimiter, int paramCount)
{
this->name = name;
this->id = id;
this->overrideLimiter = overrideLimiter;
this->paramCount = paramCount;
}
int ParticleType::getId() const
{
return id;
}
bool ParticleType::getOverrideLimiter() const
{
return overrideLimiter;
}
int ParticleType::getParamCount() const
{
return paramCount;
}
const ParticleType* ParticleType::getDefault()
{
return nullptr;
}
const ParticleType* ParticleType::byId(int searchId)
{
return nullptr;
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <string>
class ParticleType
{
private:
std::string name;
int id;
bool overrideLimiter;
int paramCount;
public:
ParticleType(const std::string& name, int id, bool overrideLimiter, int paramCount);
int getId() const;
bool getOverrideLimiter() const;
int getParamCount() const;
static const ParticleType* byId(int id);
static const ParticleType* getDefault();
};

View file

@ -0,0 +1,14 @@
#pragma once
#include <memory>
using namespace std;
class LivingEntity;
class RenderLayer {
public:
virtual ~RenderLayer() {}
virtual int colorsOnDamage() = 0;
virtual void render(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob,
float headRot, float headRotX,
float scale, bool useCompiled) = 0;
};

View file

@ -1283,22 +1283,6 @@ PortalForcer *ServerLevel::getPortalForcer()
return portalForcer;
}
void ServerLevel::sendParticles(const wstring &name, double x, double y, double z, int count)
{
sendParticles(name, x + 0.5f, y + 0.5f, z + 0.5f, count, 0.5f, 0.5f, 0.5f, 0.02f);
}
void ServerLevel::sendParticles(const wstring &name, double x, double y, double z, int count, double xDist, double yDist, double zDist, double speed)
{
shared_ptr<Packet> packet = std::make_shared<LevelParticlesPacket>( name, static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(xDist), static_cast<float>(yDist), static_cast<float>(zDist), static_cast<float>(speed), count );
for(auto& it : players)
{
shared_ptr<ServerPlayer> player = dynamic_pointer_cast<ServerPlayer>(it);
player->connection->send(packet);
}
}
// 4J Stu - Sometimes we want to update tiles on the server from the main thread (eg SignTileEntity when string verify returns)
void ServerLevel::queueSendTileUpdate(int x, int y, int z)
{
@ -1631,4 +1615,35 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFoun
{
chunkMap->flagEntitiesToBeRemoved(flags, removedFound);
}
}
}
void ServerLevel::sendParticles(const ParticleType* type, bool longDistance, double x, double y, double z, int count, double dx, double dy, double dz, double speed, arrayWithLength<int> data)
{
auto packet = make_shared<LevelParticlesPacket>(
type,
longDistance,
(float)x, (float)y, (float)z,
(float)dx, (float)dy, (float)dz,
(float)speed,
count,
data
);
for (auto const& p : players)
{
shared_ptr<ServerPlayer> player = dynamic_pointer_cast<ServerPlayer>(p);
if (player != nullptr && player->connection != nullptr)
{
double distSqr = player->distanceToSqr(x, y, z);
if (distSqr <= 256.0 || (longDistance && distSqr <= 65536.0))
{
player->connection->send(packet);
}
}
}
}
void ServerLevel::sendParticles(const ParticleType* type, double x, double y, double z, int count, double dx, double dy, double dz, double speed, arrayWithLength<int> data)
{
this->sendParticles(type, false, x, y, z, count, dx, dy, dz, speed, data);
}

View file

@ -1,11 +1,14 @@
#pragma once
#include "../Minecraft.World/net.minecraft.world.level.h"
#include "../Minecraft.World/JavaIntHash.h"
#include "../Minecraft.World/ArrayWithLength.h"
#include "ParticleType.h"
class ServerChunkCache;
class MinecraftServer;
class Node;
class EntityTracker;
class PlayerChunkMap;
class ArrayWithLength;
using namespace std;
class ServerLevel : public Level
@ -180,5 +183,6 @@ public:
static C4JThread* m_updateThread;
static int runUpdate(void* lpParam);
virtual void sendParticles(const ParticleType* type, bool longDistance, double x, double y, double z, int count, double dx, double dy, double dz, double speed, arrayWithLength<int> data);
virtual void sendParticles(const ParticleType* type, double x, double y, double z, int count, double dx, double dy, double dz, double speed, arrayWithLength<int> data);
};

View file

@ -2065,3 +2065,11 @@ void ServerPlayer::debug_setPosition(double x, double y, double z, double nYRot,
connection->teleport(x, y, z, nYRot, nXRot);
}
#endif
bool ServerPlayer::isSpectator()
{
if (gameMode == nullptr)
{
return false;
}
return gameMode->getGameType() == GameType::SPECTATOR;
}

View file

@ -158,6 +158,7 @@ public:
static int getFlagIndexForChunk(const ChunkPos& pos, int dimension); // 4J - added
int getPlayerViewDistanceModifier(); // 4J Added, returns a number which is subtracted from the default view distance
bool isSpectator();
public:
// 4J Stu - Added hooks for the game rules

View file

@ -454,3 +454,8 @@ void ServerPlayerGameMode::setGameRules(GameRulesInstance *rules)
if(m_gameRules != nullptr) delete m_gameRules;
m_gameRules = rules;
}
GameType* ServerPlayerGameMode::getGameType()
{
return gameModeForPlayer;
}

View file

@ -32,6 +32,7 @@ private:
public:
void setGameRules(GameRulesInstance *rules);
GameRulesInstance *getGameRules() { return m_gameRules; }
GameType* getGameType();
public:
ServerPlayerGameMode(Level *level);

View file

@ -181,7 +181,7 @@ const wchar_t *Textures::preLoaded[TN_COUNT] =
L"item/trapped",
L"item/trapped_double",
L"item/armor_stand",
L"mob/armor_stand",
//L"item/christmas",

View file

@ -647,6 +647,17 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_MODEL_GEOM
"${CMAKE_CURRENT_SOURCE_DIR}/ModelPart.h"
"${CMAKE_CURRENT_SOURCE_DIR}/TexOffs.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/TexOffs.h"
"${CMAKE_CURRENT_SOURCE_DIR}/AbstractArmorLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/AbstractArmorLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/HumanoidArmorLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/HumanoidArmorLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandArmorModel.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ArmorStandArmorModel.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ItemInHandLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ItemInHandLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/CustomHeadLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/CustomHeadLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RenderLayer.h"
)
source_group("net/minecraft/client/model/geom" FILES ${_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_MODEL_GEOM})
@ -729,6 +740,8 @@ set(_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_PARTICLE
"${CMAKE_CURRENT_SOURCE_DIR}/TerrainParticle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/WaterDropParticle.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/WaterDropParticle.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ParticleType.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ParticleType.cpp"
)
source_group("net/minecraft/client/particle" FILES ${_MINECRAFT_CLIENT_COMMON_NET_MINECRAFT_CLIENT_PARTICLE})

File diff suppressed because it is too large Load diff

View file

@ -1,19 +1,15 @@
#pragma once
#include "Mob.h"
#include "Rotations.h"
#include "SynchedEntityData.h"
#include "Vec3.h"
#include "Random.h"
struct Rotations
{
float x, y, z;
Rotations() : x(0), y(0), z(0) {}
Rotations(float x, float y, float z) : x(x), y(y), z(z) {}
};
class ArmorStand : public Mob
class ArmorStand : public LivingEntity
{
public:
eINSTANCEOF GetType() { return eTYPE_ARMORSTAND; }
static Entity *create(Level *level) { return new ArmorStand(level); }
eINSTANCEOF GetType() override { return eTYPE_ARMORSTAND; }
static Entity* create(Level* level) { return new ArmorStand(level); }
static const Rotations DEFAULT_HEAD_POSE;
static const Rotations DEFAULT_BODY_POSE;
@ -23,50 +19,63 @@ public:
static const Rotations DEFAULT_RIGHT_LEG_POSE;
private:
static const int DATA_CLIENT_FLAGS = 10;
static const int DATA_HEAD_POSE_X = 11;
static const int DATA_HEAD_POSE_Y = 12;
static const int DATA_HEAD_POSE_Z = 13;
static const int DATA_BODY_POSE_X = 14;
static const int DATA_BODY_POSE_Y = 15;
static const int DATA_BODY_POSE_Z = 16;
static const int DATA_LEFT_ARM_X = 17;
static const int DATA_LEFT_ARM_Y = 18;
static const int DATA_LEFT_ARM_Z = 19;
static const int DATA_RIGHT_ARM_X = 20;
static const int DATA_RIGHT_ARM_Y = 21;
static const int DATA_RIGHT_ARM_Z = 22;
static const int DATA_LEFT_LEG_X = 23;
static const int DATA_LEFT_LEG_Y = 24;
static const int DATA_LEFT_LEG_Z = 25;
static const int DATA_RIGHT_LEG_X = 26;
static const int DATA_RIGHT_LEG_Y = 27;
static const int DATA_RIGHT_LEG_Z = 28;
static const int DATA_CLIENT_FLAGS = 0xA;
static const int DATA_HEAD_POSE = 0xB;
static const int DATA_BODY_POSE = 0xC;
static const int DATA_LEFT_ARM_POSE = 0xD;
static const int DATA_RIGHT_ARM_POSE = 0xE;
static const int DATA_LEFT_LEG_POSE = 0xF;
static const int DATA_RIGHT_LEG_POSE = 0x10;
static const int FLAG_SMALL = 1;
static const int FLAG_SHOW_ARMS = 4;
static const int FLAG_NO_BASEPLATE = 8;
static const int FLAG_MARKER = 16;
static const int FLAG_SMALL = 1;
static const int FLAG_NO_GRAVITY = 2;
static const int FLAG_SHOW_ARMS = 4;
static const int FLAG_NO_BASEPLATE= 8;
static const int FLAG_MARKER = 16;
public:
static const int SLOT_WEAPON = 0;
static const int SLOT_BOOTS = 1;
static const int SLOT_LEGGINGS = 2;
static const int SLOT_CHEST = 3;
static const int SLOT_HELM = 4;
static const int equipmentCount = 5;
private:
shared_ptr<ItemInstance> equipment[equipmentCount];
Rotations headPose;
Rotations bodyPose;
Rotations leftArmPose;
Rotations rightArmPose;
Rotations leftLegPose;
Rotations rightLegPose;
int disabledSlots;
bool invisible;
bool isMarkerFlag;
bool noPhysics;
public:
long long lastHit;
private:
int disabledSlots;
bool invisible;
public:
ArmorStand(Level *level);
virtual ~ArmorStand() {}
explicit ArmorStand(Level* level);
virtual ~ArmorStand();
bool isBaby() const;
bool isSmall() const;
bool showArms() const;
bool isShowArms() const;
bool isNoBasePlate() const;
bool showBasePlate() const;
bool isMarker() const;
void setSmall(bool v);
void setShowArms(bool v);
void setNoBasePlate(bool v);
void setMarker(bool v);
bool isEffectiveAi() const;
void setSmall (bool v);
void setShowArms (bool v);
void setNoBasePlate (bool v);
void setMarker (bool v);
void setNoGravity (bool v);
void setInvisible (bool v);
Rotations getHeadPose() const;
Rotations getBodyPose() const;
@ -75,59 +84,82 @@ public:
Rotations getLeftLegPose() const;
Rotations getRightLegPose() const;
void setHeadPose (const Rotations &r);
void setBodyPose (const Rotations &r);
void setLeftArmPose (const Rotations &r);
void setRightArmPose(const Rotations &r);
void setLeftLegPose (const Rotations &r);
void setRightLegPose(const Rotations &r);
void setHeadPose (const Rotations& r);
void setBodyPose (const Rotations& r);
void setLeftArmPose (const Rotations& r);
void setRightArmPose(const Rotations& r);
void setLeftLegPose (const Rotations& r);
void setRightLegPose(const Rotations& r);
virtual bool useNewAi() override { return false; }
virtual void tick() override;
virtual bool hurt(DamageSource *source, float damage) override;
virtual bool interact(shared_ptr<Player> player) override;
virtual bool useNewAi() override { return false; }
virtual void tick() override;
virtual bool hurt(DamageSource* source, float damage) override;
virtual bool isPickable() override;
virtual bool isPushable() override;
bool ignoreExplosion();
void kill();
virtual bool isAttackable() override { return true; }
virtual bool shouldShowName() override { return false; }
virtual bool isInWall() override { return false; }
virtual float getEyeHeight() override;
virtual bool shouldRenderAtSqrDistance(double distSq) override;
virtual bool isPickable() override;
virtual bool isPushable() override { return false; }
virtual void push(shared_ptr<Entity> entity) override {}
virtual void push(double xa, double ya, double za) override {}
virtual bool isAttackable() override { return true; }
virtual bool isBaby() override { return isSmall(); }
virtual bool shouldShowName() override { return false; }
virtual wstring getAName() override { return L""; }
virtual void pushEntities() override;
virtual void doPush(shared_ptr<Entity> e) override {}
virtual int getHurtSound() override { return -1; }
virtual int getDeathSound() override { return -1; }
virtual float getSoundVolume() override { return 0.0f; }
virtual bool makeStepSound() override { return false; }
virtual wstring getAName() override { return L""; }
virtual wstring getDisplayName() override { return L""; }
virtual wstring getNetworkName() override { return L""; }
virtual bool isInWall() override { return false; }
virtual bool interact(shared_ptr<Player> player) override;
virtual bool interactAt(shared_ptr<Player> player, const Vec3& hitVec);
virtual int test_interactAt(shared_ptr<Player> player, const Vec3& hitVec);
virtual shared_ptr<ItemInstance> getCarriedItem() override;
virtual shared_ptr<ItemInstance> getCarried(int slot) override;
virtual shared_ptr<ItemInstance> getArmor(int pos) override;
virtual void setEquippedSlot(int slot, shared_ptr<ItemInstance> item) override;
virtual ItemInstanceArray getEquipmentSlots() override;
void brokenByAnything();
void brokenByPlayer(shared_ptr<Player> player, DamageSource* source);
void causeDamage(float damage);
void updateBoundingBox(bool markerMode);
void updateInvisibilityStatus();
virtual shared_ptr<ItemInstance> getCarriedItem() override;
virtual shared_ptr<ItemInstance> getCarried(int slot) override;
virtual shared_ptr<ItemInstance> getArmor(int pos) override;
virtual void setEquippedSlot(int slot, shared_ptr<ItemInstance> item) override;
virtual ItemInstanceArray getEquipmentSlots() override;
bool setSlot(int inventorySlot, shared_ptr<ItemInstance> item);
void swapItem(shared_ptr<Player> player, int slot);
int getEquipmentSlotForItem(shared_ptr<ItemInstance> item) const;
virtual void readAdditionalSaveData(CompoundTag* tag) override;
virtual void addAdditonalSaveData (CompoundTag* tag) override;
void readPose(CompoundTag* poseTag);
CompoundTag* writePose();
virtual void readAdditionalSaveData(CompoundTag *tag) override;
virtual void addAdditonalSaveData(CompoundTag *tag) override;
virtual void handleEntityEvent(byte eventId) override;
virtual bool updateInWaterState() override;
protected:
virtual void defineSynchedData() override;
virtual void registerAttributes() override;
virtual int getHurtSound() override { return -1; }
virtual int getDeathSound() override { return -1; }
virtual float getSoundVolume() override { return 0.0f; }
virtual bool makeStepSound() override { return false; }
virtual void registerAttributes() override;
private:
byte setBit(byte oldBit, int offset, bool value);
Rotations readRotation(int slotX) const;
void writeRotation(int slotX, const Rotations &r);
int getEquipmentSlotForItem(shared_ptr<ItemInstance> item) const;
bool isSlotDisabled(int slot) const;
shared_ptr<ItemInstance> getItemInSlot(int slot);
void init();
};

View file

@ -7,6 +7,27 @@
#include "Mth.h"
#include "ArmorStandItem.h"
#include "..\Minecraft.World\ArmorStand.h"
#include "..\Minecraft.World\Entity.h"
ArmorStandItem::ArmorStandItem(int id) : Item(id)
{
maxStackSize = 16;
}
void ArmorStandItem::randomizePose(shared_ptr<ArmorStand> stand, Random *rng)
{
Rotations head = stand->getHeadPose();
float newX = head.getX() + rng->nextFloat() * 5.0f;
float newY = head.getY() + (rng->nextFloat() * 20.0f - 10.0f);
stand->setBodyPose(Rotations(newX, newY, head.getZ()));
Rotations body = stand->getBodyPose();
float bodyY = body.getY() + (rng->nextFloat() * 10.0f - 5.0f);
stand->setBodyPose(Rotations(body.getX(), bodyY, body.getZ()));
}
bool ArmorStandItem::useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player,
Level *level, int x, int y, int z, int face,
@ -18,20 +39,15 @@ bool ArmorStandItem::useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Pla
int py = y;
int pz = z;
if (face == 0) py--; // bottom
if (face == 1) py++; // top
if (face == 2) pz--; // North
if (face == 3) pz++; // South
if (face == 4) px--; // West
if (face == 5) px++; // East
if (face == 0) py--;
if (face == 1) py++;
if (face == 2) pz--;
if (face == 3) pz++;
if (face == 4) px--;
if (face == 5) px++;
//if (face != 1) return false;
if (level->getTile(px, py, pz) != 0) return false;
if (level->getTile(px, py + 1, pz) != 0) return false;
if (bTestUseOnOnly) return true;
if (level->isClientSide) return true;
@ -39,7 +55,7 @@ bool ArmorStandItem::useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Pla
float targetRot = player->yRot + 180.0f;
float snapped = (float)(Mth::floor((targetRot + 22.5f) / 45.0f) * 45.0f);
shared_ptr<ArmorStand> stand = std::make_shared<ArmorStand>(level);
auto stand = std::make_shared<ArmorStand>(level);
stand->moveTo(px + 0.5, py, pz + 0.5, snapped, 0.0f);
stand->yRot = snapped;
stand->yBodyRot = snapped;
@ -47,7 +63,6 @@ bool ArmorStandItem::useOn(shared_ptr<ItemInstance> itemInstance, shared_ptr<Pla
stand->yRotO = snapped;
stand->yBodyRotO = snapped;
stand->yHeadRotO = snapped;
level->addEntity(stand);
if (!player->abilities.instabuild)

View file

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

View file

@ -10,6 +10,7 @@
#include "StringTag.h"
#include "ByteArrayTag.h"
#include "IntArrayTag.h"
#include "CompoundContainer.h"
class CompoundTag : public Tag
{
@ -143,7 +144,29 @@ public:
{
return tags.find(name) != tags.end();
}
bool contains(const wstring& name, int typeId)
{
auto it = tags.find(name);
if (it != tags.end())
{
int foundType = it->second->getId();
if (foundType == typeId)
return true;
if (typeId == 99)
return (unsigned int)(foundType - 1) <= 5;
return false;
}
else
{
return typeId == 0;
}
}
byte getByte(const wstring &name)
{
if (tags.find(name) == tags.end()) return (byte)0;
@ -198,10 +221,13 @@ public:
return static_cast<IntArrayTag *>(tags[name])->data;
}
CompoundTag *getCompound(const wstring &name)
CompoundTag* getCompound(const wstring& name)
{
if (tags.find(name) == tags.end()) return new CompoundTag(name);
return static_cast<CompoundTag *>(tags[name]);
if (contains(name, Tag::TAG_Compound))
{
return static_cast<CompoundTag*>(get(name));
}
return new CompoundTag(name);
}
ListTag<Tag> *getList(const wstring &name)
@ -297,4 +323,8 @@ public:
}
return false;
}
};

View file

@ -111,6 +111,9 @@ bool DamageSource::isBypassInvul()
return _bypassInvul;
}
bool DamageSource::isBypassMagic() {
return _bypassInvul;
}
//DamageSource::DamageSource(const wstring &msgId)
DamageSource::DamageSource(ChatPacket::EChatPacketMessage msgId, ChatPacket::EChatPacketMessage msgWithItemId)
@ -214,6 +217,33 @@ bool DamageSource::isFire()
{
return isFireSource;
}
bool DamageSource::isFireProjectile() {
return _isProjectile;
}
DamageSource* DamageSource::setIsFireProjectile() {
_isProjectile = true;
return this;
}
bool DamageSource::isCreativePlayer() const
{
shared_ptr<Entity> entity = const_cast<DamageSource*>(this)->getEntity();
if (entity != nullptr)
{
shared_ptr<Player> player = dynamic_pointer_cast<Player>(entity);
if (player != nullptr)
{
return player->abilities.instabuild;
}
}
return false;
}
ChatPacket::EChatPacketMessage DamageSource::getMsgId()
{

View file

@ -1,4 +1,6 @@
#pragma once
#include <memory>
#include "ChatPacket.h"
using namespace std;
class LivingEntity;
@ -8,93 +10,105 @@ class Fireball;
class Player;
class Explosion;
#include "ChatPacket.h"
class DamageSource
{
public:
static DamageSource *inFire;
static DamageSource *onFire;
static DamageSource *lava;
static DamageSource *inWall;
static DamageSource *drown;
static DamageSource *starve;
static DamageSource *cactus;
static DamageSource *fall;
static DamageSource *outOfWorld;
static DamageSource *genericSource;
static DamageSource *magic;
static DamageSource *dragonbreath;
static DamageSource *wither;
static DamageSource *anvil;
static DamageSource *fallingBlock;
static DamageSource *inFire;
static DamageSource *onFire;
static DamageSource *lava;
static DamageSource *inWall;
static DamageSource *drown;
static DamageSource *starve;
static DamageSource *cactus;
static DamageSource *fall;
static DamageSource *outOfWorld;
static DamageSource *genericSource;
static DamageSource *magic;
static DamageSource *dragonbreath;
static DamageSource *wither;
static DamageSource *anvil;
static DamageSource *fallingBlock;
static DamageSource *mobAttack(shared_ptr<LivingEntity> mob);
static DamageSource *playerAttack(shared_ptr<Player> player);
static DamageSource *arrow(shared_ptr<Arrow> arrow, shared_ptr<Entity> owner);
static DamageSource *fireball(shared_ptr<Fireball> fireball, shared_ptr<Entity> owner);
static DamageSource *thrown(shared_ptr<Entity> entity, shared_ptr<Entity> owner);
static DamageSource *indirectMagic(shared_ptr<Entity> entity, shared_ptr<Entity> owner);
static DamageSource *thorns(shared_ptr<Entity> source);
static DamageSource *explosion(Explosion *explosion);
static DamageSource *mobAttack(shared_ptr<LivingEntity> mob);
static DamageSource *playerAttack(shared_ptr<Player> player);
static DamageSource *arrow(shared_ptr<Arrow> arrow, shared_ptr<Entity> owner);
static DamageSource *fireball(shared_ptr<Fireball> fireball, shared_ptr<Entity> owner);
static DamageSource *thrown(shared_ptr<Entity> entity, shared_ptr<Entity> owner);
static DamageSource *indirectMagic(shared_ptr<Entity> entity, shared_ptr<Entity> owner);
static DamageSource *thorns(shared_ptr<Entity> source);
static DamageSource *explosion(Explosion *explosion);
private:
bool _bypassArmor;
bool _bypassInvul;
// food exhastion caused by being damaged by this source
float exhaustion;
bool isFireSource;
bool _isProjectile;
bool _scalesWithDifficulty;
bool _isMagic;
bool _isExplosion;
bool _isCritical;
bool _bypassArmor;
bool _bypassInvul;
float exhaustion;
bool isFireSource;
bool _isProjectile;
bool _scalesWithDifficulty;
bool _isMagic;
bool _isExplosion;
bool _isCritical;
public:
ChatPacket::EChatPacketMessage m_msgId;
public:
bool isCritical();
DamageSource *setIsCritical();
bool isProjectile();
DamageSource *setProjectile();
bool isExplosion();
DamageSource *setExplosion();
bool isBypassArmor();
float getFoodExhaustion();
bool isBypassInvul();
//wstring msgId;
ChatPacket::EChatPacketMessage m_msgId; // 4J Made int so we can localise
ChatPacket::EChatPacketMessage m_msgWithItemId; // 4J: Renamed from m_msgWithSourceId (it was already renamed in places, just made consistent)
ChatPacket::EChatPacketMessage m_msgWithItemId;
protected:
//DamageSource(const wstring &msgId);
DamageSource(ChatPacket::EChatPacketMessage msgId, ChatPacket::EChatPacketMessage msgWithItemId = ChatPacket::e_ChatCustom);
DamageSource(ChatPacket::EChatPacketMessage msgId,
ChatPacket::EChatPacketMessage msgWithItemId = ChatPacket::e_ChatCustom);
public:
virtual ~DamageSource() {}
virtual ~DamageSource() {}
virtual shared_ptr<Entity> getDirectEntity();
virtual shared_ptr<Entity> getEntity();
virtual shared_ptr<Entity> getDirectEntity();
virtual shared_ptr<Entity> getEntity();
virtual bool scalesWithDifficulty();
virtual shared_ptr<ChatPacket> getDeathMessagePacket(shared_ptr<LivingEntity> player);
virtual DamageSource *copy();
bool isBypassArmor();
bool isBypassInvul();
bool isBypassMagic();
bool isFire();
DamageSource *setIsFire();
bool isFireProjectile();
DamageSource *setIsFireProjectile();
bool isProjectile();
DamageSource *setProjectile();
bool isMagic();
DamageSource *setMagic();
bool isExplosion();
DamageSource *setExplosion();
bool isCritical();
DamageSource *setIsCritical();
bool isCreativePlayer() const;
float getFoodExhaustion();
ChatPacket::EChatPacketMessage getMsgId();
bool equals(DamageSource *source);
protected:
DamageSource *bypassArmor();
DamageSource *bypassInvul();
DamageSource *setIsFire();
DamageSource *setScalesWithDifficulty();
public:
virtual bool scalesWithDifficulty();
bool isMagic();
DamageSource *setMagic();
// 4J Stu - Made return a packet
//virtual wstring getLocalizedDeathMessage(shared_ptr<Player> player);
virtual shared_ptr<ChatPacket> getDeathMessagePacket(shared_ptr<LivingEntity> player);
bool isFire();
ChatPacket::EChatPacketMessage getMsgId(); // 4J Stu - Used to return String
// 4J Added
bool equals(DamageSource *source);
virtual DamageSource *copy();
DamageSource *bypassArmor();
DamageSource *bypassInvul();
DamageSource *setScalesWithDifficulty();
};

View file

@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "com.mojang.nbt.h"
#include "net.minecraft.world.item.h"
#include "net.minecraft.world.item.enchantment.h"
@ -2150,4 +2150,225 @@ unsigned int Entity::getAnimOverrideBitmask()
}
return m_uiAnimOverrideBitmask;
}
float Entity::getEyeHeight()
{
return bbHeight * 0.85f;
}
bool Entity::ignoreExplosion()
{
return false;
}
void Entity::kill()
{
remove();
}
static const int DATA_CUSTOM_NAME_ID = 2;
static const int DATA_CUSTOM_NAME_VISIBLE_ID = 3;
bool Entity::hasCustomName()
{
if (!entityData) return false;
return !entityData->getString(DATA_CUSTOM_NAME_ID).empty();
}
wstring Entity::getCustomName()
{
if (!entityData) return L"";
return entityData->getString(DATA_CUSTOM_NAME_ID);
}
void Entity::setCustomName(const wstring& name)
{
if (entityData)
entityData->set(DATA_CUSTOM_NAME_ID, name);
}
bool Entity::isCustomNameVisible()
{
if (!entityData) return false;
return entityData->getByte(DATA_CUSTOM_NAME_VISIBLE_ID) == 1;
}
void Entity::setCustomNameVisible(bool visible)
{
if (entityData)
entityData->set(DATA_CUSTOM_NAME_VISIBLE_ID, static_cast<byte>(visible ? 1 : 0));
}
bool Entity::isOutsideWorldBorder()
{
return m_outsideWorldBorder;
}
void Entity::setOutsideWorldBorder(bool outside)
{
m_outsideWorldBorder = outside;
}
int Entity::getDirection()
{
int raw = (int)Mth::floor(yRot * 4.0f / 360.0f + 0.5f) & 3;
switch (raw & 3)
{
case 0: return 2; // South
case 1: return 3; // West
case 2: return 0; // North
case 3: return 1; // East
default: return 0;
}
}
Vec3* Entity::getEyePosition(float partialTicks)
{
if (partialTicks == 1.0f)
{
return Vec3::newTemp(x, y + getEyeHeight(), z);
}
double ix = xo + (x - xo) * partialTicks;
double iy = yo + (y - yo) * partialTicks;
double iz = zo + (z - zo) * partialTicks;
return Vec3::newTemp(ix, iy + getEyeHeight(), iz);
}
bool Entity::isInvulnerableTo(DamageSource* source)
{
if (!entityData) return false;
bool netInvuln = (entityData->getByte(DATA_SHARED_FLAGS_ID) >> 2 & 1) != 0;
if (!netInvuln) return false;
if (source->isCreativePlayer()) return false;
return true;
}
void Entity::setInvulnerable(bool value)
{
setSharedFlag(2, value);
}
wstring Entity::getName()
{
if (hasCustomName())
return getCustomName();
return getAName();
}
void Entity::doSprintParticleEffect()
{
int xt = Mth::floor(x);
int yt = Mth::floor(y - 0.2 - heightOffset);
int zt = Mth::floor(z);
int t = level->getTile(xt, yt, zt);
int d = level->getData(xt, yt, zt);
if (t > 0)
{
AABB* box = getBoundingBox();
level->addParticle(
PARTICLE_TILECRACK(t, d),
x + (random->nextFloat() - 0.5) * bbWidth,
box->y0 + 0.1,
z + (random->nextFloat() - 0.5) * bbWidth,
-(xd * 4.0),
1.5,
-(zd * 4.0));
}
}
bool Entity::shouldShowName()
{
return isCustomNameVisible();
}
int Entity::getPortalEntranceOffset()
{
return portalTime;
}
int Entity::getPortalEntranceForwards()
{
return portalEntranceDir;
}
void Entity::getPortalEntranceBlock(int& ox, int& oy, int& oz)
{
ox = Mth::floor(x);
oy = Mth::floor(y);
oz = Mth::floor(z);
}
Vec3* Entity::getCommandSenderWorldPosition()
{
return Vec3::newTemp(x, y, z);
}
Level* Entity::getCommandSenderWorld()
{
return level;
}
shared_ptr<Entity> Entity::getCommandSenderEntity()
{
return shared_from_this();
}
double Entity::distanceSqrToBlockPosCenter(int bx, int by, int bz)
{
double dx = x - (bx + 0.5);
double dy = y - (by + 0.5);
double dz = z - (bz + 0.5);
return dx*dx + dy*dy + dz*dz;
}
double Entity::distanceSqrToBlockPosCenter(BlockPos* pos)
{
return distanceSqrToBlockPosCenter(pos->getX(), pos->getY(), pos->getZ());
}
void Entity::getSkinAdjustments(struct _SkinAdjustments* adj)
{
if (app.GetGameSettings((eGameSetting)0x18) || (this->m_skinAdjustments.data[17] & 0x1F1F810) != 0)
{
*adj = this->m_skinAdjustments;
}
else
{
*adj = _SkinAdjustments();
}
}
void Entity::setSkinAdjustments(struct _SkinAdjustments* adj)
{
this->m_skinAdjustments = *adj;
}

View file

@ -18,6 +18,7 @@ class Level;
class CompoundTag;
class DamageSource;
class Explosion;
class BlockPos;
// 4J Stu Added this mainly to allow is to record telemetry for player deaths
enum EEntityDamageType
@ -31,6 +32,10 @@ enum EEntityDamageType
eEntityDamageType_OutOfWorld,
eEntityDamageType_Cactus,
};
struct _SkinAdjustments
{
int data[18];
};
class Entity : public enable_shared_from_this<Entity>
{
@ -48,6 +53,7 @@ public:
private:
static int entityCounter;
bool m_outsideWorldBorder = false;
public:
int entityId;
@ -73,6 +79,7 @@ public:
protected:
bool isStuckInWeb;
_SkinAdjustments m_skinAdjustments;
public:
bool slide;
@ -199,7 +206,7 @@ protected:
public:
virtual void remove();
protected:
public:
virtual void setSize(float w, float h);
void setPos(EntityPos *pos);
void setRot(float yRot, float xRot);
@ -256,6 +263,7 @@ public:
virtual bool updateInWaterState();
bool isUnderLiquid(Material *material);
virtual float getHeadHeight();
float getEyeHeight();
bool isInLava();
void moveRelative(float xa, float za, float speed);
virtual int getLightColor(float a); // 4J - change brought forward from 1.8.2
@ -434,4 +442,77 @@ public:
virtual void setDespawnProtected() {}
virtual bool couldWander() { return false; }
virtual bool canCreateParticles() { return true; }
bool ignoreExplosion();
void kill();
virtual bool hasCustomName();
virtual wstring getCustomName();
virtual void setCustomName(const wstring& name);
virtual bool isCustomNameVisible();
virtual void setCustomNameVisible(bool visible);
bool isOutsideWorldBorder();
void setOutsideWorldBorder(bool outside);
virtual AABB* getBoundingBox() { return bb; }
virtual void setBoundingBox(AABB* box) { bb = box; }
int getDirection();
Vec3* getEyePosition(float partialTicks);
bool isInvulnerableTo(DamageSource* source);
void setInvulnerable(bool value);
wstring getName();
void doSprintParticleEffect();
virtual int getSwimSplashSound() { return 0xDE; }
virtual int getSwimSound() { return 0xDD; }
virtual void onSyncedDataUpdated() {}
int getPortalEntranceOffset();
int getPortalEntranceForwards();
void getPortalEntranceBlock(int& x, int& y, int& z);
virtual void setYBodyRot() {}
virtual bool broadcastToPlayer() { return true; }
virtual bool shouldShowName();
virtual bool interactAt(shared_ptr<Player> player, const Vec3& hitVec) { return false; }
virtual void handleEntityTag() {}
virtual int getEntityTag() { return 0; }
virtual int setSlot() { return 0; }
Vec3* getCommandSenderWorldPosition();
Level* getCommandSenderWorld();
shared_ptr<Entity> getCommandSenderEntity();
double distanceSqrToBlockPosCenter(int bx, int by, int bz);
double distanceSqrToBlockPosCenter(BlockPos* pos);
void getSkinAdjustments(struct _SkinAdjustments* adj);
void setSkinAdjustments(struct _SkinAdjustments* adj);
};

View file

@ -1,110 +1,127 @@

#include "stdafx.h"
#include "PacketListener.h"
#include "LevelParticlesPacket.h"
#include "../Minecraft.Client/ParticleType.h"
LevelParticlesPacket::LevelParticlesPacket()
{
this->name = L"";
this->x = 0.0f;
this->y = 0.0f;
this->z = 0.0f;
this->xDist = 0.0f;
this->yDist = 0.0f;
this->zDist = 0.0f;
this->maxSpeed = 0.0f;
this->count = 0;
this->overrideLimiter = false;
this->type = nullptr;
this->count = 0;
this->y = 0.0f;
this->paramCount = 0;
this->x = 0.0f;
this->yDist = 0.0f;
this->zDist = 0.0f;
this->z = 0.0f;
this->maxSpeed = 0.0f;
this->xDist = 0.0f;
this->params = nullptr;
}
LevelParticlesPacket::LevelParticlesPacket(const wstring &name, float x, float y, float z, float xDist, float yDist, float zDist, float maxSpeed, int count)
LevelParticlesPacket::LevelParticlesPacket(const ParticleType* type, bool overrideLimiter,
float x, float y, float z,
float xDist, float yDist, float zDist,
float maxSpeed, int count,
arrayWithLength<int> data)
{
this->name = name;
this->x = x;
this->y = y;
this->z = z;
this->xDist = xDist;
this->yDist = yDist;
this->zDist = zDist;
this->maxSpeed = maxSpeed;
this->count = count;
this->type = type;
this->overrideLimiter = overrideLimiter;
this->x = x;
this->y = y;
this->z = z;
this->xDist = xDist;
this->yDist = yDist;
this->zDist = zDist;
this->maxSpeed = maxSpeed;
this->count = count;
this->paramCount = data.length;
if (data.data && data.length > 0)
{
this->params = new int[data.length];
memcpy(this->params, data.data, data.length * sizeof(int));
}
else
{
this->params = nullptr;
}
}
void LevelParticlesPacket::read(DataInputStream *dis)
LevelParticlesPacket::~LevelParticlesPacket()
{
name = readUtf(dis, 64);
x = dis->readFloat();
y = dis->readFloat();
z = dis->readFloat();
xDist = dis->readFloat();
yDist = dis->readFloat();
zDist = dis->readFloat();
maxSpeed = dis->readFloat();
count = dis->readInt();
if (params)
{
delete[] params;
params = nullptr;
}
}
void LevelParticlesPacket::write(DataOutputStream *dos)
void LevelParticlesPacket::read(DataInputStream* dis)
{
writeUtf(name, dos);
dos->writeFloat(x);
dos->writeFloat(y);
dos->writeFloat(z);
dos->writeFloat(xDist);
dos->writeFloat(yDist);
dos->writeFloat(zDist);
dos->writeFloat(maxSpeed);
dos->writeInt(count);
int particleId = dis->readInt();
const ParticleType* resolved = ParticleType::byId(particleId);
if (!resolved)
resolved = ParticleType::getDefault();
this->type = resolved;
this->overrideLimiter = dis->readBoolean();
this->x = dis->readFloat();
this->y = dis->readFloat();
this->z = dis->readFloat();
this->xDist = dis->readFloat();
this->yDist = dis->readFloat();
this->zDist = dis->readFloat();
this->maxSpeed = dis->readFloat();
this->count = dis->readInt();
int paramCount = this->type ? this->type->getParamCount() : 0;
this->paramCount = paramCount;
if (paramCount > 0)
{
this->params = new int[paramCount]();
for (int i = 0; i < paramCount; i++)
{
this->params[i] = dis->readInt();
}
}
else
{
this->params = nullptr;
}
}
wstring LevelParticlesPacket::getName()
void LevelParticlesPacket::write(DataOutputStream* dos)
{
return name;
dos->writeInt(this->type ? this->type->getId() : 0);
dos->writeBoolean(this->overrideLimiter);
dos->writeFloat(this->x);
dos->writeFloat(this->y);
dos->writeFloat(this->z);
dos->writeFloat(this->xDist);
dos->writeFloat(this->yDist);
dos->writeFloat(this->zDist);
dos->writeFloat(this->maxSpeed);
dos->writeInt(this->count);
int toWrite = this->type ? this->type->getParamCount() : 0;
for (int i = 0; i < toWrite; i++)
{
dos->writeInt(this->params[i]);
}
}
double LevelParticlesPacket::getX()
void LevelParticlesPacket::handle(PacketListener* listener)
{
return x;
}
double LevelParticlesPacket::getY()
{
return y;
}
double LevelParticlesPacket::getZ()
{
return z;
}
float LevelParticlesPacket::getXDist()
{
return xDist;
}
float LevelParticlesPacket::getYDist()
{
return yDist;
}
float LevelParticlesPacket::getZDist()
{
return zDist;
}
float LevelParticlesPacket::getMaxSpeed()
{
return maxSpeed;
}
int LevelParticlesPacket::getCount()
{
return count;
}
void LevelParticlesPacket::handle(PacketListener *listener)
{
listener->handleParticleEvent(shared_from_this());
listener->handleParticleEvent(shared_from_this());
}
int LevelParticlesPacket::getEstimatedSize()
{
return 4 * 2 + 7 * 8;
return 0x40;
}

View file

@ -1,39 +1,53 @@
#pragma once
#pragma once
#include "Packet.h"
#include "../Minecraft.Client/ParticleType.h"
class LevelParticlesPacket : public Packet, public enable_shared_from_this<LevelParticlesPacket>
{
private:
wstring name;
float x;
float y;
float z;
float xDist;
float yDist;
float zDist;
float maxSpeed;
int count;
const ParticleType* type;
float x;
float y;
float z;
float xDist;
float yDist;
float zDist;
float maxSpeed;
int count;
bool overrideLimiter;
int* params;
int paramCount;
public:
LevelParticlesPacket();
LevelParticlesPacket(const wstring &name, float x, float y, float z, float xDist, float yDist, float zDist, float maxSpeed, int count);
LevelParticlesPacket();
LevelParticlesPacket(const ParticleType* type, bool overrideLimiter,
float x, float y, float z,
float xDist, float yDist, float zDist,
float maxSpeed, int count,
arrayWithLength<int> data);
~LevelParticlesPacket();
void read(DataInputStream *dis);
void write(DataOutputStream *dos);
wstring getName();
double getX();
double getY();
double getZ();
float getXDist();
float getYDist();
float getZDist();
float getMaxSpeed();
int getCount();
void handle(PacketListener *listener);
int getEstimatedSize();
void read(DataInputStream* dis) override;
void write(DataOutputStream* dos) override;
public:
static shared_ptr<Packet> create() { return std::make_shared<LevelParticlesPacket>(); }
virtual int getId() { return 63; }
const ParticleType* getType() { return type; }
double getX() { return x; }
double getY() { return y; }
double getZ() { return z; }
double getXDist() { return xDist; }
double getYDist() { return yDist; }
double getZDist() { return zDist; }
double getMaxSpeed() { return maxSpeed; }
int getCount() { return count; }
bool isOverrideLimiter() { return overrideLimiter; }
int* getParams() { return params; }
int getParamCount() { return paramCount; }
void handle(PacketListener* listener) override;
int getEstimatedSize() override;
static shared_ptr<Packet> create() { return std::make_shared<LevelParticlesPacket>(); }
virtual int getId() override { return 63; }
};

View file

@ -7,6 +7,7 @@ GameType *GameType::NOT_SET = nullptr;
GameType *GameType::SURVIVAL= nullptr;
GameType *GameType::CREATIVE = nullptr;
GameType *GameType::ADVENTURE = nullptr;
GameType* GameType::SPECTATOR = nullptr;
void GameType::staticCtor()
{
@ -14,6 +15,7 @@ void GameType::staticCtor()
SURVIVAL = new GameType(0, L"survival");
CREATIVE = new GameType(1, L"creative");
ADVENTURE = new GameType(2, L"adventure");
SPECTATOR = new GameType(3, L"spectator");
}
GameType::GameType(int id, const wstring &name)
@ -59,6 +61,10 @@ bool GameType::isCreative()
{
return this == CREATIVE;
}
bool GameType::isSpectator()
{
return this == SPECTATOR;
}
bool GameType::isSurvival()
{

View file

@ -14,6 +14,7 @@ public:
static GameType *SURVIVAL;
static GameType *CREATIVE;
static GameType *ADVENTURE;
static GameType *SPECTATOR;
static void staticCtor();
@ -30,6 +31,7 @@ public:
bool isAdventureRestricted();
bool isCreative();
bool isSurvival();
bool isSpectator();
static GameType *byId(int id);
static GameType *byName(const wstring &name);
};

View file

@ -45,6 +45,7 @@ public:
list.push_back(tag);
}
}
byte getId() { return TAG_List; }
@ -148,4 +149,7 @@ public:
}
return false;
}
};

View file

@ -2051,7 +2051,7 @@ HitResult *LivingEntity::pick(double range, float a)
return level->clip(from, to);
}
bool LivingEntity::isEffectiveAi()
bool LivingEntity::isEffectiveAi()const
{
return !level->isClientSide;
}
@ -2145,4 +2145,4 @@ HitResult *LivingEntity::rayTrace(double blockReachDistance, float partialTicks)
return this->level->clip(vec3, vec32, false, false);
}
}

View file

@ -24,12 +24,12 @@ protected:
// 4J - added for common ctor code
void _init();
public:
// 4J-PB - added to replace (e instanceof Type), avoiding dynamic casts
eINSTANCEOF GetType() { return eTYPE_LIVINGENTITY;}
static Entity *create(Level *level) { return nullptr; }
eINSTANCEOF GetType() { return eTYPE_LIVINGENTITY; }
static Entity* create(Level* level) { return nullptr; }
private:
static AttributeModifier *SPEED_MODIFIER_SPRINTING;
static AttributeModifier* SPEED_MODIFIER_SPRINTING;
public:
static const int SLOT_WEAPON = 0;
@ -51,9 +51,9 @@ public:
static const int DATA_ARROW_COUNT_ID = 9;
private:
BaseAttributeMap *attributes;
CombatTracker *combatTracker;
unordered_map<int, MobEffectInstance *> activeEffects;
BaseAttributeMap* attributes;
CombatTracker* combatTracker;
unordered_map<int, MobEffectInstance*> activeEffects;
ItemInstanceArray lastEquipment;
public:
@ -143,7 +143,7 @@ protected:
virtual bool isAlwaysExperienceDropper();
public:
virtual Random *getRandom();
virtual Random* getRandom();
virtual shared_ptr<LivingEntity> getLastHurtByMob();
virtual int getLastHurtByMobTimestamp();
virtual void setLastHurtByMob(shared_ptr<LivingEntity> hurtBy);
@ -151,37 +151,37 @@ public:
virtual int getLastHurtMobTimestamp();
virtual void setLastHurtMob(shared_ptr<Entity> target);
virtual int getNoActionTime();
virtual void addAdditonalSaveData(CompoundTag *entityTag);
virtual void readAdditionalSaveData(CompoundTag *tag);
virtual void addAdditonalSaveData(CompoundTag* entityTag);
virtual void readAdditionalSaveData(CompoundTag* tag);
protected:
virtual void tickEffects();
public:
virtual void removeAllEffects();
virtual vector<MobEffectInstance *> *getActiveEffects();
virtual vector<MobEffectInstance*>* getActiveEffects();
virtual bool hasEffect(int id);
virtual bool hasEffect(MobEffect *effect);
virtual MobEffectInstance *getEffect(MobEffect *effect);
virtual void addEffect(MobEffectInstance *newEffect);
virtual void addEffectNoUpdate(MobEffectInstance *newEffect); // 4J added
virtual bool canBeAffected(MobEffectInstance *newEffect);
virtual bool hasEffect(MobEffect* effect);
virtual MobEffectInstance* getEffect(MobEffect* effect);
virtual void addEffect(MobEffectInstance* newEffect);
virtual void addEffectNoUpdate(MobEffectInstance* newEffect); // 4J added
virtual bool canBeAffected(MobEffectInstance* newEffect);
virtual bool isInvertedHealAndHarm();
virtual void removeEffectNoUpdate(int effectId);
virtual void removeEffect(int effectId);
protected:
virtual void onEffectAdded(MobEffectInstance *effect);
virtual void onEffectUpdated(MobEffectInstance *effect, bool doRefreshAttributes);
virtual void onEffectRemoved(MobEffectInstance *effect);
virtual void onEffectAdded(MobEffectInstance* effect);
virtual void onEffectUpdated(MobEffectInstance* effect, bool doRefreshAttributes);
virtual void onEffectRemoved(MobEffectInstance* effect);
public:
virtual void heal(float heal);
virtual float getHealth();
virtual void setHealth(float health);
virtual bool hurt(DamageSource *source, float dmg);
virtual bool hurt(DamageSource* source, float dmg);
virtual void breakItem(shared_ptr<ItemInstance> itemInstance);
virtual void die(DamageSource *source);
virtual void die(DamageSource* source);
protected:
virtual void dropEquipment(bool byPlayer, int playerBonusLevel);
@ -208,12 +208,12 @@ public:
protected:
virtual void hurtArmor(float damage);
virtual float getDamageAfterArmorAbsorb(DamageSource *damageSource, float damage);
virtual float getDamageAfterMagicAbsorb(DamageSource *damageSource, float damage);
virtual void actuallyHurt(DamageSource *source, float dmg);
virtual float getDamageAfterArmorAbsorb(DamageSource* damageSource, float damage);
virtual float getDamageAfterMagicAbsorb(DamageSource* damageSource, float damage);
virtual void actuallyHurt(DamageSource* source, float dmg);
public:
virtual CombatTracker *getCombatTracker();
virtual CombatTracker* getCombatTracker();
virtual shared_ptr<LivingEntity> getKillCredit();
virtual float getMaxHealth();
virtual int getArrowCount();
@ -231,8 +231,8 @@ protected:
virtual void updateSwingTime();
public:
virtual AttributeInstance *getAttribute(Attribute *attribute);
virtual BaseAttributeMap *getAttributes();
virtual AttributeInstance* getAttribute(Attribute* attribute);
virtual BaseAttributeMap* getAttributes();
virtual MobType getMobType();
virtual shared_ptr<ItemInstance> getCarriedItem() = 0;
@ -243,7 +243,7 @@ public:
virtual ItemInstanceArray getEquipmentSlots() = 0;
virtual Icon *getItemInHandIcon(shared_ptr<ItemInstance> item, int layer);
virtual Icon* getItemInHandIcon(shared_ptr<ItemInstance> item, int layer);
protected:
virtual float getSoundVolume();
@ -255,7 +255,7 @@ public:
protected:
virtual void findStandUpPosition(shared_ptr<Entity> vehicle);
public:
virtual bool shouldShowName();
@ -303,12 +303,12 @@ public:
public:
virtual Vec3 *getLookAngle();
virtual Vec3 *getViewVector(float a);
virtual Vec3* getLookAngle();
virtual Vec3* getViewVector(float a);
virtual float getAttackAnim(float a);
virtual Vec3 *getPos(float a);
virtual HitResult *pick(double range, float a);
virtual bool isEffectiveAi();
virtual Vec3* getPos(float a);
virtual HitResult* pick(double range, float a);
virtual bool isEffectiveAi()const;
virtual bool isPickable();
virtual bool isPushable();
@ -323,12 +323,13 @@ public:
virtual float getAbsorptionAmount();
virtual void setAbsorptionAmount(float absorptionAmount);
virtual Team *getTeam();
virtual Team* getTeam();
virtual bool isAlliedTo(shared_ptr<LivingEntity> other);
virtual bool isAlliedTo(Team *other);
virtual bool isAlliedTo(Team* other);
public:
virtual float getEyeHeight();
virtual Vec3 *getPositionEyes(float partialTicks);
virtual HitResult *rayTrace(double blockReachDistance, float partialTicks);
virtual float getEyeHeight();
virtual Vec3* getPositionEyes(float partialTicks);
virtual HitResult* rayTrace(double blockReachDistance, float partialTicks);
};

View file

@ -2794,6 +2794,47 @@ unsigned int Player::getPlayerGamePrivilege(unsigned int uiGamePrivileges, EPlay
return 0;
}
_SkinAdjustments Player::getSkinAdjustmentsById(unsigned int skinId)
{
_SkinAdjustments adj = _SkinAdjustments();
if ((int)skinId < 0)
{
app.GetSkinAdjustments(&adj, skinId);
unsigned int rawId = skinId & 0x7FFFFFFF;
if (rawId == 2 || rawId == 3 || rawId == 0xC8 || rawId == 0xC9 ||
rawId == 0x194 || rawId == 0x195 || rawId == 0x1F8 || rawId == 0x220 ||
rawId == 0x23A || rawId == 0x23D || rawId == 0x247)
{
adj.data[17] = 2;
}
else if (rawId == 0x1F4)
{
adj.data[17] = 5;
}
else if (rawId == 0x1FA)
{
adj.data[17] = 6;
}
}
return adj;
}
void Player::setPlayerGamePrivilege(EPlayerGamePrivileges privilege, unsigned int value)
{
Player::setPlayerGamePrivilege(m_uiGamePrivileges,privilege,value);
@ -3204,3 +3245,8 @@ void Player::SetPlayerNameValidState(bool bState)
}
}
#endif
bool Player::isSpectator()
{
return false;
}

View file

@ -503,6 +503,7 @@ private:
unsigned int getPlayerGamePrivilege(EPlayerGamePrivileges privilege);
public:
static _SkinAdjustments getSkinAdjustmentsById(unsigned int skinId);
unsigned int getAllPlayerGamePrivileges() { return getPlayerGamePrivilege(ePlayerGamePrivilege_All); }
static unsigned int getPlayerGamePrivilege(unsigned int uiGamePrivileges, EPlayerGamePrivileges privilege);
@ -522,6 +523,7 @@ public:
bool hasInvisiblePrivilege();
bool hasInvulnerablePrivilege();
bool isModerator();
bool isSpectator();
static void enableAllPlayerPrivileges(unsigned int &uigamePrivileges, bool enable);
void enableAllPlayerPrivileges(bool enable);

View file

@ -0,0 +1,22 @@
#include "stdafx.h"
#include "Rotations.h"
#include "ListTag.h"
#include "FloatTag.h"
Rotations::Rotations(ListTag<FloatTag>* list)
{
x = list->get(0)->data;
y = list->get(1)->data;
z = list->get(2)->data;
}
ListTag<FloatTag>* Rotations::save() const
{
ListTag<FloatTag>* tag = new ListTag<FloatTag>();
tag->add(new FloatTag(L"", x));
tag->add(new FloatTag(L"", y));
tag->add(new FloatTag(L"", z));
return tag;
}

View file

@ -0,0 +1,44 @@
#pragma once
#include <memory>
using namespace std;
template<class T> class ListTag;
class FloatTag;
class Rotations
{
public:
float x, y, z;
public:
Rotations() : x(0.0f), y(0.0f), z(0.0f) {}
Rotations(float x, float y, float z) : x(x), y(y), z(z) {}
Rotations(const Rotations& other) : x(other.x), y(other.y), z(other.z) {}
Rotations(ListTag<FloatTag>* list);
float getX() const { return x; }
float getY() const { return y; }
float getZ() const { return z; }
bool operator==(const Rotations& other) const
{
return x == other.x && y == other.y && z == other.z;
}
bool operator!=(const Rotations& other) const
{
return !(*this == other);
}
ListTag<FloatTag>* save() const;
};

View file

@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Class.h"
#include "BasicTypeContainers.h"
#include "InputOutputStream.h"
@ -7,619 +7,344 @@
#include "net.minecraft.world.item.h"
#include "SynchedEntityData.h"
SynchedEntityData::SynchedEntityData()
{
m_isDirty = false;
m_isEmpty = true;
m_isDirty = false;
m_isEmpty = true;
}
void SynchedEntityData::define(int id, int value)
{
MemSect(17);
checkId(id);
int type = TYPE_INT;
shared_ptr<DataItem> dataItem = std::make_shared<DataItem>(type, id, value);
itemsById[id] = dataItem;
MemSect(0);
m_isEmpty = false;
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_INT, id, value);
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::define(int id, byte value)
{
MemSect(17);
checkId(id);
int type = TYPE_BYTE;
shared_ptr<DataItem> dataItem = std::make_shared<DataItem>(type, id, value);
itemsById[id] = dataItem;
MemSect(0);
m_isEmpty = false;
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_BYTE, id, value);
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::define(int id, short value)
{
MemSect(17);
checkId(id);
int type = TYPE_SHORT;
shared_ptr<DataItem> dataItem = std::make_shared<DataItem>(type, id, value);
itemsById[id] = dataItem;
MemSect(0);
m_isEmpty = false;
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_SHORT, id, value);
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::define(int id, float value)
{
MemSect(17);
checkId(id);
int type = TYPE_FLOAT;
shared_ptr<DataItem> dataItem = std::make_shared<DataItem>(type, id, value);
itemsById[id] = dataItem;
MemSect(0);
m_isEmpty = false;
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_FLOAT, id, value);
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::define(int id, const wstring& value)
{
MemSect(17);
checkId(id);
int type = TYPE_STRING;
shared_ptr<DataItem> dataItem = std::make_shared<DataItem>(type, id, value);
itemsById[id] = dataItem;
MemSect(0);
m_isEmpty = false;
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_STRING, id, value);
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::defineNULL(int id, void *pVal)
void SynchedEntityData::define(int id, const Rotations& value)
{
MemSect(17);
checkId(id);
int type = TYPE_ITEMINSTANCE;
shared_ptr<DataItem> dataItem = std::make_shared<DataItem>(type, id, shared_ptr<ItemInstance>());
itemsById[id] = dataItem;
MemSect(0);
m_isEmpty = false;
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_ROTATIONS, id, value);
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::defineNULL(int id, void* pVal)
{
MemSect(17);
checkId(id);
itemsById[id] = std::make_shared<DataItem>(TYPE_ITEMINSTANCE, id, shared_ptr<ItemInstance>());
MemSect(0);
m_isEmpty = false;
}
void SynchedEntityData::checkId(int id)
{
#if 0
if (id > MAX_ID_VALUE)
{
throw new IllegalArgumentException(L"Data value id is too big with " + std::to_wstring(id) + L"! (Max is " + std::to_wstring(MAX_ID_VALUE) + L")");
}
if (itemsById.find(id) != itemsById.end())
{
throw new IllegalArgumentException(L"Duplicate id value for " + std::to_wstring(id) + L"!");
}
#endif
// validation disabled in shipping build
}
byte SynchedEntityData::getByte(int id)
byte SynchedEntityData::getByte(int id) { return itemsById[id]->getValue_byte(); }
short SynchedEntityData::getShort(int id) { return itemsById[id]->getValue_short(); }
int SynchedEntityData::getInteger(int id) { return itemsById[id]->getValue_int(); }
float SynchedEntityData::getFloat(int id) { return itemsById[id]->getValue_float(); }
wstring SynchedEntityData::getString(int id) { return itemsById[id]->getValue_wstring(); }
shared_ptr<ItemInstance> SynchedEntityData::getItemInstance(int id) { return itemsById[id]->getValue_itemInstance(); }
Pos* SynchedEntityData::getPos(int id)
{
return itemsById[id]->getValue_byte();
assert(false);
return nullptr;
}
short SynchedEntityData::getShort(int id)
Rotations SynchedEntityData::getRotations(int id)
{
return itemsById[id]->getValue_short();
return itemsById[id]->getValue_rotations();
}
int SynchedEntityData::getInteger(int id)
{
return itemsById[id]->getValue_int();
}
float SynchedEntityData::getFloat(int id)
{
return itemsById[id]->getValue_float();
}
wstring SynchedEntityData::getString(int id)
{
return itemsById[id]->getValue_wstring();
}
shared_ptr<ItemInstance> SynchedEntityData::getItemInstance(int id)
{
//assert(false); // 4J - not currently implemented
return itemsById[id]->getValue_itemInstance();
}
Pos *SynchedEntityData::getPos(int id)
{
assert(false); // 4J - not currently implemented
return nullptr;
}
void SynchedEntityData::set(int id, int value)
{
shared_ptr<DataItem> dataItem = itemsById[id];
// update the value if it has changed
if (value != dataItem->getValue_int())
{
dataItem->setValue(value);
dataItem->setDirty(true);
m_isDirty = true;
}
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_int()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::set(int id, byte value)
{
shared_ptr<DataItem> dataItem = itemsById[id];
// update the value if it has changed
if (value != dataItem->getValue_byte())
{
dataItem->setValue(value);
dataItem->setDirty(true);
m_isDirty = true;
}
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_byte()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::set(int id, short value)
{
shared_ptr<DataItem> dataItem = itemsById[id];
// update the value if it has changed
if (value != dataItem->getValue_short())
{
dataItem->setValue(value);
dataItem->setDirty(true);
m_isDirty = true;
}
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_short()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::set(int id, float value)
{
shared_ptr<DataItem> dataItem = itemsById[id];
// update the value if it has changed
if (value != dataItem->getValue_float())
{
dataItem->setValue(value);
dataItem->setDirty(true);
m_isDirty = true;
}
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_float()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::set(int id, const wstring& value)
{
shared_ptr<DataItem> dataItem = itemsById[id];
// update the value if it has changed
if (value != dataItem->getValue_wstring())
{
dataItem->setValue(value);
dataItem->setDirty(true);
m_isDirty = true;
}
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_wstring()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::set(int id, shared_ptr<ItemInstance> value)
{
shared_ptr<DataItem> dataItem = itemsById[id];
// update the value if it has changed
if (value != dataItem->getValue_itemInstance())
{
dataItem->setValue(value);
dataItem->setDirty(true);
m_isDirty = true;
}
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_itemInstance()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::markDirty(int id)
void SynchedEntityData::set(int id, const Rotations& value)
{
itemsById[id]->dirty = true;
m_isDirty = true;
}
bool SynchedEntityData::isDirty()
{
return m_isDirty;
}
void SynchedEntityData::pack(vector<shared_ptr<DataItem> > *items, DataOutputStream *output) // TODO throws IOException
{
if (items)
{
for (auto& dataItem : *items)
{
writeDataItem(output, dataItem);
}
}
// add an eof
output->writeByte(EOF_MARKER);
}
vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::packDirty()
{
vector<shared_ptr<DataItem> > *result = nullptr;
if (m_isDirty)
{
for( int i = 0; i <= MAX_ID_VALUE; i++ )
{
shared_ptr<DataItem> dataItem = itemsById[i];
if ((dataItem != nullptr) && dataItem->isDirty())
{
dataItem->setDirty(false);
if (result == nullptr)
{
result = new vector<shared_ptr<DataItem> >();
}
result->push_back(dataItem);
}
}
}
m_isDirty = false;
return result;
}
void SynchedEntityData::packAll(DataOutputStream *output) // throws IOException
{
for( int i = 0; i <= MAX_ID_VALUE; i++ )
{
shared_ptr<DataItem> dataItem = itemsById[i];
if(dataItem != nullptr)
{
writeDataItem(output, dataItem);
}
}
// add an eof
output->writeByte(EOF_MARKER);
}
vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::getAll()
{
vector<shared_ptr<DataItem> > *result = nullptr;
for( int i = 0; i <= MAX_ID_VALUE; i++ )
{
shared_ptr<DataItem> dataItem = itemsById[i];
if(dataItem != nullptr)
{
if (result == nullptr)
{
result = new vector<shared_ptr<DataItem> >();
}
result->push_back(dataItem);
}
}
return result;
shared_ptr<DataItem> item = itemsById[id];
if (value != item->getValue_rotations()) { item->setValue(value); item->setDirty(true); m_isDirty = true; }
}
void SynchedEntityData::writeDataItem(DataOutputStream *output, shared_ptr<DataItem> dataItem) //throws IOException
void SynchedEntityData::markDirty(int id) { itemsById[id]->dirty = true; m_isDirty = true; }
bool SynchedEntityData::isDirty() { return m_isDirty; }
bool SynchedEntityData::isEmpty() { return m_isEmpty; }
void SynchedEntityData::clearDirty() { m_isDirty = false; }
void SynchedEntityData::pack(vector<shared_ptr<DataItem>>* items, DataOutputStream* output)
{
// pack type and id
int header = ((dataItem->getType() << TYPE_SHIFT) | (dataItem->getId() & MAX_ID_VALUE)) & 0xff;
output->writeByte(header);
// write value
switch (dataItem->getType())
{
case TYPE_BYTE:
output->writeByte( dataItem->getValue_byte());
break;
case TYPE_INT:
output->writeInt( dataItem->getValue_int());
break;
case TYPE_SHORT:
output->writeShort( dataItem->getValue_short());
break;
case TYPE_FLOAT:
output->writeFloat( dataItem->getValue_float());
break;
case TYPE_STRING:
Packet::writeUtf(dataItem->getValue_wstring(), output);
break;
case TYPE_ITEMINSTANCE:
{
shared_ptr<ItemInstance> instance = (shared_ptr<ItemInstance> )dataItem->getValue_itemInstance();
Packet::writeItem(instance, output);
}
break;
default:
assert(false); // 4J - not implemented
break;
}
if (items)
for (auto& item : *items)
writeDataItem(output, item);
output->writeByte(EOF_MARKER);
}
vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::unpack(DataInputStream *input) //throws IOException
vector<shared_ptr<SynchedEntityData::DataItem>>* SynchedEntityData::packDirty()
{
vector<shared_ptr<DataItem>>* result = nullptr;
if (m_isDirty)
{
for (int i = 0; i <= MAX_ID_VALUE; i++)
{
shared_ptr<DataItem> item = itemsById[i];
if (item && item->isDirty())
{
item->setDirty(false);
if (!result) result = new vector<shared_ptr<DataItem>>();
result->push_back(item);
}
}
}
m_isDirty = false;
return result;
}
vector<shared_ptr<DataItem> > *result = nullptr;
void SynchedEntityData::packAll(DataOutputStream* output)
{
for (int i = 0; i <= MAX_ID_VALUE; i++)
if (itemsById[i]) writeDataItem(output, itemsById[i]);
output->writeByte(EOF_MARKER);
}
int currentHeader = input->readByte();
vector<shared_ptr<SynchedEntityData::DataItem>>* SynchedEntityData::getAll()
{
vector<shared_ptr<DataItem>>* result = nullptr;
for (int i = 0; i <= MAX_ID_VALUE; i++)
{
if (itemsById[i])
{
if (!result) result = new vector<shared_ptr<DataItem>>();
result->push_back(itemsById[i]);
}
}
return result;
}
int itemCount = 0;
void SynchedEntityData::writeDataItem(DataOutputStream* output, shared_ptr<DataItem> item)
{
int header = ((item->getType() << TYPE_SHIFT) | (item->getId() & MAX_ID_VALUE)) & 0xff;
output->writeByte(header);
switch (item->getType())
{
case TYPE_BYTE: output->writeByte(item->getValue_byte()); break;
case TYPE_INT: output->writeInt(item->getValue_int()); break;
case TYPE_SHORT: output->writeShort(item->getValue_short()); break;
case TYPE_FLOAT: output->writeFloat(item->getValue_float()); break;
case TYPE_STRING: Packet::writeUtf(item->getValue_wstring(), output); break;
case TYPE_ITEMINSTANCE: Packet::writeItem(item->getValue_itemInstance(), output); break;
case TYPE_ROTATIONS:
output->writeFloat(item->getValue_rotations().getX());
output->writeFloat(item->getValue_rotations().getY());
output->writeFloat(item->getValue_rotations().getZ());
break;
default: assert(false); break;
}
}
vector<shared_ptr<SynchedEntityData::DataItem>>* SynchedEntityData::unpack(DataInputStream* input)
{
vector<shared_ptr<DataItem>>* result = nullptr;
int currentHeader = input->readByte();
int itemCount = 0;
const int MAX_ENTITY_DATA_ITEMS = 256;
while (currentHeader != EOF_MARKER && itemCount < MAX_ENTITY_DATA_ITEMS)
{
{
if (!result) result = new vector<shared_ptr<DataItem>>();
int itemType = (currentHeader & TYPE_MASK) >> TYPE_SHIFT;
int itemId = (currentHeader & MAX_ID_VALUE);
shared_ptr<DataItem> item;
if (result == nullptr)
{
result = new vector<shared_ptr<DataItem> >();
}
// split type and id
int itemType = (currentHeader & TYPE_MASK) >> TYPE_SHIFT;
int itemId = (currentHeader & MAX_ID_VALUE);
shared_ptr<DataItem> item = shared_ptr<DataItem>();
switch (itemType)
{
case TYPE_BYTE:
{
byte dataRead = input->readByte();
item = std::make_shared<DataItem>(itemType, itemId, dataRead);
}
break;
case TYPE_SHORT:
{
short dataRead = input->readShort();
item = std::make_shared<DataItem>(itemType, itemId, dataRead);
}
break;
case TYPE_INT:
{
int dataRead = input->readInt();
item = std::make_shared<DataItem>(itemType, itemId, dataRead);
}
break;
case TYPE_FLOAT:
{
float dataRead = input->readFloat();
item = std::make_shared<DataItem>(itemType, itemId, dataRead);
}
break;
case TYPE_STRING:
item = std::make_shared<DataItem>(itemType, itemId, Packet::readUtf(input, MAX_STRING_DATA_LENGTH));
break;
case TYPE_ITEMINSTANCE:
{
item = std::make_shared<DataItem>(itemType, itemId, Packet::readItem(input));
}
break;
default:
app.DebugPrintf(" ------ garbage data, or early end of stream due to an incomplete packet\n");
delete result;
return nullptr;
break;
}
result->push_back(item);
switch (itemType)
{
case TYPE_BYTE: item = std::make_shared<DataItem>(itemType, itemId, (byte)input->readByte()); break;
case TYPE_SHORT: item = std::make_shared<DataItem>(itemType, itemId, (short)input->readShort()); break;
case TYPE_INT: item = std::make_shared<DataItem>(itemType, itemId, (int)input->readInt()); break;
case TYPE_FLOAT: item = std::make_shared<DataItem>(itemType, itemId, (float)input->readFloat()); break;
case TYPE_STRING: item = std::make_shared<DataItem>(itemType, itemId, Packet::readUtf(input, MAX_STRING_DATA_LENGTH)); break;
case TYPE_ITEMINSTANCE: item = std::make_shared<DataItem>(itemType, itemId, Packet::readItem(input)); break;
case TYPE_ROTATIONS:
{
float rx = input->readFloat();
float ry = input->readFloat();
float rz = input->readFloat();
item = std::make_shared<DataItem>(itemType, itemId, Rotations(rx, ry, rz));
break;
}
default:
app.DebugPrintf(" ------ garbage data, or early end of stream\n");
delete result;
return nullptr;
}
result->push_back(item);
itemCount++;
currentHeader = input->readByte();
}
return result;
currentHeader = input->readByte();
}
return result;
}
/**
* Assigns values from a list of data items.
*
* @param items
*/
void SynchedEntityData::assignValues(vector<shared_ptr<DataItem> > *items)
void SynchedEntityData::assignValues(vector<shared_ptr<DataItem>>* items)
{
for (auto& item : *items)
{
shared_ptr<DataItem> itemFromId = itemsById[item->getId()];
if( itemFromId != nullptr )
{
switch(item->getType())
{
case TYPE_BYTE:
itemFromId->setValue(item->getValue_byte());
break;
case TYPE_SHORT:
itemFromId->setValue(item->getValue_short());
break;
case TYPE_INT:
itemFromId->setValue(item->getValue_int());
break;
case TYPE_FLOAT:
itemFromId->setValue(item->getValue_float());
break;
case TYPE_STRING:
itemFromId->setValue(item->getValue_wstring());
break;
case TYPE_ITEMINSTANCE:
itemFromId->setValue(item->getValue_itemInstance());
break;
default:
assert(false); // 4J - not implemented
break;
}
}
}
// client-side dirty
m_isDirty = true;
}
bool SynchedEntityData::isEmpty()
{
return m_isEmpty;
}
void SynchedEntityData::clearDirty()
{
m_isDirty = false;
for (auto& item : *items)
{
shared_ptr<DataItem> dest = itemsById[item->getId()];
if (!dest) continue;
switch (item->getType())
{
case TYPE_BYTE: dest->setValue(item->getValue_byte()); break;
case TYPE_SHORT: dest->setValue(item->getValue_short()); break;
case TYPE_INT: dest->setValue(item->getValue_int()); break;
case TYPE_FLOAT: dest->setValue(item->getValue_float()); break;
case TYPE_STRING: dest->setValue(item->getValue_wstring()); break;
case TYPE_ITEMINSTANCE: dest->setValue(item->getValue_itemInstance()); break;
case TYPE_ROTATIONS: dest->setValue(item->getValue_rotations()); break;
default: assert(false); break;
}
}
m_isDirty = true;
}
int SynchedEntityData::getSizeInBytes()
{
int size = 1;
for( int i = 0; i <= MAX_ID_VALUE; i++ )
{
shared_ptr<DataItem> dataItem = itemsById[i];
if(dataItem != nullptr)
{
size += 1;
// write value
switch (dataItem->getType())
{
case TYPE_BYTE:
size += 1;
break;
case TYPE_SHORT:
size += 2;
break;
case TYPE_INT:
size += 4;
break;
case TYPE_FLOAT:
size += 4;
break;
case TYPE_STRING:
size += static_cast<int>(dataItem->getValue_wstring().length()) + 2; // Estimate, assuming all ascii chars
break;
case TYPE_ITEMINSTANCE:
// short + byte + short
size += 2 + 1 + 2; // Estimate, assuming all ascii chars
break;
default:
break;
}
}
}
return size;
int size = 1;
for (int i = 0; i <= MAX_ID_VALUE; i++)
{
shared_ptr<DataItem> item = itemsById[i];
if (!item) continue;
size += 1;
switch (item->getType())
{
case TYPE_BYTE: size += 1; break;
case TYPE_SHORT: size += 2; break;
case TYPE_INT: size += 4; break;
case TYPE_FLOAT: size += 4; break;
case TYPE_STRING: size += (int)item->getValue_wstring().length() + 2; break;
case TYPE_ITEMINSTANCE: size += 5; break;
case TYPE_ROTATIONS: size += 12; break;
default: break;
}
}
return size;
}
//////////////////
// DataItem class
/////////////////
SynchedEntityData::DataItem::DataItem(int type, int id, int value) : type( type ), id( id )
SynchedEntityData::DataItem::DataItem(int type, int id, int value) : type(type), id(id) { value_int = value; dirty = true; }
SynchedEntityData::DataItem::DataItem(int type, int id, byte value) : type(type), id(id) { value_byte = value; dirty = true; }
SynchedEntityData::DataItem::DataItem(int type, int id, short value) : type(type), id(id) { value_short = value; dirty = true; }
SynchedEntityData::DataItem::DataItem(int type, int id, float value) : type(type), id(id) { value_float = value; dirty = true; }
SynchedEntityData::DataItem::DataItem(int type, int id, const wstring& value) : type(type), id(id) { value_wstring = value; dirty = true; }
SynchedEntityData::DataItem::DataItem(int type, int id, shared_ptr<ItemInstance> value) : type(type), id(id) { value_itemInstance = value; dirty = true; }
SynchedEntityData::DataItem::DataItem(int type, int id, const Rotations& value)
: type(type), id(id), value_rotations(value)
{
this->value_int = value;
this->dirty = true;
value_int = 0;
dirty = true;
}
SynchedEntityData::DataItem::DataItem(int type, int id, byte value) : type( type ), id( id )
{
this->value_byte = value;
this->dirty = true;
}
void SynchedEntityData::DataItem::setValue(const Rotations& value) { value_rotations = value; }
Rotations SynchedEntityData::DataItem::getValue_rotations() { return value_rotations; }
SynchedEntityData::DataItem::DataItem(int type, int id, short value) : type( type ), id( id )
{
this->value_short = value;
this->dirty = true;
}
int SynchedEntityData::DataItem::getId() { return id; }
int SynchedEntityData::DataItem::getType() { return type; }
bool SynchedEntityData::DataItem::isDirty() { return dirty; }
void SynchedEntityData::DataItem::setDirty(bool d) { dirty = d; }
SynchedEntityData::DataItem::DataItem(int type, int id, float value) : type( type ), id( id )
{
this->value_float = value;
this->dirty = true;
}
void SynchedEntityData::DataItem::setValue(int v) { value_int = v; }
void SynchedEntityData::DataItem::setValue(byte v) { value_byte = v; }
void SynchedEntityData::DataItem::setValue(short v) { value_short = v; }
void SynchedEntityData::DataItem::setValue(float v) { value_float = v; }
void SynchedEntityData::DataItem::setValue(const wstring& v) { value_wstring = v; }
void SynchedEntityData::DataItem::setValue(shared_ptr<ItemInstance> v) { value_itemInstance = v; }
SynchedEntityData::DataItem::DataItem(int type, int id, const wstring& value) : type( type ), id( id )
{
this->value_wstring = value;
this->dirty = true;
}
SynchedEntityData::DataItem::DataItem(int type, int id, shared_ptr<ItemInstance> itemInstance) : type( type ), id( id )
{
this->value_itemInstance = itemInstance;
this->dirty = true;
}
int SynchedEntityData::DataItem::getId()
{
return id;
}
void SynchedEntityData::DataItem::setValue(int value)
{
this->value_int = value;
}
void SynchedEntityData::DataItem::setValue(byte value)
{
this->value_byte = value;
}
void SynchedEntityData::DataItem::setValue(short value)
{
this->value_short = value;
}
void SynchedEntityData::DataItem::setValue(float value)
{
this->value_float = value;
}
void SynchedEntityData::DataItem::setValue(const wstring& value)
{
this->value_wstring = value;
}
void SynchedEntityData::DataItem::setValue(shared_ptr<ItemInstance> itemInstance)
{
this->value_itemInstance = itemInstance;
}
int SynchedEntityData::DataItem::getValue_int()
{
return value_int;
}
short SynchedEntityData::DataItem::getValue_short()
{
return value_short;
}
float SynchedEntityData::DataItem::getValue_float()
{
return value_float;
}
byte SynchedEntityData::DataItem::getValue_byte()
{
return value_byte;
}
wstring SynchedEntityData::DataItem::getValue_wstring()
{
return value_wstring;
}
shared_ptr<ItemInstance> SynchedEntityData::DataItem::getValue_itemInstance()
{
return value_itemInstance;
}
int SynchedEntityData::DataItem::getType()
{
return type;
}
bool SynchedEntityData::DataItem::isDirty()
{
return dirty;
}
void SynchedEntityData::DataItem::setDirty(bool dirty)
{
this->dirty = dirty;
}
int SynchedEntityData::DataItem::getValue_int() { return value_int; }
short SynchedEntityData::DataItem::getValue_short() { return value_short; }
float SynchedEntityData::DataItem::getValue_float() { return value_float; }
byte SynchedEntityData::DataItem::getValue_byte() { return value_byte; }
wstring SynchedEntityData::DataItem::getValue_wstring() { return value_wstring; }
shared_ptr<ItemInstance> SynchedEntityData::DataItem::getValue_itemInstance() { return value_itemInstance; }

View file

@ -1,135 +1,129 @@
#pragma once
#include "Rotations.h"
using namespace std;
class Pos;
class SynchedEntityData
{
public:
class DataItem
{
friend class SynchedEntityData;
private:
const int type;
const int id;
// 4J - there used to be one "value" type here of general type Object, just storing the different (used) varieties
// here separately for us
union {
byte value_byte;
int value_int;
short value_short;
float value_float;
};
wstring value_wstring;
shared_ptr<ItemInstance> value_itemInstance;
bool dirty;
class DataItem
{
friend class SynchedEntityData;
private:
const int type;
const int id;
union {
byte value_byte;
int value_int;
short value_short;
float value_float;
};
wstring value_wstring;
shared_ptr<ItemInstance> value_itemInstance;
bool dirty;
public:
// There was one type here that took a generic Object type, using overloading here instead
DataItem(int type, int id, byte value);
DataItem(int type, int id, int value);
DataItem(int type, int id, const wstring& value);
DataItem(int type, int id, shared_ptr<ItemInstance> itemInstance);
DataItem(int type, int id, short value);
DataItem(int type, int id, float value);
public:
Rotations value_rotations;
int getId();
void setValue(byte value);
void setValue(int value);
void setValue(short value);
void setValue(float value);
void setValue(const wstring& value);
void setValue(shared_ptr<ItemInstance> value);
byte getValue_byte();
int getValue_int();
short getValue_short();
float getValue_float();
wstring getValue_wstring();
shared_ptr<ItemInstance> getValue_itemInstance();
int getType();
bool isDirty();
void setDirty(bool dirty);
};
DataItem(int type, int id, const Rotations& value);
void setValue(const Rotations& value);
Rotations getValue_rotations();
DataItem(int type, int id, byte value);
DataItem(int type, int id, int value);
DataItem(int type, int id, const wstring& value);
DataItem(int type, int id, shared_ptr<ItemInstance> itemInstance);
DataItem(int type, int id, short value);
DataItem(int type, int id, float value);
int getId();
void setValue(byte value);
void setValue(int value);
void setValue(short value);
void setValue(float value);
void setValue(const wstring& value);
void setValue(shared_ptr<ItemInstance> value);
byte getValue_byte();
int getValue_int();
short getValue_short();
float getValue_float();
wstring getValue_wstring();
shared_ptr<ItemInstance> getValue_itemInstance();
int getType();
bool isDirty();
void setDirty(bool dirty);
};
public:
static const int MAX_STRING_DATA_LENGTH = 64;
static const int EOF_MARKER = 0x7f;
static const int MAX_STRING_DATA_LENGTH = 64;
static const int EOF_MARKER = 0x7f;
static const int TYPE_BYTE = 0;
static const int TYPE_SHORT = 1;
static const int TYPE_INT = 2;
static const int TYPE_FLOAT = 3;
static const int TYPE_STRING = 4;
// special types (max possible value is 7):
static const int TYPE_ITEMINSTANCE = 5;
static const int TYPE_POS = 6;
static const int TYPE_BYTE = 0;
static const int TYPE_SHORT = 1;
static const int TYPE_INT = 2;
static const int TYPE_FLOAT = 3;
static const int TYPE_STRING = 4;
static const int TYPE_ITEMINSTANCE = 5;
static const int TYPE_POS = 6;
static const int TYPE_ROTATIONS = 7;
private:
bool m_isEmpty;
bool m_isEmpty;
// must have enough bits to fit the type
private:
static const int TYPE_MASK = 0xe0;
static const int TYPE_SHIFT = 5;
static const int TYPE_MASK = 0xe0;
static const int TYPE_SHIFT = 5;
static const int MAX_ID_VALUE = ~TYPE_MASK & 0xff;
// the id value must fit in the remaining bits
static const int MAX_ID_VALUE = ~TYPE_MASK & 0xff;
shared_ptr<DataItem> itemsById[MAX_ID_VALUE+1];
bool m_isDirty;
shared_ptr<DataItem> itemsById[MAX_ID_VALUE + 1];
bool m_isDirty;
public:
SynchedEntityData();
SynchedEntityData();
// 4J - this function used to be a template, but there's only 3 varieties of use I've found so just hard-coding now, as
// the original had some automatic Class to type sort of conversion that's a real pain for us to actually do
void define(int id, byte value);
void define(int id, const wstring& value);
void define(int id, int value);
void define(int id, short value);
void define(int id, float value);
void defineNULL(int id, void *pVal);
void define(int id, byte value);
void define(int id, const wstring& value);
void define(int id, int value);
void define(int id, short value);
void define(int id, float value);
void define(int id, const Rotations& value);
void defineNULL(int id, void* pVal);
void checkId(int id); // 4J - added to contain common code from overloaded define functions above
byte getByte(int id);
short getShort(int id);
int getInteger(int id);
float getFloat(int id);
wstring getString(int id);
shared_ptr<ItemInstance> getItemInstance(int id);
Pos *getPos(int id);
// 4J - using overloads rather than template here
void set(int id, byte value);
void set(int id, int value);
void set(int id, short value);
void set(int id, float value);
void set(int id, const wstring& value);
void set(int id, shared_ptr<ItemInstance>);
void markDirty(int id);
bool isDirty();
static void pack(vector<shared_ptr<DataItem> > *items, DataOutputStream *output); // TODO throws IOException
vector<shared_ptr<DataItem> > *packDirty();
void packAll(DataOutputStream *output); // throws IOException
vector<shared_ptr<DataItem> > *getAll();
void checkId(int id);
byte getByte(int id);
short getShort(int id);
int getInteger(int id);
float getFloat(int id);
wstring getString(int id);
shared_ptr<ItemInstance> getItemInstance(int id);
Pos* getPos(int id);
void set(int id, byte value);
void set(int id, int value);
void set(int id, short value);
void set(int id, float value);
void set(int id, const wstring& value);
void set(int id, shared_ptr<ItemInstance>);
void set(int id, const Rotations& value);
Rotations getRotations(int id);
void markDirty(int id);
bool isDirty();
static void pack(vector<shared_ptr<DataItem>>* items, DataOutputStream* output);
vector<shared_ptr<DataItem>>* packDirty();
void packAll(DataOutputStream* output);
vector<shared_ptr<DataItem>>* getAll();
private:
static void writeDataItem(DataOutputStream *output, shared_ptr<DataItem> dataItem); //throws IOException
static void writeDataItem(DataOutputStream* output, shared_ptr<DataItem> dataItem);
public:
static vector<shared_ptr<DataItem> > *unpack(DataInputStream *input); // throws IOException
static vector<shared_ptr<DataItem>>* unpack(DataInputStream* input);
void assignValues(vector<shared_ptr<DataItem>>* items);
bool isEmpty();
void clearDirty();
/**
* Assigns values from a list of data items.
*
* @param items
*/
public:
void assignValues(vector<shared_ptr<DataItem> > *items);
bool isEmpty();
void clearDirty();
// 4J Added
int getSizeInBytes();
// 4J Added
int getSizeInBytes();
};

View file

@ -52,7 +52,7 @@ void Tag::print(ostream out)
out << "";
}
void Tag::print(char *prefix, wostream out)
void Tag::print(char *prefix, wostream& out)
{
wstring name = getName();

View file

@ -32,7 +32,7 @@ public:
virtual wstring toString() = 0;
virtual byte getId() = 0;
void print(ostream out);
void print(char *prefix, wostream out);
void print(char *prefix, wostream& out);
wstring getName();
Tag *setName(const wstring& name);
static Tag *readNamedTag(DataInput *dis);

View file

@ -145,6 +145,8 @@ set(_MINECRAFT_WORLD_COMMON_COM_MOJANG_NBT
"${CMAKE_CURRENT_SOURCE_DIR}/Tag.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Tag.h"
"${CMAKE_CURRENT_SOURCE_DIR}/com.mojang.nbt.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Rotations.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Rotations.cpp"
)
source_group("com/mojang/nbt" FILES ${_MINECRAFT_WORLD_COMMON_COM_MOJANG_NBT})