Compare commits

..

No commits in common. "main" and "v1.0.6b" have entirely different histories.

58 changed files with 339 additions and 1238 deletions

View file

@ -62,7 +62,7 @@ body:
- type: input - type: input
id: itsrevela id: itsrevela
attributes: attributes:
label: Is this reproducable in itsRevela/LCE-Revelations? (https://git.revela.dev/itsRevela/LCE-Revelations) label: Is this reproducable in itsRevela/LCE-Revelations? (https://github.com/itsRevela/LCE-Revelations)
description: If this was a "no idea" or similar, it will be rejected. description: If this was a "no idea" or similar, it will be rejected.
validations: validations:
required: true required: true

BIN
.github/banner.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 KiB

After

Width:  |  Height:  |  Size: 656 KiB

2
BUMP
View file

@ -1 +1 @@
1.0.8b 1.0.6b

View file

@ -8,6 +8,7 @@ ArmorStandModel::ArmorStandModel(float scale) : HumanoidModel(scale)
{ {
texWidth = 64; texWidth = 64;
texHeight = 64; texHeight = 64;
head = new ModelPart(this, 0, 0); head = new ModelPart(this, 0, 0);
head->addBox(-1.0f, -7.0f, -1.0f, 2, 7, 2, scale); head->addBox(-1.0f, -7.0f, -1.0f, 2, 7, 2, scale);

View file

@ -16,7 +16,6 @@
#include "PlayerRenderer.h" #include "PlayerRenderer.h"
#include "../Minecraft.World/SkullItem.h" #include "../Minecraft.World/SkullItem.h"
#include "../Minecraft.World/SkullTileEntity.h" #include "../Minecraft.World/SkullTileEntity.h"
#include "../Minecraft.World/ElytraItem.h"
static const float DEG_TO_RAD = 3.14159265f / 180.0f; static const float DEG_TO_RAD = 3.14159265f / 180.0f;
@ -85,22 +84,9 @@ void ArmorStandRenderer::render(shared_ptr<Entity> entity,
double x, double y, double z, double x, double y, double z,
float rot, float a) float rot, float a)
{ {
shared_ptr<LivingEntity> mob = dynamic_pointer_cast<LivingEntity>(entity);
float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a);
glColor3f(brightness, brightness, brightness);
shared_ptr<ItemInstance> item = mob->getCarriedItem();
prepareCarriedItem(mob, item);
LivingEntityRenderer::render(entity, x, y, z, rot, a); LivingEntityRenderer::render(entity, x, y, z, rot, a);
} }
void ArmorStandRenderer::prepareCarriedItem(shared_ptr<Entity> mob, shared_ptr<ItemInstance> item)
{
armorLayer->armorModel1->holdingRightHand = armorLayer->armorModel2->holdingRightHand = item != nullptr ? 1 : 0;
}
void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob, void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob,
float wp, float ws, float bob, float wp, float ws, float bob,
float headRotMinusBodyRot, float headRotMinusBodyRot,
@ -179,109 +165,7 @@ void ArmorStandRenderer::renderModel(shared_ptr<LivingEntity> mob,
void ArmorStandRenderer::additionalRendering(shared_ptr<LivingEntity> mob, float a) void ArmorStandRenderer::additionalRendering(shared_ptr<LivingEntity> mob, float a)
{ {
{
shared_ptr<ItemInstance> chestItem = mob->getEquipmentSlots()[ArmorStand::SLOT_CHEST];
if (chestItem != nullptr && dynamic_cast<ElytraItem*>(chestItem->getItem()) != nullptr)
{
static ResourceLocation elytraTexture(L"item/elytra.png");
bindTexture(&elytraTexture);
float brightness2 = SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a);
glColor3f(brightness2, brightness2, brightness2);
ArmorStandModel* standModel = ((ArmorStandModel*)this->model);
ArmorStand* stand = dynamic_cast<ArmorStand*>(mob.get());
float wf = 0.2617994f;
float wf1 = -0.2617994f;
float wf2 = standModel->body->y;
float wf3 = 0.0f;
stand->rotateElytraX += (wf - stand->rotateElytraX) * 0.3f;
stand->rotateElytraY += (wf3 - stand->rotateElytraY) * 0.3f;
stand->rotateElytraZ += (wf1 - stand->rotateElytraZ) * 0.3f;
standModel->elytraRight->y = wf2;
standModel->elytraRight->xRot = stand->rotateElytraX;
standModel->elytraRight->yRot = stand->rotateElytraY;
standModel->elytraRight->zRot = stand->rotateElytraZ;
standModel->elytraLeft->y = wf2;
standModel->elytraLeft->xRot = stand->rotateElytraX;
standModel->elytraLeft->yRot = -stand->rotateElytraY;
standModel->elytraLeft->zRot = -stand->rotateElytraZ;
glPushMatrix();
glTranslatef(0, 0.0f, (2.0f + 0.125f) / 16.0f);
standModel->renderElytra(1 / 16.0f, true);
glPopMatrix();
}
}
std::shared_ptr<ItemInstance> item = mob->getCarriedItem();
if (item != nullptr)
{
glPushMatrix();
ArmorStandModel* standModel = ((ArmorStandModel*)model);
if (standModel->young) {
float s = 0.5f;
glTranslatef(0 / 16.0f, 10 / 16.0f, 0 / 16.0f);
glRotatef(-20, -1, 0, 0);
glScalef(s, s, s);
}
standModel->arm1->translateTo(1 / 16.0f);
glTranslatef(-1 / 16.0f, 7 / 16.0f, 1 / 16.0f);
if (item->id < 256 && TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape()) && item->id != Tile::barrier_Id)
{
float s = 8 / 16.0f;
glTranslatef(-0 / 16.0f, 3 / 16.0f, -5 / 16.0f);
s *= 0.75f;
glRotatef(20, 1, 0, 0);
glRotatef(45, 0, 1, 0);
glScalef(-s, -s, s);
}
else if (item->id == Item::bow_Id)
{
float s = 10 / 16.0f;
glTranslatef(0 / 16.0f, 2 / 16.0f, 5 / 16.0f);
glRotatef(-20, 0, 1, 0);
glScalef(s, -s, s);
glRotatef(-100, 1, 0, 0);
glRotatef(45, 0, 1, 0);
}
else if (Item::items[item->id]->isHandEquipped())
{
float s = 10 / 16.0f;
glTranslatef(0, 3 / 16.0f, 0);
glScalef(s, -s, s);
glRotatef(-100, 1, 0, 0);
glRotatef(45, 0, 1, 0);
}
else
{
float s = 6 / 16.0f;
glTranslatef(+4 / 16.0f, +3 / 16.0f, -3 / 16.0f);
glScalef(s, s, s);
glRotatef(60, 0, 0, 1);
glRotatef(-90, 1, 0, 0);
glRotatef(20, 0, 0, 1);
}
this->entityRenderDispatcher->itemInHandRenderer->renderItem(mob, item, 0);
if (item->getItem()->hasMultipleSpriteLayers())
{
this->entityRenderDispatcher->itemInHandRenderer->renderItem(mob, item, 1);
}
glPopMatrix();
}
} }

View file

@ -47,7 +47,5 @@ public:
float headRotMinusBodyRot, float headRotMinusBodyRot,
float headRotx, float scale) override; float headRotx, float scale) override;
virtual int prepareArmor(shared_ptr<LivingEntity> mob, int layer, float a) override; virtual int prepareArmor(shared_ptr<LivingEntity> mob, int layer, float a) override;
void prepareCarriedItem(shared_ptr<Entity> mob, shared_ptr<ItemInstance> item);
virtual void additionalRendering(shared_ptr<LivingEntity> mob, float a) override; virtual void additionalRendering(shared_ptr<LivingEntity> mob, float a) override;
}; };

View file

@ -4323,19 +4323,22 @@ void ClientConnection::handleSetPlayerTeamPacket(shared_ptr<SetPlayerTeamPacket>
void ClientConnection::handleParticleEvent(shared_ptr<LevelParticlesPacket> packet) void ClientConnection::handleParticleEvent(shared_ptr<LevelParticlesPacket> packet)
{ {
ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)Integer::parseInt(packet->getName()); const ParticleType* type = packet->getType();
if (type == nullptr) return;
for (int i = 0; i < packet->getCount(); i++) ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)type->getId();
{
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); 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) void ClientConnection::handleUpdateAttributes(shared_ptr<UpdateAttributesPacket> packet)

View file

@ -56,7 +56,8 @@ enum EGameHostOptionWorldSize
e_worldSize_Classic, e_worldSize_Classic,
e_worldSize_Small, e_worldSize_Small,
e_worldSize_Medium, e_worldSize_Medium,
e_worldSize_Large e_worldSize_Large,
e_worldSize_Expanded
}; };

View file

