TU19: merge Minecraft.World/Blocks

This commit is contained in:
Tropical 2026-03-21 15:52:50 -05:00
parent f25cd66f4d
commit 9b6046cb83
241 changed files with 8070 additions and 4644 deletions

View file

@ -16,7 +16,8 @@ const unsigned int AnvilTile::ANVIL_NAMES[ANVIL_NAMES_LENGTH] = {
std::wstring AnvilTile::TEXTURE_DAMAGE_NAMES[ANVIL_NAMES_LENGTH] = {
L"anvil_top", L"anvil_top_damaged_1", L"anvil_top_damaged_2"};
AnvilTile::AnvilTile(int id) : HeavyTile(id, Material::heavyMetal, false) {
AnvilTile::AnvilTile(int id)
: HeavyTile(id, Material::heavyMetal, false) {
part = PART_BASE;
setLightBlock(0);
icons = NULL;
@ -44,15 +45,24 @@ void AnvilTile::registerIcons(IconRegister* iconRegister) {
}
void AnvilTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3;
int dmg = level->getData(x, y, z) >> 2;
dir = ++dir % 4;
if (dir == 0) level->setData(x, y, z, Direction::NORTH | (dmg << 2));
if (dir == 1) level->setData(x, y, z, Direction::EAST | (dmg << 2));
if (dir == 2) level->setData(x, y, z, Direction::SOUTH | (dmg << 2));
if (dir == 3) level->setData(x, y, z, Direction::WEST | (dmg << 2));
if (dir == 0)
level->setData(x, y, z, Direction::NORTH | (dmg << 2),
Tile::UPDATE_CLIENTS);
if (dir == 1)
level->setData(x, y, z, Direction::EAST | (dmg << 2),
Tile::UPDATE_CLIENTS);
if (dir == 2)
level->setData(x, y, z, Direction::SOUTH | (dmg << 2),
Tile::UPDATE_CLIENTS);
if (dir == 3)
level->setData(x, y, z, Direction::WEST | (dmg << 2),
Tile::UPDATE_CLIENTS);
}
bool AnvilTile::use(Level* level, int x, int y, int z,
@ -92,4 +102,4 @@ void AnvilTile::onLand(Level* level, int xt, int yt, int zt, int data) {
bool AnvilTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
return true;
}
}

View file

@ -36,7 +36,8 @@ public:
Icon* getTexture(int face, int data);
void registerIcons(IconRegister* iconRegister);
void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
bool use(Level* level, int x, int y, int z, std::shared_ptr<Player> player,
int clickedFace, float clickX, float clickY, float clickZ,
bool soundOnly = false);

View file

@ -0,0 +1,32 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "TileEntities/TileEntity.h"
#include "BaseEntityTile.h"
BaseEntityTile::BaseEntityTile(int id, Material* material,
bool isSolidRender /*= true*/)
: Tile(id, material, isSolidRender) {
_isEntityTile = true;
}
void BaseEntityTile::onPlace(Level* level, int x, int y, int z) {
Tile::onPlace(level, x, y, z);
// level->setTileEntity(x, y, z, newTileEntity(level));
}
void BaseEntityTile::onRemove(Level* level, int x, int y, int z, int id,
int data) {
Tile::onRemove(level, x, y, z, id, data);
level->removeTileEntity(x, y, z);
}
bool BaseEntityTile::triggerEvent(Level* level, int x, int y, int z, int b0,
int b1) {
Tile::triggerEvent(level, x, y, z, b0, b1);
std::shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
if (te != NULL) {
return te->triggerEvent(b0, b1);
}
return false;
}

View file

@ -0,0 +1,16 @@
#pragma once
#include "Tile.h"
#include "TileEntities/EntityTile.h"
class TileEntity;
class BaseEntityTile : public Tile, public EntityTile {
protected:
BaseEntityTile(int id, Material* material, bool isSolidRender = true);
public:
virtual void onPlace(Level* level, int x, int y, int z);
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual bool triggerEvent(Level* level, int x, int y, int z, int b0,
int b1);
};

View file

@ -0,0 +1,163 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.h"
#include "BasePressurePlateTile.h"
BasePressurePlateTile::BasePressurePlateTile(int id, const std::wstring& tex,
Material* material)
: Tile(id, material, false) {
texture = tex;
setTicking(true);
// 4J Stu - Move this to derived classes
// updateShape(getDataForSignal(Redstone::SIGNAL_MAX));
}
void BasePressurePlateTile::updateShape(
LevelSource* level, int x, int y, int z, int forceData,
std::shared_ptr<TileEntity> forceEntity) {
updateShape(level->getData(x, y, z));
}
void BasePressurePlateTile::updateShape(int data) {
bool pressed = getSignalForData(data) > Redstone::SIGNAL_NONE;
float o = 1 / 16.0f;
if (pressed) {
setShape(o, 0, o, 1 - o, 0.5f / 16.0f, 1 - o);
} else {
setShape(o, 0, o, 1 - o, 1 / 16.0f, 1 - o);
}
}
int BasePressurePlateTile::getTickDelay(Level* level) {
return SharedConstants::TICKS_PER_SECOND;
}
AABB* BasePressurePlateTile::getAABB(Level* level, int x, int y, int z) {
return NULL;
}
bool BasePressurePlateTile::isSolidRender(bool isServerLevel) { return false; }
bool BasePressurePlateTile::blocksLight() { return false; }
bool BasePressurePlateTile::isCubeShaped() { return false; }
bool BasePressurePlateTile::isPathfindable(LevelSource* level, int x, int y,
int z) {
return true;
}
bool BasePressurePlateTile::mayPlace(Level* level, int x, int y, int z) {
return level->isTopSolidBlocking(x, y - 1, z) ||
FenceTile::isFence(level->getTile(x, y - 1, z));
}
void BasePressurePlateTile::neighborChanged(Level* level, int x, int y, int z,
int type) {
bool replace = false;
if (!level->isTopSolidBlocking(x, y - 1, z) &&
!FenceTile::isFence(level->getTile(x, y - 1, z)))
replace = true;
if (replace) {
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->removeTile(x, y, z);
}
}
void BasePressurePlateTile::tick(Level* level, int x, int y, int z,
Random* random) {
if (level->isClientSide) return;
int signal = getSignalForData(level->getData(x, y, z));
if (signal > Redstone::SIGNAL_NONE) checkPressed(level, x, y, z, signal);
}
void BasePressurePlateTile::entityInside(Level* level, int x, int y, int z,
std::shared_ptr<Entity> entity) {
if (level->isClientSide) return;
int signal = getSignalForData(level->getData(x, y, z));
if (signal == Redstone::SIGNAL_NONE) checkPressed(level, x, y, z, signal);
}
void BasePressurePlateTile::checkPressed(Level* level, int x, int y, int z,
int oldSignal) {
int signal = getSignalStrength(level, x, y, z);
bool wasPressed = oldSignal > Redstone::SIGNAL_NONE;
bool shouldBePressed = signal > Redstone::SIGNAL_NONE;
if (oldSignal != signal) {
level->setData(x, y, z, getDataForSignal(signal), Tile::UPDATE_CLIENTS);
updateNeighbours(level, x, y, z);
level->setTilesDirty(x, y, z, x, y, z);
}
if (!shouldBePressed && wasPressed) {
level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK,
0.3f, 0.5f);
} else if (shouldBePressed && !wasPressed) {
level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK,
0.3f, 0.6f);
}
if (shouldBePressed) {
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
}
AABB* BasePressurePlateTile::getSensitiveAABB(int x, int y, int z) {
float b = 2 / 16.0f;
return AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b);
}
void BasePressurePlateTile::onRemove(Level* level, int x, int y, int z, int id,
int data) {
if (getSignalForData(data) > 0) {
updateNeighbours(level, x, y, z);
}
Tile::onRemove(level, x, y, z, id, data);
}
void BasePressurePlateTile::updateNeighbours(Level* level, int x, int y,
int z) {
level->updateNeighborsAt(x, y, z, id);
level->updateNeighborsAt(x, y - 1, z, id);
}
int BasePressurePlateTile::getSignal(LevelSource* level, int x, int y, int z,
int dir) {
return getSignalForData(level->getData(x, y, z));
}
int BasePressurePlateTile::getDirectSignal(LevelSource* level, int x, int y,
int z, int dir) {
if (dir == Facing::UP) {
return getSignalForData(level->getData(x, y, z));
} else {
return Redstone::SIGNAL_NONE;
}
}
bool BasePressurePlateTile::isSignalSource() { return true; }
void BasePressurePlateTile::updateDefaultShape() {
float x = 8 / 16.0f;
float y = 2 / 16.0f;
float z = 8 / 16.0f;
setShape(0.5f - x, 0.5f - y, 0.5f - z, 0.5f + x, 0.5f + y, 0.5f + z);
}
int BasePressurePlateTile::getPistonPushReaction() {
return Material::PUSH_DESTROY;
}
void BasePressurePlateTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(texture);
}

View file

@ -0,0 +1,59 @@
#pragma once
#include "Tile.h"
class BasePressurePlateTile : public Tile {
private:
std::wstring texture;
protected:
BasePressurePlateTile(int id, const std::wstring& tex, Material* material);
public:
virtual void updateShape(LevelSource* level, int x, int y, int z,
int forceData = -1,
std::shared_ptr<TileEntity> forceEntity =
std::shared_ptr<TileEntity>());
protected:
virtual void updateShape(int data);
public:
virtual int getTickDelay(Level* level);
virtual AABB* getAABB(Level* level, int x, int y, int z);
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool blocksLight();
virtual bool isCubeShaped();
virtual bool isPathfindable(LevelSource* level, int x, int y, int z);
virtual bool mayPlace(Level* level, int x, int y, int z);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual void entityInside(Level* level, int x, int y, int z,
std::shared_ptr<Entity> entity);
protected:
virtual void checkPressed(Level* level, int x, int y, int z, int oldSignal);
virtual AABB* getSensitiveAABB(int x, int y, int z);
public:
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
protected:
virtual void updateNeighbours(Level* level, int x, int y, int z);
public:
virtual int getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual int getDirectSignal(LevelSource* level, int x, int y, int z,
int dir);
virtual bool isSignalSource();
virtual void updateDefaultShape();
virtual int getPistonPushReaction();
protected:
virtual int getSignalStrength(Level* level, int x, int y, int z) = 0;
virtual int getSignalForData(int data) = 0;
virtual int getDataForSignal(int signal) = 0;
public:
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -0,0 +1,418 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.h"
#include "BaseRailTile.h"
BaseRailTile::Rail::Rail(Level* level, int x, int y, int z) {
this->level = level;
this->x = x;
this->y = y;
this->z = z;
int id = level->getTile(x, y, z);
// 4J Stu - We saw a random crash near the end of development on XboxOne
// orignal version where the id here isn't a tile any more Adding this check
// in to avoid that crash
m_bValidRail = isRail(id);
if (m_bValidRail) {
int direction = level->getData(x, y, z);
if (((BaseRailTile*)Tile::tiles[id])->usesDataBit) {
usesDataBit = true;
direction = direction & ~RAIL_DATA_BIT;
} else {
usesDataBit = false;
}
updateConnections(direction);
}
}
BaseRailTile::Rail::~Rail() {
for (int i = 0; i < connections.size(); i++) {
delete connections[i];
}
}
void BaseRailTile::Rail::updateConnections(int direction) {
if (m_bValidRail) {
for (int i = 0; i < connections.size(); i++) {
delete connections[i];
}
connections.clear();
MemSect(50);
if (direction == DIR_FLAT_Z) {
connections.push_back(new TilePos(x, y, z - 1));
connections.push_back(new TilePos(x, y, z + 1));
} else if (direction == DIR_FLAT_X) {
connections.push_back(new TilePos(x - 1, y, z));
connections.push_back(new TilePos(x + 1, y, z));
} else if (direction == 2) {
connections.push_back(new TilePos(x - 1, y, z));
connections.push_back(new TilePos(x + 1, y + 1, z));
} else if (direction == 3) {
connections.push_back(new TilePos(x - 1, y + 1, z));
connections.push_back(new TilePos(x + 1, y, z));
} else if (direction == 4) {
connections.push_back(new TilePos(x, y + 1, z - 1));
connections.push_back(new TilePos(x, y, z + 1));
} else if (direction == 5) {
connections.push_back(new TilePos(x, y, z - 1));
connections.push_back(new TilePos(x, y + 1, z + 1));
} else if (direction == 6) {
connections.push_back(new TilePos(x + 1, y, z));
connections.push_back(new TilePos(x, y, z + 1));
} else if (direction == 7) {
connections.push_back(new TilePos(x - 1, y, z));
connections.push_back(new TilePos(x, y, z + 1));
} else if (direction == 8) {
connections.push_back(new TilePos(x - 1, y, z));
connections.push_back(new TilePos(x, y, z - 1));
} else if (direction == 9) {
connections.push_back(new TilePos(x + 1, y, z));
connections.push_back(new TilePos(x, y, z - 1));
}
MemSect(0);
}
}
void BaseRailTile::Rail::removeSoftConnections() {
if (m_bValidRail) {
for (unsigned int i = 0; i < connections.size(); i++) {
Rail* rail = getRail(connections[i]);
if (rail == NULL || !rail->connectsTo(this)) {
delete connections[i];
connections.erase(connections.begin() + i);
i--;
} else {
delete connections[i];
MemSect(50);
connections[i] = new TilePos(rail->x, rail->y, rail->z);
MemSect(0);
}
delete rail;
}
}
}
bool BaseRailTile::Rail::hasRail(int x, int y, int z) {
if (!m_bValidRail) return false;
if (isRail(level, x, y, z)) return true;
if (isRail(level, x, y + 1, z)) return true;
if (isRail(level, x, y - 1, z)) return true;
return false;
}
BaseRailTile::Rail* BaseRailTile::Rail::getRail(TilePos* p) {
if (!m_bValidRail) return NULL;
if (isRail(level, p->x, p->y, p->z))
return new Rail(level, p->x, p->y, p->z);
if (isRail(level, p->x, p->y + 1, p->z))
return new Rail(level, p->x, p->y + 1, p->z);
if (isRail(level, p->x, p->y - 1, p->z))
return new Rail(level, p->x, p->y - 1, p->z);
return NULL;
}
bool BaseRailTile::Rail::connectsTo(Rail* rail) {
if (m_bValidRail) {
AUTO_VAR(itEnd, connections.end());
for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) {
TilePos* p = *it; // connections[i];
if (p->x == rail->x && p->z == rail->z) {
return true;
}
}
}
return false;
}
bool BaseRailTile::Rail::hasConnection(int x, int y, int z) {
if (m_bValidRail) {
AUTO_VAR(itEnd, connections.end());
for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) {
TilePos* p = *it; // connections[i];
if (p->x == x && p->z == z) {
return true;
}
}
}
return false;
}
int BaseRailTile::Rail::countPotentialConnections() {
int count = 0;
if (m_bValidRail) {
if (hasRail(x, y, z - 1)) count++;
if (hasRail(x, y, z + 1)) count++;
if (hasRail(x - 1, y, z)) count++;
if (hasRail(x + 1, y, z)) count++;
}
return count;
}
bool BaseRailTile::Rail::canConnectTo(Rail* rail) {
if (!m_bValidRail) return false;
if (connectsTo(rail)) return true;
if (connections.size() == 2) {
return false;
}
if (connections.empty()) {
return true;
}
return true;
}
void BaseRailTile::Rail::connectTo(Rail* rail) {
if (m_bValidRail) {
MemSect(50);
connections.push_back(new TilePos(rail->x, rail->y, rail->z));
MemSect(0);
bool n = hasConnection(x, y, z - 1);
bool s = hasConnection(x, y, z + 1);
bool w = hasConnection(x - 1, y, z);
bool e = hasConnection(x + 1, y, z);
int dir = -1;
if (n || s) dir = DIR_FLAT_Z;
if (w || e) dir = DIR_FLAT_X;
if (!usesDataBit) {
if (s && e && !n && !w) dir = 6;
if (s && w && !n && !e) dir = 7;
if (n && w && !s && !e) dir = 8;
if (n && e && !s && !w) dir = 9;
}
if (dir == DIR_FLAT_Z) {
if (isRail(level, x, y + 1, z - 1)) dir = 4;
if (isRail(level, x, y + 1, z + 1)) dir = 5;
}
if (dir == DIR_FLAT_X) {
if (isRail(level, x + 1, y + 1, z)) dir = 2;
if (isRail(level, x - 1, y + 1, z)) dir = 3;
}
if (dir < 0) dir = DIR_FLAT_Z;
int data = dir;
if (usesDataBit) {
data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir;
}
level->setData(x, y, z, data, Tile::UPDATE_ALL);
}
}
bool BaseRailTile::Rail::hasNeighborRail(int x, int y, int z) {
if (!m_bValidRail) return false;
TilePos tp(x, y, z);
Rail* neighbor = getRail(&tp);
if (neighbor == NULL) return false;
neighbor->removeSoftConnections();
bool retval = neighbor->canConnectTo(this);
delete neighbor;
return retval;
}
void BaseRailTile::Rail::place(bool hasSignal, bool first) {
if (m_bValidRail) {
bool n = hasNeighborRail(x, y, z - 1);
bool s = hasNeighborRail(x, y, z + 1);
bool w = hasNeighborRail(x - 1, y, z);
bool e = hasNeighborRail(x + 1, y, z);
int dir = -1;
if ((n || s) && !w && !e) dir = DIR_FLAT_Z;
if ((w || e) && !n && !s) dir = DIR_FLAT_X;
if (!usesDataBit) {
if (s && e && !n && !w) dir = 6;
if (s && w && !n && !e) dir = 7;
if (n && w && !s && !e) dir = 8;
if (n && e && !s && !w) dir = 9;
}
if (dir == -1) {
if (n || s) dir = DIR_FLAT_Z;
if (w || e) dir = DIR_FLAT_X;
if (!usesDataBit) {
if (hasSignal) {
if (s && e) dir = 6;
if (w && s) dir = 7;
if (e && n) dir = 9;
if (n && w) dir = 8;
} else {
if (n && w) dir = 8;
if (e && n) dir = 9;
if (w && s) dir = 7;
if (s && e) dir = 6;
}
}
}
if (dir == DIR_FLAT_Z) {
if (isRail(level, x, y + 1, z - 1)) dir = 4;
if (isRail(level, x, y + 1, z + 1)) dir = 5;
}
if (dir == DIR_FLAT_X) {
if (isRail(level, x + 1, y + 1, z)) dir = 2;
if (isRail(level, x - 1, y + 1, z)) dir = 3;
}
if (dir < 0) dir = DIR_FLAT_Z;
updateConnections(dir);
int data = dir;
if (usesDataBit) {
data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir;
}
if (first || level->getData(x, y, z) != data) {
level->setData(x, y, z, data, Tile::UPDATE_ALL);
AUTO_VAR(itEnd, connections.end());
for (AUTO_VAR(it, connections.begin()); it != itEnd; it++) {
Rail* neighbor = getRail(*it);
if (neighbor == NULL) continue;
neighbor->removeSoftConnections();
if (neighbor->canConnectTo(this)) {
neighbor->connectTo(this);
}
delete neighbor;
}
}
}
}
bool BaseRailTile::isRail(Level* level, int x, int y, int z) {
return isRail(level->getTile(x, y, z));
}
bool BaseRailTile::isRail(int id) {
return id == Tile::rail_Id || id == Tile::goldenRail_Id ||
id == Tile::detectorRail_Id || id == Tile::activatorRail_Id;
}
BaseRailTile::BaseRailTile(int id, bool usesDataBit)
: Tile(id, Material::decoration, false) {
this->usesDataBit = usesDataBit;
setShape(0, 0, 0, 1, 2 / 16.0f, 1);
iconTurn = NULL;
}
bool BaseRailTile::isUsesDataBit() { return usesDataBit; }
AABB* BaseRailTile::getAABB(Level* level, int x, int y, int z) { return NULL; }
bool BaseRailTile::blocksLight() { return false; }
bool BaseRailTile::isSolidRender(bool isServerLevel) { return false; }
HitResult* BaseRailTile::clip(Level* level, int xt, int yt, int zt, Vec3* a,
Vec3* b) {
updateShape(level, xt, yt, zt);
return Tile::clip(level, xt, yt, zt, a, b);
}
void BaseRailTile::updateShape(
LevelSource* level, int x, int y, int z, int forceData,
std::shared_ptr<TileEntity>
forceEntity) // 4J added forceData, forceEntity param
{
int data = level->getData(x, y, z);
if (data >= 2 && data <= 5) {
setShape(0, 0, 0, 1, 2 / 16.0f + 0.5f, 1);
} else {
setShape(0, 0, 0, 1, 2 / 16.0f, 1);
}
}
bool BaseRailTile::isCubeShaped() { return false; }
int BaseRailTile::getRenderShape() { return Tile::SHAPE_RAIL; }
int BaseRailTile::getResourceCount(Random random) { return 1; }
bool BaseRailTile::mayPlace(Level* level, int x, int y, int z) {
if (level->isTopSolidBlocking(x, y - 1, z)) {
return true;
}
return false;
}
void BaseRailTile::onPlace(Level* level, int x, int y, int z) {
if (!level->isClientSide) {
updateDir(level, x, y, z, true);
if (usesDataBit) {
neighborChanged(level, x, y, z, id);
}
}
}
void BaseRailTile::neighborChanged(Level* level, int x, int y, int z,
int type) {
if (level->isClientSide) return;
int data = level->getData(x, y, z);
int dir = data;
if (usesDataBit) {
dir = dir & RAIL_DIRECTION_MASK;
}
bool remove = false;
if (!level->isTopSolidBlocking(x, y - 1, z)) remove = true;
if (dir == 2 && !level->isTopSolidBlocking(x + 1, y, z)) remove = true;
if (dir == 3 && !level->isTopSolidBlocking(x - 1, y, z)) remove = true;
if (dir == 4 && !level->isTopSolidBlocking(x, y, z - 1)) remove = true;
if (dir == 5 && !level->isTopSolidBlocking(x, y, z + 1)) remove = true;
if (remove) {
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->removeTile(x, y, z);
} else {
updateState(level, x, y, z, data, dir, type);
}
}
void BaseRailTile::updateState(Level* level, int x, int y, int z, int data,
int dir, int type) {}
void BaseRailTile::updateDir(Level* level, int x, int y, int z, bool first) {
if (level->isClientSide) return;
Rail* rail = new Rail(level, x, y, z);
rail->place(level->hasNeighborSignal(x, y, z), first);
delete rail;
}
int BaseRailTile::getPistonPushReaction() {
// override the decoration material's reaction
return Material::PUSH_NORMAL;
}
void BaseRailTile::onRemove(Level* level, int x, int y, int z, int id,
int data) {
int dir = data;
if (usesDataBit) {
dir &= RAIL_DIRECTION_MASK;
}
Tile::onRemove(level, x, y, z, id, data);
if (dir == 2 || dir == 3 || dir == 4 || dir == 5) {
level->updateNeighborsAt(x, y + 1, z, id);
}
if (usesDataBit) {
level->updateNeighborsAt(x, y, z, id);
level->updateNeighborsAt(x, y - 1, z, id);
}
}

View file

@ -0,0 +1,97 @@
#pragma once
#include "Tile.h"
#include "../Level/TilePos.h"
#include "../Util/Definitions.h"
class Random;
class HitResult;
class ChunkRebuildData;
class BaseRailTile : public Tile {
friend class Tile;
friend class ChunkRebuildData;
public:
static const int DIR_FLAT_Z = 0;
static const int DIR_FLAT_X = 1;
// the data bit is used by boosters and detectors, so they can't turn
static const int RAIL_DATA_BIT = 8;
static const int RAIL_DIRECTION_MASK = 7;
private:
Icon* iconTurn;
protected:
bool usesDataBit;
class Rail {
friend class BaseRailTile;
friend class RailTile;
private:
Level* level;
int x, y, z;
bool usesDataBit;
std::vector<TilePos*> connections;
bool m_bValidRail; // 4J added
public:
Rail(Level* level, int x, int y, int z);
~Rail();
private:
void updateConnections(int direction);
void removeSoftConnections();
bool hasRail(int x, int y, int z);
Rail* getRail(TilePos* p);
bool connectsTo(Rail* rail);
bool hasConnection(int x, int y, int z);
protected:
int countPotentialConnections();
private:
bool canConnectTo(Rail* rail);
void connectTo(Rail* rail);
bool hasNeighborRail(int x, int y, int z);
public:
void place(bool hasSignal, bool first);
};
public:
static bool isRail(Level* level, int x, int y, int z);
static bool isRail(int id);
protected:
BaseRailTile(int id, bool usesDataBit);
public:
using Tile::getResourceCount;
bool isUsesDataBit();
virtual AABB* getAABB(Level* level, int x, int y, int z);
virtual bool blocksLight();
virtual bool isSolidRender(bool isServerLevel = false);
virtual HitResult* clip(Level* level, int xt, int yt, int zt, Vec3* a,
Vec3* b);
virtual void updateShape(
LevelSource* level, int x, int y, int z, int forceData = -1,
std::shared_ptr<TileEntity> forceEntity = std::shared_ptr<
TileEntity>()); // 4J added forceData, forceEntity param
virtual bool isCubeShaped();
virtual int getRenderShape();
virtual int getResourceCount(Random random);
virtual bool mayPlace(Level* level, int x, int y, int z);
virtual void onPlace(Level* level, int x, int y, int z);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
protected:
virtual void updateState(Level* level, int x, int y, int z, int data,
int dir, int type);
virtual void updateDir(Level* level, int x, int y, int z, bool first);
public:
int getPistonPushReaction();
void onRemove(Level* level, int x, int y, int z, int id, int data);
};

View file

@ -0,0 +1,52 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.entity.player.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "BeaconTile.h"
BeaconTile::BeaconTile(int id)
: BaseEntityTile(id, Material::glass, false) {
setDestroyTime(3.0f);
}
std::shared_ptr<TileEntity> BeaconTile::newTileEntity(Level* level) {
return std::shared_ptr<BeaconTileEntity>(new BeaconTileEntity());
}
bool BeaconTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ, bool soundOnly) {
if (level->isClientSide) return true;
std::shared_ptr<BeaconTileEntity> beacon =
std::dynamic_pointer_cast<BeaconTileEntity>(
level->getTileEntity(x, y, z));
if (beacon != NULL) player->openBeacon(beacon);
return true;
}
bool BeaconTile::isSolidRender(bool isServerLevel) { return false; }
bool BeaconTile::isCubeShaped() { return false; }
bool BeaconTile::blocksLight() { return false; }
int BeaconTile::getRenderShape() { return SHAPE_BEACON; }
void BeaconTile::registerIcons(IconRegister* iconRegister) {
BaseEntityTile::registerIcons(iconRegister);
}
void BeaconTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
BaseEntityTile::setPlacedBy(level, x, y, z, by, itemInstance);
if (itemInstance->hasCustomHoverName()) {
std::dynamic_pointer_cast<BeaconTileEntity>(
level->getTileEntity(x, y, z))
->setCustomName(itemInstance->getHoverName());
}
}
bool BeaconTile::TestUse() { return true; }

