Update to NeoLegacy Latest

This commit is contained in:
2026-05-28 01:23:47 -04:00
parent f4390d5f0b
commit 10f9576b72
201 changed files with 12535 additions and 25235 deletions
+6
View File
@@ -54,10 +54,16 @@ AABB *AABB::newPermanent(double x0, double y0, double z0, double x1, double y1,
void AABB::clearPool()
{
ThreadStorage *tls = static_cast<ThreadStorage *>(TlsGetValue(tlsIdx));
if (tls != nullptr)
{
tls->poolPointer = 0;
}
}
void AABB::resetPool()
{
clearPool();
}
AABB *AABB::newTemp(double x0, double y0, double z0, double x1, double y1, double z1)
+3 -3
View File
@@ -54,7 +54,7 @@ AddEntityPacket::AddEntityPacket(shared_ptr<Entity> e, int type, int data, int y
void AddEntityPacket::read(DataInputStream *dis) // throws IOException TODO 4J JEV add throws statement
{
id = dis->readShort();
id = dis->readInt();
type = dis->readByte();
#ifdef _LARGE_WORLDS
x = dis->readInt();
@@ -78,7 +78,7 @@ void AddEntityPacket::read(DataInputStream *dis) // throws IOException TODO 4J
void AddEntityPacket::write(DataOutputStream *dos) // throws IOException TODO 4J JEV add throws statement
{
dos->writeShort(id);
dos->writeInt(id);
dos->writeByte(type);
#ifdef _LARGE_WORLDS
dos->writeInt(x);
@@ -107,5 +107,5 @@ void AddEntityPacket::handle(PacketListener *listener)
int AddEntityPacket::getEstimatedSize()
{
return 11 + data > -1 ? 6 : 0;
return (11 + data > -1 ? 6 : 0) + 2;
}
+3 -3
View File
@@ -66,7 +66,7 @@ AddMobPacket::AddMobPacket(shared_ptr<LivingEntity> mob, int yRotp, int xRotp, i
void AddMobPacket::read(DataInputStream *dis) //throws IOException
{
id = dis->readShort();
id = dis->readInt();
type = dis->readByte() & 0xff;
#ifdef _LARGE_WORLDS
x = dis->readInt();
@@ -90,7 +90,7 @@ void AddMobPacket::read(DataInputStream *dis) //throws IOException
void AddMobPacket::write(DataOutputStream *dos) //throws IOException
{
dos->writeShort(id);
dos->writeInt(id);
dos->writeByte(type & 0xff);
#ifdef _LARGE_WORLDS
dos->writeInt(x);
@@ -127,7 +127,7 @@ int AddMobPacket::getEstimatedSize()
// 4J Stu - This is an incoming value which we aren't currently analysing
//size += unpack->get
}
return size;
return size + 2;
}
vector<shared_ptr<SynchedEntityData::DataItem> > *AddMobPacket::getUnpackedData()
+4 -4
View File
@@ -8,7 +8,7 @@
const BlockPos BlockPos::ZERO = BlockPos(0, 0, 0);
// Costruttori
BlockPos::BlockPos() : Vec3i(0, 0, 0) {}
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)
: Vec3i(source.getBlockX(), source.getBlockY(), source.getBlockZ()) {}
// Metodi di confronto
bool BlockPos::equals(const BlockPos& other) const {
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);
}
// Metodi direzionali
// directional methods
BlockPos BlockPos::above(int distance) const {
return BlockPos(x, y + distance, z);
}
@@ -119,7 +119,7 @@ BlockPos BlockPos::multiply(int factor) const {
return BlockPos(x * factor, y * factor, z * factor);
}
// Compressione
// compression
int BlockPos::compress() const {
static const int MASK_X = (1 << BITS_X) - 1;
static const int MASK_Y = (1 << BITS_Y) - 1;
+36 -25
View File
@@ -148,7 +148,7 @@ void Boat::lerpTo(double x, double y, double z, float yRot, float xRot, int step
{
if (doLerp)
{
lSteps = steps + 5;
lSteps = steps +5;
}
else
{
@@ -188,6 +188,10 @@ void Boat::lerpMotion(double xd, double yd, double zd)
void Boat::tick()
{
Entity::tick();
if (getHurtTime() > 0) setHurtTime(getHurtTime() - 1);
if (getDamage() > 0) setDamage(getDamage() - 1);
xo = x;
@@ -199,8 +203,8 @@ void Boat::tick()
double waterPercentage = 0;
for (int i = 0; i < steps; i++)
{
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 - 2 / 16.0f;
double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps + 1.5f / 16.0f;
double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps + 1.5f / 16.0f;
AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1);
if (level->containsLiquid(bb2, Material::water))
{
@@ -257,18 +261,19 @@ void Boat::tick()
return;
}
// Bob in water
if (waterPercentage > 0)
// Bob in water & gravity
if (waterPercentage < 1.0)
{
double bob = waterPercentage * 2 - 1;
double bob = waterPercentage * 2.0 - 1.0;
yd += 0.04f * bob;
}
// Reimplement gravity again (??)
int tileUnder = level->getTile(Mth::floor(x), Mth::floor(y-0.15), Mth::floor(z));
if (tileUnder == 0 && !onGround)
else
{
yd -= 0.04f;
if (yd < 0.0)
{
yd /= 2.0;
}
yd += 0.007f;
}
// Rider controls
@@ -281,24 +286,16 @@ void Boat::tick()
{
double riderXd = -sin(livingRider->yRot * PI / 180);
double riderZd = cos(livingRider->yRot * PI / 180);
float mult = livingRider->isSprinting() ? 2.0f : 1.0f;
double currentSpeed = sqrt(xd * xd + zd * zd);
float moveFactor = (float)forward;
if (forward < 0) moveFactor *= 0.5f; // Move slower backwards
xd += riderXd * acceleration * 0.05f * mult * moveFactor;
zd += riderZd * acceleration * 0.05f * mult * moveFactor;
xd += riderXd * acceleration * 0.05f * moveFactor;
zd += riderZd * acceleration * 0.05f * moveFactor;
}
}
double curSpeed = sqrt(xd * xd + zd * zd);
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)
{
@@ -330,10 +327,12 @@ void Boat::tick()
move(xd, yd, zd);
// Break boat on high speed collision
float breakThreshold = (rider.lock() != nullptr) ? 0.35f : 0.20f;
if ((horizontalCollision && lastSpeed > 0.20))
{
if (!level->isClientSide && !removed)
{
remove();
for (int i = 0; i < 3; i++)
{
@@ -343,6 +342,9 @@ void Boat::tick()
{
spawnAtLocation(Item::stick->id, 1, 0);
}
}
}
else
@@ -472,10 +474,19 @@ bool Boat::interact(shared_ptr<Player> player)
if ( (rider.lock() != nullptr) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true;
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)
player->ride( rider.lock() == player ? nullptr : shared_from_this() );
}
return true;
player->ride(isRiding ? nullptr : shared_from_this());
}
return true;
}
void Boat::setDamage(float damage)
+2 -2
View File
@@ -38,11 +38,11 @@ void ClothDyeRecipes::addRecipes(Recipes *r)
}
// some dye recipes
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::YELLOW),
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW),
L"tg",
Tile::flower,L'D');
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::RED),
r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED),
L"tg",
Tile::rose,L'D');
+57 -24
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "net.minecraft.world.item.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.redstone.h"
@@ -107,33 +107,42 @@ bool ComparatorTile::shouldTurnOn(Level *level, int x, int y, int z, int data)
int ComparatorTile::getInputSignal(Level *level, int x, int y, int z, int data)
{
int result = DiodeTile::getInputSignal(level, x, y, z, data);
int result = DiodeTile::getInputSignal(level, x, y, z, data);
int dir = getDirection(data);
int xx = x + Direction::STEP_X[dir];
int zz = z + Direction::STEP_Z[dir];
int tile = level->getTile(xx, y, zz);
int dir = getDirection(data);
int xx = x + Direction::STEP_X[dir];
int zz = z + Direction::STEP_Z[dir];
int tile = level->getTile(xx, y, zz);
if (tile > 0)
{
if (Tile::tiles[tile]->hasAnalogOutputSignal())
{
result = Tile::tiles[tile]->getAnalogOutputSignal(level, xx, y, zz, Direction::DIRECTION_OPPOSITE[dir]);
}
else if (result < Redstone::SIGNAL_MAX && Tile::isSolidBlockingTile(tile))
{
xx += Direction::STEP_X[dir];
zz += Direction::STEP_Z[dir];
tile = level->getTile(xx, y, zz);
if (tile > 0)
{
if (Tile::tiles[tile]->hasAnalogOutputSignal())
{
result = Tile::tiles[tile]->getAnalogOutputSignal(level, xx, y, zz, Direction::DIRECTION_OPPOSITE[dir]);
}
else if (result < Redstone::SIGNAL_MAX && Tile::isSolidBlockingTile(tile))
{
xx += Direction::STEP_X[dir];
zz += Direction::STEP_Z[dir];
tile = level->getTile(xx, y, zz);
if (tile > 0 && Tile::tiles[tile]->hasAnalogOutputSignal())
{
result = Tile::tiles[tile]->getAnalogOutputSignal(level, xx, y, zz, Direction::DIRECTION_OPPOSITE[dir]);
}
}
}
if (tile > 0 && Tile::tiles[tile]->hasAnalogOutputSignal())
{
result = Tile::tiles[tile]->getAnalogOutputSignal(level, xx, y, zz, Direction::DIRECTION_OPPOSITE[dir]);
}
else if (tile == 0)
{
shared_ptr<ItemFrame> frame = getItemFrame(level, xx, y, zz);
if (frame != nullptr)
{
result = frame->getAnalogOutput();
}
}
}
}
return result;
return result;
}
shared_ptr<ComparatorTileEntity> ComparatorTile::getComparator(LevelSource *level, int x, int y, int z)
@@ -250,4 +259,28 @@ shared_ptr<TileEntity> ComparatorTile::newTileEntity(Level *level)
bool ComparatorTile::TestUse()
{
return true;
}
shared_ptr<ItemFrame> ComparatorTile::getItemFrame(
Level* level,
int x,
int y,
int z)
{
AABB* box = AABB::newTemp(
x,
y,
z,
x + 1,
y + 1,
z + 1
);
vector<shared_ptr<Entity>>* entities =
level->getEntitiesOfClass(typeid(ItemFrame), box);
if (entities == nullptr || entities->size() != 1)
return nullptr;
return dynamic_pointer_cast<ItemFrame>((*entities)[0]);
}
+2
View File
@@ -2,6 +2,7 @@
#include "DiodeTile.h"
#include "EntityTile.h"
#include "AABB.h"
class ComparatorTileEntity;
@@ -57,4 +58,5 @@ public:
virtual bool triggerEvent(Level *level, int x, int y, int z, int b0, int b1);
virtual shared_ptr<TileEntity> newTileEntity(Level *level);
virtual bool TestUse();
shared_ptr<ItemFrame> ComparatorTile::getItemFrame(Level* level,int x,int y,int z);
};
+36
View File
@@ -26,6 +26,7 @@ void Creeper::_init()
oldSwell = 0;
maxSwell = 30;
explosionRadius = 3;
ignited = false;
}
Creeper::Creeper(Level *level) : Monster( level )
@@ -190,3 +191,38 @@ void Creeper::thunderHit(const LightningBolt *lightningBolt)
Monster::thunderHit(lightningBolt);
entityData->set(DATA_IS_POWERED, static_cast<byte>(1));
}
void Creeper::Ignite()
{
setSwellDir(1);
ignited = true;
}
bool Creeper::isIgnited()
{
return ignited;
}
bool Creeper::mobInteract(shared_ptr<Player> player)
{
shared_ptr<ItemInstance> item = player->inventory->getSelected();
if (item == nullptr || item->id != Item::flintAndSteel_Id)
return Mob::mobInteract(player);
playSound(eSoundType_FIRE_NEWIGNITE, 1, random->nextFloat() * 0.4f + 0.8f);
player->swing();
if (!level->isClientSide)
{
if (!isIgnited())
{
Ignite();
item->hurtAndBreak(1, player);
return true;
}
return Mob::mobInteract(player);
}
return true;
}
+9 -1
View File
@@ -21,6 +21,8 @@ private:
int maxSwell;
int explosionRadius;
bool ignited;
void _init();
public:
@@ -34,6 +36,8 @@ public:
virtual int getMaxFallDistance();
virtual bool mobInteract(shared_ptr<Player> player);
protected:
virtual void causeFallDamage(float distance);
virtual void defineSynchedData();
@@ -61,5 +65,9 @@ protected:
public:
int getSwellDir();
void setSwellDir(int dir);
void thunderHit(const LightningBolt *lightningBolt) ;
void thunderHit(const LightningBolt *lightningBolt);
public:
void Ignite();
bool isIgnited();
};
+28 -19
View File
@@ -5,30 +5,39 @@
#include "CustomPayloadPacket.h"
// Mojang-defined custom packets
const wstring CustomPayloadPacket::CUSTOM_BOOK_PACKET = L"MC|BEdit";
const wstring CustomPayloadPacket::CUSTOM_BOOK_SIGN_PACKET = L"MC|BSign";
const wstring CustomPayloadPacket::TEXTURE_PACK_PACKET = L"MC|TPack";
const wstring CustomPayloadPacket::TRADER_LIST_PACKET = L"MC|TrList";
const wstring CustomPayloadPacket::TRADER_SELECTION_PACKET = L"MC|TrSel";
const wstring CustomPayloadPacket::SET_ADVENTURE_COMMAND_PACKET = L"MC|AdvCdm";
const wstring CustomPayloadPacket::SET_BEACON_PACKET = L"MC|Beacon";
const wstring CustomPayloadPacket::SET_ITEM_NAME_PACKET = L"MC|ItemName";
const wstring CustomPayloadPacket::CUSTOM_BOOK_PACKET = CreateVanillaPayloadKey(L"BEdit");
const wstring CustomPayloadPacket::CUSTOM_BOOK_SIGN_PACKET = CreateVanillaPayloadKey(L"BSign");
const wstring CustomPayloadPacket::TEXTURE_PACK_PACKET = CreateVanillaPayloadKey(L"TPack");
const wstring CustomPayloadPacket::TRADER_LIST_PACKET = CreateVanillaPayloadKey(L"TrList");
const wstring CustomPayloadPacket::TRADER_SELECTION_PACKET = CreateVanillaPayloadKey(L"TrSel");
const wstring CustomPayloadPacket::CIPHER_KEY_CHANNEL = L"MC|CKey";
const wstring CustomPayloadPacket::CIPHER_ACK_CHANNEL = L"MC|CAck";
const wstring CustomPayloadPacket::CIPHER_ON_CHANNEL = L"MC|COn";
// neoLegacy-defined custom packets
const wstring CustomPayloadPacket::UPDATE_RECIPE_REGISTRY = CreatePayloadKey(L"neo", L"UpdRReg");
const wstring CustomPayloadPacket::UPDATE_CREATIVE_REGISTRY = CreatePayloadKey(L"neo", L"UpdCReg");
const wstring CustomPayloadPacket::IDENTITY_TOKEN_ISSUE = L"MC|CTIssue";
const wstring CustomPayloadPacket::IDENTITY_TOKEN_CHALLENGE = L"MC|CTChallenge";
const wstring CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE = L"MC|CTResponse";
//todo: figure out if we should replace the packets in the comment section with a custom payload identifier
//comment section start
const wstring CustomPayloadPacket::SET_ADVENTURE_COMMAND_PACKET = CreateVanillaPayloadKey(L"AdvCdm");
const wstring CustomPayloadPacket::SET_BEACON_PACKET = CreateVanillaPayloadKey(L"Beacon");
const wstring CustomPayloadPacket::SET_ITEM_NAME_PACKET = CreateVanillaPayloadKey(L"ItemName");
const wstring CustomPayloadPacket::FORK_HELLO_CHANNEL = L"MC|ForkHello";
const wstring CustomPayloadPacket::FORK_PLAYER_LEAVE_CHANNEL = L"MC|ForkPLeave";
const wstring CustomPayloadPacket::CIPHER_KEY_CHANNEL = CreateVanillaPayloadKey(L"CKey");
const wstring CustomPayloadPacket::CIPHER_ACK_CHANNEL = CreateVanillaPayloadKey(L"CAck");
const wstring CustomPayloadPacket::CIPHER_ON_CHANNEL = CreateVanillaPayloadKey(L"COn");
const wstring CustomPayloadPacket::QUICK_EQUIP_PACKET = L"MC|QEquip";
const wstring CustomPayloadPacket::QUICK_EQUIP_SERVER_PACKET = L"MC|QEquipServer";
const wstring CustomPayloadPacket::IDENTITY_TOKEN_ISSUE = CreateVanillaPayloadKey(L"CTIssue");
const wstring CustomPayloadPacket::IDENTITY_TOKEN_CHALLENGE = CreateVanillaPayloadKey(L"CTChallenge");
const wstring CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE = CreateVanillaPayloadKey(L"CTResponse");
const wstring CustomPayloadPacket::ENCHANTMENT_LIST_PACKET = L"MC|EnchList";
const wstring CustomPayloadPacket::FORK_HELLO_CHANNEL = CreateVanillaPayloadKey(L"ForkHello");
const wstring CustomPayloadPacket::FORK_PLAYER_LEAVE_CHANNEL = CreateVanillaPayloadKey(L"ForkPLeave");
const wstring CustomPayloadPacket::ENCHANTMENT_LIST_PACKET = CreateVanillaPayloadKey(L"EnchList");
//comment section end
//removed cause its now handled on the server side
// const wstring CustomPayloadPacket::QUICK_EQUIP_PACKET = CreateVanillaPayloadKey(L"QEquip");
// const wstring CustomPayloadPacket::QUICK_EQUIP_SERVER_PACKET = CreateVanillaPayloadKey(L"QEquipServer");
CustomPayloadPacket::CustomPayloadPacket()
: length(0)
+9 -2
View File
@@ -3,6 +3,9 @@ using namespace std;
#include "Packet.h"
#define CreatePayloadKey(identifier, action) identifier L"|" action
#define CreateVanillaPayloadKey(action) CreatePayloadKey(L"MC", action)
class CustomPayloadPacket : public Packet, public enable_shared_from_this<CustomPayloadPacket>
{
public:
@@ -17,6 +20,10 @@ public:
static const wstring SET_BEACON_PACKET;
static const wstring SET_ITEM_NAME_PACKET;
// neoLegacy-defined custom packets
static const wstring UPDATE_RECIPE_REGISTRY;
static const wstring UPDATE_CREATIVE_REGISTRY;
// Security: stream cipher handshake channels
static const wstring CIPHER_KEY_CHANNEL; // server->client: carries 32-byte key (16 AES key + 16 IV)
static const wstring CIPHER_ACK_CHANNEL; // client->server: ack (empty payload)
@@ -32,8 +39,8 @@ public:
static const wstring FORK_PLAYER_LEAVE_CHANNEL; // server->client: player disconnected (payload: UTF gamertag)
// Fixes for MP related crashes
static const wstring QUICK_EQUIP_PACKET;
static const wstring QUICK_EQUIP_SERVER_PACKET;
//static const wstring QUICK_EQUIP_PACKET;
//static const wstring QUICK_EQUIP_SERVER_PACKET;
static const wstring ENCHANTMENT_LIST_PACKET;
+14 -2
View File
@@ -42,8 +42,20 @@ Icon* DirtTile::getTexture(int face, int data)
if (data < 0 || data >= DIRT_NAMES_LENGTH)
data = 0;
if (TEXTURE_NAMES[data] == L"dirt_podzol") {
return (face == Facing::UP) ? podzolTop : podzolSide;
if (TEXTURE_NAMES[data] == L"dirt_podzol")
{
switch(face)
{
case Facing::UP:
return podzolTop;
break;
case Facing::DOWN:
return Tile::dirt->getTexture(face);
break;
default:
return podzolSide;
break;
}
}
return icons[data];
+7 -7
View File
@@ -6,13 +6,13 @@
#include "net.minecraft.world.item.h"
#include "net.minecraft.world.item.enchantment.h"
#include "EnchantmentMenu.h"
#include "../../../Minecraft.Client/ServerPlayer.h"
#include "../../../Minecraft.Client/MinecraftServer.h"
#include "../../../Minecraft.Client/PlayerList.h"
#include "../../../Minecraft.Client/MultiPlayerLocalPlayer.h"
#include "../../../Minecraft.Client/PlayerConnection.h"
#include "../../../Minecraft.World/CustomPayloadPacket.h"
#include "../../../Minecraft.Client/Minecraft.h"
#include "../Minecraft.Client/ServerPlayer.h"
#include "../Minecraft.Client/MinecraftServer.h"
#include "../Minecraft.Client/PlayerList.h"
#include "../Minecraft.Client/MultiPlayerLocalPlayer.h"
#include "../Minecraft.Client/PlayerConnection.h"
#include "../Minecraft.World/CustomPayloadPacket.h"
#include "../Minecraft.Client/Minecraft.h"
EnchantmentMenu::EnchantmentMenu(shared_ptr<Inventory> inventory, Level *level, int xt, int yt, int zt)
{
+4
View File
@@ -43,4 +43,8 @@ public:
// 4J Added
static void updatePossibleRecipes(shared_ptr<CraftingContainer> craftSlots, bool *firework, bool *charge, bool *fade);
static bool isValidIngredient(shared_ptr<ItemInstance> item, bool firework, bool charge, bool fade);
virtual void writeToStream(DataOutputStream* dos) {
dos->writeByte(99);
}
};
+7 -1
View File
@@ -121,8 +121,14 @@ 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);
if (above->isSolid() || above->isLiquid()) level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
if (above->isLiquid() || Tile::lightBlock[aboveTileId] > 2)
{
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
}
}
int GrassTile::getResource(int data, Random *random, int playerBonusLevel)
+1 -1
View File
@@ -360,7 +360,7 @@ void Item::staticCtor()
Item::diamond = ( new Item(8) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_diamond)->setIconName(L"diamond")->setDescriptionId(IDS_ITEM_DIAMOND)->setUseDescriptionId(IDS_DESC_DIAMONDS);
Item::stick = ( new Item(24) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stick, Item::eMaterial_wood)->setIconName(L"stick")->handEquipped()->setDescriptionId(IDS_ITEM_STICK)->setUseDescriptionId(IDS_DESC_STICK);
Item::mushroomStew = ( new BowlFoodItem(26, 6) ) ->setIconName(L"mushroomStew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW);
Item::rabbitStew = ( new BowlFoodItem(157, 10) ) ->setIconName(L"rabbitStew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW);
Item::rabbitStew = ( new BowlFoodItem(157, 10) ) ->setIconName(L"rabbitStew")->setDescriptionId(IDS_ITEM_RABBIT_STEW)->setUseDescriptionId(IDS_DESC_RABBIT_STEW);
Item::string = ( new TilePlanterItem(31, Tile::tripWire) ) ->setIconName(L"string")->setDescriptionId(IDS_ITEM_STRING)->setUseDescriptionId(IDS_DESC_STRING);
Item::feather = ( new Item(32) ) ->setIconName(L"feather")->setDescriptionId(IDS_ITEM_FEATHER)->setUseDescriptionId(IDS_DESC_FEATHER);
+89 -14
View File
@@ -10,7 +10,8 @@
#include "net.minecraft.world.level.saveddata.h"
#include "com.mojang.nbt.h"
#include "ItemFrame.h"
#include "DamageSource.h"
#include "Level.h"
@@ -87,29 +88,52 @@ shared_ptr<ItemInstance> ItemFrame::getItem()
return getEntityData()->getItemInstance(DATA_ITEM);
}
void ItemFrame::setItem(shared_ptr<ItemInstance> item)
void ItemFrame::setItem(shared_ptr<ItemInstance> item, bool notifyNeighbors)
{
if(item != nullptr)
{
item = item->copy();
item->count = 1;
if (item != nullptr)
{
item = item->copy();
item->count = 1;
item->setFramed(dynamic_pointer_cast<ItemFrame>(shared_from_this()));
}
getEntityData()->set(DATA_ITEM, item);
getEntityData()->markDirty(DATA_ITEM);
item->setFramed(dynamic_pointer_cast<ItemFrame>( shared_from_this() ));
}
getEntityData()->set(DATA_ITEM, item);
getEntityData()->markDirty(DATA_ITEM);
if (notifyNeighbors)
{
level->updateNeighbourForOutputSignal(xTile, yTile, zTile, Tile::comparator_off->id);
}
}
int ItemFrame::getRotation()
void ItemFrame::setItem(shared_ptr<ItemInstance> item)
{
return getEntityData()->getByte(DATA_ROTATION);
setItem(item, true);
}
void ItemFrame::setRotation(int rotation)
int ItemFrame::getRotation()
{
getEntityData()->set(DATA_ROTATION, static_cast<byte>(rotation % 4));
return getEntityData()->getByte(DATA_ROTATION);
}
void ItemFrame::setRotation(int rotation, bool notifyNeighbors)
{
getEntityData()->set(DATA_ROTATION, static_cast<byte>(rotation % 8));
if (notifyNeighbors)
{
level->updateNeighbourForOutputSignal(xTile, yTile, zTile, Tile::comparator_off->id);
}
}
void ItemFrame::setRotation(int rotation)
{
getEntityData()->set(DATA_ROTATION, static_cast<byte>(rotation % 8));
level->updateNeighbourForOutputSignal(xTile, yTile, zTile, Tile::comparator_off->id);
}
void ItemFrame::addAdditonalSaveData(CompoundTag *tag)
{
if (getItem() != nullptr)
@@ -171,3 +195,54 @@ bool ItemFrame::interact(shared_ptr<Player> player)
return true;
}
bool ItemFrame::hurt(DamageSource *source, float damage)
{
if (level->isClientSide) return false;
shared_ptr<ItemInstance> item = getItem();
if (!source->isExplosion() && item != nullptr)
{
shared_ptr<Entity> sourceEntity = source->getEntity();
if (sourceEntity != nullptr && sourceEntity->instanceof(eTYPE_PLAYER))
{
shared_ptr<Player> player = dynamic_pointer_cast<Player>(sourceEntity);
if (!player->abilities.instabuild)
{
shared_ptr<ItemInstance> copy = item->copy();
removeFramedMap(copy);
spawnAtLocation(copy, 0);
}
else
{
removeFramedMap(item);
}
}
else
{
shared_ptr<ItemInstance> copy = item->copy();
removeFramedMap(copy);
spawnAtLocation(copy, 0);
}
setItem(nullptr);
return true;
}
return HangingEntity::hurt(source, damage);
}
int ItemFrame::getAnalogOutput()
{
shared_ptr<ItemInstance> item = getItem();
if (item == nullptr) return 0;
return getRotation() % 8 + 1;
}
float ItemFrame::getPickRadius()
{
return 0.0f;
}
+5
View File
@@ -38,9 +38,14 @@ private:
public:
shared_ptr<ItemInstance> getItem();
void setItem(shared_ptr<ItemInstance> item, bool notifyNeighbors);
void setItem(shared_ptr<ItemInstance> item);
int getRotation();
void setRotation(int rotation, bool notifyNeighbors);
void setRotation(int rotation);
virtual bool hurt(DamageSource *source, float damage) override;
virtual int getAnalogOutput();
virtual float getPickRadius()override;
virtual void addAdditonalSaveData(CompoundTag *tag);
virtual void readAdditionalSaveData(CompoundTag *tag);
+5
View File
@@ -220,6 +220,11 @@ void ItemInstance::setAuxValue(int value)
}
}
void ItemInstance::setRawAuxValue(int value)
{
auxValue = value;
}
int ItemInstance::getMaxDamage()
{
return Item::items[id]->getMaxDamage();
+1
View File
@@ -90,6 +90,7 @@ public:
int getDamageValue();
int getAuxValue() const;
void setAuxValue(int value);
void setRawAuxValue(int value);
int getMaxDamage();
bool hurt(int dmg, Random *random);
void hurtAndBreak(int dmg, shared_ptr<LivingEntity> owner);
+11 -10
View File
@@ -15,13 +15,13 @@ const unsigned int LeafTile2::LEAF2_NAMES[LEAF2_NAMES_SIZE] = {
};
const wstring LeafTile2::TEXTURES[2][2] = {
{ L"leaves_acacia", L"leaves_dark_oak" }, // Indice 0: Fancy
{ L"leaves_acacia_opaque", L"leaves_dark_oak_opaque" } // Indice 1: Veloce/Opaca
{ L"leaves_acacia", L"leaves_dark_oak" }, // index 0: Fancy
{ L"leaves_acacia_opaque", L"leaves_dark_oak_opaque" } // index 1: Fast
};
LeafTile2::LeafTile2(int id) : LeafTile(id)
{
// Non serve fare checkBuffer qui, ci pensa già la classe padre LeafTile!
// do nothing here
}
Icon *LeafTile2::getTexture(int face, int data)
@@ -29,8 +29,8 @@ Icon *LeafTile2::getTexture(int face, int data)
int type = data & 3;
if (type >= LEAF2_NAMES_SIZE) type = 0;
// isSolidRender() in LeafTile restituisce 'true' se la grafica è su Veloce/Opaca.
// Quindi se è true usiamo l'indice 1, se è false (Trasparente) usiamo l'indice 0.
// isSolidRender() in LeafTile returns 'true' if graphics is Fast
// if true -> index is 1, else 0.
int textureSet = isSolidRender(false) ? 1 : 0;
return icons[textureSet][type];
@@ -56,13 +56,14 @@ void LeafTile2::registerIcons(IconRegister *iconRegister)
int LeafTile2::getColor(int data)
{
// In inventario o in mano, l'Acacia e la Dark Oak usano il verde base
// in the inventory use the default colour for leaves
return FoliageColor::getDefaultColor();
}
int LeafTile2::getColor(LevelSource *level, int x, int y, int z, int data)
{
// Codice di blending per il colore del bioma (copiato dal tuo LeafTile.cpp)
// Codice di blending per il colore del bioma (copiato dal tuo LeafTile.cpp))
// blending biome colors copied from LeafTile.cpp
int totalRed = 0;
int totalGreen = 0;
int totalBlue = 0;
@@ -71,7 +72,7 @@ int LeafTile2::getColor(LevelSource *level, int x, int y, int z, int data)
{
for (int ox = -1; ox <= 1; ox++)
{
int foliageColor = level->getBiome(x + ox, z + oz)->getFolageColor(); // Attento, nel tuo engine si chiama getFolageColor() senza la 'i'
int foliageColor = level->getBiome(x + ox, z + oz)->getFolageColor(); // they mispelled the word. getFolageColor without "i"
totalRed += (foliageColor & 0xff0000) >> 16;
totalGreen += (foliageColor & 0xff00) >> 8;
totalBlue += (foliageColor & 0xff);
@@ -83,7 +84,7 @@ int LeafTile2::getColor(LevelSource *level, int x, int y, int z, int data)
void LeafTile2::playerDestroy(Level *level, shared_ptr<Player> player, int x, int y, int z, int data)
{
// Se il giocatore usa le cesoie, vogliamo droppare "leaves2" (ID 161) e non "leaves" (ID 18)
// if player is using shears, drop "leaves2" (ID 161) , instead of "leaves" (ID 18)
if (!level->isClientSide && player->getSelectedItem() != nullptr && player->getSelectedItem()->id == Item::shears->id)
{
player->awardStat(
@@ -95,7 +96,7 @@ void LeafTile2::playerDestroy(Level *level, shared_ptr<Player> player, int x, in
}
else
{
// Altrimenti usa la distruzione standard di TransparentTile
// or default destroy
TransparentTile::playerDestroy(level, player, x, y, z, data);
}
}
+1 -1
View File
@@ -13,7 +13,7 @@ public:
static const unsigned int LEAF2_NAMES[LEAF2_NAMES_SIZE];
private:
//[0] = Fancy (Trasparenti), [1] = Fast (Opache)
//index 0, fancy; index 1, fast
static const wstring TEXTURES[2][2];
Icon *icons[2][2];
+11 -11
View File
@@ -63,18 +63,18 @@ void MobCategory::setMaxInstancesPerLevel(int max)
m_maxPerLevel = max;
}
int MobCategory::maxAnimalsWithBreeding() { return creature->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxChickensWithBreeding() { return creature_chicken->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxMushroomCowsWithBreeding() { return creature_mushroomcow->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxWolvesWithBreeding() { return creature_wolf->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAnimalsWithBreeding() { return (creature->getMaxInstancesPerLevel() + 20)*2; }
int MobCategory::maxChickensWithBreeding() { return (creature_chicken->getMaxInstancesPerLevel() + 8)*2; }
int MobCategory::maxMushroomCowsWithBreeding() { return (creature_mushroomcow->getMaxInstancesPerLevel() + 20)*2; }
int MobCategory::maxWolvesWithBreeding() { return (creature_wolf->getMaxInstancesPerLevel() + 8)*2; }
int MobCategory::maxAnimalsWithSpawnEgg() { return maxAnimalsWithBreeding() + 20; }
int MobCategory::maxChickensWithSpawnEgg() { return maxChickensWithBreeding() + 10; }
int MobCategory::maxWolvesWithSpawnEgg() { return maxWolvesWithBreeding() + 10; }
int MobCategory::maxMonstersWithSpawnEgg() { return monster->getMaxInstancesPerLevel() + 20; }
int MobCategory::maxMushroomCowsWithSpawnEgg() { return maxMushroomCowsWithBreeding() + 8; }
int MobCategory::maxSquidsWithSpawnEgg() { return waterCreature->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAmbientWithSpawnEgg() { return ambient->getMaxInstancesPerLevel() + 8; }
int MobCategory::maxAnimalsWithSpawnEgg() { return (maxAnimalsWithBreeding() + 20)*2; }
int MobCategory::maxChickensWithSpawnEgg() { return (maxChickensWithBreeding() + 10)*2; }
int MobCategory::maxWolvesWithSpawnEgg() { return (maxWolvesWithBreeding() + 10)*2; }
int MobCategory::maxMonstersWithSpawnEgg() { return (monster->getMaxInstancesPerLevel() + 20)*2; }
int MobCategory::maxMushroomCowsWithSpawnEgg() { return (maxMushroomCowsWithBreeding() + 8)*2; }
int MobCategory::maxSquidsWithSpawnEgg() { return (waterCreature->getMaxInstancesPerLevel() + 8)*2; }
int MobCategory::maxAmbientWithSpawnEgg() { return (ambient->getMaxInstancesPerLevel() + 8)*2; }
Material *MobCategory::getSpawnPositionMaterial()
{
+4 -4
View File
@@ -7,9 +7,9 @@ class MobCategory
{
public:
// 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 = 50; // Max number of enemies (skeleton, zombie, creeper etc) 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 = 20; // Ambient mobs
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_ANIMALS_HARD_LIMIT = 100; // 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 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
@@ -20,7 +20,7 @@ public:
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
static const int MAX_VILLAGERS_WITH_BREEDING = 35;
static const int MAX_VILLAGERS_WITH_BREEDING = 70;
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
+6 -2
View File
@@ -137,9 +137,13 @@ void MobEffect::applyEffectTick(shared_ptr<LivingEntity> mob, int amplification)
}
else if (id == poison->id)
{
if (mob->getHealth() > 1.0f)
// poison must never reduce health below 1 hp
// if the current health is between 1 and 2 hp the player is left at exactly 1 HP rather than dying.
float currentHealth = mob->getHealth();
if (currentHealth > 1.0f)
{
mob->hurt(DamageSource::magic, 1.0f);
float poisonDmg = min(1.0f, currentHealth - 1.0f);
mob->hurt(DamageSource::magic, poisonDmg);
}
}
else if (id == wither->id)
+6 -6
View File
@@ -30,7 +30,7 @@ MoveEntityPacket::MoveEntityPacket(int id)
void MoveEntityPacket::read(DataInputStream *dis) //throws IOException
{
id = dis->readShort();
id = dis->readInt();
}
void MoveEntityPacket::write(DataOutputStream *dos) //throws IOException
@@ -40,7 +40,7 @@ void MoveEntityPacket::write(DataOutputStream *dos) //throws IOException
// We shouln't be tracking an entity that doesn't have a short type of id
DEBUG_BREAK();
}
dos->writeShort(static_cast<short>(id));
dos->writeInt(static_cast<short>(id));
}
void MoveEntityPacket::handle(PacketListener *listener)
@@ -50,7 +50,7 @@ void MoveEntityPacket::handle(PacketListener *listener)
int MoveEntityPacket::getEstimatedSize()
{
return 2;
return 4;
}
bool MoveEntityPacket::canBeInvalidated()
@@ -101,7 +101,7 @@ void MoveEntityPacket::PosRot::write(DataOutputStream *dos) //throws IOException
int MoveEntityPacket::PosRot::getEstimatedSize()
{
return 2+5;
return 4+5;
}
MoveEntityPacket::Pos::Pos()
@@ -133,7 +133,7 @@ void MoveEntityPacket::Pos::write(DataOutputStream *dos) //throws IOException
int MoveEntityPacket::Pos::getEstimatedSize()
{
return 2+3;
return 4+3;
}
MoveEntityPacket::Rot::Rot()
@@ -164,5 +164,5 @@ void MoveEntityPacket::Rot::write(DataOutputStream *dos) //throws IOException
int MoveEntityPacket::Rot::getEstimatedSize()
{
return 2+2;
return 4+2;
}
+24 -27
View File
@@ -37,7 +37,7 @@ MoveEntityPacketSmall::MoveEntityPacketSmall(int id)
void MoveEntityPacketSmall::read(DataInputStream *dis) //throws IOException
{
id = dis->readShort();
id = dis->readInt();
}
void MoveEntityPacketSmall::write(DataOutputStream *dos) //throws IOException
@@ -47,7 +47,7 @@ void MoveEntityPacketSmall::write(DataOutputStream *dos) //throws IOException
// We shouln't be tracking an entity that doesn't have a short type of id
DEBUG_BREAK();
}
dos->writeShort(static_cast<short>(id));
dos->writeInt(id);
}
void MoveEntityPacketSmall::handle(PacketListener *listener)
@@ -57,7 +57,7 @@ void MoveEntityPacketSmall::handle(PacketListener *listener)
int MoveEntityPacketSmall::getEstimatedSize()
{
return 2;
return 4;
}
bool MoveEntityPacketSmall::canBeInvalidated()
@@ -88,13 +88,12 @@ MoveEntityPacketSmall::PosRot::PosRot(int id, char xa, char ya, char za, char yR
void MoveEntityPacketSmall::PosRot::read(DataInputStream *dis) //throws IOException
{
int idAndRot = dis->readShort();
this->id = idAndRot & 0x07ff;
this->yRot = idAndRot >> 11;
int xAndYAndZ = (int)dis->readShort();
this->xa = xAndYAndZ >> 11;
this->ya = (xAndYAndZ << 21 ) >> 26;
this->za = (xAndYAndZ << 27 ) >> 27;
this->id = dis->readInt();
this->yRot = dis->readChar();
int XandYandZ = (int)dis->readShort();
this->xa = XandYandZ >> 11;
this->ya = (XandYandZ << 21 ) >> 26;
this->za = (XandYandZ << 27 ) >> 27;
}
void MoveEntityPacketSmall::PosRot::write(DataOutputStream *dos) //throws IOException
@@ -104,15 +103,15 @@ void MoveEntityPacketSmall::PosRot::write(DataOutputStream *dos) //throws IOExce
// We shouln't be tracking an entity that doesn't have a short type of id
DEBUG_BREAK();
}
short idAndRot = id | yRot << 11;
dos->writeShort(idAndRot);
short xAndYAndZ = ( xa << 11 ) | ( ( ya & 0x3f ) << 5 ) | ( za & 0x1f );
dos->writeShort(xAndYAndZ);
dos->writeInt(id);
dos->writeChar(yRot);
short XandYandZ = ( xa << 11 ) | ( ( ya & 0x3f ) << 5 ) | ( za & 0x1f );
dos->writeShort(XandYandZ);
}
int MoveEntityPacketSmall::PosRot::getEstimatedSize()
{
return 4;
return 7;
}
MoveEntityPacketSmall::Pos::Pos()
@@ -128,9 +127,8 @@ MoveEntityPacketSmall::Pos::Pos(int id, char xa, char ya, char za) : MoveEntityP
void MoveEntityPacketSmall::Pos::read(DataInputStream *dis) //throws IOException
{
int idAndY = dis->readShort();
this->id = idAndY & 0x07ff;
this->ya = idAndY >> 11;
this->id = dis->readInt();
this->ya = dis->readChar();
int XandZ = (int)static_cast<signed char>(dis->readByte());
xa = XandZ >> 4;
za = ( XandZ << 28 ) >> 28;
@@ -143,15 +141,15 @@ void MoveEntityPacketSmall::Pos::write(DataOutputStream *dos) //throws IOExcepti
// We shouln't be tracking an entity that doesn't have a short type of id
DEBUG_BREAK();
}
short idAndY = id | ya << 11;
dos->writeShort(idAndY);
dos->writeInt(id);
dos->writeChar(ya);
char XandZ = ( xa << 4 ) | ( za & 0x0f );
dos->writeByte(XandZ);
}
int MoveEntityPacketSmall::Pos::getEstimatedSize()
{
return 3;
return 7;
}
MoveEntityPacketSmall::Rot::Rot()
@@ -169,9 +167,8 @@ MoveEntityPacketSmall::Rot::Rot(int id, char yRot, char xRot) : MoveEntityPacket
void MoveEntityPacketSmall::Rot::read(DataInputStream *dis) //throws IOException
{
int idAndRot = (int)dis->readShort();
this->id = idAndRot & 0x07ff;
this->yRot = idAndRot >> 11;
this->id = dis->readInt();
this->yRot = dis->readChar();
}
void MoveEntityPacketSmall::Rot::write(DataOutputStream *dos) //throws IOException
@@ -181,11 +178,11 @@ void MoveEntityPacketSmall::Rot::write(DataOutputStream *dos) //throws IOExcepti
// We shouln't be tracking an entity that doesn't have a short type of id
DEBUG_BREAK();
}
short idAndRot = id | yRot << 11;
dos->writeShort(idAndRot);
dos->writeInt(id);
dos->writeChar(yRot);
}
int MoveEntityPacketSmall::Rot::getEstimatedSize()
{
return 2;
return 5;
}
-2
View File
@@ -103,7 +103,5 @@ public:
static shared_ptr<ItemInstance> readItem(DataInputStream *dis);
static void writeItem(shared_ptr<ItemInstance> item, DataOutputStream *dos);
static CompoundTag *readNbt(DataInputStream *dis);
protected:
static void writeNbt(CompoundTag *tag, DataOutputStream *dos);
};
+4 -27
View File
@@ -29,21 +29,12 @@ DWORD PistonBaseTile::tlsIdx = TlsAlloc();
// For us, that means that if we create a piston next to another one, then one of them gets two events to createPush, the second of which fails, leaving the
// piston in a bad (simultaneously extended & not extended) state.
// 4J - ignoreUpdate is a static in java, implementing as TLS here to make thread safe
bool PistonBaseTile::ignoreUpdate()
{
return (TlsGetValue(tlsIdx) != nullptr);
}
void PistonBaseTile::ignoreUpdate(bool set)
{
TlsSetValue(tlsIdx,(LPVOID)(set?1:0));
}
//I removed the code for ignoreUpdate so the above comment no longer applies ^.^
PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, isSolidRender() )
{
// 4J - added initialiser
ignoreUpdate(false);
this->isSticky = isSticky;
setSoundType(SOUND_STONE);
setDestroyTime(0.5f);
@@ -131,7 +122,7 @@ void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<L
{
int targetData = getNewFacing(level, x, y, z, dynamic_pointer_cast<Player>(by) );
level->setData(x, y, z, targetData, Tile::UPDATE_CLIENTS);
if (!level->isClientSide && !ignoreUpdate())
if (!level->isClientSide)
{
checkIfExtend(level, x, y, z);
}
@@ -139,7 +130,7 @@ void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<L
void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type)
{
if (!level->isClientSide && !ignoreUpdate())
if (!level->isClientSide)
{
checkIfExtend(level, x, y, z);
}
@@ -147,7 +138,7 @@ void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type
void PistonBaseTile::onPlace(Level *level, int x, int y, int z)
{
if (!level->isClientSide && level->getTileEntity(x, y, z) == nullptr && !ignoreUpdate())
if (!level->isClientSide && level->getTileEntity(x, y, z) == nullptr)
{
checkIfExtend(level, x, y, z);
}
@@ -212,7 +203,6 @@ bool PistonBaseTile::getNeighborSignal(Level *level, int x, int y, int z, int fa
bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, int facing)
{
ignoreUpdate(true);
if (!level->isClientSide)
{
@@ -221,12 +211,10 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
if (extend && param1 == TRIGGER_CONTRACT)
{
level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS);
ignoreUpdate(false);
return false;
}
else if (!extend && param1 == TRIGGER_EXTEND)
{
ignoreUpdate(false);
return false;
}
}
@@ -253,7 +241,6 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
}
if (FourKitBridge::FirePistonExtend(level->dimension->id, x, y, z, facing, pushLength))
{
ignoreUpdate(false);
return false;
}
}
@@ -277,7 +264,6 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
}
else
{
ignoreUpdate(false);
return false;
}
PIXEndNamedEvent();
@@ -288,7 +274,6 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
if (FourKitBridge::FirePistonRetract(level->dimension->id, x, y, z, facing))
{
level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS);
ignoreUpdate(false);
return false;
}
#endif
@@ -353,32 +338,24 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
level->setTileAndData(x, y, z, Tile::pistonMovingPiece_Id, blockData, Tile::UPDATE_ALL);
level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(block, blockData, facing, false, false));
ignoreUpdate(false);
level->removeTile(twoX, twoY, twoZ);
ignoreUpdate(true);
}
else if (!pistonPiece)
{
stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]);
ignoreUpdate(true);
}
PIXEndNamedEvent();
}
else
{
stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->removeTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]);
ignoreUpdate(true);
}
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_IN, 0.5f, level->random->nextFloat() * 0.15f + 0.6f);
}
ignoreUpdate(false);
return true;
}
+2 -3
View File
@@ -27,8 +27,7 @@ private:
static DWORD tlsIdx;
// 4J - was just a static but implemented with TLS for our version
static bool ignoreUpdate();
static void ignoreUpdate(bool set);
//code removed so the above comment no longer applies
public:
PistonBaseTile(int id, bool isSticky);
@@ -68,4 +67,4 @@ private:
static void stopSharingIfServer(Level *level, int x, int y, int z); // 4J added
bool createPush(Level *level, int sx, int sy, int sz, int facing);
};
};
+118 -85
View File
@@ -29,20 +29,14 @@ void Recipes::_init()
{
// 4J Jev: instance = new Recipes();
recipies = new RecipyList();
}
Recipes::Recipes()
{
int iCount=0;
_init();
pArmorRecipes = new ArmorRecipes;
pClothDyeRecipes = new ClothDyeRecipes;
pFoodRecipies = new FoodRecipies;
pOreRecipies = new OreRecipies;
pStructureRecipies = new StructureRecipies;
pToolRecipies = new ToolRecipies;
pWeaponRecipies = new WeaponRecipies;
pArmorRecipes = new ArmorRecipes;
pClothDyeRecipes = new ClothDyeRecipes;
pFoodRecipies = new FoodRecipies;
pOreRecipies = new OreRecipies;
pStructureRecipies = new StructureRecipies;
pToolRecipies = new ToolRecipies;
pWeaponRecipies = new WeaponRecipies;
// 4J Stu - These just don't work with our crafting menu
//recipies->push_back(new ArmorDyeRecipe());
@@ -50,8 +44,10 @@ Recipes::Recipes()
//recipies->add(new MapExtendingRecipe());
//recipies->add(new FireworksRecipe());
pFireworksRecipes = new FireworksRecipe();
}
void Recipes::_compileRecipes()
{
addShapedRecipy(new ItemInstance(Tile::wood, 4, 0), //
L"sczg",
L"#", //
@@ -186,7 +182,7 @@ Recipes::Recipes()
L"W#W", //
L"W#W", //
L'#', Item::stick,
L'#', Item::stick,
L'W', new ItemInstance(Tile::wood, 1, TreeTile::ACACIA_TRUNK),
L'S');
@@ -195,7 +191,7 @@ Recipes::Recipes()
L"W#W", //
L"W#W", //
L'#', Item::stick,
L'#', Item::stick,
L'W', new ItemInstance(Tile::wood, 1, TreeTile::DARK_TRUNK),
L'S');
@@ -475,12 +471,10 @@ Recipes::Recipes()
L'S');
pArmorRecipes->addRecipes(this);
//iCount=getRecipies()->size();
pClothDyeRecipes->addRecipes(this);
addShapedRecipy(new ItemInstance(Tile::snow, 1), //
L"sscig",
L"##", //
@@ -497,7 +491,7 @@ Recipes::Recipes()
L'#', Item::prismarine_shard,
L'S');
addShapedRecipy(new ItemInstance(Tile::prismarine, 1,PrismarineTile::TYPE_BRICKS), //
addShapedRecipy(new ItemInstance(Tile::prismarine, 1, PrismarineTile::TYPE_BRICKS), //
L"ssscig",
L"###", //
L"###", //
@@ -507,7 +501,7 @@ Recipes::Recipes()
L'S');
addShapedRecipy(new ItemInstance(Tile::prismarine, 1,PrismarineTile::TYPE_DARK), //
addShapedRecipy(new ItemInstance(Tile::prismarine, 1, PrismarineTile::TYPE_DARK), //
L"ssscicig",
L"###", //
L"#X#", //
@@ -657,10 +651,6 @@ Recipes::Recipes()
//iCount=getRecipies()->size();
addShapedRecipy(new ItemInstance(Item::cake, 1), //
L"ssscicicicig",
L"AAA", //
@@ -770,7 +760,7 @@ Recipes::Recipes()
L'#', Tile::wood,
L'V');
addShapedRecipy(new ItemInstance((Item *)Item::fishingRod, 1), //
addShapedRecipy(new ItemInstance((Item*)Item::fishingRod, 1), //
L"ssscicig",
L" #", //
L" #X", //
@@ -803,7 +793,7 @@ Recipes::Recipes()
L'F');
// Moved bow and arrow in from weapons to avoid stacking on the group name display
addShapedRecipy(new ItemInstance((Item *)Item::bow, 1), //
addShapedRecipy(new ItemInstance((Item*)Item::bow, 1), //
L"ssscicig",
L" #X", //
L"# X", //
@@ -850,7 +840,7 @@ Recipes::Recipes()
L'#', Tile::glass,
L'T');
// torch made of charcoal - moved to be the default due to the tutorial using it
addShapedRecipy(new ItemInstance(Tile::torch, 4), //
@@ -961,12 +951,12 @@ Recipes::Recipes()
addShapelessRecipy(new ItemInstance(Item::fireball, 3), //
L"iiig",
Item::gunpowder, Item::blazePowder,Item::coal,
Item::gunpowder, Item::blazePowder, Item::coal,
L'T');
addShapelessRecipy(new ItemInstance(Item::fireball, 3), //
L"iizg",
Item::gunpowder, Item::blazePowder,new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL),
Item::gunpowder, Item::blazePowder, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL),
L'T');
addShapedRecipy(new ItemInstance(Item::lead, 2), //
@@ -1096,24 +1086,24 @@ Recipes::Recipes()
L'#', Tile::wood, L'X', Item::diamond,
'D');
addShapedRecipy(new ItemInstance(Item::leather, 1),
L"sscig",
L"##",
L"##",
L'#', Item::rabbit_hide,
L'D');
addShapedRecipy(new ItemInstance(Item::leather, 1),
L"sscig",
L"##",
L"##",
L'#', Item::rabbit_hide,
L'D');
addShapedRecipy(new ItemInstance(Item::armor_stand, 1),
L"ssscictg",
L"SSS",
L" S ",
L"SXS",
L'S', Item::stick,
L'X', Tile::stoneSlabHalf,
L"ssscictg",
L"SSS",
L" S ",
L"SXS",
L'S', Item::stick,
L'X', Tile::stoneSlabHalf,
L'D');
addShapedRecipy(new ItemInstance(Item::paper, 3), //
@@ -1206,21 +1196,21 @@ Recipes::Recipes()
L'D');
// 4J - TODO - put these new 1.7.3 items in required place within recipes
addShapedRecipy(new ItemInstance(static_cast<Tile *>(Tile::pistonBase), 1), //
addShapedRecipy(new ItemInstance(static_cast<Tile*>(Tile::pistonBase), 1), //
L"sssctcicictg",
L"TTT", //
L"#X#", //
L"#R#", //
L"TTT", //
L"#X#", //
L"#R#", //
L'#', Tile::cobblestone, L'X', Item::ironIngot, L'R', Item::redStone, L'T', Tile::wood,
L'#', Tile::cobblestone, L'X', Item::ironIngot, L'R', Item::redStone, L'T', Tile::wood,
L'M');
addShapedRecipy(new ItemInstance(static_cast<Tile *>(Tile::pistonStickyBase), 1), //
addShapedRecipy(new ItemInstance(static_cast<Tile*>(Tile::pistonStickyBase), 1), //
L"sscictg",
L"S", //
L"P", //
L"S", //
L"P", //
L'S', Item::slimeBall, L'P', Tile::pistonBase,
L'S', Item::slimeBall, L'P', Tile::pistonBase,
L'M');
@@ -1233,7 +1223,7 @@ Recipes::Recipes()
L'P', Item::paper, L'G', Item::gunpowder,
L'D');
addShapedRecipy(new ItemInstance(Item::fireworksCharge,1), //
addShapedRecipy(new ItemInstance(Item::fireworksCharge, 1), //
L"sscicig",
L" D ", //
L" G ", //
@@ -1241,7 +1231,7 @@ Recipes::Recipes()
L'D', Item::dye_powder, L'G', Item::gunpowder,
L'D');
addShapedRecipy(new ItemInstance(Item::fireworksCharge,1), //
addShapedRecipy(new ItemInstance(Item::fireworksCharge, 1), //
L"sscicig",
L" D ", //
L" C ", //
@@ -1249,37 +1239,38 @@ Recipes::Recipes()
L'D', Item::dye_powder, L'C', Item::fireworksCharge,
L'D');
// Sort so the largest recipes get checked first!
/* 4J-PB - TODO
Collections.sort(recipies, new Comparator<Recipy>()
{
public: int compare(Recipy r0, Recipy r1)
{
// shapeless recipes are put in the back of the list
if (r0 instanceof ShapelessRecipy && r1 instanceof ShapedRecipy)
{
return 1;
}
if (r1 instanceof ShapelessRecipy && r0 instanceof ShapedRecipy)
{
return -1;
}
if (r1.size() < r0.size()) return -1;
if (r1.size() > r0.size()) return 1;
return 0;
}
});
*/
// 4J-PB removed System.out.println(recipies->size() + L" recipes");
// 4J-PB - build the array of ingredients required per recipe
buildRecipeIngredientsArray();
}
void Recipes::_wipeRecipes()
{
int iCount = recipies->size();
for (int i = 0; i < iCount; i++) {
Recipy::INGREDIENTS_REQUIRED& req = m_pRecipeIngredientsRequired[i];
delete[] req.iIngIDA;
delete[] req.iIngValA;
delete[] req.iIngAuxValA;
delete[] req.uiGridA;
}
for (int i = 0; i < iCount; i++) {
delete (*recipies)[i];
}
recipies->clear();
delete[] m_pRecipeIngredientsRequired;
m_pRecipeIngredientsRequired = nullptr;
}
Recipes::Recipes()
{
_init();
_compileRecipes();
}
// 4J-PB - this function has been substantially changed due to the differences with a va_list of classes in C++ and Java
ShapedRecipy *Recipes::addShapedRecipy(ItemInstance *result, ...)
{
@@ -1563,7 +1554,7 @@ void Recipes::buildRecipeIngredientsArray(void)
int iRecipeC=static_cast<int>(recipies->size());
m_pRecipeIngredientsRequired= new Recipy::INGREDIENTS_REQUIRED [iRecipeC];
m_pRecipeIngredientsRequired = new Recipy::INGREDIENTS_REQUIRED [iRecipeC];
int iCount=0;
for (auto& recipe : *recipies)
@@ -1577,4 +1568,46 @@ void Recipes::buildRecipeIngredientsArray(void)
Recipy::INGREDIENTS_REQUIRED *Recipes::getRecipeIngredientsArray(void)
{
return m_pRecipeIngredientsRequired;
}
}
void Recipes::loadFromLocal()
{
this->_wipeRecipes();
this->_compileRecipes();
}
void Recipes::loadFromPacket(byteArray packetData)
{
ByteArrayInputStream bais(packetData);
DataInputStream input(&bais);
this->_wipeRecipes();
{
int iCount = input.readInt();
for (int i = 0; i < iCount; i++) {
int recipeType = input.readByte();
if (recipeType == 1) {
recipies->push_back(ShapelessRecipy::readFromStream(&input));
} else if (recipeType == 2) {
recipies->push_back(ShapedRecipy::readFromStream(&input));
}
}
}
this->buildRecipeIngredientsArray();
}
std::shared_ptr<CustomPayloadPacket> Recipes::createUpdatePacket()
{
ByteArrayOutputStream baos;
DataOutputStream dos(&baos);
int iCount = recipies->size();
dos.writeInt(iCount);
for (int i = 0; i < iCount; i++) {
(*recipies)[i]->writeToStream(&dos);
}
return std::make_shared<CustomPayloadPacket>(CustomPayloadPacket::UPDATE_RECIPE_REGISTRY, baos.toByteArray());
}
+8
View File
@@ -16,6 +16,7 @@ import net.minecraft.world.level.tile.Tile;
*/
#include "Recipy.h"
#include "../Minecraft.World/CustomPayloadPacket.h"
#pragma once
using namespace std;
@@ -84,6 +85,8 @@ public:
private:
void _init(); // 4J add
void _compileRecipes();
void _wipeRecipes();
Recipes();
public:
@@ -97,6 +100,11 @@ public:
shared_ptr<ItemInstance> getItemForRecipe(Recipy *r);
Recipy::INGREDIENTS_REQUIRED *getRecipeIngredientsArray();
void loadFromLocal();
void loadFromPacket(byteArray packetData);
std::shared_ptr<CustomPayloadPacket> createUpdatePacket();
private:
void buildRecipeIngredientsArray();
Recipy::INGREDIENTS_REQUIRED *m_pRecipeIngredientsRequired;
+16 -14
View File
@@ -10,13 +10,13 @@
#define RECIPE_TYPE_2x2 0
#define RECIPE_TYPE_3x3 1
class Recipy
class Recipy
{
public:
enum _eGroupType
{
eGroupType_First=0,
eGroupType_Structure=0,
eGroupType_First = 0,
eGroupType_Structure = 0,
eGroupType_Tool,
eGroupType_Food,
eGroupType_Armour,
@@ -28,28 +28,30 @@ public:
eGroupType; // to class the item produced by the recipe
// 4J-PB - we'll classing an ingredient ID with a different aux value as a different IngID AuxVal pair
typedef struct
typedef struct
{
int iIngC;
int iType; // Can be a 2x2 or a 3x3. Inventory crafting can only make a 2x2.
int *iIngIDA;
int *iIngValA;
int *iIngAuxValA;
Recipy *pRecipy;
int* iIngIDA;
int* iIngValA;
int* iIngAuxValA;
Recipy* pRecipy;
bool bCanMake[XUSER_MAX_COUNT];
unsigned int *uiGridA; // hold the layout of the recipe (id | auxval<<24)
unsigned int* uiGridA; // hold the layout of the recipe (id | auxval<<24)
unsigned short usBitmaskMissingGridIngredients[XUSER_MAX_COUNT]; // each bit set means we don't have that grid ingredient
}
INGREDIENTS_REQUIRED;
~Recipy() {}
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level *level) = 0;
virtual ~Recipy() = default;
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level* level) = 0;
virtual shared_ptr<ItemInstance> assemble(shared_ptr<CraftingContainer> craftSlots) = 0;
virtual int size() = 0;
virtual const ItemInstance *getResultItem() = 0;
virtual const int getGroup() = 0;
virtual const ItemInstance* getResultItem() = 0;
virtual const int getGroup() = 0;
// 4J-PB
virtual bool reqs(int iRecipe) = 0;
virtual void reqs(INGREDIENTS_REQUIRED *pIngReq) = 0;
virtual void reqs(INGREDIENTS_REQUIRED* pIngReq) = 0;
virtual void writeToStream(DataOutputStream* dos) = 0;
};
+3 -3
View File
@@ -58,7 +58,7 @@ void RespawnPacket::read(DataInputStream *dis) //throws IOException
mapSeed = dis->readLong();
difficulty = dis->readByte();
m_newSeaLevel = dis->readBoolean();
m_newEntityId = dis->readShort();
m_newEntityId = dis->readInt();
#ifdef _LARGE_WORLDS
m_xzSize = dis->readShort();
m_hellScale = dis->read();
@@ -83,7 +83,7 @@ void RespawnPacket::write(DataOutputStream *dos) //throws IOException
dos->writeLong(mapSeed);
dos->writeByte(difficulty);
dos->writeBoolean(m_newSeaLevel);
dos->writeShort(m_newEntityId);
dos->writeInt(m_newEntityId);
#ifdef _LARGE_WORLDS
dos->writeShort(m_xzSize);
dos->write(m_hellScale);
@@ -97,5 +97,5 @@ int RespawnPacket::getEstimatedSize()
{
length = static_cast<int>(m_pLevelType->getGeneratorName().length());
}
return 13+length;
return 13+length+2;
}
+7 -8
View File
@@ -49,9 +49,9 @@ SetEntityMotionPacket::SetEntityMotionPacket(int id, double xd, double yd, doubl
void SetEntityMotionPacket::read(DataInputStream *dis) //throws IOException
{
short idAndFlag = dis->readShort();
id = idAndFlag & 0x07ff;
if( idAndFlag & 0x0800 )
useBytes = dis->readBoolean();
id = dis->readInt();
if(useBytes)
{
xa = static_cast<int>(dis->readByte());
ya = static_cast<int>(dis->readByte());
@@ -62,29 +62,28 @@ void SetEntityMotionPacket::read(DataInputStream *dis) //throws IOException
xa *= 16;
ya *= 16;
za *= 16;
useBytes = true;
}
else
{
xa = dis->readShort();
ya = dis->readShort();
za = dis->readShort();
useBytes = false;
}
}
void SetEntityMotionPacket::write(DataOutputStream *dos) //throws IOException
{
dos->writeBoolean(useBytes);
if( useBytes )
{
dos->writeShort(id | 0x800);
dos->writeInt(id);
dos->writeByte(xa/16);
dos->writeByte(ya/16);
dos->writeByte(za/16);
}
else
{
dos->writeShort(id);
dos->writeInt(id);
dos->writeShort(xa);
dos->writeShort(ya);
dos->writeShort(za);
@@ -98,7 +97,7 @@ void SetEntityMotionPacket::handle(PacketListener *listener)
int SetEntityMotionPacket::getEstimatedSize()
{
return useBytes ? 5 : 8;
return useBytes ? 8 : 11;
}
bool SetEntityMotionPacket::canBeInvalidated()
+79
View File
@@ -23,6 +23,24 @@ ShapedRecipy::ShapedRecipy(int width, int height, ItemInstance **recipeItems, It
_keepTag = false;
}
ShapedRecipy::~ShapedRecipy() {
// todo: why does this cause a error when clearing out these specifically?
// might be leaking memory here but im not sure cause it crashes when you clear them, so we dont clear them
/*for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (x < width && y < height) {
delete recipeItems[x + y * width];
}
}
}*/
delete[] recipeItems;
delete result;
recipeItems = nullptr;
result = nullptr;
}
const int ShapedRecipy::getGroup()
{
return group;
@@ -227,4 +245,65 @@ ShapedRecipy *ShapedRecipy::keepTag()
{
_keepTag = true;
return this;
}
void ShapedRecipy::writeToStream(DataOutputStream* dos) {
dos->writeByte(2);
dos->writeByte(this->group);
//write result item, it should always be valid
{
dos->writeShort(this->result->id);
dos->writeByte(this->result->count);
dos->writeShort(this->result->getAuxValue());
Packet::writeNbt(this->result->tag, dos);
}
dos->writeByte((this->width << 2) | this->height);
for (int i = 0; i < (this->width * this->height); i++) {
ItemInstance* ingredients_item = this->recipeItems[i];
dos->writeBoolean(ingredients_item == nullptr);
if (ingredients_item == nullptr) continue;
dos->writeShort(ingredients_item->id);
dos->writeShort(ingredients_item->getAuxValue());
Packet::writeNbt(ingredients_item->tag, dos);
}
}
ShapedRecipy* ShapedRecipy::readFromStream(DataInputStream* dis) {
int groupType = dis->readByte();
int resultItemID = dis->readShort();
int resultItemCount = dis->readByte();
int resultItemAux = dis->readShort();
ItemInstance* resultItem = new ItemInstance(resultItemID, resultItemCount, 0);
resultItem->setRawAuxValue(resultItemAux);
resultItem->tag = Packet::readNbt(dis);
unsigned char packedSize = dis->readByte();
int width = (packedSize >> 2) & 0x3;
int height = packedSize & 0x3;
ItemInstance** ids = new ItemInstance*[width * height];
for (int i = 0; i < width * height; i++) {
ItemInstance* ingredients_item = nullptr;
bool isNull = dis->readBoolean();
if (!isNull) {
int itemId = dis->readShort();
int itemAux = dis->readShort();
ingredients_item = new ItemInstance(itemId, 1, 0);
ingredients_item->setRawAuxValue(itemAux);
ingredients_item->tag = Packet::readNbt(dis);
}
ids[i] = ingredients_item;
}
return new ShapedRecipy(width, height, ids, resultItem, groupType);
}
+13 -8
View File
@@ -1,21 +1,22 @@
#pragma once
class ShapedRecipy : public Recipy
class ShapedRecipy : public Recipy
{
private:
int width, height, group;
ItemInstance **recipeItems;
ItemInstance *result;
ItemInstance** recipeItems;
ItemInstance* result;
bool _keepTag;
public:
const int resultId;
public:
ShapedRecipy(int width, int height, ItemInstance **recipeItems, ItemInstance *result, int iGroup=Recipy::eGroupType_Decoration);
ShapedRecipy(int width, int height, ItemInstance** recipeItems, ItemInstance* result, int iGroup = Recipy::eGroupType_Decoration);
virtual ~ShapedRecipy() override;
virtual const ItemInstance *getResultItem();
virtual const ItemInstance* getResultItem();
virtual const int getGroup();
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level *level);
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level* level);
private:
bool matches(shared_ptr<CraftingContainer> craftSlots, int xOffs, int yOffs, bool xFlip);
@@ -23,10 +24,14 @@ private:
public:
virtual shared_ptr<ItemInstance> assemble(shared_ptr<CraftingContainer> craftSlots);
virtual int size();
ShapedRecipy *keepTag();
ShapedRecipy* keepTag();
// 4J-PB - to return the items required to make a recipe
virtual bool reqs(int iRecipe);
virtual void reqs(INGREDIENTS_REQUIRED *pIngReq);
virtual void reqs(INGREDIENTS_REQUIRED* pIngReq);
virtual void writeToStream(DataOutputStream* dos);
static ShapedRecipy* readFromStream(DataInputStream* dis);
};
+71 -1
View File
@@ -19,6 +19,19 @@ ShapelessRecipy::ShapelessRecipy(ItemInstance *result, vector<ItemInstance *> *i
{
}
ShapelessRecipy::~ShapelessRecipy() {
for (int i = 0; i < ingredients->size(); i++) {
delete (*ingredients)[i];
}
delete ingredients;
delete result;
ingredients = nullptr;
result = nullptr;
}
const int ShapelessRecipy::getGroup()
{
return group;
@@ -173,4 +186,61 @@ void ShapelessRecipy::reqs(INGREDIENTS_REQUIRED *pIngReq)
delete [] TempIngReq.iIngValA;
delete [] TempIngReq.iIngAuxValA;
delete [] TempIngReq.uiGridA;
}
}
void ShapelessRecipy::writeToStream(DataOutputStream* dos) {
dos->writeByte(1);
dos->writeByte(this->group);
//write result item, it should always be valid
{
dos->writeShort(this->result->id);
dos->writeByte(this->result->count);
dos->writeShort(this->result->getAuxValue());
Packet::writeNbt(this->result->tag, dos);
}
byte iCount = ingredients->size();
dos->writeByte(iCount);
for (int i = 0; i < iCount; i++) {
ItemInstance* item = (*ingredients)[i];
dos->writeBoolean(item == nullptr);
if (item == nullptr) continue;
dos->writeShort(item->id);
dos->writeShort(item->getAuxValue());
Packet::writeNbt(item->tag, dos);
}
}
ShapelessRecipy* ShapelessRecipy::readFromStream(DataInputStream* dis) {
unsigned char groupType = dis->readByte();
int resultItemID = dis->readShort();
int resultItemCount = dis->readByte();
int resultItemAux = dis->readShort();
ItemInstance* resultItem = new ItemInstance(resultItemID, resultItemCount, 0);
resultItem->setRawAuxValue(resultItemAux);
resultItem->tag = Packet::readNbt(dis);
vector<ItemInstance*>* ingredients = new vector<ItemInstance*>();
int iCount = dis->readByte();
for (int i = 0; i < iCount; i++) {
if (dis->readBoolean() == true) continue; //item is null or something weird
int itemID = dis->readShort();
int itemAux = dis->readShort();
ItemInstance* ingredients_item = new ItemInstance(itemID, 1, 0);
ingredients_item->setRawAuxValue(itemAux);
ingredients_item->tag = Packet::readNbt(dis);
ingredients->push_back(ingredients_item);
}
return new ShapelessRecipy(resultItem, ingredients, (Recipy::_eGroupType)groupType);
}
+3
View File
@@ -9,6 +9,7 @@ private:
public:
ShapelessRecipy(ItemInstance *result, vector<ItemInstance *> *ingredients, _eGroupType egroup=Recipy::eGroupType_Decoration);
virtual ~ShapelessRecipy() override;
virtual const ItemInstance *getResultItem();
virtual const int getGroup();
@@ -20,4 +21,6 @@ public:
virtual bool reqs(int iRecipe);
virtual void reqs(INGREDIENTS_REQUIRED *pIngReq);
virtual void writeToStream(DataOutputStream* dos);
static ShapelessRecipy* readFromStream(DataInputStream* dos);
};
+2 -2
View File
@@ -7,7 +7,7 @@ class SharedConstants
public:
static void staticCtor();
static const wstring VERSION_STRING;
static const int NETWORK_PROTOCOL_VERSION = 78;
static const int NETWORK_PROTOCOL_VERSION = 79;
static const bool INGAME_DEBUG_OUTPUT = false;
// NOT texture resolution. How many sub-blocks each block face is made up of.
@@ -31,4 +31,4 @@ class SharedConstants
static const int TICKS_PER_SECOND = 20;
static const int FULLBRIGHT_LIGHTVALUE = 15 << 20 | 15 << 4;
};
};
+46 -2
View File
@@ -76,8 +76,52 @@ void StructureRecipies::addRecipes(Recipes *r)
L'#', new ItemInstance(Tile::quartzBlock, 1, QuartzBlockTile::TYPE_DEFAULT),
L'S');
r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 2, StoneTile::DIORITE), //
L"ssctcig",
L"#Q", //
L"Q#", //
L'#', Tile::cobblestone, L'Q', Item::netherQuartz,
L'S');
r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 1, StoneTile::GRANITE), //
L"sczcig",
L"#Q", //
L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::DIORITE), L'Q', Item::netherQuartz,
L'S');
r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 2, StoneTile::ANDESITE), //
L"sczctg",
L"#-", //
L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::DIORITE), L'-', Tile::cobblestone,
L'S');
r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 4, StoneTile::POLISHED_DIORITE), //
L"ssczg",
L"##", //
L"##", //
L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::DIORITE),
L'S');
r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 4, StoneTile::POLISHED_GRANITE), //
L"ssczg",
L"##", //
L"##", //
L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::GRANITE),
L'S');
r->addShapedRecipy(new ItemInstance(Tile::stone_Id, 4, StoneTile::POLISHED_ANDESITE), //
L"ssczg",
L"##", //
L"##", //
L'#', new ItemInstance(Tile::stone_Id, 1, StoneTile::ANDESITE),
L'S');
// 4J Stu - Changed the order, as the blocks that go with sandstone cause a 3-icon scroll
// that touches the text "Structures" in the title in 720 fullscreen.
+6
View File
@@ -32,6 +32,12 @@ void SwellGoal::stop()
void SwellGoal::tick()
{
if(creeper->isIgnited())
{
creeper->setSwellDir(1);
return;
}
if (target.lock() == nullptr)
{
creeper->setSwellDir(-1);
+6 -6
View File
@@ -189,11 +189,12 @@ void TallGrass2::neighborChanged(Level* level, int x, int y, int z, int type)
if (!isUpper)
{
if (!canSurvive(level, x, y, z))
int upperTileId = level->getTile(x, y + 1, z);
if (!canSurvive(level, x, y, z) || (upperTileId != id))
{
spawnResources(level, x, y, z, data, 0);
level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS);
if (level->getTile(x, y + 1, z) == id)
if (upperTileId == id)
level->removeTile(x, y + 1, z);
}
}
@@ -211,11 +212,12 @@ void TallGrass2::tick(Level* level, int x, int y, int z, Random* random)
if (!isUpper)
{
if (!canSurvive(level, x, y, z))
int upperTileId = level->getTile(x, y + 1, z);
if (!canSurvive(level, x, y, z) || (upperTileId != id))
{
spawnResources(level, x, y, z, data, 0);
level->setTileAndData(x, y, z, 0, 0, Tile::UPDATE_CLIENTS);
if (level->getTile(x, y + 1, z) == id)
if (upperTileId == id)
level->removeTile(x, y + 1, z);
}
}
@@ -224,7 +226,6 @@ void TallGrass2::tick(Level* level, int x, int y, int z, Random* random)
int TallGrass2::getResource(int data, Random* random, int playerBonusLevel)
{
return -1;
}
@@ -240,7 +241,6 @@ bool TallGrass2::isSilkTouchable()
shared_ptr<ItemInstance> TallGrass2::getSilkTouchItemInstance(int data)
{
if ((data & UPPER_BIT) != 0) return nullptr;
int variant = data & ~UPPER_BIT;
return std::make_shared<ItemInstance>(this, 1, variant);
+3 -3
View File
@@ -39,7 +39,7 @@ TeleportEntityPacket::TeleportEntityPacket(int id, int x, int y, int z, byte yRo
void TeleportEntityPacket::read(DataInputStream *dis) //throws IOException
{
id = dis->readShort();
id = dis->readInt();
#ifdef _LARGE_WORLDS
x = dis->readInt();
y = dis->readInt();
@@ -55,7 +55,7 @@ void TeleportEntityPacket::read(DataInputStream *dis) //throws IOException
void TeleportEntityPacket::write(DataOutputStream *dos) //throws IOException
{
dos->writeShort(id);
dos->writeInt(id);
#ifdef _LARGE_WORLDS
dos->writeInt(x);
dos->writeInt(y);
@@ -76,7 +76,7 @@ void TeleportEntityPacket::handle(PacketListener *listener)
int TeleportEntityPacket::getEstimatedSize()
{
return 2 + 2 + 2 + 2 + 1 + 1;
return 4 + 2 + 2 + 2 + 1 + 1;
}
bool TeleportEntityPacket::canBeInvalidated()
+1 -1
View File
@@ -324,7 +324,7 @@ void Tile::staticCtor()
Tile::tiles = new Tile *[TILE_NUM_COUNT];
memset( tiles, 0, sizeof( Tile *)*TILE_NUM_COUNT );
Tile::stone = (new StoneTile(1)) ->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stone")->setDescriptionId(IDS_TILE_STONE)->setUseDescriptionId(IDS_DESC_STONE);
Tile::stone = (new StoneTile(1))->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stone)->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stone")->setDescriptionId(IDS_TILE_STONE)->setUseDescriptionId(IDS_DESC_STONE);
Tile::grass = static_cast<GrassTile *>((new GrassTile(2))->setDestroyTime(0.6f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"grass")->setDescriptionId(IDS_TILE_GRASS)->setUseDescriptionId(IDS_DESC_GRASS));
Tile::dirt = (new DirtTile(3)) ->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_GRAVEL)->setIconName(L"dirt")->setDescriptionId(IDS_TILE_DIRT)->setUseDescriptionId(IDS_DESC_DIRT);
Tile::cobblestone = (new Tile(4, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"cobblestone")->setDescriptionId(IDS_TILE_STONE_BRICK)->setUseDescriptionId(IDS_DESC_STONE_BRICK);
+6
View File
@@ -49,10 +49,16 @@ Vec3 *Vec3::newPermanent(double x, double y, double z)
void Vec3::clearPool()
{
ThreadStorage *tls = static_cast<ThreadStorage *>(TlsGetValue(tlsIdx));
if (tls != nullptr)
{
tls->poolPointer = 0;
}
}
void Vec3::resetPool()
{
clearPool();
}
Vec3 *Vec3::newTemp(double x, double y, double z)
+4 -2
View File
@@ -709,7 +709,8 @@ BoundingBox *VillagePieces::StraightRoad::findPieceBox(StartPiece *startPiece, l
bool VillagePieces::StraightRoad::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
{
int tile = biomeBlock(Tile::gravel_Id, 0);
int roadTile = biomeBlock(Tile::gravel_Id, 0);
int baseTile = biomeBlock(Tile::cobblestone_Id, 0);
for (int x = boundingBox->x0; x <= boundingBox->x1; x++)
{
for (int z = boundingBox->z0; z <= boundingBox->z1; z++)
@@ -717,7 +718,8 @@ bool VillagePieces::StraightRoad::postProcess(Level *level, Random *random, Boun
if (chunkBB->isInside(x, 64, z))
{
int y = level->getTopSolidBlock(x, z) - 1;
level->setTileAndData(x, y, z,tile, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y, z, roadTile, 0, Tile::UPDATE_CLIENTS);
level->setTileAndData(x, y - 1, z, baseTile, 0, Tile::UPDATE_CLIENTS);
}
}
}
+17 -1
View File
@@ -156,7 +156,7 @@ bool Villager::mobInteract(shared_ptr<Player> player)
shared_ptr<ItemInstance> item = player->inventory->getSelected();
bool holdingSpawnEgg = item != nullptr && item->id == Item::spawnEgg_Id;
if (!holdingSpawnEgg && isAlive() && !isTrading() && !isBaby())
if (!player->isSneaking() && !holdingSpawnEgg && isAlive() && !isTrading() && !isBaby())
{
if (!level->isClientSide)
{
@@ -776,3 +776,19 @@ wstring Villager::getDisplayName()
};
return app.GetString(name);
}
void Villager::thunderHit(const LightningBolt *lightningBolt)
{
if (level->isClientSide) return;
shared_ptr<Witch> witch = std::make_shared<Witch>(level);
witch->moveTo(x, y, z, yRot, xRot);
if (this->hasCustomName())
witch->setCustomName(this->getCustomName());
if (this->isPersistenceRequired())
witch->setPersistenceRequired();
level->addEntity(witch);
remove();
}
+1
View File
@@ -147,4 +147,5 @@ public:
virtual shared_ptr<AgableMob> getBreedOffspring(shared_ptr<AgableMob> target);
virtual bool canBeLeashed();
virtual wstring getDisplayName();
virtual void thunderHit(const LightningBolt *lightningBolt);
};
@@ -20,3 +20,4 @@
#include "TheEndPortalTileEntity.h"
#include "SkullTileEntity.h"
#include "EnderChestTileEntity.h"
#include "ItemFrame.h"