@ -916,7 +916,7 @@ void IUIScene_CraftingMenu::UpdateHighlight()
// special case for the torch coal/charcoal // special case for the torch coal/charcoal
int id=pTempItemInstAdditional->getDescriptionId(); int id=pTempItemInstAdditional->getDescriptionId();
wstring itemstring; LPCWSTR itemstring;
switch(id) switch(id)
{ {
@ -945,15 +945,11 @@ void IUIScene_CraftingMenu::UpdateHighlight()
} }
break; break;
default: default:
if (pTempItemInstAdditional->hasCustomHoverName()) { itemstring=app.GetString(id );
itemstring = pTempItemInstAdditional->getHoverName();
} else {
itemstring = app.GetString(id);
}
break; break;
} }
setItemText(itemstring.c_str()); setItemText(itemstring);
} }
else else
{ {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -13,19 +13,11 @@
#include "../Minecraft.World/SkullTileEntity.h" #include "../Minecraft.World/SkullTileEntity.h"
#include "../Minecraft.World/LivingEntity.h" #include "../Minecraft.World/LivingEntity.h"
#include "../Minecraft.World/Facing.h" #include "../Minecraft.World/Facing.h"
#include "../Minecraft.Client/SimpleIcon.h"
#include "../Minecraft.World/AirTile.h"
CustomHeadLayer::CustomHeadLayer(ModelPart* headPart, LivingEntityRenderer* parentRenderer) CustomHeadLayer::CustomHeadLayer(ModelPart* headPart, LivingEntityRenderer* parentRenderer)
: headPart(headPart), parentRenderer(parentRenderer) : headPart(headPart), parentRenderer(parentRenderer)
{ {
tileRenderer = new TileRenderer();
}
CustomHeadLayer::~CustomHeadLayer() {
delete tileRenderer;
} }
int CustomHeadLayer::colorsOnDamage() int CustomHeadLayer::colorsOnDamage()
@ -98,136 +90,12 @@ void CustomHeadLayer::render(shared_ptr<LivingEntity> mob,
glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
Minecraft* mc = Minecraft::GetInstance();
if (mc)
{ {
// 4J - code borrowed from render method below, although not factoring in brightness as that should already be being taken into account auto* iihr = mc->getItemInHandRenderer();
// by texture lighting. This is for colourising things held in 3rd person view. if (iihr)
if ((item != nullptr)) { iihr->renderItem(mob, helmet, 0, true);
int col = Item::items[item->id]->getColor(helmet, 0);
float red = ((col >> 16) & 0xff) / 255.0f;
float g = ((col >> 8) & 0xff) / 255.0f;
float b = ((col) & 0xff) / 255.0f;
glColor4f(red, g, b, 1);
}
Minecraft* minecraft = Minecraft::GetInstance();
glPushMatrix();
Tile* tile = Tile::tiles[item->id];
if ((item->getIconType() == Icon::TYPE_TERRAIN && tile != nullptr && TileRenderer::canRender(tile->getRenderShape())) && item->id != AirTile::barrier_Id)
{
MemSect(31);
minecraft->textures->bindTexture(minecraft->textures->getTextureLocation(Icon::TYPE_TERRAIN));
MemSect(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
tileRenderer->renderTile(Tile::tiles[item->id], helmet->getAuxValue(), SharedConstants::TEXTURE_LIGHTING ? 1.0f : mob->getBrightness(1)); // 4J - change brought forward from 1.8.2
glDisable(GL_BLEND);
}
else
{
MemSect(31);
Icon* icon = mob->getItemInHandIcon(helmet, 0);
if (icon == nullptr)
{
glPopMatrix();
MemSect(0);
return;
}
bool bIsTerrain = item->getIconType() == Icon::TYPE_TERRAIN;
minecraft->textures->bindTexture(minecraft->textures->getTextureLocation(item->getIconType()));
MemSect(0);
Tesselator* t = Tesselator::getInstance();
// Consider forcing the mipmap LOD level to use, if this is to be rendered from a larger than standard source texture.
int iconWidth = icon->getWidth();
int LOD = -1; // Default to not doing anything special with LOD forcing
if (iconWidth == 32)
{
LOD = 1; // Force LOD level 1 to achieve texture reads from 256x256 map
}
else if (iconWidth == 64)
{
LOD = 2; // Force LOD level 2 to achieve texture reads from 256x256 map
}
RenderManager.StateSetForceLOD(LOD);
// 4J Original comment
// Yes, these are backwards.
// No, I don't know why.
// 4J Stu - Make them the right way round...u coords were swapped
float u0 = icon->getU0();
float u1 = icon->getU1();
float v0 = icon->getV0();
float v1 = icon->getV1();
float xo = 0.0f;
float yo = 0.3f;
// Re position height of held item if skin is small
if (mob->getAnimOverrideBitmask() & (1 << HumanoidModel::eAnim_SmallModel))
{
if (mob->isRiding())
{
std::shared_ptr<Entity> ridingEntity = mob->riding;
if (ridingEntity != nullptr) // Safety check;
{
yo += 0.3f; // reverts the change in Boat.cpp for smaller models.
}
}
}
glEnable(GL_RESCALE_NORMAL);
glTranslatef(-xo, -yo, 0);
glScalef(1, 1, 1);
glRotatef(90, 0, 1, 0);
glTranslatef(-7.5f / 16.0f, 9 / 16.0f, 0);
glTranslatef(0, 0.03f, 0);
float dd = 1 / 16.0f;
ItemInHandRenderer::renderItem3D(t, u0, v0, u1, v1, icon->getSourceWidth(), icon->getSourceHeight(), 1 / 16.0f, false, bIsTerrain);
if (item != nullptr && helmet->isFoil())
{
glDepthFunc(GL_EQUAL);
glDisable(GL_LIGHTING);
minecraft->textures->bindTexture(&ItemInHandRenderer::ENCHANT_GLINT_LOCATION);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR, GL_ONE);
float br = 0.76f;
glColor4f(0.5f * br, 0.25f * br, 0.8f * br, 1); // MGH - for some reason this colour isn't making it through to the render, so I've added to the tesselator for the glint geom above
glMatrixMode(GL_TEXTURE);
glPushMatrix();
float ss = 1 / 8.0f;
glScalef(ss, ss, ss);
float sx = Minecraft::currentTimeMillis() % (3000) / (3000.0f) * 8;
glTranslatef(sx, 0, 0);
glRotatef(-50, 0, 0, 1);
ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 256, 256, 1 / 16.0f, true, bIsTerrain);
glPopMatrix();
glPushMatrix();
glScalef(ss, ss, ss);
sx = System::currentTimeMillis() % (3000 + 1873) / (3000 + 1873.0f) * 8;
glTranslatef(-sx, 0, 0);
glRotatef(10, 0, 0, 1);
ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 256, 256, 1 / 16.0f, true, bIsTerrain);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glDepthFunc(GL_LEQUAL);
}
RenderManager.StateSetForceLOD(-1);
glDisable(GL_RESCALE_NORMAL);
}
glPopMatrix();
} }
} }

View file

