TU19: merge Minecraft.World/Level

This commit is contained in:
Tropical 2026-03-21 17:07:51 -05:00
parent 29522d1ac9
commit 86e08af338
73 changed files with 3013 additions and 1259 deletions

View file

@ -0,0 +1,362 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "BaseMobSpawner.h"
BaseMobSpawner::BaseMobSpawner() {
spawnPotentials = NULL;
spawnDelay = 20;
entityId = L"Pig";
nextSpawnData = NULL;
spin = oSpin = 0.0;
minSpawnDelay = SharedConstants::TICKS_PER_SECOND * 10;
maxSpawnDelay = SharedConstants::TICKS_PER_SECOND * 40;
spawnCount = 4;
displayEntity = nullptr;
maxNearbyEntities = 6;
requiredPlayerRange = 16;
spawnRange = 4;
}
BaseMobSpawner::~BaseMobSpawner() {
if (spawnPotentials) {
for (AUTO_VAR(it, spawnPotentials->begin());
it != spawnPotentials->end(); ++it) {
delete *it;
}
delete spawnPotentials;
}
}
std::wstring BaseMobSpawner::getEntityId() {
if (getNextSpawnData() == NULL) {
if (entityId.compare(L"Minecart") == 0) {
entityId = L"MinecartRideable";
}
return entityId;
} else {
return getNextSpawnData()->type;
}
}
void BaseMobSpawner::setEntityId(const std::wstring& entityId) {
this->entityId = entityId;
}
bool BaseMobSpawner::isNearPlayer() {
return getLevel()->getNearestPlayer(getX() + 0.5, getY() + 0.5,
getZ() + 0.5,
requiredPlayerRange) != NULL;
}
void BaseMobSpawner::tick() {
if (!isNearPlayer()) {
return;
}
if (getLevel()->isClientSide) {
double xP = getX() + getLevel()->random->nextFloat();
double yP = getY() + getLevel()->random->nextFloat();
double zP = getZ() + getLevel()->random->nextFloat();
getLevel()->addParticle(eParticleType_smoke, xP, yP, zP, 0, 0, 0);
getLevel()->addParticle(eParticleType_flame, xP, yP, zP, 0, 0, 0);
if (spawnDelay > 0) spawnDelay--;
oSpin = spin;
spin = (int)(spin + 1000 / (spawnDelay + 200.0f)) % 360;
} else {
if (spawnDelay == -1) delay();
if (spawnDelay > 0) {
spawnDelay--;
return;
}
bool _delay = false;
for (int c = 0; c < spawnCount; c++) {
std::shared_ptr<Entity> entity =
EntityIO::newEntity(getEntityId(), getLevel());
if (entity == NULL) return;
int nearBy =
getLevel()
->getEntitiesOfClass(
typeid(entity.get()),
AABB::newTemp(getX(), getY(), getZ(), getX() + 1,
getY() + 1, getZ() + 1)
->grow(spawnRange * 2, 4, spawnRange * 2))
->size();
if (nearBy >= maxNearbyEntities) {
delay();
return;
}
double xp = getX() + (getLevel()->random->nextDouble() -
getLevel()->random->nextDouble()) *
spawnRange;
double yp = getY() + getLevel()->random->nextInt(3) - 1;
double zp = getZ() + (getLevel()->random->nextDouble() -
getLevel()->random->nextDouble()) *
spawnRange;
std::shared_ptr<Mob> mob =
entity->instanceof(eTYPE_MOB)
? std::dynamic_pointer_cast<Mob>(entity)
: nullptr;
entity->moveTo(xp, yp, zp, getLevel()->random->nextFloat() * 360,
0);
if (mob == NULL || mob->canSpawn()) {
loadDataAndAddEntity(entity);
getLevel()->levelEvent(LevelEvent::PARTICLES_MOBTILE_SPAWN,
getX(), getY(), getZ(), 0);
if (mob != NULL) {
mob->spawnAnim();
}
_delay = true;
}
}
if (_delay) delay();
}
}
std::shared_ptr<Entity> BaseMobSpawner::loadDataAndAddEntity(
std::shared_ptr<Entity> entity) {
if (getNextSpawnData() != NULL) {
CompoundTag* data = new CompoundTag();
entity->save(data);
std::vector<Tag*>* tags = getNextSpawnData()->tag->getAllTags();
for (AUTO_VAR(it, tags->begin()); it != tags->end(); ++it) {
Tag* tag = *it;
data->put(tag->getName(), tag->copy());
}
delete tags;
entity->load(data);
if (entity->level != NULL) entity->level->addEntity(entity);
// add mounts
std::shared_ptr<Entity> rider = entity;
while (data->contains(Entity::RIDING_TAG)) {
CompoundTag* ridingTag = data->getCompound(Entity::RIDING_TAG);
std::shared_ptr<Entity> mount =
EntityIO::newEntity(ridingTag->getString(L"id"), entity->level);
if (mount != NULL) {
CompoundTag* mountData = new CompoundTag();
mount->save(mountData);
std::vector<Tag*>* ridingTags = ridingTag->getAllTags();
for (AUTO_VAR(it, ridingTags->begin()); it != ridingTags->end();
++it) {
Tag* tag = *it;
mountData->put(tag->getName(), tag->copy());
}
delete ridingTags;
mount->load(mountData);
mount->moveTo(rider->x, rider->y, rider->z, rider->yRot,
rider->xRot);
if (entity->level != NULL) entity->level->addEntity(mount);
rider->ride(mount);
}
rider = mount;
data = ridingTag;
}
} else if (entity->instanceof(eTYPE_LIVINGENTITY) &&
entity->level != NULL) {
std::dynamic_pointer_cast<Mob>(entity)->finalizeMobSpawn(NULL);
getLevel()->addEntity(entity);
}
return entity;
}
void BaseMobSpawner::delay() {
if (maxSpawnDelay <= minSpawnDelay) {
spawnDelay = minSpawnDelay;
} else {
spawnDelay = minSpawnDelay +
getLevel()->random->nextInt(maxSpawnDelay - minSpawnDelay);
}
if ((spawnPotentials != NULL) && (spawnPotentials->size() > 0)) {
setNextSpawnData((SpawnData*)WeighedRandom::getRandomItem(
(Random*)getLevel()->random,
(std::vector<WeighedRandomItem*>*)spawnPotentials));
}
broadcastEvent(EVENT_SPAWN);
}
void BaseMobSpawner::load(CompoundTag* tag) {
entityId = tag->getString(L"EntityId");
spawnDelay = tag->getShort(L"Delay");
if (tag->contains(L"SpawnPotentials")) {
spawnPotentials = new std::vector<SpawnData*>();
ListTag<CompoundTag>* potentials =
(ListTag<CompoundTag>*)tag->getList(L"SpawnPotentials");
for (int i = 0; i < potentials->size(); i++) {
spawnPotentials->push_back(new SpawnData(potentials->get(i)));
}
} else {
spawnPotentials = NULL;
}
if (tag->contains(L"SpawnData")) {
setNextSpawnData(
new SpawnData(tag->getCompound(L"SpawnData"), entityId));
} else {
setNextSpawnData(NULL);
}
if (tag->contains(L"MinSpawnDelay")) {
minSpawnDelay = tag->getShort(L"MinSpawnDelay");
maxSpawnDelay = tag->getShort(L"MaxSpawnDelay");
spawnCount = tag->getShort(L"SpawnCount");
}
if (tag->contains(L"MaxNearbyEntities")) {
maxNearbyEntities = tag->getShort(L"MaxNearbyEntities");
requiredPlayerRange = tag->getShort(L"RequiredPlayerRange");
}
if (tag->contains(L"SpawnRange")) spawnRange = tag->getShort(L"SpawnRange");
if (getLevel() != NULL && getLevel()->isClientSide) {
displayEntity = nullptr;
}
}
void BaseMobSpawner::save(CompoundTag* tag) {
tag->putString(L"EntityId", getEntityId());
tag->putShort(L"Delay", (short)spawnDelay);
tag->putShort(L"MinSpawnDelay", (short)minSpawnDelay);
tag->putShort(L"MaxSpawnDelay", (short)maxSpawnDelay);
tag->putShort(L"SpawnCount", (short)spawnCount);
tag->putShort(L"MaxNearbyEntities", (short)maxNearbyEntities);
tag->putShort(L"RequiredPlayerRange", (short)requiredPlayerRange);
tag->putShort(L"SpawnRange", (short)spawnRange);
if (getNextSpawnData() != NULL) {
tag->putCompound(L"SpawnData",
(CompoundTag*)getNextSpawnData()->tag->copy());
}
if (getNextSpawnData() != NULL ||
(spawnPotentials != NULL && spawnPotentials->size() > 0)) {
ListTag<CompoundTag>* list = new ListTag<CompoundTag>();
if (spawnPotentials != NULL && spawnPotentials->size() > 0) {
for (AUTO_VAR(it, spawnPotentials->begin());
it != spawnPotentials->end(); ++it) {
SpawnData* data = *it;
list->add(data->save());
}
} else {
list->add(getNextSpawnData()->save());
}
tag->put(L"SpawnPotentials", list);
}
}
std::shared_ptr<Entity> BaseMobSpawner::getDisplayEntity() {
if (displayEntity == NULL) {
std::shared_ptr<Entity> e = EntityIO::newEntity(getEntityId(), NULL);
e = loadDataAndAddEntity(e);
displayEntity = e;
}
return displayEntity;
}
bool BaseMobSpawner::onEventTriggered(int id) {
if (id == EVENT_SPAWN && getLevel()->isClientSide) {
spawnDelay = minSpawnDelay;
return true;
}
return false;
}
BaseMobSpawner::SpawnData* BaseMobSpawner::getNextSpawnData() {
return nextSpawnData;
}
void BaseMobSpawner::setNextSpawnData(SpawnData* nextSpawnData) {
this->nextSpawnData = nextSpawnData;
}
BaseMobSpawner::SpawnData::SpawnData(CompoundTag* base)
: WeighedRandomItem(base->getInt(L"Weight")) {
CompoundTag* tag = base->getCompound(L"Properties");
std::wstring _type = base->getString(L"Type");
if (_type.compare(L"Minecart") == 0) {
if (tag != NULL) {
switch (tag->getInt(L"Type")) {
case Minecart::TYPE_CHEST:
type = L"MinecartChest";
break;
case Minecart::TYPE_FURNACE:
type = L"MinecartFurnace";
break;
case Minecart::TYPE_RIDEABLE:
type = L"MinecartRideable";
break;
}
} else {
type = L"MinecartRideable";
}
}
this->tag = tag;
this->type = _type;
}
BaseMobSpawner::SpawnData::SpawnData(CompoundTag* tag, std::wstring _type)
: WeighedRandomItem(1) {
if (_type.compare(L"Minecart") == 0) {
if (tag != NULL) {
switch (tag->getInt(L"Type")) {
case Minecart::TYPE_CHEST:
_type = L"MinecartChest";
break;
case Minecart::TYPE_FURNACE:
_type = L"MinecartFurnace";
break;
case Minecart::TYPE_RIDEABLE:
_type = L"MinecartRideable";
break;
}
} else {
_type = L"MinecartRideable";
}
}
this->tag = tag;
this->type = _type;
}
BaseMobSpawner::SpawnData::~SpawnData() { delete tag; }
CompoundTag* BaseMobSpawner::SpawnData::save() {
CompoundTag* result = new CompoundTag();
result->putCompound(L"Properties", tag);
result->putString(L"Type", type);
result->putInt(L"Weight", randomWeight);
return result;
}

View file

@ -0,0 +1,69 @@
#pragma once
#include "../Util/WeighedRandom.h"
class BaseMobSpawner {
public:
class SpawnData : public WeighedRandomItem {
public:
CompoundTag* tag;
std::wstring type;
SpawnData(CompoundTag* base);
SpawnData(CompoundTag* tag, std::wstring type);
~SpawnData();
virtual CompoundTag* save();
};
private:
static const int EVENT_SPAWN = 1;
public:
int spawnDelay;
private:
std::wstring entityId;
std::vector<SpawnData*>* spawnPotentials;
SpawnData* nextSpawnData;
public:
double spin, oSpin;
private:
int minSpawnDelay;
int maxSpawnDelay;
int spawnCount;
std::shared_ptr<Entity> displayEntity;
int maxNearbyEntities;
int requiredPlayerRange;
int spawnRange;
public:
BaseMobSpawner();
~BaseMobSpawner();
virtual std::wstring getEntityId();
virtual void setEntityId(const std::wstring& entityId);
virtual bool isNearPlayer();
virtual void tick();
virtual std::shared_ptr<Entity> loadDataAndAddEntity(
std::shared_ptr<Entity> entity);
private:
virtual void delay();
public:
virtual void load(CompoundTag* tag);
virtual void save(CompoundTag* tag);
virtual std::shared_ptr<Entity> getDisplayEntity();
virtual bool onEventTriggered(int id);
virtual SpawnData* getNextSpawnData();
virtual void setNextSpawnData(SpawnData* nextSpawnData);
virtual void broadcastEvent(int id) = 0;
virtual Level* getLevel() = 0;
virtual int getX() = 0;
virtual int getY() = 0;
virtual int getZ() = 0;
};

View file

@ -0,0 +1,17 @@
#include "../Platform/stdafx.h"
#include "Calendar.h"
#include <time.h>
unsigned int Calendar::GetDayOfMonth() {
time_t t = time(0);
struct tm* now = localtime(&t);
return now->tm_mday;
}
unsigned int Calendar::GetMonth() {
time_t t = time(0);
struct tm* now = localtime(&t);
return now->tm_mon;
}

View file

@ -0,0 +1,9 @@
#pragma once
class Calendar {
public:
Calendar();
static unsigned int GetDayOfMonth();
static unsigned int GetMonth();
};

View file

@ -4,14 +4,14 @@
ChunkPos::ChunkPos(int x, int z) : x(x), z(z) {} ChunkPos::ChunkPos(int x, int z) : x(x), z(z) {}
__int64 ChunkPos::hashCode(int x, int z) { int64_t ChunkPos::hashCode(int x, int z) {
__int64 xx = x; int64_t xx = x;
__int64 zz = z; int64_t zz = z;
return (xx & 0xffffffffl) | ((zz & 0xffffffffl) << 32l); return (xx & 0xffffffffl) | ((zz & 0xffffffffl) << 32l);
} }
int ChunkPos::hashCode() { int ChunkPos::hashCode() {
__int64 hash = hashCode(x, z); int64_t hash = hashCode(x, z);
int h1 = (int)(hash); int h1 = (int)(hash);
int h2 = (int)(hash >> 32l); int h2 = (int)(hash >> 32l);
return h1 ^ h2; return h1 ^ h2;
@ -49,7 +49,7 @@ std::wstring ChunkPos::toString() {
return L"[" + _toString<int>(x) + L", " + _toString<int>(z) + L"]"; return L"[" + _toString<int>(x) + L", " + _toString<int>(z) + L"]";
} }
__int64 ChunkPos::hash_fnct(const ChunkPos& k) { return k.hashCode(k.x, k.z); } int64_t ChunkPos::hash_fnct(const ChunkPos& k) { return k.hashCode(k.x, k.z); }
bool ChunkPos::eq_test(const ChunkPos& x, const ChunkPos& y) { bool ChunkPos::eq_test(const ChunkPos& x, const ChunkPos& y) {
return x.x == y.x && x.z == y.z; return x.x == y.x && x.z == y.z;

View file

@ -10,7 +10,7 @@ public:
ChunkPos(int x, int z); ChunkPos(int x, int z);
static __int64 hashCode(int x, int z); static int64_t hashCode(int x, int z);
int hashCode(); int hashCode();
double distanceToSqr(std::shared_ptr<Entity> e); double distanceToSqr(std::shared_ptr<Entity> e);
@ -22,7 +22,7 @@ public:
TilePos getMiddleBlockPosition(int y); TilePos getMiddleBlockPosition(int y);
std::wstring toString(); std::wstring toString();
static __int64 hash_fnct(const ChunkPos& k); static int64_t hash_fnct(const ChunkPos& k);
static bool eq_test(const ChunkPos& x, const ChunkPos& y); static bool eq_test(const ChunkPos& x, const ChunkPos& y);
bool operator==(const ChunkPos& k) const { bool operator==(const ChunkPos& k) const {
return (this->x == k.x) && (this->z == k.z); return (this->x == k.x) && (this->z == k.z);
@ -35,7 +35,7 @@ public:
}; };
struct ChunkPosKeyHash { struct ChunkPosKeyHash {
__int64 operator()(const ChunkPos& k) const { int64_t operator()(const ChunkPos& k) const {
return ChunkPos::hash_fnct(k); return ChunkPos::hash_fnct(k);
} }
}; };

View file

@ -8,6 +8,12 @@ class TilePos;
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
// 4J Stu - Our default map (at zoom level 3) is 1024x1024 blocks (or 64 chunks) // 4J Stu - Our default map (at zoom level 3) is 1024x1024 blocks (or 64 chunks)
#define LEVEL_MAX_WIDTH (5 * 64) //(6*54) #define LEVEL_MAX_WIDTH (5 * 64) //(6*54)
#define LEVEL_WIDTH_CLASSIC 54
#define LEVEL_WIDTH_SMALL 64
#define LEVEL_WIDTH_MEDIUM (3 * 64)
#define LEVEL_WIDTH_LARGE (5 * 64)
#else #else
#define LEVEL_MAX_WIDTH 54 #define LEVEL_MAX_WIDTH 54
#endif #endif
@ -19,6 +25,12 @@ class TilePos;
// overworld // overworld
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
#define HELL_LEVEL_MAX_SCALE 8 #define HELL_LEVEL_MAX_SCALE 8
#define HELL_LEVEL_SCALE_CLASSIC 3
#define HELL_LEVEL_SCALE_SMALL 3
#define HELL_LEVEL_SCALE_MEDIUM 6
#define HELL_LEVEL_SCALE_LARGE 8
#else #else
#define HELL_LEVEL_MAX_SCALE 3 #define HELL_LEVEL_MAX_SCALE 3
#endif #endif
@ -39,6 +51,11 @@ class ChunkSource {
public: public:
// 4J Added so that we can store the maximum dimensions of this world // 4J Added so that we can store the maximum dimensions of this world
int m_XZSize; int m_XZSize;
#ifdef _LARGE_WORLDS
bool m_classicEdgeMoat;
bool m_smallEdgeMoat;
bool m_mediumEdgeMoat;
#endif
public: public:
virtual ~ChunkSource() {} virtual ~ChunkSource() {}
@ -69,4 +86,12 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z) = 0; int x, int y, int z) = 0;
/**
* Recreates "logic structures" for a chunk that has been loaded from disk.
* For example, fortress bridges in the Nether.
*/
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ) = 0;
// virtual void flushSave() = 0; // 4J removed
}; };

View file

