mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-29 08:23:38 +00:00
TU19: merge Minecraft.World/Blocks
This commit is contained in:
parent
f25cd66f4d
commit
9b6046cb83
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
32
Minecraft.World/Blocks/BaseEntityTile.cpp
Normal file
32
Minecraft.World/Blocks/BaseEntityTile.cpp
Normal 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;
|
||||
}
|
||||
16
Minecraft.World/Blocks/BaseEntityTile.h
Normal file
16
Minecraft.World/Blocks/BaseEntityTile.h
Normal 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);
|
||||
};
|
||||
163
Minecraft.World/Blocks/BasePressurePlateTile.cpp
Normal file
163
Minecraft.World/Blocks/BasePressurePlateTile.cpp
Normal 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);
|
||||
}
|
||||
59
Minecraft.World/Blocks/BasePressurePlateTile.h
Normal file
59
Minecraft.World/Blocks/BasePressurePlateTile.h
Normal 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);
|
||||
};
|
||||
418
Minecraft.World/Blocks/BaseRailTile.cpp
Normal file
418
Minecraft.World/Blocks/BaseRailTile.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
97
Minecraft.World/Blocks/BaseRailTile.h
Normal file
97
Minecraft.World/Blocks/BaseRailTile.h
Normal 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);
|
||||
};
|
||||
52
Minecraft.World/Blocks/BeaconTile.cpp
Normal file
52
Minecraft.World/Blocks/BeaconTile.cpp
Normal 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; }
|
||||
22
Minecraft.World/Blocks/BeaconTile.h
Normal file
22
Minecraft.World/Blocks/BeaconTile.h
Normal 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();
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
@ -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();
|
||||
};
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
26
Minecraft.World/Blocks/ColoredTile.cpp
Normal file
26
Minecraft.World/Blocks/ColoredTile.cpp
Normal 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)]);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
86
Minecraft.World/Blocks/CommandBlock.cpp
Normal file
86
Minecraft.World/Blocks/CommandBlock.cpp
Normal 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; }
|
||||
27
Minecraft.World/Blocks/CommandBlock.h
Normal file
27
Minecraft.World/Blocks/CommandBlock.h
Normal 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);
|
||||
};
|
||||
215
Minecraft.World/Blocks/ComparatorTile.cpp
Normal file
215
Minecraft.World/Blocks/ComparatorTile.cpp
Normal 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; }
|
||||
68
Minecraft.World/Blocks/ComparatorTile.h
Normal file
68
Minecraft.World/Blocks/ComparatorTile.h
Normal 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();
|
||||
};
|
||||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
96
Minecraft.World/Blocks/DaylightDetectorTile.cpp
Normal file
96
Minecraft.World/Blocks/DaylightDetectorTile.cpp
Normal 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");
|
||||
}
|
||||
30
Minecraft.World/Blocks/DaylightDetectorTile.h
Normal file
30
Minecraft.World/Blocks/DaylightDetectorTile.h
Normal 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);
|
||||
};
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
68
Minecraft.World/Blocks/DropperTile.cpp
Normal file
68
Minecraft.World/Blocks/DropperTile.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
23
Minecraft.World/Blocks/DropperTile.h
Normal file
23
Minecraft.World/Blocks/DropperTile.h
Normal 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);
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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) ||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
19
Minecraft.World/Blocks/GlowstoneTile.cpp
Normal file
19
Minecraft.World/Blocks/GlowstoneTile.cpp
Normal 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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -23,4 +23,4 @@ bool HalfTransparentTile::blocksLight() { return false; }
|
|||
|
||||
void HalfTransparentTile::registerIcons(IconRegister* iconRegister) {
|
||||
icon = iconRegister->registerIcon(texture);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
14
Minecraft.World/Blocks/HayBlockTile.cpp
Normal file
14
Minecraft.World/Blocks/HayBlockTile.cpp
Normal 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");
|
||||
}
|
||||
18
Minecraft.World/Blocks/HayBlockTile.h
Normal file
18
Minecraft.World/Blocks/HayBlockTile.h
Normal 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);
|
||||
};
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
#include "../Platform/stdafx.h"
|
||||
#include "HellStoneTile.h"
|
||||
|
||||
HellStoneTile::HellStoneTile(int id) : Tile(id, Material::stone) {}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#pragma once
|
||||
#include "Tile.h"
|
||||
|
||||
class HellStoneTile : public Tile {
|
||||
public:
|
||||
HellStoneTile(int id);
|
||||
};
|
||||
189
Minecraft.World/Blocks/HopperTile.cpp
Normal file
189
Minecraft.World/Blocks/HopperTile.cpp
Normal 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));
|
||||
}
|
||||
70
Minecraft.World/Blocks/HopperTile.h
Normal file
70
Minecraft.World/Blocks/HopperTile.h
Normal 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);
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
159
Minecraft.World/Blocks/JukeboxTile.cpp
Normal file
159
Minecraft.World/Blocks/JukeboxTile.cpp
Normal 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;
|
||||
}
|
||||
61
Minecraft.World/Blocks/JukeboxTile.h
Normal file
61
Minecraft.World/Blocks/JukeboxTile.h
Normal 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);
|
||||
};
|
||||
|
|
@ -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; }
|
||||
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
@ -57,4 +57,5 @@ private:
|
|||
|
||||
public:
|
||||
void onPlace(Level* level, int x, int y, int z);
|
||||
bool canInstantlyTick();
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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
Loading…
Reference in a new issue