@ -4,17 +4,14 @@
class ModelPart; class ModelPart;
class LivingEntity; class LivingEntity;
class LivingEntityRenderer; class LivingEntityRenderer;
class TileRenderer;
class CustomHeadLayer : public RenderLayer { class CustomHeadLayer : public RenderLayer {
public: public:
ModelPart* headPart; ModelPart* headPart;
LivingEntityRenderer* parentRenderer; LivingEntityRenderer* parentRenderer;
TileRenderer* tileRenderer;
CustomHeadLayer(ModelPart* headPart, LivingEntityRenderer* parentRenderer); CustomHeadLayer(ModelPart* headPart, LivingEntityRenderer* parentRenderer);
virtual ~CustomHeadLayer(); virtual ~CustomHeadLayer() {}
virtual int colorsOnDamage() override; virtual int colorsOnDamage() override;
virtual void render(shared_ptr<LivingEntity> mob, virtual void render(shared_ptr<LivingEntity> mob,

View file

@ -8,15 +8,6 @@ GuiParticles::GuiParticles(Minecraft *mc)
this->mc = mc; this->mc = mc;
} }
GuiParticles::~GuiParticles()
{
for (GuiParticle *gp : particles)
{
delete gp;
}
particles.clear();
}
void GuiParticles::tick() void GuiParticles::tick()
{ {
for (unsigned int i = 0; i < particles.size(); i++) for (unsigned int i = 0; i < particles.size(); i++)
@ -28,7 +19,6 @@ void GuiParticles::tick()
if (gp->removed) if (gp->removed)
{ {
delete gp;
particles.erase(particles.begin()+i); particles.erase(particles.begin()+i);
i--; i--;
} }

View file

@ -13,7 +13,6 @@ private:
public: public:
GuiParticles(Minecraft *mc); GuiParticles(Minecraft *mc);
~GuiParticles();
void tick(); void tick();
void add(GuiParticle *guiParticle); void add(GuiParticle *guiParticle);
void render(float a); void render(float a);

View file

@ -555,7 +555,7 @@ void LivingEntityRenderer::renderName(shared_ptr<LivingEntity> mob, double x, do
bool LivingEntityRenderer::shouldShowName(shared_ptr<LivingEntity> mob) bool LivingEntityRenderer::shouldShowName(shared_ptr<LivingEntity> mob)
{ {
return Minecraft::renderNames() && mob != entityRenderDispatcher->cameraEntity && (!mob->isInvisibleTo(Minecraft::GetInstance()->player) || mob->isCustomNameVisible()) && mob->rider.lock() == nullptr; return Minecraft::renderNames() && mob != entityRenderDispatcher->cameraEntity && !mob->isInvisibleTo(Minecraft::GetInstance()->player) && mob->rider.lock() == nullptr;
} }
void LivingEntityRenderer::renderNameTags(shared_ptr<LivingEntity> mob, double x, double y, double z, const wstring &msg, float scale, double dist) void LivingEntityRenderer::renderNameTags(shared_ptr<LivingEntity> mob, double x, double y, double z, const wstring &msg, float scale, double dist)

View file

@ -10,14 +10,7 @@ public:
int id; int id;
bool isLoaded; bool isLoaded;
int ticksSinceLastUse; int ticksSinceLastUse;
// @CDevJoud static const int UNUSED_TICKS_TO_FREE = 20;
// changing the lifetime of the texture from 20 ticks(1 sec) to 200 ticks (10 sec)
// as it helps the texture to have longer lifetime and reducing the usage of loadTexture for every second/frame
// note that we dont remove the code that removes the textures from `tick()` as it is required in memory limited environment such as older Consoles(PS3/XBOX360)
static const int UNUSED_TICKS_TO_FREE = 200;
//default ctor for int Texture::getHeight(const wstring& url, int backup)
MemTexture() = default;
MemTexture(const wstring& _name, PBYTE pbData, DWORD dwBytes, MemTextureProcessor *processor); MemTexture(const wstring& _name, PBYTE pbData, DWORD dwBytes, MemTextureProcessor *processor);
~MemTexture(); ~MemTexture();

View file

@ -526,10 +526,9 @@ LevelStorageSource *Minecraft::getLevelSource()
void Minecraft::setScreen(Screen *screen) void Minecraft::setScreen(Screen *screen)
{ {
Screen *oldScreen = this->screen; if (this->screen != nullptr)
if (oldScreen != nullptr)
{ {
oldScreen->removed(); this->screen->removed();
} }
#ifdef _WINDOWS64 #ifdef _WINDOWS64
@ -4439,8 +4438,6 @@ void Minecraft::setLevel(MultiPlayerLevel *level, int message /*=-1*/, shared_pt
// 4J If we are setting the level to nullptr then we are exiting, so delete the levels // 4J If we are setting the level to nullptr then we are exiting, so delete the levels
if( level == nullptr ) if( level == nullptr )
{ {
if (soundEngine) soundEngine->stopElytraSound();
if(levels[0]!=nullptr) if(levels[0]!=nullptr)
{ {
delete levels[0]; delete levels[0];

View file

@ -94,7 +94,7 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
this->level = level; this->level = level;
this->cache = new LevelChunk *[XZSIZE * XZSIZE]; this->cache = new LevelChunk *[XZSIZE * XZSIZE];
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *)); memset(this->cache, 0, sizeof(LevelChunk*) * XZSIZE * XZSIZE);
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000); InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000);
} }
@ -132,7 +132,7 @@ bool MultiPlayerChunkCache::reallyHasChunk(int x, int z)
int idx = ix * XZSIZE + iz; int idx = ix * XZSIZE + iz;
LevelChunk *chunk = cache[idx]; LevelChunk *chunk = cache[idx];
if( chunk == nullptr ) if (chunk == nullptr)
{ {
return false; return false;
} }
@ -145,7 +145,8 @@ void MultiPlayerChunkCache::drop(const int x, const int z)
const int iz = z + XZOFFSET; const int iz = z + XZOFFSET;
if ((ix < 0) || (ix >= XZSIZE)) return; if ((ix < 0) || (ix >= XZSIZE)) return;
if ((iz < 0) || (iz >= XZSIZE)) return; if ((iz < 0) || (iz >= XZSIZE)) return;
const int idx = ix * XZSIZE + iz;
int idx = ix * XZSIZE + iz;
LevelChunk* chunk = cache[idx]; LevelChunk* chunk = cache[idx];
if (chunk != nullptr && !chunk->isEmpty()) if (chunk != nullptr && !chunk->isEmpty())
@ -169,6 +170,7 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk ); if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk ); if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
int idx = ix * XZSIZE + iz; int idx = ix * XZSIZE + iz;
LevelChunk *chunk = cache[idx]; LevelChunk *chunk = cache[idx];
LevelChunk *lastChunk = chunk; LevelChunk *lastChunk = chunk;

View file

@ -1046,13 +1046,6 @@ void PlayerConnection::handleCommand(const wstring& message)
ss >> cmd; ss >> cmd;
if (cmd == L"tp" || cmd == L"teleport") if (cmd == L"tp" || cmd == L"teleport")
{ {
if (!app.GetGameHostOption(eGameHostOption_CheatsEnabled))
{
warn(L"Cheats are not enabled on this server.");
return;
}
if (!player->hasPermission(eGameCommand_Teleport)) if (!player->hasPermission(eGameCommand_Teleport))
{ {
warn(L"You do not have permission to use this command."); warn(L"You do not have permission to use this command.");
@ -1145,13 +1138,6 @@ if (cmd == L"tp" || cmd == L"teleport")
} }
} else if (cmd == L"time") } else if (cmd == L"time")
{ {
if (!app.GetGameHostOption(eGameHostOption_CheatsEnabled))
{
warn(L"Cheats are not enabled on this server.");
return;
}
if (!player->hasPermission(eGameCommand_Time)) if (!player->hasPermission(eGameCommand_Time))
{ {
warn(L"You do not have permission to use this command."); warn(L"You do not have permission to use this command.");
@ -1282,44 +1268,15 @@ if (cmd == L"tp" || cmd == L"teleport")
} }
else if (cmd == L"kill") else if (cmd == L"kill")
{ {
if (!app.GetGameHostOption(eGameHostOption_CheatsEnabled))
{
warn(L"Cheats are not enabled on this server.");
return;
}
if (!player->hasPermission(eGameCommand_Kill)) if (!player->hasPermission(eGameCommand_Kill))
{ {
warn(L"You do not have permission to use this command."); warn(L"You do not have permission to use this command.");
return; return;
} }
server->getCommandDispatcher()->performCommand(player, eGameCommand_Kill, byteArray());
wstring targetName;
ss >> targetName;
if (targetName.empty())
{
server->getCommandDispatcher()->performCommand(player, eGameCommand_Kill, byteArray());
}
else
{
ByteArrayOutputStream baos;
DataOutputStream dos(&baos);
dos.writeUTF(targetName);
byteArray data = baos.toByteArray();
server->getCommandDispatcher()->performCommand(player, eGameCommand_Kill, data);
}
} }
else if (cmd == L"toggledownfall") else if (cmd == L"toggledownfall")
{ {
if (!app.GetGameHostOption(eGameHostOption_CheatsEnabled))
{
warn(L"Cheats are not enabled on this server.");
return;
}
if (!player->hasPermission(eGameCommand_ToggleDownfall)) if (!player->hasPermission(eGameCommand_ToggleDownfall))
{ {
warn(L"You do not have permission to use this command."); warn(L"You do not have permission to use this command.");
@ -1328,14 +1285,6 @@ if (cmd == L"tp" || cmd == L"teleport")
shared_ptr<GameCommandPacket> packet = ToggleDownfallCommand::preparePacket(); shared_ptr<GameCommandPacket> packet = ToggleDownfallCommand::preparePacket();
server->getCommandDispatcher()->performCommand(player, eGameCommand_ToggleDownfall, packet->data); server->getCommandDispatcher()->performCommand(player, eGameCommand_ToggleDownfall, packet->data);
} else if (cmd == L"gamemode") { } else if (cmd == L"gamemode") {
if (!app.GetGameHostOption(eGameHostOption_CheatsEnabled))
{
warn(L"Cheats are not enabled on this server.");
return;
}
if (!player->hasPermission(eGameCommand_GameMode)) if (!player->hasPermission(eGameCommand_GameMode))
{ {
warn(L"You do not have permission to use this command."); warn(L"You do not have permission to use this command.");
@ -1374,13 +1323,6 @@ if (cmd == L"tp" || cmd == L"teleport")
shared_ptr<GameCommandPacket> packet = GameModeCommand::preparePacket(target, mode); shared_ptr<GameCommandPacket> packet = GameModeCommand::preparePacket(target, mode);
server->getCommandDispatcher()->performCommand(player, eGameCommand_GameMode, packet->data); server->getCommandDispatcher()->performCommand(player, eGameCommand_GameMode, packet->data);
} else if (cmd == L"give") { } else if (cmd == L"give") {
if (!app.GetGameHostOption(eGameHostOption_CheatsEnabled))
{
warn(L"Cheats are not enabled on this server.");
return;
}
if (!player->hasPermission(eGameCommand_Give)) if (!player->hasPermission(eGameCommand_Give))
{ {
warn(L"You do not have permission to use this command."); warn(L"You do not have permission to use this command.");
@ -1926,8 +1868,6 @@ void PlayerConnection::handleGameCommand(shared_ptr<GameCommandPacket> packet)
player->getName().c_str(), player->isModerator() ? 1 : 0, isHost ? 1 : 0, player->getName().c_str(), player->isModerator() ? 1 : 0, isHost ? 1 : 0,
static_cast<int>(packet->command)); static_cast<int>(packet->command));
#endif #endif
MinecraftServer::getInstance()->getCommandDispatcher()->performCommand(player, packet->command, packet->data); MinecraftServer::getInstance()->getCommandDispatcher()->performCommand(player, packet->command, packet->data);
} }

View file

@ -23,18 +23,6 @@ Screen::Screen() // 4J added
clickedButton = nullptr; clickedButton = nullptr;
} }
Screen::~Screen()
{
delete particles;
particles = nullptr;
for (Button *button : buttons)
{
delete button;
}
buttons.clear();
}
void Screen::render(int xm, int ym, float a) void Screen::render(int xm, int ym, float a)
{ {
for (Button* button : buttons) for (Button* button : buttons)

View file

@ -22,7 +22,6 @@ public:
GuiParticles *particles; GuiParticles *particles;
Screen(); // 4J added Screen(); // 4J added
virtual ~Screen();
virtual void render(int xm, int ym, float a); virtual void render(int xm, int ym, float a);
protected: protected:
virtual void keyPressed(wchar_t eventCharacter, int eventKey); virtual void keyPressed(wchar_t eventCharacter, int eventKey);

View file

@ -1683,15 +1683,14 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFoun
} }
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) 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)
{ {
wchar_t buf[32];
swprintf_s(buf, L"%d", type->getId());
auto packet = make_shared<LevelParticlesPacket>( auto packet = make_shared<LevelParticlesPacket>(
buf, type,
longDistance,
(float)x, (float)y, (float)z, (float)x, (float)y, (float)z,
(float)dx, (float)dy, (float)dz, (float)dx, (float)dy, (float)dz,
(float)speed, (float)speed,
count count,
data
); );
for (auto const& p : players) for (auto const& p : players)

View file

@ -138,21 +138,12 @@ private:
// 4J - added for implementation of finite limit to number of item entities, tnt and falling block entities // 4J - added for implementation of finite limit to number of item entities, tnt and falling block entities
public: public:
static const int MAX_HANGING_ENTITIES = 800; static const int MAX_HANGING_ENTITIES = 400;
static const int MAX_ITEM_ENTITIES = 400; static const int MAX_ITEM_ENTITIES = 200;
static const int MAX_ARROW_ENTITIES = 400; static const int MAX_ARROW_ENTITIES = 200;
static const int MAX_EXPERIENCEORB_ENTITIES = 100; static const int MAX_EXPERIENCEORB_ENTITIES = 50;
static const int MAX_PRIMED_TNT = 40; static const int MAX_PRIMED_TNT = 20;
static const int MAX_FALLING_TILE = 40; static const int MAX_FALLING_TILE = 20;
//static const int MAX_HANGING_ENTITIES = 400;
//static const int MAX_ITEM_ENTITIES = 200;
//static const int MAX_ARROW_ENTITIES = 200;
//static const int MAX_EXPERIENCEORB_ENTITIES = 50;
//static const int MAX_PRIMED_TNT = 20;
//static const int MAX_FALLING_TILE = 20;
int m_primedTntCount; int m_primedTntCount;
int m_fallingTileCount; int m_fallingTileCount;

View file

@ -850,10 +850,8 @@ void ServerPlayer::die(DamageSource *source)
bool ServerPlayer::hurt(DamageSource *dmgSource, float dmg) bool ServerPlayer::hurt(DamageSource *dmgSource, float dmg)
{ {
if (isInvulnerable() && dmgSource != DamageSource::outOfWorld) return false; if (isInvulnerable()) return false;
if (gameMode == nullptr || gameMode->isCreative()) { if (gameMode == nullptr||gameMode->isCreative()) return false;
if (dmgSource != DamageSource::outOfWorld) return false;
}
// 4J: Not relevant to console servers // 4J: Not relevant to console servers
// Allow falldamage on dedicated pvpservers -- so people cannot cheat their way out of 'fall traps' // Allow falldamage on dedicated pvpservers -- so people cannot cheat their way out of 'fall traps'

View file

@ -1256,14 +1256,8 @@ int Textures::getHeight(const wstring& url, int backup)
if (img) if (img)
{ {
MemTexture* _texture = new MemTexture();
_texture->loadedImage = img;
_texture->isLoaded = true;
_texture->id = getTexture(_texture->loadedImage, C4JRender::TEXTURE_FORMAT_RxGyBzAw, MIPMAP);
int h = img->getHeight(); int h = img->getHeight();
//delete img; // commenting this out and inserting the loaded texture to memTextures unordered_map delete img;
this->memTextures[url] = _texture;
return h; return h;
} }

View file

@ -290,53 +290,24 @@ void TrackedEntity::tick(EntityTracker *tracker, vector<shared_ptr<Player> > *pl
wasRiding = false; wasRiding = false;
} }
else else
{ {
// the entity have a rider, the code didnt send position updates, bool rot = abs(yRotn - yRotp) >= TOLERANCE_LEVEL || abs(xRotn - xRotp) >= TOLERANCE_LEVEL;
// causing desync between client and server when boat was spritning. if (rot)
{
// 4J: Changed this to use deltas
broadcast(std::make_shared<MoveEntityPacket::Rot>(e->entityId, static_cast<byte>(yRota), static_cast<byte>(xRota)));
yRotp = yRotn;
xRotp = xRotn;
}
bool rot = abs(yRotn - yRotp) >= TOLERANCE_LEVEL || abs(xRotn - xRotp) >= TOLERANCE_LEVEL; xp = Mth::floor(e->x * 32.0);
if (rot) yp = Mth::floor(e->y * 32.0);
{ zp = Mth::floor(e->z * 32.0);
broadcast(std::make_shared<MoveEntityPacket::Rot>(e->entityId, static_cast<byte>(yRota), static_cast<byte>(xRota)));
yRotp = yRotn;
xRotp = xRotn;
}
int xn = Mth::floor(e->x * 32.0); sendDirtyEntityData();
int yn = Mth::floor(e->y * 32.0);
int zn = Mth::floor(e->z * 32.0);
int xa = xn - xp;
int ya = yn - yp;
int za = zn - zp;
// send only if the boat moved enough wasRiding = true;
// or 3 seconds periodically }
bool pos = abs(xa) >= TOLERANCE_LEVEL || abs(ya) >= TOLERANCE_LEVEL || abs(za) >= TOLERANCE_LEVEL
|| (tickCount % (SharedConstants::TICKS_PER_SECOND * 3) == 0);
if (pos)
{
// if deltapos is too much big use teleport.
if (xa < -128 || xa >= 128 || ya < -128 || ya >= 128 || za < -128 || za >= 128)
{
broadcast(std::make_shared<TeleportEntityPacket>(e->entityId, xn, yn, zn,
static_cast<byte>(yRotn), static_cast<byte>(xRotn)));
}
else
{
// small movement, delta
broadcast(std::make_shared<MoveEntityPacket::Pos>(e->entityId,
static_cast<char>(xa), static_cast<char>(ya), static_cast<char>(za)));
}
xp = xn;
yp = yn;
zp = zn;
}
sendDirtyEntityData();
wasRiding = true;
}
int yHeadRot = Mth::floor(e->getYHeadRot() * 256 / 360); int yHeadRot = Mth::floor(e->getYHeadRot() * 256 / 360);
if (abs(yHeadRot - yHeadRotp) >= TOLERANCE_LEVEL) if (abs(yHeadRot - yHeadRotp) >= TOLERANCE_LEVEL)

View file

@ -149,57 +149,47 @@ static void CopyWideArgToAnsi(LPCWSTR source, char* dest, size_t destSize)
dest[destSize - 1] = 0; dest[destSize - 1] = 0;
} }
// ---------- Persistent options (options.dat next to exe) ---------- // ---------- Persistent options (options.txt next to exe) ----------
static void GetOptionsFilePath(char *out, DWORD outSize) static void GetOptionsFilePath(char *out, size_t outSize)
{ {
GetModuleFileNameA(nullptr, out, outSize); GetModuleFileNameA(nullptr, out, static_cast<DWORD>(outSize));
char *p = strrchr(out, '\\'); char *p = strrchr(out, '\\');
if (p) *(p + 1) = '\0'; if (p) *(p + 1) = '\0';
strncat_s(out, outSize, "settings.dat", _TRUNCATE); strncat_s(out, outSize, "options.txt", _TRUNCATE);
} }
static void SaveFullscreenOption(bool fullscreen) static void SaveFullscreenOption(bool fullscreen)
{ {
GAME_SETTINGS settings = {}; char path[MAX_PATH];
GetOptionsFilePath(path, sizeof(path));
char path[MAX_PATH] = {}; FILE *f = nullptr;
GetOptionsFilePath(path, MAX_PATH); if (fopen_s(&f, path, "w") == 0 && f)
FILE *f = nullptr; {
if (fopen_s(&f, path, "rb") == 0 && f) fprintf(f, "fullscreen=%d\n", fullscreen ? 1 : 0);
{ fclose(f);
fread(&settings, sizeof(GAME_SETTINGS), 1, f); }
fclose(f);
}
if (fullscreen)
settings.uiBitmaskValues |= (1UL << 25);
else
settings.uiBitmaskValues &= ~(1UL << 25);
if (fopen_s(&f, path, "wb") == 0 && f)
{
fwrite(&settings, sizeof(GAME_SETTINGS), 1, f);
fclose(f);
}
} }
static bool LoadFullscreenOption() static bool LoadFullscreenOption()
{ {
char path[MAX_PATH] = {}; char path[MAX_PATH];
GetOptionsFilePath(path, sizeof(path)); GetOptionsFilePath(path, sizeof(path));
FILE *f = nullptr;
FILE *f = nullptr; if (fopen_s(&f, path, "r") == 0 && f)
if (fopen_s(&f, path, "rb") != 0 || !f) {
return false; char line[256];
while (fgets(line, sizeof(line), f))
GAME_SETTINGS current = {}; {
bool ok = (fread(&current, sizeof(GAME_SETTINGS), 1, f) == 1); int val = 0;
fclose(f); if (sscanf_s(line, "fullscreen=%d", &val) == 1)
{
if (!ok) fclose(f);
return false; return val != 0;
}
return (current.uiBitmaskValues & (1UL << 25)) != 0; }
fclose(f);
}
return false;
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -834,7 +824,8 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
return FALSE; return FALSE;
} }
ShowWindow(g_hWnd, (nCmdShow != SW_HIDE) ? SW_SHOWMAXIMIZED : nCmdShow);
UpdateWindow(g_hWnd);
return TRUE; return TRUE;
} }
@ -1465,9 +1456,8 @@ void CleanupDevice()
static Minecraft* InitialiseMinecraftRuntime() static Minecraft* InitialiseMinecraftRuntime()
{ {
app.loadMediaArchive(); app.loadMediaArchive();
// @CDevJoud: No need to call this method as it gets called once in `InitDevice()`
// Calling it again and it results of 20MB of memory leak! RenderManager.Initialise(g_pd3dDevice, g_pSwapChain);
//RenderManager.Initialise(g_pd3dDevice, g_pSwapChain);
app.loadStringTable(); app.loadStringTable();
ui.init(g_pd3dDevice, g_pImmediateContext, g_pRenderTargetView, g_pDepthStencilView, g_rScreenWidth, g_rScreenHeight); ui.init(g_pd3dDevice, g_pImmediateContext, g_pRenderTargetView, g_pDepthStencilView, g_rScreenWidth, g_rScreenHeight);
@ -1705,12 +1695,11 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
CleanupDevice(); CleanupDevice();
return 0; return 0;
} }
// Restore fullscreen state from previous session. Route through the // Restore fullscreen state from previous session. Route through the
// deferred exclusive fullscreen path so the main loop applies it on the // deferred exclusive fullscreen path so the main loop applies it on the
// first tick (safer than transitioning during init). // first tick (safer than transitioning during init).
if ((LoadFullscreenOption() && !g_isFullscreen) || launchOptions.fullscreen)
bool FullScreenEnabled = LoadFullscreenOption();
if (FullScreenEnabled && !g_isFullscreen)
{ {
g_bPendingExclusiveFullscreen = true; g_bPendingExclusiveFullscreen = true;
g_bPendingExclusiveFullscreenValue = true; g_bPendingExclusiveFullscreenValue = true;
@ -1775,7 +1764,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
return 1; return 1;
} }
g_bResizeReady = true; g_bResizeReady = true;
//app.TemporaryCreateGameStart(); //app.TemporaryCreateGameStart();
//Sleep(10000); //Sleep(10000);
@ -1801,20 +1790,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
hr = XuiTimersRun(); hr = XuiTimersRun();
} }
#endif #endif
// @CDevJoud The window should only be shown after the engine/game
// initialization has fully completed.
//
// Showing the window too early especially on low end devices,
// may cause windows to display a "Not Responding" state while
// initialization is still in progress.
//
// This creates an unprofessional first impression for the player.
// Instead, initialize all engine systems first, then display the
// window once everything is ready.
ShowWindow(g_hWnd, (nCmdShow != SW_HIDE) ? SW_SHOWMAXIMIZED : nCmdShow);
UpdateWindow(g_hWnd);
MSG msg = {0}; MSG msg = {0};
while( WM_QUIT != msg.message && !app.m_bShutdown) while( WM_QUIT != msg.message && !app.m_bShutdown)
{ {

View file

@ -1281,9 +1281,10 @@ void __cdecl NativeSpawnParticle(int entityId, int particleId, float x, float y,
{ {
auto player = FindPlayer(entityId); auto player = FindPlayer(entityId);
if (!player || !player->connection) return; if (!player || !player->connection) return;
wchar_t buf[32]; const ParticleType* type = ParticleType::byId(particleId);
swprintf_s(buf, L"%d", particleId); if (!type) type = ParticleType::getDefault();
player->connection->send(std::make_shared<LevelParticlesPacket>(std::wstring(buf), x, y, z, offsetX, offsetY, offsetZ, speed, count)); arrayWithLength<int> noParams = { nullptr, 0 };
player->connection->send(std::make_shared<LevelParticlesPacket>(type, false, x, y, z, offsetX, offsetY, offsetZ, speed, count, noParams));
} }
int __cdecl NativeSetPassenger(int entityId, int passengerEntityId) int __cdecl NativeSetPassenger(int entityId, int passengerEntityId)

View file

@ -628,6 +628,8 @@ static std::string WorldSizeToPropertyValue(int worldSize)
return "medium"; return "medium";
case e_worldSize_Large: case e_worldSize_Large:
return "large"; return "large";
case e_worldSize_Expanded:
return "expanded";
case e_worldSize_Classic: case e_worldSize_Classic:
default: default:
return "classic"; return "classic";
@ -644,6 +646,8 @@ static int WorldSizeToXzChunks(int worldSize)
return LEVEL_WIDTH_MEDIUM; return LEVEL_WIDTH_MEDIUM;
case e_worldSize_Large: case e_worldSize_Large:
return LEVEL_WIDTH_LARGE; return LEVEL_WIDTH_LARGE;
case e_worldSize_Expanded:
return LEVEL_WIDTH_EXPANDED;
case e_worldSize_Classic: case e_worldSize_Classic:
default: default:
return LEVEL_WIDTH_CLASSIC; return LEVEL_WIDTH_CLASSIC;
@ -659,6 +663,7 @@ static int WorldSizeToHellScale(int worldSize)
case e_worldSize_Medium: case e_worldSize_Medium:
return HELL_LEVEL_SCALE_MEDIUM; return HELL_LEVEL_SCALE_MEDIUM;
case e_worldSize_Large: case e_worldSize_Large:
case e_worldSize_Expanded:
return HELL_LEVEL_SCALE_LARGE; return HELL_LEVEL_SCALE_LARGE;
case e_worldSize_Classic: case e_worldSize_Classic:
default: default:
@ -694,6 +699,12 @@ static bool TryParseWorldSize(const std::string &lowered, int *outWorldSize)
return true; return true;
} }
if (lowered == "expanded" || lowered == "344" || lowered == "8")
{
*outWorldSize = e_worldSize_Expanded;
return true;
}
return false; return false;
} }

View file

@ -54,16 +54,10 @@ AABB *AABB::newPermanent(double x0, double y0, double z0, double x1, double y1,
void AABB::clearPool() void AABB::clearPool()
{ {
ThreadStorage *tls = static_cast<ThreadStorage *>(TlsGetValue(tlsIdx));
if (tls != nullptr)
{
tls->poolPointer = 0;
}
} }
void AABB::resetPool() void AABB::resetPool()
{ {
clearPool();
} }
AABB *AABB::newTemp(double x0, double y0, double z0, double x1, double y1, double z1) AABB *AABB::newTemp(double x0, double y0, double z0, double x1, double y1, double z1)

View file

@ -16,12 +16,11 @@
#include "ParticleTypes.h" #include "ParticleTypes.h"
#include "Random.h" #include "Random.h"
#include "AABB.h" #include "AABB.h"
#include "../Minecraft.World/LevelChunk.h"
const Rotations ArmorStand::DEFAULT_HEAD_POSE (0.0f, 0.0f, 0.0f); const Rotations ArmorStand::DEFAULT_HEAD_POSE (0.0f, 0.0f, 0.0f);
const Rotations ArmorStand::DEFAULT_BODY_POSE (0.0f, 0.0f, 0.0f); const Rotations ArmorStand::DEFAULT_BODY_POSE (0.0f, 0.0f, 0.0f);
const Rotations ArmorStand::DEFAULT_LEFT_ARM_POSE (-15.0f, 0.0f, 10.0f); const Rotations ArmorStand::DEFAULT_LEFT_ARM_POSE (-10.0f, 0.0f, -10.0f);
const Rotations ArmorStand::DEFAULT_RIGHT_ARM_POSE (-10.0f, 0.0f, -10.0f); const Rotations ArmorStand::DEFAULT_RIGHT_ARM_POSE (-15.0f, 0.0f, 10.0f);
const Rotations ArmorStand::DEFAULT_LEFT_LEG_POSE (-1.0f, 0.0f, -1.0f); const Rotations ArmorStand::DEFAULT_LEFT_LEG_POSE (-1.0f, 0.0f, -1.0f);
const Rotations ArmorStand::DEFAULT_RIGHT_LEG_POSE (1.0f, 0.0f, 1.0f); const Rotations ArmorStand::DEFAULT_RIGHT_LEG_POSE (1.0f, 0.0f, 1.0f);
@ -46,10 +45,6 @@ void ArmorStand::init()
for (int i = 0; i < equipmentCount; i++) for (int i = 0; i < equipmentCount; i++)
equipment[i] = nullptr; equipment[i] = nullptr;
rotateElytraX = 0.2617994f;
rotateElytraY = 0.0f;
rotateElytraZ = -0.2617994f;
headPose = DEFAULT_HEAD_POSE; headPose = DEFAULT_HEAD_POSE;
bodyPose = DEFAULT_BODY_POSE; bodyPose = DEFAULT_BODY_POSE;
leftArmPose = DEFAULT_LEFT_ARM_POSE; leftArmPose = DEFAULT_LEFT_ARM_POSE;
@ -88,7 +83,7 @@ void ArmorStand::defineSynchedData()
ArmorStand::~ArmorStand() {} ArmorStand::~ArmorStand() {}
bool ArmorStand::hasPhysics() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_NO_GRAVITY) == 0; }
bool ArmorStand::isBaby() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_SMALL) != 0; } bool ArmorStand::isBaby() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_SMALL) != 0; }
bool ArmorStand::isSmall() const { return isBaby(); } bool ArmorStand::isSmall() const { return isBaby(); }
bool ArmorStand::isShowArms() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_SHOW_ARMS) != 0; } bool ArmorStand::isShowArms() const { return (entityData->getByte(DATA_CLIENT_FLAGS) & FLAG_SHOW_ARMS) != 0; }
@ -193,93 +188,6 @@ void ArmorStand::updateInvisibilityStatus()
setInvisible(invisible); setInvisible(invisible);
} }
void ArmorStand::travel(float xa, float ya)
{
if (hasPhysics()) {
float friction = 0.91f;
int frictionTile = 0;
if (onGround)
{
frictionTile = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z));
friction = 0.6f * 0.91f;
if (frictionTile > 0)
{
friction = Tile::tiles[frictionTile]->friction * 0.91f;
}
}
float friction2 = (0.6f * 0.6f * 0.91f * 0.91f * 0.6f * 0.91f) / (friction * friction * friction);
float speed;
if (onGround)
{
speed = getSpeed() * friction2;
}
else
{
speed = flyingSpeed;
}
moveRelative(xa, ya, speed);
friction = 0.91f;
if (onGround)
{
friction = 0.6f * 0.91f;
if (frictionTile > 0)
{
friction = Tile::tiles[frictionTile]->friction * 0.91f;
}
}
if (onLadder())
{
float max = 0.15f;
if (xd < -max) xd = -max;
if (xd > max) xd = max;
if (zd < -max) zd = -max;
if (zd > max) zd = max;
fallDistance = 0;
if (yd < -0.15) yd = -0.15;
bool playerSneaking = isSneaking() && this->instanceof(eTYPE_PLAYER);
if (playerSneaking && yd < 0) yd = 0;
}
move(xd, yd, zd);
if (horizontalCollision && onLadder())
{
yd = 0.2;
}
if (!level->isClientSide || (level->hasChunkAt(static_cast<int>(x), 0, static_cast<int>(z)) && level->getChunkAt(static_cast<int>(x), static_cast<int>(z))->loaded))
{
yd -= 0.08;
}
else if (y > 0)
{
yd = -0.1;
}
else
{
yd = 0;
}
yd *= 0.98f;
xd *= friction;
zd *= friction;
walkAnimSpeedO = walkAnimSpeed;
double xxd = x - xo;
double zzd = z - zo;
float wst = Mth::sqrt(xxd * xxd + zzd * zzd) * 4;
if (wst > 1) wst = 1;
walkAnimSpeed += (wst - walkAnimSpeed) * 0.4f;
walkAnimPos += walkAnimSpeed;
} else {
move(xd, yd, zd);
}
}
void ArmorStand::tick() void ArmorStand::tick()
{ {
@ -287,14 +195,14 @@ void ArmorStand::tick()
LivingEntity::tick(); LivingEntity::tick();
if (onGround) if (onGround)
{ {
BlockPos pos((int)floorf(x), (int)floorf(y) - 1, (int)floorf(z)); BlockPos pos((int)floorf(x), (int)floorf(y) - 1, (int)floorf(z));
int blockId = level->getTile(pos.getX(), pos.getY(), pos.getZ()); int blockId = level->getTile(pos.getX(), pos.getY(), pos.getZ());
if (blockId == Tile::topSnow->id) if (blockId == Tile::topSnow->id)
{ {
int meta = level->getData(pos.getX(), pos.getY(), pos.getZ()); int meta = level->getData(pos.getX(), pos.getY(), pos.getZ());
float snowHeight = ((meta & 0x7) + 1) * 0.125f; float snowHeight = ((meta & 0x7) + 1) * 0.125f;
moveTo(x, floorf(y) + snowHeight, z, yRot, xRot); moveTo(x, floorf(y) + snowHeight, z, yRot, xRot);
} }
} }
this->yRot = lockedRot; this->yRot = lockedRot;
this->yRotO = lockedRot; this->yRotO = lockedRot;

View file

@ -56,10 +56,6 @@ private:
bool isMarkerFlag; bool isMarkerFlag;
bool noPhysics; bool noPhysics;
float standDamage; float standDamage;
public:
float rotateElytraX;
float rotateElytraY;
float rotateElytraZ;
public: public:
long long lastHit; long long lastHit;
@ -68,7 +64,6 @@ public:
explicit ArmorStand(Level* level); explicit ArmorStand(Level* level);
virtual ~ArmorStand(); virtual ~ArmorStand();
bool hasPhysics() const;
bool isBaby() const; bool isBaby() const;
bool isSmall() const; bool isSmall() const;
bool isShowArms() const; bool isShowArms() const;
@ -147,8 +142,6 @@ public:
void updateBoundingBox(bool markerMode); void updateBoundingBox(bool markerMode);
void updateInvisibilityStatus(); void updateInvisibilityStatus();
virtual void travel(float xz, float ya);
virtual shared_ptr<ItemInstance> getCarriedItem() override; virtual shared_ptr<ItemInstance> getCarriedItem() override;
virtual shared_ptr<ItemInstance> getCarried(int slot) override; virtual shared_ptr<ItemInstance> getCarried(int slot) override;
virtual shared_ptr<ItemInstance> getArmor(int pos) override; virtual shared_ptr<ItemInstance> getArmor(int pos) override;

View file

@ -8,7 +8,7 @@
const BlockPos BlockPos::ZERO = BlockPos(0, 0, 0); const BlockPos BlockPos::ZERO = BlockPos(0, 0, 0);
// Costruttori
BlockPos::BlockPos() : Vec3i(0, 0, 0) {} BlockPos::BlockPos() : Vec3i(0, 0, 0) {}
BlockPos::BlockPos(int x, int y, int z) : Vec3i(x, y, z) {} BlockPos::BlockPos(int x, int y, int z) : Vec3i(x, y, z) {}
@ -49,7 +49,7 @@ BlockPos::BlockPos(int compressed) : Vec3i(0, 0, 0) {
BlockPos::BlockPos(BlockSource& source) BlockPos::BlockPos(BlockSource& source)
: Vec3i(source.getBlockX(), source.getBlockY(), source.getBlockZ()) {} : Vec3i(source.getBlockX(), source.getBlockY(), source.getBlockZ()) {}
// Metodi di confronto
bool BlockPos::equals(const BlockPos& other) const { bool BlockPos::equals(const BlockPos& other) const {
return x == other.x && y == other.y && z == other.z; return x == other.x && y == other.y && z == other.z;
} }
@ -88,7 +88,7 @@ BlockPos BlockPos::relative(int direction, int distance) const {
return BlockPos(x + dx, y, z + dz); return BlockPos(x + dx, y, z + dz);
} }
// directional methods // Metodi direzionali
BlockPos BlockPos::above(int distance) const { BlockPos BlockPos::above(int distance) const {
return BlockPos(x, y + distance, z); return BlockPos(x, y + distance, z);
} }
@ -119,7 +119,7 @@ BlockPos BlockPos::multiply(int factor) const {
return BlockPos(x * factor, y * factor, z * factor); return BlockPos(x * factor, y * factor, z * factor);
} }
// compression // Compressione
int BlockPos::compress() const { int BlockPos::compress() const {
static const int MASK_X = (1 << BITS_X) - 1; static const int MASK_X = (1 << BITS_X) - 1;
static const int MASK_Y = (1 << BITS_Y) - 1; static const int MASK_Y = (1 << BITS_Y) - 1;

View file

@ -148,7 +148,7 @@ void Boat::lerpTo(double x, double y, double z, float yRot, float xRot, int step
{ {
if (doLerp) if (doLerp)
{ {
lSteps = steps +5; lSteps = steps + 5;
} }
else else
{ {
@ -188,10 +188,6 @@ void Boat::lerpMotion(double xd, double yd, double zd)
void Boat::tick() void Boat::tick()
{ {
Entity::tick(); Entity::tick();
if (getHurtTime() > 0) setHurtTime(getHurtTime() - 1); if (getHurtTime() > 0) setHurtTime(getHurtTime() - 1);
if (getDamage() > 0) setDamage(getDamage() - 1); if (getDamage() > 0) setDamage(getDamage() - 1);
xo = x; xo = x;
@ -203,8 +199,8 @@ void Boat::tick()
double waterPercentage = 0; double waterPercentage = 0;
for (int i = 0; i < steps; i++) for (int i = 0; i < steps; i++)
{ {
double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps + 1.5f / 16.0f; double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f;
double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps + 1.5f / 16.0f; double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f;
AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1);
if (level->containsLiquid(bb2, Material::water)) if (level->containsLiquid(bb2, Material::water))
{ {
@ -261,19 +257,18 @@ void Boat::tick()
return; return;
} }
// Bob in water & gravity // Bob in water
if (waterPercentage < 1.0) if (waterPercentage > 0)
{ {
double bob = waterPercentage * 2.0 - 1.0; double bob = waterPercentage * 2 - 1;
yd += 0.04f * bob; yd += 0.04f * bob;
} }
else
// Reimplement gravity again (??)
int tileUnder = level->getTile(Mth::floor(x), Mth::floor(y-0.15), Mth::floor(z));
if (tileUnder == 0 && !onGround)
{ {
if (yd < 0.0) yd -= 0.04f;
{
yd /= 2.0;
}
yd += 0.007f;
} }
// Rider controls // Rider controls
@ -286,16 +281,24 @@ void Boat::tick()
{ {
double riderXd = -sin(livingRider->yRot * PI / 180); double riderXd = -sin(livingRider->yRot * PI / 180);
double riderZd = cos(livingRider->yRot * PI / 180); double riderZd = cos(livingRider->yRot * PI / 180);
double currentSpeed = sqrt(xd * xd + zd * zd); float mult = livingRider->isSprinting() ? 2.0f : 1.0f;
float moveFactor = (float)forward; float moveFactor = (float)forward;
if (forward < 0) moveFactor *= 0.5f; // Move slower backwards if (forward < 0) moveFactor *= 0.5f; // Move slower backwards
xd += riderXd * acceleration * 0.05f * moveFactor; xd += riderXd * acceleration * 0.05f * mult * moveFactor;
zd += riderZd * acceleration * 0.05f * moveFactor; zd += riderZd * acceleration * 0.05f * mult * moveFactor;
} }
} }
double curSpeed = sqrt(xd * xd + zd * zd); double curSpeed = sqrt(xd * xd + zd * zd);
double maxSpeed = MAX_SPEED; double maxSpeed = MAX_SPEED;
if (rider.lock() != nullptr && rider.lock()->instanceof(eTYPE_LIVINGENTITY))
{
shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock());
if (livingRider->isSprinting())
{
maxSpeed *= 1.5;
}
}
if (curSpeed > maxSpeed) if (curSpeed > maxSpeed)
{ {
@ -327,12 +330,10 @@ void Boat::tick()
move(xd, yd, zd); move(xd, yd, zd);
// Break boat on high speed collision // Break boat on high speed collision
float breakThreshold = (rider.lock() != nullptr) ? 0.35f : 0.20f;
if ((horizontalCollision && lastSpeed > 0.20)) if ((horizontalCollision && lastSpeed > 0.20))
{ {
if (!level->isClientSide && !removed) if (!level->isClientSide && !removed)
{ {
remove(); remove();
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
@ -342,9 +343,6 @@ void Boat::tick()
{ {
spawnAtLocation(Item::stick->id, 1, 0); spawnAtLocation(Item::stick->id, 1, 0);
} }
} }
} }
else else
@ -474,19 +472,10 @@ bool Boat::interact(shared_ptr<Player> player)
if ( (rider.lock() != nullptr) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true; if ( (rider.lock() != nullptr) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true;
if (!level->isClientSide) if (!level->isClientSide)
{ {
bool isRiding = (rider.lock() == player);
if (isRiding)
{
player->xd = 0;
player->yd = 0;
player->zd = 0;
}
// 4J HEG - Fixed issue with player not being able to dismount boat (issue #4446) // 4J HEG - Fixed issue with player not being able to dismount boat (issue #4446)
player->ride(isRiding ? nullptr : shared_from_this()); player->ride( rider.lock() == player ? nullptr : shared_from_this() );
} }
return true; return true;
} }
void Boat::setDamage(float damage) void Boat::setDamage(float damage)

View file

@ -7,12 +7,14 @@ class TilePos;
// The maximum number of chunks that we can store // The maximum number of chunks that we can store
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
// 4J Stu - Our default map (at zoom level 3) is 1024x1024 blocks (or 64 chunks) // 4J Stu - Our default map (at zoom level 3) is 1024x1024 blocks (or 64 chunks)
#define LEVEL_MAX_WIDTH (5*64) //(6*54)
#define LEVEL_WIDTH_CLASSIC 54 #define LEVEL_WIDTH_CLASSIC 54
#define LEVEL_WIDTH_SMALL 64 #define LEVEL_WIDTH_SMALL 64
#define LEVEL_WIDTH_MEDIUM (3*64) #define LEVEL_WIDTH_MEDIUM (3*64)
#define LEVEL_WIDTH_LARGE (5*64) #define LEVEL_WIDTH_LARGE (5*64)
#define LEVEL_WIDTH_EXPANDED (5*64) + 24
#define LEVEL_MAX_WIDTH LEVEL_WIDTH_EXPANDED
#else #else
#define LEVEL_MAX_WIDTH 54 #define LEVEL_MAX_WIDTH 54

View file

@ -38,8 +38,6 @@ void ClothDyeRecipes::addRecipes(Recipes *r)
} }
// some dye recipes // some dye recipes
//flowers
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW), r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW),
L"tg", L"tg",
Tile::flower,L'D'); Tile::flower,L'D');
@ -48,44 +46,6 @@ void ClothDyeRecipes::addRecipes(Recipes *r)
L"tg", L"tg",
Tile::rose,L'D'); Tile::rose,L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::LIGHT_BLUE),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::BLUE_ORCHID), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::MAGENTA),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::ALLIUM), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::AZURE_BLUET), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::RED_TULIP), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::PINK_TULIP), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::WHITE_TULIP), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::ORANGE),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::ORANGE_TULIP), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER),
L"zg", new ItemInstance(Item::items[Tile::rose_Id], 1, Rose::OXEYE_DAISY), L'D');
// Tall flowers
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::YELLOW),
L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::SUNFLOWER), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA),
L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::LILAC), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::RED),
L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::ROSE_BUSH), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA),
L"zg", new ItemInstance(Item::items[Tile::tallgrass2_Id], 1, TallGrass2::PEONY), L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 3, DyePowderItem::WHITE), r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 3, DyePowderItem::WHITE),
L"ig", L"ig",
Item::bone,L'D'); Item::bone,L'D');
@ -154,9 +114,6 @@ void ClothDyeRecipes::addRecipes(Recipes *r)
new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED),
new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D'); new ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE),L'D');
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
r->addShapedRecipy(new ItemInstance(Tile::woolCarpet, 3, i), r->addShapedRecipy(new ItemInstance(Tile::woolCarpet, 3, i),

View file

@ -1170,13 +1170,7 @@ bool EnderDragon::hurt(shared_ptr<MultiEntityMobPart> MultiEntityMobPart, Damage
bool EnderDragon::hurt(DamageSource *source, float damage) bool EnderDragon::hurt(DamageSource *source, float damage)
{ {
if (source == DamageSource::outOfWorld) return false;
{
setSynchedAction(e_EnderdragonAction_Sitting_Scanning, true);
reallyHurt(source, getMaxHealth() + 1);
return true;
}
return false;
} }
bool EnderDragon::reallyHurt(DamageSource *source, float damage) bool EnderDragon::reallyHurt(DamageSource *source, float damage)

View file

@ -1,118 +0,0 @@
#include "stdafx.h"
#include "EntityTypeMap.h"
static const unordered_map<wstring, eINSTANCEOF> s_nameToType = {
// animals
{ L"pig", eTYPE_PIG },
{ L"cow", eTYPE_COW },
{ L"sheep", eTYPE_SHEEP },
{ L"chicken", eTYPE_CHICKEN },
{ L"horse", eTYPE_HORSE },
{ L"wolf", eTYPE_WOLF },
{ L"ocelot", eTYPE_OCELOT },
{ L"rabbit", eTYPE_RABBIT },
{ L"mooshroom", eTYPE_MUSHROOMCOW },
{ L"squid", eTYPE_SQUID },
{ L"bat", eTYPE_BAT },
// neutral/passive
{ L"villager", eTYPE_VILLAGER },
{ L"snowgolem", eTYPE_SNOWMAN },
{ L"irongolem", eTYPE_VILLAGERGOLEM },
// monsters
{ L"zombie", eTYPE_ZOMBIE },
{ L"skeleton", eTYPE_SKELETON },
{ L"creeper", eTYPE_CREEPER },
{ L"spider", eTYPE_SPIDER },
{ L"cavespider", eTYPE_CAVESPIDER },
{ L"enderman", eTYPE_ENDERMAN },
{ L"silverfish", eTYPE_SILVERFISH },
{ L"blaze", eTYPE_BLAZE },
{ L"witch", eTYPE_WITCH },
{ L"ghast", eTYPE_GHAST },
{ L"slime", eTYPE_SLIME },
{ L"magmacube", eTYPE_LAVASLIME },
{ L"zombie_pigman", eTYPE_PIGZOMBIE },
{ L"witherboss", eTYPE_WITHERBOSS },
{ L"enderdragon", eTYPE_ENDERDRAGON },
{ L"giant", eTYPE_GIANT },
{ L"endermite", eTYPE_ENDERMITE },
{ L"guardian", eTYPE_GUARDIAN },
{ L"elder_guardian", eTYPE_ELDER_GUARDIAN },
// minecart
{ L"minecart", eTYPE_MINECART },
{ L"minecart_chest", eTYPE_MINECART_CHEST },
{ L"minecart_hopper", eTYPE_MINECART_HOPPER },
{ L"minecart_tnt", eTYPE_MINECART_TNT },
{ L"minecart_furnace", eTYPE_MINECART_FURNACE },
{ L"minecart_spawner", eTYPE_MINECART_SPAWNER },
// projectiles
{ L"arrow", eTYPE_ARROW },
{ L"snowball", eTYPE_SNOWBALL },
{ L"egg", eTYPE_THROWNEGG },
{ L"enderpearl", eTYPE_THROWNENDERPEARL },
{ L"potion", eTYPE_THROWNPOTION },
{ L"expbottle", eTYPE_THROWNEXPBOTTLE },
{ L"large_fireball", eTYPE_LARGE_FIREBALL },
{ L"small_fireball", eTYPE_SMALL_FIREBALL },
{ L"wither_skull", eTYPE_WITHER_SKULL },
{ L"dragon_fireball", eTYPE_DRAGON_FIREBALL },
{ L"fireworks_rocket", eTYPE_FIREWORKS_ROCKET },
{ L"eyeofender", eTYPE_EYEOFENDERSIGNAL },
// hanging
{ L"painting", eTYPE_PAINTING },
{ L"item_frame", eTYPE_ITEM_FRAME },
{ L"leash_knot", eTYPE_LEASHFENCEKNOT },
// others
{ L"item", eTYPE_ITEMENTITY },
{ L"xp_orb", eTYPE_EXPERIENCEORB },
{ L"boat", eTYPE_BOAT },
{ L"tnt", eTYPE_PRIMEDTNT },
{ L"falling_block", eTYPE_FALLINGTILE },
{ L"armor_stand", eTYPE_ARMORSTAND },
{ L"ender_crystal", eTYPE_ENDER_CRYSTAL },
{ L"lightning_bolt", eTYPE_LIGHTNINGBOLT },
};
static const unordered_map<eINSTANCEOF, wstring> s_typeToName = []()
{
unordered_map<eINSTANCEOF, wstring> m;
for (auto& pair : s_nameToType)
{
if (m.find(pair.second) == m.end())
m[pair.second] = pair.first;
}
return m;
}();
const unordered_map<wstring, eINSTANCEOF>& EntityTypeMap::getNameToTypeMap()
{
return s_nameToType;
}
const unordered_map<eINSTANCEOF, wstring>& EntityTypeMap::getTypeToNameMap()
{
return s_typeToName;
}
eINSTANCEOF EntityTypeMap::getTypeFromName(const wstring& name)
{
wstring lower = name;
transform(lower.begin(), lower.end(), lower.begin(), towlower);
auto it = s_nameToType.find(lower);
if (it != s_nameToType.end())
return it->second;
return eTYPE_NOTSET;
}
wstring EntityTypeMap::getNameFromType(eINSTANCEOF type)
{
auto it = s_typeToName.find(type);
if (it != s_typeToName.end())
return it->second;
return L"";
}
bool EntityTypeMap::isValidType(const wstring& name)
{
return getTypeFromName(name) != eTYPE_NOTSET;
}

View file

@ -1,21 +0,0 @@
#pragma once
#include "../Minecraft.World/Class.h"
#include <unordered_map>
#include <string>
using namespace std;
class EntityTypeMap
{
public:
static eINSTANCEOF getTypeFromName(const wstring& name);
static wstring getNameFromType(eINSTANCEOF type);
static bool isValidType(const wstring& name);
private:
static const unordered_map<wstring, eINSTANCEOF>& getNameToTypeMap();
static const unordered_map<eINSTANCEOF, wstring>& getTypeToNameMap();
};

View file

@ -121,14 +121,8 @@ void GrassTile::tick(Level *level, int x, int y, int z, Random *random)
} }
} }
// using isSolid() here is wrong because non full blocks like iron bars,
// fences, walls are also flagged as solid by their material
int aboveTileId = level->getTile(x, y + 1, z);
Material* above = level->getMaterial(x, y + 1, z); Material* above = level->getMaterial(x, y + 1, z);
if (above->isLiquid() || Tile::lightBlock[aboveTileId] > 2) if (above->isSolid() || above->isLiquid()) level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
{
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
}
} }
int GrassTile::getResource(int data, Random *random, int playerBonusLevel) int GrassTile::getResource(int data, Random *random, int playerBonusLevel)