@ -1,5 +1,4 @@
#include "../Platform/stdafx.h" #include "../Platform/stdafx.h"
#include "../Util/PortableFileIO.h"
#include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.biome.h" #include "../Headers/net.minecraft.world.level.biome.h"
#include "../Headers/net.minecraft.world.level.levelgen.h" #include "../Headers/net.minecraft.world.level.levelgen.h"
@ -8,12 +7,13 @@
#include "../Headers/net.minecraft.world.level.levelgen.synth.h" #include "../Headers/net.minecraft.world.level.levelgen.synth.h"
#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.level.storage.h" #include "../Headers/net.minecraft.world.level.storage.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "CustomLevelSource.h" #include "CustomLevelSource.h"
const double CustomLevelSource::SNOW_SCALE = 0.3; const double CustomLevelSource::SNOW_SCALE = 0.3;
const double CustomLevelSource::SNOW_CUTOFF = 0.5; const double CustomLevelSource::SNOW_CUTOFF = 0.5;
CustomLevelSource::CustomLevelSource(Level* level, __int64 seed, CustomLevelSource::CustomLevelSource(Level* level, int64_t seed,
bool generateStructures) bool generateStructures)
: generateStructures(generateStructures) { : generateStructures(generateStructures) {
#ifdef _OVERRIDE_HEIGHTMAP #ifdef _OVERRIDE_HEIGHTMAP
@ -21,55 +21,86 @@ CustomLevelSource::CustomLevelSource(Level* level, __int64 seed,
m_heightmapOverride = byteArray((m_XZSize * 16) * (m_XZSize * 16)); m_heightmapOverride = byteArray((m_XZSize * 16) * (m_XZSize * 16));
#ifdef _WINDOWS64 #ifdef _UNICODE
const std::wstring path = L"GameRules\\heightmap.bin"; std::wstring path = L"GAME:\\GameRules\\heightmap.bin";
#else #else
const std::wstring path = L"GAME:\\GameRules\\heightmap.bin"; #ifdef _WINDOWS64
std::string path = "GameRules\\heightmap.bin";
#else
std::string path = "GAME:\\GameRules\\heightmap.bin";
#endif #endif
const PortableFileIO::BinaryReadResult heightmapReadResult = #endif
PortableFileIO::ReadBinaryFile(path, m_heightmapOverride.data, HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
m_heightmapOverride.length); FILE_ATTRIBUTE_NORMAL, NULL);
if (heightmapReadResult.status == if (file == INVALID_HANDLE_VALUE) {
PortableFileIO::BinaryReadStatus::not_found) {
app.FatalLoadError(); app.FatalLoadError();
DWORD error = GetLastError();
assert(false); assert(false);
} else if (heightmapReadResult.status == } else {
PortableFileIO::BinaryReadStatus::too_large) { #ifdef _DURANGO
app.DebugPrintf("Heightmap binary is too large!!\n"); __debugbreak(); // TODO
__debugbreak(); DWORD bytesRead, dwFileSize = 0;
} else if (heightmapReadResult.status != #else
PortableFileIO::BinaryReadStatus::ok) { DWORD bytesRead, dwFileSize = GetFileSize(file, NULL);
app.FatalLoadError(); #endif
if (dwFileSize > m_heightmapOverride.length) {
app.DebugPrintf("Heightmap binary is too large!!\n");
__debugbreak();
}
BOOL bSuccess = ReadFile(file, m_heightmapOverride.data, dwFileSize,
&bytesRead, NULL);
if (bSuccess == FALSE) {
app.FatalLoadError();
}
CloseHandle(file);
} }
m_waterheightOverride = byteArray((m_XZSize * 16) * (m_XZSize * 16)); m_waterheightOverride = byteArray((m_XZSize * 16) * (m_XZSize * 16));
#ifdef _WINDOWS64 #ifdef _UNICODE
const std::wstring waterHeightPath = L"GameRules\\waterheight.bin"; std::wstring waterHeightPath = L"GAME:\\GameRules\\waterheight.bin";
#else #else
const std::wstring waterHeightPath = L"GAME:\\GameRules\\waterheight.bin"; #ifdef _WINDOWS64
std::string waterHeightPath = "GameRules\\waterheight.bin";
#else
std::string waterHeightPath = "GAME:\\GameRules\\waterheight.bin";
#endif #endif
const PortableFileIO::BinaryReadResult waterHeightReadResult = #endif
PortableFileIO::ReadBinaryFile(waterHeightPath, file = CreateFile(waterHeightPath.c_str(), GENERIC_READ, 0, NULL,
m_waterheightOverride.data, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
m_waterheightOverride.length); if (file == INVALID_HANDLE_VALUE) {
if (waterHeightReadResult.status == DWORD error = GetLastError();
PortableFileIO::BinaryReadStatus::not_found) { // assert(false);
memset(m_waterheightOverride.data, level->seaLevel, memset(m_waterheightOverride.data, level->seaLevel,
m_waterheightOverride.length); m_waterheightOverride.length);
} else if (waterHeightReadResult.status == } else {
PortableFileIO::BinaryReadStatus::too_large) { #ifdef _DURANGO
app.DebugPrintf("waterheight binary is too large!!\n"); __debugbreak(); // TODO
__debugbreak(); DWORD bytesRead, dwFileSize = 0;
} else if (waterHeightReadResult.status != #else
PortableFileIO::BinaryReadStatus::ok) { DWORD bytesRead, dwFileSize = GetFileSize(file, NULL);
app.FatalLoadError(); #endif
if (dwFileSize > m_waterheightOverride.length) {
app.DebugPrintf("waterheight binary is too large!!\n");
__debugbreak();
}
BOOL bSuccess = ReadFile(file, m_waterheightOverride.data, dwFileSize,
&bytesRead, NULL);
if (bSuccess == FALSE) {
app.FatalLoadError();
}
CloseHandle(file);
} }
caveFeature = new LargeCaveFeature(); caveFeature = new LargeCaveFeature();
strongholdFeature = new StrongholdFeature(); strongholdFeature = new StrongholdFeature();
villageFeature = new VillageFeature(0, m_XZSize); villageFeature = new VillageFeature(m_XZSize);
mineShaftFeature = new MineShaftFeature(); mineShaftFeature = new MineShaftFeature();
scatteredFeature = new RandomScatteredLargeFeature();
canyonFeature = new CanyonFeature(); canyonFeature = new CanyonFeature();
this->level = level; this->level = level;
@ -90,6 +121,8 @@ CustomLevelSource::~CustomLevelSource() {
delete mineShaftFeature; delete mineShaftFeature;
delete canyonFeature; delete canyonFeature;
this->level = level;
delete random; delete random;
delete perlinNoise3; delete perlinNoise3;
#endif #endif
@ -169,9 +202,9 @@ void CustomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
// 4J - this comparison used to just be with 0.0f // 4J - this comparison used to just be with 0.0f
// but is now varied by block above // but is now varied by block above
if (yc * CHUNK_HEIGHT + y < mapHeight) { if (yc * CHUNK_HEIGHT + y < mapHeight) {
tileId = (std::uint8_t)Tile::rock_Id; tileId = (uint8_t)Tile::stone_Id;
} else if (yc * CHUNK_HEIGHT + y < waterHeight) { } else if (yc * CHUNK_HEIGHT + y < waterHeight) {
tileId = (std::uint8_t)Tile::calmWater_Id; tileId = (uint8_t)Tile::calmWater_Id;
} }
// 4J - more extra code to make sure that the column // 4J - more extra code to make sure that the column
@ -185,7 +218,7 @@ void CustomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
// the edge of the world // the edge of the world
if (yc * CHUNK_HEIGHT + y <= if (yc * CHUNK_HEIGHT + y <=
(level->getSeaLevel() - 10)) (level->getSeaLevel() - 10))
tileId = Tile::rock_Id; tileId = Tile::stone_Id;
else if (yc * CHUNK_HEIGHT + y < else if (yc * CHUNK_HEIGHT + y <
level->getSeaLevel()) level->getSeaLevel())
tileId = Tile::calmWater_Id; tileId = Tile::calmWater_Id;
@ -245,8 +278,8 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
int run = -1; int run = -1;
std::uint8_t top = b->topMaterial; uint8_t top = b->topMaterial;
std::uint8_t material = b->material; uint8_t material = b->material;
LevelGenerationOptions* lgo = app.getLevelGenerationOptions(); LevelGenerationOptions* lgo = app.getLevelGenerationOptions();
if (lgo != NULL) { if (lgo != NULL) {
@ -270,17 +303,17 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
// if (y <= 0 + // if (y <= 0 +
// random->nextInt(5)) // random->nextInt(5))
{ {
blocks[offs] = (std::uint8_t)Tile::unbreakable_Id; blocks[offs] = (uint8_t)Tile::unbreakable_Id;
} else { } else {
int old = blocks[offs]; int old = blocks[offs];
if (old == 0) { if (old == 0) {
run = -1; run = -1;
} else if (old == Tile::rock_Id) { } else if (old == Tile::stone_Id) {
if (run == -1) { if (run == -1) {
if (runDepth <= 0) { if (runDepth <= 0) {
top = 0; top = 0;
material = (std::uint8_t)Tile::rock_Id; material = (uint8_t)Tile::stone_Id;
} else if (y >= waterHeight - 4 && } else if (y >= waterHeight - 4 &&
y <= waterHeight + 1) { y <= waterHeight + 1) {
top = b->topMaterial; top = b->topMaterial;
@ -292,9 +325,9 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
if (y < waterHeight && top == 0) { if (y < waterHeight && top == 0) {
if (temp < 0.15f) if (temp < 0.15f)
top = (std::uint8_t)Tile::ice_Id; top = (uint8_t)Tile::ice_Id;
else else
top = (std::uint8_t)Tile::calmWater_Id; top = (uint8_t)Tile::calmWater_Id;
} }
run = runDepth; run = runDepth;
@ -310,7 +343,7 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
// runs // runs
if (run == 0 && material == Tile::sand_Id) { if (run == 0 && material == Tile::sand_Id) {
run = random->nextInt(4); run = random->nextInt(4);
material = (std::uint8_t)Tile::sandStone_Id; material = (uint8_t)Tile::sandStone_Id;
} }
} }
} }
@ -338,8 +371,8 @@ LevelChunk* CustomLevelSource::getChunk(int xOffs, int zOffs) {
// 4J - now allocating this with a physical alloc & bypassing general memory // 4J - now allocating this with a physical alloc & bypassing general memory
// management so that it will get cleanly freed // management so that it will get cleanly freed
int blocksSize = Level::maxBuildHeight * 16 * 16; int blocksSize = Level::maxBuildHeight * 16 * 16;
std::uint8_t* tileData = (std::uint8_t*)XPhysicalAlloc( uint8_t* tileData = (uint8_t*)XPhysicalAlloc(blocksSize, MAXULONG_PTR, 4096,
blocksSize, MAXULONG_PTR, 4096, PAGE_READWRITE); PAGE_READWRITE);
XMemSet128(tileData, 0, blocksSize); XMemSet128(tileData, 0, blocksSize);
byteArray blocks = byteArray(tileData, blocksSize); byteArray blocks = byteArray(tileData, blocksSize);
// byteArray blocks = byteArray(16 * level->depth * 16); // byteArray blocks = byteArray(16 * level->depth * 16);
@ -368,6 +401,7 @@ LevelChunk* CustomLevelSource::getChunk(int xOffs, int zOffs) {
mineShaftFeature->apply(this, level, xOffs, zOffs, blocks); mineShaftFeature->apply(this, level, xOffs, zOffs, blocks);
villageFeature->apply(this, level, xOffs, zOffs, blocks); villageFeature->apply(this, level, xOffs, zOffs, blocks);
strongholdFeature->apply(this, level, xOffs, zOffs, blocks); strongholdFeature->apply(this, level, xOffs, zOffs, blocks);
scatteredFeature->apply(this, level, xOffs, zOffs, blocks);
} }
// canyonFeature.apply(this, level, xOffs, zOffs, blocks); // canyonFeature.apply(this, level, xOffs, zOffs, blocks);
// townFeature.apply(this, level, xOffs, zOffs, blocks); // townFeature.apply(this, level, xOffs, zOffs, blocks);
@ -451,19 +485,21 @@ void CustomLevelSource::calcWaterDepths(ChunkSource* parent, int xt, int zt) {
int od = int od =
level->getData(xp + x2, y, zp + z2); level->getData(xp + x2, y, zp + z2);
if (od < 7 && od < d) { if (od < 7 && od < d) {
level->setData(xp + x2, y, zp + z2, level->setData(
d); xp + x2, y, zp + z2, d,
Tile::UPDATE_CLIENTS);
} }
} }
} }
} }
} }
if (hadWater) { if (hadWater) {
level->setTileAndDataNoUpdate( level->setTileAndData(xp, y, zp, Tile::calmWater_Id,
xp, y, zp, Tile::calmWater_Id, 7); 7, Tile::UPDATE_CLIENTS);
for (int y2 = 0; y2 < y; y2++) { for (int y2 = 0; y2 < y; y2++) {
level->setTileAndDataNoUpdate( level->setTileAndData(xp, y2, zp,
xp, y2, zp, Tile::calmWater_Id, 8); Tile::calmWater_Id, 8,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -489,8 +525,8 @@ void CustomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
} }
pprandom->setSeed(level->getSeed()); pprandom->setSeed(level->getSeed());
__int64 xScale = pprandom->nextLong() / 2 * 2 + 1; int64_t xScale = pprandom->nextLong() / 2 * 2 + 1;
__int64 zScale = pprandom->nextLong() / 2 * 2 + 1; int64_t zScale = pprandom->nextLong() / 2 * 2 + 1;
pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed());
bool hasVillage = false; bool hasVillage = false;
@ -500,6 +536,7 @@ void CustomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
mineShaftFeature->postProcess(level, pprandom, xt, zt); mineShaftFeature->postProcess(level, pprandom, xt, zt);
hasVillage = villageFeature->postProcess(level, pprandom, xt, zt); hasVillage = villageFeature->postProcess(level, pprandom, xt, zt);
strongholdFeature->postProcess(level, pprandom, xt, zt); strongholdFeature->postProcess(level, pprandom, xt, zt);
scatteredFeature->postProcess(level, random, xt, zt);
} }
PIXEndNamedEvent(); PIXEndNamedEvent();
@ -562,14 +599,16 @@ void CustomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int y = level->getTopRainBlock(xo + x, zo + z); int y = level->getTopRainBlock(xo + x, zo + z);
if (level->shouldFreezeIgnoreNeighbors(x + xo, y - 1, z + zo)) { if (level->shouldFreezeIgnoreNeighbors(x + xo, y - 1, z + zo)) {
level->setTileNoUpdate( level->setTileAndData(
x + xo, y - 1, z + zo, x + xo, y - 1, z + zo, Tile::ice_Id, 0,
Tile::ice_Id); // 4J - changed from setTile, otherwise we Tile::UPDATE_INVISIBLE); // 4J - changed from setTile,
// end up creating a *lot* of dynamic water // otherwise we end up creating a
// tiles as these ice tiles are set // *lot* of dynamic water tiles as
// these ice tiles are set
} }
if (level->shouldSnow(x + xo, y, z + zo)) { if (level->shouldSnow(x + xo, y, z + zo)) {
level->setTile(x + xo, y, z + zo, Tile::topSnow_Id); level->setTileAndData(x + xo, y, z + zo, Tile::topSnow_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -595,6 +634,10 @@ std::vector<Biome::MobSpawnerData*>* CustomLevelSource::getMobsAt(
if (biome == NULL) { if (biome == NULL) {
return NULL; return NULL;
} }
if (mobCategory == MobCategory::monster &&
scatteredFeature->isSwamphut(x, y, z)) {
return scatteredFeature->getSwamphutEnemies();
}
return biome->getMobs(mobCategory); return biome->getMobs(mobCategory);
#else #else
return NULL; return NULL;
@ -610,3 +653,15 @@ TilePos* CustomLevelSource::findNearestMapFeature(
#endif #endif
return NULL; return NULL;
} }
void CustomLevelSource::recreateLogicStructuresForChunk(int chunkX,
int chunkZ) {
if (generateStructures) {
#ifdef _OVERRIDE_HEIGHTMAP
mineShaftFeature->apply(this, level, chunkX, chunkZ, NULL);
villageFeature->apply(this, level, chunkX, chunkZ, NULL);
strongholdFeature->apply(this, level, chunkX, chunkZ, NULL);
scatteredFeature->apply(this, level, chunkX, chunkZ, NULL);
#endif
}
}

View file

@ -11,6 +11,7 @@ class LargeFeature;
class StrongholdFeature; class StrongholdFeature;
class VillageFeature; class VillageFeature;
class MineShaftFeature; class MineShaftFeature;
class RandomScatteredLargeFeature;
class CustomLevelSource : public ChunkSource { class CustomLevelSource : public ChunkSource {
public: public:
@ -29,6 +30,7 @@ private:
StrongholdFeature* strongholdFeature; StrongholdFeature* strongholdFeature;
VillageFeature* villageFeature; VillageFeature* villageFeature;
MineShaftFeature* mineShaftFeature; MineShaftFeature* mineShaftFeature;
RandomScatteredLargeFeature* scatteredFeature;
LargeFeature* canyonFeature; LargeFeature* canyonFeature;
Level* level; Level* level;
#endif #endif
@ -40,7 +42,7 @@ private:
const bool generateStructures; const bool generateStructures;
public: public:
CustomLevelSource(Level* level, __int64 seed, bool generateStructures); CustomLevelSource(Level* level, int64_t seed, bool generateStructures);
~CustomLevelSource(); ~CustomLevelSource();
public: public:
@ -76,4 +78,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z); int x, int y, int z);
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
}; };

View file

@ -17,7 +17,7 @@ CompoundTag* DerivedLevelData::createTag(
return wrapped->createTag(players); return wrapped->createTag(players);
} }
__int64 DerivedLevelData::getSeed() { return wrapped->getSeed(); } int64_t DerivedLevelData::getSeed() { return wrapped->getSeed(); }
int DerivedLevelData::getXSpawn() { return wrapped->getXSpawn(); } int DerivedLevelData::getXSpawn() { return wrapped->getXSpawn(); }
@ -25,9 +25,11 @@ int DerivedLevelData::getYSpawn() { return wrapped->getYSpawn(); }
int DerivedLevelData::getZSpawn() { return wrapped->getZSpawn(); } int DerivedLevelData::getZSpawn() { return wrapped->getZSpawn(); }
__int64 DerivedLevelData::getTime() { return wrapped->getTime(); } int64_t DerivedLevelData::getGameTime() { return wrapped->getGameTime(); }
__int64 DerivedLevelData::getSizeOnDisk() { return wrapped->getSizeOnDisk(); } int64_t DerivedLevelData::getDayTime() { return wrapped->getDayTime(); }
int64_t DerivedLevelData::getSizeOnDisk() { return wrapped->getSizeOnDisk(); }
CompoundTag* DerivedLevelData::getLoadedPlayerTag() { CompoundTag* DerivedLevelData::getLoadedPlayerTag() {
return wrapped->getLoadedPlayerTag(); return wrapped->getLoadedPlayerTag();
@ -39,7 +41,7 @@ std::wstring DerivedLevelData::getLevelName() {
int DerivedLevelData::getVersion() { return wrapped->getVersion(); } int DerivedLevelData::getVersion() { return wrapped->getVersion(); }
__int64 DerivedLevelData::getLastPlayed() { return wrapped->getLastPlayed(); } int64_t DerivedLevelData::getLastPlayed() { return wrapped->getLastPlayed(); }
bool DerivedLevelData::isThundering() { return wrapped->isThundering(); } bool DerivedLevelData::isThundering() { return wrapped->isThundering(); }
@ -51,7 +53,7 @@ int DerivedLevelData::getRainTime() { return wrapped->getRainTime(); }
GameType* DerivedLevelData::getGameType() { return wrapped->getGameType(); } GameType* DerivedLevelData::getGameType() { return wrapped->getGameType(); }
void DerivedLevelData::setSeed(__int64 seed) {} void DerivedLevelData::setSeed(int64_t seed) {}
void DerivedLevelData::setXSpawn(int xSpawn) {} void DerivedLevelData::setXSpawn(int xSpawn) {}
@ -59,9 +61,11 @@ void DerivedLevelData::setYSpawn(int ySpawn) {}
void DerivedLevelData::setZSpawn(int zSpawn) {} void DerivedLevelData::setZSpawn(int zSpawn) {}
void DerivedLevelData::setTime(__int64 time) {} void DerivedLevelData::setGameTime(int64_t time) {}
void DerivedLevelData::setSizeOnDisk(__int64 sizeOnDisk) {} void DerivedLevelData::setDayTime(int64_t time) {}
void DerivedLevelData::setSizeOnDisk(int64_t sizeOnDisk) {}
void DerivedLevelData::setLoadedPlayerTag(CompoundTag* loadedPlayerTag) {} void DerivedLevelData::setLoadedPlayerTag(CompoundTag* loadedPlayerTag) {}
@ -103,6 +107,8 @@ bool DerivedLevelData::isInitialized() { return wrapped->isInitialized(); }
void DerivedLevelData::setInitialized(bool initialized) {} void DerivedLevelData::setInitialized(bool initialized) {}
GameRules* DerivedLevelData::getGameRules() { return wrapped->getGameRules(); }
int DerivedLevelData::getXZSize() { return wrapped->getXZSize(); } int DerivedLevelData::getXZSize() { return wrapped->getXZSize(); }
int DerivedLevelData::getHellScale() { return wrapped->getHellScale(); } int DerivedLevelData::getHellScale() { return wrapped->getHellScale(); }

View file

@ -2,6 +2,8 @@
#include "LevelData.h" #include "LevelData.h"
class GameRules;
class DerivedLevelData : public LevelData { class DerivedLevelData : public LevelData {
private: private:
LevelData* wrapped; LevelData* wrapped;
@ -15,27 +17,29 @@ protected:
public: public:
CompoundTag* createTag(); CompoundTag* createTag();
CompoundTag* createTag(std::vector<std::shared_ptr<Player> >* players); CompoundTag* createTag(std::vector<std::shared_ptr<Player> >* players);
__int64 getSeed(); int64_t getSeed();
int getXSpawn(); int getXSpawn();
int getYSpawn(); int getYSpawn();
int getZSpawn(); int getZSpawn();
__int64 getTime(); int64_t getGameTime();
__int64 getSizeOnDisk(); int64_t getDayTime();
int64_t getSizeOnDisk();
CompoundTag* getLoadedPlayerTag(); CompoundTag* getLoadedPlayerTag();
std::wstring getLevelName(); std::wstring getLevelName();
int getVersion(); int getVersion();
__int64 getLastPlayed(); int64_t getLastPlayed();
bool isThundering(); bool isThundering();
int getThunderTime(); int getThunderTime();
bool isRaining(); bool isRaining();
int getRainTime(); int getRainTime();
GameType* getGameType(); GameType* getGameType();
void setSeed(__int64 seed); void setSeed(int64_t seed);
void setXSpawn(int xSpawn); void setXSpawn(int xSpawn);
void setYSpawn(int ySpawn); void setYSpawn(int ySpawn);
void setZSpawn(int zSpawn); void setZSpawn(int zSpawn);
void setTime(__int64 time); void setGameTime(int64_t time);
void setSizeOnDisk(__int64 sizeOnDisk); void setDayTime(int64_t time);
void setSizeOnDisk(int64_t sizeOnDisk);
void setLoadedPlayerTag(CompoundTag* loadedPlayerTag); void setLoadedPlayerTag(CompoundTag* loadedPlayerTag);
void setDimension(int dimension); void setDimension(int dimension);
void setSpawn(int xSpawn, int ySpawn, int zSpawn); void setSpawn(int xSpawn, int ySpawn, int zSpawn);
@ -54,6 +58,7 @@ public:
void setAllowCommands(bool allowCommands); void setAllowCommands(bool allowCommands);
bool isInitialized(); bool isInitialized();
void setInitialized(bool initialized); void setInitialized(bool initialized);
GameRules* getGameRules();
int getXZSize(); // 4J Added int getXZSize(); // 4J Added
int getHellScale(); // 4J Addded int getHellScale(); // 4J Addded
}; };

View file

@ -1,4 +1,5 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.levelgen.flat.h"
#include "../../Headers/net.minecraft.world.level.levelgen.h" #include "../../Headers/net.minecraft.world.level.levelgen.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.storage.h" #include "../../Headers/net.minecraft.world.level.storage.h"
@ -13,9 +14,13 @@
#include "../../../Minecraft.Client/Minecraft.h" #include "../../../Minecraft.Client/Minecraft.h"
#include "../../../Minecraft.Client/Platform/Common/Colours/ColourTable.h" #include "../../../Minecraft.Client/Platform/Common/Colours/ColourTable.h"
const float Dimension::MOON_BRIGHTNESS_PER_PHASE[8] = {
1.0f, 0.75f, 0.5f, 0.25f, 0, 0.25f, 0.5f, 0.75f};
void Dimension::init(Level* level) { void Dimension::init(Level* level) {
this->level = level; this->level = level;
this->levelType = level->getLevelData()->getGenerator(); levelType = level->getLevelData()->getGenerator();
levelTypeOptions = level->getLevelData()->getGeneratorOptions();
init(); init();
updateLightRamp(); updateLightRamp();
} }
@ -35,12 +40,16 @@ void Dimension::init() {
// file // file
if (app.DebugSettingsOn() && if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) & app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableHeightWaterBiomeOverride)) { (1L << eDebugSetting_EnableBiomeOverride)) {
biomeSource = new BiomeSource(level); biomeSource = new BiomeSource(level);
} else } else
#endif #endif
if (level->getLevelData()->getGenerator() == LevelType::lvl_flat) { if (level->getLevelData()->getGenerator() == LevelType::lvl_flat) {
biomeSource = new FixedBiomeSource(Biome::plains, 0.5f, 0.5f); FlatGeneratorInfo* generator = FlatGeneratorInfo::fromValue(
level->getLevelData()->getGeneratorOptions());
biomeSource = new FixedBiomeSource(Biome::biomes[generator->getBiome()],
0.5f, 0.5f);
delete generator;
} else { } else {
biomeSource = new BiomeSource(level); biomeSource = new BiomeSource(level);
} }
@ -51,6 +60,7 @@ Dimension::Dimension() {
hasCeiling = false; hasCeiling = false;
brightnessRamp = new float[Level::MAX_BRIGHTNESS + 1]; brightnessRamp = new float[Level::MAX_BRIGHTNESS + 1];
id = 0; id = 0;
levelTypeOptions = L"";
} }
Dimension::~Dimension() { Dimension::~Dimension() {
@ -65,7 +75,7 @@ ChunkSource* Dimension::createRandomLevelSource() const {
// file // file
if (app.DebugSettingsOn() && if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) & app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableHeightWaterBiomeOverride)) { (1L << eDebugSetting_EnableHeightWaterOverride)) {
return new CustomLevelSource( return new CustomLevelSource(
level, level->getSeed(), level, level->getSeed(),
level->getLevelData()->isGenerateMapFeatures()); level->getLevelData()->isGenerateMapFeatures());
@ -99,7 +109,7 @@ bool Dimension::isValidSpawn(int x, int z) const {
return true; return true;
} }
float Dimension::getTimeOfDay(__int64 time, float a) const { float Dimension::getTimeOfDay(int64_t time, float a) const {
int dayStep = (int)(time % Level::TICKS_PER_DAY); int dayStep = (int)(time % Level::TICKS_PER_DAY);
float td = (dayStep + a) / Level::TICKS_PER_DAY - 0.25f; float td = (dayStep + a) / Level::TICKS_PER_DAY - 0.25f;
if (td < 0) td += 1; if (td < 0) td += 1;
@ -110,7 +120,7 @@ float Dimension::getTimeOfDay(__int64 time, float a) const {
return td; return td;
} }
int Dimension::getMoonPhase(__int64 time, float a) const { int Dimension::getMoonPhase(int64_t time) const {
return ((int)(time / Level::TICKS_PER_DAY)) % 8; return ((int)(time / Level::TICKS_PER_DAY)) % 8;
} }

View file

@ -11,8 +11,11 @@ class LevelType;
class Dimension { class Dimension {
public: public:
static const float MOON_BRIGHTNESS_PER_PHASE[8];
Level* level; Level* level;
LevelType* levelType; LevelType* levelType;
std::wstring levelTypeOptions;
BiomeSource* biomeSource; BiomeSource* biomeSource;
bool ultraWarm; bool ultraWarm;
bool hasCeiling; bool hasCeiling;
@ -34,8 +37,8 @@ public:
virtual bool isValidSpawn(int x, int z) const; virtual bool isValidSpawn(int x, int z) const;
virtual float getTimeOfDay(__int64 time, float a) const; virtual float getTimeOfDay(int64_t time, float a) const;
virtual int getMoonPhase(__int64 time, float a) const; virtual int getMoonPhase(int64_t time) const;
virtual bool isNaturalDimension(); virtual bool isNaturalDimension();
private: private:

View file

@ -56,7 +56,7 @@ bool HellDimension::isNaturalDimension() { return false; }
bool HellDimension::isValidSpawn(int x, int z) const { return false; } bool HellDimension::isValidSpawn(int x, int z) const { return false; }
float HellDimension::getTimeOfDay(__int64 time, float a) const { return 0.5f; } float HellDimension::getTimeOfDay(int64_t time, float a) const { return 0.5f; }
bool HellDimension::mayRespawn() const { return false; } bool HellDimension::mayRespawn() const { return false; }

View file

@ -13,7 +13,7 @@ public:
virtual ChunkSource* createRandomLevelSource() const; virtual ChunkSource* createRandomLevelSource() const;
virtual bool isNaturalDimension(); virtual bool isNaturalDimension();
virtual bool isValidSpawn(int x, int y) const; virtual bool isValidSpawn(int x, int y) const;
virtual float getTimeOfDay(__int64 time, float a) const; virtual float getTimeOfDay(int64_t time, float a) const;
virtual bool mayRespawn() const; virtual bool mayRespawn() const;
virtual bool isFoggyAt(int x, int z); virtual bool isFoggyAt(int x, int z);

View file

@ -14,7 +14,7 @@ ChunkSource* SkyIslandDimension::createRandomLevelSource() const {
return new SkyIslandRandomLevelSource(level, level->getSeed()); return new SkyIslandRandomLevelSource(level, level->getSeed());
} }
float SkyIslandDimension::getTimeOfDay(__int64 time, float a) const { float SkyIslandDimension::getTimeOfDay(int64_t time, float a) const {
return 0.0f; return 0.0f;
} }

View file

@ -17,7 +17,7 @@ ChunkSource* TheEndDimension::createRandomLevelSource() const {
return new TheEndLevelRandomLevelSource(level, level->getSeed()); return new TheEndLevelRandomLevelSource(level, level->getSeed());
} }
float TheEndDimension::getTimeOfDay(__int64 time, float a) const { float TheEndDimension::getTimeOfDay(int64_t time, float a) const {
return 0.0f; return 0.0f;
} }

View file

@ -5,7 +5,7 @@ class TheEndDimension : public Dimension {
public: public:
virtual void init(); virtual void init();
virtual ChunkSource* createRandomLevelSource() const; virtual ChunkSource* createRandomLevelSource() const;
virtual float getTimeOfDay(__int64 time, float a) const; virtual float getTimeOfDay(int64_t time, float a) const;
virtual float* getSunriseColor(float td, float a); virtual float* getSunriseColor(float td, float a);
virtual Vec3* getFogColor(float td, float a) const; virtual Vec3* getFogColor(float td, float a) const;
virtual bool hasGround(); virtual bool hasGround();

View file

@ -102,14 +102,17 @@ void EmptyLevelChunk::load() {}
void EmptyLevelChunk::unload(bool unloadTileEntities) // 4J - added parameter void EmptyLevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
{} {}
bool EmptyLevelChunk::containsPlayer() { return false; }
void EmptyLevelChunk::markUnsaved() {} void EmptyLevelChunk::markUnsaved() {}
void EmptyLevelChunk::getEntities(std::shared_ptr<Entity> except, AABB bb, void EmptyLevelChunk::getEntities(std::shared_ptr<Entity> except, AABB bb,
std::vector<std::shared_ptr<Entity> >& es) {} std::vector<std::shared_ptr<Entity> >& es,
EntitySelector* selector) {}
void EmptyLevelChunk::getEntitiesOfClass( void EmptyLevelChunk::getEntitiesOfClass(
const std::type_info& ec, AABB bb, const std::type_info& ec, AABB bb,
std::vector<std::shared_ptr<Entity> >& es) {} std::vector<std::shared_ptr<Entity> >& es, EntitySelector* selector) {}
int EmptyLevelChunk::countEntities() { return 0; } int EmptyLevelChunk::countEntities() { return 0; }
@ -157,7 +160,7 @@ bool EmptyLevelChunk::testSetBlocksAndData(byteArray data, int x0, int y0,
return false; return false;
} }
Random* EmptyLevelChunk::getRandom(__int64 l) { Random* EmptyLevelChunk::getRandom(int64_t l) {
return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 + return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 +
z * z * 4392871l + z * 389711) ^ z * z * 4392871l + z * 389711) ^
l); l);

View file

@ -42,11 +42,14 @@ public:
void removeTileEntity(int x, int y, int z); void removeTileEntity(int x, int y, int z);
void load(); void load();
void unload(bool unloadTileEntities); // 4J - added parameter void unload(bool unloadTileEntities); // 4J - added parameter
bool containsPlayer(); // 4J added
void markUnsaved(); void markUnsaved();
void getEntities(std::shared_ptr<Entity> except, AABB bb, void getEntities(std::shared_ptr<Entity> except, AABB bb,
std::vector<std::shared_ptr<Entity> >& es); std::vector<std::shared_ptr<Entity> >& es,
EntitySelector* selector);
void getEntitiesOfClass(const std::type_info& ec, AABB bb, void getEntitiesOfClass(const std::type_info& ec, AABB bb,
std::vector<std::shared_ptr<Entity> >& es); std::vector<std::shared_ptr<Entity> >& es,
EntitySelector* selector);
int countEntities(); int countEntities();
bool shouldSave(bool force); bool shouldSave(bool force);
void setBlocks(byteArray newBlocks, int sub); void setBlocks(byteArray newBlocks, int sub);
@ -58,7 +61,7 @@ public:
bool includeLighting = true); // 4J - added includeLighting parameter bool includeLighting = true); // 4J - added includeLighting parameter
bool testSetBlocksAndData(byteArray data, int x0, int y0, int z0, int x1, bool testSetBlocksAndData(byteArray data, int x0, int y0, int z0, int x1,
int y1, int z1, int p); // 4J added int y1, int z1, int p); // 4J added
Random* getRandom(__int64 l); Random* getRandom(int64_t l);
bool isEmpty(); bool isEmpty();
virtual void reSyncLighting() {}; // 4J added virtual void reSyncLighting() {}; // 4J added
}; };

View file

@ -33,6 +33,7 @@ public:
static const int PARTICLES_POTION_SPLASH = 2002; static const int PARTICLES_POTION_SPLASH = 2002;
static const int PARTICLES_EYE_OF_ENDER_DEATH = 2003; static const int PARTICLES_EYE_OF_ENDER_DEATH = 2003;
static const int PARTICLES_MOBTILE_SPAWN = 2004; static const int PARTICLES_MOBTILE_SPAWN = 2004;
static const int PARTICLES_PLANT_GROWTH = 2005;
// static const int ENDERDRAGON_KILLED = 9000; // 4J Added to signal the the // static const int ENDERDRAGON_KILLED = 9000; // 4J Added to signal the the
// enderdragon was killed // enderdragon was killed

View file

@ -15,16 +15,17 @@ public:
virtual void allChanged() = 0; virtual void allChanged() = 0;
// virtual void playSound(const std::wstring& name, double x, double y, // virtual void playSound(const wstring& name, double x, double y, double z,
// double z, float volume, float pitch) = 0; // float volume, float pitch) = 0;
virtual void playSound(int iSound, double x, double y, double z, virtual void playSound(int iSound, double x, double y, double z,
float volume, float pitch, float volume, float pitch,
float fSoundClipDist = 16.0f) = 0; float fSoundClipDist = 16.0f) = 0;
virtual void playSound(std::shared_ptr<Entity> entity, int iSound, double x, virtual void playSoundExceptPlayer(std::shared_ptr<Player> player,
double y, double z, float volume, float pitch, int iSound, double x, double y, double z,
float fSoundClipDist = 16.0f) = 0; float volume, float pitch,
float fSoundClipDist = 16.0f) = 0;
// 4J removed - virtual void addParticle(const std::wstring& name, double x, // 4J removed - virtual void addParticle(const wstring& name, double x,
// double y, double z, double xa, double ya, double za) = 0; // double y, double z, double xa, double ya, double za) = 0;
virtual void addParticle(ePARTICLE_TYPE name, double x, double y, double z, virtual void addParticle(ePARTICLE_TYPE name, double x, double y, double z,
@ -43,7 +44,8 @@ public:
virtual void playStreamingMusic(const std::wstring& name, int x, int y, virtual void playStreamingMusic(const std::wstring& name, int x, int y,
int z) = 0; int z) = 0;
virtual void globalLevelEvent(int type, int sourceX, int sourceY,
int sourceZ, int data) = 0;
virtual void levelEvent(std::shared_ptr<Player> source, int type, int x, virtual void levelEvent(std::shared_ptr<Player> source, int type, int x,
int y, int z, int data) = 0; int y, int z, int data) = 0;

View file

@ -125,7 +125,7 @@ bool VillageSiege::trySpawn() {
// try // try
{ {
mob = std::shared_ptr<Zombie>(new Zombie(level)); mob = std::shared_ptr<Zombie>(new Zombie(level));
mob->finalizeMobSpawn(); mob->finalizeMobSpawn(NULL);
mob->setVillager(false); mob->setVillager(false);
} }
// catch (Exception e) { // catch (Exception e) {

View file

@ -1,5 +1,7 @@
#include "../Platform/stdafx.h" #include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.entity.h"
#include "../Headers/net.minecraft.world.entity.item.h"
#include "../Headers/net.minecraft.world.item.enchantment.h"
#include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.world.phys.h"
@ -64,12 +66,18 @@ void Explosion::explode() {
int zt = Mth::floor(zp); int zt = Mth::floor(zp);
int t = level->getTile(xt, yt, zt); int t = level->getTile(xt, yt, zt);
if (t > 0) { if (t > 0) {
remainingPower -= Tile* tile = Tile::tiles[t];
(Tile::tiles[t]->getExplosionResistance(source) + float resistance =
0.3f) * source != NULL
stepSize; ? source->getTileExplosionResistance(
this, level, xt, yt, zt, tile)
: tile->getExplosionResistance(source);
remainingPower -= (resistance + 0.3f) * stepSize;
} }
if (remainingPower > 0) { if (remainingPower > 0 &&
(source == NULL ||
source->shouldTileExplode(this, level, xt, yt, zt, t,
remainingPower))) {
toBlow.insert(TilePos(xt, yt, zt)); toBlow.insert(TilePos(xt, yt, zt));
} }
@ -141,17 +149,19 @@ void Explosion::explode() {
double sp = level->getSeenPercent(center, e->bb); double sp = level->getSeenPercent(center, e->bb);
double pow = (1 - dist) * sp; double pow = (1 - dist) * sp;
if (canDamage) if (canDamage)
e->hurt(DamageSource::explosion, e->hurt(DamageSource::explosion(this),
(int)((pow * pow + pow) / 2 * 8 * r + 1)); (int)((pow * pow + pow) / 2 * 8 * r + 1));
double push = pow; double kbPower =
e->xd += xa * push; ProtectionEnchantment::getExplosionKnockbackAfterDampener(e,
e->yd += ya * push; pow);
e->zd += za * push; e->xd += xa * kbPower;
e->yd += ya * kbPower;
e->zd += za * kbPower;
std::shared_ptr<Player> player = if (e->instanceof(eTYPE_PLAYER)) {
std::dynamic_pointer_cast<Player>(e); std::shared_ptr<Player> player =
if (player != NULL) { std::dynamic_pointer_cast<Player>(e);
// app.DebugPrintf("Adding player knockback (%f,%f,%f)\n", xa * // app.DebugPrintf("Adding player knockback (%f,%f,%f)\n", xa *
// pow, ya * pow, za * pow); // pow, ya * pow, za * pow);
hitPlayers.insert(playerVec3Map::value_type( hitPlayers.insert(playerVec3Map::value_type(
@ -171,72 +181,84 @@ void Explosion::finalizeExplosion(
x, y, z, eSoundType_RANDOM_EXPLODE, 4, x, y, z, eSoundType_RANDOM_EXPLODE, 4,
(1 + (level->random->nextFloat() - level->random->nextFloat()) * 0.2f) * (1 + (level->random->nextFloat() - level->random->nextFloat()) * 0.2f) *
0.7f); 0.7f);
level->addParticle(eParticleType_hugeexplosion, x, y, z, 0, 0, 0); if (r < 2 || !destroyBlocks) {
level->addParticle(eParticleType_largeexplode, x, y, z, 1.0f, 0, 0);
} else {
level->addParticle(eParticleType_hugeexplosion, x, y, z, 1.0f, 0, 0);
}
// 4J - use pointer to vector directly passed in if this is available - used // 4J - use pointer to vector directly passed in if this is available - used
// to speed up calling this from an incoming packet // to speed up calling this from an incoming packet
std::vector<TilePos>* toBlowArray = std::vector<TilePos>* toBlowArray =
toBlowDirect ? toBlowDirect toBlowDirect ? toBlowDirect
: new std::vector<TilePos>(toBlow.begin(), toBlow.end()); : new std::vector<TilePos>(toBlow.begin(), toBlow.end());
// toBlowArray.addAll(toBlow); if (destroyBlocks) {
// TODO 4J Stu - Reverse iterator // toBlowArray.addAll(toBlow);
PIXBeginNamedEvent(0, "Finalizing explosion size %d", toBlow.size()); // TODO 4J Stu - Reverse iterator
app.DebugPrintf("Finalizing explosion size %d\n", toBlow.size()); PIXBeginNamedEvent(0, "Finalizing explosion size %d", toBlow.size());
static const int MAX_EXPLODE_PARTICLES = 50; app.DebugPrintf("Finalizing explosion size %d\n", toBlow.size());
// 4J - try and make at most MAX_EXPLODE_PARTICLES pairs of particles static const int MAX_EXPLODE_PARTICLES = 50;
int fraction = (int)toBlowArray->size() / MAX_EXPLODE_PARTICLES; // 4J - try and make at most MAX_EXPLODE_PARTICLES pairs of particles
if (fraction == 0) fraction = 1; int fraction = (int)toBlowArray->size() / MAX_EXPLODE_PARTICLES;
size_t j = toBlowArray->size() - 1; if (fraction == 0) fraction = 1;
// for (size_t j = toBlowArray->size() - 1; j >= 0; j--) size_t j = toBlowArray->size() - 1;
for (AUTO_VAR(it, toBlowArray->rbegin()); it != toBlowArray->rend(); ++it) { // for (size_t j = toBlowArray->size() - 1; j >= 0; j--)
TilePos* tp = &(*it); //&toBlowArray->at(j); for (AUTO_VAR(it, toBlowArray->rbegin()); it != toBlowArray->rend();
int xt = tp->x; ++it) {
int yt = tp->y; TilePos* tp = &(*it); //&toBlowArray->at(j);
int zt = tp->z; int xt = tp->x;
// if (xt >= 0 && yt >= 0 && zt >= 0 && xt < width && yt < depth && int yt = tp->y;
// zt < height) { int zt = tp->z;
int t = level->getTile(xt, yt, zt); // if (xt >= 0 && yt >= 0 && zt >= 0 && xt < width && yt < depth &&
// zt < height) {
int t = level->getTile(xt, yt, zt);
if (generateParticles) { if (generateParticles) {
if ((j % fraction) == 0) { if ((j % fraction) == 0) {
double xa = xt + level->random->nextFloat(); double xa = xt + level->random->nextFloat();
double ya = yt + level->random->nextFloat(); double ya = yt + level->random->nextFloat();
double za = zt + level->random->nextFloat(); double za = zt + level->random->nextFloat();
double xd = xa - x; double xd = xa - x;
double yd = ya - y; double yd = ya - y;
double zd = za - z; double zd = za - z;
double dd = sqrt(xd * xd + yd * yd + zd * zd); double dd = sqrt(xd * xd + yd * yd + zd * zd);
xd /= dd; xd /= dd;
yd /= dd; yd /= dd;
zd /= dd; zd /= dd;
double speed = 0.5 / (dd / r + 0.1); double speed = 0.5 / (dd / r + 0.1);
speed *= speed *= (level->random->nextFloat() *
(level->random->nextFloat() * level->random->nextFloat() + level->random->nextFloat() +
0.3f); 0.3f);
xd *= speed; xd *= speed;
yd *= speed; yd *= speed;
zd *= speed; zd *= speed;
level->addParticle(eParticleType_explode, (xa + x * 1) / 2, level->addParticle(eParticleType_explode, (xa + x * 1) / 2,
(ya + y * 1) / 2, (za + z * 1) / 2, xd, yd, (ya + y * 1) / 2, (za + z * 1) / 2, xd,
zd); yd, zd);
level->addParticle(eParticleType_smoke, xa, ya, za, xd, yd, zd); level->addParticle(eParticleType_smoke, xa, ya, za, xd, yd,
zd);
}
} }
}
if (t > 0) { if (t > 0) {
Tile::tiles[t]->spawnResources(level, xt, yt, zt, Tile* tile = Tile::tiles[t];
level->getData(xt, yt, zt), 0.3f, 0);
level->setTile(xt, yt, zt, 0);
Tile::tiles[t]->wasExploded(level, xt, yt, zt);
}
// }
--j; if (tile->dropFromExplosion(this)) {
tile->spawnResources(level, xt, yt, zt,
level->getData(xt, yt, zt), 1.0f / r,
0);
}
level->setTileAndData(xt, yt, zt, 0, 0, Tile::UPDATE_ALL);
tile->wasExploded(level, xt, yt, zt, this);
}
--j;
}
} }
if (fire) { if (fire) {
@ -250,7 +272,7 @@ void Explosion::finalizeExplosion(
int t = level->getTile(xt, yt, zt); int t = level->getTile(xt, yt, zt);
int b = level->getTile(xt, yt - 1, zt); int b = level->getTile(xt, yt - 1, zt);
if (t == 0 && Tile::solid[b] && random->nextInt(3) == 0) { if (t == 0 && Tile::solid[b] && random->nextInt(3) == 0) {
level->setTile(xt, yt, zt, Tile::fire_Id); level->setTileAndUpdate(xt, yt, zt, Tile::fire_Id);
} }
} }
} }
@ -267,4 +289,13 @@ Vec3* Explosion::getHitPlayerKnockback(std::shared_ptr<Player> player) {
if (it == hitPlayers.end()) return Vec3::newTemp(0.0, 0.0, 0.0); if (it == hitPlayers.end()) return Vec3::newTemp(0.0, 0.0, 0.0);
return it->second; return it->second;
}
std::shared_ptr<LivingEntity> Explosion::getSourceMob() {
if (source == NULL) return nullptr;
if (source->instanceof(eTYPE_PRIMEDTNT))
return std::dynamic_pointer_cast<PrimedTnt>(source)->getOwner();
if (source->instanceof(eTYPE_LIVINGENTITY))
return std::dynamic_pointer_cast<LivingEntity>(source);
return nullptr;
} }

View file

@ -43,4 +43,5 @@ public:
NULL); // 4J - added toBlow parameter NULL); // 4J - added toBlow parameter
playerVec3Map* getHitPlayers(); playerVec3Map* getHitPlayers();
Vec3* getHitPlayerKnockback(std::shared_ptr<Player> player); Vec3* getHitPlayerKnockback(std::shared_ptr<Player> player);
std::shared_ptr<LivingEntity> getSourceMob();
}; };

View file

@ -0,0 +1,191 @@
#include "../Platform/stdafx.h"
#include "GameRules.h"
// 4J: GameRules isn't in use anymore, just routes any requests to app game host
// options, kept things commented out for context
const int GameRules::RULE_DOFIRETICK = 0;
const int GameRules::RULE_MOBGRIEFING = 1;
const int GameRules::RULE_KEEPINVENTORY = 2;
const int GameRules::RULE_DOMOBSPAWNING = 3;
const int GameRules::RULE_DOMOBLOOT = 4;
const int GameRules::RULE_DOTILEDROPS = 5;
// const int GameRules::RULE_COMMANDBLOCKOUTPUT = 6;
const int GameRules::RULE_NATURAL_REGENERATION = 7;
const int GameRules::RULE_DAYLIGHT = 8;
GameRules::GameRules() {
/*registerRule(RULE_DOFIRETICK, L"1");
registerRule(RULE_MOBGRIEFING, L"1");
registerRule(RULE_KEEPINVENTORY, L"0");
registerRule(RULE_DOMOBSPAWNING, L"1");
registerRule(RULE_DOMOBLOOT, L"1");
registerRule(RULE_DOTILEDROPS, L"1");
registerRule(RULE_COMMANDBLOCKOUTPUT, L"1");
registerRule(RULE_NATURAL_REGENERATION, L"1");
registerRule(RULE_DAYLIGHT, L"1");*/
}
GameRules::~GameRules() {
/*for(AUTO_VAR(it,rules.begin()); it != rules.end(); ++it)
{
delete it->second;
}*/
}
bool GameRules::getBoolean(const int rule) {
switch (rule) {
case GameRules::RULE_DOFIRETICK:
return app.GetGameHostOption(eGameHostOption_FireSpreads);
case GameRules::RULE_MOBGRIEFING:
return app.GetGameHostOption(eGameHostOption_MobGriefing);
case GameRules::RULE_KEEPINVENTORY:
return app.GetGameHostOption(eGameHostOption_KeepInventory);
case GameRules::RULE_DOMOBSPAWNING:
return app.GetGameHostOption(eGameHostOption_DoMobSpawning);
case GameRules::RULE_DOMOBLOOT:
return app.GetGameHostOption(eGameHostOption_DoMobLoot);
case GameRules::RULE_DOTILEDROPS:
return app.GetGameHostOption(eGameHostOption_DoTileDrops);
case GameRules::RULE_NATURAL_REGENERATION:
return app.GetGameHostOption(eGameHostOption_NaturalRegeneration);
case GameRules::RULE_DAYLIGHT:
return app.GetGameHostOption(eGameHostOption_DoDaylightCycle);
default:
assert(0);
return false;
}
}
/*
void GameRules::registerRule(const std::wstring &name, const std::wstring
&startValue)
{
rules[name] = new GameRule(startValue);
}
void GameRules::set(const std::wstring &ruleName, const std::wstring &newValue)
{
AUTO_VAR(it, rules.find(ruleName));
if(it != rules.end() )
{
GameRule *gameRule = it->second;
gameRule->set(newValue);
}
else
{
registerRule(ruleName, newValue);
}
}
std::wstring GameRules::get(const std::wstring &ruleName)
{
AUTO_VAR(it, rules.find(ruleName));
if(it != rules.end() )
{
GameRule *gameRule = it->second;
return gameRule->get();
}
return L"";
}
int GameRules::getInt(const std::wstring &ruleName)
{
AUTO_VAR(it, rules.find(ruleName));
if(it != rules.end() )
{
GameRule *gameRule = it->second;
return gameRule->getInt();
}
return 0;
}
double GameRules::getDouble(const std::wstring &ruleName)
{
AUTO_VAR(it, rules.find(ruleName));
if(it != rules.end() )
{
GameRule *gameRule = it->second;
return gameRule->getDouble();
}
return 0;
}
CompoundTag *GameRules::createTag()
{
CompoundTag *result = new CompoundTag(L"GameRules");
for(AUTO_VAR(it,rules.begin()); it != rules.end(); ++it)
{
GameRule *gameRule = it->second;
result->putString(it->first, gameRule->get());
}
return result;
}
void GameRules::loadFromTag(CompoundTag *tag)
{
vector<Tag *> *allTags = tag->getAllTags();
for (AUTO_VAR(it, allTags->begin()); it != allTags->end(); ++it)
{
Tag *ruleTag = *it;
std::wstring ruleName = ruleTag->getName();
std::wstring value = tag->getString(ruleTag->getName());
set(ruleName, value);
}
delete allTags;
}
// Need to delete returned vector.
vector<std::wstring> *GameRules::getRuleNames()
{
vector<std::wstring> *out = new vector<std::wstring>();
for (AUTO_VAR(it, rules.begin()); it != rules.end(); it++)
out->push_back(it->first); return out;
}
bool GameRules::contains(const std::wstring &rule)
{
AUTO_VAR(it, rules.find(rule));
return it != rules.end();
}
GameRules::GameRule::GameRule(const std::wstring &startValue)
{
value = L"";
booleanValue = false;
intValue = 0;
doubleValue = 0.0;
set(startValue);
}
void GameRules::GameRule::set(const std::wstring &newValue)
{
value = newValue;
booleanValue = _fromString<bool>(newValue);
intValue = _fromString<int>(newValue);
doubleValue = _fromString<double>(newValue);
}
std::wstring GameRules::GameRule::get()
{
return value;
}
bool GameRules::GameRule::getBoolean()
{
return booleanValue;
}
int GameRules::GameRule::getInt()
{
return intValue;
}
double GameRules::GameRule::getDouble()
{
return doubleValue;
}*/

View file

@ -0,0 +1,54 @@
#pragma once
class GameRules {
private:
class GameRule {
private:
std::wstring value;
bool booleanValue;
int intValue;
double doubleValue;
public:
GameRule(const std::wstring& startValue);
void set(const std::wstring& newValue);
std::wstring get();
bool getBoolean();
int getInt();
double getDouble();
};
public:
// 4J: Originally strings
// default rules
static const int RULE_DOFIRETICK;
static const int RULE_MOBGRIEFING;
static const int RULE_KEEPINVENTORY;
static const int RULE_DOMOBSPAWNING;
static const int RULE_DOMOBLOOT;
static const int RULE_DOTILEDROPS;
static const int RULE_COMMANDBLOCKOUTPUT;
static const int RULE_NATURAL_REGENERATION;
static const int RULE_DAYLIGHT;
private:
std::unordered_map<std::wstring, GameRule*> rules;
public:
GameRules();
~GameRules();
bool getBoolean(const int rule);
// 4J: Removed unused functions
/*void set(const std::wstring &ruleName, const std::wstring &newValue);
void registerRule(const std::wstring &name, const std::wstring &startValue);
std::wstring get(const std::wstring &ruleName);
int getInt(const std::wstring &ruleName);
double getDouble(const std::wstring &ruleName);
CompoundTag *createTag();
void loadFromTag(CompoundTag *tag);
vector<std::wstring> *getRuleNames();
bool contains(const std::wstring &rule);*/
};

File diff suppressed because it is too large Load diff

View file

@ -46,6 +46,11 @@ class LevelSettings;
class Biome; class Biome;
class Villages; class Villages;
class VillageSiege; class VillageSiege;
class Tickable;
class Minecart;
class EntitySelector;
class Scoreboard;
class GameRules;
class Level : public LevelSource { class Level : public LevelSource {
public: public:
@ -138,11 +143,10 @@ public:
protected: protected:
float oRainLevel, rainLevel; float oRainLevel, rainLevel;
float oThunderLevel, thunderLevel; float oThunderLevel, thunderLevel;
int lightningTime;
public: public:
int lightningBoltTime; int skyFlashTime;
bool noNeighborUpdate;
int difficulty; int difficulty;
Random* random; Random* random;
bool isNew; bool isNew;
@ -168,6 +172,13 @@ public:
std::shared_ptr<Villages> villages; std::shared_ptr<Villages> villages;
VillageSiege* villageSiege; VillageSiege* villageSiege;
private:
// 4J - Calendar is now static
// Calendar *calendar;
protected:
Scoreboard* scoreboard;
public: public:
Biome* getBiome(int x, int z); // 4J - brought forward from 1.2.3 Biome* getBiome(int x, int z); // 4J - brought forward from 1.2.3
virtual BiomeSource* getBiomeSource(); virtual BiomeSource* getBiomeSource();
@ -183,7 +194,6 @@ public:
Level(std::shared_ptr<LevelStorage> levelStorage, const std::wstring& name, Level(std::shared_ptr<LevelStorage> levelStorage, const std::wstring& name,
Dimension* dimension, LevelSettings* levelSettings, Dimension* dimension, LevelSettings* levelSettings,
bool doCreateChunkSource = true); bool doCreateChunkSource = true);
Level(Level* level, Dimension* dimension);
Level(std::shared_ptr<LevelStorage> levelStorage, Level(std::shared_ptr<LevelStorage> levelStorage,
const std::wstring& levelName, LevelSettings* levelSettings); const std::wstring& levelName, LevelSettings* levelSettings);
Level(std::shared_ptr<LevelStorage> levelStorage, Level(std::shared_ptr<LevelStorage> levelStorage,
@ -209,6 +219,8 @@ public:
bool isEmptyTile(int x, int y, int z); bool isEmptyTile(int x, int y, int z);
virtual bool isEntityTile(int x, int y, int z); virtual bool isEntityTile(int x, int y, int z);
int getTileRenderShape(int x, int y, int z); int getTileRenderShape(int x, int y, int z);
int getTileRenderShape(int t); // 4J Added to slightly optimise and avoid
// getTile call if we already know the tile
bool hasChunkAt(int x, int y, int z); bool hasChunkAt(int x, int y, int z);
bool hasChunksAt(int x, int y, int z, int r); bool hasChunksAt(int x, int y, int z, int r);
bool hasChunksAt(int x0, int y0, int z0, int x1, int y1, int z1); bool hasChunksAt(int x0, int y0, int z0, int x1, int y1, int z1);
@ -224,40 +236,34 @@ public:
public: public:
LevelChunk* getChunkAt(int x, int z); LevelChunk* getChunkAt(int x, int z);
LevelChunk* getChunk(int x, int z); LevelChunk* getChunk(int x, int z);
virtual bool setTileAndDataNoUpdate(int x, int y, int z, int tile, virtual bool setTileAndData(int x, int y, int z, int tile, int data,
int data); int updateFlags);
virtual bool setTileAndDataNoUpdate(int x, int y, int z, int tile, int data,
bool informClients);
virtual bool setTileNoUpdate(int x, int y, int z, int tile);
bool setTileNoUpdateNoLightCheck(int x, int y, int z,
int tile); // 4J added
Material* getMaterial(int x, int y, int z); Material* getMaterial(int x, int y, int z);
virtual int getData(int x, int y, int z); virtual int getData(int x, int y, int z);
void setData(int x, int y, int z, int data, virtual bool setData(int x, int y, int z, int data, int updateFlags,
bool forceUpdate = false); // 4J added forceUpdate bool forceUpdate = false); // 4J added forceUpdate
virtual bool setDataNoUpdate(int x, int y, int z, int data); virtual bool removeTile(int x, int y, int z);
bool setTile(int x, int y, int z, int tile); virtual bool destroyTile(int x, int y, int z, bool dropResources);
bool setTileAndData(int x, int y, int z, int tile, int data); virtual bool setTileAndUpdate(int x, int y, int z, int tile);
void sendTileUpdated(int x, int y, int z); virtual void sendTileUpdated(int x, int y, int z);
public: public:
virtual void tileUpdated(int x, int y, int z, int tile); virtual void tileUpdated(int x, int y, int z, int tile);
void lightColumnChanged(int x, int z, int y0, int y1); void lightColumnChanged(int x, int z, int y0, int y1);
void setTileDirty(int x, int y, int z); void setTileDirty(int x, int y, int z);
void setTilesDirty(int x0, int y0, int z0, int x1, int y1, int z1); void setTilesDirty(int x0, int y0, int z0, int x1, int y1, int z1);
void swap(int x1, int y1, int z1, int x2, int y2, int z2);
void updateNeighborsAt(int x, int y, int z, int tile); void updateNeighborsAt(int x, int y, int z, int tile);
void updateNeighborsAtExceptFromFacing(int x, int y, int z, int tile,
private: int skipFacing);
void neighborChanged(int x, int y, int z, int type); void neighborChanged(int x, int y, int z, int type);
virtual bool isTileToBeTickedAt(int x, int y, int z, int tileId);
public:
bool canSeeSky(int x, int y, int z); bool canSeeSky(int x, int y, int z);
int getDaytimeRawBrightness(int x, int y, int z); int getDaytimeRawBrightness(int x, int y, int z);
int getRawBrightness(int x, int y, int z); int getRawBrightness(int x, int y, int z);
int getRawBrightness(int x, int y, int z, bool propagate); int getRawBrightness(int x, int y, int z, bool propagate);
bool isSkyLit(int x, int y, int z); bool isSkyLit(int x, int y, int z);
int getHeightmap(int x, int z); int getHeightmap(int x, int z);
int getLowestHeightmap(int x, int z);
void updateLightIfOtherThan(LightLayer::variety layer, int x, int y, int z, void updateLightIfOtherThan(LightLayer::variety layer, int x, int y, int z,
int expected); int expected);
int getBrightnessPropagate(LightLayer::variety layer, int x, int y, int z, int getBrightnessPropagate(LightLayer::variety layer, int x, int y, int z,
@ -272,11 +278,11 @@ public:
int z, int brightness); // 4J added int z, int brightness); // 4J added
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
typedef __uint64 lightCache_t; typedef uint64_t lightCache_t;
#else #else
typedef unsigned int lightCache_t; typedef unsigned int lightCache_t;
#endif #endif
inline void setBrightnessCached(lightCache_t* cache, __uint64* cacheUse, inline void setBrightnessCached(lightCache_t* cache, uint64_t* cacheUse,
LightLayer::variety layer, int x, int y, LightLayer::variety layer, int x, int y,
int z, int brightness); int z, int brightness);
inline int getBrightnessCached(lightCache_t* cache, inline int getBrightnessCached(lightCache_t* cache,
@ -286,8 +292,9 @@ public:
int z); int z);
inline int getBlockingCached(lightCache_t* cache, LightLayer::variety layer, inline int getBlockingCached(lightCache_t* cache, LightLayer::variety layer,
int* ct, int x, int y, int z); int* ct, int x, int y, int z);
void initCache(lightCache_t* cache); void initCachePartial(lightCache_t* cache, int xc, int yc, int zc);
void flushCache(lightCache_t* cache, __uint64 cacheUse, void initCacheComplete(lightCache_t* cache, int xc, int yc, int zc);
void flushCache(lightCache_t* cache, uint64_t cacheUse,
LightLayer::variety layer); LightLayer::variety layer);
bool cachewritten; bool cachewritten;
@ -295,10 +302,10 @@ public:
static const int BLOCKING_SHIFT = 20; static const int BLOCKING_SHIFT = 20;
static const int EMISSION_SHIFT = 16; static const int EMISSION_SHIFT = 16;
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
static const __int64 LIGHTING_WRITEBACK = 0x80000000LL; static const int64_t LIGHTING_WRITEBACK = 0x80000000LL;
static const __int64 EMISSION_VALID = 0x40000000LL; static const int64_t EMISSION_VALID = 0x40000000LL;
static const __int64 BLOCKING_VALID = 0x20000000LL; static const int64_t BLOCKING_VALID = 0x20000000LL;
static const __int64 LIGHTING_VALID = 0x10000000LL; static const int64_t LIGHTING_VALID = 0x10000000LL;
static const lightCache_t POSITION_MASK = 0xffffffff0000ffffLL; static const lightCache_t POSITION_MASK = 0xffffffff0000ffffLL;
#else #else
static const int LIGHTING_WRITEBACK = 0x80000000; static const int LIGHTING_WRITEBACK = 0x80000000;
@ -320,19 +327,21 @@ public:
HitResult* clip(Vec3* a, Vec3* b, bool liquid); HitResult* clip(Vec3* a, Vec3* b, bool liquid);
HitResult* clip(Vec3* a, Vec3* b, bool liquid, bool solidOnly); HitResult* clip(Vec3* a, Vec3* b, bool liquid, bool solidOnly);
virtual void playSound(std::shared_ptr<Entity> entity, int iSound, virtual void playEntitySound(std::shared_ptr<Entity> entity, int iSound,
float volume, float pitch); float volume, float pitch);
virtual void playPlayerSound(std::shared_ptr<Player> entity, int iSound,
float volume, float pitch);
virtual void playSound(double x, double y, double z, int iSound, virtual void playSound(double x, double y, double z, int iSound,
float volume, float pitch, float volume, float pitch,
float fClipSoundDist = 16.0f); float fClipSoundDist = 16.0f);
virtual void playLocalSound(double x, double y, double z, int iSound, virtual void playLocalSound(double x, double y, double z, int iSound,
float volume, float pitch, float volume, float pitch, bool distanceDelay,
float fClipSoundDist = 16.0f); float fClipSoundDist = 16.0f);
void playStreamingMusic(const std::wstring& name, int x, int y, int z); void playStreamingMusic(const std::wstring& name, int x, int y, int z);
void playMusic(double x, double y, double z, const std::wstring& string, void playMusic(double x, double y, double z,
float volume); const std::wstring& std::string, float volume);
// 4J removed - void addParticle(const std::wstring& id, double x, double y, // 4J removed - void addParticle(const std::wstring& id, double x, double y,
// double z, double xd, double yd, double zd); // double z, double xd, double yd, double zd);
void addParticle(ePARTICLE_TYPE id, double x, double y, double z, double xd, void addParticle(ePARTICLE_TYPE id, double x, double y, double z, double xd,
@ -358,17 +367,16 @@ public:
AABBList* getCubes( AABBList* getCubes(
std::shared_ptr<Entity> source, AABB* box, bool noEntities = false, std::shared_ptr<Entity> source, AABB* box, bool noEntities = false,
bool blockAtEdge = bool blockAtEdge =
false); // 4J - added noEntities & blockAtEdge parameters false); // 4J: Added noEntities & blockAtEdge parameters
AABBList* getTileCubes( AABBList* getTileCubes(
AABB* box, AABB* box, bool blockAtEdge =
bool blockAtEdge); // 4J Stu - Brought forward from 12w36 to fix #46282 false); // 4J: Added noEntities & blockAtEdge parameters
// - TU5: Gameplay: Exiting the minecart in a tight
// corridor damages the player
int getOldSkyDarken(float a); // 4J - change brought forward from 1.8.2 int getOldSkyDarken(float a); // 4J - change brought forward from 1.8.2
float getSkyDarken(float a); // 4J - change brought forward from 1.8.2 float getSkyDarken(float a); // 4J - change brought forward from 1.8.2
Vec3* getSkyColor(std::shared_ptr<Entity> source, float a); Vec3* getSkyColor(std::shared_ptr<Entity> source, float a);
float getTimeOfDay(float a); float getTimeOfDay(float a);
int getMoonPhase(float a); int getMoonPhase();
float getMoonBrightness();
float getSunAngle(float a); float getSunAngle(float a);
Vec3* getCloudColor(float a); Vec3* getCloudColor(float a);
Vec3* getFogColor(float a); Vec3* getFogColor(float a);
@ -380,8 +388,10 @@ public:
float getStarBrightness(float a); float getStarBrightness(float a);
virtual void addToTickNextTick(int x, int y, int z, int tileId, virtual void addToTickNextTick(int x, int y, int z, int tileId,
int tickDelay); int tickDelay);
virtual void addToTickNextTick(int x, int y, int z, int tileId,
int tickDelay, int priorityTilt);
virtual void forceAddTileTick(int x, int y, int z, int tileId, virtual void forceAddTileTick(int x, int y, int z, int tileId,
int tickDelay); int tickDelay, int prioTilt);
virtual void tickEntities(); virtual void tickEntities();
void addAllPendingTileEntities( void addAllPendingTileEntities(
std::vector<std::shared_ptr<TileEntity> >& entities); std::vector<std::shared_ptr<TileEntity> >& entities);
@ -420,8 +430,10 @@ public:
virtual bool isSolidBlockingTile(int x, int y, int z); virtual bool isSolidBlockingTile(int x, int y, int z);
bool isSolidBlockingTileInLoadedChunk(int x, int y, int z, bool isSolidBlockingTileInLoadedChunk(int x, int y, int z,
bool valueIfNotLoaded); bool valueIfNotLoaded);
bool isFullAABBTile(int x, int y, int z);
virtual bool isTopSolidBlocking(int x, int y, virtual bool isTopSolidBlocking(int x, int y,
int z); // 4J - brought forward from 1.3.2 int z); // 4J - brought forward from 1.3.2
bool isTopSolidBlocking(Tile* tile, int data);
protected: protected:
bool spawnEnemies; bool spawnEnemies;
@ -477,11 +489,9 @@ public:
false); // 4J added force, rootOnlySource parameters false); // 4J added force, rootOnlySource parameters
private: private:
int* toCheckLevel; int* toCheckLevel;
int getExpectedSkyColor(lightCache_t* cache, int oc, int x, int y, int z, int getExpectedLight(lightCache_t* cache, int x, int y, int z,
int ct, int block); LightLayer::variety layer, bool propagatedOnly);
int getExpectedBlockColor(lightCache_t* cache, int oc, int x, int y, int z,
int ct, int block,
bool propagatedOnly); // 4J added parameter
public: public:
void checkLight(LightLayer::variety layer, int xc, int yc, int zc, void checkLight(LightLayer::variety layer, int xc, int yc, int zc,
bool force = false, bool force = false,
@ -501,11 +511,18 @@ public:
std::vector<std::shared_ptr<Entity> >* getEntities( std::vector<std::shared_ptr<Entity> >* getEntities(
std::shared_ptr<Entity> except, AABB* bb); std::shared_ptr<Entity> except, AABB* bb);
std::vector<std::shared_ptr<Entity> >* getEntities(
std::shared_ptr<Entity> except, AABB* bb,
const EntitySelector* selector);
std::vector<std::shared_ptr<Entity> >* getEntitiesOfClass( std::vector<std::shared_ptr<Entity> >* getEntitiesOfClass(
const std::type_info& baseClass, AABB* bb); const std::type_info& baseClass, AABB* bb);
std::vector<std::shared_ptr<Entity> >* getEntitiesOfClass(
const std::type_info& baseClass, AABB* bb,
const EntitySelector* selector);
std::shared_ptr<Entity> getClosestEntityOfClass( std::shared_ptr<Entity> getClosestEntityOfClass(
const std::type_info& baseClass, AABB* bb, const std::type_info& baseClass, AABB* bb,
std::shared_ptr<Entity> source); std::shared_ptr<Entity> source);
virtual std::shared_ptr<Entity> getEntity(int entityId) = 0;
std::vector<std::shared_ptr<Entity> > getAllEntities(); std::vector<std::shared_ptr<Entity> > getAllEntities();
void tileEntityChanged(int x, int y, int z, std::shared_ptr<TileEntity> te); void tileEntityChanged(int x, int y, int z, std::shared_ptr<TileEntity> te);
// unsigned int countInstanceOf(BaseObject::Class *clas); // unsigned int countInstanceOf(BaseObject::Class *clas);
@ -518,7 +535,8 @@ public:
void addEntities(std::vector<std::shared_ptr<Entity> >* list); void addEntities(std::vector<std::shared_ptr<Entity> >* list);
virtual void removeEntities(std::vector<std::shared_ptr<Entity> >* list); virtual void removeEntities(std::vector<std::shared_ptr<Entity> >* list);
bool mayPlace(int tileId, int x, int y, int z, bool ignoreEntities, bool mayPlace(int tileId, int x, int y, int z, bool ignoreEntities,
int face, std::shared_ptr<Entity> ignoreEntity); int face, std::shared_ptr<Entity> ignoreEntity,
std::shared_ptr<ItemInstance> item);
int getSeaLevel(); int getSeaLevel();
Path* findPath(std::shared_ptr<Entity> from, std::shared_ptr<Entity> to, Path* findPath(std::shared_ptr<Entity> from, std::shared_ptr<Entity> to,
float maxDist, bool canPassDoors, bool canOpenDoors, float maxDist, bool canPassDoors, bool canOpenDoors,
@ -526,10 +544,12 @@ public:
Path* findPath(std::shared_ptr<Entity> from, int xBest, int yBest, Path* findPath(std::shared_ptr<Entity> from, int xBest, int yBest,
int zBest, float maxDist, bool canPassDoors, int zBest, float maxDist, bool canPassDoors,
bool canOpenDoors, bool avoidWater, bool canFloat); bool canOpenDoors, bool avoidWater, bool canFloat);
bool getDirectSignal(int x, int y, int z, int dir); int getDirectSignal(int x, int y, int z, int dir);
bool hasDirectSignal(int x, int y, int z); int getDirectSignalTo(int x, int y, int z);
bool getSignal(int x, int y, int z, int dir); bool hasSignal(int x, int y, int z, int dir);
int getSignal(int x, int y, int z, int dir);
bool hasNeighborSignal(int x, int y, int z); bool hasNeighborSignal(int x, int y, int z);
int getBestNeighborSignal(int x, int y, int z);
// 4J Added maxYDist param // 4J Added maxYDist param
std::shared_ptr<Player> getNearestPlayer(std::shared_ptr<Entity> source, std::shared_ptr<Player> getNearestPlayer(std::shared_ptr<Entity> source,
double maxDist, double maxDist,
@ -554,12 +574,11 @@ public:
byteArray data, bool includeLighting = true); byteArray data, bool includeLighting = true);
virtual void disconnect(bool sendDisconnect = true); virtual void disconnect(bool sendDisconnect = true);
void checkSession(); void checkSession();
void setTime(__int64 time); void setGameTime(int64_t time);
void setOverrideTimeOfDay( int64_t getSeed();
__int64 time); // 4J Added so we can override timeOfDay without int64_t getGameTime();
// changing tick time int64_t getDayTime();
__int64 getSeed(); void setDayTime(int64_t newTime);
__int64 getTime();
Pos* getSharedSpawnPos(); Pos* getSharedSpawnPos();
void setSpawnPos(int x, int y, int z); void setSpawnPos(int x, int y, int z);
void setSpawnPos(Pos* spawnPos); void setSpawnPos(Pos* spawnPos);
@ -571,6 +590,7 @@ public:
virtual void tileEvent(int x, int y, int z, int tile, int b0, int b1); virtual void tileEvent(int x, int y, int z, int tile, int b0, int b1);
LevelStorage* getLevelStorage(); LevelStorage* getLevelStorage();
LevelData* getLevelData(); LevelData* getLevelData();
GameRules* getGameRules();
virtual void updateSleepingPlayerList(); virtual void updateSleepingPlayerList();
bool useNewSeaLevel(); // 4J added bool useNewSeaLevel(); // 4J added
bool getHasBeenInCreative(); // 4J Added bool getHasBeenInCreative(); // 4J Added
@ -588,16 +608,26 @@ public:
std::shared_ptr<SavedData> getSavedData(const std::type_info& clazz, std::shared_ptr<SavedData> getSavedData(const std::type_info& clazz,
const std::wstring& id); const std::wstring& id);
int getFreeAuxValueFor(const std::wstring& id); int getFreeAuxValueFor(const std::wstring& id);
void globalLevelEvent(int type, int sourceX, int sourceY, int sourceZ,
int data);
void levelEvent(int type, int x, int y, int z, int data); void levelEvent(int type, int x, int y, int z, int data);
void levelEvent(std::shared_ptr<Player> source, int type, int x, int y, void levelEvent(std::shared_ptr<Player> source, int type, int x, int y,
int z, int data); int z, int data);
int getMaxBuildHeight(); int getMaxBuildHeight();
int getHeight(); int getHeight();
virtual Tickable* makeSoundUpdater(std::shared_ptr<Minecart> minecart);
Random* getRandomFor(int x, int z, int blend); Random* getRandomFor(int x, int z, int blend);
bool updateLights();
virtual bool isAllEmpty(); virtual bool isAllEmpty();
double getHorizonHeight(); double getHorizonHeight();
void destroyTileProgress(int id, int x, int y, int z, int progress); void destroyTileProgress(int id, int x, int y, int z, int progress);
// Calendar *getCalendar(); // 4J - Calendar is now static
virtual void createFireworks(double x, double y, double z, double xd,
double yd, double zd, CompoundTag* infoTag);
virtual Scoreboard* getScoreboard();
virtual void updateNeighbourForOutputSignal(int x, int y, int z,
int source);
virtual float getDifficulty(double x, double y, double z);
virtual float getDifficulty(int x, int y, int z);
TilePos* findNearestMapFeature(const std::wstring& featureName, int x, TilePos* findNearestMapFeature(const std::wstring& featureName, int x,
int y, int z); int y, int z);
@ -605,10 +635,6 @@ public:
int getAuxValueForMap(PlayerUID xuid, int dimension, int centreXC, int getAuxValueForMap(PlayerUID xuid, int dimension, int centreXC,
int centreZC, int scale); int centreZC, int scale);
// 4J added
__int64 m_timeOfDayOverride;
// 4J - optimisation - keep direct reference of underlying cache here // 4J - optimisation - keep direct reference of underlying cache here
LevelChunk** chunkSourceCache; LevelChunk** chunkSourceCache;
int chunkSourceXZSize; int chunkSourceXZSize;
@ -642,6 +668,7 @@ public:
enum ESPAWN_TYPE { enum ESPAWN_TYPE {
eSpawnType_Egg, eSpawnType_Egg,
eSpawnType_Breed, eSpawnType_Breed,
eSpawnType_Portal,
}; };
bool canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType); bool canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType);

View file

@ -11,10 +11,13 @@
#include "Storage/SparseLightStorage.h" #include "Storage/SparseLightStorage.h"
#include "BlockReplacements.h" #include "BlockReplacements.h"
#include "LevelChunk.h" #include "LevelChunk.h"
#include "../Util/BasicTypeContainers.h"
#include "../../Minecraft.Client/MinecraftServer.h" #include "../../Minecraft.Client/MinecraftServer.h"
#include "../../Minecraft.Client/Level/ServerLevel.h" #include "../../Minecraft.Client/Level/ServerLevel.h"
#include "../../Minecraft.Client/Network/ServerChunkCache.h" #include "../../Minecraft.Client/Network/ServerChunkCache.h"
#include "../../Minecraft.Client/Rendering/GameRenderer.h" #include "../../Minecraft.Client/Rendering/GameRenderer.h"
#include "../Entities/ItemEntity.h"
#include "../Entities/Mobs/Minecart.h"
#ifdef __PS3__ #ifdef __PS3__
#include "../../Minecraft.Client/Platform/PS3/PS3Extras/C4JSpursJob.h" #include "../../Minecraft.Client/Platform/PS3/PS3Extras/C4JSpursJob.h"
@ -97,6 +100,9 @@ void LevelChunk::init(Level* level, int x, int z) {
MemSect(0); MemSect(0);
lowestHeightmap = 256;
inhabitedTime = 0;
// Optimisation brought forward from 1.8.2, change from int to unsigned char // Optimisation brought forward from 1.8.2, change from int to unsigned char
// & this special value changed from -999 to 255 // & this special value changed from -999 to 255
for (int i = 0; i < 16 * 16; i++) { for (int i = 0; i < 16 * 16; i++) {
@ -398,7 +404,7 @@ void LevelChunk::startSharingTilesAndData(int forceMs) {
} else { } else {
// Only force if it has been more than forceMs milliseconds since we // Only force if it has been more than forceMs milliseconds since we
// last wanted to unshare this chunk // last wanted to unshare this chunk
__int64 timenow = System::currentTimeMillis(); int64_t timenow = System::currentTimeMillis();
if ((timenow - lastUnsharedTime) < forceMs) { if ((timenow - lastUnsharedTime) < forceMs) {
LeaveCriticalSection(&m_csSharing); LeaveCriticalSection(&m_csSharing);
return; return;
@ -462,7 +468,7 @@ LevelChunk::~LevelChunk() {
bool LevelChunk::isAt(int x, int z) { return x == this->x && z == this->z; } bool LevelChunk::isAt(int x, int z) { return x == this->x && z == this->z; }
int LevelChunk::getHeightmap(int x, int z) { int LevelChunk::getHeightmap(int x, int z) {
return heightmap[(unsigned)z << 4 | x] & 0xff; return heightmap[z << 4 | x] & 0xff;
} }
int LevelChunk::getHighestSectionPosition() { int LevelChunk::getHighestSectionPosition() {
@ -555,6 +561,7 @@ void LevelChunk::recalcHeightmap() {
byteArray blockData = byteArray(Level::CHUNK_TILE_COUNT); byteArray blockData = byteArray(Level::CHUNK_TILE_COUNT);
getBlockData(blockData); getBlockData(blockData);
#endif #endif
lowestHeightmap = Integer::MAX_VALUE;
int min = Level::maxBuildHeight - 1; int min = Level::maxBuildHeight - 1;
for (int x = 0; x < 16; x++) for (int x = 0; x < 16; x++)
@ -607,6 +614,7 @@ void LevelChunk::recalcHeightmap() {
#endif #endif
heightmap[(unsigned)z << 4 | x] = (uint8_t)y; heightmap[(unsigned)z << 4 | x] = (uint8_t)y;
if (y < min) min = y; if (y < min) min = y;
if (y < lowestHeightmap) lowestHeightmap = y;
if (!level->dimension->hasCeiling) { if (!level->dimension->hasCeiling) {
int br = Level::MAX_BRIGHTNESS; int br = Level::MAX_BRIGHTNESS;
@ -934,6 +942,7 @@ void LevelChunk::recalcHeight(int x, int yStart, int z) {
y1 = y2; y1 = y2;
y2 = tmp; y2 = tmp;
} }
if (height < lowestHeightmap) lowestHeightmap = height;
if (!level->dimension->hasCeiling) { if (!level->dimension->hasCeiling) {
PIXBeginNamedEvent(0, "Light gaps"); PIXBeginNamedEvent(0, "Light gaps");
lightGap(xOffs - 1, zOffs, y1, y2); lightGap(xOffs - 1, zOffs, y1, y2);
@ -986,6 +995,15 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) {
int old = blocks->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z); int old = blocks->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z);
int oldData = data->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z); int oldData = data->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z);
if (old == _tile && oldData == _data) return false; if (old == _tile && oldData == _data) return false;
// 4J Stu - Need to do this here otherwise double chests don't always
// work correctly
std::shared_ptr<TileEntity> te = getTileEntity(x, y, z);
if (te != NULL) {
te->clearCache();
}
return false;
}
int xOffs = this->x * 16 + x; int xOffs = this->x * 16 + x;
int zOffs = this->z * 16 + z; int zOffs = this->z * 16 + z;
if (old != 0 && !level->isClientSide) { if (old != 0 && !level->isClientSide) {
@ -1056,7 +1074,8 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) {
blocks->set(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, blocks->set(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT,
z, 0); z, 0);
// blocks[x << // blocks[x <<
//level->depthBitsPlusFour | z << level->depthBits | y] = 0; // level->depthBitsPlusFour | z << level->depthBits | y] =
// 0;
} }
} }
} }
@ -1068,7 +1087,8 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) {
Tile::tiles[_tile]->isEntityTile()) { Tile::tiles[_tile]->isEntityTile()) {
std::shared_ptr<TileEntity> te = getTileEntity(x, y, z); std::shared_ptr<TileEntity> te = getTileEntity(x, y, z);
if (te == NULL) { if (te == NULL) {
te = ((EntityTile*)Tile::tiles[_tile])->newTileEntity(level); te = dynamic_cast<EntityTile*>(Tile::tiles[_tile])
->newTileEntity(level);
// app.DebugPrintf("%s: Setting tile id %d, created tileEntity // app.DebugPrintf("%s: Setting tile id %d, created tileEntity
// type %d\n", level->isClientSide?"Client":"Server", _tile, // type %d\n", level->isClientSide?"Client":"Server", _tile,
// te->GetType()); // te->GetType());
@ -1085,7 +1105,7 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) {
// AP - changed the method of EntityTile detection cos it's well slow on // AP - changed the method of EntityTile detection cos it's well slow on
// Vita mate // Vita mate
// else if (old > 0 && dynamic_cast<EntityTile *>(Tile::tiles[old]) != // else if (old > 0 && dynamic_cast<EntityTile *>(Tile::tiles[old]) !=
//NULL) // NULL)
else if (old > 0 && Tile::tiles[_tile] != NULL && else if (old > 0 && Tile::tiles[_tile] != NULL &&
Tile::tiles[_tile]->isEntityTile()) { Tile::tiles[_tile]->isEntityTile()) {
std::shared_ptr<TileEntity> te = getTileEntity(x, y, z); std::shared_ptr<TileEntity> te = getTileEntity(x, y, z);
@ -1137,6 +1157,9 @@ bool LevelChunk::setData(int x, int y, int z, int val, int mask,
int LevelChunk::getBrightness(LightLayer::variety layer, int x, int y, int z) { int LevelChunk::getBrightness(LightLayer::variety layer, int x, int y, int z) {
if (layer == LightLayer::Sky) { if (layer == LightLayer::Sky) {
if (level->dimension->hasCeiling) {
return 0;
}
SparseLightStorage* skyLight = SparseLightStorage* skyLight =
y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT ? upperSkyLight y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT ? upperSkyLight
: lowerSkyLight; : lowerSkyLight;
@ -1229,7 +1252,7 @@ int LevelChunk::getRawBrightness(int x, int y, int z, int skyDampen) {
level->dimension->hasCeiling level->dimension->hasCeiling
? 0 ? 0
: skyLight->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z); : skyLight->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z);
if (light > 0) LevelChunk::touchedSky = true; if (light > 0) touchedSky = true;
light -= skyDampen; light -= skyDampen;
SparseLightStorage* blockLight = y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT SparseLightStorage* blockLight = y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT
? upperBlockLight ? upperBlockLight
@ -1341,7 +1364,7 @@ std::shared_ptr<TileEntity> LevelChunk::getTileEntity(int x, int y, int z) {
// 4J Stu - Changed as we should not be using the [] accessor (causes an // 4J Stu - Changed as we should not be using the [] accessor (causes an
// insert when we don't want one) // insert when we don't want one)
// std::shared_ptr<TileEntity> tileEntity = tileEntities[pos]; // shared_ptr<TileEntity> tileEntity = tileEntities[pos];
EnterCriticalSection(&m_csTileEntities); EnterCriticalSection(&m_csTileEntities);
std::shared_ptr<TileEntity> tileEntity = nullptr; std::shared_ptr<TileEntity> tileEntity = nullptr;
AUTO_VAR(it, tileEntities.find(pos)); AUTO_VAR(it, tileEntities.find(pos));
@ -1366,7 +1389,8 @@ std::shared_ptr<TileEntity> LevelChunk::getTileEntity(int x, int y, int z) {
// if (tileEntity == NULL) // if (tileEntity == NULL)
//{ //{
tileEntity = ((EntityTile*)Tile::tiles[t])->newTileEntity(level); tileEntity =
dynamic_cast<EntityTile*>(Tile::tiles[t])->newTileEntity(level);
level->setTileEntity(this->x * 16 + x, y, this->z * 16 + z, tileEntity); level->setTileEntity(this->x * 16 + x, y, this->z * 16 + z, tileEntity);
//} //}
@ -1425,6 +1449,8 @@ void LevelChunk::setTileEntity(int x, int y, int z,
"tile!\n"); "tile!\n");
return; return;
} }
AUTO_VAR(it, tileEntities.find(pos));
if (it != tileEntities.end()) it->second->setRemoved();
tileEntity->clearRemoved(); tileEntity->clearRemoved();
@ -1471,10 +1497,11 @@ void LevelChunk::load() {
if (entityTags != NULL) { if (entityTags != NULL) {
for (int i = 0; i < entityTags->size(); i++) { for (int i = 0; i < entityTags->size(); i++) {
CompoundTag* teTag = entityTags->get(i); CompoundTag* teTag = entityTags->get(i);
std::shared_ptr<Entity> te = std::shared_ptr<Entity> ent =
EntityIO::loadStatic(teTag, level); EntityIO::loadStatic(teTag, level);
if (te != NULL) { if (ent != NULL) {
addEntity(te); ent->onLoadedFromSave();
addEntity(ent);
} }
} }
} }
@ -1612,6 +1639,33 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
#endif #endif
} }
bool LevelChunk::containsPlayer() {
#ifdef _ENTITIES_RW_SECTION
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
#endif
for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) {
std::vector<std::shared_ptr<Entity> >* vecEntity = entityBlocks[i];
for (int j = 0; j < vecEntity->size(); j++) {
if (vecEntity->at(j)->GetType() == eTYPE_SERVERPLAYER) {
#ifdef _ENTITIES_RW_SECTION
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
#endif
return true;
}
}
}
#ifdef _ENTITIES_RW_SECTION
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
#endif
return false;
}
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
bool LevelChunk::isUnloaded() { return m_bUnloaded; } bool LevelChunk::isUnloaded() { return m_bUnloaded; }
#endif #endif
@ -1619,7 +1673,8 @@ bool LevelChunk::isUnloaded() { return m_bUnloaded; }
void LevelChunk::markUnsaved() { this->setUnsaved(true); } void LevelChunk::markUnsaved() { this->setUnsaved(true); }
void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb, void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb,
std::vector<std::shared_ptr<Entity> >& es) { std::vector<std::shared_ptr<Entity> >& es,
const EntitySelector* selector) {
int yc0 = Mth::floor((bb->y0 - 2) / 16); int yc0 = Mth::floor((bb->y0 - 2) / 16);
int yc1 = Mth::floor((bb->y1 + 2) / 16); int yc1 = Mth::floor((bb->y1 + 2) / 16);
if (yc0 < 0) yc0 = 0; if (yc0 < 0) yc0 = 0;
@ -1636,14 +1691,16 @@ void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb,
AUTO_VAR(itEnd, entities->end()); AUTO_VAR(itEnd, entities->end());
for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) {
std::shared_ptr<Entity> e = *it; // entities->at(i); std::shared_ptr<Entity> e = *it; // entities->at(i);
if (e != except && e->bb->intersects(bb)) { if (e != except && e->bb->intersects(bb) &&
(selector == NULL || selector->matches(e))) {
es.push_back(e); es.push_back(e);
std::vector<std::shared_ptr<Entity> >* subs = std::vector<std::shared_ptr<Entity> >* subs =
e->getSubEntities(); e->getSubEntities();
if (subs != NULL) { if (subs != NULL) {
for (int j = 0; j < subs->size(); j++) { for (int j = 0; j < subs->size(); j++) {
e = subs->at(j); e = subs->at(j);
if (e != except && e->bb->intersects(bb)) { if (e != except && e->bb->intersects(bb) &&
(selector == NULL || selector->matches(e))) {
es.push_back(e); es.push_back(e);
} }
} }
@ -1657,7 +1714,8 @@ void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb,
} }
void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb, void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb,
std::vector<std::shared_ptr<Entity> >& es) { std::vector<std::shared_ptr<Entity> >& es,
const EntitySelector* selector) {
int yc0 = Mth::floor((bb->y0 - 2) / 16); int yc0 = Mth::floor((bb->y0 - 2) / 16);
int yc1 = Mth::floor((bb->y1 + 2) / 16); int yc1 = Mth::floor((bb->y1 + 2) / 16);
@ -1687,25 +1745,30 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb,
bool isAssignableFrom = false; bool isAssignableFrom = false;
// Some special cases where the base class is a general type that // Some special cases where the base class is a general type that
// our class may be derived from, otherwise do a direct comparison // our class may be derived from, otherwise do a direct comparison
// of std::type_info // of type_info
if (ec == typeid(Player)) { if (ec == typeid(Player))
if (std::dynamic_pointer_cast<Player>(e) != NULL) isAssignableFrom = e->instanceof(eTYPE_PLAYER);
isAssignableFrom = true; else if (ec == typeid(Entity))
} else if (ec == typeid(Mob)) { isAssignableFrom = e->instanceof(eTYPE_ENTITY);
if (std::dynamic_pointer_cast<Mob>(e) != NULL) else if (ec == typeid(Mob))
isAssignableFrom = true; isAssignableFrom = e->instanceof(eTYPE_MOB);
} else if (ec == typeid(Monster)) { else if (ec == typeid(LivingEntity))
if (std::dynamic_pointer_cast<Monster>(e) != NULL) isAssignableFrom = e->instanceof(eTYPE_LIVINGENTITY);
isAssignableFrom = true; else if (ec == typeid(ItemEntity))
} else if (ec == typeid(Zombie)) { isAssignableFrom = e->instanceof(eTYPE_ITEMENTITY);
if (std::dynamic_pointer_cast<Zombie>(e) != NULL) else if (ec == typeid(Minecart))
isAssignableFrom = true; isAssignableFrom = e->instanceof(eTYPE_MINECART);
} else { else if (ec == typeid(Monster))
Entity* entityPtr = e.get(); isAssignableFrom = e->instanceof(eTYPE_MONSTER);
if (entityPtr != NULL && ec == typeid(*entityPtr)) else if (ec == typeid(Zombie))
isAssignableFrom = true; isAssignableFrom = e->instanceof(eTYPE_ZOMBIE);
else if (e != NULL && ec == typeid(*(e.get())))
isAssignableFrom = true;
if (isAssignableFrom && e->bb->intersects(bb)) {
if (selector == NULL || selector->matches(e)) {
es.push_back(e);
}
} }
if (isAssignableFrom && e->bb->intersects(bb)) es.push_back(e);
// 4J - note needs to be equivalent to // 4J - note needs to be equivalent to
// baseClass.isAssignableFrom(e.getClass()) // baseClass.isAssignableFrom(e.getClass())
} }
@ -1736,10 +1799,13 @@ int LevelChunk::countEntities() {
bool LevelChunk::shouldSave(bool force) { bool LevelChunk::shouldSave(bool force) {
if (dontSave) return false; if (dontSave) return false;
if (force) { if (force) {
if (lastSaveHadEntities && level->getTime() != lastSaveTime) if ((lastSaveHadEntities && level->getGameTime() != lastSaveTime) ||
m_unsaved) {
return true; return true;
}
} else { } else {
if (lastSaveHadEntities && level->getTime() >= lastSaveTime + 20 * 30) if (lastSaveHadEntities &&
level->getGameTime() >= lastSaveTime + 20 * 30)
return true; return true;
} }
@ -1796,22 +1862,22 @@ int LevelChunk::getBlocksAndData(byteArray* data, int x0, int y0, int z0,
} }
/* /*
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
for (int z = z0; z < z1; z++) for (int z = z0; z < z1; z++)
{ {
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
>> 1; int len = (y1 - y0) / 2; System::arraycopy(blockLight->data, slot, data, 1; int len = (y1 - y0) / 2; System::arraycopy(blockLight->data, slot, data,
p, len); p += len; p, len); p += len;
} }
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
for (int z = z0; z < z1; z++) for (int z = z0; z < z1; z++)
{ {
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
>> 1; int len = (y1 - y0) / 2; System::arraycopy(skyLight->data, slot, data, p, 1; int len = (y1 - y0) / 2; System::arraycopy(skyLight->data, slot, data, p,
len); p += len; len); p += len;
} }
*/ */
return p; return p;
} }
@ -1890,13 +1956,13 @@ int LevelChunk::setBlocksAndData(byteArray data, int x0, int y0, int z0, int x1,
includeLighting ? NULL : tileUpdatedCallback, this, includeLighting ? NULL : tileUpdatedCallback, this,
Level::COMPRESSED_CHUNK_SECTION_HEIGHT); Level::COMPRESSED_CHUNK_SECTION_HEIGHT);
/* /*
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
for (int z = z0; z < z1; z++) for (int z = z0; z < z1; z++)
{ {
int slot = x << level->depthBitsPlusFour | z << level->depthBits | y0; int slot = x << level->depthBitsPlusFour | z << level->depthBits | y0;
int len = y1 - y0; int len = y1 - y0;
System::arraycopy(data, p, &blocks, slot, len); System::arraycopy(data, p, &blocks, slot, len);
p += len; p += len;
}*/ }*/
recalcHeightmapOnly(); recalcHeightmapOnly();
@ -1956,22 +2022,22 @@ for (int x = x0; x < x1; x++)
} }
/* /*
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
for (int z = z0; z < z1; z++) for (int z = z0; z < z1; z++)
{ {
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
>> 1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &blockLight->data, 1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &blockLight->data,
slot, len); p += len; slot, len); p += len;
} }
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
for (int z = z0; z < z1; z++) for (int z = z0; z < z1; z++)
{ {
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
>> 1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &skyLight->data, slot, 1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &skyLight->data,
len); p += len; slot, len); p += len;
} }
*/ */
for (AUTO_VAR(it, tileEntities.begin()); it != tileEntities.end(); ++it) { for (AUTO_VAR(it, tileEntities.begin()); it != tileEntities.end(); ++it) {
it->second->clearCache(); it->second->clearCache();
@ -1991,7 +2057,7 @@ len); p += len;
void LevelChunk::setCheckAllLight() { checkLightPosition = 0; } void LevelChunk::setCheckAllLight() { checkLightPosition = 0; }
Random* LevelChunk::getRandom(__int64 l) { Random* LevelChunk::getRandom(int64_t l) {
return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 + return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 +
z * z * 4392871l + z * 389711) ^ z * z * 4392871l + z * 389711) ^
l); l);
@ -2001,15 +2067,15 @@ bool LevelChunk::isEmpty() { return false; }
void LevelChunk::attemptCompression() { void LevelChunk::attemptCompression() {
// 4J - removed // 4J - removed
#if 0 #if 0
try { try {
ByteArrayOutputStream *baos = new ByteArrayOutputStream(); ByteArrayOutputStream *baos = new ByteArrayOutputStream();
GZIPOutputStream *gzos = new GZIPOutputStream(baos); GZIPOutputStream *gzos = new GZIPOutputStream(baos);
DataOutputStream *dos = new DataOutputStream(gzos); DataOutputStream *dos = new DataOutputStream(gzos);
dos.close(); dos.close();
System.out.println("Compressed size: " + baos.toByteArray().length); System.out.println("Compressed size: " + baos.toByteArray().length);
} catch (Exception e) { } catch (Exception e) {
} }
#endif #endif
} }
@ -2074,20 +2140,32 @@ bool LevelChunk::isYSpaceEmpty(int y1, int y2) {
return false; return false;
// 4J Unused // 4J Unused
/*if (y1 < 0) { /*if (y1 < 0) {
y1 = 0; y1 = 0;
} }
if (y2 >= Level.maxBuildHeight) { if (y2 >= Level.maxBuildHeight) {
y2 = Level.maxBuildHeight - 1; y2 = Level.maxBuildHeight - 1;
} }
for (int y = y1; y <= y2; y += 16) { for (int y = y1; y <= y2; y += 16) {
LevelChunkSection section = sections[y >> 4]; LevelChunkSection section = sections[y >> 4];
if (section != null && !section.isEmpty()) { if (section != null && !section.isEmpty()) {
return false; return false;
} }
} }
return true;*/ return true;*/
} }
// 4J Added
void LevelChunk::reloadBiomes() {
BiomeSource* biomeSource = level->dimension->biomeSource;
for (unsigned int x = 0; x < 16; ++x) {
for (unsigned int z = 0; z < 16; ++z) {
Biome* biome =
biomeSource->getBiome((this->x << 4) + x, (this->z << 4) + z);
biomes[(z << 4) | x] = (uint8_t)((biome->id) & 0xff);
}
}
}
Biome* LevelChunk::getBiome(int x, int z, BiomeSource* biomeSource) { Biome* LevelChunk::getBiome(int x, int z, BiomeSource* biomeSource) {
int value = biomes[((unsigned)z << 4) | x] & 0xff; int value = biomes[((unsigned)z << 4) | x] & 0xff;
if (value == 0xff) { if (value == 0xff) {
@ -2422,9 +2500,13 @@ int LevelChunk::getBlocksAllocatedSize(int* count0, int* count1, int* count2,
int LevelChunk::getHighestNonEmptyY() { int LevelChunk::getHighestNonEmptyY() {
int highestNonEmptyY = -1; int highestNonEmptyY = -1;
if (upperBlocks) if (upperBlocks) {
highestNonEmptyY = upperBlocks->getHighestNonEmptyY() + int upperNonEmpty = upperBlocks->getHighestNonEmptyY();
Level::COMPRESSED_CHUNK_SECTION_HEIGHT; if (upperNonEmpty >= 0) {
highestNonEmptyY =
upperNonEmpty + Level::COMPRESSED_CHUNK_SECTION_HEIGHT;
}
}
if (highestNonEmptyY < 0) if (highestNonEmptyY < 0)
highestNonEmptyY = lowerBlocks->getHighestNonEmptyY(); highestNonEmptyY = lowerBlocks->getHighestNonEmptyY();
if (highestNonEmptyY < 0) highestNonEmptyY = 0; if (highestNonEmptyY < 0) highestNonEmptyY = 0;
@ -2510,7 +2592,7 @@ byteArray LevelChunk::getReorderedBlocksAndData(int x0, int y0, int z0, int xs,
// //
// unsigned int offset = Level::CHUNK_TILE_COUNT; // unsigned int offset = Level::CHUNK_TILE_COUNT;
//// Don't bother reordering block data, block light or sky light as they //// Don't bother reordering block data, block light or sky light as they
///don't seem to make much difference /// don't seem to make much difference
// byteArray dataData = byteArray(rawBuffer.data+offset, // byteArray dataData = byteArray(rawBuffer.data+offset,
// Level::HALF_CHUNK_TILE_COUNT); lc->getDataData(dataData); offset += // Level::HALF_CHUNK_TILE_COUNT); lc->getDataData(dataData); offset +=
// Level::HALF_CHUNK_TILE_COUNT; byteArray blockLightData = // Level::HALF_CHUNK_TILE_COUNT; byteArray blockLightData =
@ -2564,7 +2646,7 @@ void LevelChunk::reorderBlocksAndDataToXZY(int y0, int xs, int ys, int zs,
// setBlocksAndData(*data, x0, y0, z0, x1, y1, z1, p); // setBlocksAndData(*data, x0, y0, z0, x1, y1, z1, p);
//// If it is a full chunk, we'll need to rearrange into the order the rest //// If it is a full chunk, we'll need to rearrange into the order the rest
///of the game expects /// of the game expects
// if( xs == 16 && ys == 128 && zs == 16 && ( ( x & 15 ) == 0 ) && ( y == 0 // if( xs == 16 && ys == 128 && zs == 16 && ( ( x & 15 ) == 0 ) && ( y == 0
// ) && ( ( z & 15 ) == 0 ) ) // ) && ( ( z & 15 ) == 0 ) )
//{ //{

View file

@ -4,6 +4,8 @@ class DataLayer;
class TileEntity; class TileEntity;
class Random; class Random;
class ChunkSource; class ChunkSource;
class EntitySelector;
#include "Storage/SparseLightStorage.h" #include "Storage/SparseLightStorage.h"
#include "Storage/CompressedTileStorage.h" #include "Storage/CompressedTileStorage.h"
#include "Storage/SparseDataStorage.h" #include "Storage/SparseDataStorage.h"
@ -167,9 +169,11 @@ public:
void stopSharingTilesAndData(); // 4J added void stopSharingTilesAndData(); // 4J added
virtual void reSyncLighting(); // 4J added virtual void reSyncLighting(); // 4J added
void startSharingTilesAndData(int forceMs = 0); // 4J added void startSharingTilesAndData(int forceMs = 0); // 4J added
__int64 lastUnsharedTime; // 4J added int64_t lastUnsharedTime; // 4J added
__int64 lastSaveTime; int64_t lastSaveTime;
bool seenByPlayer; bool seenByPlayer;
int lowestHeightmap;
int64_t inhabitedTime;
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
bool m_bUnloaded; bool m_bUnloaded;
@ -237,14 +241,17 @@ public:
virtual void removeTileEntity(int x, int y, int z); virtual void removeTileEntity(int x, int y, int z);
virtual void load(); virtual void load();
virtual void unload(bool unloadTileEntities); // 4J - added parameter virtual void unload(bool unloadTileEntities); // 4J - added parameter
virtual bool containsPlayer(); // 4J - added
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
virtual bool isUnloaded(); virtual bool isUnloaded();
#endif #endif
virtual void markUnsaved(); virtual void markUnsaved();
virtual void getEntities(std::shared_ptr<Entity> except, AABB* bb, virtual void getEntities(std::shared_ptr<Entity> except, AABB* bb,
std::vector<std::shared_ptr<Entity> >& es); std::vector<std::shared_ptr<Entity> >& es,
const EntitySelector* selector);
virtual void getEntitiesOfClass(const std::type_info& ec, AABB* bb, virtual void getEntitiesOfClass(const std::type_info& ec, AABB* bb,
std::vector<std::shared_ptr<Entity> >& es); std::vector<std::shared_ptr<Entity> >& es,
const EntitySelector* selector);
virtual int countEntities(); virtual int countEntities();
virtual bool shouldSave(bool force); virtual bool shouldSave(bool force);
virtual int getBlocksAndData( virtual int getBlocksAndData(
@ -260,7 +267,7 @@ public:
int p); // 4J added int p); // 4J added
virtual void setCheckAllLight(); virtual void setCheckAllLight();
virtual Random* getRandom(__int64 l); virtual Random* getRandom(int64_t l);
virtual bool isEmpty(); virtual bool isEmpty();
virtual void attemptCompression(); virtual void attemptCompression();
@ -285,6 +292,7 @@ public:
void tick(); // 4J - lighting change brought forward from 1.8.2 void tick(); // 4J - lighting change brought forward from 1.8.2
ChunkPos* getPos(); ChunkPos* getPos();
bool isYSpaceEmpty(int y1, int y2); bool isYSpaceEmpty(int y1, int y2);
void reloadBiomes(); // 4J added
virtual Biome* getBiome(int x, int z, BiomeSource* biomeSource); virtual Biome* getBiome(int x, int z, BiomeSource* biomeSource);
byteArray getBiomes(); byteArray getBiomes();
void setBiomes(byteArray biomes); void setBiomes(byteArray biomes);

View file

@ -24,6 +24,9 @@ LevelData::LevelData(CompoundTag* tag) {
m_pGenerator = m_pGenerator =
m_pGenerator->getReplacementForVersion(generatorVersion); m_pGenerator->getReplacementForVersion(generatorVersion);
} }
if (tag->contains(L"generatorOptions"))
generatorOptions = tag->getString(L"generatorOptions");
} }
gameType = GameType::byId(tag->getInt(L"GameType")); gameType = GameType::byId(tag->getInt(L"GameType"));
@ -37,7 +40,12 @@ LevelData::LevelData(CompoundTag* tag) {
xSpawn = tag->getInt(L"SpawnX"); xSpawn = tag->getInt(L"SpawnX");
ySpawn = tag->getInt(L"SpawnY"); ySpawn = tag->getInt(L"SpawnY");
zSpawn = tag->getInt(L"SpawnZ"); zSpawn = tag->getInt(L"SpawnZ");
time = tag->getLong(L"Time"); gameTime = tag->getLong(L"Time");
if (tag->contains(L"DayTime")) {
dayTime = tag->getLong(L"DayTime");
} else {
dayTime = gameTime;
}
lastPlayed = tag->getLong(L"LastPlayed"); lastPlayed = tag->getLong(L"LastPlayed");
sizeOnDisk = tag->getLong(L"SizeOnDisk"); sizeOnDisk = tag->getLong(L"SizeOnDisk");
levelName = tag->getString(L"LevelName"); levelName = tag->getString(L"LevelName");
@ -60,6 +68,12 @@ LevelData::LevelData(CompoundTag* tag) {
allowCommands = gameType == GameType::CREATIVE; allowCommands = gameType == GameType::CREATIVE;
} }
// 4J: Game rules are now stored with app game host options
/*if (tag->contains(L"GameRules"))
{
gameRules.loadFromTag(tag->getCompound(L"GameRules"));
}*/
newSeaLevel = tag->getBoolean( newSeaLevel = tag->getBoolean(
L"newSeaLevel"); // 4J added - only use new sea level for newly created L"newSeaLevel"); // 4J added - only use new sea level for newly created
// maps. This read defaults to false. (sea level // maps. This read defaults to false. (sea level
@ -95,6 +109,37 @@ LevelData::LevelData(CompoundTag* tag) {
m_xzSize = tag->getInt(L"XZSize"); m_xzSize = tag->getInt(L"XZSize");
m_hellScale = tag->getInt(L"HellScale"); m_hellScale = tag->getInt(L"HellScale");
#ifdef _LARGE_WORLDS
m_classicEdgeMoat = tag->getInt(L"ClassicMoat");
m_smallEdgeMoat = tag->getInt(L"SmallMoat");
m_mediumEdgeMoat = tag->getInt(L"MediumMoat");
int newWorldSize = app.GetGameNewWorldSize();
int newHellScale = app.GetGameNewHellScale();
m_hellScaleOld = m_hellScale;
m_xzSizeOld = m_xzSize;
if (newWorldSize > m_xzSize) {
bool bUseMoat = app.GetGameNewWorldSizeUseMoat();
switch (m_xzSize) {
case LEVEL_WIDTH_CLASSIC:
m_classicEdgeMoat = bUseMoat;
break;
case LEVEL_WIDTH_SMALL:
m_smallEdgeMoat = bUseMoat;
break;
case LEVEL_WIDTH_MEDIUM:
m_mediumEdgeMoat = bUseMoat;
break;
default:
assert(0);
break;
}
assert(newWorldSize > m_xzSize);
m_xzSize = newWorldSize;
m_hellScale = newHellScale;
}
#endif
m_xzSize = std::min(m_xzSize, LEVEL_MAX_WIDTH); m_xzSize = std::min(m_xzSize, LEVEL_MAX_WIDTH);
m_xzSize = std::max(m_xzSize, LEVEL_MIN_WIDTH); m_xzSize = std::max(m_xzSize, LEVEL_MIN_WIDTH);
@ -108,15 +153,38 @@ LevelData::LevelData(CompoundTag* tag) {
hellXZSize = m_xzSize / m_hellScale; hellXZSize = m_xzSize / m_hellScale;
} }
#ifdef _LARGE_WORLDS
// set the host option, in case it wasn't setup already
EGameHostOptionWorldSize hostOptionworldSize = e_worldSize_Unknown;
switch (m_xzSize) {
case LEVEL_WIDTH_CLASSIC:
hostOptionworldSize = e_worldSize_Classic;
break;
case LEVEL_WIDTH_SMALL:
hostOptionworldSize = e_worldSize_Small;
break;
case LEVEL_WIDTH_MEDIUM:
hostOptionworldSize = e_worldSize_Medium;
break;
case LEVEL_WIDTH_LARGE:
hostOptionworldSize = e_worldSize_Large;
break;
default:
assert(0);
break;
}
app.SetGameHostOption(eGameHostOption_WorldSize, hostOptionworldSize);
#endif
/* 4J - we don't store this anymore /* 4J - we don't store this anymore
if (tag->contains(L"Player")) if (tag->contains(L"Player"))
{ {
loadedPlayerTag = tag->getCompound(L"Player"); loadedPlayerTag = tag->getCompound(L"Player");
dimension = loadedPlayerTag->getInt(L"Dimension"); dimension = loadedPlayerTag->getInt(L"Dimension");
} }
else else
{ {
this->loadedPlayerTag = NULL; this->loadedPlayerTag = NULL;
} }
*/ */
dimension = 0; dimension = 0;
@ -124,46 +192,48 @@ if (tag->contains(L"Player"))
LevelData::LevelData(LevelSettings* levelSettings, LevelData::LevelData(LevelSettings* levelSettings,
const std::wstring& levelName) { const std::wstring& levelName) {
this->seed = levelSettings->getSeed(); seed = levelSettings->getSeed();
this->gameType = levelSettings->getGameType(); gameType = levelSettings->getGameType();
this->generateMapFeatures = levelSettings->isGenerateMapFeatures(); generateMapFeatures = levelSettings->isGenerateMapFeatures();
this->spawnBonusChest = levelSettings->hasStartingBonusItems(); spawnBonusChest = levelSettings->hasStartingBonusItems();
this->levelName = levelName; this->levelName = levelName;
this->m_pGenerator = levelSettings->getLevelType(); m_pGenerator = levelSettings->getLevelType();
this->hardcore = levelSettings->isHardcore(); hardcore = levelSettings->isHardcore();
generatorOptions = levelSettings->getLevelTypeOptions();
allowCommands = levelSettings->getAllowCommands();
// 4J Stu - Default initers // 4J Stu - Default initers
this->xSpawn = 0; xSpawn = 0;
this->ySpawn = 0; ySpawn = 0;
this->zSpawn = 0; zSpawn = 0;
this->time = -1; // 4J-JEV: Edited: To know when this is uninitialized. dayTime = -1; // 4J-JEV: Edited: To know when this is uninitialized.
this->lastPlayed = 0; gameTime = -1;
this->sizeOnDisk = 0; lastPlayed = 0;
sizeOnDisk = 0;
// this->loadedPlayerTag = NULL; // 4J - we don't store this anymore // this->loadedPlayerTag = NULL; // 4J - we don't store this anymore
this->dimension = 0; dimension = 0;
this->version = 0; version = 0;
this->rainTime = 0; rainTime = 0;
this->raining = false; raining = false;
this->thunderTime = 0; thunderTime = 0;
this->thundering = false; thundering = false;
this->allowCommands = levelSettings->getAllowCommands(); initialized = false;
this->initialized = false; newSeaLevel =
this->newSeaLevel =
levelSettings levelSettings
->useNewSeaLevel(); // 4J added - only use new sea level for newly ->useNewSeaLevel(); // 4J added - only use new sea level for newly
// created maps (sea level changes in 1.8.2) // created maps (sea level changes in 1.8.2)
this->hasBeenInCreative = hasBeenInCreative =
levelSettings->getGameType() == GameType::CREATIVE; // 4J added levelSettings->getGameType() == GameType::CREATIVE; // 4J added
// 4J-PB for the stronghold position // 4J-PB for the stronghold position
this->bStronghold = false; bStronghold = false;
this->xStronghold = 0; xStronghold = 0;
this->yStronghold = 0; yStronghold = 0;
this->zStronghold = 0; zStronghold = 0;
this->xStrongholdEndPortal = 0; xStrongholdEndPortal = 0;
this->zStrongholdEndPortal = 0; zStrongholdEndPortal = 0;
this->bStrongholdEndPortal = false; bStrongholdEndPortal = false;
m_xzSize = levelSettings->getXZSize(); m_xzSize = levelSettings->getXZSize();
m_hellScale = levelSettings->getHellScale(); m_hellScale = levelSettings->getHellScale();
@ -179,46 +249,63 @@ LevelData::LevelData(LevelSettings* levelSettings,
++m_hellScale; ++m_hellScale;
hellXZSize = m_xzSize / m_hellScale; hellXZSize = m_xzSize / m_hellScale;
} }
#ifdef _LARGE_WORLDS
m_hellScaleOld = m_hellScale;
m_xzSizeOld = m_xzSize;
m_classicEdgeMoat = false;
m_smallEdgeMoat = false;
m_mediumEdgeMoat = false;
#endif
} }
LevelData::LevelData(LevelData* copy) { LevelData::LevelData(LevelData* copy) {
this->seed = copy->seed; seed = copy->seed;
this->m_pGenerator = copy->m_pGenerator; m_pGenerator = copy->m_pGenerator;
this->gameType = copy->gameType; generatorOptions = copy->generatorOptions;
this->generateMapFeatures = copy->generateMapFeatures; gameType = copy->gameType;
this->spawnBonusChest = copy->spawnBonusChest; generateMapFeatures = copy->generateMapFeatures;
this->xSpawn = copy->xSpawn; spawnBonusChest = copy->spawnBonusChest;
this->ySpawn = copy->ySpawn; xSpawn = copy->xSpawn;
this->zSpawn = copy->zSpawn; ySpawn = copy->ySpawn;
this->time = copy->time; zSpawn = copy->zSpawn;
this->lastPlayed = copy->lastPlayed; gameTime = copy->gameTime;
this->sizeOnDisk = copy->sizeOnDisk; dayTime = copy->dayTime;
lastPlayed = copy->lastPlayed;
sizeOnDisk = copy->sizeOnDisk;
// this->loadedPlayerTag = copy->loadedPlayerTag; // 4J - // this->loadedPlayerTag = copy->loadedPlayerTag; // 4J -
// we don't store this anymore // we don't store this anymore
this->dimension = copy->dimension; dimension = copy->dimension;
this->levelName = copy->levelName; levelName = copy->levelName;
this->version = copy->version; version = copy->version;
this->rainTime = copy->rainTime; rainTime = copy->rainTime;
this->raining = copy->raining; raining = copy->raining;
this->thunderTime = copy->thunderTime; thunderTime = copy->thunderTime;
this->thundering = copy->thundering; thundering = copy->thundering;
this->hardcore = copy->hardcore; hardcore = copy->hardcore;
this->allowCommands = copy->allowCommands; allowCommands = copy->allowCommands;
this->initialized = copy->initialized; initialized = copy->initialized;
this->newSeaLevel = copy->newSeaLevel; newSeaLevel = copy->newSeaLevel;
this->hasBeenInCreative = copy->hasBeenInCreative; hasBeenInCreative = copy->hasBeenInCreative;
gameRules = copy->gameRules;
// 4J-PB for the stronghold position // 4J-PB for the stronghold position
this->bStronghold = copy->bStronghold; bStronghold = copy->bStronghold;
this->xStronghold = copy->xStronghold; xStronghold = copy->xStronghold;
this->yStronghold = copy->yStronghold; yStronghold = copy->yStronghold;
this->zStronghold = copy->zStronghold; zStronghold = copy->zStronghold;
this->xStrongholdEndPortal = copy->xStrongholdEndPortal; xStrongholdEndPortal = copy->xStrongholdEndPortal;
this->zStrongholdEndPortal = copy->zStrongholdEndPortal; zStrongholdEndPortal = copy->zStrongholdEndPortal;
this->bStrongholdEndPortal = copy->bStrongholdEndPortal; bStrongholdEndPortal = copy->bStrongholdEndPortal;
m_xzSize = copy->m_xzSize; m_xzSize = copy->m_xzSize;
m_hellScale = copy->m_hellScale; m_hellScale = copy->m_hellScale;
#ifdef _LARGE_WORLDS
m_classicEdgeMoat = copy->m_classicEdgeMoat;
m_smallEdgeMoat = copy->m_smallEdgeMoat;
m_mediumEdgeMoat = copy->m_mediumEdgeMoat;
m_xzSizeOld = copy->m_xzSizeOld;
m_hellScaleOld = copy->m_hellScaleOld;
#endif
} }
CompoundTag* LevelData::createTag() { CompoundTag* LevelData::createTag() {
@ -239,13 +326,15 @@ void LevelData::setTagData(CompoundTag* tag) {
tag->putLong(L"RandomSeed", seed); tag->putLong(L"RandomSeed", seed);
tag->putString(L"generatorName", m_pGenerator->getGeneratorName()); tag->putString(L"generatorName", m_pGenerator->getGeneratorName());
tag->putInt(L"generatorVersion", m_pGenerator->getVersion()); tag->putInt(L"generatorVersion", m_pGenerator->getVersion());
tag->putString(L"generatorOptions", generatorOptions);
tag->putInt(L"GameType", gameType->getId()); tag->putInt(L"GameType", gameType->getId());
tag->putBoolean(L"MapFeatures", generateMapFeatures); tag->putBoolean(L"MapFeatures", generateMapFeatures);
tag->putBoolean(L"spawnBonusChest", spawnBonusChest); tag->putBoolean(L"spawnBonusChest", spawnBonusChest);
tag->putInt(L"SpawnX", xSpawn); tag->putInt(L"SpawnX", xSpawn);
tag->putInt(L"SpawnY", ySpawn); tag->putInt(L"SpawnY", ySpawn);
tag->putInt(L"SpawnZ", zSpawn); tag->putInt(L"SpawnZ", zSpawn);
tag->putLong(L"Time", time); tag->putLong(L"Time", gameTime);
tag->putLong(L"DayTime", dayTime);
tag->putLong(L"SizeOnDisk", sizeOnDisk); tag->putLong(L"SizeOnDisk", sizeOnDisk);
tag->putLong(L"LastPlayed", System::currentTimeMillis()); tag->putLong(L"LastPlayed", System::currentTimeMillis());
tag->putString(L"LevelName", levelName); tag->putString(L"LevelName", levelName);
@ -257,6 +346,8 @@ void LevelData::setTagData(CompoundTag* tag) {
tag->putBoolean(L"hardcore", hardcore); tag->putBoolean(L"hardcore", hardcore);
tag->putBoolean(L"allowCommands", allowCommands); tag->putBoolean(L"allowCommands", allowCommands);
tag->putBoolean(L"initialized", initialized); tag->putBoolean(L"initialized", initialized);
// 4J: Game rules are now stored with app game host options
// tag->putCompound(L"GameRules", gameRules.createTag());
tag->putBoolean(L"newSeaLevel", newSeaLevel); tag->putBoolean(L"newSeaLevel", newSeaLevel);
tag->putBoolean(L"hasBeenInCreative", hasBeenInCreative); tag->putBoolean(L"hasBeenInCreative", hasBeenInCreative);
// store the stronghold position // store the stronghold position
@ -269,10 +360,16 @@ void LevelData::setTagData(CompoundTag* tag) {
tag->putInt(L"StrongholdEndPortalX", xStrongholdEndPortal); tag->putInt(L"StrongholdEndPortalX", xStrongholdEndPortal);
tag->putInt(L"StrongholdEndPortalZ", zStrongholdEndPortal); tag->putInt(L"StrongholdEndPortalZ", zStrongholdEndPortal);
tag->putInt(L"XZSize", m_xzSize); tag->putInt(L"XZSize", m_xzSize);
#ifdef _LARGE_WORLDS
tag->putInt(L"ClassicMoat", m_classicEdgeMoat);
tag->putInt(L"SmallMoat", m_smallEdgeMoat);
tag->putInt(L"MediumMoat", m_mediumEdgeMoat);
#endif
tag->putInt(L"HellScale", m_hellScale); tag->putInt(L"HellScale", m_hellScale);
} }
__int64 LevelData::getSeed() { return seed; } int64_t LevelData::getSeed() { return seed; }
int LevelData::getXSpawn() { return xSpawn; } int LevelData::getXSpawn() { return xSpawn; }
@ -288,9 +385,11 @@ int LevelData::getXStrongholdEndPortal() { return xStrongholdEndPortal; }
int LevelData::getZStrongholdEndPortal() { return zStrongholdEndPortal; } int LevelData::getZStrongholdEndPortal() { return zStrongholdEndPortal; }
__int64 LevelData::getTime() { return time; } int64_t LevelData::getGameTime() { return gameTime; }
__int64 LevelData::getSizeOnDisk() { return sizeOnDisk; } int64_t LevelData::getDayTime() { return dayTime; }
int64_t LevelData::getSizeOnDisk() { return sizeOnDisk; }
CompoundTag* LevelData::getLoadedPlayerTag() { CompoundTag* LevelData::getLoadedPlayerTag() {
return NULL; // 4J - we don't store this anymore return NULL; // 4J - we don't store this anymore
@ -302,7 +401,7 @@ CompoundTag* LevelData::getLoadedPlayerTag() {
// return dimension; // return dimension;
//} //}
void LevelData::setSeed(__int64 seed) { this->seed = seed; } void LevelData::setSeed(int64_t seed) { this->seed = seed; }
void LevelData::setXSpawn(int xSpawn) { this->xSpawn = xSpawn; } void LevelData::setXSpawn(int xSpawn) { this->xSpawn = xSpawn; }
@ -338,9 +437,11 @@ void LevelData::setZStrongholdEndPortal(int zStrongholdEndPortal) {
this->zStrongholdEndPortal = zStrongholdEndPortal; this->zStrongholdEndPortal = zStrongholdEndPortal;
} }
void LevelData::setTime(__int64 time) { this->time = time; } void LevelData::setGameTime(int64_t time) { gameTime = time; }
void LevelData::setSizeOnDisk(__int64 sizeOnDisk) { void LevelData::setDayTime(int64_t time) { dayTime = time; }
void LevelData::setSizeOnDisk(int64_t sizeOnDisk) {
this->sizeOnDisk = sizeOnDisk; this->sizeOnDisk = sizeOnDisk;
} }
@ -371,7 +472,7 @@ int LevelData::getVersion() { return version; }
void LevelData::setVersion(int version) { this->version = version; } void LevelData::setVersion(int version) { this->version = version; }
__int64 LevelData::getLastPlayed() { return lastPlayed; } int64_t LevelData::getLastPlayed() { return lastPlayed; }
bool LevelData::isThundering() { return thundering; } bool LevelData::isThundering() { return thundering; }
@ -405,7 +506,7 @@ void LevelData::setGameType(GameType* gameType) {
// 4J Added // 4J Added
hasBeenInCreative = hasBeenInCreative =
hasBeenInCreative || (gameType == GameType::CREATIVE) || hasBeenInCreative || (gameType == GameType::CREATIVE) ||
app.GetGameHostOption(eGameHostOption_CheatsEnabled) > 0; (app.GetGameHostOption(eGameHostOption_CheatsEnabled) > 0);
} }
bool LevelData::useNewSeaLevel() { return newSeaLevel; } bool LevelData::useNewSeaLevel() { return newSeaLevel; }
@ -418,6 +519,12 @@ LevelType* LevelData::getGenerator() { return m_pGenerator; }
void LevelData::setGenerator(LevelType* generator) { m_pGenerator = generator; } void LevelData::setGenerator(LevelType* generator) { m_pGenerator = generator; }
std::wstring LevelData::getGeneratorOptions() { return generatorOptions; }
void LevelData::setGeneratorOptions(const std::wstring& options) {
generatorOptions = options;
}
bool LevelData::isHardcore() { return hardcore; } bool LevelData::isHardcore() { return hardcore; }
bool LevelData::getAllowCommands() { return allowCommands; } bool LevelData::getAllowCommands() { return allowCommands; }
@ -432,6 +539,33 @@ void LevelData::setInitialized(bool initialized) {
this->initialized = initialized; this->initialized = initialized;
} }
GameRules* LevelData::getGameRules() { return &gameRules; }
int LevelData::getXZSize() { return m_xzSize; } int LevelData::getXZSize() { return m_xzSize; }
#ifdef _LARGE_WORLDS
int LevelData::getXZSizeOld() { return m_xzSizeOld; }
void LevelData::getMoatFlags(bool* bClassicEdgeMoat, bool* bSmallEdgeMoat,
bool* bMediumEdgeMoat) {
*bClassicEdgeMoat = m_classicEdgeMoat;
*bSmallEdgeMoat = m_smallEdgeMoat;
*bMediumEdgeMoat = m_mediumEdgeMoat;
}
int LevelData::getXZHellSizeOld() {
int hellXZSizeOld = ceil((float)m_xzSizeOld / m_hellScaleOld);
while (hellXZSizeOld > HELL_LEVEL_MAX_WIDTH &&
m_hellScaleOld < HELL_LEVEL_MAX_SCALE) {
assert(0); // should never get in here?
++m_hellScaleOld;
hellXZSizeOld = m_xzSize / m_hellScale;
}
return hellXZSizeOld;
}
#endif
int LevelData::getHellScale() { return m_hellScale; } int LevelData::getHellScale() { return m_hellScale; }

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "GameRules.h"
class Player; class Player;
class CompoundTag; class CompoundTag;
class LevelSettings; class LevelSettings;
@ -10,14 +12,16 @@ class LevelData {
friend class DerivedLevelData; friend class DerivedLevelData;
private: private:
__int64 seed; int64_t seed;
LevelType* m_pGenerator; // = LevelType.normal; LevelType* m_pGenerator; // = LevelType.normal;
std::wstring generatorOptions;
int xSpawn; int xSpawn;
int ySpawn; int ySpawn;
int zSpawn; int zSpawn;
__int64 time; int64_t gameTime;
__int64 lastPlayed; int64_t dayTime;
__int64 sizeOnDisk; int64_t lastPlayed;
int64_t sizeOnDisk;
// CompoundTag *loadedPlayerTag; // 4J removed // CompoundTag *loadedPlayerTag; // 4J removed
int dimension; int dimension;
std::wstring levelName; std::wstring levelName;
@ -37,7 +41,14 @@ private:
bool hasBeenInCreative; // 4J added bool hasBeenInCreative; // 4J added
bool spawnBonusChest; // 4J added bool spawnBonusChest; // 4J added
int m_xzSize; // 4J Added int m_xzSize; // 4J Added
int m_hellScale; // 4J Added #ifdef _LARGE_WORLDS
int m_xzSizeOld; // 4J MGH Added, for expanding worlds
int m_hellScaleOld;
bool m_classicEdgeMoat;
bool m_smallEdgeMoat;
bool m_mediumEdgeMoat;
#endif
int m_hellScale; // 4J Added
// 4J added // 4J added
int xStronghold; int xStronghold;
@ -49,6 +60,8 @@ private:
int zStrongholdEndPortal; int zStrongholdEndPortal;
bool bStrongholdEndPortal; bool bStrongholdEndPortal;
GameRules gameRules;
protected: protected:
LevelData(); LevelData();
@ -66,8 +79,7 @@ protected:
CompoundTag* tag); // 4J - removed CompoundTag *playerTag CompoundTag* tag); // 4J - removed CompoundTag *playerTag
public: public:
virtual ~LevelData() {} virtual int64_t getSeed();
virtual __int64 getSeed();
virtual int getXSpawn(); virtual int getXSpawn();
virtual int getYSpawn(); virtual int getYSpawn();
virtual int getZSpawn(); virtual int getZSpawn();
@ -75,11 +87,12 @@ public:
virtual int getZStronghold(); virtual int getZStronghold();
virtual int getXStrongholdEndPortal(); virtual int getXStrongholdEndPortal();
virtual int getZStrongholdEndPortal(); virtual int getZStrongholdEndPortal();
virtual __int64 getTime(); virtual int64_t getGameTime();
virtual __int64 getSizeOnDisk(); virtual int64_t getDayTime();
virtual int64_t getSizeOnDisk();
virtual CompoundTag* getLoadedPlayerTag(); virtual CompoundTag* getLoadedPlayerTag();
// int getDimension(); // 4J Removed TU 9 as it's never accurate // int getDimension(); // 4J Removed TU 9 as it's never accurate
virtual void setSeed(__int64 seed); virtual void setSeed(int64_t seed);
virtual void setXSpawn(int xSpawn); virtual void setXSpawn(int xSpawn);
virtual void setYSpawn(int ySpawn); virtual void setYSpawn(int ySpawn);
virtual void setZSpawn(int zSpawn); virtual void setZSpawn(int zSpawn);
@ -92,8 +105,9 @@ public:
virtual void setXStrongholdEndPortal(int xStrongholdEndPortal); virtual void setXStrongholdEndPortal(int xStrongholdEndPortal);
virtual void setZStrongholdEndPortal(int zStrongholdEndPortal); virtual void setZStrongholdEndPortal(int zStrongholdEndPortal);
virtual void setTime(__int64 time); virtual void setGameTime(int64_t time);
virtual void setSizeOnDisk(__int64 sizeOnDisk); virtual void setDayTime(int64_t time);
virtual void setSizeOnDisk(int64_t sizeOnDisk);
virtual void setLoadedPlayerTag(CompoundTag* loadedPlayerTag); virtual void setLoadedPlayerTag(CompoundTag* loadedPlayerTag);
// void setDimension(int dimension); // 4J Removed TU 9 as it's never used // void setDimension(int dimension); // 4J Removed TU 9 as it's never used
virtual void setSpawn(int xSpawn, int ySpawn, int zSpawn); virtual void setSpawn(int xSpawn, int ySpawn, int zSpawn);
@ -101,7 +115,7 @@ public:
virtual void setLevelName(const std::wstring& levelName); virtual void setLevelName(const std::wstring& levelName);
virtual int getVersion(); virtual int getVersion();
virtual void setVersion(int version); virtual void setVersion(int version);
virtual __int64 getLastPlayed(); virtual int64_t getLastPlayed();
virtual bool isThundering(); virtual bool isThundering();
virtual void setThundering(bool thundering); virtual void setThundering(bool thundering);
virtual int getThunderTime(); virtual int getThunderTime();
@ -119,11 +133,21 @@ public:
virtual void setHasBeenInCreative(bool value); // 4J Added virtual void setHasBeenInCreative(bool value); // 4J Added
virtual LevelType* getGenerator(); virtual LevelType* getGenerator();
virtual void setGenerator(LevelType* generator); virtual void setGenerator(LevelType* generator);
virtual std::wstring getGeneratorOptions();
virtual void setGeneratorOptions(const std::wstring& options);
virtual bool isHardcore(); virtual bool isHardcore();
virtual bool getAllowCommands(); virtual bool getAllowCommands();
virtual void setAllowCommands(bool allowCommands); virtual void setAllowCommands(bool allowCommands);
virtual bool isInitialized(); virtual bool isInitialized();
virtual void setInitialized(bool initialized); virtual void setInitialized(bool initialized);
virtual int getXZSize(); // 4J Added virtual GameRules* getGameRules();
virtual int getXZSize(); // 4J Added
#ifdef _LARGE_WORLDS
virtual int getXZSizeOld(); // 4J Added
virtual void getMoatFlags(bool* bClassicEdgeMoat, bool* bSmallEdgeMoat,
bool* bMediumEdgeMoat); // 4J MGH - added
virtual int getXZHellSizeOld(); // 4J Added
#endif
virtual int getHellScale(); // 4J Addded virtual int getHellScale(); // 4J Addded
}; };

View file

@ -7,6 +7,7 @@
#include "../Headers/net.minecraft.world.level.levelgen.synth.h" #include "../Headers/net.minecraft.world.level.levelgen.synth.h"
#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.level.storage.h" #include "../Headers/net.minecraft.world.level.storage.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "RandomLevelSource.h" #include "RandomLevelSource.h"
#ifdef __PS3__ #ifdef __PS3__
@ -17,19 +18,24 @@ static PerlinNoise_DataIn g_lperlinNoise2_SPU __attribute__((__aligned__(16)));
static PerlinNoise_DataIn g_perlinNoise1_SPU __attribute__((__aligned__(16))); static PerlinNoise_DataIn g_perlinNoise1_SPU __attribute__((__aligned__(16)));
static PerlinNoise_DataIn g_scaleNoise_SPU __attribute__((__aligned__(16))); static PerlinNoise_DataIn g_scaleNoise_SPU __attribute__((__aligned__(16)));
static PerlinNoise_DataIn g_depthNoise_SPU __attribute__((__aligned__(16))); static PerlinNoise_DataIn g_depthNoise_SPU __attribute__((__aligned__(16)));
// #define DISABLE_SPU_CODE
#endif #endif
const double RandomLevelSource::SNOW_SCALE = 0.3; const double RandomLevelSource::SNOW_SCALE = 0.3;
const double RandomLevelSource::SNOW_CUTOFF = 0.5; const double RandomLevelSource::SNOW_CUTOFF = 0.5;
RandomLevelSource::RandomLevelSource(Level* level, __int64 seed, RandomLevelSource::RandomLevelSource(Level* level, int64_t seed,
bool generateStructures) bool generateStructures)
: generateStructures(generateStructures) { : generateStructures(generateStructures) {
m_XZSize = level->getLevelData()->getXZSize(); m_XZSize = level->getLevelData()->getXZSize();
#ifdef _LARGE_WORLDS
level->getLevelData()->getMoatFlags(&m_classicEdgeMoat, &m_smallEdgeMoat,
&m_mediumEdgeMoat);
#endif
caveFeature = new LargeCaveFeature(); caveFeature = new LargeCaveFeature();
strongholdFeature = new StrongholdFeature(); strongholdFeature = new StrongholdFeature();
villageFeature = new VillageFeature(0, m_XZSize); villageFeature = new VillageFeature(m_XZSize);
mineShaftFeature = new MineShaftFeature(); mineShaftFeature = new MineShaftFeature();
scatteredFeature = new RandomScatteredLargeFeature(); scatteredFeature = new RandomScatteredLargeFeature();
canyonFeature = new CanyonFeature(); canyonFeature = new CanyonFeature();
@ -67,6 +73,8 @@ RandomLevelSource::~RandomLevelSource() {
delete scatteredFeature; delete scatteredFeature;
delete canyonFeature; delete canyonFeature;
this->level = level;
delete random; delete random;
; ;
delete lperlinNoise1; delete lperlinNoise1;
@ -91,6 +99,140 @@ int g_numPrepareHeightCalls = 0;
LARGE_INTEGER g_totalPrepareHeightsTime = {0, 0}; LARGE_INTEGER g_totalPrepareHeightsTime = {0, 0};
LARGE_INTEGER g_averagePrepareHeightsTime = {0, 0}; LARGE_INTEGER g_averagePrepareHeightsTime = {0, 0};
#ifdef _LARGE_WORLDS
int RandomLevelSource::getMinDistanceToEdge(int xxx, int zzz, int worldSize,
float falloffStart) {
// Get distance to edges of world in x
// we have to do a proper line dist check here
int min = -worldSize / 2;
int max = (worldSize / 2) - 1;
// // only check if either x or z values are within the falloff
// if(xxx > (min - falloffStart)
Vec3* topLeft = Vec3::newTemp(min, 0, min);
Vec3* topRight = Vec3::newTemp(max, 0, min);
Vec3* bottomLeft = Vec3::newTemp(min, 0, max);
Vec3* bottomRight = Vec3::newTemp(max, 0, max);
float closest = falloffStart;
float dist;
// make sure we're in range of the edges before we do a full distance check
if ((xxx > (min - falloffStart) && xxx < (min + falloffStart)) ||
(xxx > (max - falloffStart) && xxx < (max + falloffStart))) {
Vec3* point = Vec3::newTemp(xxx, 0, zzz);
if (xxx > 0)
dist = point->distanceFromLine(topRight, bottomRight);
else
dist = point->distanceFromLine(topLeft, bottomLeft);
closest = dist;
}
// make sure we're in range of the edges before we do a full distance check
if ((zzz > (min - falloffStart) && zzz < (min + falloffStart)) ||
(zzz > (max - falloffStart) && zzz < (max + falloffStart))) {
Vec3* point = Vec3::newTemp(xxx, 0, zzz);
if (zzz > 0)
dist = point->distanceFromLine(bottomLeft, bottomRight);
else
dist = point->distanceFromLine(topLeft, topRight);
if (dist < closest) closest = dist;
}
return closest;
}
float RandomLevelSource::getHeightFalloff(int xxx, int zzz, int* pEMin) {
///////////////////////////////////////////////////////////////////
// 4J - add this chunk of code to make land "fall-off" at the edges of
// a finite world - size of that world is currently hard-coded in here
const int worldSize = m_XZSize * 16;
const int falloffStart =
32; // chunks away from edge were we start doing fall-off
const float falloffMax =
128.0f; // max value we need to get to falloff by the edge of the map
float comp = 0.0f;
int emin = getMinDistanceToEdge(xxx, zzz, worldSize, falloffStart);
// check if we have a larger world that should have moats
int expandedWorldSizes[3] = {LEVEL_WIDTH_CLASSIC * 16,
LEVEL_WIDTH_SMALL * 16,
LEVEL_WIDTH_MEDIUM * 16};
bool expandedMoatValues[3] = {m_classicEdgeMoat, m_smallEdgeMoat,
m_mediumEdgeMoat};
for (int i = 0; i < 3; i++) {
if (expandedMoatValues[i] && (worldSize > expandedWorldSizes[i])) {
// this world has been expanded, with moat settings, so we need
// fallofs at this edges too
int eminMoat = getMinDistanceToEdge(xxx, zzz, expandedWorldSizes[i],
falloffStart);
if (eminMoat < emin) {
emin = eminMoat;
}
}
}
// Calculate how much we want the world to fall away, if we're in the
// defined region to do so
if (emin < falloffStart) {
int falloff = falloffStart - emin;
comp = ((float)falloff / (float)falloffStart) * falloffMax;
}
*pEMin = emin;
return comp;
// 4J - end of extra code
///////////////////////////////////////////////////////////////////
}
#else
// MGH - go back to using the simpler version for PS3/vita/360, as it was
// causing a lot of slow down on the tuturial generation
float RandomLevelSource::getHeightFalloff(int xxx, int zzz, int* pEMin) {
///////////////////////////////////////////////////////////////////
// 4J - add this chunk of code to make land "fall-off" at the edges of
// a finite world - size of that world is currently hard-coded in here
const int worldSize = m_XZSize * 16;
const int falloffStart =
32; // chunks away from edge were we start doing fall-off
const float falloffMax =
128.0f; // max value we need to get to falloff by the edge of the map
// Get distance to edges of world in x
int xxx0 = xxx + (worldSize / 2);
if (xxx0 < 0) xxx0 = 0;
int xxx1 = ((worldSize / 2) - 1) - xxx;
if (xxx1 < 0) xxx1 = 0;
// Get distance to edges of world in z
int zzz0 = zzz + (worldSize / 2);
if (zzz0 < 0) zzz0 = 0;
int zzz1 = ((worldSize / 2) - 1) - zzz;
if (zzz1 < 0) zzz1 = 0;
// Get min distance to any edge
int emin = xxx0;
if (xxx1 < emin) emin = xxx1;
if (zzz0 < emin) emin = zzz0;
if (zzz1 < emin) emin = zzz1;
float comp = 0.0f;
// Calculate how much we want the world to fall away, if we're in the
// defined region to do so
if (emin < falloffStart) {
int falloff = falloffStart - emin;
comp = ((float)falloff / (float)falloffStart) * falloffMax;
}
// 4J - end of extra code
///////////////////////////////////////////////////////////////////
*pEMin = emin;
return comp;
}
#endif // _LARGE_WORLDS
void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) { void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
LARGE_INTEGER startTime; LARGE_INTEGER startTime;
int xChunks = 16 / CHUNK_WIDTH; int xChunks = 16 / CHUNK_WIDTH;
@ -166,50 +308,19 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
double vala = (_s1 - _s0) * zStep; double vala = (_s1 - _s0) * zStep;
val -= vala; val -= vala;
for (int z = 0; z < CHUNK_WIDTH; z++) { for (int z = 0; z < CHUNK_WIDTH; z++) {
/////////////////////////////////////////////////////////////////// // 4J Stu - I have removed all uses of the new
// 4J - add this chunk of code to make land // getHeightFalloff function for now as we had some
// "fall-off" at the edges of a finite world - size // problems with PS3/PSVita world generation I have
// of that world is currently hard-coded in here // fixed the non large worlds method, however we
const int worldSize = m_XZSize * 16; // will be happier if the current builds go out with
const int falloffStart = // completely old code We can put the new code back
32; // chunks away from edge were we start // in mid-november 2014 once those PS3/Vita builds
// doing fall-off // are gone (and the PS4 doesn't have world
const float falloffMax = // enlarging in these either anyway)
128.0f; // max value we need to get to falloff
// by the edge of the map
int xxx = ((xOffs * 16) + x + (xc * CHUNK_WIDTH)); int xxx = ((xOffs * 16) + x + (xc * CHUNK_WIDTH));
int zzz = ((zOffs * 16) + z + (zc * CHUNK_WIDTH)); int zzz = ((zOffs * 16) + z + (zc * CHUNK_WIDTH));
int emin;
// Get distance to edges of world in x float comp = getHeightFalloff(xxx, zzz, &emin);
int xxx0 = xxx + (worldSize / 2);
if (xxx0 < 0) xxx0 = 0;
int xxx1 = ((worldSize / 2) - 1) - xxx;
if (xxx1 < 0) xxx1 = 0;
// Get distance to edges of world in z
int zzz0 = zzz + (worldSize / 2);
if (zzz0 < 0) zzz0 = 0;
int zzz1 = ((worldSize / 2) - 1) - zzz;
if (zzz1 < 0) zzz1 = 0;
// Get min distance to any edge
int emin = xxx0;
if (xxx1 < emin) emin = xxx1;
if (zzz0 < emin) emin = zzz0;
if (zzz1 < emin) emin = zzz1;
float comp = 0.0f;
// Calculate how much we want the world to fall
// away, if we're in the defined region to do so
if (emin < falloffStart) {
int falloff = falloffStart - emin;
comp = ((float)falloff / (float)falloffStart) *
falloffMax;
}
// 4J - end of extra code
///////////////////////////////////////////////////////////////////
// 4J - slightly rearranged this code (as of // 4J - slightly rearranged this code (as of
// java 1.0.1 merge) to better fit with changes // java 1.0.1 merge) to better fit with changes
@ -220,7 +331,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
// 4J - this comparison used to just be with 0.0f // 4J - this comparison used to just be with 0.0f
// but is now varied by block above // but is now varied by block above
if ((val += vala) > comp) { if ((val += vala) > comp) {
tileId = (uint8_t)Tile::rock_Id; tileId = (uint8_t)Tile::stone_Id;
} else if (yc * CHUNK_HEIGHT + y < waterHeight) { } else if (yc * CHUNK_HEIGHT + y < waterHeight) {
tileId = (uint8_t)Tile::calmWater_Id; tileId = (uint8_t)Tile::calmWater_Id;
} }
@ -236,7 +347,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
// the edge of the world // the edge of the world
if (yc * CHUNK_HEIGHT + y <= if (yc * CHUNK_HEIGHT + y <=
(level->getSeaLevel() - 10)) (level->getSeaLevel() - 10))
tileId = Tile::rock_Id; tileId = Tile::stone_Id;
else if (yc * CHUNK_HEIGHT + y < else if (yc * CHUNK_HEIGHT + y <
level->getSeaLevel()) level->getSeaLevel())
tileId = Tile::calmWater_Id; tileId = Tile::calmWater_Id;
@ -305,7 +416,8 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
if (y <= 1 + random->nextInt( if (y <= 1 + random->nextInt(
2)) // 4J - changed to make the bedrock not 2)) // 4J - changed to make the bedrock not
// have bits you can get stuck in // have bits you can get stuck in
// if (y <= 0 + random->nextInt(5)) // if (y <= 0 +
// random->nextInt(5))
{ {
blocks[offs] = (uint8_t)Tile::unbreakable_Id; blocks[offs] = (uint8_t)Tile::unbreakable_Id;
} else { } else {
@ -313,11 +425,11 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
if (old == 0) { if (old == 0) {
run = -1; run = -1;
} else if (old == Tile::rock_Id) { } else if (old == Tile::stone_Id) {
if (run == -1) { if (run == -1) {
if (runDepth <= 0) { if (runDepth <= 0) {
top = 0; top = 0;
material = (uint8_t)Tile::rock_Id; material = (uint8_t)Tile::stone_Id;
} else if (y >= waterHeight - 4 && } else if (y >= waterHeight - 4 &&
y <= waterHeight + 1) { y <= waterHeight + 1) {
top = b->topMaterial; top = b->topMaterial;
@ -343,8 +455,7 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
run--; run--;
blocks[offs] = material; blocks[offs] = material;
// place a few sandstone blocks beneath sand // place a few sandstone blocks beneath sand runs
// runs
if (run == 0 && material == Tile::sand_Id) { if (run == 0 && material == Tile::sand_Id) {
run = random->nextInt(4); run = random->nextInt(4);
material = (uint8_t)Tile::sandStone_Id; material = (uint8_t)Tile::sandStone_Id;
@ -636,18 +747,19 @@ void RandomLevelSource::calcWaterDepths(ChunkSource* parent, int xt, int zt) {
level->getData(xp + x2, y, zp + z2); level->getData(xp + x2, y, zp + z2);
if (od < 7 && od < d) { if (od < 7 && od < d) {
level->setData(xp + x2, y, zp + z2, level->setData(xp + x2, y, zp + z2,
d); d, Tile::UPDATE_ALL);
} }
} }
} }
} }
} }
if (hadWater) { if (hadWater) {
level->setTileAndDataNoUpdate( level->setTileAndData(xp, y, zp, Tile::calmWater_Id,
xp, y, zp, Tile::calmWater_Id, 7); 7, Tile::UPDATE_CLIENTS);
for (int y2 = 0; y2 < y; y2++) { for (int y2 = 0; y2 < y; y2++) {
level->setTileAndDataNoUpdate( level->setTileAndData(xp, y2, zp,
xp, y2, zp, Tile::calmWater_Id, 8); Tile::calmWater_Id, 8,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -666,7 +778,7 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
Biome* biome = level->getBiome(xo + 16, zo + 16); Biome* biome = level->getBiome(xo + 16, zo + 16);
if (RandomLevelSource::FLOATING_ISLANDS) { if (FLOATING_ISLANDS) {
calcWaterDepths(parent, xt, zt); calcWaterDepths(parent, xt, zt);
} }
@ -690,14 +802,15 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
PIXEndNamedEvent(); PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Lakes"); PIXBeginNamedEvent(0, "Lakes");
if (!hasVillage && pprandom->nextInt(4) == 0) { if (biome != Biome::desert && biome != Biome::desertHills) {
int x = xo + pprandom->nextInt(16) + 8; if (!hasVillage && pprandom->nextInt(4) == 0) {
int y = pprandom->nextInt(Level::genDepth); int x = xo + pprandom->nextInt(16) + 8;
int z = zo + pprandom->nextInt(16) + 8; int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8;
LakeFeature* calmWater = new LakeFeature(Tile::calmWater_Id); LakeFeature calmWater(Tile::calmWater_Id);
calmWater->place(level, pprandom, x, y, z); calmWater.place(level, pprandom, x, y, z);
delete calmWater; }
} }
PIXEndNamedEvent(); PIXEndNamedEvent();
@ -707,9 +820,8 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int y = pprandom->nextInt(pprandom->nextInt(Level::genDepth - 8) + 8); int y = pprandom->nextInt(pprandom->nextInt(Level::genDepth - 8) + 8);
int z = zo + pprandom->nextInt(16) + 8; int z = zo + pprandom->nextInt(16) + 8;
if (y < level->seaLevel || pprandom->nextInt(10) == 0) { if (y < level->seaLevel || pprandom->nextInt(10) == 0) {
LakeFeature* calmLava = new LakeFeature(Tile::calmLava_Id); LakeFeature calmLava(Tile::calmLava_Id);
calmLava->place(level, pprandom, x, y, z); calmLava.place(level, pprandom, x, y, z);
delete calmLava;
} }
} }
PIXEndNamedEvent(); PIXEndNamedEvent();
@ -719,10 +831,8 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int x = xo + pprandom->nextInt(16) + 8; int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth); int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8; int z = zo + pprandom->nextInt(16) + 8;
MonsterRoomFeature* mrf = new MonsterRoomFeature(); MonsterRoomFeature mrf;
if (mrf->place(level, pprandom, x, y, z)) { mrf.place(level, pprandom, x, y, z);
}
delete mrf;
} }
PIXEndNamedEvent(); PIXEndNamedEvent();
@ -730,11 +840,16 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
biome->decorate(level, pprandom, xo, zo); biome->decorate(level, pprandom, xo, zo);
PIXEndNamedEvent(); PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Process Schematics");
app.processSchematics(parent->getChunk(xt, zt)); app.processSchematics(parent->getChunk(xt, zt));
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Post process mobs");
MobSpawner::postProcessSpawnMobs(level, biome, xo + 8, zo + 8, 16, 16, MobSpawner::postProcessSpawnMobs(level, biome, xo + 8, zo + 8, 16, 16,
pprandom); pprandom);
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Update ice and snow");
// 4J - brought forward from 1.2.3 to get snow back in taiga biomes // 4J - brought forward from 1.2.3 to get snow back in taiga biomes
xo += 8; xo += 8;
zo += 8; zo += 8;
@ -743,17 +858,16 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int y = level->getTopRainBlock(xo + x, zo + z); int y = level->getTopRainBlock(xo + x, zo + z);
if (level->shouldFreezeIgnoreNeighbors(x + xo, y - 1, z + zo)) { if (level->shouldFreezeIgnoreNeighbors(x + xo, y - 1, z + zo)) {
level->setTileNoUpdate( level->setTileAndData(x + xo, y - 1, z + zo, Tile::ice_Id, 0,
x + xo, y - 1, z + zo, Tile::UPDATE_CLIENTS);
Tile::ice_Id); // 4J - changed from setTile, otherwise we
// end up creating a *lot* of dynamic water
// tiles as these ice tiles are set
} }
if (level->shouldSnow(x + xo, y, z + zo)) { if (level->shouldSnow(x + xo, y, z + zo)) {
level->setTile(x + xo, y, z + zo, Tile::topSnow_Id); level->setTileAndData(x + xo, y, z + zo, Tile::topSnow_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
PIXEndNamedEvent();
HeavyTile::instaFall = false; HeavyTile::instaFall = false;
} }
@ -774,6 +888,10 @@ std::vector<Biome::MobSpawnerData*>* RandomLevelSource::getMobsAt(
if (biome == NULL) { if (biome == NULL) {
return NULL; return NULL;
} }
if (mobCategory == MobCategory::monster &&
scatteredFeature->isSwamphut(x, y, z)) {
return scatteredFeature->getSwamphutEnemies();
}
return biome->getMobs(mobCategory); return biome->getMobs(mobCategory);
} }
@ -784,3 +902,13 @@ TilePos* RandomLevelSource::findNearestMapFeature(
} }
return NULL; return NULL;
} }
void RandomLevelSource::recreateLogicStructuresForChunk(int chunkX,
int chunkZ) {
if (generateStructures) {
mineShaftFeature->apply(this, level, chunkX, chunkZ, NULL);
villageFeature->apply(this, level, chunkX, chunkZ, NULL);
strongholdFeature->apply(this, level, chunkX, chunkZ, NULL);
scatteredFeature->apply(this, level, chunkX, chunkZ, NULL);
}
}

View file

@ -45,10 +45,16 @@ private:
floatArray pows; floatArray pows;
public: public:
RandomLevelSource(Level* level, __int64 seed, bool generateStructures); RandomLevelSource(Level* level, int64_t seed, bool generateStructures);
~RandomLevelSource(); ~RandomLevelSource();
public: public:
#ifdef _LARGE_WORLDS
int getMinDistanceToEdge(int xxx, int zzz, int worldSize,
float falloffStart);
#endif
float getHeightFalloff(int xxx, int zzz, int* pEMin);
void prepareHeights(int xOffs, int zOffs, byteArray blocks); void prepareHeights(int xOffs, int zOffs, byteArray blocks);
public: public:
@ -93,4 +99,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z); int x, int y, int z);
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
}; };

View file

@ -0,0 +1,8 @@
#include "../Platform/stdafx.h"
#include "Redstone.h"
// 4J-JEV: Because whiny Ps4 compiler.
const int Redstone::SIGNAL_NONE;
const int Redstone::SIGNAL_MIN;
const int Redstone::SIGNAL_MAX;

View file

@ -0,0 +1,8 @@
#pragma once
class Redstone {
public:
static const int SIGNAL_NONE = 0;
static const int SIGNAL_MIN = 0;
static const int SIGNAL_MAX = 15;
};

View file

@ -13,7 +13,7 @@ ChunkStorageProfilerDecorator::ChunkStorageProfilerDecorator(
} }
LevelChunk* ChunkStorageProfilerDecorator::load(Level* level, int x, int z) { LevelChunk* ChunkStorageProfilerDecorator::load(Level* level, int x, int z) {
__int64 nanoTime = System::nanoTime(); int64_t nanoTime = System::nanoTime();
LevelChunk* chunk = capsulated->load(level, x, z); LevelChunk* chunk = capsulated->load(level, x, z);
timeSpentLoading += System::nanoTime() - nanoTime; timeSpentLoading += System::nanoTime() - nanoTime;
loadCount++; loadCount++;
@ -22,7 +22,7 @@ LevelChunk* ChunkStorageProfilerDecorator::load(Level* level, int x, int z) {
} }
void ChunkStorageProfilerDecorator::save(Level* level, LevelChunk* levelChunk) { void ChunkStorageProfilerDecorator::save(Level* level, LevelChunk* levelChunk) {
__int64 nanoTime = System::nanoTime(); int64_t nanoTime = System::nanoTime();
capsulated->save(level, levelChunk); capsulated->save(level, levelChunk);
timeSpentSaving += System::nanoTime() - nanoTime; timeSpentSaving += System::nanoTime() - nanoTime;
saveCount++; saveCount++;

View file

@ -7,10 +7,10 @@ class ChunkStorageProfilerDecorator : public ChunkStorage {
private: private:
ChunkStorage* capsulated; ChunkStorage* capsulated;
__int64 timeSpentLoading; int64_t timeSpentLoading;
__int64 loadCount; int64_t loadCount;
__int64 timeSpentSaving; int64_t timeSpentSaving;
__int64 saveCount; int64_t saveCount;
int counter; int counter;

View file

@ -12,6 +12,7 @@ static const int sc_maxCompressTiles = 64;
static CompressedTileStorage_compress_dataIn static CompressedTileStorage_compress_dataIn
g_compressTileDataIn[sc_maxCompressTiles] __attribute__((__aligned__(16))); g_compressTileDataIn[sc_maxCompressTiles] __attribute__((__aligned__(16)));
static int g_currentCompressTiles = 0; static int g_currentCompressTiles = 0;
// #define DISABLE_SPU_CODE
#endif //__PS3__ #endif //__PS3__
// Note: See header for an overview of this class // Note: See header for an overview of this class
@ -150,7 +151,7 @@ bool CompressedTileStorage::isRenderChunkEmpty(
for (int x = 0; x < 16; x += 4) for (int x = 0; x < 16; x += 4)
for (int z = 0; z < 16; z += 4) { for (int z = 0; z < 16; z += 4) {
getBlock(&block, x, y, z); getBlock(&block, x, y, z);
__uint64* comp = (__uint64*)&blockIndices[block]; uint64_t* comp = (uint64_t*)&blockIndices[block];
// Are the 4 y regions stored here all zero? (INDEX_TYPE_0_OR_8_BIT // Are the 4 y regions stored here all zero? (INDEX_TYPE_0_OR_8_BIT
// | INDEX_TYPE_0_BIT_FLAG ) // | INDEX_TYPE_0_BIT_FLAG )
if ((*comp) != 0x0007000700070007L) return false; if ((*comp) != 0x0007000700070007L) return false;
@ -168,17 +169,17 @@ bool CompressedTileStorage::isSameAs(CompressedTileStorage* other) {
// Attempt to compare as much as we can in 64-byte chunks (8 groups of 8 // Attempt to compare as much as we can in 64-byte chunks (8 groups of 8
// bytes) // bytes)
int quickCount = allocatedSize / 64; int quickCount = allocatedSize / 64;
__int64* pOld = (__int64*)indicesAndData; int64_t* pOld = (int64_t*)indicesAndData;
__int64* pNew = (__int64*)other->indicesAndData; int64_t* pNew = (int64_t*)other->indicesAndData;
for (int i = 0; i < quickCount; i++) { for (int i = 0; i < quickCount; i++) {
__int64 d0 = pOld[0] ^ pNew[0]; int64_t d0 = pOld[0] ^ pNew[0];
__int64 d1 = pOld[1] ^ pNew[1]; int64_t d1 = pOld[1] ^ pNew[1];
__int64 d2 = pOld[2] ^ pNew[2]; int64_t d2 = pOld[2] ^ pNew[2];
__int64 d3 = pOld[3] ^ pNew[3]; int64_t d3 = pOld[3] ^ pNew[3];
__int64 d4 = pOld[4] ^ pNew[4]; int64_t d4 = pOld[4] ^ pNew[4];
__int64 d5 = pOld[5] ^ pNew[5]; int64_t d5 = pOld[5] ^ pNew[5];
__int64 d6 = pOld[6] ^ pNew[6]; int64_t d6 = pOld[6] ^ pNew[6];
__int64 d7 = pOld[7] ^ pNew[7]; int64_t d7 = pOld[7] ^ pNew[7];
d0 |= d1; d0 |= d1;
d2 |= d3; d2 |= d3;
d4 |= d5; d4 |= d5;
@ -292,7 +293,7 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
int offsets[512]; int offsets[512];
int memToAlloc = 0; int memToAlloc = 0;
// static int type0 = 0, type1 = 0, type2 = 0, type4 = 0, type8 = 0, // static int type0 = 0, type1 = 0, type2 = 0, type4 = 0, type8 = 0,
//chunkTotal = 0; // chunkTotal = 0;
// Loop round all blocks // Loop round all blocks
for (int i = 0; i < 512; i++) { for (int i = 0; i < 512; i++) {
@ -327,8 +328,8 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
} }
} }
#else #else
__uint64 usedFlags[4] = {0, 0, 0, 0}; uint64_t usedFlags[4] = {0, 0, 0, 0};
__int64 i64_1 = 1; // MGH - instead of 1i64, which is MS specific int64_t i64_1 = 1; // MGH - instead of 1i64, which is MS specific
for (int j = 0; j < 64; j++) // This loop of 64 is to go round the 4 x for (int j = 0; j < 64; j++) // This loop of 64 is to go round the 4 x
// 4 tiles in the block // 4 tiles in the block
{ {
@ -374,8 +375,8 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
// chunkTotal++; // chunkTotal++;
// printf("%d: %d (0) %d (1) %d (2) %d (4) %d (8)\n", chunkTotal, type0 / // printf("%d: %d (0) %d (1) %d (2) %d (4) %d (8)\n", chunkTotal, type0 /
//chunkTotal, type1 / chunkTotal, type2 / chunkTotal, type4 / chunkTotal, // chunkTotal, type1 / chunkTotal, type2 / chunkTotal, type4 / chunkTotal,
//type8 / chunkTotal); // type8 / chunkTotal);
memToAlloc += 1024; // For the indices memToAlloc += 1024; // For the indices
unsigned char* newIndicesAndData = (unsigned char*)XPhysicalAlloc( unsigned char* newIndicesAndData = (unsigned char*)XPhysicalAlloc(
@ -976,8 +977,8 @@ void CompressedTileStorage::compress(int upgradeBlock /*=-1*/) {
} }
#else #else
__uint64 usedFlags[4] = {0, 0, 0, 0}; uint64_t usedFlags[4] = {0, 0, 0, 0};
__int64 i64_1 = int64_t i64_1 =
1; // MGH - instead of 1i64, which is MS specific 1; // MGH - instead of 1i64, which is MS specific
for (int j = 0; j < 64; j++) // This loop of 64 is to go round for (int j = 0; j < 64; j++) // This loop of 64 is to go round
// the 4x4x4 tiles in the block // the 4x4x4 tiles in the block
@ -1076,6 +1077,7 @@ void CompressedTileStorage::compress(int upgradeBlock /*=-1*/) {
memToAlloc, MAXULONG_PTR, 4096, memToAlloc, MAXULONG_PTR, 4096,
PAGE_READWRITE); //(unsigned char *)malloc( memToAlloc ); PAGE_READWRITE); //(unsigned char *)malloc( memToAlloc );
if (newIndicesAndData == NULL) { if (newIndicesAndData == NULL) {
DWORD lastError = GetLastError();
#ifndef _DURANGO #ifndef _DURANGO
MEMORYSTATUS memStatus; MEMORYSTATUS memStatus;
GlobalMemoryStatus(&memStatus); GlobalMemoryStatus(&memStatus);
@ -1380,4 +1382,4 @@ void CompressedTileStorage::reverseIndices(unsigned char* indices) {
for (int i = 0; i < 512; i++) { for (int i = 0; i < 512; i++) {
System::ReverseUSHORT(&blockIndices[i]); System::ReverseUSHORT(&blockIndices[i]);
} }
} }

View file

@ -17,20 +17,20 @@
// bytes in total (2) The type of index is determined by the least significant 2 // bytes in total (2) The type of index is determined by the least significant 2
// bits, the other 14 bits represent an offset for the data, stored divided by 2 // bits, the other 14 bits represent an offset for the data, stored divided by 2
// 0 - the data for this block is represented at 1 bit per // 0 - the data for this block is represented at 1 bit per
//tile. Data pointed to is 2 bytes describing the 2 possible tiles stored in // tile. Data pointed to is 2 bytes describing the 2 possible tiles stored in
//this block, followed by 32 bytes of data (total 34 bytes) 1 - the data for // this block, followed by 32 bytes of data (total 34 bytes)
//this block is represented at 2 bit per tile. Data pointed to is 4 bytes // 1 - the data for this block is represented at 2 bit per tile. Data pointed to
//describing the 4 possible tiles stored in this block, followed by 64 bytes of // is 4 bytes describing the 4 possible tiles stored in this block, followed by
//data (total 68 bytes) 2 - the data for this block is represented at 4 bit per // 64 bytes of data (total 68 bytes) 2 - the data for this
//tile. Data pointed to is 16 bytes describing the 16 possible tiles stored in // block is represented at 4 bit per tile. Data pointed to is 16 bytes
//this block, followed by 128 bytes of data (total 144 bytes) 3 - if bit 2 is 0, // describing the 16 possible tiles stored in this block, followed by 128 bytes
//then this block is represented at 8 bits per tile. Data pointed to is 64 // of data (total 144 bytes) 3 - if bit 2 is 0, then this block is
//bytes, offset must be a multiple of 4 (since bit 2 can also be thought of as // represented at 8 bits per tile. Data pointed to is 64 bytes, offset must be a
//being the low bit of the offset (divided by 2 as in the other cases), and is // multiple of 4 (since bit 2 can also be thought of as being
//zero) // the low bit of the offset (divided by 2 as in the other cases), and is zero)
// - if bit 2 is 1, then this block is represented at 0 // - if bit 2 is 1, then this block is represented at 0
//bits per tile. The upper 8 bits of the index store the tile value that is used // bits per tile. The upper 8 bits of the index store the tile value that is
//by the entire block. // used by the entire block.
// So: // So:
// oooooooooooooo00 - 1 bit per tile, offset oooooooooooooo0 // oooooooooooooo00 - 1 bit per tile, offset oooooooooooooo0
// oooooooooooooo01 - 2 bits per tile, offset oooooooooooooo0 // oooooooooooooo01 - 2 bits per tile, offset oooooooooooooo0

View file

@ -18,7 +18,7 @@ _MapDataMappings::_MapDataMappings() {
#ifndef _DURANGO #ifndef _DURANGO
ZeroMemory(xuids, sizeof(PlayerUID) * MAXIMUM_MAP_SAVE_DATA); ZeroMemory(xuids, sizeof(PlayerUID) * MAXIMUM_MAP_SAVE_DATA);
#endif #endif
ZeroMemory(dimensions, sizeof(std::uint8_t) * (MAXIMUM_MAP_SAVE_DATA / 4)); ZeroMemory(dimensions, sizeof(uint8_t) * (MAXIMUM_MAP_SAVE_DATA / 4));
} }
int _MapDataMappings::getDimension(int id) { int _MapDataMappings::getDimension(int id) {
@ -79,7 +79,7 @@ _MapDataMappings_old::_MapDataMappings_old() {
#ifndef _DURANGO #ifndef _DURANGO
ZeroMemory(xuids, sizeof(PlayerUID) * MAXIMUM_MAP_SAVE_DATA); ZeroMemory(xuids, sizeof(PlayerUID) * MAXIMUM_MAP_SAVE_DATA);
#endif #endif
ZeroMemory(dimensions, sizeof(std::uint8_t) * (MAXIMUM_MAP_SAVE_DATA / 8)); ZeroMemory(dimensions, sizeof(uint8_t) * (MAXIMUM_MAP_SAVE_DATA / 8));
} }
int _MapDataMappings_old::getDimension(int id) { int _MapDataMappings_old::getDimension(int id) {
@ -100,8 +100,8 @@ void DirectoryLevelStorage::PlayerMappings::addMapping(int id, int centreX,
int centreZ, int centreZ,
int dimension, int dimension,
int scale) { int scale) {
__int64 index = (((__int64)(centreZ & 0x1FFFFFFF)) << 34) | int64_t index = (((int64_t)(centreZ & 0x1FFFFFFF)) << 34) |
(((__int64)(centreX & 0x1FFFFFFF)) << 5) | (((int64_t)(centreX & 0x1FFFFFFF)) << 5) |
((scale & 0x7) << 2) | (dimension & 0x3); ((scale & 0x7) << 2) | (dimension & 0x3);
m_mappings[index] = id; m_mappings[index] = id;
// app.DebugPrintf("Adding mapping: %d - (%d,%d)/%d/%d [%I64d - // app.DebugPrintf("Adding mapping: %d - (%d,%d)/%d/%d [%I64d -
@ -112,14 +112,14 @@ bool DirectoryLevelStorage::PlayerMappings::getMapping(int& id, int centreX,
int centreZ, int centreZ,
int dimension, int dimension,
int scale) { int scale) {
//__int64 zMasked = centreZ & 0x1FFFFFFF; //int64_t zMasked = centreZ & 0x1FFFFFFF;
//__int64 xMasked = centreX & 0x1FFFFFFF; //int64_t xMasked = centreX & 0x1FFFFFFF;
//__int64 zShifted = zMasked << 34; //int64_t zShifted = zMasked << 34;
//__int64 xShifted = xMasked << 5; //int64_t xShifted = xMasked << 5;
// app.DebugPrintf("xShifted = %d (0x%016x), zShifted = %I64d // app.DebugPrintf("xShifted = %d (0x%016x), zShifted = %I64d
// (0x%016llx)\n", xShifted, xShifted, zShifted, zShifted); // (0x%016llx)\n", xShifted, xShifted, zShifted, zShifted);
__int64 index = (((__int64)(centreZ & 0x1FFFFFFF)) << 34) | int64_t index = (((int64_t)(centreZ & 0x1FFFFFFF)) << 34) |
(((__int64)(centreX & 0x1FFFFFFF)) << 5) | (((int64_t)(centreX & 0x1FFFFFFF)) << 5) |
((scale & 0x7) << 2) | (dimension & 0x3); ((scale & 0x7) << 2) | (dimension & 0x3);
AUTO_VAR(it, m_mappings.find(index)); AUTO_VAR(it, m_mappings.find(index));
if (it != m_mappings.end()) { if (it != m_mappings.end()) {
@ -148,7 +148,7 @@ void DirectoryLevelStorage::PlayerMappings::writeMappings(
void DirectoryLevelStorage::PlayerMappings::readMappings(DataInputStream* dis) { void DirectoryLevelStorage::PlayerMappings::readMappings(DataInputStream* dis) {
int count = dis->readInt(); int count = dis->readInt();
for (unsigned int i = 0; i < count; ++i) { for (unsigned int i = 0; i < count; ++i) {
__int64 index = dis->readLong(); int64_t index = dis->readLong();
int id = dis->readInt(); int id = dis->readInt();
m_mappings[index] = id; m_mappings[index] = id;
app.DebugPrintf(" -- %lld (0x%016llx) = %d\n", index, index, id); app.DebugPrintf(" -- %lld (0x%016llx) = %d\n", index, index, id);
@ -202,7 +202,7 @@ void DirectoryLevelStorage::checkSession() {
// 4J-PB - Not in the Xbox game // 4J-PB - Not in the Xbox game
/* /*
File dataFile = File( dir, std::wstring(L"session.lock")); File dataFile = File( dir, wstring(L"session.lock"));
FileInputStream fis = FileInputStream(dataFile); FileInputStream fis = FileInputStream(dataFile);
DataInputStream dis = DataInputStream(&fis); DataInputStream dis = DataInputStream(&fis);
dis.close(); dis.close();
@ -260,8 +260,7 @@ LevelData* DirectoryLevelStorage::prepareLevel() {
} else } else
#endif #endif
{ {
getSaveFile()->setFilePointer(fileEntry, 0, getSaveFile()->setFilePointer(fileEntry, 0, NULL, FILE_BEGIN);
SaveFileSeekOrigin::Begin);
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
byteArray data(fileEntry->getFileSize()); byteArray data(fileEntry->getFileSize());
@ -429,15 +428,12 @@ void DirectoryLevelStorage::save(std::shared_ptr<Player> player) {
} }
// 4J Changed return val to bool to check if new player or loaded player // 4J Changed return val to bool to check if new player or loaded player
bool DirectoryLevelStorage::load(std::shared_ptr<Player> player) { CompoundTag* DirectoryLevelStorage::load(std::shared_ptr<Player> player) {
bool newPlayer = true;
CompoundTag* tag = loadPlayerDataTag(player->getXuid()); CompoundTag* tag = loadPlayerDataTag(player->getXuid());
if (tag != NULL) { if (tag != NULL) {
newPlayer = false;
player->load(tag); player->load(tag);
delete tag;
} }
return newPlayer; return tag;
} }
CompoundTag* DirectoryLevelStorage::loadPlayerDataTag(PlayerUID xuid) { CompoundTag* DirectoryLevelStorage::loadPlayerDataTag(PlayerUID xuid) {

View file

@ -65,7 +65,7 @@ private:
const ConsoleSavePath playerDir; const ConsoleSavePath playerDir;
// const File dataDir; // const File dataDir;
const ConsoleSavePath dataDir; const ConsoleSavePath dataDir;
const __int64 sessionId; const int64_t sessionId;
const std::wstring levelId; const std::wstring levelId;
static const std::wstring sc_szPlayerDir; static const std::wstring sc_szPlayerDir;
@ -75,7 +75,7 @@ private:
friend class DirectoryLevelStorage; friend class DirectoryLevelStorage;
private: private:
std::unordered_map<__int64, short> m_mappings; std::unordered_map<int64_t, short> m_mappings;
public: public:
void addMapping(int id, int centreX, int centreZ, int dimension, void addMapping(int id, int centreX, int centreZ, int dimension,
@ -130,9 +130,10 @@ public:
std::vector<std::shared_ptr<Player> >* players); std::vector<std::shared_ptr<Player> >* players);
virtual void saveLevelData(LevelData* levelData); virtual void saveLevelData(LevelData* levelData);
virtual void save(std::shared_ptr<Player> player); virtual void save(std::shared_ptr<Player> player);
virtual bool load(std::shared_ptr<Player> virtual CompoundTag* load(
player); // 4J Changed return val to bool to check if std::shared_ptr<Player>
// new player or loaded player player); // 4J Changed return val to bool to check if new player or
// loaded player
virtual CompoundTag* loadPlayerDataTag(PlayerUID xuid); virtual CompoundTag* loadPlayerDataTag(PlayerUID xuid);
virtual void clearOldPlayerFiles(); // 4J Added virtual void clearOldPlayerFiles(); // 4J Added
PlayerIO* getPlayerIO(); PlayerIO* getPlayerIO();

View file

@ -3,6 +3,8 @@
#include "../../Entities/Mobs/Painting.h" #include "../../Entities/Mobs/Painting.h"
#include "../../Platform/System.h" #include "../../Platform/System.h"
#include "../../Entities/Entity.h" #include "../../Entities/Entity.h"
#include "../../Entities/Mobs/WitherBoss.h"
#include "../../Headers/net.minecraft.world.entity.ambient.h"
#include "../../Headers/net.minecraft.world.entity.animal.h" #include "../../Headers/net.minecraft.world.entity.animal.h"
#include "../../Headers/net.minecraft.world.entity.item.h" #include "../../Headers/net.minecraft.world.entity.item.h"
#include "../../Headers/net.minecraft.world.entity.monster.h" #include "../../Headers/net.minecraft.world.entity.monster.h"
@ -66,10 +68,11 @@ void EntityIO::staticCtor() {
setId(ItemEntity::create, eTYPE_ITEMENTITY, L"Item", 1); setId(ItemEntity::create, eTYPE_ITEMENTITY, L"Item", 1);
setId(ExperienceOrb::create, eTYPE_EXPERIENCEORB, L"XPOrb", 2); setId(ExperienceOrb::create, eTYPE_EXPERIENCEORB, L"XPOrb", 2);
setId(LeashFenceKnotEntity::create, eTYPE_LEASHFENCEKNOT, L"LeashKnot", 8);
setId(Painting::create, eTYPE_PAINTING, L"Painting", 9); setId(Painting::create, eTYPE_PAINTING, L"Painting", 9);
setId(Arrow::create, eTYPE_ARROW, L"Arrow", 10); setId(Arrow::create, eTYPE_ARROW, L"Arrow", 10);
setId(Snowball::create, eTYPE_SNOWBALL, L"Snowball", 11); setId(Snowball::create, eTYPE_SNOWBALL, L"Snowball", 11);
setId(Fireball::create, eTYPE_FIREBALL, L"Fireball", 12); setId(LargeFireball::create, eTYPE_FIREBALL, L"Fireball", 12);
setId(SmallFireball::create, eTYPE_SMALL_FIREBALL, L"SmallFireball", 13); setId(SmallFireball::create, eTYPE_SMALL_FIREBALL, L"SmallFireball", 13);
setId(ThrownEnderpearl::create, eTYPE_THROWNENDERPEARL, L"ThrownEnderpearl", setId(ThrownEnderpearl::create, eTYPE_THROWNENDERPEARL, L"ThrownEnderpearl",
14); 14);
@ -79,12 +82,24 @@ void EntityIO::staticCtor() {
setId(ThrownExpBottle::create, eTYPE_THROWNEXPBOTTLE, L"ThrownExpBottle", setId(ThrownExpBottle::create, eTYPE_THROWNEXPBOTTLE, L"ThrownExpBottle",
17); 17);
setId(ItemFrame::create, eTYPE_ITEM_FRAME, L"ItemFrame", 18); setId(ItemFrame::create, eTYPE_ITEM_FRAME, L"ItemFrame", 18);
setId(WitherSkull::create, eTYPE_WITHER_SKULL, L"WitherSkull", 19);
setId(PrimedTnt::create, eTYPE_PRIMEDTNT, L"PrimedTnt", 20); setId(PrimedTnt::create, eTYPE_PRIMEDTNT, L"PrimedTnt", 20);
setId(FallingTile::create, eTYPE_FALLINGTILE, L"FallingSand", 21); setId(FallingTile::create, eTYPE_FALLINGTILE, L"FallingSand", 21);
setId(Minecart::create, eTYPE_MINECART, L"Minecart", 40); setId(FireworksRocketEntity::create, eTYPE_FIREWORKS_ROCKET,
L"FireworksRocketEntity", 22);
setId(Boat::create, eTYPE_BOAT, L"Boat", 41); setId(Boat::create, eTYPE_BOAT, L"Boat", 41);
setId(MinecartRideable::create, eTYPE_MINECART_RIDEABLE,
L"MinecartRideable", 42);
setId(MinecartChest::create, eTYPE_MINECART_CHEST, L"MinecartChest", 43);
setId(MinecartFurnace::create, eTYPE_MINECART_FURNACE, L"MinecartFurnace",
44);
setId(MinecartTNT::create, eTYPE_MINECART_TNT, L"MinecartTNT", 45);
setId(MinecartHopper::create, eTYPE_MINECART_HOPPER, L"MinecartHopper", 46);
setId(MinecartSpawner::create, eTYPE_MINECART_SPAWNER, L"MinecartSpawner",
47);
setId(Mob::create, eTYPE_MOB, L"Mob", 48); setId(Mob::create, eTYPE_MOB, L"Mob", 48);
setId(Monster::create, eTYPE_MONSTER, L"Monster", 49); setId(Monster::create, eTYPE_MONSTER, L"Monster", 49);
@ -126,7 +141,15 @@ void EntityIO::staticCtor() {
setId(LavaSlime::create, eTYPE_LAVASLIME, L"LavaSlime", 62, setId(LavaSlime::create, eTYPE_LAVASLIME, L"LavaSlime", 62,
eMinecraftColour_Mob_LavaSlime_Colour1, eMinecraftColour_Mob_LavaSlime_Colour1,
eMinecraftColour_Mob_LavaSlime_Colour2, IDS_LAVA_SLIME); eMinecraftColour_Mob_LavaSlime_Colour2, IDS_LAVA_SLIME);
setId(EnderDragon::create, eTYPE_ENDERDRAGON, L"EnderDragon", 63); setId(EnderDragon::create, eTYPE_ENDERDRAGON, L"EnderDragon", 63,
eMinecraftColour_Mob_Enderman_Colour1,
eMinecraftColour_Mob_Enderman_Colour1, IDS_ENDERDRAGON);
setId(WitherBoss::create, eTYPE_WITHERBOSS, L"WitherBoss", 64);
setId(Bat::create, eTYPE_BAT, L"Bat", 65, eMinecraftColour_Mob_Bat_Colour1,
eMinecraftColour_Mob_Bat_Colour2, IDS_BAT);
setId(Witch::create, eTYPE_WITCH, L"Witch", 66,
eMinecraftColour_Mob_Witch_Colour1,
eMinecraftColour_Mob_Witch_Colour2, IDS_WITCH);
setId(Pig::create, eTYPE_PIG, L"Pig", 90, eMinecraftColour_Mob_Pig_Colour1, setId(Pig::create, eTYPE_PIG, L"Pig", 90, eMinecraftColour_Mob_Pig_Colour1,
eMinecraftColour_Mob_Pig_Colour2, IDS_PIG); eMinecraftColour_Mob_Pig_Colour2, IDS_PIG);
@ -148,10 +171,13 @@ void EntityIO::staticCtor() {
eMinecraftColour_Mob_MushroomCow_Colour1, eMinecraftColour_Mob_MushroomCow_Colour1,
eMinecraftColour_Mob_MushroomCow_Colour2, IDS_MUSHROOM_COW); eMinecraftColour_Mob_MushroomCow_Colour2, IDS_MUSHROOM_COW);
setId(SnowMan::create, eTYPE_SNOWMAN, L"SnowMan", 97); setId(SnowMan::create, eTYPE_SNOWMAN, L"SnowMan", 97);
setId(Ozelot::create, eTYPE_OZELOT, L"Ozelot", 98, setId(Ocelot::create, eTYPE_OCELOT, L"Ozelot", 98,
eMinecraftColour_Mob_Ocelot_Colour1, eMinecraftColour_Mob_Ocelot_Colour1,
eMinecraftColour_Mob_Ocelot_Colour2, IDS_OZELOT); eMinecraftColour_Mob_Ocelot_Colour2, IDS_OZELOT);
setId(VillagerGolem::create, eTYPE_VILLAGERGOLEM, L"VillagerGolem", 99); setId(VillagerGolem::create, eTYPE_VILLAGERGOLEM, L"VillagerGolem", 99);
setId(EntityHorse::create, eTYPE_HORSE, L"EntityHorse", 100,
eMinecraftColour_Mob_Horse_Colour1,
eMinecraftColour_Mob_Horse_Colour2, IDS_HORSE);
setId(Villager::create, eTYPE_VILLAGER, L"Villager", 120, setId(Villager::create, eTYPE_VILLAGER, L"Villager", 120,
eMinecraftColour_Mob_Villager_Colour1, eMinecraftColour_Mob_Villager_Colour1,
@ -162,6 +188,43 @@ void EntityIO::staticCtor() {
// 4J Added // 4J Added
setId(DragonFireball::create, eTYPE_DRAGON_FIREBALL, L"DragonFireball", setId(DragonFireball::create, eTYPE_DRAGON_FIREBALL, L"DragonFireball",
1000); 1000);
// 4J-PB - moved to allow the eggs to be named and coloured in the Creative
// Mode menu 4J Added for custom spawn eggs
setId(EntityHorse::create, eTYPE_HORSE, L"EntityHorse",
100 | ((EntityHorse::TYPE_DONKEY + 1) << 12),
eMinecraftColour_Mob_Horse_Colour1,
eMinecraftColour_Mob_Horse_Colour2, IDS_DONKEY);
setId(EntityHorse::create, eTYPE_HORSE, L"EntityHorse",
100 | ((EntityHorse::TYPE_MULE + 1) << 12),
eMinecraftColour_Mob_Horse_Colour1,
eMinecraftColour_Mob_Horse_Colour2, IDS_MULE);
#ifndef _CONTENT_PACKAGE
setId(EntityHorse::create, eTYPE_HORSE, L"EntityHorse",
100 | ((EntityHorse::TYPE_SKELETON + 1) << 12),
eMinecraftColour_Mob_Horse_Colour1,
eMinecraftColour_Mob_Horse_Colour2, IDS_SKELETON_HORSE);
setId(EntityHorse::create, eTYPE_HORSE, L"EntityHorse",
100 | ((EntityHorse::TYPE_UNDEAD + 1) << 12),
eMinecraftColour_Mob_Horse_Colour1,
eMinecraftColour_Mob_Horse_Colour2, IDS_ZOMBIE_HORSE);
setId(Ocelot::create, eTYPE_OCELOT, L"Ozelot",
98 | ((Ocelot::TYPE_BLACK + 1) << 12),
eMinecraftColour_Mob_Ocelot_Colour1,
eMinecraftColour_Mob_Ocelot_Colour2, IDS_OZELOT);
setId(Ocelot::create, eTYPE_OCELOT, L"Ozelot",
98 | ((Ocelot::TYPE_RED + 1) << 12),
eMinecraftColour_Mob_Ocelot_Colour1,
eMinecraftColour_Mob_Ocelot_Colour2, IDS_OZELOT);
setId(Ocelot::create, eTYPE_OCELOT, L"Ozelot",
98 | ((Ocelot::TYPE_SIAMESE + 1) << 12),
eMinecraftColour_Mob_Ocelot_Colour1,
eMinecraftColour_Mob_Ocelot_Colour2, IDS_OZELOT);
setId(Spider::create, eTYPE_SPIDER, L"Spider", 52 | (2 << 12),
eMinecraftColour_Mob_Spider_Colour1,
eMinecraftColour_Mob_Spider_Colour2, IDS_SKELETON);
#endif
} }
std::shared_ptr<Entity> EntityIO::newEntity(const std::wstring& id, std::shared_ptr<Entity> EntityIO::newEntity(const std::wstring& id,
@ -172,6 +235,10 @@ std::shared_ptr<Entity> EntityIO::newEntity(const std::wstring& id,
if (it != idCreateMap->end()) { if (it != idCreateMap->end()) {
entityCreateFn create = it->second; entityCreateFn create = it->second;
if (create != NULL) entity = std::shared_ptr<Entity>(create(level)); if (create != NULL) entity = std::shared_ptr<Entity>(create(level));
if ((entity != NULL) && entity->GetType() == eTYPE_ENDERDRAGON) {
std::dynamic_pointer_cast<EnderDragon>(entity)
->AddParts(); // 4J added to finalise creation
}
} }
return entity; return entity;
@ -180,10 +247,32 @@ std::shared_ptr<Entity> EntityIO::newEntity(const std::wstring& id,
std::shared_ptr<Entity> EntityIO::loadStatic(CompoundTag* tag, Level* level) { std::shared_ptr<Entity> EntityIO::loadStatic(CompoundTag* tag, Level* level) {
std::shared_ptr<Entity> entity; std::shared_ptr<Entity> entity;
if (tag->getString(L"id").compare(L"Minecart") == 0) {
// I don't like this any more than you do. Sadly, compatibility...
switch (tag->getInt(L"Type")) {
case Minecart::TYPE_CHEST:
tag->putString(L"id", L"MinecartChest");
break;
case Minecart::TYPE_FURNACE:
tag->putString(L"id", L"MinecartFurnace");
break;
case Minecart::TYPE_RIDEABLE:
tag->putString(L"id", L"MinecartRideable");
break;
}
tag->remove(L"Type");
}
AUTO_VAR(it, idCreateMap->find(tag->getString(L"id"))); AUTO_VAR(it, idCreateMap->find(tag->getString(L"id")));
if (it != idCreateMap->end()) { if (it != idCreateMap->end()) {
entityCreateFn create = it->second; entityCreateFn create = it->second;
if (create != NULL) entity = std::shared_ptr<Entity>(create(level)); if (create != NULL) entity = std::shared_ptr<Entity>(create(level));
if ((entity != NULL) && entity->GetType() == eTYPE_ENDERDRAGON) {
std::dynamic_pointer_cast<EnderDragon>(entity)
->AddParts(); // 4J added to finalise creation
}
} }
if (entity != NULL) { if (entity != NULL) {
@ -204,6 +293,10 @@ std::shared_ptr<Entity> EntityIO::newById(int id, Level* level) {
if (it != numCreateMap->end()) { if (it != numCreateMap->end()) {
entityCreateFn create = it->second; entityCreateFn create = it->second;
if (create != NULL) entity = std::shared_ptr<Entity>(create(level)); if (create != NULL) entity = std::shared_ptr<Entity>(create(level));
if ((entity != NULL) && entity->GetType() == eTYPE_ENDERDRAGON) {
std::dynamic_pointer_cast<EnderDragon>(entity)
->AddParts(); // 4J added to finalise creation
}
} }
if (entity != NULL) { if (entity != NULL) {
@ -225,6 +318,10 @@ std::shared_ptr<Entity> EntityIO::newByEnumType(eINSTANCEOF eType,
if (it2 != numCreateMap->end()) { if (it2 != numCreateMap->end()) {
entityCreateFn create = it2->second; entityCreateFn create = it2->second;
if (create != NULL) entity = std::shared_ptr<Entity>(create(level)); if (create != NULL) entity = std::shared_ptr<Entity>(create(level));
if ((entity != NULL) && entity->GetType() == eTYPE_ENDERDRAGON) {
std::dynamic_pointer_cast<EnderDragon>(entity)
->AddParts(); // 4J added to finalise creation
}
} }
} }

View file

@ -35,10 +35,10 @@ void GameType::updatePlayerAbilities(Abilities* abilities) {
abilities->invulnerable = false; abilities->invulnerable = false;
abilities->flying = false; abilities->flying = false;
} }
abilities->mayBuild = !isReadOnly(); abilities->mayBuild = !isAdventureRestricted();
} }
bool GameType::isReadOnly() { return this == ADVENTURE; } bool GameType::isAdventureRestricted() { return this == ADVENTURE; }
bool GameType::isCreative() { return this == CREATIVE; } bool GameType::isCreative() { return this == CREATIVE; }
@ -70,7 +70,7 @@ GameType* GameType::byName(const std::wstring& name) {
return SURVIVAL; return SURVIVAL;
} }
void LevelSettings::_init(__int64 seed, GameType* gameType, void LevelSettings::_init(int64_t seed, GameType* gameType,
bool generateMapFeatures, bool hardcore, bool generateMapFeatures, bool hardcore,
bool newSeaLevel, LevelType* levelType, int xzSize, bool newSeaLevel, LevelType* levelType, int xzSize,
int hellScale) { int hellScale) {
@ -82,11 +82,12 @@ void LevelSettings::_init(__int64 seed, GameType* gameType,
this->levelType = levelType; this->levelType = levelType;
this->allowCommands = false; this->allowCommands = false;
this->startingBonusItems = false; this->startingBonusItems = false;
levelTypeOptions = L"";
m_xzSize = xzSize; m_xzSize = xzSize;
m_hellScale = hellScale; m_hellScale = hellScale;
} }
LevelSettings::LevelSettings(__int64 seed, GameType* gameType, LevelSettings::LevelSettings(int64_t seed, GameType* gameType,
bool generateMapFeatures, bool hardcore, bool generateMapFeatures, bool hardcore,
bool newSeaLevel, LevelType* levelType, int xzSize, bool newSeaLevel, LevelType* levelType, int xzSize,
int hellScale) int hellScale)
@ -118,9 +119,14 @@ LevelSettings* LevelSettings::enableSinglePlayerCommands() {
return this; return this;
} }
LevelSettings* LevelSettings::setLevelTypeOptions(const std::wstring& options) {
levelTypeOptions = options;
return this;
}
bool LevelSettings::hasStartingBonusItems() { return startingBonusItems; } bool LevelSettings::hasStartingBonusItems() { return startingBonusItems; }
__int64 LevelSettings::getSeed() { return seed; } int64_t LevelSettings::getSeed() { return seed; }
GameType* LevelSettings::getGameType() { return gameType; } GameType* LevelSettings::getGameType() { return gameType; }
@ -142,3 +148,5 @@ bool LevelSettings::useNewSeaLevel() { return newSeaLevel; }
int LevelSettings::getXZSize() { return m_xzSize; } int LevelSettings::getXZSize() { return m_xzSize; }
int LevelSettings::getHellScale() { return m_hellScale; } int LevelSettings::getHellScale() { return m_hellScale; }
std::wstring LevelSettings::getLevelTypeOptions() { return levelTypeOptions; }

View file

@ -4,6 +4,8 @@ class LevelType;
class Abilities; class Abilities;
class LevelData; class LevelData;
#define _ADVENTURE_MODE_ENABLED
// 4J Stu - Was Java enum class // 4J Stu - Was Java enum class
class GameType { class GameType {
public: public:
@ -24,7 +26,7 @@ public:
int getId(); int getId();
std::wstring getName(); std::wstring getName();
void updatePlayerAbilities(Abilities* abilities); void updatePlayerAbilities(Abilities* abilities);
bool isReadOnly(); bool isAdventureRestricted();
bool isCreative(); bool isCreative();
bool isSurvival(); bool isSurvival();
static GameType* byId(int id); static GameType* byId(int id);
@ -33,7 +35,7 @@ public:
class LevelSettings { class LevelSettings {
private: private:
__int64 seed; int64_t seed;
GameType* gameType; GameType* gameType;
bool generateMapFeatures; bool generateMapFeatures;
bool hardcore; bool hardcore;
@ -41,16 +43,17 @@ private:
LevelType* levelType; LevelType* levelType;
bool allowCommands; bool allowCommands;
bool startingBonusItems; // 4J - brought forward from 1.3.2 bool startingBonusItems; // 4J - brought forward from 1.3.2
int m_xzSize; // 4J Added std::wstring levelTypeOptions;
int m_xzSize; // 4J Added
int m_hellScale; int m_hellScale;
void _init(__int64 seed, GameType* gameType, bool generateMapFeatures, void _init(int64_t seed, GameType* gameType, bool generateMapFeatures,
bool hardcore, bool newSeaLevel, LevelType* levelType, bool hardcore, bool newSeaLevel, LevelType* levelType,
int xzSize, int xzSize,
int hellScale); // 4J Added xzSize and hellScale param int hellScale); // 4J Added xzSize and hellScale param
public: public:
LevelSettings(__int64 seed, GameType* gameType, bool generateMapFeatures, LevelSettings(int64_t seed, GameType* gameType, bool generateMapFeatures,
bool hardcore, bool newSeaLevel, LevelType* levelType, bool hardcore, bool newSeaLevel, LevelType* levelType,
int xzSize, int xzSize,
int hellScale); // 4J Added xzSize and hellScale param int hellScale); // 4J Added xzSize and hellScale param
@ -58,8 +61,9 @@ public:
LevelSettings* LevelSettings*
enableStartingBonusItems(); // 4J - brought forward from 1.3.2 enableStartingBonusItems(); // 4J - brought forward from 1.3.2
LevelSettings* enableSinglePlayerCommands(); LevelSettings* enableSinglePlayerCommands();
LevelSettings* setLevelTypeOptions(const std::wstring& options);
bool hasStartingBonusItems(); // 4J - brought forward from 1.3.2 bool hasStartingBonusItems(); // 4J - brought forward from 1.3.2
__int64 getSeed(); int64_t getSeed();
GameType* getGameType(); GameType* getGameType();
bool isHardcore(); bool isHardcore();
LevelType* getLevelType(); LevelType* getLevelType();
@ -69,4 +73,5 @@ public:
int getXZSize(); // 4J Added int getXZSize(); // 4J Added
int getHellScale(); // 4J Added int getHellScale(); // 4J Added
static GameType* validateGameType(int gameType); static GameType* validateGameType(int gameType);
std::wstring getLevelTypeOptions();
}; };

View file

@ -27,5 +27,6 @@ public:
virtual int getMaxBuildHeight() = 0; virtual int getMaxBuildHeight() = 0;
virtual bool isAllEmpty() = 0; virtual bool isAllEmpty() = 0;
virtual bool isTopSolidBlocking(int x, int y, int z) = 0; virtual bool isTopSolidBlocking(int x, int y, int z) = 0;
virtual int getDirectSignal(int x, int y, int z, int dir) = 0;
virtual ~LevelSource() {} virtual ~LevelSource() {}
}; };

View file

@ -2,8 +2,8 @@
#include "LevelSummary.h" #include "LevelSummary.h"
LevelSummary::LevelSummary(const std::wstring& levelId, LevelSummary::LevelSummary(const std::wstring& levelId,
const std::wstring& levelName, __int64 lastPlayed, const std::wstring& levelName, int64_t lastPlayed,
__int64 sizeOnDisk, GameType* gameMode, int64_t sizeOnDisk, GameType* gameMode,
bool requiresConversion, bool hardcore, bool requiresConversion, bool hardcore,
bool hasCheats) bool hasCheats)
: levelId(levelId), : levelId(levelId),
@ -19,11 +19,11 @@ std::wstring LevelSummary::getLevelId() { return levelId; }
std::wstring LevelSummary::getLevelName() { return levelName; } std::wstring LevelSummary::getLevelName() { return levelName; }
__int64 LevelSummary::getSizeOnDisk() { return sizeOnDisk; } int64_t LevelSummary::getSizeOnDisk() { return sizeOnDisk; }
bool LevelSummary::isRequiresConversion() { return requiresConversion; } bool LevelSummary::isRequiresConversion() { return requiresConversion; }
__int64 LevelSummary::getLastPlayed() { return lastPlayed; } int64_t LevelSummary::getLastPlayed() { return lastPlayed; }
int LevelSummary::compareTo(LevelSummary* rhs) { int LevelSummary::compareTo(LevelSummary* rhs) {
if (lastPlayed < rhs->lastPlayed) { if (lastPlayed < rhs->lastPlayed) {

View file

@ -5,8 +5,8 @@ class GameType;
class LevelSummary { class LevelSummary {
const std::wstring levelId; const std::wstring levelId;
const std::wstring levelName; const std::wstring levelName;
const __int64 lastPlayed; const int64_t lastPlayed;
const __int64 sizeOnDisk; const int64_t sizeOnDisk;
const bool requiresConversion; const bool requiresConversion;
GameType* gameMode; GameType* gameMode;
const bool hardcore; const bool hardcore;
@ -14,13 +14,13 @@ class LevelSummary {
public: public:
LevelSummary(const std::wstring& levelId, const std::wstring& levelName, LevelSummary(const std::wstring& levelId, const std::wstring& levelName,
__int64 lastPlayed, __int64 sizeOnDisk, GameType* gameMode, int64_t lastPlayed, int64_t sizeOnDisk, GameType* gameMode,
bool requiresConversion, bool hardcore, bool hasCheats); bool requiresConversion, bool hardcore, bool hasCheats);
std::wstring getLevelId(); std::wstring getLevelId();
std::wstring getLevelName(); std::wstring getLevelName();
__int64 getSizeOnDisk(); int64_t getSizeOnDisk();
bool isRequiresConversion(); bool isRequiresConversion();
__int64 getLastPlayed(); int64_t getLastPlayed();
int compareTo(LevelSummary* rhs); int compareTo(LevelSummary* rhs);
GameType* getGameMode(); GameType* getGameMode();
bool isHardcore(); bool isHardcore();

View file

@ -43,6 +43,7 @@ LevelType::LevelType(int id, std::wstring generatorName, int version) {
} }
void LevelType::init(int id, std::wstring generatorName, int version) { void LevelType::init(int id, std::wstring generatorName, int version) {
this->id = id;
m_generatorName = generatorName; m_generatorName = generatorName;
m_version = version; m_version = version;
m_selectable = true; m_selectable = true;
@ -81,12 +82,14 @@ bool LevelType::hasReplacement() { return m_replacement; }
LevelType* LevelType::getLevelType(std::wstring name) { LevelType* LevelType::getLevelType(std::wstring name) {
if (name.length() > 0) { if (name.length() > 0) {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
// Fix: check NULL before accessing member to avoid null dereference std::wstring genname = levelTypes[i]->m_generatorName;
if (levelTypes[i] != NULL &&
(levelTypes[i]->m_generatorName.compare(name) == 0)) { if (levelTypes[i] != NULL && (genname.compare(name) == 0)) {
return levelTypes[i]; return levelTypes[i];
} }
} }
} }
return NULL; return NULL;
} }
int LevelType::getId() { return id; }

View file

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
class LevelType { class LevelType {
@ -15,6 +14,7 @@ public:
static void staticCtor(); static void staticCtor();
private: private:
int id;
std::wstring m_generatorName; std::wstring m_generatorName;
int m_version; int m_version;
bool m_selectable; bool m_selectable;
@ -42,4 +42,5 @@ private:
public: public:
bool hasReplacement(); bool hasReplacement();
static LevelType* getLevelType(std::wstring name); static LevelType* getLevelType(std::wstring name);
int getId();
}; };

View file

@ -33,6 +33,8 @@ MapItemSavedData::HoldingPlayer::HoldingPlayer(std::shared_ptr<Player> player,
tick = 0; tick = 0;
sendPosTick = 0; sendPosTick = 0;
step = 0;
hasSentInitial = false;
// java ctor // java ctor
// this->player = player; // this->player = player;
@ -50,6 +52,14 @@ MapItemSavedData::HoldingPlayer::~HoldingPlayer() {
charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket( charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket(
std::shared_ptr<ItemInstance> itemInstance) { std::shared_ptr<ItemInstance> itemInstance) {
if (!hasSentInitial) {
charArray data(2);
data[0] = HEADER_METADATA;
data[1] = parent->scale;
hasSentInitial = true;
return data;
}
if (--sendPosTick < 0) { if (--sendPosTick < 0) {
sendPosTick = 4; sendPosTick = 4;
@ -129,15 +139,13 @@ charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket(
std::shared_ptr<ServerPlayer> servPlayer = std::shared_ptr<ServerPlayer> servPlayer =
std::dynamic_pointer_cast<ServerPlayer>(player); std::dynamic_pointer_cast<ServerPlayer>(player);
for (int d = 0; d < 10; d++) { for (int d = 0; d < 10; d++) {
int column = (tick * 11) % (MapItem::IMAGE_WIDTH);
tick++;
if (rowsDirtyMin[column] >= 0) { if (rowsDirtyMin[column] >= 0) {
int len = rowsDirtyMax[column] - rowsDirtyMin[column] + 1; int len = rowsDirtyMax[column] - rowsDirtyMin[column] + 1;
int min = rowsDirtyMin[column]; int min = rowsDirtyMin[column];
charArray data = charArray(len + 3); charArray data = charArray(len + 3);
data[0] = 0; data[0] = HEADER_COLOURS;
data[1] = (char)column; data[1] = (char)column;
data[2] = (char)min; data[2] = (char)min;
for (unsigned int y = 0; y < data.length - 3; y++) { for (unsigned int y = 0; y < data.length - 3; y++) {
@ -157,7 +165,6 @@ MapItemSavedData::MapItemSavedData(const std::wstring& id) : SavedData(id) {
dimension = 0; dimension = 0;
scale = 0; scale = 0;
colors = byteArray(MapItem::IMAGE_WIDTH * MapItem::IMAGE_HEIGHT); colors = byteArray(MapItem::IMAGE_WIDTH * MapItem::IMAGE_HEIGHT);
step = 0;
} }
MapItemSavedData::~MapItemSavedData() { MapItemSavedData::~MapItemSavedData() {
@ -173,7 +180,7 @@ void MapItemSavedData::load(CompoundTag* tag) {
z = tag->getInt(L"zCenter"); z = tag->getInt(L"zCenter");
scale = tag->getByte(L"scale"); scale = tag->getByte(L"scale");
if (scale < 0) scale = 0; if (scale < 0) scale = 0;
if (scale > 4) scale = 4; if (scale > MAX_SCALE) scale = MAX_SCALE;
int width = tag->getShort(L"width"); int width = tag->getShort(L"width");
int height = tag->getShort(L"height"); int height = tag->getShort(L"height");
@ -246,8 +253,7 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
if (it2 != carriedByPlayers.end()) { if (it2 != carriedByPlayers.end()) {
carriedByPlayers.erase(it2); carriedByPlayers.erase(it2);
} }
it = carriedBy.erase( it = carriedBy.erase(find(carriedBy.begin(), carriedBy.end(), hp));
std::find(carriedBy.begin(), carriedBy.end(), hp));
} else { } else {
++it; ++it;
@ -330,7 +336,9 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
int size = MAP_SIZE - 1; int size = MAP_SIZE - 1;
char rot = (char)((item->getFrame()->dir * 90) * 16 / 360); char rot = (char)((item->getFrame()->dir * 90) * 16 / 360);
if (dimension < 0) { if (dimension < 0) {
int s = step / 10; int s =
(int)(playerLevel->getLevelData()->getDayTime() /
10);
rot = (char)((s * s * 34187121 + s * 121) >> 15 & 15); rot = (char)((s * s * 34187121 + s * 121) >> 15 & 15);
} }
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
@ -416,7 +424,9 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
rot = rot =
(char)(decorationPlayer->yRot * 16 / 360 + 0.5); (char)(decorationPlayer->yRot * 16 / 360 + 0.5);
if (dimension < 0) { if (dimension < 0) {
int s = step / 10; int s = (int)(playerLevel->getLevelData()
->getDayTime() /
10);
rot = rot =
(char)((s * s * 34187121 + s * 121) >> 15 & (char)((s * s * 34187121 + s * 121) >> 15 &
15); 15);
@ -460,11 +470,10 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
} }
// float xd = (float) (hp->player->x - x) / (1 << // float xd = (float) (hp->player->x - x) / (1 <<
// scale); float yd = (float) (hp->player->z - z) / (1 << scale); // scale); float yd = (float) (hp->player->z - z) /
// int ww = 64; // (1 << scale); int ww = 64;
// int hh = 64; // int hh = 64; if (xd >= -ww && yd >= -hh && xd
// if (xd >= -ww && yd >= -hh && xd <= ww && yd <= // <= ww && yd <= hh)
// hh)
// { // {
// char img = 0; // char img = 0;
// char x = (char) (xd * 2 + 0.5); // char x = (char) (xd * 2 + 0.5);
@ -511,7 +520,7 @@ void MapItemSavedData::setDirty(int x, int y0, int y1) {
} }
void MapItemSavedData::handleComplexItemData(charArray& data) { void MapItemSavedData::handleComplexItemData(charArray& data) {
if (data[0] == 0) { if (data[0] == HEADER_COLOURS) {
int xx = data[1] & 0xff; int xx = data[1] & 0xff;
int yy = data[2] & 0xff; int yy = data[2] & 0xff;
for (unsigned int y = 0; y < data.length - 3; y++) { for (unsigned int y = 0; y < data.length - 3; y++) {
@ -519,7 +528,7 @@ void MapItemSavedData::handleComplexItemData(charArray& data) {
} }
setDirty(); setDirty();
} else if (data[0] == 1) { } else if (data[0] == HEADER_DECORATIONS) {
for (unsigned int i = 0; i < decorations.size(); i++) { for (unsigned int i = 0; i < decorations.size(); i++) {
delete decorations[i]; delete decorations[i];
} }
@ -546,9 +555,27 @@ void MapItemSavedData::handleComplexItemData(charArray& data) {
decorations.push_back( decorations.push_back(
new MapDecoration(img, x, y, rot, entityId, visible)); new MapDecoration(img, x, y, rot, entityId, visible));
} }
} else if (data[0] == HEADER_METADATA) {
scale = data[1];
} }
} }
std::shared_ptr<MapItemSavedData::HoldingPlayer>
MapItemSavedData::getHoldingPlayer(std::shared_ptr<Player> player) {
std::shared_ptr<HoldingPlayer> hp = nullptr;
AUTO_VAR(it, carriedByPlayers.find(player));
if (it == carriedByPlayers.end()) {
hp = std::shared_ptr<HoldingPlayer>(new HoldingPlayer(player, this));
carriedByPlayers[player] = hp;
carriedBy.push_back(hp);
} else {
hp = it->second;
}
return hp;
}
// 4J Added // 4J Added
// We only have one map per player per dimension, so if they pickup someone // We only have one map per player per dimension, so if they pickup someone
// elses map we merge their map data with ours so that we can see everything // elses map we merge their map data with ours so that we can see everything

View file

@ -4,6 +4,11 @@
#include "SavedData.h" #include "SavedData.h"
class MapItemSavedData : public SavedData { class MapItemSavedData : public SavedData {
private:
static const int HEADER_COLOURS = 0;
static const int HEADER_DECORATIONS = 1;
static const int HEADER_METADATA = 2;
public: public:
static const int MAP_SIZE = 64; static const int MAP_SIZE = 64;
static const int MAX_SCALE = 4; static const int MAX_SCALE = 4;
@ -35,6 +40,12 @@ public:
int sendPosTick; int sendPosTick;
charArray lastSentDecorations; charArray lastSentDecorations;
public:
int step;
private:
bool hasSentInitial;
protected: protected:
const MapItemSavedData* parent; const MapItemSavedData* parent;
@ -52,7 +63,6 @@ public:
char dimension; char dimension;
uint8_t scale; uint8_t scale;
byteArray colors; byteArray colors;
int step;
std::vector<std::shared_ptr<HoldingPlayer> > carriedBy; std::vector<std::shared_ptr<HoldingPlayer> > carriedBy;
private: private:
@ -86,6 +96,8 @@ public:
using SavedData::setDirty; using SavedData::setDirty;
void setDirty(int x, int y0, int y1); void setDirty(int x, int y0, int y1);
void handleComplexItemData(charArray& data); void handleComplexItemData(charArray& data);
std::shared_ptr<HoldingPlayer> getHoldingPlayer(
std::shared_ptr<Player> player);
// 4J Stu Added // 4J Stu Added
void mergeInMapData(std::shared_ptr<MapItemSavedData> dataToAdd); void mergeInMapData(std::shared_ptr<MapItemSavedData> dataToAdd);

View file

@ -45,7 +45,7 @@ McRegionChunkStorage::McRegionChunkStorage(ConsoleSaveFile* saveFile,
int count = dis.readInt(); int count = dis.readInt();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
__int64 index = dis.readLong(); int64_t index = dis.readLong();
CompoundTag* tag = NbtIo::read(&dis); CompoundTag* tag = NbtIo::read(&dis);
ByteArrayOutputStream bos; ByteArrayOutputStream bos;
@ -160,6 +160,14 @@ LevelChunk* McRegionChunkStorage::load(Level* level, int x, int z) {
#endif #endif
delete chunkData; delete chunkData;
} }
#ifndef _CONTENT_PACKAGE
if (levelChunk && app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableBiomeOverride)) {
// 4J Stu - This will force an update of the chunk's biome array
levelChunk->reloadBiomes();
}
#endif
return levelChunk; return levelChunk;
} }

View file

@ -30,7 +30,7 @@ ChunkStorage* McRegionLevelStorage::createChunkStorage(Dimension* dimension) {
std::vector<FileEntry*>* netherFiles = std::vector<FileEntry*>* netherFiles =
m_saveFile->getRegionFilesByDimension(1); m_saveFile->getRegionFilesByDimension(1);
if (netherFiles != NULL) { if (netherFiles != NULL) {
unsigned int bytesWritten = 0; DWORD bytesWritten = 0;
for (AUTO_VAR(it, netherFiles->begin()); for (AUTO_VAR(it, netherFiles->begin());
it != netherFiles->end(); ++it) { it != netherFiles->end(); ++it) {
m_saveFile->zeroFile(*it, (*it)->getFileSize(), m_saveFile->zeroFile(*it, (*it)->getFileSize(),
@ -99,4 +99,4 @@ void McRegionLevelStorage::saveLevelData(
MemSect(0); MemSect(0);
} }
void McRegionLevelStorage::closeAll() { RegionFileCache::clear(); } void McRegionLevelStorage::closeAll() { RegionFileCache::clear(); }

View file

@ -260,7 +260,8 @@ void OldChunkStorage::save(LevelChunk* lc, Level* level,
dos->writeShort(SAVE_FILE_VERSION_NUMBER); dos->writeShort(SAVE_FILE_VERSION_NUMBER);
dos->writeInt(lc->x); dos->writeInt(lc->x);
dos->writeInt(lc->z); dos->writeInt(lc->z);
dos->writeLong(level->getTime()); dos->writeLong(level->getGameTime());
dos->writeLong(lc->inhabitedTime);
PIXBeginNamedEvent(0, "Getting block data"); PIXBeginNamedEvent(0, "Getting block data");
lc->writeCompressedBlockData(dos); lc->writeCompressedBlockData(dos);
@ -333,7 +334,8 @@ void OldChunkStorage::save(LevelChunk* lc, Level* level, CompoundTag* tag) {
level->checkSession(); level->checkSession();
tag->putInt(L"xPos", lc->x); tag->putInt(L"xPos", lc->x);
tag->putInt(L"zPos", lc->z); tag->putInt(L"zPos", lc->z);
tag->putLong(L"LastUpdate", level->getTime()); tag->putLong(L"LastUpdate", level->getGameTime());
tag->putLong(L"InhabitedTime", lc->inhabitedTime);
// 4J - changes here for new storage. Now have static storage for getting // 4J - changes here for new storage. Now have static storage for getting
// lighting data for block, data, and sky & block lighting. This wasn't // lighting data for block, data, and sky & block lighting. This wasn't
// required in the original version as we could just reference the // required in the original version as we could just reference the
@ -414,6 +416,7 @@ void OldChunkStorage::save(LevelChunk* lc, Level* level, CompoundTag* tag) {
teTag->putInt(L"y", td.y); teTag->putInt(L"y", td.y);
teTag->putInt(L"z", td.z); teTag->putInt(L"z", td.z);
teTag->putInt(L"t", (int)(td.m_delay - levelTime)); teTag->putInt(L"t", (int)(td.m_delay - levelTime));
teTag->putInt(L"p", td.priorityTilt);
tickTags->add(teTag); tickTags->add(teTag);
} }
@ -453,6 +456,7 @@ void OldChunkStorage::loadEntities(LevelChunk* lc, Level* level,
} }
LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) { LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
PIXBeginNamedEvent(0, "Loading chunk");
short version = dis->readShort(); short version = dis->readShort();
int x = dis->readInt(); int x = dis->readInt();
int z = dis->readInt(); int z = dis->readInt();
@ -460,6 +464,10 @@ LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
LevelChunk* levelChunk = new LevelChunk(level, x, z); LevelChunk* levelChunk = new LevelChunk(level, x, z);
if (version >= SAVE_FILE_VERSION_CHUNK_INHABITED_TIME) {
levelChunk->inhabitedTime = dis->readLong();
}
levelChunk->readCompressedBlockData(dis); levelChunk->readCompressedBlockData(dis);
levelChunk->readCompressedDataData(dis); levelChunk->readCompressedDataData(dis);
levelChunk->readCompressedSkyLightData(dis); levelChunk->readCompressedSkyLightData(dis);
@ -479,13 +487,26 @@ LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
levelChunk->terrainPopulated |= LevelChunk::sTerrainPostPostProcessed; levelChunk->terrainPopulated |= LevelChunk::sTerrainPostPostProcessed;
} }
dis->readFully(levelChunk->biomes); #ifndef _CONTENT_PACKAGE
if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableBiomeOverride)) {
// Read the biome data from the stream, but don't use it
byteArray dummyBiomes(levelChunk->biomes.length);
dis->readFully(dummyBiomes);
delete[] dummyBiomes.data;
} else
#endif
{
dis->readFully(levelChunk->biomes);
}
CompoundTag* tag = NbtIo::read(dis); CompoundTag* tag = NbtIo::read(dis);
loadEntities(levelChunk, level, tag); loadEntities(levelChunk, level, tag);
if (tag->contains(L"TileTicks")) { if (tag->contains(L"TileTicks")) {
PIXBeginNamedEvent(0, "Loading TileTicks");
ListTag<CompoundTag>* tileTicks = ListTag<CompoundTag>* tileTicks =
(ListTag<CompoundTag>*)tag->getList(L"TileTicks"); (ListTag<CompoundTag>*)tag->getList(L"TileTicks");
@ -496,13 +517,16 @@ LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
level->forceAddTileTick( level->forceAddTileTick(
teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"x"), teTag->getInt(L"y"),
teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"z"), teTag->getInt(L"i"),
teTag->getInt(L"t")); teTag->getInt(L"t"), teTag->getInt(L"p"));
} }
} }
PIXEndNamedEvent();
} }
delete tag; delete tag;
PIXEndNamedEvent();
return levelChunk; return levelChunk;
} }
@ -536,8 +560,8 @@ LevelChunk* OldChunkStorage::load(Level* level, CompoundTag* tag) {
delete[] tag->getByteArray(L"BlockLight").data; delete[] tag->getByteArray(L"BlockLight").data;
// levelChunk->skyLight = new DataLayer(tag->getByteArray(L"SkyLight"), // levelChunk->skyLight = new DataLayer(tag->getByteArray(L"SkyLight"),
//level->depthBits); levelChunk->blockLight = new // level->depthBits); levelChunk->blockLight = new
//DataLayer(tag->getByteArray(L"BlockLight"), level->depthBits); // DataLayer(tag->getByteArray(L"BlockLight"), level->depthBits);
delete[] levelChunk->heightmap.data; delete[] levelChunk->heightmap.data;
levelChunk->heightmap = tag->getByteArray(L"HeightMap"); levelChunk->heightmap = tag->getByteArray(L"HeightMap");
@ -597,8 +621,17 @@ LevelChunk* OldChunkStorage::load(Level* level, CompoundTag* tag) {
} }
#endif #endif
if (tag->contains(L"Biomes")) { #ifndef _CONTENT_PACKAGE
levelChunk->setBiomes(tag->getByteArray(L"Biomes")); if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableBiomeOverride)) {
// Do nothing
} else
#endif
{
if (tag->contains(L"Biomes")) {
levelChunk->setBiomes(tag->getByteArray(L"Biomes"));
}
} }
loadEntities(levelChunk, level, tag); loadEntities(levelChunk, level, tag);
@ -614,7 +647,7 @@ LevelChunk* OldChunkStorage::load(Level* level, CompoundTag* tag) {
level->forceAddTileTick( level->forceAddTileTick(
teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"x"), teTag->getInt(L"y"),
teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"z"), teTag->getInt(L"i"),
teTag->getInt(L"t")); teTag->getInt(L"t"), teTag->getInt(L"p"));
} }
} }
} }

View file

@ -10,15 +10,13 @@ class Player;
class PlayerIO { class PlayerIO {
public: public:
virtual void save(std::shared_ptr<Player> player) = 0; virtual void save(std::shared_ptr<Player> player) = 0;
virtual bool load(std::shared_ptr<Player> virtual CompoundTag* load(std::shared_ptr<Player> player) = 0;
player) = 0; // 4J Changed return val to bool to
// check if new player or loaded player
virtual CompoundTag* loadPlayerDataTag( virtual CompoundTag* loadPlayerDataTag(
PlayerUID xuid) = 0; // 4J Changed from string name to xuid PlayerUID xuid) = 0; // 4J Changed from std::string name to xuid
// 4J Added // 4J Added
virtual void clearOldPlayerFiles() = 0; virtual void clearOldPlayerFiles() = 0;
virtual void saveMapIdLookup() = 0; virtual void saveMapIdLookup() = 0;
virtual void deleteMapFilesForPlayer(std::shared_ptr<Player> player) = 0; virtual void deleteMapFilesForPlayer(std::shared_ptr<Player> player) = 0;
virtual void saveAllCachedData() = 0; virtual void saveAllCachedData() = 0;
}; };

View file

@ -3,11 +3,28 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.dimension.h" #include "../../Headers/net.minecraft.world.level.dimension.h"
#include "../../../Minecraft.Client/Level/ServerLevel.h"
#include "PortalForcer.h" #include "PortalForcer.h"
PortalForcer::PortalForcer() { random = new Random(); } PortalForcer::PortalPosition::PortalPosition(int x, int y, int z, int64_t time)
: Pos(x, y, z) {
lastUsed = time;
}
void PortalForcer::force(Level* level, std::shared_ptr<Entity> e) { PortalForcer::PortalForcer(ServerLevel* level) {
this->level = level;
random = new Random(level->getSeed());
}
PortalForcer::~PortalForcer() {
for (AUTO_VAR(it, cachedPortals.begin()); it != cachedPortals.end(); ++it) {
delete it->second;
}
}
void PortalForcer::force(std::shared_ptr<Entity> e, double xOriginal,
double yOriginal, double zOriginal,
float yRotOriginal) {
if (level->dimension->id == 1) { if (level->dimension->id == 1) {
int x = Mth::floor(e->x); int x = Mth::floor(e->x);
int y = Mth::floor(e->y) - 1; int y = Mth::floor(e->y) - 1;
@ -24,7 +41,8 @@ void PortalForcer::force(Level* level, std::shared_ptr<Entity> e) {
bool border = h < 0; bool border = h < 0;
level->setTile(xt, yt, zt, border ? Tile::obsidian_Id : 0); level->setTileAndUpdate(xt, yt, zt,
border ? Tile::obsidian_Id : 0);
} }
} }
} }
@ -35,15 +53,17 @@ void PortalForcer::force(Level* level, std::shared_ptr<Entity> e) {
return; return;
} }
if (findPortal(level, e)) { if (findPortal(e, xOriginal, yOriginal, zOriginal, yRotOriginal)) {
return; return;
} }
createPortal(level, e); createPortal(e);
findPortal(level, e); findPortal(e, xOriginal, yOriginal, zOriginal, yRotOriginal);
} }
bool PortalForcer::findPortal(Level* level, std::shared_ptr<Entity> e) { bool PortalForcer::findPortal(std::shared_ptr<Entity> e, double xOriginal,
double yOriginal, double zOriginal,
float yRotOriginal) {
// 4J Stu - Decrease the range at which we search for a portal in the nether // 4J Stu - Decrease the range at which we search for a portal in the nether
// given our smaller nether // given our smaller nether
int r = 16; //* 8; int r = 16; //* 8;
@ -66,23 +86,39 @@ bool PortalForcer::findPortal(Level* level, std::shared_ptr<Entity> e) {
int xc = Mth::floor(e->x); int xc = Mth::floor(e->x);
int zc = Mth::floor(e->z); int zc = Mth::floor(e->z);
for (int x = xc - r; x <= xc + r; x++) { long hash = ChunkPos::hashCode(xc, zc);
double xd = (x + 0.5) - e->x; bool updateCache = true;
for (int z = zc - r; z <= zc + r; z++) {
double zd = (z + 0.5) - e->z;
for (int y = level->getHeight() - 1; y >= 0; y--) {
if (level->getTile(x, y, z) == Tile::portalTile_Id) {
while (level->getTile(x, y - 1, z) == Tile::portalTile_Id) {
y--;
}
double yd = (y + 0.5) - e->y; AUTO_VAR(it, cachedPortals.find(hash));
double dist = xd * xd + yd * yd + zd * zd; if (it != cachedPortals.end()) {
if (closest < 0 || dist < closest) { PortalPosition* pos = it->second;
closest = dist;
xTarget = x; closest = 0;
yTarget = y; xTarget = pos->x;
zTarget = z; yTarget = pos->y;
zTarget = pos->z;
pos->lastUsed = level->getGameTime();
updateCache = false;
} else {
for (int x = xc - r; x <= xc + r; x++) {
double xd = (x + 0.5) - e->x;
for (int z = zc - r; z <= zc + r; z++) {
double zd = (z + 0.5) - e->z;
for (int y = level->getHeight() - 1; y >= 0; y--) {
if (level->getTile(x, y, z) == Tile::portalTile_Id) {
while (level->getTile(x, y - 1, z) ==
Tile::portalTile_Id) {
y--;
}
double yd = (y + 0.5) - e->y;
double dist = xd * xd + yd * yd + zd * zd;
if (closest < 0 || dist < closest) {
closest = dist;
xTarget = x;
yTarget = y;
zTarget = z;
}
} }
} }
} }
@ -94,25 +130,115 @@ bool PortalForcer::findPortal(Level* level, std::shared_ptr<Entity> e) {
int y = yTarget; int y = yTarget;
int z = zTarget; int z = zTarget;
if (updateCache) {
cachedPortals[hash] =
new PortalPosition(x, y, z, level->getGameTime());
cachedPortalKeys.push_back(hash);
}
double xt = x + 0.5; double xt = x + 0.5;
double yt = y + 0.5; double yt = y + 0.5;
double zt = z + 0.5; double zt = z + 0.5;
int dir = Direction::UNDEFINED;
if (level->getTile(x - 1, y, z) == Tile::portalTile_Id) xt -= 0.5; if (level->getTile(x - 1, y, z) == Tile::portalTile_Id)
if (level->getTile(x + 1, y, z) == Tile::portalTile_Id) xt += 0.5; dir = Direction::NORTH;
if (level->getTile(x + 1, y, z) == Tile::portalTile_Id)
dir = Direction::SOUTH;
if (level->getTile(x, y, z - 1) == Tile::portalTile_Id)
dir = Direction::EAST;
if (level->getTile(x, y, z + 1) == Tile::portalTile_Id)
dir = Direction::WEST;
if (level->getTile(x, y, z - 1) == Tile::portalTile_Id) zt -= 0.5; int originalDir = e->getPortalEntranceDir();
if (level->getTile(x, y, z + 1) == Tile::portalTile_Id) zt += 0.5;
e->moveTo(xt, yt, zt, e->yRot, 0); if (dir > Direction::UNDEFINED) {
e->xd = e->yd = e->zd = 0; int leftDir = Direction::DIRECTION_COUNTER_CLOCKWISE[dir];
int forwardsx = Direction::STEP_X[dir];
int forwardsz = Direction::STEP_Z[dir];
int leftx = Direction::STEP_X[leftDir];
int leftz = Direction::STEP_Z[leftDir];
bool leftBlocked = !level->isEmptyTile(x + forwardsx + leftx, y,
z + forwardsz + leftz) ||
!level->isEmptyTile(x + forwardsx + leftx, y + 1,
z + forwardsz + leftz);
bool rightBlocked =
!level->isEmptyTile(x + forwardsx, y, z + forwardsz) ||
!level->isEmptyTile(x + forwardsx, y + 1, z + forwardsz);
if (leftBlocked && rightBlocked) {
dir = Direction::DIRECTION_OPPOSITE[dir];
leftDir = Direction::DIRECTION_OPPOSITE[leftDir];
forwardsx = Direction::STEP_X[dir];
forwardsz = Direction::STEP_Z[dir];
leftx = Direction::STEP_X[leftDir];
leftz = Direction::STEP_Z[leftDir];
x -= leftx;
xt -= leftx;
z -= leftz;
zt -= leftz;
leftBlocked = !level->isEmptyTile(x + forwardsx + leftx, y,
z + forwardsz + leftz) ||
!level->isEmptyTile(x + forwardsx + leftx, y + 1,
z + forwardsz + leftz);
rightBlocked =
!level->isEmptyTile(x + forwardsx, y, z + forwardsz) ||
!level->isEmptyTile(x + forwardsx, y + 1, z + forwardsz);
}
float offsetLeft = 0.5f;
float offsetForwards = 0.5f;
if (!leftBlocked && rightBlocked) {
offsetLeft = 1;
} else if (leftBlocked && !rightBlocked) {
offsetLeft = 0;
} else if (leftBlocked && rightBlocked) {
offsetForwards = 0;
}
// Center them in the frame and push them out forwards
xt += (leftx * offsetLeft) + (offsetForwards * forwardsx);
zt += (leftz * offsetLeft) + (offsetForwards * forwardsz);
float xx = 0;
float zz = 0;
float xz = 0;
float zx = 0;
if (dir == originalDir) {
xx = 1;
zz = 1;
} else if (dir == Direction::DIRECTION_OPPOSITE[originalDir]) {
xx = -1;
zz = -1;
} else if (dir == Direction::DIRECTION_CLOCKWISE[originalDir]) {
xz = 1;
zx = -1;
} else {
xz = -1;
zx = 1;
}
double xd = e->xd;
double zd = e->zd;
e->xd = xd * xx + zd * zx;
e->zd = xd * xz + zd * zz;
e->yRot = (yRotOriginal - originalDir * 90) + (dir * 90);
} else {
e->xd = e->yd = e->zd = 0;
}
e->moveTo(xt, yt, zt, e->yRot, e->xRot);
return true; return true;
} }
return false; return false;
} }
bool PortalForcer::createPortal(Level* level, std::shared_ptr<Entity> e) { bool PortalForcer::createPortal(std::shared_ptr<Entity> e) {
// 4J Stu - Increase the range at which we try and create a portal to stop // 4J Stu - Increase the range at which we try and create a portal to stop
// creating them floating in mid air over lava // creating them floating in mid air over lava
int r = 16 * 3; int r = 16 * 3;
@ -317,14 +443,14 @@ bool PortalForcer::createPortal(Level* level, std::shared_ptr<Entity> e) {
bool border = h < 0; bool border = h < 0;
level->setTile(xt, yt, zt, border ? Tile::obsidian_Id : 0); level->setTileAndUpdate(xt, yt, zt,
border ? Tile::obsidian_Id : 0);
} }
} }
} }
} }
for (int pass = 0; pass < 4; pass++) { for (int pass = 0; pass < 4; pass++) {
level->noNeighborUpdate = true;
for (int s = 0; s < 4; s++) { for (int s = 0; s < 4; s++) {
for (int h = -1; h < 4; h++) { for (int h = -1; h < 4; h++) {
int xt = x + (s - 1) * xa; int xt = x + (s - 1) * xa;
@ -332,12 +458,12 @@ bool PortalForcer::createPortal(Level* level, std::shared_ptr<Entity> e) {
int zt = z + (s - 1) * za; int zt = z + (s - 1) * za;
bool border = s == 0 || s == 3 || h == -1 || h == 3; bool border = s == 0 || s == 3 || h == -1 || h == 3;
level->setTile( level->setTileAndData(
xt, yt, zt, xt, yt, zt,
border ? Tile::obsidian_Id : Tile::portalTile_Id); border ? Tile::obsidian_Id : Tile::portalTile_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
level->noNeighborUpdate = false;
for (int s = 0; s < 4; s++) { for (int s = 0; s < 4; s++) {
for (int h = -1; h < 4; h++) { for (int h = -1; h < 4; h++) {
@ -353,3 +479,23 @@ bool PortalForcer::createPortal(Level* level, std::shared_ptr<Entity> e) {
return true; return true;
} }
void PortalForcer::tick(int64_t time) {
if (time % (SharedConstants::TICKS_PER_SECOND * 5) == 0) {
int64_t cutoff = time - SharedConstants::TICKS_PER_SECOND * 30;
for (AUTO_VAR(it, cachedPortalKeys.begin());
it != cachedPortalKeys.end();) {
int64_t key = *it;
PortalPosition* pos = cachedPortals[key];
if (pos == NULL || pos->lastUsed < cutoff) {
delete pos;
it = cachedPortalKeys.erase(it);
cachedPortals.erase(key);
} else {
++it;
}
}
}
}

View file

@ -3,18 +3,28 @@
class Random; class Random;
class PortalForcer { class PortalForcer {
public:
class PortalPosition : public Pos {
public:
int64_t lastUsed;
PortalPosition(int x, int y, int z, int64_t time);
};
private: private:
ServerLevel* level;
Random* random; Random* random;
std::unordered_map<int64_t, PortalPosition*> cachedPortals;
std::vector<int64_t> cachedPortalKeys;
public: public:
// 4J Stu Added - Java has no ctor, but we need to initialise random PortalForcer(ServerLevel* level);
PortalForcer(); ~PortalForcer();
void force(Level* level, std::shared_ptr<Entity> e); void force(std::shared_ptr<Entity> e, double xOriginal, double yOriginal,
double zOriginal, float yRotOriginal);
public: bool findPortal(std::shared_ptr<Entity> e, double xOriginal,
bool findPortal(Level* level, std::shared_ptr<Entity> e); double yOriginal, double zOriginal, float yRotOriginal);
bool createPortal(std::shared_ptr<Entity> e);
public: void tick(int64_t time);
bool createPortal(Level* level, std::shared_ptr<Entity> e);
}; };

View file

@ -3,6 +3,7 @@
#include "../../Headers/net.minecraft.world.level.chunk.h" #include "../../Headers/net.minecraft.world.level.chunk.h"
#include "../../Headers/net.minecraft.world.level.dimension.h" #include "../../Headers/net.minecraft.world.level.dimension.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.redstone.h"
#include "../../Blocks/Material.h" #include "../../Blocks/Material.h"
#include "../Level.h" #include "../Level.h"
@ -23,13 +24,14 @@ Region::~Region() {
} }
} }
Region::Region(Level* level, int x1, int y1, int z1, int x2, int y2, int z2) { Region::Region(Level* level, int x1, int y1, int z1, int x2, int y2, int z2,
int r) {
this->level = level; this->level = level;
xc1 = x1 >> 4; xc1 = (x1 - r) >> 4;
zc1 = z1 >> 4; zc1 = (z1 - r) >> 4;
int xc2 = x2 >> 4; int xc2 = (x2 + r) >> 4;
int zc2 = z2 >> 4; int zc2 = (z2 + r) >> 4;
chunks = new LevelChunk2DArray(xc2 - xc1 + 1, zc2 - zc1 + 1); chunks = new LevelChunk2DArray(xc2 - xc1 + 1, zc2 - zc1 + 1);
@ -40,7 +42,14 @@ Region::Region(Level* level, int x1, int y1, int z1, int x2, int y2, int z2) {
if (chunk != NULL) { if (chunk != NULL) {
LevelChunkArray* lca = (*chunks)[xc - xc1]; LevelChunkArray* lca = (*chunks)[xc - xc1];
lca->data[zc - zc1] = chunk; lca->data[zc - zc1] = chunk;
//(*chunks)[xc - xc1].data[zc - zc1] = level->getChunk(xc, zc); }
}
}
for (int xc = (x1 >> 4); xc <= (x2 >> 4); xc++) {
for (int zc = (z1 >> 4); zc <= (z2 >> 4); zc++) {
LevelChunkArray* lca = (*chunks)[xc - xc1];
LevelChunk* chunk = lca->data[zc - zc1];
if (chunk != NULL) {
if (!chunk->isYSpaceEmpty(y1, y2)) { if (!chunk->isYSpaceEmpty(y1, y2)) {
allEmpty = false; allEmpty = false;
} }
@ -246,18 +255,8 @@ bool Region::isSolidBlockingTile(int x, int y, int z) {
} }
bool Region::isTopSolidBlocking(int x, int y, int z) { bool Region::isTopSolidBlocking(int x, int y, int z) {
// Temporary workaround until tahgs per-face solidity is finished
Tile* tile = Tile::tiles[getTile(x, y, z)]; Tile* tile = Tile::tiles[getTile(x, y, z)];
if (tile == NULL) return false; return level->isTopSolidBlocking(tile, getData(x, y, z));
if (tile->material->isSolidBlocking() && tile->isCubeShaped()) return true;
if (dynamic_cast<StairTile*>(tile))
return (getData(x, y, z) & StairTile::UPSIDEDOWN_BIT) ==
StairTile::UPSIDEDOWN_BIT;
if (dynamic_cast<HalfSlabTile*>(tile))
return (getData(x, y, z) & HalfSlabTile::TOP_SLOT_BIT) ==
HalfSlabTile::TOP_SLOT_BIT;
return false;
} }
bool Region::isEmptyTile(int x, int y, int z) { bool Region::isEmptyTile(int x, int y, int z) {
@ -279,6 +278,9 @@ int Region::getBrightnessPropagate(LightLayer::variety layer, int x, int y,
// an int // an int
return (int)layer; return (int)layer;
} }
if (layer == LightLayer::Sky && level->dimension->hasCeiling) {
return 0;
}
int id = tileId > -1 ? tileId : getTile(x, y, z); int id = tileId > -1 ? tileId : getTile(x, y, z);
if (Tile::propagate[id]) { if (Tile::propagate[id]) {
@ -324,4 +326,10 @@ int Region::getBrightness(LightLayer::variety layer, int x, int y, int z) {
return (*chunks)[xc]->data[zc]->getBrightness(layer, x & 15, y, z & 15); return (*chunks)[xc]->data[zc]->getBrightness(layer, x & 15, y, z & 15);
} }
int Region::getMaxBuildHeight() { return Level::maxBuildHeight; } int Region::getMaxBuildHeight() { return Level::maxBuildHeight; }
int Region::getDirectSignal(int x, int y, int z, int dir) {
int t = getTile(x, y, z);
if (t == 0) return Redstone::SIGNAL_NONE;
return Tile::tiles[t]->getDirectSignal(this, x, y, z, dir);
}

View file

@ -18,7 +18,7 @@ private:
unsigned char* CachedTiles; unsigned char* CachedTiles;
public: public:
Region(Level* level, int x1, int y1, int z1, int x2, int y2, int z2); Region(Level* level, int x1, int y1, int z1, int x2, int y2, int z2, int r);
virtual ~Region(); virtual ~Region();
bool isAllEmpty(); bool isAllEmpty();
int getTile(int x, int y, int z); int getTile(int x, int y, int z);
@ -45,6 +45,7 @@ public:
int getBrightness(LightLayer::variety layer, int x, int y, int z); int getBrightness(LightLayer::variety layer, int x, int y, int z);
int getMaxBuildHeight(); int getMaxBuildHeight();
int getDirectSignal(int x, int y, int z, int dir);
LevelChunk* getLevelChunk(int x, int y, int z); LevelChunk* getLevelChunk(int x, int y, int z);

View file

@ -29,7 +29,7 @@ private:
int* chunkTimestamps; int* chunkTimestamps;
std::vector<bool>* sectorFree; std::vector<bool>* sectorFree;
int sizeDelta; int sizeDelta;
__int64 _lastModified; int64_t _lastModified;
bool m_bIsEmpty; // 4J added bool m_bIsEmpty; // 4J added
public: public:
@ -37,7 +37,7 @@ public:
~RegionFile(); ~RegionFile();
/* the modification date of the region file when it was first opened */ /* the modification date of the region file when it was first opened */
__int64 lastModified(); int64_t lastModified();
/* gets how much the region file has grown since it was last checked */ /* gets how much the region file has grown since it was last checked */
int getSizeDelta(); int getSizeDelta();

View file

@ -25,7 +25,7 @@ RegionFile* RegionFileCache::_getRegionFile(
// File regionDir(basePath, L"region"); // File regionDir(basePath, L"region");
// File file(regionDir, std::wstring(L"r.") + _toString(chunkX>>5) + L"." + // File file(regionDir, wstring(L"r.") + _toString(chunkX>>5) + L"." +
// _toString(chunkZ>>5) + L".mcr" ); // _toString(chunkZ>>5) + L".mcr" );
MemSect(31); MemSect(31);
File file; File file;
@ -109,3 +109,5 @@ DataOutputStream* RegionFileCache::_getChunkDataOutputStream(
return r->getChunkDataOutputStream(chunkX & 31, chunkZ & 31); return r->getChunkDataOutputStream(chunkX & 31, chunkZ & 31);
} }
} }
RegionFileCache::~RegionFileCache() { _clear(); }

View file

@ -17,6 +17,7 @@ public:
// Made public and non-static so we can have a cache for input and output // Made public and non-static so we can have a cache for input and output
// files // files
RegionFileCache() {} RegionFileCache() {}
~RegionFileCache();
RegionFile* _getRegionFile(ConsoleSaveFile* saveFile, RegionFile* _getRegionFile(ConsoleSaveFile* saveFile,
const std::wstring& prefix, int chunkX, const std::wstring& prefix, int chunkX,

View file

@ -10,9 +10,9 @@
SavedDataStorage::SavedDataStorage(LevelStorage* levelStorage) { SavedDataStorage::SavedDataStorage(LevelStorage* levelStorage) {
/* /*
cache = new std::unordered_map<std::wstring, std::shared_ptr<SavedData> >; cache = new unordered_map<wstring, shared_ptr<SavedData> >;
savedDatas = new std::vector<std::shared_ptr<SavedData> >; savedDatas = new vector<shared_ptr<SavedData> >;
usedAuxIds = new std::unordered_map<std::wstring, short*>; usedAuxIds = new unordered_map<wstring, short*>;
*/ */
this->levelStorage = levelStorage; this->levelStorage = levelStorage;
@ -31,7 +31,8 @@ std::shared_ptr<SavedData> SavedDataStorage::get(const std::type_info& clazz,
if (!file.getName().empty() && if (!file.getName().empty() &&
levelStorage->getSaveFile()->doesFileExist(file)) { levelStorage->getSaveFile()->doesFileExist(file)) {
// mob = std::dynamic_pointer_cast<Mob>(Mob::_class->newInstance( // mob = std::dynamic_pointer_cast<Mob>(Mob::_class->newInstance(
// level )); // level
// ));
// data = clazz.getConstructor(String.class).newInstance(id); // data = clazz.getConstructor(String.class).newInstance(id);
if (clazz == typeid(MapItemSavedData)) { if (clazz == typeid(MapItemSavedData)) {
@ -41,6 +42,10 @@ std::shared_ptr<SavedData> SavedDataStorage::get(const std::type_info& clazz,
} else if (clazz == typeid(Villages)) { } else if (clazz == typeid(Villages)) {
data = std::dynamic_pointer_cast<SavedData>( data = std::dynamic_pointer_cast<SavedData>(
std::shared_ptr<Villages>(new Villages(id))); std::shared_ptr<Villages>(new Villages(id)));
} else if (clazz == typeid(StructureFeatureSavedData)) {
data = std::dynamic_pointer_cast<SavedData>(
std::shared_ptr<StructureFeatureSavedData>(
new StructureFeatureSavedData(id)));
} else { } else {
// Handling of new SavedData class required // Handling of new SavedData class required
__debugbreak(); __debugbreak();

View file

@ -3,7 +3,7 @@
#include "ZoneIO.h" #include "ZoneIO.h"
namespace { namespace {
bool SeekFile(std::FILE* file, __int64 offset) { bool SeekFile(std::FILE* file, int64_t offset) {
#if defined(_WIN32) #if defined(_WIN32)
return _fseeki64(file, offset, SEEK_SET) == 0; return _fseeki64(file, offset, SEEK_SET) == 0;
#else #else
@ -12,7 +12,7 @@ bool SeekFile(std::FILE* file, __int64 offset) {
} }
} // namespace } // namespace
ZoneIo::ZoneIo(std::FILE* channel, __int64 pos) { ZoneIo::ZoneIo(std::FILE* channel, int64_t pos) {
this->channel = channel; this->channel = channel;
this->pos = pos; this->pos = pos;
} }

View file

@ -8,10 +8,10 @@ class ByteBuffer;
class ZoneIo { class ZoneIo {
private: private:
std::FILE* channel; std::FILE* channel;
__int64 pos; int64_t pos;
public: public:
ZoneIo(std::FILE* channel, __int64 pos); ZoneIo(std::FILE* channel, int64_t pos);
void write(byteArray bb, int size); void write(byteArray bb, int size);
void write(ByteBuffer* bb, int size); void write(ByteBuffer* bb, int size);
ByteBuffer* read(int size); ByteBuffer* read(int size);

View file

@ -52,7 +52,7 @@ ZoneFile* ZonedChunkStorage::getZoneFile(int x, int z, bool create) {
int xZone = x >> CHUNKS_PER_ZONE_BITS; int xZone = x >> CHUNKS_PER_ZONE_BITS;
int zZone = z >> CHUNKS_PER_ZONE_BITS; int zZone = z >> CHUNKS_PER_ZONE_BITS;
__int64 key = xZone + (zZone << 20l); int64_t key = xZone + (zZone << 20l);
// 4J - was !zoneFiles.containsKey(key) // 4J - was !zoneFiles.containsKey(key)
if (zoneFiles.find(key) == zoneFiles.end()) { if (zoneFiles.find(key) == zoneFiles.end()) {
wchar_t xRadix36[64]; wchar_t xRadix36[64];
@ -108,8 +108,8 @@ LevelChunk* ZonedChunkStorage::load(Level* level, int x, int z) {
header->flip(); header->flip();
int xOrg = header->getInt(); int xOrg = header->getInt();
int zOrg = header->getInt(); int zOrg = header->getInt();
__int64 time = header->getLong(); int64_t time = header->getLong();
__int64 flags = header->getLong(); int64_t flags = header->getLong();
lc->terrainPopulated = (flags & BIT_TERRAIN_POPULATED) != 0; lc->terrainPopulated = (flags & BIT_TERRAIN_POPULATED) != 0;
@ -120,7 +120,7 @@ LevelChunk* ZonedChunkStorage::load(Level* level, int x, int z) {
} }
void ZonedChunkStorage::save(Level* level, LevelChunk* lc) { void ZonedChunkStorage::save(Level* level, LevelChunk* lc) {
__int64 flags = 0; int64_t flags = 0;
if (lc->terrainPopulated) flags |= BIT_TERRAIN_POPULATED; if (lc->terrainPopulated) flags |= BIT_TERRAIN_POPULATED;
ByteBuffer* header = ByteBuffer::allocate(CHUNK_HEADER_SIZE); ByteBuffer* header = ByteBuffer::allocate(CHUNK_HEADER_SIZE);
@ -144,10 +144,10 @@ void ZonedChunkStorage::save(Level* level, LevelChunk* lc) {
void ZonedChunkStorage::tick() { void ZonedChunkStorage::tick() {
tickCount++; tickCount++;
if (tickCount % (20 * 10) == 4) { if (tickCount % (20 * 10) == 4) {
std::vector<__int64> toClose; std::vector<int64_t> toClose;
AUTO_VAR(itEndZF, zoneFiles.end()); AUTO_VAR(itEndZF, zoneFiles.end());
for (std::unordered_map<__int64, ZoneFile*>::iterator it = for (std::unordered_map<int64_t, ZoneFile*>::iterator it =
zoneFiles.begin(); zoneFiles.begin();
it != itEndZF; it++) { it != itEndZF; it++) {
ZoneFile* zoneFile = it->second; ZoneFile* zoneFile = it->second;
@ -158,7 +158,7 @@ void ZonedChunkStorage::tick() {
AUTO_VAR(itEndTC, toClose.end()); AUTO_VAR(itEndTC, toClose.end());
for (AUTO_VAR(it, toClose.begin()); it != itEndTC; it++) { for (AUTO_VAR(it, toClose.begin()); it != itEndTC; it++) {
__int64 key = *it; // toClose[i]; int64_t key = *it; // toClose[i];
// 4J - removed try/catch // 4J - removed try/catch
// try { // try {
char buf[256]; char buf[256];
@ -175,7 +175,7 @@ void ZonedChunkStorage::tick() {
void ZonedChunkStorage::flush() { void ZonedChunkStorage::flush() {
AUTO_VAR(itEnd, zoneFiles.end()); AUTO_VAR(itEnd, zoneFiles.end());
for (std::unordered_map<__int64, ZoneFile*>::iterator it = for (std::unordered_map<int64_t, ZoneFile*>::iterator it =
zoneFiles.begin(); zoneFiles.begin();
it != itEnd; it++) { it != itEnd; it++) {
ZoneFile* zoneFile = it->second; ZoneFile* zoneFile = it->second;

View file

@ -28,8 +28,8 @@ public:
File dir; File dir;
private: private:
std::unordered_map<__int64, ZoneFile*> zoneFiles; std::unordered_map<int64_t, ZoneFile*> zoneFiles;
__int64 tickCount; int64_t tickCount;
public: public:
ZonedChunkStorage(File dir); ZonedChunkStorage(File dir);

View file

@ -1,8 +1,8 @@
#include "../Platform/stdafx.h" #include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "TickNextTickData.h" #include "TickNextTickData.h"
__int64 TickNextTickData::C = 0; int64_t TickNextTickData::C = 0;
TickNextTickData::TickNextTickData(int x, int y, int z, int tileId) { TickNextTickData::TickNextTickData(int x, int y, int z, int tileId) {
m_delay = 0; m_delay = 0;
@ -12,38 +12,47 @@ TickNextTickData::TickNextTickData(int x, int y, int z, int tileId) {
this->y = y; this->y = y;
this->z = z; this->z = z;
this->tileId = tileId; this->tileId = tileId;
priorityTilt = 0;
} }
bool TickNextTickData::equals(const void* o) const { bool TickNextTickData::equals(const TickNextTickData* o) const {
// TODO 4J Is this safe to cast it before we do a dynamic_cast? Will the // TODO 4J Is this safe to cast it before we do a dynamic_cast? Will the
// dynamic_cast still fail? We cannot dynamic_cast a void* // dynamic_cast still fail? We cannot dynamic_cast a void*
if (dynamic_cast<TickNextTickData*>((TickNextTickData*)o) != NULL) { if (o != NULL) {
TickNextTickData* t = (TickNextTickData*)o; TickNextTickData* t = (TickNextTickData*)o;
return x == t->x && y == t->y && z == t->z && tileId == t->tileId; return x == t->x && y == t->y && z == t->z &&
Tile::isMatching(tileId, t->tileId);
} }
return false; return false;
} }
int TickNextTickData::hashCode() const { int TickNextTickData::hashCode() const {
// 4jcraft added cast to unsigned return (((x * 1024 * 1024) + (z * 1024) + y) * 256);
return ((((unsigned)x * 1024 * 1024) + ((unsigned)z * 1024) + (unsigned)y) *
256) +
tileId;
} }
TickNextTickData* TickNextTickData::delay(__int64 l) { TickNextTickData* TickNextTickData::delay(int64_t l) {
this->m_delay = l; m_delay = l;
return this; return this;
} }
void TickNextTickData::setPriorityTilt(int priorityTilt) {
this->priorityTilt = priorityTilt;
}
int TickNextTickData::compareTo(const TickNextTickData* tnd) const { int TickNextTickData::compareTo(const TickNextTickData* tnd) const {
if (m_delay < tnd->m_delay) return -1; if (m_delay < tnd->m_delay) return -1;
if (m_delay > tnd->m_delay) return 1; if (m_delay > tnd->m_delay) return 1;
if (priorityTilt != tnd->priorityTilt)
return priorityTilt - tnd->priorityTilt;
if (c < tnd->c) return -1; if (c < tnd->c) return -1;
if (c > tnd->c) return 1; if (c > tnd->c) return 1;
return 0; return 0;
} }
bool TickNextTickData::operator==(const TickNextTickData& k) {
return equals(&k);
}
// A class that takes two arguments of the same type as the container elements // A class that takes two arguments of the same type as the container elements
// and returns a bool. The expression comp(a,b), where comp is an object of this // and returns a bool. The expression comp(a,b), where comp is an object of this
// comparison class and a and b are elements of the container, shall return true // comparison class and a and b are elements of the container, shall return true
@ -62,6 +71,5 @@ int TickNextTickData::hash_fnct(const TickNextTickData& k) {
bool TickNextTickData::eq_test(const TickNextTickData& x, bool TickNextTickData::eq_test(const TickNextTickData& x,
const TickNextTickData& y) { const TickNextTickData& y) {
return (x.x == y.x) && (x.y == y.y) && (x.z == y.z) && return x.equals(&y);
(x.tileId == y.tileId); }
}

View file

@ -6,27 +6,30 @@
class TickNextTickData { class TickNextTickData {
private: private:
static __int64 C; static int64_t C;
public: public:
int x, y, z, tileId; int x, y, z, tileId;
__int64 m_delay; int64_t m_delay;
int priorityTilt;
private: private:
__int64 c; int64_t c;
public: public:
TickNextTickData(int x, int y, int z, int tileId); TickNextTickData(int x, int y, int z, int tileId);
bool equals(const void* o) const; bool equals(const TickNextTickData* o) const;
int hashCode() const; int hashCode() const;
TickNextTickData* delay(__int64 l); TickNextTickData* delay(int64_t l);
void setPriorityTilt(int priorityTilt);
int compareTo(const TickNextTickData* tnd) const; int compareTo(const TickNextTickData* tnd) const;
static bool compare_fnct(const TickNextTickData& x, static bool compare_fnct(const TickNextTickData& x,
const TickNextTickData& y); const TickNextTickData& y);
static int hash_fnct(const TickNextTickData& k); static int hash_fnct(const TickNextTickData& k);
static bool eq_test(const TickNextTickData& x, const TickNextTickData& y); static bool eq_test(const TickNextTickData& x, const TickNextTickData& y);
bool operator==(const TickNextTickData& k);
}; };
struct TickNextTickDataKeyHash { struct TickNextTickDataKeyHash {

View file

@ -67,6 +67,8 @@ void WaterLevelChunk::load() {}
void WaterLevelChunk::unload(bool unloadTileEntities) // 4J - added parameter void WaterLevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
{} {}
bool WaterLevelChunk::containsPlayer() { return false; }
void WaterLevelChunk::markUnsaved() {} void WaterLevelChunk::markUnsaved() {}
void WaterLevelChunk::getEntities(std::shared_ptr<Entity> except, AABB bb, void WaterLevelChunk::getEntities(std::shared_ptr<Entity> except, AABB bb,
@ -104,7 +106,7 @@ bool WaterLevelChunk::testSetBlocksAndData(byteArray data, int x0, int y0,
return false; return false;
} }
Random* WaterLevelChunk::getRandom(__int64 l) { Random* WaterLevelChunk::getRandom(int64_t l) {
return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 + return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 +
z * z * 4392871l + z * 389711) ^ z * z * 4392871l + z * 389711) ^
l); l);

View file

@ -36,6 +36,7 @@ public:
void removeTileEntity(int x, int y, int z); void removeTileEntity(int x, int y, int z);
void load(); void load();
void unload(bool unloadTileEntities); // 4J - added parameter void unload(bool unloadTileEntities); // 4J - added parameter
bool containsPlayer(); // 4J added
void markUnsaved(); void markUnsaved();
void getEntities(std::shared_ptr<Entity> except, AABB bb, void getEntities(std::shared_ptr<Entity> except, AABB bb,
std::vector<std::shared_ptr<Entity> >& es); std::vector<std::shared_ptr<Entity> >& es);
@ -49,7 +50,7 @@ public:
bool includeLighting = true); // 4J - added includeLighting parameter; bool includeLighting = true); // 4J - added includeLighting parameter;
bool testSetBlocksAndData(byteArray data, int x0, int y0, int z0, int x1, bool testSetBlocksAndData(byteArray data, int x0, int y0, int z0, int x1,
int y1, int z1, int p); int y1, int z1, int p);
Random* getRandom(__int64 l); Random* getRandom(int64_t l);
virtual Biome* getBiome(int x, int z, BiomeSource* biomeSource); virtual Biome* getBiome(int x, int z, BiomeSource* biomeSource);
virtual void reSyncLighting() {}; // 4J added virtual void reSyncLighting() {}; // 4J added
}; };