View file

@ -0,0 +1,22 @@
#pragma once
#include "BaseEntityTile.h"
class BeaconTile : public BaseEntityTile {
public:
BeaconTile(int id);
std::shared_ptr<TileEntity> newTileEntity(Level* level);
bool use(Level* level, int x, int y, int z, std::shared_ptr<Player> player,
int clickedFace, float clickX, float clickY, float clickZ,
bool soundOnly = false);
bool isSolidRender(bool isServerLevel = false);
bool isCubeShaped();
bool blocksLight();
int getRenderShape();
void registerIcons(IconRegister* iconRegister);
void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual bool TestUse();
};

View file

@ -9,7 +9,8 @@
int BedTile::HEAD_DIRECTION_OFFSETS[4][2] = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}};
BedTile::BedTile(int id) : DirectionalTile(id, Material::cloth, false) {
BedTile::BedTile(int id)
: DirectionalTile(id, Material::cloth, false) {
setShape();
iconEnd = NULL;
@ -64,7 +65,7 @@ bool BedTile::use(Level* level, int x, int y, int z,
int data = level->getData(x, y, z);
if (!BedTile::isHeadPiece(data)) {
if (!isHeadPiece(data)) {
// fetch head piece instead
int direction = getDirection(data);
x += HEAD_DIRECTION_OFFSETS[direction][0];
@ -75,16 +76,17 @@ bool BedTile::use(Level* level, int x, int y, int z,
data = level->getData(x, y, z);
}
if (!level->dimension->mayRespawn()) {
if (!level->dimension->mayRespawn() ||
level->getBiome(x, z) == Biome::hell) {
double xc = x + 0.5;
double yc = y + 0.5;
double zc = z + 0.5;
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
int direction = getDirection(data);
x += HEAD_DIRECTION_OFFSETS[direction][0];
z += HEAD_DIRECTION_OFFSETS[direction][1];
if (level->getTile(x, y, z) == id) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
xc = (xc + x + 0.5) / 2;
yc = (yc + y + 0.5) / 2;
zc = (zc + z + 0.5) / 2;
@ -93,7 +95,7 @@ bool BedTile::use(Level* level, int x, int y, int z,
return true;
}
if (BedTile::isOccupied(data)) {
if (isOccupied(data)) {
std::shared_ptr<Player> sleepingPlayer = nullptr;
AUTO_VAR(itEnd, level->players.end());
for (AUTO_VAR(it, level->players.begin()); it != itEnd; it++) {
@ -107,7 +109,7 @@ bool BedTile::use(Level* level, int x, int y, int z,
}
if (sleepingPlayer == NULL) {
BedTile::setOccupied(level, x, y, z, false);
setOccupied(level, x, y, z, false);
} else {
player->displayClientMessage(IDS_TILE_BED_OCCUPIED);
@ -117,7 +119,7 @@ bool BedTile::use(Level* level, int x, int y, int z,
Player::BedSleepingResult result = player->startSleepInBed(x, y, z);
if (result == Player::OK) {
BedTile::setOccupied(level, x, y, z, true);
setOccupied(level, x, y, z, true);
// 4J-PB added
// are there multiple players in the same world as us?
if (level->AllPlayersAreSleeping() == false) {
@ -190,12 +192,12 @@ void BedTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (isHeadPiece(data)) {
if (level->getTile(x - HEAD_DIRECTION_OFFSETS[direction][0], y,
z - HEAD_DIRECTION_OFFSETS[direction][1]) != id) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
} else {
if (level->getTile(x + HEAD_DIRECTION_OFFSETS[direction][0], y,
z + HEAD_DIRECTION_OFFSETS[direction][1]) != id) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
if (!level->isClientSide) {
Tile::spawnResources(
level, x, y, z, data,
@ -226,7 +228,7 @@ void BedTile::setOccupied(Level* level, int x, int y, int z, bool occupied) {
} else {
data = data & ~OCCUPIED_DATA;
}
level->setData(x, y, z, data);
level->setData(x, y, z, data, Tile::UPDATE_NONE);
}
Pos* BedTile::findStandUpPosition(Level* level, int x, int y, int z,
@ -236,10 +238,8 @@ Pos* BedTile::findStandUpPosition(Level* level, int x, int y, int z,
// try to find a clear location near the bed
for (int step = 0; step <= 1; step++) {
int startX =
x - BedTile::HEAD_DIRECTION_OFFSETS[direction][0] * step - 1;
int startZ =
z - BedTile::HEAD_DIRECTION_OFFSETS[direction][1] * step - 1;
int startX = x - HEAD_DIRECTION_OFFSETS[direction][0] * step - 1;
int startZ = z - HEAD_DIRECTION_OFFSETS[direction][1] * step - 1;
int endX = startX + 2;
int endZ = startZ + 2;
@ -249,8 +249,9 @@ Pos* BedTile::findStandUpPosition(Level* level, int x, int y, int z,
// isEmpty for the blocks that we wish to place the player This
// allows the player to spawn in blocks with snow, grass etc
if (level->isTopSolidBlocking(standX, y - 1, standZ) &&
!level->isSolidBlockingTile(standX, y, standZ) &&
!level->isSolidBlockingTile(standX, y + 1, standZ)) {
!level->getMaterial(standX, y, standZ)->isSolidBlocking() &&
!level->getMaterial(standX, y + 1, standZ)
->isSolidBlocking()) {
if (skipCount > 0) {
skipCount--;
continue;
@ -276,3 +277,17 @@ int BedTile::getPistonPushReaction() { return Material::PUSH_DESTROY; }
int BedTile::cloneTileId(Level* level, int x, int y, int z) {
return Item::bed_Id;
}
void BedTile::playerWillDestroy(Level* level, int x, int y, int z, int data,
std::shared_ptr<Player> player) {
if (player->abilities.instabuild) {
if (isHeadPiece(data)) {
int direction = getDirection(data);
x -= HEAD_DIRECTION_OFFSETS[direction][0];
z -= HEAD_DIRECTION_OFFSETS[direction][1];
if (level->getTile(x, y, z) == id) {
level->removeTile(x, y, z);
}
}
}
}

View file

@ -58,4 +58,6 @@ public:
float odds, int playerBonus);
virtual int getPistonPushReaction();
virtual int cloneTileId(Level* level, int x, int y, int z);
virtual void playerWillDestroy(Level* level, int x, int y, int z, int data,
std::shared_ptr<Player> player);
};

View file

@ -5,11 +5,10 @@
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.h"
const std::wstring BrewingStandTile::TEXTURE_BASE = L"brewingStand_base";
#include "../Headers/net.minecraft.world.inventory.h"
BrewingStandTile::BrewingStandTile(int id)
: EntityTile(id, Material::metal, false) {
: BaseEntityTile(id, Material::metal, false) {
random = new Random();
iconBase = NULL;
}
@ -31,9 +30,9 @@ void BrewingStandTile::addAABBs(Level* level, int x, int y, int z, AABB* box,
std::shared_ptr<Entity> source) {
setShape(7.0f / 16.0f, 0, 7.0f / 16.0f, 9.0f / 16.0f, 14.0f / 16.0f,
9.0f / 16.0f);
EntityTile::addAABBs(level, x, y, z, box, boxes, source);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
updateDefaultShape();
EntityTile::addAABBs(level, x, y, z, box, boxes, source);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
}
void BrewingStandTile::updateDefaultShape() {
@ -58,6 +57,16 @@ bool BrewingStandTile::use(
return true;
}
void BrewingStandTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
if (itemInstance->hasCustomHoverName()) {
std::dynamic_pointer_cast<BrewingStandTileEntity>(
level->getTileEntity(x, y, z))
->setCustomName(itemInstance->getHoverName());
}
}
void BrewingStandTile::animateTick(Level* level, int xt, int yt, int zt,
Random* random) {
double x = xt + 0.4f + random->nextFloat() * 0.2f;
@ -105,7 +114,7 @@ void BrewingStandTile::onRemove(Level* level, int x, int y, int z, int id,
}
}
}
EntityTile::onRemove(level, x, y, z, id, data);
BaseEntityTile::onRemove(level, x, y, z, id, data);
}
int BrewingStandTile::getResource(int data, Random* random,
@ -117,9 +126,17 @@ int BrewingStandTile::cloneTileId(Level* level, int x, int y, int z) {
return Item::brewingStand_Id;
}
void BrewingStandTile::registerIcons(IconRegister* iconRegister) {
EntityTile::registerIcons(iconRegister);
iconBase = iconRegister->registerIcon(TEXTURE_BASE);
bool BrewingStandTile::hasAnalogOutputSignal() { return true; }
int BrewingStandTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
return AbstractContainerMenu::getRedstoneSignalFromContainer(
std::dynamic_pointer_cast<Container>(level->getTileEntity(x, y, z)));
}
Icon* BrewingStandTile::getBaseTexture() { return iconBase; }
void BrewingStandTile::registerIcons(IconRegister* iconRegister) {
BaseEntityTile::registerIcons(iconRegister);
iconBase = iconRegister->registerIcon(getIconName() + L"_base");
}
Icon* BrewingStandTile::getBaseTexture() { return iconBase; }

View file

@ -1,15 +1,12 @@
#pragma once
#include "TileEntities/EntityTile.h"
#include "BaseEntityTile.h"
class IconRegister;
class ChunkRebuildData;
class BrewingStandTile : public EntityTile {
class BrewingStandTile : public BaseEntityTile {
friend ChunkRebuildData;
public:
static const std::wstring TEXTURE_BASE;
private:
Random* random;
Icon* iconBase;
@ -28,11 +25,17 @@ public:
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual void animateTick(Level* level, int xt, int yt, int zt,
Random* random);
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual int getResource(int data, Random* random, int playerBonusLevel);
virtual int cloneTileId(Level* level, int x, int y, int z);
void registerIcons(IconRegister* iconRegister);
Icon* getBaseTexture();
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
virtual void registerIcons(IconRegister* iconRegister);
virtual Icon* getBaseTexture();
};

View file

@ -1,6 +1,7 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.entity.projectile.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "../Headers/net.minecraft.h"
#include "ButtonTile.h"
@ -16,12 +17,12 @@ Icon* ButtonTile::getTexture(int face, int data) {
if (id == Tile::button_wood_Id)
return Tile::wood->getTexture(Facing::UP);
else
return Tile::rock->getTexture(Facing::UP);
return Tile::stone->getTexture(Facing::UP);
}
AABB* ButtonTile::getAABB(Level* level, int x, int y, int z) { return NULL; }
int ButtonTile::getTickDelay() { return sensitive ? 30 : 20; }
int ButtonTile::getTickDelay(Level* level) { return sensitive ? 30 : 20; }
bool ButtonTile::blocksLight() { return false; }
@ -100,8 +101,8 @@ void ButtonTile::neighborChanged(Level* level, int x, int y, int z, int type) {
replace = true;
if (replace) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->removeTile(x, y, z);
}
}
}
@ -109,7 +110,7 @@ void ButtonTile::neighborChanged(Level* level, int x, int y, int z, int type) {
bool ButtonTile::checkCanSurvive(Level* level, int x, int y, int z) {
if (!mayPlace(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return false;
}
return true;
@ -164,12 +165,13 @@ bool ButtonTile::use(Level* level, int x, int y, int z,
0.3f, 0.6f);
return false;
}
int data = level->getData(x, y, z);
int dir = data & 7;
int open = 8 - (data & 8);
if (open == 0) return true;
level->setData(x, y, z, dir + open);
level->setData(x, y, z, dir + open, Tile::UPDATE_ALL);
level->setTilesDirty(x, y, z, x, y, z);
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_CLICK, 0.3f,
@ -177,7 +179,7 @@ bool ButtonTile::use(Level* level, int x, int y, int z,
updateNeighbours(level, x, y, z, dir);
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
return true;
}
@ -190,20 +192,22 @@ void ButtonTile::onRemove(Level* level, int x, int y, int z, int id, int data) {
Tile::onRemove(level, x, y, z, id, data);
}
bool ButtonTile::getSignal(LevelSource* level, int x, int y, int z, int dir) {
return (level->getData(x, y, z) & 8) > 0;
int ButtonTile::getSignal(LevelSource* level, int x, int y, int z, int dir) {
return (level->getData(x, y, z) & 8) > 0 ? Redstone::SIGNAL_MAX
: Redstone::SIGNAL_NONE;
}
bool ButtonTile::getDirectSignal(Level* level, int x, int y, int z, int dir) {
int ButtonTile::getDirectSignal(LevelSource* level, int x, int y, int z,
int dir) {
int data = level->getData(x, y, z);
if ((data & 8) == 0) return false;
if ((data & 8) == 0) return Redstone::SIGNAL_NONE;
int myDir = data & 7;
if (myDir == 5 && dir == 1) return true;
if (myDir == 4 && dir == 2) return true;
if (myDir == 3 && dir == 3) return true;
if (myDir == 2 && dir == 4) return true;
if (myDir == 1 && dir == 5) return true;
if (myDir == 5 && dir == 1) return Redstone::SIGNAL_MAX;
if (myDir == 4 && dir == 2) return Redstone::SIGNAL_MAX;
if (myDir == 3 && dir == 3) return Redstone::SIGNAL_MAX;
if (myDir == 2 && dir == 4) return Redstone::SIGNAL_MAX;
if (myDir == 1 && dir == 5) return Redstone::SIGNAL_MAX;
return false;
}
@ -219,7 +223,7 @@ void ButtonTile::tick(Level* level, int x, int y, int z, Random* random) {
if (sensitive) {
checkPressed(level, x, y, z);
} else {
level->setData(x, y, z, data & 7);
level->setData(x, y, z, data & 7, Tile::UPDATE_ALL);
int dir = data & 7;
updateNeighbours(level, x, y, z, dir);
@ -265,7 +269,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) {
delete entities;
if (shouldBePressed && !wasPressed) {
level->setData(x, y, z, dir | 8);
level->setData(x, y, z, dir | 8, Tile::UPDATE_ALL);
updateNeighbours(level, x, y, z, dir);
level->setTilesDirty(x, y, z, x, y, z);
@ -273,7 +277,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) {
0.3f, 0.6f);
}
if (!shouldBePressed && wasPressed) {
level->setData(x, y, z, dir);
level->setData(x, y, z, dir, Tile::UPDATE_ALL);
updateNeighbours(level, x, y, z, dir);
level->setTilesDirty(x, y, z, x, y, z);
@ -282,7 +286,7 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) {
}
if (shouldBePressed) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
}

View file

@ -18,7 +18,7 @@ protected:
public:
Icon* getTexture(int face, int data);
virtual AABB* getAABB(Level* level, int x, int y, int z);
virtual int getTickDelay();
virtual int getTickDelay(Level* level);
virtual bool blocksLight();
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool isCubeShaped();
@ -55,8 +55,9 @@ public:
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir);
virtual int getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual int getDirectSignal(LevelSource* level, int x, int y, int z,
int dir);
virtual bool isSignalSource();
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual void updateDefaultShape();

View file

@ -23,10 +23,11 @@ void CactusTile::tick(Level* level, int x, int y, int z, Random* random) {
if (height < 3) {
int age = level->getData(x, y, z);
if (age == 15) {
level->setTile(x, y + 1, z, id);
level->setData(x, y, z, 0);
level->setTileAndUpdate(x, y + 1, z, id);
level->setData(x, y, z, 0, Tile::UPDATE_NONE);
neighborChanged(level, x, y + 1, z, id);
} else {
level->setData(x, y, z, age + 1);
level->setData(x, y, z, age + 1, Tile::UPDATE_NONE);
}
}
}
@ -64,8 +65,7 @@ bool CactusTile::mayPlace(Level* level, int x, int y, int z) {
void CactusTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (!canSurvive(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->destroyTile(x, y, z, true);
}
}

View file

@ -93,10 +93,9 @@ void CakeTile::eat(Level* level, int x, int y, int z,
int d = level->getData(x, y, z) + 1;
if (d >= 6) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
} else {
level->setData(x, y, z, d);
level->setTileDirty(x, y, z);
level->setData(x, y, z, d, Tile::UPDATE_CLIENTS);
}
}
}
@ -109,8 +108,7 @@ bool CakeTile::mayPlace(Level* level, int x, int y, int z) {
void CakeTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (!canSurvive(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
}
@ -126,4 +124,4 @@ int CakeTile::getResource(int data, Random* random, int playerBonusLevel) {
int CakeTile::cloneTileId(Level* level, int x, int y, int z) {
return Item::cake_Id;
}
}

View file

@ -22,6 +22,7 @@ int CarrotTile::getBasePlantId() { return Item::carrots_Id; }
void CarrotTile::registerIcons(IconRegister* iconRegister) {
for (int i = 0; i < 4; i++) {
icons[i] = iconRegister->registerIcon(L"carrots_" + _toString(i));
icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" +
_toString(i));
}
}

View file

@ -11,7 +11,8 @@
const std::wstring CauldronTile::TEXTURE_INSIDE = L"cauldron_inner";
const std::wstring CauldronTile::TEXTURE_BOTTOM = L"cauldron_bottom";
CauldronTile::CauldronTile(int id) : Tile(id, Material::metal, false) {
CauldronTile::CauldronTile(int id)
: Tile(id, Material::metal, false) {
iconInner = NULL;
iconTop = NULL;
iconBottom = NULL;
@ -82,9 +83,10 @@ bool CauldronTile::use(Level* level, int x, int y, int z,
}
int currentData = level->getData(x, y, z);
int fillLevel = getFillLevel(currentData);
if (item->id == Item::bucket_water_Id) {
if (currentData < 3) {
if (fillLevel < 3) {
if (!player->abilities.instabuild) {
player->inventory->setItem(
player->inventory->selected,
@ -92,11 +94,12 @@ bool CauldronTile::use(Level* level, int x, int y, int z,
new ItemInstance(Item::bucket_empty)));
}
level->setData(x, y, z, 3);
level->setData(x, y, z, 3, Tile::UPDATE_CLIENTS);
level->updateNeighbourForOutputSignal(x, y, z, id);
}
return true;
} else if (item->id == Item::glassBottle_Id) {
if (currentData > 0) {
if (fillLevel > 0) {
std::shared_ptr<ItemInstance> potion =
std::shared_ptr<ItemInstance>(
new ItemInstance(Item::potion, 1, 0));
@ -106,7 +109,7 @@ bool CauldronTile::use(Level* level, int x, int y, int z,
}
// 4J Stu - Brought forward change to update inventory when filling
// bottles with water
else if (std::dynamic_pointer_cast<ServerPlayer>(player) != NULL) {
else if (player->instanceof(eTYPE_SERVERPLAYER)) {
std::dynamic_pointer_cast<ServerPlayer>(player)
->refreshContainer(player->inventoryMenu);
}
@ -118,13 +121,15 @@ bool CauldronTile::use(Level* level, int x, int y, int z,
nullptr);
}
}
level->setData(x, y, z, currentData - 1);
level->setData(x, y, z, fillLevel - 1, Tile::UPDATE_CLIENTS);
level->updateNeighbourForOutputSignal(x, y, z, id);
}
} else if (currentData > 0) {
} else if (fillLevel > 0) {
ArmorItem* armor = dynamic_cast<ArmorItem*>(item->getItem());
if (armor && armor->getMaterial() == ArmorItem::ArmorMaterial::CLOTH) {
armor->clearColor(item);
level->setData(x, y, z, currentData - 1);
level->setData(x, y, z, fillLevel - 1, Tile::UPDATE_CLIENTS);
level->updateNeighbourForOutputSignal(x, y, z, id);
return true;
}
}
@ -138,7 +143,7 @@ void CauldronTile::handleRain(Level* level, int x, int y, int z) {
int data = level->getData(x, y, z);
if (data < 3) {
level->setData(x, y, z, data + 1);
level->setData(x, y, z, data + 1, Tile::UPDATE_CLIENTS);
}
}
@ -149,3 +154,14 @@ int CauldronTile::getResource(int data, Random* random, int playerBonusLevel) {
int CauldronTile::cloneTileId(Level* level, int x, int y, int z) {
return Item::cauldron_Id;
}
bool CauldronTile::hasAnalogOutputSignal() { return true; }
int CauldronTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
int data = level->getData(x, y, z);
return getFillLevel(data);
}
int CauldronTile::getFillLevel(int data) { return data; }

View file

@ -33,4 +33,8 @@ public:
virtual void handleRain(Level* level, int x, int y, int z);
virtual int getResource(int data, Random* random, int playerBonusLevel);
virtual int cloneTileId(Level* level, int x, int y, int z);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
static int getFillLevel(int data);
};

View file

@ -2,16 +2,19 @@
#include "../Headers/net.minecraft.world.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.entity.animal.h"
#include "../Headers/net.minecraft.world.entity.player.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "ChestTile.h"
#include "../Util/Facing.h"
#include "../Entities/Mobs/Ocelot.h"
ChestTile::ChestTile(int id) : EntityTile(id, Material::wood, false) {
ChestTile::ChestTile(int id, int type)
: BaseEntityTile(id, Material::wood, false) {
random = new Random();
this->type = type;
setShape(1 / 16.0f, 0, 1 / 16.0f, 15 / 16.0f, 14 / 16.0f, 15 / 16.0f);
}
@ -41,7 +44,7 @@ void ChestTile::updateShape(LevelSource* level, int x, int y, int z,
}
void ChestTile::onPlace(Level* level, int x, int y, int z) {
EntityTile::onPlace(level, x, y, z);
BaseEntityTile::onPlace(level, x, y, z);
recalcLockDir(level, x, y, z);
int n = level->getTile(x, y, z - 1); // face = 2
@ -55,7 +58,8 @@ void ChestTile::onPlace(Level* level, int x, int y, int z) {
}
void ChestTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int n = level->getTile(x, y, z - 1); // face = 2
int s = level->getTile(x, y, z + 1); // face = 3
int w = level->getTile(x - 1, y, z); // face = 4
@ -70,25 +74,31 @@ void ChestTile::setPlacedBy(Level* level, int x, int y, int z,
if (dir == 3) facing = Facing::WEST;
if (n != id && s != id && w != id && e != id) {
level->setData(x, y, z, facing);
level->setData(x, y, z, facing, Tile::UPDATE_ALL);
} else {
if ((n == id || s == id) &&
(facing == Facing::WEST || facing == Facing::EAST)) {
if (n == id)
level->setData(x, y, z - 1, facing);
level->setData(x, y, z - 1, facing, Tile::UPDATE_ALL);
else
level->setData(x, y, z + 1, facing);
level->setData(x, y, z, facing);
level->setData(x, y, z + 1, facing, Tile::UPDATE_ALL);
level->setData(x, y, z, facing, Tile::UPDATE_ALL);
}
if ((w == id || e == id) &&
(facing == Facing::NORTH || facing == Facing::SOUTH)) {
if (w == id)
level->setData(x - 1, y, z, facing);
level->setData(x - 1, y, z, facing, Tile::UPDATE_ALL);
else
level->setData(x + 1, y, z, facing);
level->setData(x, y, z, facing);
level->setData(x + 1, y, z, facing, Tile::UPDATE_ALL);
level->setData(x, y, z, facing, Tile::UPDATE_ALL);
}
}
if (itemInstance->hasCustomHoverName()) {
std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x, y, z))
->setCustomName(itemInstance->getHoverName());
}
}
void ChestTile::recalcLockDir(Level* level, int x, int y, int z) {
@ -148,7 +158,7 @@ void ChestTile::recalcLockDir(Level* level, int x, int y, int z) {
if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4;
}
level->setData(x, y, z, lockDir);
level->setData(x, y, z, lockDir, Tile::UPDATE_ALL);
}
bool ChestTile::mayPlace(Level* level, int x, int y, int z) {
@ -178,7 +188,7 @@ bool ChestTile::isFullChest(Level* level, int x, int y, int z) {
}
void ChestTile::neighborChanged(Level* level, int x, int y, int z, int type) {
EntityTile::neighborChanged(level, x, y, z, type);
BaseEntityTile::neighborChanged(level, x, y, z, type);
std::shared_ptr<ChestTileEntity>(cte) =
std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x, y, z));
@ -225,8 +235,9 @@ void ChestTile::onRemove(Level* level, int x, int y, int z, int id, int data) {
container->setItem(i, nullptr);
}
}
level->updateNeighbourForOutputSignal(x, y, z, id);
}
EntityTile::onRemove(level, x, y, z, id, data);
BaseEntityTile::onRemove(level, x, y, z, id, data);
}
// 4J-PB - Adding a TestUse for tooltip display
@ -243,31 +254,41 @@ bool ChestTile::use(Level* level, int x, int y, int z,
if (level->isClientSide) {
return true;
}
std::shared_ptr<Container> container = getContainer(level, x, y, z);
if (container != NULL) {
player->openContainer(container);
}
return true;
}
std::shared_ptr<Container> ChestTile::getContainer(Level* level, int x, int y,
int z) {
std::shared_ptr<Container> container =
std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x, y, z));
if (container == NULL) return true;
if (container == NULL) return nullptr;
if (level->isSolidBlockingTile(x, y + 1, z)) return true;
if (isCatSittingOnChest(level, x, y, z)) return true;
if (level->isSolidBlockingTile(x, y + 1, z)) return nullptr;
if (isCatSittingOnChest(level, x, y, z)) return nullptr;
if (level->getTile(x - 1, y, z) == id &&
(level->isSolidBlockingTile(x - 1, y + 1, z) ||
isCatSittingOnChest(level, x - 1, y, z)))
return true;
return nullptr;
if (level->getTile(x + 1, y, z) == id &&
(level->isSolidBlockingTile(x + 1, y + 1, z) ||
isCatSittingOnChest(level, x + 1, y, z)))
return true;
return nullptr;
if (level->getTile(x, y, z - 1) == id &&
(level->isSolidBlockingTile(x, y + 1, z - 1) ||
isCatSittingOnChest(level, x, y, z - 1)))
return true;
return nullptr;
if (level->getTile(x, y, z + 1) == id &&
(level->isSolidBlockingTile(x, y + 1, z + 1) ||
isCatSittingOnChest(level, x, y, z + 1)))
return true;
return nullptr;
if (level->getTile(x - 1, y, z) == id)
container = std::shared_ptr<Container>(
@ -292,23 +313,7 @@ bool ChestTile::use(Level* level, int x, int y, int z,
std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x, y, z + 1))));
player->openContainer(container);
return true;
}
// 4J-PB - added from 1.5
bool ChestTile::isCatSittingOnChest(Level* level, int x, int y, int z) {
std::vector<std::shared_ptr<Entity> >* entities = level->getEntitiesOfClass(
typeid(Ozelot), AABB::newTemp(x, y + 1, z, x + 1, y + 2, z + 1));
for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) {
std::shared_ptr<Ozelot> ocelot = std::dynamic_pointer_cast<Ozelot>(*it);
if (ocelot->isSitting()) {
return true;
}
}
return false;
return container;
}
std::shared_ptr<TileEntity> ChestTile::newTileEntity(Level* level) {
@ -319,8 +324,50 @@ std::shared_ptr<TileEntity> ChestTile::newTileEntity(Level* level) {
return retval;
}
bool ChestTile::isSignalSource() { return type == TYPE_TRAP; }
int ChestTile::getSignal(LevelSource* level, int x, int y, int z, int dir) {
if (!isSignalSource()) return Redstone::SIGNAL_NONE;
int openCount = std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x, y, z))
->openCount;
return Mth::clamp(openCount, Redstone::SIGNAL_NONE, Redstone::SIGNAL_MAX);
}
int ChestTile::getDirectSignal(LevelSource* level, int x, int y, int z,
int dir) {
if (dir == Facing::UP) {
return getSignal(level, x, y, z, dir);
} else {
return Redstone::SIGNAL_NONE;
}
}
bool ChestTile::isCatSittingOnChest(Level* level, int x, int y, int z) {
std::vector<std::shared_ptr<Entity> >* entities = level->getEntitiesOfClass(
typeid(Ocelot), AABB::newTemp(x, y + 1, z, x + 1, y + 2, z + 1));
for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) {
std::shared_ptr<Ocelot> ocelot = std::dynamic_pointer_cast<Ocelot>(*it);
if (ocelot->isSitting()) {
delete entities;
return true;
}
}
delete entities;
return false;
}
bool ChestTile::hasAnalogOutputSignal() { return true; }
int ChestTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
return AbstractContainerMenu::getRedstoneSignalFromContainer(
getContainer(level, x, y, z));
}
void ChestTile::registerIcons(IconRegister* iconRegister) {
// Register wood as the chest's icon, because it's used by the particles
// when destroying the chest
icon = iconRegister->registerIcon(L"wood");
icon = iconRegister->registerIcon(L"planks_oak");
}

View file

@ -1,21 +1,28 @@
#pragma once
#include "TileEntities/EntityTile.h"
#include "BaseEntityTile.h"
#include "Material.h"
class Player;
class Random;
class ChestTile : public EntityTile {
class ChestTile : public BaseEntityTile {
friend class Tile;
friend class Minecraft;
public:
static const int TYPE_BASIC = 0;
static const int TYPE_TRAP = 1;
static const int EVENT_SET_OPEN_COUNT = 1;
private:
Random* random;
public:
int type;
protected:
ChestTile(int id);
ChestTile(int id, int type);
~ChestTile();
public:
@ -28,13 +35,13 @@ public:
std::shared_ptr<TileEntity>());
virtual void onPlace(Level* level, int x, int y, int z);
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
void recalcLockDir(Level* level, int x, int y, int z);
virtual bool mayPlace(Level* level, int x, int y, int z);
private:
bool isFullChest(Level* level, int x, int y, int z);
bool isCatSittingOnChest(Level* level, int x, int y, int z);
public:
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
@ -44,7 +51,20 @@ public:
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
std::shared_ptr<TileEntity> newTileEntity(Level* level);
//@Override
void registerIcons(IconRegister* iconRegister);
virtual std::shared_ptr<Container> getContainer(Level* level, int x, int y,
int z);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual bool isSignalSource();
virtual int getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual int getDirectSignal(LevelSource* level, int x, int y, int z,
int dir);
private:
bool isCatSittingOnChest(Level* level, int x, int y, int z);
public:
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -1,23 +0,0 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.h"
#include "ClothTile.h"
ClothTile::ClothTile() : Tile(35, Material::cloth) { icons = NULL; }
Icon* ClothTile::getTexture(int face, int data) { return icons[data]; }
int ClothTile::getSpawnResourcesAuxValue(int data) { return data; }
int ClothTile::getTileDataForItemAuxValue(int auxValue) {
return (~auxValue & 0xf);
}
int ClothTile::getItemAuxValueForTileData(int data) { return (~data & 0xf); }
void ClothTile::registerIcons(IconRegister* iconRegister) {
icons = new Icon*[16];
for (int i = 0; i < 16; i++) {
icons[i] = iconRegister->registerIcon(L"cloth_" + _toString(i));
}
}

View file

@ -9,7 +9,8 @@
const std::wstring CocoaTile::TEXTURE_AGES[] = {L"cocoa_0", L"cocoa_1",
L"cocoa_2"};
CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, false) {
CocoaTile::CocoaTile(int id)
: DirectionalTile(id, Material::plant, false) {
setTicking(true);
}
@ -25,13 +26,14 @@ Icon* CocoaTile::getTextureForAge(int age) {
void CocoaTile::tick(Level* level, int x, int y, int z, Random* random) {
if (!canSurvive(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->setTileAndData(x, y, z, 0, 0, UPDATE_CLIENTS);
} else if (level->random->nextInt(5) == 0) {
int data = level->getData(x, y, z);
int age = getAge(data);
if (age < 2) {
age++;
level->setData(x, y, z, (age << 2) | (getDirection(data)));
level->setData(x, y, z, (age << 2) | (getDirection(data)),
Tile::UPDATE_CLIENTS);
}
}
}
@ -101,10 +103,10 @@ void CocoaTile::updateShape(LevelSource* level, int x, int y, int z,
}
void CocoaTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3) + 0) % 4;
level->setData(x, y, z, dir);
level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS);
}
int CocoaTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
@ -119,7 +121,7 @@ int CocoaTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
void CocoaTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (!canSurvive(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->setTileAndData(x, y, z, 0, 0, UPDATE_CLIENTS);
}
}
@ -155,4 +157,4 @@ void CocoaTile::registerIcons(IconRegister* iconRegister) {
for (int i = 0; i < COCOA_TEXTURES_LENGTH; i++) {
icons[i] = iconRegister->registerIcon(TEXTURE_AGES[i]);
}
}
}

View file

@ -29,7 +29,7 @@ public:
std::shared_ptr<TileEntity> forceEntity =
std::shared_ptr<TileEntity>());
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
int face, float clickX, float clickY,

View file

@ -0,0 +1,26 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.h"
#include "../Headers/net.minecraft.world.item.h"
#include "ColoredTile.h"
ColoredTile::ColoredTile(int id, Material* material) : Tile(id, material) {}
Icon* ColoredTile::getTexture(int face, int data) {
return icons[data % ICON_COUNT];
}
int ColoredTile::getSpawnResourcesAuxValue(int data) { return data; }
int ColoredTile::getTileDataForItemAuxValue(int auxValue) {
return (~auxValue & 0xf);
}
int ColoredTile::getItemAuxValueForTileData(int data) { return (~data & 0xf); }
void ColoredTile::registerIcons(IconRegister* iconRegister) {
for (int i = 0; i < ICON_COUNT; i++) {
icons[i] = iconRegister->registerIcon(
getIconName() + L"_" +
DyePowderItem::COLOR_TEXTURES[getItemAuxValueForTileData(i)]);
}
}

View file

@ -1,25 +1,20 @@
#pragma once
#include "Tile.h"
#include "Material.h"
class ChunkRebuildData;
class ClothTile : public Tile {
class ColoredTile : public Tile {
friend class ChunkRebuildData;
private:
Icon** icons;
static const int ICON_COUNT = 16;
Icon* icons[ICON_COUNT];
public:
ClothTile();
virtual Icon* getTexture(int face, int data);
ColoredTile(int id, Material* material);
protected:
Icon* getTexture(int face, int data);
virtual int getSpawnResourcesAuxValue(int data);
public:
static int getTileDataForItemAuxValue(int auxValue);
static int getItemAuxValueForTileData(int data);
//@Override
void registerIcons(IconRegister* iconRegister);
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -0,0 +1,86 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "CommandBlock.h"
CommandBlock::CommandBlock(int id)
: BaseEntityTile(id, Material::metal, false) {}
std::shared_ptr<TileEntity> CommandBlock::newTileEntity(Level* level) {
return std::shared_ptr<CommandBlockEntity>(new CommandBlockEntity());
}
void CommandBlock::neighborChanged(Level* level, int x, int y, int z,
int type) {
if (!level->isClientSide) {
bool signal = level->hasNeighborSignal(x, y, z);
int data = level->getData(x, y, z);
bool isTriggered = (data & TRIGGER_BIT) != 0;
if (signal && !isTriggered) {
level->setData(x, y, z, data | TRIGGER_BIT, Tile::UPDATE_NONE);
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
} else if (!signal && isTriggered) {
level->setData(x, y, z, data & ~TRIGGER_BIT, Tile::UPDATE_NONE);
}
}
}
void CommandBlock::tick(Level* level, int x, int y, int z, Random* random) {
std::shared_ptr<TileEntity> tileEntity = level->getTileEntity(x, y, z);
if (tileEntity != NULL &&
std::dynamic_pointer_cast<CommandBlockEntity>(tileEntity) != NULL) {
std::shared_ptr<CommandBlockEntity> commandBlock =
std::dynamic_pointer_cast<CommandBlockEntity>(tileEntity);
commandBlock->setSuccessCount(commandBlock->performCommand(level));
level->updateNeighbourForOutputSignal(x, y, z, id);
}
}
int CommandBlock::getTickDelay(Level* level) { return 1; }
bool CommandBlock::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly) {
std::shared_ptr<CommandBlockEntity> amce =
std::dynamic_pointer_cast<CommandBlockEntity>(
level->getTileEntity(x, y, z));
if (amce != NULL) {
player->openTextEdit(amce);
}
return true;
}
bool CommandBlock::hasAnalogOutputSignal() { return true; }
int CommandBlock::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
std::shared_ptr<TileEntity> tileEntity = level->getTileEntity(x, y, z);
if (tileEntity != NULL &&
std::dynamic_pointer_cast<CommandBlockEntity>(tileEntity) != NULL) {
return std::dynamic_pointer_cast<CommandBlockEntity>(tileEntity)
->getSuccessCount();
}
return Redstone::SIGNAL_NONE;
}
void CommandBlock::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
std::shared_ptr<CommandBlockEntity> cblock =
std::dynamic_pointer_cast<CommandBlockEntity>(
level->getTileEntity(x, y, z));
if (itemInstance->hasCustomHoverName()) {
cblock->setName(itemInstance->getHoverName());
}
}
int CommandBlock::getResourceCount(Random* random) { return 0; }

View file

@ -0,0 +1,27 @@
#pragma once
#include "BaseEntityTile.h"
class CommandBlock : public BaseEntityTile {
private:
static const int TRIGGER_BIT = 1;
public:
CommandBlock(int id);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual int getTickDelay(Level* level);
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual int getResourceCount(Random* random);
};

View file

@ -0,0 +1,215 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.h"
#include "ComparatorTile.h"
ComparatorTile::ComparatorTile(int id, bool on) : DiodeTile(id, on) {
_isEntityTile = true;
}
int ComparatorTile::getResource(int data, Random* random,
int playerBonusLevel) {
return Item::comparator_Id;
}
int ComparatorTile::cloneTileId(Level* level, int x, int y, int z) {
return Item::comparator_Id;
}
int ComparatorTile::getTurnOnDelay(int data) { return 2; }
DiodeTile* ComparatorTile::getOnTile() { return Tile::comparator_on; }
DiodeTile* ComparatorTile::getOffTile() { return Tile::comparator_off; }
int ComparatorTile::getRenderShape() { return SHAPE_COMPARATOR; }
Icon* ComparatorTile::getTexture(int face, int data) {
bool isOn = on || (data & BIT_IS_LIT) != 0;
// down is used by the torch tesselator
if (face == Facing::DOWN) {
if (isOn) {
return Tile::redstoneTorch_on->getTexture(face);
}
return Tile::redstoneTorch_off->getTexture(face);
}
if (face == Facing::UP) {
if (isOn) {
return Tile::comparator_on->icon;
}
return icon;
}
// edge of stone half-step
return Tile::stoneSlab->getTexture(Facing::UP);
}
bool ComparatorTile::isOn(int data) { return on || (data & BIT_IS_LIT) != 0; }
int ComparatorTile::getOutputSignal(LevelSource* levelSource, int x, int y,
int z, int data) {
return getComparator(levelSource, x, y, z)->getOutputSignal();
}
int ComparatorTile::calculateOutputSignal(Level* level, int x, int y, int z,
int data) {
if (!isReversedOutputSignal(data)) {
return getInputSignal(level, x, y, z, data);
} else {
return std::max(getInputSignal(level, x, y, z, data) -
getAlternateSignal(level, x, y, z, data),
Redstone::SIGNAL_NONE);
}
}
bool ComparatorTile::isReversedOutputSignal(int data) {
return (data & BIT_OUTPUT_SUBTRACT) == BIT_OUTPUT_SUBTRACT;
}
bool ComparatorTile::shouldTurnOn(Level* level, int x, int y, int z, int data) {
int input = getInputSignal(level, x, y, z, data);
if (input >= Redstone::SIGNAL_MAX) return true;
if (input == Redstone::SIGNAL_NONE) return false;
int alt = getAlternateSignal(level, x, y, z, data);
if (alt == Redstone::SIGNAL_NONE) return true;
return input >= alt;
}
int ComparatorTile::getInputSignal(Level* level, int x, int y, int z,
int 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);
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]);
}
}
}
return result;
}
std::shared_ptr<ComparatorTileEntity> ComparatorTile::getComparator(
LevelSource* level, int x, int y, int z) {
return std::dynamic_pointer_cast<ComparatorTileEntity>(
level->getTileEntity(x, y, z));
}
bool ComparatorTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly) {
int data = level->getData(x, y, z);
bool isOn = on || ((data & BIT_IS_LIT) != 0);
bool subtract = !isReversedOutputSignal(data);
int outputBit = subtract ? BIT_OUTPUT_SUBTRACT : 0;
outputBit |= isOn ? BIT_IS_LIT : 0;
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_CLICK, 0.3f,
subtract ? 0.55f : 0.5f);
if (!soundOnly) {
level->setData(x, y, z, outputBit | (data & DIRECTION_MASK),
Tile::UPDATE_CLIENTS);
refreshOutputState(level, x, y, z, level->random);
}
return true;
}
void ComparatorTile::checkTickOnNeighbor(Level* level, int x, int y, int z,
int type) {
if (!level->isTileToBeTickedAt(x, y, z, id)) {
int data = level->getData(x, y, z);
int outputValue = calculateOutputSignal(level, x, y, z, data);
int oldValue = getComparator(level, x, y, z)->getOutputSignal();
if (outputValue != oldValue ||
(isOn(data) != shouldTurnOn(level, x, y, z, data))) {
// prioritize locking comparators
if (shouldPrioritize(level, x, y, z, data)) {
level->addToTickNextTick(x, y, z, id, getTurnOnDelay(0), -1);
} else {
level->addToTickNextTick(x, y, z, id, getTurnOnDelay(0), 0);
}
}
}
}
void ComparatorTile::refreshOutputState(Level* level, int x, int y, int z,
Random* random) {
int data = level->getData(x, y, z);
int outputValue = calculateOutputSignal(level, x, y, z, data);
int oldValue = getComparator(level, x, y, z)->getOutputSignal();
getComparator(level, x, y, z)->setOutputSignal(outputValue);
if (oldValue != outputValue || !isReversedOutputSignal(data)) {
bool sourceOn = shouldTurnOn(level, x, y, z, data);
bool isOn = on || (data & BIT_IS_LIT) != 0;
if (isOn && !sourceOn) {
level->setData(x, y, z, data & ~BIT_IS_LIT, Tile::UPDATE_CLIENTS);
} else if (!isOn && sourceOn) {
level->setData(x, y, z, data | BIT_IS_LIT, Tile::UPDATE_CLIENTS);
}
updateNeighborsInFront(level, x, y, z);
}
}
void ComparatorTile::tick(Level* level, int x, int y, int z, Random* random) {
if (on) {
// clean-up old tiles with the 'on' id
int data = level->getData(x, y, z);
level->setTileAndData(x, y, z, getOffTile()->id, data | BIT_IS_LIT,
Tile::UPDATE_NONE);
}
refreshOutputState(level, x, y, z, random);
}
void ComparatorTile::onPlace(Level* level, int x, int y, int z) {
DiodeTile::onPlace(level, x, y, z);
level->setTileEntity(x, y, z, newTileEntity(level));
}
void ComparatorTile::onRemove(Level* level, int x, int y, int z, int id,
int data) {
DiodeTile::onRemove(level, x, y, z, id, data);
level->removeTileEntity(x, y, z);
updateNeighborsInFront(level, x, y, z);
}
bool ComparatorTile::triggerEvent(Level* level, int x, int y, int z, int b0,
int b1) {
DiodeTile::triggerEvent(level, x, y, z, b0, b1);
std::shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
if (te != NULL) {
return te->triggerEvent(b0, b1);
}
return false;
}
std::shared_ptr<TileEntity> ComparatorTile::newTileEntity(Level* level) {
return std::shared_ptr<ComparatorTileEntity>(new ComparatorTileEntity());
}
bool ComparatorTile::TestUse() { return true; }

View file

@ -0,0 +1,68 @@
#pragma once
#include "DiodeTile.h"
#include "TileEntities/EntityTile.h"
class ComparatorTileEntity;
class ComparatorTile : public DiodeTile, public EntityTile {
private:
static const int BIT_OUTPUT_SUBTRACT = 0x4;
static const int BIT_IS_LIT = 0x8;
public:
ComparatorTile(int id, bool on);
virtual int getResource(int data, Random* random, int playerBonusLevel);
virtual int cloneTileId(Level* level, int x, int y, int z);
protected:
virtual int getTurnOnDelay(int data);
virtual DiodeTile* getOnTile();
virtual DiodeTile* getOffTile();
public:
virtual int getRenderShape();
virtual Icon* getTexture(int face, int data);
protected:
virtual bool isOn(int data);
virtual int getOutputSignal(LevelSource* levelSource, int x, int y, int z,
int data);
private:
virtual int calculateOutputSignal(Level* level, int x, int y, int z,
int data);
public:
virtual bool isReversedOutputSignal(int data);
protected:
virtual bool shouldTurnOn(Level* level, int x, int y, int z, int data);
virtual int getInputSignal(Level* level, int x, int y, int z, int data);
virtual std::shared_ptr<ComparatorTileEntity> getComparator(
LevelSource* level, int x, int y, int z);
public:
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false);
protected:
virtual void checkTickOnNeighbor(Level* level, int x, int y, int z,
int type);
private:
virtual void refreshOutputState(Level* level, int x, int y, int z,
Random* random);
public:
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual void onPlace(Level* level, int x, int y, int z);
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual bool triggerEvent(Level* level, int x, int y, int z, int b0,
int b1);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual bool TestUse();
};