View file

@ -1,197 +1,26 @@
#include "stdafx.h" #include "stdafx.h"
#include "net.minecraft.commands.h" #include "net.minecraft.commands.h"
#include "net.minecraft.world.entity.player.h" #include "net.minecraft.world.entity.player.h"
#include "net.minecraft.world.damagesource.h" #include "net.minecraft.world.damagesource.h"
#include "net.minecraft.world.level.h"
#include "BasicTypeContainers.h" #include "BasicTypeContainers.h"
#include "KillCommand.h" #include "KillCommand.h"
#include "EntityTypeMap.h"
static void killEntity(shared_ptr<Entity> entity)
{
if (entity->instanceof(eTYPE_LIVINGENTITY))
{
auto living = dynamic_pointer_cast<LivingEntity>(entity);
if (living != nullptr)
{
living->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
return;
}
entity->remove();
return;
}
entity->remove();
}
EGameCommand KillCommand::getId() EGameCommand KillCommand::getId()
{ {
return eGameCommand_Kill; return eGameCommand_Kill;
} }
int KillCommand::getPermissionLevel() int KillCommand::getPermissionLevel()
{ {
return LEVEL_ALL; return LEVEL_ALL;
} }
void KillCommand::execute(shared_ptr<CommandSender> source, byteArray commandData) void KillCommand::execute(shared_ptr<CommandSender> source, byteArray commandData)
{ {
shared_ptr<Player> senderPlayer = dynamic_pointer_cast<Player>(source); shared_ptr<Player> player = dynamic_pointer_cast<Player>(source);
if (senderPlayer == nullptr)
return;
Level *level = senderPlayer->level; player->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
if (level == nullptr)
return;
source->sendMessage(L"Ouch. That look like it hurt.");
//nothing is the same of @s //source.sendMessage(ChatMessageComponent.forTranslation("commands.kill.success"));
if (commandData.length == 0 || commandData.data == nullptr)
{
senderPlayer->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
return;
}
ByteArrayInputStream bais(commandData);
DataInputStream dis(&bais);
wstring targetName = dis.readUTF();
wstring targetLower = targetName;
transform(targetLower.begin(), targetLower.end(), targetLower.begin(), towlower);
//@s
if (targetLower == L"@s")
{
senderPlayer->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
return;
}
//@a
if (targetLower == L"@a")
{
vector<shared_ptr<Player>> toKill;
for (auto& p : level->players)
if (p != nullptr && !p->removed)
toKill.push_back(p);
for (auto& p : toKill)
p->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
return;
}
//@p
if (targetLower == L"@p")
{
shared_ptr<Player> nearest = level->getNearestPlayer(
dynamic_pointer_cast<Entity>(senderPlayer), 9999.0);
if (nearest != nullptr)
{
nearest->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
source->sendMessage(L"Killed " + nearest->getName() + L".");
}
else
{
source->sendMessage(L"No player found.");
}
return;
}
//@r
if (targetLower == L"@r")
{
if (level->players.empty())
{
source->sendMessage(L"No player found.");
return;
}
int idx = rand() % (int)level->players.size();
auto& p = level->players[idx];
if (p != nullptr && !p->removed)
{
p->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
source->sendMessage(L"Killed " + p->getName() + L".");
}
return;
}
// @e
if (targetLower.size() >= 2 && targetLower.substr(0, 2) == L"@e")
{
eINSTANCEOF filterType = eTYPE_NOTSET;
bool invertFilter = false;
bool filterIsPlayer = false;
if (targetLower.size() > 3 && targetLower[2] == L'[')
{
wstring inner = targetLower.substr(3, targetLower.size() - 4);
wstring key = L"type=";
size_t pos = inner.find(key);
if (pos == wstring::npos)
{
source->sendMessage(L"Invalid selector syntax. Usage: @e[type=<entity_type>]");
return;
}
wstring typeStr = inner.substr(pos + key.size());
if (!typeStr.empty() && typeStr[0] == L'!')
{
invertFilter = true;
typeStr = typeStr.substr(1);
}
if (typeStr == L"player")
{
filterIsPlayer = true;
}
else
{
filterType = EntityTypeMap::getTypeFromName(typeStr);
if (filterType == eTYPE_NOTSET)
{
source->sendMessage(L"Unknown entity type: " + typeStr);
return;
}
}
}
vector<shared_ptr<Entity>> toKill;
for (auto& entity : level->entities)
{
if (entity == nullptr || entity->removed) continue;
bool isPlayer = entity->instanceof(eTYPE_PLAYER);
bool matchesFilter;
if (filterType == eTYPE_NOTSET && !filterIsPlayer)
matchesFilter = true;
else if (filterIsPlayer)
matchesFilter = isPlayer;
else
matchesFilter = entity->instanceof(filterType);
if (invertFilter) matchesFilter = !matchesFilter;
if (matchesFilter)
toKill.push_back(entity);
}
for (auto& entity : toKill)
if (!entity->removed)
killEntity(entity);
source->sendMessage(L"Killed " + to_wstring(toKill.size()) + L" entities.");
return;
}
// by player name
shared_ptr<Player> targetPlayer = level->getPlayerByName(targetName);
if (targetPlayer != nullptr)
{
targetPlayer->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
source->sendMessage(L"Killed " + targetName + L".");
return;
}
source->sendMessage(L"No entity was found.");
} }

View file

@ -46,6 +46,7 @@ DWORD Level::tlsIdxLightCache = TlsAlloc();
// 4J : WESTY : Added for time played stats. // 4J : WESTY : Added for time played stats.
#include "net.minecraft.stats.h" #include "net.minecraft.stats.h"
#include "../Minecraft.Client/MultiPlayerChunkCache.h"
// 4J - Caching of lighting data added. This is implemented as a 16x16x16 cache of ints (ie 16K storage in total). The index of the element to be used in the array is determined by the lower // 4J - Caching of lighting data added. This is implemented as a 16x16x16 cache of ints (ie 16K storage in total). The index of the element to be used in the array is determined by the lower
// four bits of each x/y/z position, and the upper 7/4/7 bits of the x/y/z positions are stored within the element itself along with the cached values etc. The cache can be enabled per thread by // four bits of each x/y/z position, and the upper 7/4/7 bits of the x/y/z positions are stored within the element itself along with the cached values etc. The cache can be enabled per thread by
@ -1335,7 +1336,7 @@ int Level::getBrightness(LightLayer::variety layer, int x, int y, int z)
int idx = ix * chunkSourceXZSize + iz; int idx = ix * chunkSourceXZSize + iz;
LevelChunk *c = chunkSourceCache[idx]; LevelChunk *c = chunkSourceCache[idx];
if( c == nullptr ) return (int)layer; if( c == nullptr) return (int)layer;
if (y < 0) y = 0; if (y < 0) y = 0;
if (y >= maxBuildHeight) y = maxBuildHeight - 1; if (y >= maxBuildHeight) y = maxBuildHeight - 1;