View file

@ -33,14 +33,16 @@ void CropTile::tick(Level* level, int x, int y, int z, Random* random) {
if (random->nextInt((int)(25 / growthSpeed) + 1) == 0) {
age++;
level->setData(x, y, z, age);
level->setData(x, y, z, age, Tile::UPDATE_CLIENTS);
}
}
}
}
void CropTile::growCropsToMax(Level* level, int x, int y, int z) {
level->setData(x, y, z, 7);
void CropTile::growCrops(Level* level, int x, int y, int z) {
int stage = level->getData(x, y, z) + Mth::nextInt(level->random, 2, 5);
if (stage > 7) stage = 7;
level->setData(x, y, z, stage, Tile::UPDATE_CLIENTS);
}
float CropTile::getGrowthSpeed(Level* level, int x, int y, int z) {
@ -56,10 +58,9 @@ float CropTile::getGrowthSpeed(Level* level, int x, int y, int z) {
int d2 = level->getTile(x + 1, y, z + 1);
int d3 = level->getTile(x - 1, y, z + 1);
bool horizontal = w == this->id || e == this->id;
bool vertical = n == this->id || s == this->id;
bool diagonal =
d0 == this->id || d1 == this->id || d2 == this->id || d3 == this->id;
bool horizontal = w == id || e == id;
bool vertical = n == id || s == id;
bool diagonal = d0 == id || d1 == id || d2 == id || d3 == id;
for (int xx = x - 1; xx <= x + 1; xx++)
for (int zz = z - 1; zz <= z + 1; zz++) {

View file

@ -21,7 +21,7 @@ public:
// 4J Added override
virtual void updateDefaultShape();
virtual void tick(Level* level, int x, int y, int z, Random* random);
void growCropsToMax(Level* level, int x, int y, int z);
virtual void growCrops(Level* level, int x, int y, int z);
private:
float getGrowthSpeed(Level* level, int x, int y, int z);

View file

@ -0,0 +1,96 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.level.dimension.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.world.h"
#include "../Util/JavaMath.h"
#include "DaylightDetectorTile.h"
DaylightDetectorTile::DaylightDetectorTile(int id)
: BaseEntityTile(id, Material::wood, false) {
updateDefaultShape();
}
void DaylightDetectorTile::updateDefaultShape() {
setShape(0, 0, 0, 1, 6.0f / 16.0f, 1);
}
void DaylightDetectorTile::updateShape(
LevelSource* level, int x, int y, int z, int forceData,
std::shared_ptr<TileEntity> forceEntity) {
setShape(0, 0, 0, 1, 6.0f / 16.0f, 1);
}
int DaylightDetectorTile::getSignal(LevelSource* level, int x, int y, int z,
int dir) {
return level->getData(x, y, z);
}
void DaylightDetectorTile::tick(Level* level, int x, int y, int z,
Random* random) {
// updateSignalStrength(level, x, y, z);
}
void DaylightDetectorTile::neighborChanged(Level* level, int x, int y, int z,
int type) {
// level.addToTickNextTick(x, y, z, id, getTickDelay());
}
void DaylightDetectorTile::onPlace(Level* level, int x, int y, int z) {
// level.addToTickNextTick(x, y, z, id, getTickDelay());
}
void DaylightDetectorTile::updateSignalStrength(Level* level, int x, int y,
int z) {
if (level->dimension->hasCeiling) return;
int current = level->getData(x, y, z);
int target =
level->getBrightness(LightLayer::Sky, x, y, z) - level->skyDarken;
float sunAngle = level->getSunAngle(1);
// tilt sunAngle towards zenith (to make the transition to night
// smoother)
if (sunAngle < PI) {
sunAngle = sunAngle + (0 - sunAngle) * .2f;
} else {
sunAngle = sunAngle + (PI * 2.0f - sunAngle) * .2f;
}
target = Math::round((float)target * Mth::cos(sunAngle));
if (target < 0) {
target = 0;
}
if (target > Redstone::SIGNAL_MAX) {
target = Redstone::SIGNAL_MAX;
}
if (current != target) {
level->setData(x, y, z, target, UPDATE_ALL);
}
}
bool DaylightDetectorTile::isCubeShaped() { return false; }
bool DaylightDetectorTile::isSolidRender(bool isServerLevel) { return false; }
bool DaylightDetectorTile::isSignalSource() { return true; }
std::shared_ptr<TileEntity> DaylightDetectorTile::newTileEntity(Level* level) {
return std::shared_ptr<DaylightDetectorTileEntity>(
new DaylightDetectorTileEntity());
}
Icon* DaylightDetectorTile::getTexture(int face, int data) {
if (face == Facing::UP) {
return icons[0];
}
return icons[1];
}
void DaylightDetectorTile::registerIcons(IconRegister* iconRegister) {
icons[0] = iconRegister->registerIcon(getIconName() + L"_top");
icons[1] = iconRegister->registerIcon(getIconName() + L"_side");
}

View file

@ -0,0 +1,30 @@
#pragma once
#include "BaseEntityTile.h"
class DaylightDetectorTile : public BaseEntityTile {
friend class ChunkRebuildData;
private:
Icon* icons[2];
public:
DaylightDetectorTile(int id);
virtual void updateDefaultShape(); // 4J Added override
virtual void updateShape(LevelSource* level, int x, int y, int z,
int forceData = -1,
std::shared_ptr<TileEntity> forceEntity =
std::shared_ptr<TileEntity>());
virtual int getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
virtual void onPlace(Level* level, int x, int y, int z);
virtual void updateSignalStrength(Level* level, int x, int y, int z);
virtual bool isCubeShaped();
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool isSignalSource();
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual Icon* getTexture(int face, int data);
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -1,5 +1,7 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.inventory.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.phys.h"
@ -7,12 +9,12 @@
#include "DetectorRailTile.h"
#include "../Headers/net.minecraft.h"
DetectorRailTile::DetectorRailTile(int id) : RailTile(id, true) {
DetectorRailTile::DetectorRailTile(int id) : BaseRailTile(id, true) {
setTicking(true);
icons = NULL;
}
int DetectorRailTile::getTickDelay() { return 20; }
int DetectorRailTile::getTickDelay(Level* level) { return 20; }
bool DetectorRailTile::isSignalSource() { return true; }
@ -41,15 +43,19 @@ void DetectorRailTile::tick(Level* level, int x, int y, int z, Random* random) {
checkPressed(level, x, y, z, data);
}
bool DetectorRailTile::getSignal(LevelSource* level, int x, int y, int z,
int dir) {
return (level->getData(x, y, z) & RAIL_DATA_BIT) != 0;
int DetectorRailTile::getSignal(LevelSource* level, int x, int y, int z,
int dir) {
return (level->getData(x, y, z) & RAIL_DATA_BIT) != 0
? Redstone::SIGNAL_MAX
: Redstone::SIGNAL_NONE;
}
bool DetectorRailTile::getDirectSignal(Level* level, int x, int y, int z,
int facing) {
if ((level->getData(x, y, z) & RAIL_DATA_BIT) == 0) return false;
return (facing == Facing::UP);
int DetectorRailTile::getDirectSignal(LevelSource* level, int x, int y, int z,
int facing) {
if ((level->getData(x, y, z) & RAIL_DATA_BIT) == 0)
return Redstone::SIGNAL_NONE;
return (facing == Facing::UP) ? Redstone::SIGNAL_MAX
: Redstone::SIGNAL_NONE;
}
void DetectorRailTile::checkPressed(Level* level, int x, int y, int z,
@ -66,25 +72,56 @@ void DetectorRailTile::checkPressed(Level* level, int x, int y, int z,
}
if (shouldBePressed && !wasPressed) {
level->setData(x, y, z, currentData | RAIL_DATA_BIT);
level->setData(x, y, z, currentData | RAIL_DATA_BIT, Tile::UPDATE_ALL);
level->updateNeighborsAt(x, y, z, id);
level->updateNeighborsAt(x, y - 1, z, id);
level->setTilesDirty(x, y, z, x, y, z);
}
if (!shouldBePressed && wasPressed) {
level->setData(x, y, z, currentData & RAIL_DIRECTION_MASK);
level->setData(x, y, z, currentData & RAIL_DIRECTION_MASK,
Tile::UPDATE_ALL);
level->updateNeighborsAt(x, y, z, id);
level->updateNeighborsAt(x, y - 1, z, id);
level->setTilesDirty(x, y, z, x, y, z);
}
if (shouldBePressed) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
level->updateNeighbourForOutputSignal(x, y, z, id);
delete entities;
}
void DetectorRailTile::onPlace(Level* level, int x, int y, int z) {
BaseRailTile::onPlace(level, x, y, z);
checkPressed(level, x, y, z, level->getData(x, y, z));
}
bool DetectorRailTile::hasAnalogOutputSignal() { return true; }
int DetectorRailTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
if ((level->getData(x, y, z) & RAIL_DATA_BIT) > 0) {
float b = 2 / 16.0f;
std::vector<std::shared_ptr<Entity> >* entities =
level->getEntitiesOfClass(
typeid(Minecart),
AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 1 - b, z + 1 - b),
EntitySelector::CONTAINER_ENTITY_SELECTOR);
if (entities->size() > 0) {
std::shared_ptr<Entity> out = entities->at(0);
delete entities;
return AbstractContainerMenu::getRedstoneSignalFromContainer(
std::dynamic_pointer_cast<Container>(out));
}
}
return Redstone::SIGNAL_NONE;
}
void DetectorRailTile::registerIcons(IconRegister* iconRegister) {
icons = new Icon*[2];
icons[0] = iconRegister->registerIcon(L"detectorRail");

View file

@ -1,12 +1,12 @@
#pragma once
#include "RailTile.h"
#include "BaseRailTile.h"
class Entity;
class Random;
class Level;
class ChunkRebuildData;
class DetectorRailTile : public RailTile {
class DetectorRailTile : public BaseRailTile {
friend class ChunkRebuildData;
private:
@ -14,13 +14,18 @@ private:
public:
DetectorRailTile(int id);
virtual int getTickDelay();
virtual int getTickDelay(Level* level);
virtual bool isSignalSource();
virtual void entityInside(Level* level, int x, int y, int z,
std::shared_ptr<Entity> entity);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual bool getDirectSignal(Level* level, int x, int y, int z, int facing);
virtual int getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual int getDirectSignal(LevelSource* level, int x, int y, int z,
int facing);
virtual void onPlace(Level* level, int x, int y, int z);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
private:
virtual void checkPressed(Level* level, int x, int y, int z,

View file

@ -1,15 +1,13 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "../Headers/net.minecraft.world.h"
#include "DiodeTile.h"
const double DiodeTile::DELAY_RENDER_OFFSETS[4] = {-1.0f / 16.0f, 1.0f / 16.0f,
3.0f / 16.0f, 5.0f / 16.0f};
const int DiodeTile::DELAYS[4] = {1, 2, 3, 4};
DiodeTile::DiodeTile(int id, bool on)
: DirectionalTile(id, Material::decoration, false) {
this->on = on;
@ -37,17 +35,20 @@ bool DiodeTile::canSurvive(Level* level, int x, int y, int z) {
void DiodeTile::tick(Level* level, int x, int y, int z, Random* random) {
int data = level->getData(x, y, z);
bool sourceOn = getSourceSignal(level, x, y, z, data);
if (on && !sourceOn) {
level->setTileAndData(x, y, z, Tile::diode_off_Id, data);
} else if (!on) {
// when off-diodes are ticked, they always turn on for one tick and
// then off again if necessary
level->setTileAndData(x, y, z, Tile::diode_on_Id, data);
if (!sourceOn) {
int delay = (data & DELAY_MASK) >> DELAY_SHIFT;
level->addToTickNextTick(x, y, z, Tile::diode_on_Id,
DELAYS[delay] * 2);
if (!isLocked(level, x, y, z, data)) {
bool sourceOn = shouldTurnOn(level, x, y, z, data);
if (on && !sourceOn) {
level->setTileAndData(x, y, z, getOffTile()->id, data,
Tile::UPDATE_CLIENTS);
} else if (!on) {
// when off-diodes are ticked, they always turn on for one tick and
// then off again if necessary
level->setTileAndData(x, y, z, getOnTile()->id, data,
Tile::UPDATE_CLIENTS);
if (!sourceOn) {
level->addToTickNextTick(x, y, z, getOnTile()->id,
getTurnOffDelay(data), -1);
}
}
}
}
@ -56,9 +57,9 @@ Icon* DiodeTile::getTexture(int face, int data) {
// down is used by the torch tesselator
if (face == Facing::DOWN) {
if (on) {
return Tile::notGate_on->getTexture(face);
return Tile::redstoneTorch_on->getTexture(face);
}
return Tile::notGate_off->getTexture(face);
return Tile::redstoneTorch_off->getTexture(face);
}
if (face == Facing::UP) {
return icon;
@ -67,10 +68,6 @@ Icon* DiodeTile::getTexture(int face, int data) {
return Tile::stoneSlab->getTexture(Facing::UP);
}
void DiodeTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(on ? L"repeater_lit" : L"repeater");
}
bool DiodeTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
if (face == Facing::DOWN || face == Facing::UP) {
@ -82,29 +79,37 @@ bool DiodeTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int DiodeTile::getRenderShape() { return SHAPE_DIODE; }
bool DiodeTile::getDirectSignal(Level* level, int x, int y, int z, int dir) {
bool DiodeTile::isOn(int data) { return on; }
int DiodeTile::getDirectSignal(LevelSource* level, int x, int y, int z,
int dir) {
return getSignal(level, x, y, z, dir);
}
bool DiodeTile::getSignal(LevelSource* level, int x, int y, int z, int facing) {
if (!on) {
return false;
int DiodeTile::getSignal(LevelSource* level, int x, int y, int z, int facing) {
int data = level->getData(x, y, z);
if (!isOn(data)) {
return Redstone::SIGNAL_NONE;
}
int dir = getDirection(level->getData(x, y, z));
int dir = getDirection(data);
if (dir == Direction::SOUTH && facing == Facing::SOUTH) return true;
if (dir == Direction::WEST && facing == Facing::WEST) return true;
if (dir == Direction::NORTH && facing == Facing::NORTH) return true;
if (dir == Direction::EAST && facing == Facing::EAST) return true;
if (dir == Direction::SOUTH && facing == Facing::SOUTH)
return getOutputSignal(level, x, y, z, data);
if (dir == Direction::WEST && facing == Facing::WEST)
return getOutputSignal(level, x, y, z, data);
if (dir == Direction::NORTH && facing == Facing::NORTH)
return getOutputSignal(level, x, y, z, data);
if (dir == Direction::EAST && facing == Facing::EAST)
return getOutputSignal(level, x, y, z, data);
return false;
return Redstone::SIGNAL_NONE;
}
void DiodeTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (!canSurvive(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
level->updateNeighborsAt(x + 1, y, z, id);
level->updateNeighborsAt(x - 1, y, z, id);
level->updateNeighborsAt(x, y, z + 1, id);
@ -114,76 +119,125 @@ void DiodeTile::neighborChanged(Level* level, int x, int y, int z, int type) {
return;
}
checkTickOnNeighbor(level, x, y, z, type);
}
void DiodeTile::checkTickOnNeighbor(Level* level, int x, int y, int z,
int type) {
int data = level->getData(x, y, z);
bool sourceOn = getSourceSignal(level, x, y, z, data);
int delay = (data & DELAY_MASK) >> DELAY_SHIFT;
if ((on && !sourceOn) || (!on && sourceOn)) {
level->addToTickNextTick(x, y, z, id, DELAYS[delay] * 2);
if (!isLocked(level, x, y, z, data)) {
bool sourceOn = shouldTurnOn(level, x, y, z, data);
if ((on && !sourceOn || !on && sourceOn) &&
!level->isTileToBeTickedAt(x, y, z, id)) {
int prio = -1;
// if the tile in front is a repeater, we prioritize this update
if (shouldPrioritize(level, x, y, z, data)) {
prio = -3;
} else if (on) {
prio = -2;
}
level->addToTickNextTick(x, y, z, id, getTurnOnDelay(data), prio);
}
}
}
bool DiodeTile::getSourceSignal(Level* level, int x, int y, int z, int data) {
int dir = getDirection(data);
switch (dir) {
case Direction::SOUTH:
return level->getSignal(x, y, z + 1, Facing::SOUTH) ||
(level->getTile(x, y, z + 1) == Tile::redStoneDust_Id &&
level->getData(x, y, z + 1) > 0);
case Direction::NORTH:
return level->getSignal(x, y, z - 1, Facing::NORTH) ||
(level->getTile(x, y, z - 1) == Tile::redStoneDust_Id &&
level->getData(x, y, z - 1) > 0);
case Direction::EAST:
return level->getSignal(x + 1, y, z, Facing::EAST) ||
(level->getTile(x + 1, y, z) == Tile::redStoneDust_Id &&
level->getData(x + 1, y, z) > 0);
case Direction::WEST:
return level->getSignal(x - 1, y, z, Facing::WEST) ||
(level->getTile(x - 1, y, z) == Tile::redStoneDust_Id &&
level->getData(x - 1, y, z) > 0);
}
bool DiodeTile::isLocked(LevelSource* level, int x, int y, int z, int data) {
return false;
}
// 4J-PB - Adding a TestUse for tooltip display
bool DiodeTile::TestUse() { return true; }
bool DiodeTile::shouldTurnOn(Level* level, int x, int y, int z, int data) {
return getInputSignal(level, x, y, z, data) > Redstone::SIGNAL_NONE;
}
bool DiodeTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly /*=false*/) // 4J added soundOnly param
{
if (soundOnly) return false;
int DiodeTile::getInputSignal(Level* level, int x, int y, int z, int data) {
int dir = getDirection(data);
int data = level->getData(x, y, z);
int delay = (data & DELAY_MASK) >> DELAY_SHIFT;
delay = ((delay + 1) << DELAY_SHIFT) & DELAY_MASK;
int xx = x + Direction::STEP_X[dir];
int zz = z + Direction::STEP_Z[dir];
int input = level->getSignal(xx, y, zz, Direction::DIRECTION_FACING[dir]);
level->setData(x, y, z, delay | (data & DIRECTION_MASK));
return true;
if (input >= Redstone::SIGNAL_MAX) return input;
return std::max(input, level->getTile(xx, y, zz) == Tile::redStoneDust_Id
? level->getData(xx, y, zz)
: Redstone::SIGNAL_NONE);
}
int DiodeTile::getAlternateSignal(LevelSource* level, int x, int y, int z,
int data) {
int dir = getDirection(data);
switch (dir) {
case Direction::SOUTH:
case Direction::NORTH:
return std::max(
getAlternateSignalAt(level, x - 1, y, z, Facing::WEST),
getAlternateSignalAt(level, x + 1, y, z, Facing::EAST));
case Direction::EAST:
case Direction::WEST:
return std::max(
getAlternateSignalAt(level, x, y, z + 1, Facing::SOUTH),
getAlternateSignalAt(level, x, y, z - 1, Facing::NORTH));
}
return Redstone::SIGNAL_NONE;
}
int DiodeTile::getAlternateSignalAt(LevelSource* level, int x, int y, int z,
int facing) {
int tile = level->getTile(x, y, z);
if (isAlternateInput(tile)) {
if (tile == Tile::redStoneDust_Id) {
return level->getData(x, y, z);
} else {
return level->getDirectSignal(x, y, z, facing);
}
}
return Redstone::SIGNAL_NONE;
}
bool DiodeTile::isSignalSource() { return true; }
void DiodeTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3) + 2) % 4;
level->setData(x, y, z, dir);
level->setData(x, y, z, dir, Tile::UPDATE_ALL);
bool sourceOn = getSourceSignal(level, x, y, z, dir);
bool sourceOn = shouldTurnOn(level, x, y, z, dir);
if (sourceOn) {
level->addToTickNextTick(x, y, z, id, 1);
}
}
void DiodeTile::onPlace(Level* level, int x, int y, int z) {
level->updateNeighborsAt(x + 1, y, z, id);
level->updateNeighborsAt(x - 1, y, z, id);
level->updateNeighborsAt(x, y, z + 1, id);
level->updateNeighborsAt(x, y, z - 1, id);
level->updateNeighborsAt(x, y - 1, z, id);
level->updateNeighborsAt(x, y + 1, z, id);
updateNeighborsInFront(level, x, y, z);
}
void DiodeTile::updateNeighborsInFront(Level* level, int x, int y, int z) {
int dir = getDirection(level->getData(x, y, z));
if (dir == Direction::WEST) {
level->neighborChanged(x + 1, y, z, id);
level->updateNeighborsAtExceptFromFacing(x + 1, y, z, id, Facing::WEST);
}
if (dir == Direction::EAST) {
level->neighborChanged(x - 1, y, z, id);
level->updateNeighborsAtExceptFromFacing(x - 1, y, z, id, Facing::EAST);
}
if (dir == Direction::NORTH) {
level->neighborChanged(x, y, z + 1, id);
level->updateNeighborsAtExceptFromFacing(x, y, z + 1, id,
Facing::NORTH);
}
if (dir == Direction::SOUTH) {
level->neighborChanged(x, y, z - 1, id);
level->updateNeighborsAtExceptFromFacing(x, y, z - 1, id,
Facing::SOUTH);
}
}
void DiodeTile::destroy(Level* level, int x, int y, int z, int data) {
@ -200,60 +254,37 @@ void DiodeTile::destroy(Level* level, int x, int y, int z, int data) {
bool DiodeTile::isSolidRender(bool isServerLevel) { return false; }
int DiodeTile::getResource(int data, Random* random, int playerBonusLevel) {
return Item::diode->id;
bool DiodeTile::isAlternateInput(int tile) {
Tile* tt = Tile::tiles[tile];
return tt != NULL && tt->isSignalSource();
}
void DiodeTile::animateTick(Level* level, int xt, int yt, int zt,
Random* random) {
if (!on) return;
int data = level->getData(xt, yt, zt);
int DiodeTile::getOutputSignal(LevelSource* level, int x, int y, int z,
int data) {
return Redstone::SIGNAL_MAX;
}
bool DiodeTile::isDiode(int id) {
return Tile::diode_off->isSameDiode(id) ||
Tile::comparator_off->isSameDiode(id);
}
bool DiodeTile::isSameDiode(int id) {
return id == getOnTile()->id || id == getOffTile()->id;
}
bool DiodeTile::shouldPrioritize(Level* level, int x, int y, int z, int data) {
int dir = getDirection(data);
double x = xt + 0.5f + (random->nextFloat() - 0.5f) * 0.2;
double y = yt + 0.4f + (random->nextFloat() - 0.5f) * 0.2;
double z = zt + 0.5f + (random->nextFloat() - 0.5f) * 0.2;
double xo = 0;
double zo = 0;
if (random->nextInt(2) == 0) {
// spawn on receiver
switch (dir) {
case Direction::SOUTH:
zo = -5.0f / 16.0f;
break;
case Direction::NORTH:
zo = 5.0f / 16.0f;
break;
case Direction::EAST:
xo = -5.0f / 16.0f;
break;
case Direction::WEST:
xo = 5.0f / 16.0f;
break;
}
} else {
// spawn on transmitter
int delay = (data & DELAY_MASK) >> DELAY_SHIFT;
switch (dir) {
case Direction::SOUTH:
zo = DiodeTile::DELAY_RENDER_OFFSETS[delay];
break;
case Direction::NORTH:
zo = -DiodeTile::DELAY_RENDER_OFFSETS[delay];
break;
case Direction::EAST:
xo = DiodeTile::DELAY_RENDER_OFFSETS[delay];
break;
case Direction::WEST:
xo = -DiodeTile::DELAY_RENDER_OFFSETS[delay];
break;
}
if (isDiode(level->getTile(x - Direction::STEP_X[dir], y,
z - Direction::STEP_Z[dir]))) {
int odata = level->getData(x - Direction::STEP_X[dir], y,
z - Direction::STEP_Z[dir]);
int odir = getDirection(odata);
return odir != dir;
}
level->addParticle(eParticleType_reddust, x + xo, y, z + zo, 0, 0, 0);
return false;
}
int DiodeTile::cloneTileId(Level* level, int x, int y, int z) {
return Item::diode_Id;
}
int DiodeTile::getTurnOffDelay(int data) { return getTurnOnDelay(data); }
bool DiodeTile::isMatching(int id) { return isSameDiode(id); }

View file

@ -8,14 +8,7 @@ class Level;
class DiodeTile : public DirectionalTile {
friend class Tile;
public:
static const int DELAY_MASK = DIRECTION_INV_MASK;
static const int DELAY_SHIFT = 2;
static const double DELAY_RENDER_OFFSETS[4];
static const int DELAYS[4];
private:
protected:
bool on;
protected:
@ -28,32 +21,67 @@ public:
virtual bool canSurvive(Level* level, int x, int y, int z);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual Icon* getTexture(int face, int data);
//@Override
void registerIcons(IconRegister* iconRegister);
virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z,
int face);
virtual int getRenderShape();
virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir);
virtual bool getSignal(LevelSource* level, int x, int y, int z, int facing);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
private:
virtual bool getSourceSignal(Level* level, int x, int y, int z, int data);
protected:
virtual bool isOn(int data);
public:
virtual int getDirectSignal(LevelSource* level, int x, int y, int z,
int dir);
virtual int getSignal(LevelSource* level, int x, int y, int z, int facing);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
protected:
virtual void checkTickOnNeighbor(Level* level, int x, int y, int z,
int type);
public:
virtual bool isLocked(LevelSource* level, int x, int y, int z, int data);
protected:
virtual bool shouldTurnOn(Level* level, int x, int y, int z, int data);
virtual int getInputSignal(Level* level, int x, int y, int z, int data);
virtual int getAlternateSignal(LevelSource* level, int x, int y, int z,
int data);
virtual int getAlternateSignalAt(LevelSource* level, int x, int y, int z,
int facing);
public:
virtual bool TestUse();
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
virtual bool isSignalSource();
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual void onPlace(Level* level, int x, int y, int z);
protected:
virtual void updateNeighborsInFront(Level* level, int x, int y, int z);
public:
virtual void destroy(Level* level, int x, int y, int z, int data);
virtual bool isSolidRender(bool isServerLevel = false);
virtual int getResource(int data, Random* random, int playerBonusLevel);
virtual void animateTick(Level* level, int xt, int yt, int zt,
Random* random);
virtual int cloneTileId(Level* level, int x, int y, int z);
virtual int getResource(int data, Random* random, int playerBonusLevel) = 0;
virtual int cloneTileId(Level* level, int x, int y, int z) = 0;
protected:
virtual bool isAlternateInput(int tile);
virtual int getOutputSignal(LevelSource* level, int x, int y, int z,
int data);
public:
static bool isDiode(int id);
virtual bool isSameDiode(int id);
virtual bool shouldPrioritize(Level* level, int x, int y, int z, int data);
protected:
virtual int getTurnOffDelay(int data);
virtual int getTurnOnDelay(int data) = 0;
virtual DiodeTile* getOnTile() = 0;
virtual DiodeTile* getOffTile() = 0;
public:
virtual bool isMatching(int id);
};

View file

@ -2,9 +2,6 @@
#include "DirectionalTile.h"
DirectionalTile::DirectionalTile(int id, Material* material)
: Tile(id, material) {}
DirectionalTile::DirectionalTile(int id, Material* material, bool isSolidRender)
: Tile(id, material, isSolidRender) {}

View file

@ -8,7 +8,6 @@ public:
static const int DIRECTION_INV_MASK = 0xC;
protected:
DirectionalTile(int id, Material* material);
DirectionalTile(int id, Material* material, bool isSolidRender);
public:

View file

@ -3,6 +3,7 @@
#include "../Headers/net.minecraft.world.entity.player.h"
#include "../Headers/net.minecraft.world.entity.projectile.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.inventory.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
@ -11,7 +12,10 @@
#include "../Headers/net.minecraft.h"
#include "../Entities/Mob.h"
DispenserTile::DispenserTile(int id) : EntityTile(id, Material::stone) {
BehaviorRegistry DispenserTile::REGISTRY =
BehaviorRegistry(new DefaultDispenseItemBehavior());
DispenserTile::DispenserTile(int id) : BaseEntityTile(id, Material::stone) {
random = new Random();
iconTop = NULL;
@ -19,14 +23,10 @@ DispenserTile::DispenserTile(int id) : EntityTile(id, Material::stone) {
iconFrontVertical = NULL;
}
int DispenserTile::getTickDelay() { return 4; }
int DispenserTile::getResource(int data, Random* random, int playerBonusLevel) {
return Tile::dispenser_Id;
}
int DispenserTile::getTickDelay(Level* level) { return 4; }
void DispenserTile::onPlace(Level* level, int x, int y, int z) {
EntityTile::onPlace(level, x, y, z);
BaseEntityTile::onPlace(level, x, y, z);
recalcLockDir(level, x, y, z);
}
@ -45,7 +45,7 @@ void DispenserTile::recalcLockDir(Level* level, int x, int y, int z) {
if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2;
if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5;
if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4;
level->setData(x, y, z, lockDir);
level->setData(x, y, z, lockDir, Tile::UPDATE_CLIENTS);
}
Icon* DispenserTile::getTexture(int face, int data) {
@ -97,68 +97,53 @@ bool DispenserTile::use(Level* level, int x, int y, int z,
return true;
}
void DispenserTile::fireArrow(Level* level, int x, int y, int z,
Random* random) {
const int lockDir = level->getData(x, y, z);
// const float power = 1.1f;
const int accuracy = 6;
// bool bLaunched=true;
int xd = 0, zd = 0;
if (lockDir == Facing::SOUTH) {
zd = 1;
} else if (lockDir == Facing::NORTH) {
zd = -1;
} else if (lockDir == Facing::EAST) {
xd = 1;
} else {
xd = -1;
}
void DispenserTile::dispenseFrom(Level* level, int x, int y, int z) {
BlockSourceImpl source(level, x, y, z);
std::shared_ptr<DispenserTileEntity> trap =
std::dynamic_pointer_cast<DispenserTileEntity>(
level->getTileEntity(x, y, z));
if (trap != NULL) {
int slot = trap->getRandomSlot();
std::dynamic_pointer_cast<DispenserTileEntity>(source.getEntity());
if (trap == NULL) return;
if (slot < 0) {
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
} else {
double xp = x + xd * 0.6 + 0.5;
double yp = y + 0.5;
double zp = z + zd * 0.6 + 0.5;
std::shared_ptr<ItemInstance> item = trap->getItem(slot);
int result = dispenseItem(trap, level, item, random, x, y, z, xd,
zd, xp, yp, zp);
if (result == REMOVE_ITEM) {
trap->removeItem(slot, 1);
} else if (result == DISPENSE_ITEM) {
item = trap->removeItem(slot, 1);
throwItem(level, item, random, accuracy, xd, zd, xp, yp, zp);
level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0);
}
int slot = trap->getRandomSlot();
if (slot < 0) {
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
} else {
std::shared_ptr<ItemInstance> item = trap->getItem(slot);
DispenseItemBehavior* behavior = getDispenseMethod(item);
level->levelEvent(LevelEvent::PARTICLES_SHOOT, x, y, z,
(xd + 1) + (zd + 1) * 3);
if (behavior != DispenseItemBehavior::NOOP) {
std::shared_ptr<ItemInstance> leftOver =
behavior->dispense(&source, item);
trap->setItem(slot, leftOver->count == 0 ? nullptr : leftOver);
}
}
}
DispenseItemBehavior* DispenserTile::getDispenseMethod(
std::shared_ptr<ItemInstance> item) {
return REGISTRY.get(item->getItem());
}
void DispenserTile::neighborChanged(Level* level, int x, int y, int z,
int type) {
if (type > 0 && Tile::tiles[type]->isSignalSource()) {
bool signal = level->hasNeighborSignal(x, y, z) ||
level->hasNeighborSignal(x, y + 1, z);
if (signal) {
level->addToTickNextTick(x, y, z, this->id, getTickDelay());
}
bool signal = level->hasNeighborSignal(x, y, z) ||
level->hasNeighborSignal(x, y + 1, z);
int data = level->getData(x, y, z);
bool isTriggered = (data & TRIGGER_BIT) != 0;
if (signal && !isTriggered) {
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
level->setData(x, y, z, data | TRIGGER_BIT, UPDATE_NONE);
} else if (!signal && isTriggered) {
level->setData(x, y, z, data & ~TRIGGER_BIT, UPDATE_NONE);
}
}
void DispenserTile::tick(Level* level, int x, int y, int z, Random* random) {
if (!level->isClientSide && (level->hasNeighborSignal(x, y, z) ||
level->hasNeighborSignal(x, y + 1, z))) {
fireArrow(level, x, y, z, random);
if (!level->isClientSide) // && (level.hasNeighborSignal(x, y, z) ||
// level.hasNeighborSignal(x, y + 1, z)))
{
dispenseFrom(level, x, y, z);
}
}
@ -167,13 +152,17 @@ std::shared_ptr<TileEntity> DispenserTile::newTileEntity(Level* level) {
}
void DispenserTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3;
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = PistonBaseTile::getNewFacing(level, x, y, z, by);
if (dir == 0) level->setData(x, y, z, Facing::NORTH);
if (dir == 1) level->setData(x, y, z, Facing::EAST);
if (dir == 2) level->setData(x, y, z, Facing::SOUTH);
if (dir == 3) level->setData(x, y, z, Facing::WEST);
level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS);
if (itemInstance->hasCustomHoverName()) {
std::dynamic_pointer_cast<DispenserTileEntity>(
level->getTileEntity(x, y, z))
->setCustomName(itemInstance->getHoverName());
}
}
void DispenserTile::onRemove(Level* level, int x, int y, int z, int id,
@ -216,340 +205,29 @@ void DispenserTile::onRemove(Level* level, int x, int y, int z, int id,
container->setItem(i, nullptr);
}
}
level->updateNeighbourForOutputSignal(x, y, z, id);
}
EntityTile::onRemove(level, x, y, z, id, data);
BaseEntityTile::onRemove(level, x, y, z, id, data);
}
void DispenserTile::throwItem(Level* level, std::shared_ptr<ItemInstance> item,
Random* random, int accuracy, int xd, int zd,
double xp, double yp, double zp) {
std::shared_ptr<ItemEntity> itemEntity = std::shared_ptr<ItemEntity>(
new ItemEntity(level, xp, yp - 0.3, zp, item));
Position* DispenserTile::getDispensePosition(BlockSource* source) {
FacingEnum* facing = getFacing(source->getData());
double pow = random->nextDouble() * 0.1 + 0.2;
itemEntity->xd = xd * pow;
itemEntity->yd = .2f;
itemEntity->zd = zd * pow;
double originX = source->getX() + 0.7 * facing->getStepX();
double originY = source->getY() + 0.7 * facing->getStepY();
double originZ = source->getZ() + 0.7 * facing->getStepZ();
itemEntity->xd += (random->nextGaussian()) * 0.0075f * accuracy;
itemEntity->yd += (random->nextGaussian()) * 0.0075f * accuracy;
itemEntity->zd += (random->nextGaussian()) * 0.0075f * accuracy;
level->addEntity(itemEntity);
return new PositionImpl(originX, originY, originZ);
}
int DispenserTile::dispenseItem(std::shared_ptr<DispenserTileEntity> trap,
Level* level,
std::shared_ptr<ItemInstance> item,
Random* random, int x, int y, int z, int xd,
int zd, double xp, double yp, double zp) {
float power = 1.1f;
int accuracy = 6;
// 4J-PB - moved to a switch
switch (item->id) {
case Item::arrow_Id: {
int currentProjectiles =
level->countInstanceOf(eTYPE_PROJECTILE, false);
if (currentProjectiles <
Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit
{
std::shared_ptr<Arrow> arrow =
std::shared_ptr<Arrow>(new Arrow(level, xp, yp, zp));
arrow->shoot(xd, .1f, zd, power, (float)accuracy);
arrow->pickup = Arrow::PICKUP_ALLOWED;
level->addEntity(arrow);
level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0);
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::egg_Id: {
int currentProjectiles =
level->countInstanceOf(eTYPE_PROJECTILE, false);
if (currentProjectiles <
Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit
{
std::shared_ptr<ThrownEgg> egg = std::shared_ptr<ThrownEgg>(
new ThrownEgg(level, xp, yp, zp));
egg->shoot(xd, .1f, zd, power, (float)accuracy);
level->addEntity(egg);
level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0);
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::snowBall_Id: {
int currentProjectiles =
level->countInstanceOf(eTYPE_PROJECTILE, false);
if (currentProjectiles <
Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit
{
std::shared_ptr<Snowball> snowball =
std::shared_ptr<Snowball>(new Snowball(level, xp, yp, zp));
snowball->shoot(xd, .1f, zd, power, (float)accuracy);
level->addEntity(snowball);
level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0);
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::potion_Id: {
int currentProjectiles =
level->countInstanceOf(eTYPE_PROJECTILE, false);
if (currentProjectiles <
Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit
{
if (PotionItem::isThrowable(item->getAuxValue())) {
std::shared_ptr<ThrownPotion> potion =
std::shared_ptr<ThrownPotion>(new ThrownPotion(
level, xp, yp, zp, item->getAuxValue()));
potion->shoot(xd, .1f, zd, power * 1.25f, accuracy * .5f);
level->addEntity(potion);
level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0);
} else {
std::shared_ptr<ItemEntity> itemEntity =
std::shared_ptr<ItemEntity>(
new ItemEntity(level, xp, yp - 0.3, zp, item));
double pow = random->nextDouble() * 0.1 + 0.2;
itemEntity->xd = xd * pow;
itemEntity->yd = .2f;
itemEntity->zd = zd * pow;
itemEntity->xd +=
(random->nextGaussian()) * 0.0075f * accuracy;
itemEntity->yd +=
(random->nextGaussian()) * 0.0075f * accuracy;
itemEntity->zd +=
(random->nextGaussian()) * 0.0075f * accuracy;
level->addEntity(itemEntity);
level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0);
}
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::expBottle_Id: {
int currentProjectiles =
level->countInstanceOf(eTYPE_PROJECTILE, false);
if (currentProjectiles <
Level::MAX_DISPENSABLE_PROJECTILES) // 4J - added limit
{
std::shared_ptr<ThrownExpBottle> expBottle =
std::shared_ptr<ThrownExpBottle>(
new ThrownExpBottle(level, xp, yp, zp));
expBottle->shoot(xd, .1f, zd, power * 1.25f, accuracy * .5f);
level->addEntity(expBottle);
level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0);
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::fireball_Id: // TU9
{
int currentFireballs =
level->countInstanceOf(eTYPE_SMALL_FIREBALL, true);
if (currentFireballs <
Level::MAX_DISPENSABLE_FIREBALLS) // 4J - added limit
{
std::shared_ptr<SmallFireball> fireball =
std::shared_ptr<SmallFireball>(
new SmallFireball(level, xp + xd * .3, yp, zp + zd * .3,
xd + random->nextGaussian() * .05,
random->nextGaussian() * .05,
zd + random->nextGaussian() * .05));
level->addEntity(fireball);
level->levelEvent(LevelEvent::SOUND_BLAZE_FIREBALL, x, y, z, 0);
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::monsterPlacer_Id: {
int iResult = 0;
// MonsterPlacerItem *spawnEgg = (MonsterPlacerItem
// *)item->getItem();
std::shared_ptr<Entity> newEntity = MonsterPlacerItem::canSpawn(
item->getAuxValue(), level, &iResult);
std::shared_ptr<Mob> mob =
std::dynamic_pointer_cast<Mob>(newEntity);
if (mob != NULL) {
// 4J-PB - Changed the line below slightly since mobs were
// sticking to the dispenser rather than dropping down when
// fired
mob->moveTo(xp + xd * 0.4, yp - 0.3, zp + zd * 0.4,
level->random->nextFloat() * 360, 0);
mob->finalizeMobSpawn();
level->addEntity(mob);
level->levelEvent(LevelEvent::SOUND_LAUNCH, x, y, z, 0);
return REMOVE_ITEM;
} else {
// some negative sound effect?
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
// not sending a message here, since we will probably get
// flooded with them when people have automatic dispensers for
// spawn eggs
return LEAVE_ITEM;
}
} break;
case Item::bucket_lava_Id:
case Item::bucket_water_Id: {
BucketItem* pBucket = (BucketItem*)item->getItem();
if (pBucket->emptyBucket(level, x, y, z, x + xd, y, z + zd)) {
item->id = Item::bucket_empty_Id;
item->count = 1;
return LEAVE_ITEM;
}
return DISPENSE_ITEM;
} break;
case Item::bucket_empty_Id: {
int xt = x + xd;
int zt = z + zd;
Material* pMaterial = level->getMaterial(xt, y, zt);
int data = level->getData(xt, y, zt);
if (pMaterial == Material::water && data == 0) {
level->setTile(xt, y, zt, 0);
if (--item->count == 0) {
item->id = Item::bucket_water_Id;
item->count = 1;
} else if (trap->addItem(std::shared_ptr<ItemInstance>(
new ItemInstance(Item::bucket_water))) < 0) {
throwItem(level,
std::shared_ptr<ItemInstance>(
new ItemInstance(Item::bucket_water)),
random, 6, xd, zd, xp, yp, zp);
}
return LEAVE_ITEM;
} else if (pMaterial == Material::lava && data == 0) {
level->setTile(xt, y, zt, 0);
if (--item->count == 0) {
item->id = Item::bucket_lava_Id;
item->count = 1;
} else if (trap->addItem(std::shared_ptr<ItemInstance>(
new ItemInstance(Item::bucket_lava))) < 0) {
throwItem(level,
std::shared_ptr<ItemInstance>(
new ItemInstance(Item::bucket_lava)),
random, 6, xd, zd, xp, yp, zp);
}
return LEAVE_ITEM;
}
return DISPENSE_ITEM;
}
break;
// TU12
case Item::minecart_Id:
case Item::minecart_chest_Id:
case Item::minecart_furnace_Id: {
xp = x + (xd < 0 ? xd * 0.8 : xd * 1.8f) + Mth::abs(zd) * 0.5f;
zp = z + (zd < 0 ? zd * 0.8 : zd * 1.8f) + Mth::abs(xd) * 0.5f;
if (RailTile::isRail(level, x + xd, y, z + zd)) {
yp = y + 0.5f;
} else if (level->isEmptyTile(x + xd, y, z + zd) &&
RailTile::isRail(level, x + xd, y - 1, z + zd)) {
yp = y - 0.5f;
} else {
return DISPENSE_ITEM;
}
if (level->countInstanceOf(eTYPE_MINECART, true) <
Level::MAX_CONSOLE_MINECARTS) // 4J - added limit
{
std::shared_ptr<Minecart> minecart = std::shared_ptr<Minecart>(
new Minecart(level, xp, yp, zp,
((MinecartItem*)item->getItem())->type));
level->addEntity(minecart);
level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0);
return REMOVE_ITEM;
} else {
return DISPENSE_ITEM;
}
} break;
case Item::boat_Id: {
bool bLaunchBoat = false;
xp = x + (xd < 0 ? xd * 0.8 : xd * 1.8f) + Mth::abs(zd) * 0.5f;
zp = z + (zd < 0 ? zd * 0.8 : zd * 1.8f) + Mth::abs(xd) * 0.5f;
if (level->getMaterial(x + xd, y, z + zd) == Material::water) {
bLaunchBoat = true;
yp = y + 1.0f;
} else if (level->isEmptyTile(x + xd, y, z + zd) &&
level->getMaterial(x + xd, y - 1, z + zd) ==
Material::water) {
bLaunchBoat = true;
yp = y;
}
// check the limit on boats
if (bLaunchBoat && level->countInstanceOf(eTYPE_BOAT, true) <
Level::MAX_XBOX_BOATS) // 4J - added limit
{
std::shared_ptr<Boat> boat =
std::shared_ptr<Boat>(new Boat(level, xp, yp, zp));
level->addEntity(boat);
level->levelEvent(LevelEvent::SOUND_CLICK, x, y, z, 0);
return REMOVE_ITEM;
} else {
return DISPENSE_ITEM;
}
} break;
}
return DISPENSE_ITEM;
FacingEnum* DispenserTile::getFacing(int data) {
return FacingEnum::fromData(data & FACING_MASK);
}
bool DispenserTile::hasAnalogOutputSignal() { return true; }
int DispenserTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
return AbstractContainerMenu::getRedstoneSignalFromContainer(
std::dynamic_pointer_cast<Container>(level->getTileEntity(x, y, z)));
}

View file

@ -1,20 +1,19 @@
#pragma once
#include "TileEntities/EntityTile.h"
#include "BaseEntityTile.h"
#include "../Headers/net.minecraft.core.h"
class Player;
class Mob;
class ChunkRebuildData;
class DispenserTile : public EntityTile {
class DispenserTile : public BaseEntityTile {
friend class Tile;
friend class ChunkRebuildData;
private:
static const int DISPENSE_ITEM = 0;
static const int REMOVE_ITEM = 1;
static const int LEAVE_ITEM = 2;
public:
static const int FACING_MASK = 0x7;
static const int TRIGGER_BIT = 8;
static BehaviorRegistry REGISTRY;
protected:
Random* random;
@ -27,8 +26,7 @@ protected:
DispenserTile(int id);
public:
virtual int getTickDelay();
virtual int getResource(int data, Random* random, int playerBonusLevel);
virtual int getTickDelay(Level* level);
virtual void onPlace(Level* level, int x, int y, int z);
private:
@ -36,31 +34,30 @@ private:
public:
virtual Icon* getTexture(int face, int data);
//@Override
void registerIcons(IconRegister* iconRegister);
virtual void registerIcons(IconRegister* iconRegister);
virtual bool TestUse();
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
private:
void fireArrow(Level* level, int x, int y, int z, Random* random);
protected:
virtual void dispenseFrom(Level* level, int x, int y, int z);
virtual DispenseItemBehavior* getDispenseMethod(
std::shared_ptr<ItemInstance> item);
public:
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
private:
static void throwItem(Level* level, std::shared_ptr<ItemInstance> item,
Random* random, int accuracy, int xd, int zd,
double xp, double yp, double zp);
static int dispenseItem(std::shared_ptr<DispenserTileEntity> trap,
Level* level, std::shared_ptr<ItemInstance> item,
Random* random, int x, int y, int z, int xd, int zd,
double xp, double yp, double zp);
static Position* getDispensePosition(BlockSource* source);
static FacingEnum* getFacing(int data);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
};

View file

@ -11,9 +11,8 @@
const std::wstring DoorTile::TEXTURES[] = {
L"doorWood_lower", L"doorWood_upper", L"doorIron_lower", L"doorIron_upper"};
DoorTile::DoorTile(int id, Material* material) : Tile(id, material, false) {
icons = NULL;
DoorTile::DoorTile(int id, Material* material)
: Tile(id, material, false) {
if (material == Material::metal) {
texBase = 2;
} else {
@ -25,10 +24,13 @@ DoorTile::DoorTile(int id, Material* material) : Tile(id, material, false) {
Tile::setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r);
}
Icon* DoorTile::getTexture(int face, int data) { return icons[texBase]; }
Icon* DoorTile::getTexture(int face, int data) {
return iconBottom[TEXTURE_NORMAL];
}
Icon* DoorTile::getTexture(LevelSource* level, int x, int y, int z, int face) {
if (face == Facing::UP || face == Facing::DOWN) return icons[texBase];
if (face == Facing::UP || face == Facing::DOWN)
return iconBottom[TEXTURE_NORMAL];
int compositeData = getCompositeData(level, x, y, z);
int dir = compositeData & C_DIR_MASK;
@ -57,18 +59,22 @@ Icon* DoorTile::getTexture(LevelSource* level, int x, int y, int z, int face) {
if ((compositeData & C_RIGHT_HINGE_MASK) != 0) flip = !flip;
}
return icons[texBase + (flip ? DOOR_TILE_TEXTURE_COUNT : 0) +
(upper ? 1 : 0)];
if (upper) {
return iconTop[flip ? TEXTURE_FLIPPED : TEXTURE_NORMAL];
} else {
return iconBottom[flip ? TEXTURE_FLIPPED : TEXTURE_NORMAL];
}
}
void DoorTile::registerIcons(IconRegister* iconRegister) {
icons = new Icon*[DOOR_TILE_TEXTURE_COUNT * 2];
for (int i = 0; i < DOOR_TILE_TEXTURE_COUNT; i++) {
icons[i] = iconRegister->registerIcon(TEXTURES[i]);
icons[i + DOOR_TILE_TEXTURE_COUNT] =
new FlippedIcon(icons[i], true, false);
}
iconTop[TEXTURE_NORMAL] =
iconRegister->registerIcon(getIconName() + L"_upper");
iconBottom[TEXTURE_NORMAL] =
iconRegister->registerIcon(getIconName() + L"_lower");
iconTop[TEXTURE_FLIPPED] =
new FlippedIcon(iconTop[TEXTURE_NORMAL], true, false);
iconBottom[TEXTURE_FLIPPED] =
new FlippedIcon(iconBottom[TEXTURE_NORMAL], true, false);
}
bool DoorTile::blocksLight() { return false; }
@ -157,7 +163,7 @@ void DoorTile::attack(Level* level, int x, int y, int z,
}
// 4J-PB - Adding a TestUse for tooltip display
bool DoorTile::TestUse() { return true; }
bool DoorTile::TestUse() { return id == Tile::door_wood_Id; }
bool DoorTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
@ -178,10 +184,10 @@ bool DoorTile::use(Level* level, int x, int y, int z,
int lowerData = compositeData & C_LOWER_DATA_MASK;
lowerData ^= 4;
if ((compositeData & C_IS_UPPER_MASK) == 0) {
level->setData(x, y, z, lowerData); //, Tile.UPDATE_CLIENTS);
level->setData(x, y, z, lowerData, Tile::UPDATE_CLIENTS);
level->setTilesDirty(x, y, z, x, y, z);
} else {
level->setData(x, y - 1, z, lowerData); //, Tile.UPDATE_CLIENTS);
level->setData(x, y - 1, z, lowerData, Tile::UPDATE_CLIENTS);
level->setTilesDirty(x, y - 1, z, x, y, z);
}
@ -197,10 +203,10 @@ void DoorTile::setOpen(Level* level, int x, int y, int z, bool shouldOpen) {
int lowerData = compositeData & C_LOWER_DATA_MASK;
lowerData ^= 4;
if ((compositeData & C_IS_UPPER_MASK) == 0) {
level->setData(x, y, z, lowerData); //, Tile.UPDATE_CLIENTS);
level->setData(x, y, z, lowerData, Tile::UPDATE_CLIENTS);
level->setTilesDirty(x, y, z, x, y, z);
} else {
level->setData(x, y - 1, z, lowerData); //, Tile.UPDATE_CLIENTS);
level->setData(x, y - 1, z, lowerData, Tile::UPDATE_CLIENTS);
level->setTilesDirty(x, y - 1, z, x, y, z);
}
@ -212,14 +218,14 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if ((data & UPPER_BIT) == 0) {
bool spawn = false;
if (level->getTile(x, y + 1, z) != id) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
spawn = true;
}
if (!level->isSolidBlockingTile(x, y - 1, z)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
spawn = true;
if (level->getTile(x, y + 1, z) == id) {
level->setTile(x, y + 1, z, 0);
level->removeTile(x, y + 1, z);
}
}
if (spawn) {
@ -236,7 +242,7 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) {
}
} else {
if (level->getTile(x, y - 1, z) != id) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
if (type > 0 && type != id) {
neighborChanged(level, x, y - 1, z, type);
@ -291,3 +297,14 @@ int DoorTile::cloneTileId(Level* level, int x, int y, int z) {
return material == Material::metal ? Item::door_iron_Id
: Item::door_wood_Id;
}
void DoorTile::playerWillDestroy(Level* level, int x, int y, int z, int data,
std::shared_ptr<Player> player) {
if (player->abilities.instabuild) {
if ((data & UPPER_BIT) != 0) {
if (level->getTile(x, y - 1, z) == id) {
level->removeTile(x, y - 1, z);
}
}
}
}

View file

@ -10,6 +10,10 @@ class DoorTile : public Tile {
friend class Tile;
friend class ChunkRebuildData;
private:
static const int TEXTURE_NORMAL = 0;
static const int TEXTURE_FLIPPED = 1;
public:
static const int UPPER_BIT = 8;
static const int C_DIR_MASK = 3;
@ -22,17 +26,16 @@ private:
static const int DOOR_TILE_TEXTURE_COUNT = 4;
static const std::wstring TEXTURES[];
int texBase;
Icon** icons;
Icon* iconTop[2];
Icon* iconBottom[2];
protected:
DoorTile(int id, Material* material);
public:
virtual Icon* getTexture(int face, int data);
//@Override
Icon* getTexture(LevelSource* level, int x, int y, int z, int face);
//@Override
void registerIcons(IconRegister* iconRegister);
virtual Icon* getTexture(LevelSource* level, int x, int y, int z, int face);
virtual void registerIcons(IconRegister* iconRegister);
virtual bool blocksLight();
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool isCubeShaped();
@ -68,4 +71,6 @@ public:
virtual int getPistonPushReaction();
int getCompositeData(LevelSource* level, int x, int y, int z);
virtual int cloneTileId(Level* level, int x, int y, int z);
virtual void playerWillDestroy(Level* level, int x, int y, int z, int data,
std::shared_ptr<Player> player);
};

View file

@ -0,0 +1,68 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.h"
#include "../Headers/net.minecraft.core.h"
#include "DropperTile.h"
DropperTile::DropperTile(int id) : DispenserTile(id) {
DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior();
}
void DropperTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(L"furnace_side");
iconTop = iconRegister->registerIcon(L"furnace_top");
iconFront =
iconRegister->registerIcon(getIconName() + L"_front_horizontal");
iconFrontVertical =
iconRegister->registerIcon(getIconName() + L"_front_vertical");
}
DispenseItemBehavior* DropperTile::getDispenseMethod(
std::shared_ptr<ItemInstance> item) {
return DISPENSE_BEHAVIOUR;
}
std::shared_ptr<TileEntity> DropperTile::newTileEntity(Level* level) {
return std::shared_ptr<DropperTileEntity>(new DropperTileEntity());
}
void DropperTile::dispenseFrom(Level* level, int x, int y, int z) {
BlockSourceImpl source(level, x, y, z);
std::shared_ptr<DispenserTileEntity> trap =
std::dynamic_pointer_cast<DispenserTileEntity>(source.getEntity());
if (trap == NULL) return;
int slot = trap->getRandomSlot();
if (slot < 0) {
level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0);
} else {
std::shared_ptr<ItemInstance> item = trap->getItem(slot);
int face = level->getData(x, y, z) & DispenserTile::FACING_MASK;
std::shared_ptr<Container> into = HopperTileEntity::getContainerAt(
level, x + Facing::STEP_X[face], y + Facing::STEP_Y[face],
z + Facing::STEP_Z[face]);
std::shared_ptr<ItemInstance> remaining = nullptr;
if (into != NULL) {
remaining =
HopperTileEntity::addItem(into.get(), item->copy()->remove(1),
Facing::OPPOSITE_FACING[face]);
if (remaining == NULL) {
remaining = item->copy();
if (--remaining->count == 0) remaining = nullptr;
} else {
// placing one item failed, so restore original count
remaining = item->copy();
}
} else {
remaining = DISPENSE_BEHAVIOUR->dispense(&source, item);
if (remaining != NULL && remaining->count == 0) remaining = nullptr;
}
trap->setItem(slot, remaining);
}
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "DispenserTile.h"
class DropperTile : public DispenserTile {
private:
DispenseItemBehavior* DISPENSE_BEHAVIOUR;
public:
DropperTile(int id);
virtual void registerIcons(IconRegister* iconRegister);
protected:
virtual DispenseItemBehavior* getDispenseMethod(
std::shared_ptr<ItemInstance> item);
public:
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
protected:
virtual void dispenseFrom(Level* level, int x, int y, int z);
};

View file

@ -7,11 +7,11 @@
EggTile::EggTile(int id) : Tile(id, Material::egg, false) {}
void EggTile::onPlace(Level* level, int x, int y, int z) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
void EggTile::neighborChanged(Level* level, int x, int y, int z, int type) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
void EggTile::tick(Level* level, int x, int y, int z, Random* random) {
@ -23,10 +23,10 @@ void EggTile::checkSlide(Level* level, int x, int y, int z) {
int r = 32;
if (HeavyTile::instaFall ||
!level->hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
while (HeavyTile::isFree(level, x, y - 1, z) && y > 0) y--;
if (y > 0) {
level->setTile(x, y, z, id);
level->setTileAndData(x, y, z, id, 0, Tile::UPDATE_CLIENTS);
}
} else {
std::shared_ptr<FallingTile> e = std::shared_ptr<FallingTile>(
@ -64,8 +64,9 @@ void EggTile::teleport(Level* level, int x, int y, int z) {
// isn't present. Don't set tiles on client, and don't create
// particles on the server (matches later change in Java)
if (!level->isClientSide) {
level->setTileAndData(xt, yt, zt, id, level->getData(x, y, z));
level->setTile(x, y, z, 0);
level->setTileAndData(xt, yt, zt, id, level->getData(x, y, z),
Tile::UPDATE_CLIENTS);
level->removeTile(x, y, z);
// 4J Stu - The PC version is wrong as the particles calculated
// on the client side will point towards a different location to
@ -91,18 +92,19 @@ void EggTile::teleport(Level* level, int x, int y, int z) {
// for (int j = 0; j < count; j++)
// {
// double d = level->random->nextDouble(); // j <
//count / 2 ? 0 :
// count / 2 ? 0 :
//// 1;
// float xa = (level->random->nextFloat() - 0.5f) *
//0.2f; float ya = (level->random->nextFloat() - 0.5f) * 0.2f; float
//za = (level->random->nextFloat() - 0.5f) * 0.2f;
// 0.2f; float ya = (level->random->nextFloat() -
// 0.5f) * 0.2f; float za =
// (level->random->nextFloat() - 0.5f) * 0.2f;
// double _x = xt + (x - xt) * d +
//(level->random->nextDouble() - 0.5) * 1 + 0.5f; double _y = yt +
//(y - yt) * d + level->random->nextDouble() * 1 - 0.5f; double _z =
//zt + (z - zt) * d + (level->random->nextDouble() - 0.5) * 1 +
//0.5f; level->addParticle(eParticleType_ender, _x, _y, _z, xa, ya,
//za);
//(level->random->nextDouble() - 0.5) * 1 + 0.5f;
// double _y = yt + (y - yt) * d + level->random->nextDouble() * 1 -
// 0.5f; double _z = zt + (z - zt) * d +
// (level->random->nextDouble() - 0.5) * 1 + 0.5f;
// level->addParticle(eParticleType_ender, _x, _y, _z, xa, ya, za);
// }
// }
return;
@ -110,7 +112,7 @@ void EggTile::teleport(Level* level, int x, int y, int z) {
}
}
int EggTile::getTickDelay() { return 3; }
int EggTile::getTickDelay(Level* level) { return 5; }
bool EggTile::blocksLight() { return false; }
@ -118,6 +120,11 @@ bool EggTile::isSolidRender(bool isServerLevel) { return false; }
bool EggTile::isCubeShaped() { return false; }
bool EggTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
return true;
}
int EggTile::getRenderShape() { return Tile::SHAPE_EGG; }
int EggTile::cloneTileId(Level* level, int x, int y, int z) { return 0; }
@ -147,9 +154,4 @@ void EggTile::generateTeleportParticles(Level* level, int xt, int yt, int zt,
zt + deltaZ * d + (level->random->nextDouble() - 0.5) * 1 + 0.5f;
level->addParticle(eParticleType_ender, _x, _y, _z, xa, ya, za);
}
}
bool EggTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
return true;
}
}

View file

@ -23,7 +23,7 @@ private:
void teleport(Level* level, int x, int y, int z);
public:
virtual int getTickDelay();
virtual int getTickDelay(Level* level);
virtual bool blocksLight();
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool isCubeShaped();

View file

@ -10,7 +10,7 @@ const std::wstring EnchantmentTableTile::TEXTURE_TOP = L"enchantment_top";
const std::wstring EnchantmentTableTile::TEXTURE_BOTTOM = L"enchantment_bottom";
EnchantmentTableTile::EnchantmentTableTile(int id)
: EntityTile(id, Material::stone, false) {
: BaseEntityTile(id, Material::stone, false) {
updateDefaultShape();
setLightBlock(0);
@ -27,7 +27,7 @@ bool EnchantmentTableTile::isCubeShaped() { return false; }
void EnchantmentTableTile::animateTick(Level* level, int x, int y, int z,
Random* random) {
EntityTile::animateTick(level, x, y, z, random);
BaseEntityTile::animateTick(level, x, y, z, random);
for (int xx = x - 2; xx <= x + 2; xx++) {
for (int zz = z - 2; zz <= z + 2; zz++) {
@ -74,10 +74,25 @@ bool EnchantmentTableTile::use(
if (level->isClientSide) {
return true;
}
player->startEnchanting(x, y, z);
std::shared_ptr<EnchantmentTableEntity> table =
std::dynamic_pointer_cast<EnchantmentTableEntity>(
level->getTileEntity(x, y, z));
player->startEnchanting(x, y, z,
table->hasCustomName() ? table->getName() : L"");
return true;
}
void EnchantmentTableTile::setPlacedBy(
Level* level, int x, int y, int z, std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
BaseEntityTile::setPlacedBy(level, x, y, z, by, itemInstance);
if (itemInstance->hasCustomHoverName()) {
std::dynamic_pointer_cast<EnchantmentTableEntity>(
level->getTileEntity(x, y, z))
->setCustomName(itemInstance->getHoverName());
}
}
void EnchantmentTableTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(TEXTURE_SIDE);
iconTop = iconRegister->registerIcon(TEXTURE_TOP);

View file

@ -1,8 +1,8 @@
#pragma once
#include "TileEntities/EntityTile.h"
#include "BaseEntityTile.h"
class ChunkRebuildData;
class EnchantmentTableTile : public EntityTile {
class EnchantmentTableTile : public BaseEntityTile {
friend class ChunkRebuildData;
public:
@ -18,14 +18,17 @@ public:
EnchantmentTableTile(int id);
virtual void updateDefaultShape(); // 4J Added override
bool isCubeShaped();
void animateTick(Level* level, int x, int y, int z, Random* random);
bool isSolidRender(bool isServerLevel = false);
Icon* getTexture(int face, int data);
std::shared_ptr<TileEntity> newTileEntity(Level* level);
bool use(Level* level, int x, int y, int z, std::shared_ptr<Player> player,
int clickedFace, float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
//@Override
void registerIcons(IconRegister* iconRegister);
virtual bool isCubeShaped();
virtual void animateTick(Level* level, int x, int y, int z, Random* random);
virtual bool isSolidRender(bool isServerLevel = false);
virtual Icon* getTexture(int face, int data);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -8,7 +8,7 @@
#include "EnderChestTile.h"
EnderChestTile::EnderChestTile(int id)
: EntityTile(id, Material::stone, false) {
: BaseEntityTile(id, Material::stone, false) {
updateDefaultShape();
}
@ -33,7 +33,8 @@ int EnderChestTile::getResourceCount(Random* random) { return 8; }
bool EnderChestTile::isSilkTouchable() { return true; }
void EnderChestTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int facing = 0;
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5f)) & 3;
@ -42,7 +43,7 @@ void EnderChestTile::setPlacedBy(Level* level, int x, int y, int z,
if (dir == 2) facing = Facing::SOUTH;
if (dir == 3) facing = Facing::WEST;
level->setData(x, y, z, facing);
level->setData(x, y, z, facing, Tile::UPDATE_CLIENTS);
}
bool EnderChestTile::use(Level* level, int x, int y, int z,

View file

@ -1,9 +1,9 @@
#pragma once
#include "TileEntities/EntityTile.h"
#include "BaseEntityTile.h"
#include "ChestTile.h"
class EnderChestTile : public EntityTile {
class EnderChestTile : public BaseEntityTile {
public:
static const int EVENT_SET_OPEN_COUNT = ChestTile::EVENT_SET_OPEN_COUNT;
@ -21,7 +21,8 @@ protected:
public:
void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
bool use(Level* level, int x, int y, int z, std::shared_ptr<Player> player,
int clickedFace, float clickX, float clickY, float clickZ,
bool soundOnly = false);

View file

@ -21,6 +21,7 @@ void FallingTile::_init() {
hurtEntities = false;
fallDamageMax = 40;
fallDamageAmount = 2;
tileData = NULL;
// 4J Added so that client-side falling tiles can fall through blocks
// This fixes a bug on the host where the tile update from the server comes
@ -58,6 +59,8 @@ FallingTile::FallingTile(Level* level, double x, double y, double z, int tile,
zOld = z;
}
FallingTile::~FallingTile() { delete tileData; }
bool FallingTile::makeStepSound() { return false; }
void FallingTile::defineSynchedData() {}
@ -87,7 +90,7 @@ void FallingTile::tick() {
int zt = Mth::floor(z);
if (time == 1) {
if (level->getTile(xt, yt, zt) == tile) {
level->setTile(xt, yt, zt, 0);
level->removeTile(xt, yt, zt);
} else {
remove();
return;
@ -99,17 +102,40 @@ void FallingTile::tick() {
zd *= 0.7f;
yd *= -0.5f;
// if (HeavyTile.isFree(level, xt, yt, zt)) {
if (level->getTile(xt, yt, zt) != Tile::pistonMovingPiece_Id) {
remove();
if (!cancelDrop &&
level->mayPlace(tile, xt, yt, zt, true, 1, nullptr) &&
level->mayPlace(tile, xt, yt, zt, true, 1, nullptr,
nullptr) &&
!HeavyTile::isFree(level, xt, yt - 1, zt) &&
level->setTileAndData(xt, yt, zt, tile, data)) {
level->setTileAndData(xt, yt, zt, tile, data,
Tile::UPDATE_ALL)) {
HeavyTile* hv = dynamic_cast<HeavyTile*>(Tile::tiles[tile]);
if (hv) {
hv->onLand(level, xt, yt, zt, data);
}
if (tileData != NULL && Tile::tiles[tile]->isEntityTile()) {
std::shared_ptr<TileEntity> tileEntity =
level->getTileEntity(xt, yt, zt);
if (tileEntity != NULL) {
CompoundTag* swap = new CompoundTag();
tileEntity->save(swap);
std::vector<Tag*>* allTags = tileData->getAllTags();
for (AUTO_VAR(it, allTags->begin());
it != allTags->end(); ++it) {
Tag* tag = *it;
if (tag->getName().compare(L"x") == 0 ||
tag->getName().compare(L"y") == 0 ||
tag->getName().compare(L"z") == 0)
continue;
swap->put(tag->getName(), tag->copy());
}
delete allTags;
tileEntity->load(swap);
tileEntity->setChanged();
}
}
} else {
if (dropItem && !cancelDrop)
spawnAtLocation(
@ -123,7 +149,12 @@ void FallingTile::tick() {
} else if ((time > 20 * 5 && !level->isClientSide &&
(yt < 1 || yt > Level::maxBuildHeight)) ||
(time > 20 * 30)) {
if (dropItem) spawnAtLocation(tile, 1);
if (dropItem)
spawnAtLocation(
std::shared_ptr<ItemInstance>(new ItemInstance(
tile, 1,
Tile::tiles[tile]->getSpawnResourcesAuxValue(data))),
0);
remove();
}
}
@ -133,17 +164,21 @@ void FallingTile::causeFallDamage(float distance) {
if (hurtEntities) {
int dmg = Mth::ceil(distance - 1);
if (dmg > 0) {
// 4J: Copy vector since it might be modified when we hurt the
// entities (invalidating our iterator)
std::vector<std::shared_ptr<Entity> >* entities =
level->getEntities(shared_from_this(), bb);
new std::vector<std::shared_ptr<Entity> >(
*level->getEntities(shared_from_this(), bb));
DamageSource* source = tile == Tile::anvil_Id
? DamageSource::anvil
: DamageSource::fallingBlock;
// for (Entity entity : entities)
for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) {
(*it)->hurt(source, std::min(Mth::floor(dmg * fallDamageAmount),
fallDamageMax));
}
delete entities;
if (tile == Tile::anvil_Id &&
random->nextFloat() < 0.05f + (dmg * 0.05)) {
int damage = data >> 2;
@ -161,16 +196,22 @@ void FallingTile::causeFallDamage(float distance) {
void FallingTile::addAdditonalSaveData(CompoundTag* tag) {
tag->putByte(L"Tile", (uint8_t)tile);
tag->putInt(L"TileID", tile);
tag->putByte(L"Data", (uint8_t)data);
tag->putByte(L"Time", (uint8_t)time);
tag->putBoolean(L"DropItem", dropItem);
tag->putBoolean(L"HurtEntities", hurtEntities);
tag->putFloat(L"FallHurtAmount", fallDamageAmount);
tag->putInt(L"FallHurtMax", fallDamageMax);
if (tileData != NULL) tag->putCompound(L"TileEntityData", tileData);
}
void FallingTile::readAdditionalSaveData(CompoundTag* tag) {
tile = tag->getByte(L"Tile") & 0xff;
if (tag->contains(L"TileID")) {
tile = tag->getInt(L"TileID");
} else {
tile = tag->getByte(L"Tile") & 0xff;
}
data = tag->getByte(L"Data") & 0xff;
time = tag->getByte(L"Time") & 0xff;
@ -186,6 +227,10 @@ void FallingTile::readAdditionalSaveData(CompoundTag* tag) {
dropItem = tag->getBoolean(L"DropItem");
}
if (tag->contains(L"TileEntityData")) {
tileData = tag->getCompound(L"TileEntityData");
}
if (tile == 0) {
tile = Tile::sand_Id;
}

View file

@ -24,9 +24,12 @@ private:
void _init();
public:
CompoundTag* tileData;
FallingTile(Level* level);
FallingTile(Level* level, double x, double y, double z, int tile,
int data = 0);
~FallingTile();
protected:
virtual bool makeStepSound();

View file

@ -38,14 +38,14 @@ Icon* FarmTile::getTexture(int face, int data) {
void FarmTile::tick(Level* level, int x, int y, int z, Random* random) {
if (isNearWater(level, x, y, z) || level->isRainingAt(x, y + 1, z)) {
level->setData(x, y, z, 7);
level->setData(x, y, z, 7, Tile::UPDATE_CLIENTS);
} else {
int moisture = level->getData(x, y, z);
if (moisture > 0) {
level->setData(x, y, z, moisture - 1);
level->setData(x, y, z, moisture - 1, Tile::UPDATE_CLIENTS);
} else {
if (!isUnderCrops(level, x, y, z)) {
level->setTile(x, y, z, Tile::dirt_Id);
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
}
}
}
@ -58,12 +58,17 @@ void FarmTile::fallOn(Level* level, int x, int y, int z,
// the client based on random values!
if (!level->isClientSide &&
level->random->nextFloat() < (fallDistance - .5f)) {
// Fix for #60547 - TU7: Content: Gameplay: Players joining a game can
// destroy crops even with Trust Players option disabled.
std::shared_ptr<Player> player =
std::dynamic_pointer_cast<Player>(entity);
if (player == NULL || player->isAllowedToMine())
level->setTile(x, y, z, Tile::dirt_Id);
if (entity->instanceof(eTYPE_PLAYER)) {
std::shared_ptr<Player> player =
std::dynamic_pointer_cast<Player>(entity);
if (!player->isAllowedToMine()) {
return;
}
} else if (!level->getGameRules()->getBoolean(
GameRules::RULE_MOBGRIEFING)) {
return;
}
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
}
}
@ -72,7 +77,7 @@ bool FarmTile::isUnderCrops(Level* level, int x, int y, int z) {
for (int xx = x - r; xx <= x + r; xx++)
for (int zz = z - r; zz <= z + r; zz++) {
int tile = level->getTile(xx, y + 1, zz);
if (tile == Tile::crops_Id || tile == Tile::melonStem_Id ||
if (tile == Tile::wheat_Id || tile == Tile::melonStem_Id ||
tile == Tile::pumpkinStem_Id || tile == Tile::potatoes_Id ||
tile == Tile::carrots_Id) {
return true;
@ -96,7 +101,7 @@ void FarmTile::neighborChanged(Level* level, int x, int y, int z, int type) {
Tile::neighborChanged(level, x, y, z, type);
Material* above = level->getMaterial(x, y + 1, z);
if (above->isSolid()) {
level->setTile(x, y, z, Tile::dirt_Id);
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
}
}

View file

@ -59,9 +59,10 @@ bool FenceGateTile::isPathfindable(LevelSource* level, int x, int y, int z) {
int FenceGateTile::getRenderShape() { return Tile::SHAPE_FENCE_GATE; }
void FenceGateTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3)) % 4;
level->setData(x, y, z, dir);
level->setData(x, y, z, dir, Tile::UPDATE_CLIENTS);
}
bool FenceGateTile::use(Level* level, int x, int y, int z,
@ -80,7 +81,7 @@ bool FenceGateTile::use(Level* level, int x, int y, int z,
int data = level->getData(x, y, z);
if (isOpen(data)) {
level->setData(x, y, z, data & ~OPEN_BIT);
level->setData(x, y, z, data & ~OPEN_BIT, Tile::UPDATE_CLIENTS);
} else {
// open the door from the player
int dir = (((Mth::floor(player->yRot * 4 / (360) + 0.5)) & 3)) % 4;
@ -88,7 +89,7 @@ bool FenceGateTile::use(Level* level, int x, int y, int z,
if (current == ((dir + 2) % 4)) {
data = dir;
}
level->setData(x, y, z, data | OPEN_BIT);
level->setData(x, y, z, data | OPEN_BIT, Tile::UPDATE_CLIENTS);
}
level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
return true;
@ -104,10 +105,10 @@ void FenceGateTile::neighborChanged(Level* level, int x, int y, int z,
if (signal ||
((type > 0 && Tile::tiles[type]->isSignalSource()) || type == 0)) {
if (signal && !isOpen(data)) {
level->setData(x, y, z, data | OPEN_BIT);
level->setData(x, y, z, data | OPEN_BIT, Tile::UPDATE_CLIENTS);
level->levelEvent(nullptr, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
} else if (!signal && isOpen(data)) {
level->setData(x, y, z, data & ~OPEN_BIT);
level->setData(x, y, z, data & ~OPEN_BIT, Tile::UPDATE_CLIENTS);
level->levelEvent(nullptr, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
}
}
@ -122,4 +123,4 @@ void FenceGateTile::registerIcons(IconRegister* iconRegister) {
bool FenceGateTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
return true;
}
}

View file

@ -23,7 +23,8 @@ public:
int face);
virtual int getRenderShape();
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,

View file

@ -1,6 +1,6 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "../Headers/net.minecraft.world.h"
#include "FenceTile.h"
@ -9,7 +9,8 @@ FenceTile::FenceTile(int id, const std::wstring& texture, Material* material)
this->texture = texture;
}
AABB* FenceTile::getAABB(Level* level, int x, int y, int z) {
void FenceTile::addAABBs(Level* level, int x, int y, int z, AABB* box,
AABBList* boxes, std::shared_ptr<Entity> source) {
bool n = connectsTo(level, x, y, z - 1);
bool s = connectsTo(level, x, y, z + 1);
bool w = connectsTo(level, x - 1, y, z);
@ -26,14 +27,31 @@ AABB* FenceTile::getAABB(Level* level, int x, int y, int z) {
if (s) {
south = 1;
}
if (n || s) {
setShape(west, 0, north, east, 1.5f, south);
Tile::addAABBs(level, x, y, z, box, boxes, source);
}
north = 6.0f / 16.0f;
south = 10.0f / 16.0f;
if (w) {
west = 0;
}
if (e) {
east = 1;
}
if (w || e || (!n && !s)) {
setShape(west, 0, north, east, 1.5f, south);
Tile::addAABBs(level, x, y, z, box, boxes, source);
}
return AABB::newTemp(x + west, y, z + north, x + east, y + 1.5f, z + south);
if (n) {
north = 0;
}
if (s) {
south = 1;
}
setShape(west, 0, north, east, 1.0f, south);
}
void FenceTile::updateShape(
@ -67,8 +85,6 @@ void FenceTile::updateShape(
setShape(west, 0, north, east, 1.0f, south);
}
bool FenceTile::blocksLight() { return false; }
bool FenceTile::isSolidRender(bool isServerLevel) { return false; }
bool FenceTile::isCubeShaped() { return false; }
@ -106,3 +122,13 @@ bool FenceTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
return true;
}
bool FenceTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ, bool soundOnly) {
if (level->isClientSide) return true;
if (LeashItem::bindPlayerMobs(player, level, x, y, z)) {
return true;
}
return false;
}

View file

@ -8,19 +8,23 @@ private:
public:
FenceTile(int id, const std::wstring& texture, Material* material);
virtual AABB* getAABB(Level* level, int x, int y, int z);
virtual void addAABBs(Level* level, int x, int y, int z, AABB* box,
AABBList* boxes, std::shared_ptr<Entity> source);
virtual void updateShape(
LevelSource* level, int x, int y, int z, int forceData = -1,
std::shared_ptr<TileEntity> forceEntity = std::shared_ptr<
TileEntity>()); // 4J added forceData, forceEntity param
virtual bool blocksLight();
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool isCubeShaped();
virtual bool isPathfindable(LevelSource* level, int x, int y, int z);
virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z,
int face);
virtual int getRenderShape();
bool connectsTo(LevelSource* level, int x, int y, int z);
virtual bool connectsTo(LevelSource* level, int x, int y, int z);
static bool isFence(int tile);
void registerIcons(IconRegister* iconRegister);
virtual void registerIcons(IconRegister* iconRegister);
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false);
};

View file

@ -46,8 +46,10 @@ void FireTile::init() {
setFlammable(Tile::bookshelf_Id, FLAME_EASY, BURN_MEDIUM);
setFlammable(Tile::tnt_Id, FLAME_MEDIUM, BURN_INSTANT);
setFlammable(Tile::tallgrass_Id, FLAME_INSTANT, BURN_INSTANT);
setFlammable(Tile::cloth_Id, FLAME_EASY, BURN_EASY);
setFlammable(Tile::wool_Id, FLAME_EASY, BURN_EASY);
setFlammable(Tile::vine_Id, FLAME_MEDIUM, BURN_INSTANT);
setFlammable(Tile::coalBlock_Id, FLAME_HARD, BURN_HARD);
setFlammable(Tile::hayBlock_Id, FLAME_INSTANT, BURN_MEDIUM);
}
void FireTile::setFlammable(int id, int flame, int burn) {
@ -67,9 +69,13 @@ int FireTile::getRenderShape() { return Tile::SHAPE_FIRE; }
int FireTile::getResourceCount(Random* random) { return 0; }
int FireTile::getTickDelay() { return 30; }
int FireTile::getTickDelay(Level* level) { return 30; }
void FireTile::tick(Level* level, int x, int y, int z, Random* random) {
if (!level->getGameRules()->getBoolean(GameRules::RULE_DOFIRETICK)) {
return;
}
// 4J added - we don't want fire to do anything that might create new fire,
// or destroy this fire, if we aren't actually tracking (for network) the
// chunk this is in in the player chunk map. If we did change something in
@ -83,12 +89,12 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) {
{
if (!MinecraftServer::getInstance()->getPlayers()->isTrackingTile(
x, y, z, level->dimension->id)) {
level->addToTickNextTick(x, y, z, id, getTickDelay() * 5);
level->addToTickNextTick(x, y, z, id, getTickDelay(level) * 5);
return;
}
}
bool infiniBurn = level->getTile(x, y - 1, z) == Tile::hellRock_Id;
bool infiniBurn = level->getTile(x, y - 1, z) == Tile::netherRack_Id;
if (level->dimension->id == 1) // 4J - was == instanceof TheEndDimension
{
if (level->getTile(x, y - 1, z) == Tile::unbreakable_Id)
@ -96,7 +102,7 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) {
}
if (!mayPlace(level, x, y, z)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
if (!infiniBurn && level->isRaining()) {
@ -104,26 +110,28 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) {
level->isRainingAt(x + 1, y, z) ||
level->isRainingAt(x, y, z - 1) ||
level->isRainingAt(x, y, z + 1)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
}
int age = level->getData(x, y, z);
if (age < 15) {
level->setDataNoUpdate(x, y, z, age + random->nextInt(3) / 2);
level->setData(x, y, z, age + random->nextInt(3) / 2,
Tile::UPDATE_NONE);
}
level->addToTickNextTick(x, y, z, id, getTickDelay() + random->nextInt(10));
level->addToTickNextTick(x, y, z, id,
getTickDelay(level) + random->nextInt(10));
if (!infiniBurn && !isValidFireLocation(level, x, y, z)) {
if (!level->isTopSolidBlocking(x, y - 1, z) || age > 3)
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
if (!infiniBurn && !canBurn(level, x, y - 1, z)) {
if (age == 15 && random->nextInt(4) == 0) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
}
@ -152,24 +160,22 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) {
int fodds = getFireOdds(level, xx, yy, zz);
if (fodds > 0) {
int odds = (fodds + 40) / (age + 30);
int odds =
(fodds + 40 + (level->difficulty * 7)) / (age + 30);
if (isHumid) {
odds /= 2;
}
if (odds > 0 && random->nextInt(rate) <= odds) {
if ((level->isRaining() &&
level->isRainingAt(xx, yy, zz)) ||
level->isRainingAt(xx - 1, yy, z) ||
level->isRainingAt(xx + 1, yy, zz) ||
level->isRainingAt(xx, yy, zz - 1) ||
level->isRainingAt(xx, yy, zz + 1)) {
// DO NOTHING, rain!
} else {
if (!(level->isRaining() &&
level->isRainingAt(xx, yy, zz) ||
level->isRainingAt(xx - 1, yy, z) ||
level->isRainingAt(xx + 1, yy, zz) ||
level->isRainingAt(xx, yy, zz - 1) ||
level->isRainingAt(xx, yy, zz + 1))) {
int tAge = age + random->nextInt(5) / 4;
if (tAge > 15) tAge = 15;
level->setTileAndData(xx, yy, zz, this->id,
tAge);
level->setTileAndData(xx, yy, zz, id, tAge,
Tile::UPDATE_ALL);
}
}
}
@ -179,6 +185,8 @@ void FireTile::tick(Level* level, int x, int y, int z, Random* random) {
}
}
bool FireTile::canInstantlyTick() { return false; }
void FireTile::checkBurnOut(Level* level, int x, int y, int z, int chance,
Random* random, int age) {
int odds = burnOdds[level->getTile(x, y, z)];
@ -188,9 +196,9 @@ void FireTile::checkBurnOut(Level* level, int x, int y, int z, int chance,
app.GetGameHostOption(eGameHostOption_FireSpreads)) {
int tAge = age + random->nextInt(5) / 4;
if (tAge > 15) tAge = 15;
level->setTileAndData(x, y, z, this->id, tAge);
level->setTileAndData(x, y, z, id, tAge, Tile::UPDATE_ALL);
} else {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
if (wasTnt) {
Tile::tnt->destroy(level, x, y, z, TntTile::EXPLODE_BIT);
@ -243,7 +251,7 @@ bool FireTile::mayPlace(Level* level, int x, int y, int z) {
void FireTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (!level->isTopSolidBlocking(x, y - 1, z) &&
!isValidFireLocation(level, x, y, z)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
}
@ -257,11 +265,11 @@ void FireTile::onPlace(Level* level, int x, int y, int z) {
}
if (!level->isTopSolidBlocking(x, y - 1, z) &&
!isValidFireLocation(level, x, y, z)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
level->addToTickNextTick(x, y, z, id,
getTickDelay() + level->random->nextInt(10));
getTickDelay(level) + level->random->nextInt(10));
}
bool FireTile::isFlammable(int tile) { return flameOdds[tile] > 0; }
@ -270,7 +278,7 @@ void FireTile::animateTick(Level* level, int x, int y, int z, Random* random) {
if (random->nextInt(24) == 0) {
level->playLocalSound(x + 0.5f, y + 0.5f, z + 0.5f,
eSoundType_FIRE_FIRE, 1 + random->nextFloat(),
random->nextFloat() * 0.7f + 0.3f);
random->nextFloat() * 0.7f + 0.3f, false);
}
if (level->isTopSolidBlocking(x, y - 1, z) ||

View file

@ -45,8 +45,9 @@ public:
virtual bool isCubeShaped();
virtual int getRenderShape();
virtual int getResourceCount(Random* random);
virtual int getTickDelay();
virtual int getTickDelay(Level* level);
virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual bool canInstantlyTick();
private:
void checkBurnOut(Level* level, int x, int y, int z, int chance,

View file

@ -5,7 +5,8 @@
#include "../Headers/net.minecraft.world.level.tile.h"
#include "FlowerPotTile.h"
FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, false) {
FlowerPotTile::FlowerPotTile(int id)
: Tile(id, Material::decoration, false) {
updateDefaultShape();
sendTileData();
}
@ -32,7 +33,7 @@ bool FlowerPotTile::use(Level* level, int x, int y, int z,
int type = getTypeFromItem(item);
if (type > 0) {
level->setData(x, y, z, type);
level->setData(x, y, z, type, Tile::UPDATE_CLIENTS);
if (!player->abilities.instabuild) {
if (--item->count <= 0) {
@ -81,7 +82,7 @@ void FlowerPotTile::neighborChanged(Level* level, int x, int y, int z,
if (!level->isTopSolidBlocking(x, y - 1, z)) {
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
}
@ -111,10 +112,10 @@ std::shared_ptr<ItemInstance> FlowerPotTile::getItemFromType(int type) {
new ItemInstance(Tile::cactus));
case TYPE_MUSHROOM_BROWN:
return std::shared_ptr<ItemInstance>(
new ItemInstance(Tile::mushroom1));
new ItemInstance(Tile::mushroom_brown));
case TYPE_MUSHROOM_RED:
return std::shared_ptr<ItemInstance>(
new ItemInstance(Tile::mushroom2));
new ItemInstance(Tile::mushroom_red));
case TYPE_DEAD_BUSH:
return std::shared_ptr<ItemInstance>(
new ItemInstance(Tile::deadBush));
@ -144,8 +145,8 @@ int FlowerPotTile::getTypeFromItem(std::shared_ptr<ItemInstance> item) {
if (id == Tile::rose_Id) return TYPE_FLOWER_RED;
if (id == Tile::flower_Id) return TYPE_FLOWER_YELLOW;
if (id == Tile::cactus_Id) return TYPE_CACTUS;
if (id == Tile::mushroom1_Id) return TYPE_MUSHROOM_BROWN;
if (id == Tile::mushroom2_Id) return TYPE_MUSHROOM_RED;
if (id == Tile::mushroom_brown_Id) return TYPE_MUSHROOM_BROWN;
if (id == Tile::mushroom_red_Id) return TYPE_MUSHROOM_RED;
if (id == Tile::deadBush_Id) return TYPE_DEAD_BUSH;
if (id == Tile::sapling_Id) {
@ -169,4 +170,4 @@ int FlowerPotTile::getTypeFromItem(std::shared_ptr<ItemInstance> item) {
}
return 0;
}
}

View file

@ -3,6 +3,7 @@
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.entity.player.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.inventory.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.world.h"
#include "FurnaceTile.h"
@ -11,7 +12,8 @@
bool FurnaceTile::noDrop = false;
FurnaceTile::FurnaceTile(int id, bool lit) : EntityTile(id, Material::stone) {
FurnaceTile::FurnaceTile(int id, bool lit)
: BaseEntityTile(id, Material::stone) {
random = new Random();
this->lit = lit;
@ -24,7 +26,7 @@ int FurnaceTile::getResource(int data, Random* random, int playerBonusLevel) {
}
void FurnaceTile::onPlace(Level* level, int x, int y, int z) {
EntityTile::onPlace(level, x, y, z);
BaseEntityTile::onPlace(level, x, y, z);
recalcLockDir(level, x, y, z);
}
@ -43,7 +45,7 @@ void FurnaceTile::recalcLockDir(Level* level, int x, int y, int z) {
if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2;
if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5;
if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4;
level->setData(x, y, z, lockDir);
level->setData(x, y, z, lockDir, Tile::UPDATE_CLIENTS);
}
Icon* FurnaceTile::getTexture(int face, int data) {
@ -114,12 +116,12 @@ void FurnaceTile::setLit(bool lit, Level* level, int x, int y, int z) {
noDrop = true;
if (lit)
level->setTile(x, y, z, Tile::furnace_lit_Id);
level->setTileAndUpdate(x, y, z, Tile::furnace_lit_Id);
else
level->setTile(x, y, z, Tile::furnace_Id);
level->setTileAndUpdate(x, y, z, Tile::furnace_Id);
noDrop = false;
level->setData(x, y, z, data);
level->setData(x, y, z, data, Tile::UPDATE_CLIENTS);
if (te != NULL) {
te->clearRemoved();
level->setTileEntity(x, y, z, te);
@ -131,13 +133,20 @@ std::shared_ptr<TileEntity> FurnaceTile::newTileEntity(Level* level) {
}
void FurnaceTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3;
if (dir == 0) level->setData(x, y, z, Facing::NORTH);
if (dir == 1) level->setData(x, y, z, Facing::EAST);
if (dir == 2) level->setData(x, y, z, Facing::SOUTH);
if (dir == 3) level->setData(x, y, z, Facing::WEST);
if (dir == 0) level->setData(x, y, z, Facing::NORTH, Tile::UPDATE_CLIENTS);
if (dir == 1) level->setData(x, y, z, Facing::EAST, Tile::UPDATE_CLIENTS);
if (dir == 2) level->setData(x, y, z, Facing::SOUTH, Tile::UPDATE_CLIENTS);
if (dir == 3) level->setData(x, y, z, Facing::WEST, Tile::UPDATE_CLIENTS);
if (itemInstance->hasCustomHoverName()) {
std::dynamic_pointer_cast<FurnaceTileEntity>(
level->getTileEntity(x, y, z))
->setCustomName(itemInstance->getHoverName());
}
}
void FurnaceTile::onRemove(Level* level, int x, int y, int z, int id,
@ -192,7 +201,20 @@ void FurnaceTile::onRemove(Level* level, int x, int y, int z, int id,
container->setItem(i, nullptr);
}
}
level->updateNeighbourForOutputSignal(x, y, z, id);
}
}
EntityTile::onRemove(level, x, y, z, id, data);
BaseEntityTile::onRemove(level, x, y, z, id, data);
}
bool FurnaceTile::hasAnalogOutputSignal() { return true; }
int FurnaceTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
return AbstractContainerMenu::getRedstoneSignalFromContainer(
std::dynamic_pointer_cast<Container>(level->getTileEntity(x, y, z)));
}
int FurnaceTile::cloneTileId(Level* level, int x, int y, int z) {
return Tile::furnace_Id;
}

View file

@ -1,12 +1,12 @@
#pragma once
#include "TileEntities/EntityTile.h"
#include "BaseEntityTile.h"
class Mob;
class Player;
class Random;
class ChunkRebuildData;
class FurnaceTile : public EntityTile {
class FurnaceTile : public BaseEntityTile {
friend class Tile;
friend class ChunkRebuildData;
@ -44,6 +44,12 @@ protected:
public:
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by);
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
virtual int cloneTileId(Level* level, int x, int y, int z);
};

View file

@ -0,0 +1,19 @@
#include "../Platform/stdafx.h"
#include "GlowstoneTile.h"
#include "../Headers/net.minecraft.world.item.h"
Glowstonetile::Glowstonetile(int id, Material* material) : Tile(id, material) {}
int Glowstonetile::getResourceCountForLootBonus(int bonusLevel,
Random* random) {
return Mth::clamp(
getResourceCount(random) + random->nextInt(bonusLevel + 1), 1, 4);
}
int Glowstonetile::getResourceCount(Random* random) {
return 2 + random->nextInt(3);
}
int Glowstonetile::getResource(int data, Random* random, int playerBonusLevel) {
return Item::yellowDust->id;
}

View file

@ -3,9 +3,9 @@
class Random;
class LightGemTile : public Tile {
class Glowstonetile : public Tile {
public:
LightGemTile(int id, Material* material);
Glowstonetile(int id, Material* material);
virtual int getResourceCountForLootBonus(int bonusLevel, Random* random);
virtual int getResourceCount(Random* random);
virtual int getResource(int data, Random* random, int playerBonusLevel);

View file

@ -87,7 +87,7 @@ void GrassTile::tick(Level* level, int x, int y, int z, Random* random) {
if (level->getRawBrightness(x, y + 1, z) < MIN_BRIGHTNESS &&
Tile::lightBlock[level->getTile(x, y + 1, z)] > 2) {
level->setTile(x, y, z, Tile::dirt_Id);
level->setTileAndUpdate(x, y, z, Tile::dirt_Id);
} else {
if (level->getRawBrightness(x, y + 1, z) >= Level::MAX_BRIGHTNESS - 6) {
for (int i = 0; i < 4; i++) {
@ -98,7 +98,7 @@ void GrassTile::tick(Level* level, int x, int y, int z, Random* random) {
if (level->getTile(xt, yt, zt) == Tile::dirt_Id &&
level->getRawBrightness(xt, yt + 1, zt) >= MIN_BRIGHTNESS &&
Tile::lightBlock[above] <= 2) {
level->setTile(xt, yt, zt, Tile::grass_Id);
level->setTileAndUpdate(xt, yt, zt, Tile::grass_Id);
}
}
}

View file

@ -5,6 +5,7 @@
GravelTile::GravelTile(int type) : HeavyTile(type) {}
int GravelTile::getResource(int data, Random* random, int playerBonusLevel) {
if (playerBonusLevel > 3) playerBonusLevel = 3;
if (random->nextInt(10 - playerBonusLevel * 3) == 0) return Item::flint->id;
return id;
}

View file

@ -6,16 +6,6 @@
#include "../Headers/net.minecraft.stats.h"
#include "../Util/Facing.h"
/*package net.minecraft.world.level.tile;
import java.util.*;
import net.minecraft.Facing;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.*;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.phys.AABB;*/
HalfSlabTile::HalfSlabTile(int id, bool fullSize, Material* material)
: Tile(id, material, fullSize) {
this->fullSize = fullSize;
@ -119,3 +109,20 @@ bool HalfSlabTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
bool HalfSlabTile::isHalfSlab(int tileId) {
return tileId == Tile::stoneSlabHalf_Id || tileId == Tile::woodSlabHalf_Id;
}
int HalfSlabTile::cloneTileData(Level* level, int x, int y, int z) {
return Tile::cloneTileData(level, x, y, z) & TYPE_MASK;
}
int HalfSlabTile::cloneTileId(Level* level, int x, int y, int z) {
if (isHalfSlab(id)) {
return id;
}
if (id == Tile::stoneSlab_Id) {
return Tile::stoneSlabHalf_Id;
}
if (id == Tile::woodSlab_Id) {
return Tile::woodSlabHalf_Id;
}
return Tile::stoneSlabHalf_Id;
}

View file

@ -34,4 +34,7 @@ private:
public:
virtual int getAuxName(int auxValue) = 0;
virtual int cloneTileData(Level* level, int x, int y, int z);
virtual int cloneTileId(Level* level, int x, int y, int z);
};

View file

@ -23,4 +23,4 @@ bool HalfTransparentTile::blocksLight() { return false; }
void HalfTransparentTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(texture);
}
}

View file

@ -19,5 +19,5 @@ public:
virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z,
int face);
virtual bool blocksLight();
void registerIcons(IconRegister* iconRegister);
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -0,0 +1,14 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.h"
#include "HayBlockTile.h"
HayBlockTile::HayBlockTile(int id) : RotatedPillarTile(id, Material::grass) {}
int HayBlockTile::getRenderShape() { return SHAPE_TREE; }
Icon* HayBlockTile::getTypeTexture(int type) { return icon; }
void HayBlockTile::registerIcons(IconRegister* iconRegister) {
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
icon = iconRegister->registerIcon(getIconName() + L"_side");
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "RotatedPillarTile.h"
class HayBlockTile : public RotatedPillarTile {
friend class ChunkRebuildData;
public:
HayBlockTile(int id);
int getRenderShape();
protected:
Icon* getTypeTexture(int type);
public:
void registerIcons(IconRegister* iconRegister);
};

View file

@ -13,11 +13,11 @@ HeavyTile::HeavyTile(int type, Material* material, bool isSolidRender)
: Tile(type, material, isSolidRender) {}
void HeavyTile::onPlace(Level* level, int x, int y, int z) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
void HeavyTile::neighborChanged(Level* level, int x, int y, int z, int type) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
void HeavyTile::tick(Level* level, int x, int y, int z, Random* random) {
@ -35,16 +35,16 @@ void HeavyTile::checkSlide(Level* level, int x, int y, int z) {
if (instaFall ||
!level->hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
while (isFree(level, x, y - 1, z) && y > 0) y--;
if (y > 0) {
level->setTile(x, y, z, id);
level->setTileAndUpdate(x, y, z, id);
}
} else if (!level->isClientSide) {
// 4J added - don't do anything just now if we can't create any new
// falling tiles
if (!level->newFallingTileAllowed()) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
return;
}
@ -59,7 +59,7 @@ void HeavyTile::checkSlide(Level* level, int x, int y, int z) {
void HeavyTile::falling(std::shared_ptr<FallingTile> entity) {}
int HeavyTile::getTickDelay() { return 5; }
int HeavyTile::getTickDelay(Level* level) { return 2; }
bool HeavyTile::isFree(Level* level, int x, int y, int z) {
int t = level->getTile(x, y, z);

View file

@ -22,7 +22,7 @@ protected:
virtual void falling(std::shared_ptr<FallingTile> entity);
public:
virtual int getTickDelay();
virtual int getTickDelay(Level* level);
static bool isFree(Level* level, int x, int y, int z);
virtual void onLand(Level* level, int xt, int yt, int zt, int data);
};

View file

@ -1,4 +0,0 @@
#include "../Platform/stdafx.h"
#include "HellStoneTile.h"
HellStoneTile::HellStoneTile(int id) : Tile(id, Material::stone) {}

View file

@ -1,7 +0,0 @@
#pragma once
#include "Tile.h"
class HellStoneTile : public Tile {
public:
HellStoneTile(int id);
};

View file

@ -0,0 +1,189 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.inventory.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.world.h"
#include "HopperTile.h"
const std::wstring HopperTile::TEXTURE_OUTSIDE = L"hopper_outside";
const std::wstring HopperTile::TEXTURE_INSIDE = L"hopper_inside";
HopperTile::HopperTile(int id)
: BaseEntityTile(id, Material::metal, false) {
setShape(0, 0, 0, 1, 1, 1);
}
void HopperTile::updateShape(LevelSource* level, int x, int y, int z,
int forceData,
std::shared_ptr<TileEntity> forceEntity) {
setShape(0, 0, 0, 1, 1, 1);
}
void HopperTile::addAABBs(Level* level, int x, int y, int z, AABB* box,
AABBList* boxes, std::shared_ptr<Entity> source) {
setShape(0, 0, 0, 1, 10.0f / 16.0f, 1);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
float thickness = 2.0f / 16.0f;
setShape(0, 0, 0, thickness, 1, 1);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
setShape(0, 0, 0, 1, 1, thickness);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
setShape(1 - thickness, 0, 0, 1, 1, 1);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
setShape(0, 0, 1 - thickness, 1, 1, 1);
BaseEntityTile::addAABBs(level, x, y, z, box, boxes, source);
setShape(0, 0, 0, 1, 1, 1);
}
int HopperTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
int face, float clickX, float clickY,
float clickZ, int itemValue) {
int attached = Facing::OPPOSITE_FACING[face];
if (attached == Facing::UP) attached = Facing::DOWN;
return attached;
}
std::shared_ptr<TileEntity> HopperTile::newTileEntity(Level* level) {
return std::shared_ptr<HopperTileEntity>(new HopperTileEntity());
}
void HopperTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
BaseEntityTile::setPlacedBy(level, x, y, z, by, itemInstance);
if (itemInstance->hasCustomHoverName()) {
std::shared_ptr<HopperTileEntity> hopper = getHopper(level, x, y, z);
hopper->setCustomName(itemInstance->getHoverName());
}
}
void HopperTile::onPlace(Level* level, int x, int y, int z) {
BaseEntityTile::onPlace(level, x, y, z);
checkPoweredState(level, x, y, z);
}
bool HopperTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ, bool soundOnly) {
if (level->isClientSide) {
return true;
}
std::shared_ptr<HopperTileEntity> hopper = getHopper(level, x, y, z);
if (hopper != NULL) player->openHopper(hopper);
return true;
}
void HopperTile::neighborChanged(Level* level, int x, int y, int z, int type) {
checkPoweredState(level, x, y, z);
}
void HopperTile::checkPoweredState(Level* level, int x, int y, int z) {
int data = level->getData(x, y, z);
int attachedFace = getAttachedFace(data);
bool shouldBeOn = !level->hasNeighborSignal(x, y, z);
bool isOn = isTurnedOn(data);
if (shouldBeOn != isOn) {
level->setData(x, y, z, attachedFace | (shouldBeOn ? 0 : MASK_TOGGLE),
UPDATE_NONE);
}
}
void HopperTile::onRemove(Level* level, int x, int y, int z, int id, int data) {
std::shared_ptr<Container> container =
std::dynamic_pointer_cast<HopperTileEntity>(
level->getTileEntity(x, y, z));
if (container != NULL) {
for (int i = 0; i < container->getContainerSize(); i++) {
std::shared_ptr<ItemInstance> item = container->getItem(i);
if (item != NULL) {
float xo = random.nextFloat() * 0.8f + 0.1f;
float yo = random.nextFloat() * 0.8f + 0.1f;
float zo = random.nextFloat() * 0.8f + 0.1f;
while (item->count > 0) {
int count = random.nextInt(21) + 10;
if (count > item->count) count = item->count;
item->count -= count;
std::shared_ptr<ItemEntity> itemEntity =
std::shared_ptr<ItemEntity>(new ItemEntity(
level, x + xo, y + yo, z + zo,
std::shared_ptr<ItemInstance>(new ItemInstance(
item->id, count, item->getAuxValue()))));
if (item->hasTag()) {
itemEntity->getItem()->setTag(
(CompoundTag*)item->getTag()->copy());
}
float pow = 0.05f;
itemEntity->xd = (float)random.nextGaussian() * pow;
itemEntity->yd = (float)random.nextGaussian() * pow + 0.2f;
itemEntity->zd = (float)random.nextGaussian() * pow;
level->addEntity(itemEntity);
}
}
}
level->updateNeighbourForOutputSignal(x, y, z, id);
}
BaseEntityTile::onRemove(level, x, y, z, id, data);
}
int HopperTile::getRenderShape() { return SHAPE_HOPPER; }
bool HopperTile::isCubeShaped() { return false; }
bool HopperTile::isSolidRender(bool isServerLevel /*= false*/) { return false; }
bool HopperTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
return true;
}
Icon* HopperTile::getTexture(int face, int data) {
if (face == Facing::UP) {
return hopperTopIcon;
}
return hopperIcon;
}
int HopperTile::getAttachedFace(int data) { return data & MASK_ATTACHED; }
bool HopperTile::isTurnedOn(int data) {
return (data & MASK_TOGGLE) != MASK_TOGGLE;
}
bool HopperTile::hasAnalogOutputSignal() { return true; }
int HopperTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
return AbstractContainerMenu::getRedstoneSignalFromContainer(
getHopper(level, x, y, z));
}
void HopperTile::registerIcons(IconRegister* iconRegister) {
hopperIcon = iconRegister->registerIcon(TEXTURE_OUTSIDE);
hopperTopIcon = iconRegister->registerIcon(L"hopper_top");
hopperInnerIcon = iconRegister->registerIcon(TEXTURE_INSIDE);
}
Icon* HopperTile::getTexture(const std::wstring& name) {
if (name.compare(TEXTURE_OUTSIDE) == 0) return Tile::hopper->hopperIcon;
if (name.compare(TEXTURE_INSIDE) == 0) return Tile::hopper->hopperInnerIcon;
return NULL;
}
std::wstring HopperTile::getTileItemIconName() { return L"hopper"; }
std::shared_ptr<HopperTileEntity> HopperTile::getHopper(LevelSource* level,
int x, int y, int z) {
return std::dynamic_pointer_cast<HopperTileEntity>(
level->getTileEntity(x, y, z));
}

View file

@ -0,0 +1,70 @@
#pragma once
#include "BaseEntityTile.h"
class HopperTileEntity;
class HopperTile : public BaseEntityTile {
friend class ChunkRebuildData;
private:
static const int MASK_TOGGLE = 0x8;
static const int MASK_ATTACHED = 0x7;
public:
static const std::wstring TEXTURE_OUTSIDE;
static const std::wstring TEXTURE_INSIDE;
private:
Random random;
private:
Icon* hopperIcon;
Icon* hopperTopIcon;
Icon* hopperInnerIcon;
public:
HopperTile(int id);
virtual void updateShape(LevelSource* level, int x, int y, int z,
int forceData = -1,
std::shared_ptr<TileEntity> forceEntity =
std::shared_ptr<TileEntity>());
virtual void addAABBs(Level* level, int x, int y, int z, AABB* box,
AABBList* boxes, std::shared_ptr<Entity> source);
virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
int face, float clickX, float clickY,
float clickZ, int itemValue);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
virtual void onPlace(Level* level, int x, int y, int z);
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
private:
virtual void checkPoweredState(Level* level, int x, int y, int z);
public:
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual int getRenderShape();
virtual bool isCubeShaped();
virtual bool isSolidRender(bool isServerLevel = false);
virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z,
int face);
virtual Icon* getTexture(int face, int data);
static int getAttachedFace(int data);
static bool isTurnedOn(int data);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
virtual void registerIcons(IconRegister* iconRegister);
static Icon* getTexture(const std::wstring& name);
virtual std::wstring getTileItemIconName();
static std::shared_ptr<HopperTileEntity> getHopper(LevelSource* level,
int x, int y, int z);
};

View file

@ -2,10 +2,10 @@
#include "../Headers/net.minecraft.world.h"
#include "HugeMushroomTile.h"
const std::wstring HugeMushroomTile::TEXTURE_STEM = L"mushroom_skin_stem";
const std::wstring HugeMushroomTile::TEXTURE_INSIDE = L"mushroom_inside";
const std::wstring HugeMushroomTile::TEXTURE_TYPE[] = {L"mushroom_skin_brown",
L"mushroom_skin_red"};
const std::wstring HugeMushroomTile::TEXTURE_STEM = L"skin_stem";
const std::wstring HugeMushroomTile::TEXTURE_INSIDE = L"inside";
const std::wstring HugeMushroomTile::TEXTURE_TYPE[] = {L"skin_brown",
L"skin_red"};
HugeMushroomTile::HugeMushroomTile(int id, Material* material, int type)
: Tile(id, material) {
@ -46,20 +46,22 @@ int HugeMushroomTile::getResourceCount(Random* random) {
int HugeMushroomTile::getResource(int data, Random* random,
int playerBonusLevel) {
return Tile::mushroom1_Id + type;
return Tile::mushroom_brown_Id + type;
}
int HugeMushroomTile::cloneTileId(Level* level, int x, int y, int z) {
return Tile::mushroom1_Id + type;
return Tile::mushroom_brown_Id + type;
}
void HugeMushroomTile::registerIcons(IconRegister* iconRegister) {
icons = new Icon*[HUGE_MUSHROOM_TEXTURE_COUNT];
for (int i = 0; i < HUGE_MUSHROOM_TEXTURE_COUNT; i++) {
icons[i] = iconRegister->registerIcon(TEXTURE_TYPE[i]);
icons[i] =
iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_TYPE[i]);
}
iconInside = iconRegister->registerIcon(TEXTURE_INSIDE);
iconStem = iconRegister->registerIcon(TEXTURE_STEM);
iconInside =
iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_INSIDE);
iconStem = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_STEM);
}

View file

@ -6,6 +6,9 @@ class HugeMushroomTile : public Tile {
friend class ChunkRebuildData;
public:
static const int MUSHROOM_TYPE_BROWN = 0;
static const int MUSHROOM_TYPE_RED = 1;
static const std::wstring TEXTURE_STEM;
static const std::wstring TEXTURE_INSIDE;

View file

@ -25,24 +25,22 @@ void IceTile::playerDestroy(Level* level, std::shared_ptr<Player> player, int x,
GenericStats::param_blocksMined(id, data, 1));
player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE);
if (isSilkTouchable() &&
EnchantmentHelper::hasSilkTouch(player->inventory)) {
if (isSilkTouchable() && EnchantmentHelper::hasSilkTouch(player)) {
std::shared_ptr<ItemInstance> item = getSilkTouchItemInstance(data);
if (item != NULL) {
popResource(level, x, y, z, item);
}
} else {
if (level->dimension->ultraWarm) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
int playerBonusLevel =
EnchantmentHelper::getDiggingLootBonus(player->inventory);
int playerBonusLevel = EnchantmentHelper::getDiggingLootBonus(player);
spawnResources(level, x, y, z, data, playerBonusLevel);
Material* below = level->getMaterial(x, y - 1, z);
if (below->blocksMotion() || below->isLiquid()) {
level->setTile(x, y, z, Tile::water_Id);
level->setTileAndUpdate(x, y, z, Tile::water_Id);
}
}
}
@ -53,11 +51,11 @@ void IceTile::tick(Level* level, int x, int y, int z, Random* random) {
if (level->getBrightness(LightLayer::Block, x, y, z) >
11 - Tile::lightBlock[id]) {
if (level->dimension->ultraWarm) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
return;
}
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, Tile::calmWater_Id);
level->setTileAndUpdate(x, y, z, Tile::calmWater_Id);
}
}

View file

@ -0,0 +1,159 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.h"
#include "../Headers/net.minecraft.world.h"
#include "JukeboxTile.h"
#include "../Level/Events/LevelEvent.h"
JukeboxTile::Entity::Entity() : TileEntity() { record = nullptr; }
void JukeboxTile::Entity::load(CompoundTag* tag) {
TileEntity::load(tag);
if (tag->contains(L"RecordItem")) {
setRecord(ItemInstance::fromTag(tag->getCompound(L"RecordItem")));
} else if (tag->getInt(L"Record") > 0) {
setRecord(std::shared_ptr<ItemInstance>(
new ItemInstance(tag->getInt(L"Record"), 1, 0)));
}
}
void JukeboxTile::Entity::save(CompoundTag* tag) {
TileEntity::save(tag);
if (getRecord() != NULL) {
tag->putCompound(L"RecordItem", getRecord()->save(new CompoundTag()));
tag->putInt(L"Record", getRecord()->id);
}
}
// 4J Added
std::shared_ptr<TileEntity> JukeboxTile::Entity::clone() {
std::shared_ptr<JukeboxTile::Entity> result =
std::shared_ptr<JukeboxTile::Entity>(new JukeboxTile::Entity());
TileEntity::clone(result);
result->record = record;
return result;
}
std::shared_ptr<ItemInstance> JukeboxTile::Entity::getRecord() {
return record;
}
void JukeboxTile::Entity::setRecord(std::shared_ptr<ItemInstance> record) {
this->record = record;
setChanged();
}
JukeboxTile::JukeboxTile(int id) : BaseEntityTile(id, Material::wood) {
iconTop = NULL;
}
Icon* JukeboxTile::getTexture(int face, int data) {
if (face == Facing::UP) {
return iconTop;
}
return icon;
}
// 4J-PB - Adding a TestUse for tooltip display
bool JukeboxTile::TestUse(Level* level, int x, int y, int z,
std::shared_ptr<Player> player) {
// if the jukebox is empty, return true
if (level->getData(x, y, z) == 0) return false;
return true;
}
bool JukeboxTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly /*=false*/) // 4J added soundOnly param
{
if (soundOnly) return false;
if (level->getData(x, y, z) == 0) return false;
dropRecording(level, x, y, z);
return true;
}
void JukeboxTile::setRecord(Level* level, int x, int y, int z,
std::shared_ptr<ItemInstance> record) {
if (level->isClientSide) return;
std::shared_ptr<JukeboxTile::Entity> rte =
std::dynamic_pointer_cast<JukeboxTile::Entity>(
level->getTileEntity(x, y, z));
rte->setRecord(record->copy());
rte->setChanged();
level->setData(x, y, z, 1, Tile::UPDATE_CLIENTS);
}
void JukeboxTile::dropRecording(Level* level, int x, int y, int z) {
if (level->isClientSide) return;
std::shared_ptr<JukeboxTile::Entity> rte =
std::dynamic_pointer_cast<JukeboxTile::Entity>(
level->getTileEntity(x, y, z));
if (rte == NULL) return;
std::shared_ptr<ItemInstance> oldRecord = rte->getRecord();
if (oldRecord == NULL) return;
level->levelEvent(LevelEvent::SOUND_PLAY_RECORDING, x, y, z, 0);
// 4J-PB- the level event will play the music
// level->playStreamingMusic(L"", x, y, z);
rte->setRecord(nullptr);
rte->setChanged();
level->setData(x, y, z, 0, Tile::UPDATE_CLIENTS);
float s = 0.7f;
double xo = level->random->nextFloat() * s + (1 - s) * 0.5;
double yo = level->random->nextFloat() * s + (1 - s) * 0.2 + 0.6;
double zo = level->random->nextFloat() * s + (1 - s) * 0.5;
std::shared_ptr<ItemInstance> itemInstance = oldRecord->copy();
std::shared_ptr<ItemEntity> item = std::shared_ptr<ItemEntity>(
new ItemEntity(level, x + xo, y + yo, z + zo, itemInstance));
item->throwTime = 10;
level->addEntity(item);
}
void JukeboxTile::onRemove(Level* level, int x, int y, int z, int id,
int data) {
dropRecording(level, x, y, z);
Tile::onRemove(level, x, y, z, id, data);
}
void JukeboxTile::spawnResources(Level* level, int x, int y, int z, int data,
float odds, int playerBonus) {
if (level->isClientSide) return;
Tile::spawnResources(level, x, y, z, data, odds, 0);
}
std::shared_ptr<TileEntity> JukeboxTile::newTileEntity(Level* level) {
return std::shared_ptr<JukeboxTile::Entity>(new JukeboxTile::Entity());
}
void JukeboxTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(getIconName() + L"_side");
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
}
bool JukeboxTile::hasAnalogOutputSignal() { return true; }
int JukeboxTile::getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir) {
std::shared_ptr<ItemInstance> record =
std::dynamic_pointer_cast<JukeboxTile::Entity>(
level->getTileEntity(x, y, z))
->getRecord();
return record == NULL ? Redstone::SIGNAL_NONE
: record->id + 1 - Item::record_01_Id;
}

View file

@ -0,0 +1,61 @@
#pragma once
#include "BaseEntityTile.h"
#include "../IO/NBT/CompoundTag.h"
#include "TileEntities/TileEntity.h"
class CompoundTag;
class ChunkRebuildData;
class JukeboxTile : public BaseEntityTile {
friend class Tile;
friend class ChunkRebuildData;
public:
class Entity : public TileEntity {
public:
eINSTANCEOF GetType() { return eTYPE_RECORDPLAYERTILE; }
static TileEntity* create() { return new JukeboxTile::Entity(); }
private:
std::shared_ptr<ItemInstance> record;
public:
Entity();
virtual void load(CompoundTag* tag);
virtual void save(CompoundTag* tag);
virtual std::shared_ptr<ItemInstance> getRecord();
virtual void setRecord(std::shared_ptr<ItemInstance> record);
// 4J Added
std::shared_ptr<TileEntity> clone();
};
private:
Icon* iconTop;
protected:
JukeboxTile(int id);
public:
virtual Icon* getTexture(int face, int data);
virtual bool TestUse(Level* level, int x, int y, int z,
std::shared_ptr<Player> player);
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
void setRecord(Level* level, int x, int y, int z,
std::shared_ptr<ItemInstance> record);
void dropRecording(Level* level, int x, int y, int z);
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual void spawnResources(Level* level, int x, int y, int z, int data,
float odds, int playerBonus);
virtual std::shared_ptr<TileEntity> newTileEntity(Level* level);
virtual void registerIcons(IconRegister* iconRegister);
virtual bool hasAnalogOutputSignal();
virtual int getAnalogOutputSignal(Level* level, int x, int y, int z,
int dir);
};

View file

@ -2,7 +2,8 @@
#include "../Headers/net.minecraft.world.level.h"
#include "LadderTile.h"
LadderTile::LadderTile(int id) : Tile(id, Material::decoration, false) {}
LadderTile::LadderTile(int id)
: Tile(id, Material::decoration, false) {}
AABB* LadderTile::getAABB(Level* level, int x, int y, int z) {
updateShape(level, x, y, z);
@ -80,10 +81,10 @@ void LadderTile::neighborChanged(Level* level, int x, int y, int z, int type) {
if (face == 5 && level->isSolidBlockingTile(x - 1, y, z)) ok = true;
if (!ok) {
spawnResources(level, x, y, z, face, 0);
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
Tile::neighborChanged(level, x, y, z, type);
}
int LadderTile::getResourceCount(Random* random) { return 1; }
int LadderTile::getResourceCount(Random* random) { return 1; }

View file

@ -100,8 +100,9 @@ void LeafTile::onRemove(Level* level, int x, int y, int z, int id, int data) {
if (t == Tile::leaves_Id) {
int currentData =
level->getData(x + xo, y + yo, z + zo);
level->setDataNoUpdate(x + xo, y + yo, z + zo,
currentData | UPDATE_LEAF_BIT);
level->setData(x + xo, y + yo, z + zo,
currentData | UPDATE_LEAF_BIT,
Tile::UPDATE_NONE);
}
}
}
@ -113,7 +114,7 @@ void LeafTile::tick(Level* level, int x, int y, int z, Random* random) {
int currentData = level->getData(x, y, z);
if ((currentData & UPDATE_LEAF_BIT) != 0 &&
(currentData & PERSISTENT_LEAF_BIT) == 0) {
int r = LeafTile::REQUIRED_WOOD_RANGE;
int r = REQUIRED_WOOD_RANGE;
int r2 = r + 1;
int W = 32;
@ -143,7 +144,7 @@ void LeafTile::tick(Level* level, int x, int y, int z, Random* random) {
(zo + WO)] = -1;
}
}
for (int i = 1; i <= LeafTile::REQUIRED_WOOD_RANGE; i++) {
for (int i = 1; i <= REQUIRED_WOOD_RANGE; i++) {
for (int xo = -r; xo <= r; xo++)
for (int yo = -r; yo <= r; yo++)
for (int zo = -r; zo <= r; zo++) {
@ -192,7 +193,8 @@ void LeafTile::tick(Level* level, int x, int y, int z, Random* random) {
int mid = checkBuffer[(WO)*WW + (WO)*W + (WO)];
if (mid >= 0) {
level->setDataNoUpdate(x, y, z, currentData & ~UPDATE_LEAF_BIT);
level->setData(x, y, z, currentData & ~UPDATE_LEAF_BIT,
Tile::UPDATE_NONE);
} else {
die(level, x, y, z);
}
@ -212,7 +214,7 @@ void LeafTile::animateTick(Level* level, int x, int y, int z, Random* random) {
void LeafTile::die(Level* level, int x, int y, int z) {
Tile::spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
int LeafTile::getResourceCount(Random* random) {
@ -231,6 +233,12 @@ void LeafTile::spawnResources(Level* level, int x, int y, int z, int data,
if ((data & LEAF_TYPE_MASK) == JUNGLE_LEAF) {
chance = 40;
}
if (playerBonusLevel > 0) {
chance -= 2 << playerBonusLevel;
if (chance < 10) {
chance = 10;
}
}
if (level->random->nextInt(chance) == 0) {
int type = getResource(data, level->random, playerBonusLevel);
popResource(level, x, y, z,
@ -238,8 +246,15 @@ void LeafTile::spawnResources(Level* level, int x, int y, int z, int data,
type, 1, getSpawnResourcesAuxValue(data))));
}
chance = 200;
if (playerBonusLevel > 0) {
chance -= 10 << playerBonusLevel;
if (chance < 40) {
chance = 40;
}
}
if ((data & LEAF_TYPE_MASK) == NORMAL_LEAF &&
level->random->nextInt(200) == 0) {
level->random->nextInt(chance) == 0) {
popResource(level, x, y, z,
std::shared_ptr<ItemInstance>(
new ItemInstance(Item::apple_Id, 1, 0)));
@ -282,6 +297,9 @@ Icon* LeafTile::getTexture(int face, int data) {
if ((data & LEAF_TYPE_MASK) == JUNGLE_LEAF) {
return icons[fancyTextureSet][JUNGLE_LEAF];
}
if ((data & LEAF_TYPE_MASK) == BIRCH_LEAF) {
return icons[fancyTextureSet][BIRCH_LEAF];
}
return icons[fancyTextureSet][0];
}

View file

@ -1,10 +1,11 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.redstone.h"
#include "../Headers/net.minecraft.h"
#include "LeverTile.h"
#include "../Util/SoundTypes.h"
LeverTile::LeverTile(int id) : Tile(id, Material::decoration, false) {}
LeverTile::LeverTile(int id)
: Tile(id, Material::decoration, false) {}
AABB* LeverTile::getAABB(Level* level, int x, int y, int z) { return NULL; }
@ -17,12 +18,18 @@ bool LeverTile::isCubeShaped() { return false; }
int LeverTile::getRenderShape() { return Tile::SHAPE_LEVER; }
bool LeverTile::mayPlace(Level* level, int x, int y, int z, int face) {
if (face == 0 && level->isSolidBlockingTile(x, y + 1, z)) return true;
if (face == 1 && level->isTopSolidBlocking(x, y - 1, z)) return true;
if (face == 2 && level->isSolidBlockingTile(x, y, z + 1)) return true;
if (face == 3 && level->isSolidBlockingTile(x, y, z - 1)) return true;
if (face == 4 && level->isSolidBlockingTile(x + 1, y, z)) return true;
if (face == 5 && level->isSolidBlockingTile(x - 1, y, z)) return true;
if (face == Facing::DOWN && level->isSolidBlockingTile(x, y + 1, z))
return true;
if (face == Facing::UP && level->isTopSolidBlocking(x, y - 1, z))
return true;
if (face == Facing::NORTH && level->isSolidBlockingTile(x, y, z + 1))
return true;
if (face == Facing::SOUTH && level->isSolidBlockingTile(x, y, z - 1))
return true;
if (face == Facing::WEST && level->isSolidBlockingTile(x + 1, y, z))
return true;
if (face == Facing::EAST && level->isSolidBlockingTile(x - 1, y, z))
return true;
return false;
}
@ -68,6 +75,28 @@ int LeverTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
return dir + oldFlip;
}
void LeverTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance) {
int data = level->getData(x, y, z);
int dir = data & 7;
int flip = data & 8;
if (dir == getLeverFacing(Facing::UP)) {
if ((Mth::floor(by->yRot * 4 / (360) + 0.5) & 1) == 0) {
level->setData(x, y, z, 5 | flip, Tile::UPDATE_CLIENTS);
} else {
level->setData(x, y, z, 6 | flip, Tile::UPDATE_CLIENTS);
}
} else if (dir == getLeverFacing(Facing::DOWN)) {
if ((Mth::floor(by->yRot * 4 / (360) + 0.5) & 1) == 0) {
level->setData(x, y, z, 7 | flip, Tile::UPDATE_CLIENTS);
} else {
level->setData(x, y, z, 0 | flip, Tile::UPDATE_CLIENTS);
}
}
}
int LeverTile::getLeverFacing(int facing) {
switch (facing) {
case Facing::DOWN:
@ -107,16 +136,16 @@ void LeverTile::neighborChanged(Level* level, int x, int y, int z, int type) {
replace = true;
if (replace) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->removeTile(x, y, z);
}
}
}
bool LeverTile::checkCanSurvive(Level* level, int x, int y, int z) {
if (!mayPlace(level, x, y, z)) {
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->setTile(x, y, z, 0);
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
level->removeTile(x, y, z);
return false;
}
return true;
@ -146,11 +175,6 @@ void LeverTile::updateShape(
}
}
void LeverTile::attack(Level* level, int x, int y, int z,
std::shared_ptr<Player> player) {
use(level, x, y, z, player, 0, 0, 0, 0);
}
// 4J-PB - Adding a TestUse for tooltip display
bool LeverTile::TestUse() { return true; }
@ -182,7 +206,7 @@ bool LeverTile::use(Level* level, int x, int y, int z,
int dir = data & 7;
int open = 8 - (data & 8);
level->setData(x, y, z, dir + open);
level->setData(x, y, z, dir + open, Tile::UPDATE_ALL);
level->setTilesDirty(x, y, z, x, y, z);
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_CLICK, 0.3f,
@ -227,25 +251,27 @@ void LeverTile::onRemove(Level* level, int x, int y, int z, int id, int data) {
Tile::onRemove(level, x, y, z, id, data);
}
bool LeverTile::getSignal(LevelSource* level, int x, int y, int z, int dir) {
return (level->getData(x, y, z) & 8) > 0;
int LeverTile::getSignal(LevelSource* level, int x, int y, int z, int dir) {
return (level->getData(x, y, z) & 8) > 0 ? Redstone::SIGNAL_MAX
: Redstone::SIGNAL_NONE;
}
bool LeverTile::getDirectSignal(Level* level, int x, int y, int z, int dir) {
int LeverTile::getDirectSignal(LevelSource* level, int x, int y, int z,
int dir) {
int data = level->getData(x, y, z);
if ((data & 8) == 0) return false;
if ((data & 8) == 0) return Redstone::SIGNAL_NONE;
int myDir = data & 7;
if (myDir == 0 && dir == 0) return true;
if (myDir == 7 && dir == 0) return true;
if (myDir == 6 && dir == 1) return true;
if (myDir == 5 && dir == 1) return true;
if (myDir == 4 && dir == 2) return true;
if (myDir == 3 && dir == 3) return true;
if (myDir == 2 && dir == 4) return true;
if (myDir == 1 && dir == 5) return true;
if (myDir == 0 && dir == 0) return Redstone::SIGNAL_MAX;
if (myDir == 7 && dir == 0) return Redstone::SIGNAL_MAX;
if (myDir == 6 && dir == 1) return Redstone::SIGNAL_MAX;
if (myDir == 5 && dir == 1) return Redstone::SIGNAL_MAX;
if (myDir == 4 && dir == 2) return Redstone::SIGNAL_MAX;
if (myDir == 3 && dir == 3) return Redstone::SIGNAL_MAX;
if (myDir == 2 && dir == 4) return Redstone::SIGNAL_MAX;
if (myDir == 1 && dir == 5) return Redstone::SIGNAL_MAX;
return false;
return Redstone::SIGNAL_NONE;
}
bool LeverTile::isSignalSource() { return true; }

View file

@ -18,6 +18,9 @@ public:
virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z,
int face, float clickX, float clickY,
float clickZ, int itemValue);
virtual void setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<LivingEntity> by,
std::shared_ptr<ItemInstance> itemInstance);
static int getLeverFacing(int facing);
virtual void neighborChanged(Level* level, int x, int y, int z, int type);
@ -29,15 +32,14 @@ public:
LevelSource* level, int x, int y, int z, int forceData = -1,
std::shared_ptr<TileEntity> forceEntity = std::shared_ptr<
TileEntity>()); // 4J added forceData, forceEntity param
virtual void attack(Level* level, int x, int y, int z,
std::shared_ptr<Player> player);
virtual bool TestUse();
virtual bool use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly = false); // 4J added soundOnly param
virtual void onRemove(Level* level, int x, int y, int z, int id, int data);
virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir);
virtual int getSignal(LevelSource* level, int x, int y, int z, int dir);
virtual int getDirectSignal(LevelSource* level, int x, int y, int z,
int dir);
virtual bool isSignalSource();
};

View file

@ -1,18 +0,0 @@
#include "../Platform/stdafx.h"
#include "LightGemTile.h"
#include "../Headers/net.minecraft.world.item.h"
LightGemTile::LightGemTile(int id, Material* material) : Tile(id, material) {}
int LightGemTile::getResourceCountForLootBonus(int bonusLevel, Random* random) {
return Mth::clamp(
getResourceCount(random) + random->nextInt(bonusLevel + 1), 1, 4);
}
int LightGemTile::getResourceCount(Random* random) {
return 2 + random->nextInt(3);
}
int LightGemTile::getResource(int data, Random* random, int playerBonusLevel) {
return Item::yellowDust->id;
}

View file

@ -1,6 +1,7 @@
#include "../Platform/stdafx.h"
#include "../Util/JavaMath.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.dimension.h"
#include "../Headers/net.minecraft.world.level.biome.h"
#include "../Headers/net.minecraft.world.h"
#include "LiquidTile.h"
@ -12,7 +13,8 @@ const std::wstring LiquidTile::TEXTURE_WATER_STILL = L"water";
const std::wstring LiquidTile::TEXTURE_WATER_FLOW = L"water_flow";
const std::wstring LiquidTile::TEXTURE_LAVA_FLOW = L"lava_flow";
LiquidTile::LiquidTile(int id, Material* material) : Tile(id, material, false) {
LiquidTile::LiquidTile(int id, Material* material)
: Tile(id, material, false) {
float yo = 0;
float e = 0;
@ -89,7 +91,7 @@ bool LiquidTile::mayPick(int data, bool liquid) { return liquid && data == 0; }
bool LiquidTile::isSolidFace(LevelSource* level, int x, int y, int z,
int face) {
Material* m = level->getMaterial(x, y, z);
if (m == this->material) return false;
if (m == material) return false;
if (face == Facing::UP) return true;
if (m == Material::ice) return false;
@ -99,7 +101,7 @@ bool LiquidTile::isSolidFace(LevelSource* level, int x, int y, int z,
bool LiquidTile::shouldRenderFace(LevelSource* level, int x, int y, int z,
int face) {
Material* m = level->getMaterial(x, y, z);
if (m == this->material) return false;
if (m == material) return false;
if (face == Facing::UP) return true;
if (m == Material::ice) return false;
return Tile::shouldRenderFace(level, x, y, z, face);
@ -170,9 +172,15 @@ void LiquidTile::handleEntityInside(Level* level, int x, int y, int z,
current->z += flow->z;
}
int LiquidTile::getTickDelay() {
int LiquidTile::getTickDelay(Level* level) {
if (material == Material::water) return 5;
if (material == Material::lava) return 30;
if (material == Material::lava) {
if (level->dimension->hasCeiling) {
return 10;
} else {
return 30;
}
}
return 0;
}
@ -213,8 +221,8 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z,
}
// 4J-PB - this loop won't run!
for (int i = 0; i < 0; i++) { // This was an attempt to add foam to
// the bottoms of waterfalls. It
// didn't went ok.
// the bottoms of waterfalls. It
// didn't went ok.
int dir = random->nextInt(4);
int xt = x;
int zt = z;
@ -252,7 +260,7 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z,
level->playLocalSound(x + 0.5f, y + 0.5f, z + 0.5f,
eSoundType_LIQUID_WATER,
random->nextFloat() * 0.25f + 0.75f,
random->nextFloat() * 1.0f + 0.5f);
random->nextFloat() * 1.0f + 0.5f, false);
}
}
if (material == Material::lava) {
@ -268,13 +276,15 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z,
// 4J - new sound brought forward from 1.2.3
level->playLocalSound(xx, yy, zz, eSoundType_LIQUID_LAVA_POP,
0.2f + random->nextFloat() * 0.2f,
0.9f + random->nextFloat() * 0.15f);
0.9f + random->nextFloat() * 0.15f,
false);
}
// 4J - new sound brought forward from 1.2.3
if (random->nextInt(200) == 0) {
level->playLocalSound(x, y, z, eSoundType_LIQUID_LAVA,
0.2f + random->nextFloat() * 0.2f,
0.9f + random->nextFloat() * 0.15f);
0.9f + random->nextFloat() * 0.15f,
false);
}
}
}
@ -331,9 +341,9 @@ void LiquidTile::updateLiquid(Level* level, int x, int y, int z) {
if (water) {
int data = level->getData(x, y, z);
if (data == 0) {
level->setTile(x, y, z, Tile::obsidian_Id);
level->setTileAndUpdate(x, y, z, Tile::obsidian_Id);
} else if (data <= 4) {
level->setTile(x, y, z, Tile::stoneBrick_Id);
level->setTileAndUpdate(x, y, z, Tile::cobblestone_Id);
}
fizz(level, x, y, z);
}

View file

@ -51,7 +51,7 @@ private:
public:
virtual void handleEntityInside(Level* level, int x, int y, int z,
std::shared_ptr<Entity> e, Vec3* current);
virtual int getTickDelay();
virtual int getTickDelay(Level* level);
virtual int getLightColor(
LevelSource* level, int x, int y, int z,
int tileId = -1); // 4J - brought forward from 1.8.2

View file

@ -18,8 +18,7 @@ LiquidTileDynamic::~LiquidTileDynamic() {
void LiquidTileDynamic::setStatic(Level* level, int x, int y, int z) {
int d = level->getData(x, y, z);
level->setTileAndDataNoUpdate(x, y, z, id + 1, d);
level->setTilesDirty(x, y, z, x, y, z);
level->setTileAndData(x, y, z, id + 1, d, Tile::UPDATE_CLIENTS);
}
bool LiquidTileDynamic::isPathfindable(LevelSource* level, int x, int y,
@ -31,12 +30,15 @@ void LiquidTileDynamic::iterativeTick(Level* level, int x, int y, int z,
Random* random) {
m_tilesToTick.push_back(LiquidTickData(level, x, y, z, random));
while (m_tilesToTick.size() > 0) {
int failsafe = 100;
while ((m_tilesToTick.size() > 0) && (failsafe > 0)) {
LiquidTickData tickData = m_tilesToTick.front();
m_tilesToTick.pop_front();
mainTick(tickData.level, tickData.x, tickData.y, tickData.z,
tickData.random);
failsafe--;
}
m_tilesToTick.clear();
}
void LiquidTileDynamic::tick(Level* level, int x, int y, int z,
@ -63,6 +65,7 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z,
if (material == Material::lava && !level->dimension->ultraWarm) dropOff = 2;
bool becomeStatic = true;
int tickDelay = getTickDelay(level);
if (depth > 0) {
int highest = -100;
maxCount = 0;
@ -96,8 +99,7 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z,
if (depth < 8 && newDepth < 8) {
if (newDepth > depth) {
if (random->nextInt(4) != 0) {
newDepth = depth;
becomeStatic = false;
tickDelay = tickDelay * 4;
}
}
}
@ -109,10 +111,10 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z,
} else {
depth = newDepth;
if (depth < 0) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
} else {
level->setData(x, y, z, depth);
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->setData(x, y, z, depth, Tile::UPDATE_CLIENTS);
level->addToTickNextTick(x, y, z, id, tickDelay);
level->updateNeighborsAt(x, y, z, id);
}
}
@ -122,7 +124,7 @@ void LiquidTileDynamic::mainTick(Level* level, int x, int y, int z,
if (canSpreadTo(level, x, y - 1, z)) {
if (material == Material::lava) {
if (level->getMaterial(x, y - 1, z) == Material::water) {
level->setTile(x, y - 1, z, Tile::rock_Id);
level->setTileAndUpdate(x, y - 1, z, Tile::stone_Id);
fizz(level, x, y - 1, z);
return;
}
@ -161,7 +163,7 @@ void LiquidTileDynamic::trySpreadTo(Level* level, int x, int y, int z,
}
}
}
level->setTileAndData(x, y, z, id, neighbor);
level->setTileAndData(x, y, z, id, neighbor, Tile::UPDATE_ALL);
}
}
@ -288,6 +290,8 @@ bool LiquidTileDynamic::canSpreadTo(Level* level, int x, int y, int z) {
void LiquidTileDynamic::onPlace(Level* level, int x, int y, int z) {
LiquidTile::onPlace(level, x, y, z);
if (level->getTile(x, y, z) == id) {
level->addToTickNextTick(x, y, z, id, getTickDelay());
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
}
bool LiquidTileDynamic::canInstantlyTick() { return true; }

View file

@ -57,4 +57,5 @@ private:
public:
void onPlace(Level* level, int x, int y, int z);
bool canInstantlyTick();
};

View file

@ -23,11 +23,8 @@ void LiquidTileStatic::neighborChanged(Level* level, int x, int y, int z,
void LiquidTileStatic::setDynamic(Level* level, int x, int y, int z) {
int d = level->getData(x, y, z);
level->noNeighborUpdate = true;
level->setTileAndDataNoUpdate(x, y, z, id - 1, d);
level->setTilesDirty(x, y, z, x, y, z);
level->addToTickNextTick(x, y, z, id - 1, getTickDelay());
level->noNeighborUpdate = false;
level->setTileAndData(x, y, z, id - 1, d, Tile::UPDATE_CLIENTS);
level->addToTickNextTick(x, y, z, id - 1, getTickDelay(level));
}
void LiquidTileStatic::tick(Level* level, int x, int y, int z, Random* random) {
@ -45,7 +42,7 @@ void LiquidTileStatic::tick(Level* level, int x, int y, int z, Random* random) {
isFlammable(level, x, y, z + 1) ||
isFlammable(level, x, y - 1, z) ||
isFlammable(level, x, y + 1, z)) {
level->setTile(x, y, z, Tile::fire_Id);
level->setTileAndUpdate(x, y, z, Tile::fire_Id);
return;
}
} else if (Tile::tiles[t]->material->blocksMotion()) {
@ -60,7 +57,7 @@ void LiquidTileStatic::tick(Level* level, int x, int y, int z, Random* random) {
z = oz + random->nextInt(3) - 1;
if (level->isEmptyTile(x, y + 1, z) &&
isFlammable(level, x, y, z)) {
level->setTile(x, y + 1, z, Tile::fire_Id);
level->setTileAndUpdate(x, y + 1, z, Tile::fire_Id);
}
}
}

View file

@ -9,7 +9,7 @@ bool LockedChestTile::mayPlace(Level* level, int x, int y, int z) {
}
void LockedChestTile::tick(Level* level, int x, int y, int z, Random* random) {
level->setTile(x, y, z, 0);
level->removeTile(x, y, z);
}
void LockedChestTile::registerIcons(IconRegister* iconRegister) {

View file

@ -4,9 +4,6 @@
#include "../Headers/net.minecraft.world.h"
#include "../Util/Facing.h"
const std::wstring MelonTile::TEX = L"melon_side";
const std::wstring MelonTile::TEX_TOP = L"melon_top";
MelonTile::MelonTile(int id) : Tile(id, Material::vegetable) { iconTop = NULL; }
Icon* MelonTile::getTexture(int face, int data) {
@ -31,6 +28,6 @@ int MelonTile::getResourceCountForLootBonus(int bonusLevel, Random* random) {
}
void MelonTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(TEX);
iconTop = iconRegister->registerIcon(TEX_TOP);
icon = iconRegister->registerIcon(getIconName() + L"_side");
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
}

View file

@ -6,9 +6,6 @@ class MelonTile : public Tile {
friend class ChunkRebuildData;
private:
static const std::wstring TEX;
static const std::wstring TEX_TOP;
Icon* iconTop;
// 4J Stu - I don't know why this is protected in Java

Some files were not shown because too many files have changed in this diff Show more