View file

@ -185,6 +185,7 @@ LevelData::LevelData(CompoundTag *tag)
case LEVEL_WIDTH_SMALL: hostOptionworldSize = e_worldSize_Small; break; case LEVEL_WIDTH_SMALL: hostOptionworldSize = e_worldSize_Small; break;
case LEVEL_WIDTH_MEDIUM: hostOptionworldSize = e_worldSize_Medium; break; case LEVEL_WIDTH_MEDIUM: hostOptionworldSize = e_worldSize_Medium; break;
case LEVEL_WIDTH_LARGE: hostOptionworldSize = e_worldSize_Large; break; case LEVEL_WIDTH_LARGE: hostOptionworldSize = e_worldSize_Large; break;
case LEVEL_WIDTH_EXPANDED: hostOptionworldSize = e_worldSize_Expanded; break;
default: assert(0); break; default: assert(0); break;
} }
app.SetGameHostOption(eGameHostOption_WorldSize, hostOptionworldSize ); app.SetGameHostOption(eGameHostOption_WorldSize, hostOptionworldSize );

View file

@ -1,110 +1,127 @@
#include "stdafx.h" 
#include "stdafx.h"
#include "PacketListener.h" #include "PacketListener.h"
#include "LevelParticlesPacket.h" #include "LevelParticlesPacket.h"
#include "../Minecraft.Client/ParticleType.h"
LevelParticlesPacket::LevelParticlesPacket() LevelParticlesPacket::LevelParticlesPacket()
{ {
this->name = L"";
this->x = 0.0f; this->overrideLimiter = false;
this->y = 0.0f; this->type = nullptr;
this->z = 0.0f; this->count = 0;
this->xDist = 0.0f; this->y = 0.0f;
this->yDist = 0.0f; this->paramCount = 0;
this->zDist = 0.0f; this->x = 0.0f;
this->maxSpeed = 0.0f; this->yDist = 0.0f;
this->count = 0; 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->type = type;
this->x = x; this->overrideLimiter = overrideLimiter;
this->y = y; this->x = x;
this->z = z; this->y = y;
this->xDist = xDist; this->z = z;
this->yDist = yDist; this->xDist = xDist;
this->zDist = zDist; this->yDist = yDist;
this->maxSpeed = maxSpeed; this->zDist = zDist;
this->count = count; 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;
}
}
LevelParticlesPacket::~LevelParticlesPacket()
{
if (params)
{
delete[] params;
params = nullptr;
}
} }
void LevelParticlesPacket::read(DataInputStream* dis) void LevelParticlesPacket::read(DataInputStream* dis)
{ {
name = readUtf(dis, 64); int particleId = dis->readInt();
x = dis->readFloat(); const ParticleType* resolved = ParticleType::byId(particleId);
y = dis->readFloat(); if (!resolved)
z = dis->readFloat(); resolved = ParticleType::getDefault();
xDist = dis->readFloat(); this->type = resolved;
yDist = dis->readFloat();
zDist = dis->readFloat(); this->overrideLimiter = dis->readBoolean();
maxSpeed = dis->readFloat();
count = dis->readInt(); 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;
}
} }
void LevelParticlesPacket::write(DataOutputStream* dos) void LevelParticlesPacket::write(DataOutputStream* dos)
{ {
writeUtf(name, dos); dos->writeInt(this->type ? this->type->getId() : 0);
dos->writeFloat(x); dos->writeBoolean(this->overrideLimiter);
dos->writeFloat(y); dos->writeFloat(this->x);
dos->writeFloat(z); dos->writeFloat(this->y);
dos->writeFloat(xDist); dos->writeFloat(this->z);
dos->writeFloat(yDist); dos->writeFloat(this->xDist);
dos->writeFloat(zDist); dos->writeFloat(this->yDist);
dos->writeFloat(maxSpeed); dos->writeFloat(this->zDist);
dos->writeInt(count); dos->writeFloat(this->maxSpeed);
} dos->writeInt(this->count);
wstring LevelParticlesPacket::getName() int toWrite = this->type ? this->type->getParamCount() : 0;
{ for (int i = 0; i < toWrite; i++)
return name; {
} dos->writeInt(this->params[i]);
}
double LevelParticlesPacket::getX()
{
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) void LevelParticlesPacket::handle(PacketListener* listener)
{ {
listener->handleParticleEvent(shared_from_this()); listener->handleParticleEvent(shared_from_this());
} }
int LevelParticlesPacket::getEstimatedSize() int LevelParticlesPacket::getEstimatedSize()
{ {
return 4 * 2 + 7 * 8; return 0x40;
} }

View file

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

@ -51,10 +51,9 @@ public:
static const int DATA_ARROW_COUNT_ID = 9; static const int DATA_ARROW_COUNT_ID = 9;
private: private:
BaseAttributeMap* attributes;
CombatTracker* combatTracker; CombatTracker* combatTracker;
unordered_map<int, MobEffectInstance*> activeEffects; unordered_map<int, MobEffectInstance*> activeEffects;
protected:
BaseAttributeMap* attributes;
ItemInstanceArray lastEquipment; ItemInstanceArray lastEquipment;
public: public:

View file

@ -63,18 +63,18 @@ void MobCategory::setMaxInstancesPerLevel(int max)
m_maxPerLevel = max; m_maxPerLevel = max;
} }
int MobCategory::maxAnimalsWithBreeding() { return (creature->getMaxInstancesPerLevel() + 20)*2; } int MobCategory::maxAnimalsWithBreeding() { return creature->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxChickensWithBreeding() { return (creature_chicken->getMaxInstancesPerLevel() + 8)*2; } int MobCategory::maxChickensWithBreeding() { return creature_chicken->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxMushroomCowsWithBreeding() { return (creature_mushroomcow->getMaxInstancesPerLevel() + 20)*2; } int MobCategory::maxMushroomCowsWithBreeding() { return creature_mushroomcow->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxWolvesWithBreeding() { return (creature_wolf->getMaxInstancesPerLevel() + 8)*2; } int MobCategory::maxWolvesWithBreeding() { return creature_wolf->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAnimalsWithSpawnEgg() { return (maxAnimalsWithBreeding() + 20)*2; } int MobCategory::maxAnimalsWithSpawnEgg() { return maxAnimalsWithBreeding() + 20; }
int MobCategory::maxChickensWithSpawnEgg() { return (maxChickensWithBreeding() + 10)*2; } int MobCategory::maxChickensWithSpawnEgg() { return maxChickensWithBreeding() + 10; }
int MobCategory::maxWolvesWithSpawnEgg() { return (maxWolvesWithBreeding() + 10)*2; } int MobCategory::maxWolvesWithSpawnEgg() { return maxWolvesWithBreeding() + 10; }
int MobCategory::maxMonstersWithSpawnEgg() { return (monster->getMaxInstancesPerLevel() + 20)*2; } int MobCategory::maxMonstersWithSpawnEgg() { return monster->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxMushroomCowsWithSpawnEgg() { return (maxMushroomCowsWithBreeding() + 8)*2; } int MobCategory::maxMushroomCowsWithSpawnEgg() { return maxMushroomCowsWithBreeding() + 8; }
int MobCategory::maxSquidsWithSpawnEgg() { return (waterCreature->getMaxInstancesPerLevel() + 8)*2; } int MobCategory::maxSquidsWithSpawnEgg() { return waterCreature->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAmbientWithSpawnEgg() { return (ambient->getMaxInstancesPerLevel() + 8)*2; } int MobCategory::maxAmbientWithSpawnEgg() { return ambient->getMaxInstancesPerLevel() + 8; }
Material *MobCategory::getSpawnPositionMaterial() Material *MobCategory::getSpawnPositionMaterial()
{ {

View file

@ -7,9 +7,9 @@ class MobCategory
{ {
public: public:
// 4J - putting constants for xbox spawning in one place to tidy things up a bit - all numbers are per level // 4J - putting constants for xbox spawning in one place to tidy things up a bit - all numbers are per level
static const int CONSOLE_MONSTERS_HARD_LIMIT = 100; // Max number of enemies (skeleton, zombie, creeper etc) that the mob spawner will produce static const int CONSOLE_MONSTERS_HARD_LIMIT = 50; // Max number of enemies (skeleton, zombie, creeper etc) that the mob spawner will produce
static const int CONSOLE_ANIMALS_HARD_LIMIT = 100; // Max number of animals (cows, sheep, pigs) that the mob spawner will produce static const int CONSOLE_ANIMALS_HARD_LIMIT = 50; // Max number of animals (cows, sheep, pigs) that the mob spawner will produce
static const int CONSOLE_AMBIENT_HARD_LIMIT = 40; // Ambient mobs static const int CONSOLE_AMBIENT_HARD_LIMIT = 20; // Ambient mobs
static const int MAX_XBOX_CHICKENS = 8; // Max number of chickens that the mob spawner will produce static const int MAX_XBOX_CHICKENS = 8; // Max number of chickens that the mob spawner will produce
static const int MAX_XBOX_WOLVES = 8; // Max number of wolves that the mob spawner will produce static const int MAX_XBOX_WOLVES = 8; // Max number of wolves that the mob spawner will produce
@ -20,7 +20,7 @@ public:
static const int MAX_CONSOLE_BOSS = 1; // Max number of bosses (enderdragon/wither) static const int MAX_CONSOLE_BOSS = 1; // Max number of bosses (enderdragon/wither)
// 4J Villager breeding/egg limits - villagers are not a MobCategory so these stay hardcoded // 4J Villager breeding/egg limits - villagers are not a MobCategory so these stay hardcoded
static const int MAX_VILLAGERS_WITH_BREEDING = 70; static const int MAX_VILLAGERS_WITH_BREEDING = 35;
static const int MAX_XBOX_VILLAGERS_WITH_SPAWN_EGG = MAX_VILLAGERS_WITH_BREEDING + 15; static const int MAX_XBOX_VILLAGERS_WITH_SPAWN_EGG = MAX_VILLAGERS_WITH_BREEDING + 15;
// Breeding headroom above the natural spawn cap. Read at call time so these // Breeding headroom above the natural spawn cap. Read at call time so these

View file

@ -35,16 +35,13 @@ Ocelot::Ocelot(Level *level) : TamableAnimal(level)
registerAttributes(); registerAttributes();
setHealth(getMaxHealth()); setHealth(getMaxHealth());
avoidPlayerGoal = nullptr;
reassessTameGoals();
setSize(0.6f, 0.8f); setSize(0.6f, 0.8f);
getNavigation()->setAvoidWater(true); getNavigation()->setAvoidWater(true);
goalSelector.addGoal(1, new FloatGoal(this)); goalSelector.addGoal(1, new FloatGoal(this));
goalSelector.addGoal(2, sitGoal, false); goalSelector.addGoal(2, sitGoal, false);
goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED_MOD, Item::fish_raw_Id, true), false); goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED_MOD, Item::fish_raw_Id, true), false);
goalSelector.addGoal(4, new AvoidPlayerGoal(this, typeid(Player), 16, WALK_SPEED_MOD, SPRINT_SPEED_MOD));
goalSelector.addGoal(5, new FollowOwnerGoal(this, FOLLOW_SPEED_MOD, 10, 5)); goalSelector.addGoal(5, new FollowOwnerGoal(this, FOLLOW_SPEED_MOD, 10, 5));
goalSelector.addGoal(6, new OcelotSitOnTileGoal(this, SPRINT_SPEED_MOD)); goalSelector.addGoal(6, new OcelotSitOnTileGoal(this, SPRINT_SPEED_MOD));
goalSelector.addGoal(7, new LeapAtTargetGoal(this, 0.3f)); goalSelector.addGoal(7, new LeapAtTargetGoal(this, 0.3f));
@ -63,21 +60,6 @@ void Ocelot::defineSynchedData()
entityData->define(DATA_TYPE_ID, static_cast<byte>(0)); entityData->define(DATA_TYPE_ID, static_cast<byte>(0));
} }
void Ocelot::reassessTameGoals()
{
if (!avoidPlayerGoal)
avoidPlayerGoal = new AvoidPlayerGoal(this, typeid(Player), 16, WALK_SPEED_MOD, SPRINT_SPEED_MOD);
goalSelector.removeGoal(avoidPlayerGoal);
if (!isTame())
goalSelector.addGoal(4, avoidPlayerGoal, false);
}
void Ocelot::setTame(bool tame)
{
TamableAnimal::setTame(tame);
}
void Ocelot::serverAiMobStep() void Ocelot::serverAiMobStep()
{ {
if (getMoveControl()->hasWanted()) if (getMoveControl()->hasWanted())
@ -217,10 +199,7 @@ bool Ocelot::mobInteract(shared_ptr<Player> player)
} }
else else
{ {
//player must be close holding raw fish if (temptGoal->isRunning() && item != nullptr && item->id == Item::fish_raw_Id && player->distanceToSqr(shared_from_this()) < 3 * 3)
// temptGoal->isRunning() check removed
// when the player enters interaction range, which would block taming entirely
if (item != nullptr && item->id == Item::fish_raw_Id && player->distanceToSqr(shared_from_this()) < 3 * 3)
{ {
// 4J-PB - don't lose the fish in creative mode // 4J-PB - don't lose the fish in creative mode
if (!player->abilities.instabuild) item->count--; if (!player->abilities.instabuild) item->count--;
@ -305,8 +284,6 @@ void Ocelot::setCatType(int type)
bool Ocelot::canSpawn() bool Ocelot::canSpawn()
{ {
//return level->random->nextInt(3) != 0; when checkSpawnObstruction is implemented
// artificially make ozelots more rare // artificially make ozelots more rare
if (level->random->nextInt(3) == 0) if (level->random->nextInt(3) == 0)
{ {

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "TamableAnimal.h" #include "TamableAnimal.h"
#include "AvoidPlayerGoal.h"
class TemptGoal; class TemptGoal;
@ -33,7 +32,6 @@ public:
private: private:
TemptGoal *temptGoal; TemptGoal *temptGoal;
AvoidPlayerGoal *avoidPlayerGoal;
public: public:
Ocelot(Level *level); Ocelot(Level *level);
@ -43,8 +41,6 @@ protected:
public: public:
virtual void serverAiMobStep(); virtual void serverAiMobStep();
virtual void reassessTameGoals();
virtual void setTame(bool tame);
protected: protected:
virtual bool removeWhenFarAway(); virtual bool removeWhenFarAway();
@ -82,7 +78,6 @@ public:
virtual int getCatType(); virtual int getCatType();
virtual void setCatType(int type); virtual void setCatType(int type);
virtual bool canSpawn(); virtual bool canSpawn();
//virtual bool checkSpawnObstruction(); TODO when blockstates will be merged.
virtual wstring getAName(); virtual wstring getAName();
virtual MobGroupData *finalizeMobSpawn(MobGroupData *groupData, int extraData = 0); // 4J Added extraData param virtual MobGroupData *finalizeMobSpawn(MobGroupData *groupData, int extraData = 0); // 4J Added extraData param

View file

@ -49,16 +49,10 @@ Vec3 *Vec3::newPermanent(double x, double y, double z)
void Vec3::clearPool() void Vec3::clearPool()
{ {
ThreadStorage *tls = static_cast<ThreadStorage *>(TlsGetValue(tlsIdx));
if (tls != nullptr)
{
tls->poolPointer = 0;
}
} }
void Vec3::resetPool() void Vec3::resetPool()
{ {
clearPool();
} }
Vec3 *Vec3::newTemp(double x, double y, double z) Vec3 *Vec3::newTemp(double x, double y, double z)

View file

@ -204,8 +204,6 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_COMMANDS_COMMON
"${CMAKE_CURRENT_SOURCE_DIR}/ToggleDownfallCommand.h" "${CMAKE_CURRENT_SOURCE_DIR}/ToggleDownfallCommand.h"
"${CMAKE_CURRENT_SOURCE_DIR}/WeatherCommand.h" "${CMAKE_CURRENT_SOURCE_DIR}/WeatherCommand.h"
"${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.commands.common.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.commands.common.h"
"${CMAKE_CURRENT_SOURCE_DIR}/EntityTypeMap.h"
"${CMAKE_CURRENT_SOURCE_DIR}/EntityTypeMap.cpp"
) )
source_group("net/minecraft/commands/common" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_COMMANDS_COMMON}) source_group("net/minecraft/commands/common" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_COMMANDS_COMMON})

View file

@ -1,18 +1,7 @@
# neoLegacy v1.0.8b # neoLegacy v1.0.5b
### Bug Fixes ### Bug Fixes
- Game has been heavily optimized; expect more FPS. - Fixed crashing, lagging, and lighting issues caused by expanded world generation.
- Fullscreen option is now correctly applied on startup.
- `/kill` now kills the player in creative.
- Boat now follows the player correctly when speeding.
- Ocelots can now be tamed.
- Elytras and items are now rendered correctly when on an armor stand.
### Changes
- Added new logo (made by rdust).
- Added TU31 parity changes which include:
- Dye recipes using flowers.
- Prismarine block animation.
<img width="784" height="410" alt="roadmap" src="https://github.com/user-attachments/assets/134856ae-b151-4003-aa97-7ecf19ccd278" /> <img width="784" height="410" alt="roadmap" src="https://github.com/user-attachments/assets/134856ae-b151-4003-aa97-7ecf19ccd278" />

View file

@ -23,7 +23,6 @@ Huge thanks to the following projects:
- [Patoke/LCERenewed](https://github.com/Patoke/LCERenewed) - for some of the patches that required deep decompilation - [Patoke/LCERenewed](https://github.com/Patoke/LCERenewed) - for some of the patches that required deep decompilation
- [itsRevela/LCE-Revelations](https://git.revela.dev/itsRevela/LCE-Revelations) - for providing a stable project for neoLegacy to continue with - [itsRevela/LCE-Revelations](https://git.revela.dev/itsRevela/LCE-Revelations) - for providing a stable project for neoLegacy to continue with
- [GabsPuNs/Project-Zenith](https://github.com/GabsPuNs/Project-Zenith-Main) - for providing us with their implemention of the Classic Crafting Feature. - [GabsPuNs/Project-Zenith](https://github.com/GabsPuNs/Project-Zenith-Main) - for providing us with their implemention of the Classic Crafting Feature.
- rdust_dusted (Discord) - for providing us with a redesigned logo that we currently use.
# Build & Run # Build & Run