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) {}
__int64 ChunkPos::hashCode(int x, int z) {
__int64 xx = x;
__int64 zz = z;
int64_t ChunkPos::hashCode(int x, int z) {
int64_t xx = x;
int64_t zz = z;
return (xx & 0xffffffffl) | ((zz & 0xffffffffl) << 32l);
}
int ChunkPos::hashCode() {
__int64 hash = hashCode(x, z);
int64_t hash = hashCode(x, z);
int h1 = (int)(hash);
int h2 = (int)(hash >> 32l);
return h1 ^ h2;
@ -49,7 +49,7 @@ std::wstring ChunkPos::toString() {
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) {
return x.x == y.x && x.z == y.z;

View file

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

View file

@ -8,6 +8,12 @@ class TilePos;
#ifdef _LARGE_WORLDS
// 4J Stu - Our default map (at zoom level 3) is 1024x1024 blocks (or 64 chunks)
#define LEVEL_MAX_WIDTH (5 * 64) //(6*54)
#define LEVEL_WIDTH_CLASSIC 54
#define LEVEL_WIDTH_SMALL 64
#define LEVEL_WIDTH_MEDIUM (3 * 64)
#define LEVEL_WIDTH_LARGE (5 * 64)
#else
#define LEVEL_MAX_WIDTH 54
#endif
@ -19,6 +25,12 @@ class TilePos;
// overworld
#ifdef _LARGE_WORLDS
#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
#define HELL_LEVEL_MAX_SCALE 3
#endif
@ -39,6 +51,11 @@ class ChunkSource {
public:
// 4J Added so that we can store the maximum dimensions of this world
int m_XZSize;
#ifdef _LARGE_WORLDS
bool m_classicEdgeMoat;
bool m_smallEdgeMoat;
bool m_mediumEdgeMoat;
#endif
public:
virtual ~ChunkSource() {}
@ -69,4 +86,12 @@ public:
virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName,
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 "../Util/PortableFileIO.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.biome.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.tile.h"
#include "../Headers/net.minecraft.world.level.storage.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "CustomLevelSource.h"
const double CustomLevelSource::SNOW_SCALE = 0.3;
const double CustomLevelSource::SNOW_CUTOFF = 0.5;
CustomLevelSource::CustomLevelSource(Level* level, __int64 seed,
CustomLevelSource::CustomLevelSource(Level* level, int64_t seed,
bool generateStructures)
: generateStructures(generateStructures) {
#ifdef _OVERRIDE_HEIGHTMAP
@ -21,55 +21,86 @@ CustomLevelSource::CustomLevelSource(Level* level, __int64 seed,
m_heightmapOverride = byteArray((m_XZSize * 16) * (m_XZSize * 16));
#ifdef _WINDOWS64
const std::wstring path = L"GameRules\\heightmap.bin";
#ifdef _UNICODE
std::wstring path = L"GAME:\\GameRules\\heightmap.bin";
#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
const PortableFileIO::BinaryReadResult heightmapReadResult =
PortableFileIO::ReadBinaryFile(path, m_heightmapOverride.data,
m_heightmapOverride.length);
if (heightmapReadResult.status ==
PortableFileIO::BinaryReadStatus::not_found) {
#endif
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
app.FatalLoadError();
DWORD error = GetLastError();
assert(false);
} else if (heightmapReadResult.status ==
PortableFileIO::BinaryReadStatus::too_large) {
app.DebugPrintf("Heightmap binary is too large!!\n");
__debugbreak();
} else if (heightmapReadResult.status !=
PortableFileIO::BinaryReadStatus::ok) {
app.FatalLoadError();
} else {
#ifdef _DURANGO
__debugbreak(); // TODO
DWORD bytesRead, dwFileSize = 0;
#else
DWORD bytesRead, dwFileSize = GetFileSize(file, NULL);
#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));
#ifdef _WINDOWS64
const std::wstring waterHeightPath = L"GameRules\\waterheight.bin";
#ifdef _UNICODE
std::wstring waterHeightPath = L"GAME:\\GameRules\\waterheight.bin";
#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
const PortableFileIO::BinaryReadResult waterHeightReadResult =
PortableFileIO::ReadBinaryFile(waterHeightPath,
m_waterheightOverride.data,
m_waterheightOverride.length);
if (waterHeightReadResult.status ==
PortableFileIO::BinaryReadStatus::not_found) {
#endif
file = CreateFile(waterHeightPath.c_str(), GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
// assert(false);
memset(m_waterheightOverride.data, level->seaLevel,
m_waterheightOverride.length);
} else if (waterHeightReadResult.status ==
PortableFileIO::BinaryReadStatus::too_large) {
app.DebugPrintf("waterheight binary is too large!!\n");
__debugbreak();
} else if (waterHeightReadResult.status !=
PortableFileIO::BinaryReadStatus::ok) {
app.FatalLoadError();
} else {
#ifdef _DURANGO
__debugbreak(); // TODO
DWORD bytesRead, dwFileSize = 0;
#else
DWORD bytesRead, dwFileSize = GetFileSize(file, NULL);
#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();
strongholdFeature = new StrongholdFeature();
villageFeature = new VillageFeature(0, m_XZSize);
villageFeature = new VillageFeature(m_XZSize);
mineShaftFeature = new MineShaftFeature();
scatteredFeature = new RandomScatteredLargeFeature();
canyonFeature = new CanyonFeature();
this->level = level;
@ -90,6 +121,8 @@ CustomLevelSource::~CustomLevelSource() {
delete mineShaftFeature;
delete canyonFeature;
this->level = level;
delete random;
delete perlinNoise3;
#endif
@ -169,9 +202,9 @@ void CustomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
// 4J - this comparison used to just be with 0.0f
// but is now varied by block above
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) {
tileId = (std::uint8_t)Tile::calmWater_Id;
tileId = (uint8_t)Tile::calmWater_Id;
}
// 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
if (yc * CHUNK_HEIGHT + y <=
(level->getSeaLevel() - 10))
tileId = Tile::rock_Id;
tileId = Tile::stone_Id;
else if (yc * CHUNK_HEIGHT + y <
level->getSeaLevel())
tileId = Tile::calmWater_Id;
@ -245,8 +278,8 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
int run = -1;
std::uint8_t top = b->topMaterial;
std::uint8_t material = b->material;
uint8_t top = b->topMaterial;
uint8_t material = b->material;
LevelGenerationOptions* lgo = app.getLevelGenerationOptions();
if (lgo != NULL) {
@ -270,17 +303,17 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
// if (y <= 0 +
// random->nextInt(5))
{
blocks[offs] = (std::uint8_t)Tile::unbreakable_Id;
blocks[offs] = (uint8_t)Tile::unbreakable_Id;
} else {
int old = blocks[offs];
if (old == 0) {
run = -1;
} else if (old == Tile::rock_Id) {
} else if (old == Tile::stone_Id) {
if (run == -1) {
if (runDepth <= 0) {
top = 0;
material = (std::uint8_t)Tile::rock_Id;
material = (uint8_t)Tile::stone_Id;
} else if (y >= waterHeight - 4 &&
y <= waterHeight + 1) {
top = b->topMaterial;
@ -292,9 +325,9 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
if (y < waterHeight && top == 0) {
if (temp < 0.15f)
top = (std::uint8_t)Tile::ice_Id;
top = (uint8_t)Tile::ice_Id;
else
top = (std::uint8_t)Tile::calmWater_Id;
top = (uint8_t)Tile::calmWater_Id;
}
run = runDepth;
@ -310,7 +343,7 @@ void CustomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
// runs
if (run == 0 && material == Tile::sand_Id) {
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
// management so that it will get cleanly freed
int blocksSize = Level::maxBuildHeight * 16 * 16;
std::uint8_t* tileData = (std::uint8_t*)XPhysicalAlloc(
blocksSize, MAXULONG_PTR, 4096, PAGE_READWRITE);
uint8_t* tileData = (uint8_t*)XPhysicalAlloc(blocksSize, MAXULONG_PTR, 4096,
PAGE_READWRITE);
XMemSet128(tileData, 0, blocksSize);
byteArray blocks = byteArray(tileData, blocksSize);
// 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);
villageFeature->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);
// townFeature.apply(this, level, xOffs, zOffs, blocks);
@ -451,19 +485,21 @@ void CustomLevelSource::calcWaterDepths(ChunkSource* parent, int xt, int zt) {
int od =
level->getData(xp + x2, y, zp + z2);
if (od < 7 && od < d) {
level->setData(xp + x2, y, zp + z2,
d);
level->setData(
xp + x2, y, zp + z2, d,
Tile::UPDATE_CLIENTS);
}
}
}
}
}
if (hadWater) {
level->setTileAndDataNoUpdate(
xp, y, zp, Tile::calmWater_Id, 7);
level->setTileAndData(xp, y, zp, Tile::calmWater_Id,
7, Tile::UPDATE_CLIENTS);
for (int y2 = 0; y2 < y; y2++) {
level->setTileAndDataNoUpdate(
xp, y2, zp, Tile::calmWater_Id, 8);
level->setTileAndData(xp, y2, zp,
Tile::calmWater_Id, 8,
Tile::UPDATE_CLIENTS);
}
}
}
@ -489,8 +525,8 @@ void CustomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
}
pprandom->setSeed(level->getSeed());
__int64 xScale = pprandom->nextLong() / 2 * 2 + 1;
__int64 zScale = pprandom->nextLong() / 2 * 2 + 1;
int64_t xScale = pprandom->nextLong() / 2 * 2 + 1;
int64_t zScale = pprandom->nextLong() / 2 * 2 + 1;
pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed());
bool hasVillage = false;
@ -500,6 +536,7 @@ void CustomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
mineShaftFeature->postProcess(level, pprandom, xt, zt);
hasVillage = villageFeature->postProcess(level, pprandom, xt, zt);
strongholdFeature->postProcess(level, pprandom, xt, zt);
scatteredFeature->postProcess(level, random, xt, zt);
}
PIXEndNamedEvent();
@ -562,14 +599,16 @@ void CustomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int y = level->getTopRainBlock(xo + x, zo + z);
if (level->shouldFreezeIgnoreNeighbors(x + xo, y - 1, z + zo)) {
level->setTileNoUpdate(
x + xo, y - 1, z + zo,
Tile::ice_Id); // 4J - changed from setTile, otherwise we
// end up creating a *lot* of dynamic water
// tiles as these ice tiles are set
level->setTileAndData(
x + xo, y - 1, z + zo, Tile::ice_Id, 0,
Tile::UPDATE_INVISIBLE); // 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)) {
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) {
return NULL;
}
if (mobCategory == MobCategory::monster &&
scatteredFeature->isSwamphut(x, y, z)) {
return scatteredFeature->getSwamphutEnemies();
}
return biome->getMobs(mobCategory);
#else
return NULL;
@ -610,3 +653,15 @@ TilePos* CustomLevelSource::findNearestMapFeature(
#endif
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 VillageFeature;
class MineShaftFeature;
class RandomScatteredLargeFeature;
class CustomLevelSource : public ChunkSource {
public:
@ -29,6 +30,7 @@ private:
StrongholdFeature* strongholdFeature;
VillageFeature* villageFeature;
MineShaftFeature* mineShaftFeature;
RandomScatteredLargeFeature* scatteredFeature;
LargeFeature* canyonFeature;
Level* level;
#endif
@ -40,7 +42,7 @@ private:
const bool generateStructures;
public:
CustomLevelSource(Level* level, __int64 seed, bool generateStructures);
CustomLevelSource(Level* level, int64_t seed, bool generateStructures);
~CustomLevelSource();
public:
@ -76,4 +78,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName,
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);
}
__int64 DerivedLevelData::getSeed() { return wrapped->getSeed(); }
int64_t DerivedLevelData::getSeed() { return wrapped->getSeed(); }
int DerivedLevelData::getXSpawn() { return wrapped->getXSpawn(); }
@ -25,9 +25,11 @@ int DerivedLevelData::getYSpawn() { return wrapped->getYSpawn(); }
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() {
return wrapped->getLoadedPlayerTag();
@ -39,7 +41,7 @@ std::wstring DerivedLevelData::getLevelName() {
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(); }
@ -51,7 +53,7 @@ int DerivedLevelData::getRainTime() { return wrapped->getRainTime(); }
GameType* DerivedLevelData::getGameType() { return wrapped->getGameType(); }
void DerivedLevelData::setSeed(__int64 seed) {}
void DerivedLevelData::setSeed(int64_t seed) {}
void DerivedLevelData::setXSpawn(int xSpawn) {}
@ -59,9 +61,11 @@ void DerivedLevelData::setYSpawn(int ySpawn) {}
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) {}
@ -103,6 +107,8 @@ bool DerivedLevelData::isInitialized() { return wrapped->isInitialized(); }
void DerivedLevelData::setInitialized(bool initialized) {}
GameRules* DerivedLevelData::getGameRules() { return wrapped->getGameRules(); }
int DerivedLevelData::getXZSize() { return wrapped->getXZSize(); }
int DerivedLevelData::getHellScale() { return wrapped->getHellScale(); }

View file

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

View file

@ -1,4 +1,5 @@
#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.h"
#include "../../Headers/net.minecraft.world.level.storage.h"
@ -13,9 +14,13 @@
#include "../../../Minecraft.Client/Minecraft.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) {
this->level = level;
this->levelType = level->getLevelData()->getGenerator();
levelType = level->getLevelData()->getGenerator();
levelTypeOptions = level->getLevelData()->getGeneratorOptions();
init();
updateLightRamp();
}
@ -35,12 +40,16 @@ void Dimension::init() {
// file
if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableHeightWaterBiomeOverride)) {
(1L << eDebugSetting_EnableBiomeOverride)) {
biomeSource = new BiomeSource(level);
} else
#endif
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 {
biomeSource = new BiomeSource(level);
}
@ -51,6 +60,7 @@ Dimension::Dimension() {
hasCeiling = false;
brightnessRamp = new float[Level::MAX_BRIGHTNESS + 1];
id = 0;
levelTypeOptions = L"";
}
Dimension::~Dimension() {
@ -65,7 +75,7 @@ ChunkSource* Dimension::createRandomLevelSource() const {
// file
if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableHeightWaterBiomeOverride)) {
(1L << eDebugSetting_EnableHeightWaterOverride)) {
return new CustomLevelSource(
level, level->getSeed(),
level->getLevelData()->isGenerateMapFeatures());
@ -99,7 +109,7 @@ bool Dimension::isValidSpawn(int x, int z) const {
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);
float td = (dayStep + a) / Level::TICKS_PER_DAY - 0.25f;
if (td < 0) td += 1;
@ -110,7 +120,7 @@ float Dimension::getTimeOfDay(__int64 time, float a) const {
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;
}

View file

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

View file

@ -56,7 +56,7 @@ bool HellDimension::isNaturalDimension() { 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; }

View file

@ -13,7 +13,7 @@ public:
virtual ChunkSource* createRandomLevelSource() const;
virtual bool isNaturalDimension();
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 isFoggyAt(int x, int z);

View file

@ -14,7 +14,7 @@ ChunkSource* SkyIslandDimension::createRandomLevelSource() const {
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;
}

View file

@ -17,7 +17,7 @@ ChunkSource* TheEndDimension::createRandomLevelSource() const {
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;
}

View file

@ -5,7 +5,7 @@ class TheEndDimension : public Dimension {
public:
virtual void init();
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 Vec3* getFogColor(float td, float a) const;
virtual bool hasGround();

View file

@ -102,14 +102,17 @@ void EmptyLevelChunk::load() {}
void EmptyLevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
{}
bool EmptyLevelChunk::containsPlayer() { return false; }
void EmptyLevelChunk::markUnsaved() {}
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(
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; }
@ -157,7 +160,7 @@ bool EmptyLevelChunk::testSetBlocksAndData(byteArray data, int x0, int y0,
return false;
}
Random* EmptyLevelChunk::getRandom(__int64 l) {
Random* EmptyLevelChunk::getRandom(int64_t l) {
return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 +
z * z * 4392871l + z * 389711) ^
l);

View file

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

View file

@ -33,6 +33,7 @@ public:
static const int PARTICLES_POTION_SPLASH = 2002;
static const int PARTICLES_EYE_OF_ENDER_DEATH = 2003;
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
// enderdragon was killed

View file

@ -15,16 +15,17 @@ public:
virtual void allChanged() = 0;
// virtual void playSound(const std::wstring& name, double x, double y,
// double z, float volume, float pitch) = 0;
// virtual void playSound(const wstring& name, double x, double y, double z,
// float volume, float pitch) = 0;
virtual void playSound(int iSound, double x, double y, double z,
float volume, float pitch,
float fSoundClipDist = 16.0f) = 0;
virtual void playSound(std::shared_ptr<Entity> entity, int iSound, double x,
double y, double z, float volume, float pitch,
float fSoundClipDist = 16.0f) = 0;
virtual void playSoundExceptPlayer(std::shared_ptr<Player> player,
int iSound, double x, double y, double z,
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;
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,
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,
int y, int z, int data) = 0;

View file

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

View file

@ -1,5 +1,7 @@
#include "../Platform/stdafx.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.tile.h"
#include "../Headers/net.minecraft.world.phys.h"
@ -64,12 +66,18 @@ void Explosion::explode() {
int zt = Mth::floor(zp);
int t = level->getTile(xt, yt, zt);
if (t > 0) {
remainingPower -=
(Tile::tiles[t]->getExplosionResistance(source) +
0.3f) *
stepSize;
Tile* tile = Tile::tiles[t];
float resistance =
source != NULL
? 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));
}
@ -141,17 +149,19 @@ void Explosion::explode() {
double sp = level->getSeenPercent(center, e->bb);
double pow = (1 - dist) * sp;
if (canDamage)
e->hurt(DamageSource::explosion,
e->hurt(DamageSource::explosion(this),
(int)((pow * pow + pow) / 2 * 8 * r + 1));
double push = pow;
e->xd += xa * push;
e->yd += ya * push;
e->zd += za * push;
double kbPower =
ProtectionEnchantment::getExplosionKnockbackAfterDampener(e,
pow);
e->xd += xa * kbPower;
e->yd += ya * kbPower;
e->zd += za * kbPower;
std::shared_ptr<Player> player =
std::dynamic_pointer_cast<Player>(e);
if (player != NULL) {
if (e->instanceof(eTYPE_PLAYER)) {
std::shared_ptr<Player> player =
std::dynamic_pointer_cast<Player>(e);
// app.DebugPrintf("Adding player knockback (%f,%f,%f)\n", xa *
// pow, ya * pow, za * pow);
hitPlayers.insert(playerVec3Map::value_type(
@ -171,72 +181,84 @@ void Explosion::finalizeExplosion(
x, y, z, eSoundType_RANDOM_EXPLODE, 4,
(1 + (level->random->nextFloat() - level->random->nextFloat()) * 0.2f) *
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
// to speed up calling this from an incoming packet
std::vector<TilePos>* toBlowArray =
toBlowDirect ? toBlowDirect
: new std::vector<TilePos>(toBlow.begin(), toBlow.end());
// toBlowArray.addAll(toBlow);
// TODO 4J Stu - Reverse iterator
PIXBeginNamedEvent(0, "Finalizing explosion size %d", toBlow.size());
app.DebugPrintf("Finalizing explosion size %d\n", toBlow.size());
static const int MAX_EXPLODE_PARTICLES = 50;
// 4J - try and make at most MAX_EXPLODE_PARTICLES pairs of particles
int fraction = (int)toBlowArray->size() / MAX_EXPLODE_PARTICLES;
if (fraction == 0) fraction = 1;
size_t j = toBlowArray->size() - 1;
// for (size_t j = toBlowArray->size() - 1; j >= 0; j--)
for (AUTO_VAR(it, toBlowArray->rbegin()); it != toBlowArray->rend(); ++it) {
TilePos* tp = &(*it); //&toBlowArray->at(j);
int xt = tp->x;
int yt = tp->y;
int zt = tp->z;
// if (xt >= 0 && yt >= 0 && zt >= 0 && xt < width && yt < depth &&
// zt < height) {
int t = level->getTile(xt, yt, zt);
if (destroyBlocks) {
// toBlowArray.addAll(toBlow);
// TODO 4J Stu - Reverse iterator
PIXBeginNamedEvent(0, "Finalizing explosion size %d", toBlow.size());
app.DebugPrintf("Finalizing explosion size %d\n", toBlow.size());
static const int MAX_EXPLODE_PARTICLES = 50;
// 4J - try and make at most MAX_EXPLODE_PARTICLES pairs of particles
int fraction = (int)toBlowArray->size() / MAX_EXPLODE_PARTICLES;
if (fraction == 0) fraction = 1;
size_t j = toBlowArray->size() - 1;
// for (size_t j = toBlowArray->size() - 1; j >= 0; j--)
for (AUTO_VAR(it, toBlowArray->rbegin()); it != toBlowArray->rend();
++it) {
TilePos* tp = &(*it); //&toBlowArray->at(j);
int xt = tp->x;
int yt = tp->y;
int zt = tp->z;
// if (xt >= 0 && yt >= 0 && zt >= 0 && xt < width && yt < depth &&
// zt < height) {
int t = level->getTile(xt, yt, zt);
if (generateParticles) {
if ((j % fraction) == 0) {
double xa = xt + level->random->nextFloat();
double ya = yt + level->random->nextFloat();
double za = zt + level->random->nextFloat();
if (generateParticles) {
if ((j % fraction) == 0) {
double xa = xt + level->random->nextFloat();
double ya = yt + level->random->nextFloat();
double za = zt + level->random->nextFloat();
double xd = xa - x;
double yd = ya - y;
double zd = za - z;
double xd = xa - x;
double yd = ya - y;
double zd = za - z;
double dd = sqrt(xd * xd + yd * yd + zd * zd);
double dd = sqrt(xd * xd + yd * yd + zd * zd);
xd /= dd;
yd /= dd;
zd /= dd;
xd /= dd;
yd /= dd;
zd /= dd;
double speed = 0.5 / (dd / r + 0.1);
speed *=
(level->random->nextFloat() * level->random->nextFloat() +
0.3f);
xd *= speed;
yd *= speed;
zd *= speed;
double speed = 0.5 / (dd / r + 0.1);
speed *= (level->random->nextFloat() *
level->random->nextFloat() +
0.3f);
xd *= speed;
yd *= speed;
zd *= speed;
level->addParticle(eParticleType_explode, (xa + x * 1) / 2,
(ya + y * 1) / 2, (za + z * 1) / 2, xd, yd,
zd);
level->addParticle(eParticleType_smoke, xa, ya, za, xd, yd, zd);
level->addParticle(eParticleType_explode, (xa + x * 1) / 2,
(ya + y * 1) / 2, (za + z * 1) / 2, xd,
yd, zd);
level->addParticle(eParticleType_smoke, xa, ya, za, xd, yd,
zd);
}
}
}
if (t > 0) {
Tile::tiles[t]->spawnResources(level, xt, yt, zt,
level->getData(xt, yt, zt), 0.3f, 0);
level->setTile(xt, yt, zt, 0);
Tile::tiles[t]->wasExploded(level, xt, yt, zt);
}
// }
if (t > 0) {
Tile* tile = Tile::tiles[t];
--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) {
@ -250,7 +272,7 @@ void Explosion::finalizeExplosion(
int t = level->getTile(xt, yt, zt);
int b = level->getTile(xt, yt - 1, zt);
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);
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
playerVec3Map* getHitPlayers();
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 Villages;
class VillageSiege;
class Tickable;
class Minecart;
class EntitySelector;
class Scoreboard;
class GameRules;
class Level : public LevelSource {
public:
@ -138,11 +143,10 @@ public:
protected:
float oRainLevel, rainLevel;
float oThunderLevel, thunderLevel;
int lightningTime;
public:
int lightningBoltTime;
bool noNeighborUpdate;
int skyFlashTime;
int difficulty;
Random* random;
bool isNew;
@ -168,6 +172,13 @@ public:
std::shared_ptr<Villages> villages;
VillageSiege* villageSiege;
private:
// 4J - Calendar is now static
// Calendar *calendar;
protected:
Scoreboard* scoreboard;
public:
Biome* getBiome(int x, int z); // 4J - brought forward from 1.2.3
virtual BiomeSource* getBiomeSource();
@ -183,7 +194,6 @@ public:
Level(std::shared_ptr<LevelStorage> levelStorage, const std::wstring& name,
Dimension* dimension, LevelSettings* levelSettings,
bool doCreateChunkSource = true);
Level(Level* level, Dimension* dimension);
Level(std::shared_ptr<LevelStorage> levelStorage,
const std::wstring& levelName, LevelSettings* levelSettings);
Level(std::shared_ptr<LevelStorage> levelStorage,
@ -209,6 +219,8 @@ public:
bool isEmptyTile(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 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 hasChunksAt(int x, int y, int z, int r);
bool hasChunksAt(int x0, int y0, int z0, int x1, int y1, int z1);
@ -224,40 +236,34 @@ public:
public:
LevelChunk* getChunkAt(int x, int z);
LevelChunk* getChunk(int x, int z);
virtual bool setTileAndDataNoUpdate(int x, int y, int z, int tile,
int data);
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
virtual bool setTileAndData(int x, int y, int z, int tile, int data,
int updateFlags);
Material* getMaterial(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,
bool forceUpdate = false); // 4J added forceUpdate
virtual bool setDataNoUpdate(int x, int y, int z, int data);
bool setTile(int x, int y, int z, int tile);
bool setTileAndData(int x, int y, int z, int tile, int data);
void sendTileUpdated(int x, int y, int z);
virtual bool setData(int x, int y, int z, int data, int updateFlags,
bool forceUpdate = false); // 4J added forceUpdate
virtual bool removeTile(int x, int y, int z);
virtual bool destroyTile(int x, int y, int z, bool dropResources);
virtual bool setTileAndUpdate(int x, int y, int z, int tile);
virtual void sendTileUpdated(int x, int y, int z);
public:
virtual void tileUpdated(int x, int y, int z, int tile);
void lightColumnChanged(int x, int z, int y0, int y1);
void setTileDirty(int x, int y, int z);
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);
private:
void updateNeighborsAtExceptFromFacing(int x, int y, int z, int tile,
int skipFacing);
void neighborChanged(int x, int y, int z, int type);
public:
virtual bool isTileToBeTickedAt(int x, int y, int z, int tileId);
bool canSeeSky(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, bool propagate);
bool isSkyLit(int x, int y, 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,
int expected);
int getBrightnessPropagate(LightLayer::variety layer, int x, int y, int z,
@ -272,11 +278,11 @@ public:
int z, int brightness); // 4J added
#ifdef _LARGE_WORLDS
typedef __uint64 lightCache_t;
typedef uint64_t lightCache_t;
#else
typedef unsigned int lightCache_t;
#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,
int z, int brightness);
inline int getBrightnessCached(lightCache_t* cache,
@ -286,8 +292,9 @@ public:
int z);
inline int getBlockingCached(lightCache_t* cache, LightLayer::variety layer,
int* ct, int x, int y, int z);
void initCache(lightCache_t* cache);
void flushCache(lightCache_t* cache, __uint64 cacheUse,
void initCachePartial(lightCache_t* cache, int xc, int yc, int zc);
void initCacheComplete(lightCache_t* cache, int xc, int yc, int zc);
void flushCache(lightCache_t* cache, uint64_t cacheUse,
LightLayer::variety layer);
bool cachewritten;
@ -295,10 +302,10 @@ public:
static const int BLOCKING_SHIFT = 20;
static const int EMISSION_SHIFT = 16;
#ifdef _LARGE_WORLDS
static const __int64 LIGHTING_WRITEBACK = 0x80000000LL;
static const __int64 EMISSION_VALID = 0x40000000LL;
static const __int64 BLOCKING_VALID = 0x20000000LL;
static const __int64 LIGHTING_VALID = 0x10000000LL;
static const int64_t LIGHTING_WRITEBACK = 0x80000000LL;
static const int64_t EMISSION_VALID = 0x40000000LL;
static const int64_t BLOCKING_VALID = 0x20000000LL;
static const int64_t LIGHTING_VALID = 0x10000000LL;
static const lightCache_t POSITION_MASK = 0xffffffff0000ffffLL;
#else
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, bool solidOnly);
virtual void playSound(std::shared_ptr<Entity> entity, int iSound,
float volume, float pitch);
virtual void playEntitySound(std::shared_ptr<Entity> entity, int iSound,
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,
float volume, float pitch,
float fClipSoundDist = 16.0f);
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);
void playStreamingMusic(const std::wstring& name, int x, int y, int z);
void playMusic(double x, double y, double z, const std::wstring& string,
float volume);
void playMusic(double x, double y, double z,
const std::wstring& std::string, float volume);
// 4J removed - void addParticle(const std::wstring& id, double x, double y,
// double z, double xd, double yd, double zd);
void addParticle(ePARTICLE_TYPE id, double x, double y, double z, double xd,
@ -358,17 +367,16 @@ public:
AABBList* getCubes(
std::shared_ptr<Entity> source, AABB* box, bool noEntities = false,
bool blockAtEdge =
false); // 4J - added noEntities & blockAtEdge parameters
false); // 4J: Added noEntities & blockAtEdge parameters
AABBList* getTileCubes(
AABB* box,
bool blockAtEdge); // 4J Stu - Brought forward from 12w36 to fix #46282
// - TU5: Gameplay: Exiting the minecart in a tight
// corridor damages the player
AABB* box, bool blockAtEdge =
false); // 4J: Added noEntities & blockAtEdge parameters
int getOldSkyDarken(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);
float getTimeOfDay(float a);
int getMoonPhase(float a);
int getMoonPhase();
float getMoonBrightness();
float getSunAngle(float a);
Vec3* getCloudColor(float a);
Vec3* getFogColor(float a);
@ -380,8 +388,10 @@ public:
float getStarBrightness(float a);
virtual void addToTickNextTick(int x, int y, int z, int tileId,
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,
int tickDelay);
int tickDelay, int prioTilt);
virtual void tickEntities();
void addAllPendingTileEntities(
std::vector<std::shared_ptr<TileEntity> >& entities);
@ -420,8 +430,10 @@ public:
virtual bool isSolidBlockingTile(int x, int y, int z);
bool isSolidBlockingTileInLoadedChunk(int x, int y, int z,
bool valueIfNotLoaded);
bool isFullAABBTile(int x, int y, int z);
virtual bool isTopSolidBlocking(int x, int y,
int z); // 4J - brought forward from 1.3.2
bool isTopSolidBlocking(Tile* tile, int data);
protected:
bool spawnEnemies;
@ -477,11 +489,9 @@ public:
false); // 4J added force, rootOnlySource parameters
private:
int* toCheckLevel;
int getExpectedSkyColor(lightCache_t* cache, int oc, int x, int y, int z,
int ct, int block);
int getExpectedBlockColor(lightCache_t* cache, int oc, int x, int y, int z,
int ct, int block,
bool propagatedOnly); // 4J added parameter
int getExpectedLight(lightCache_t* cache, int x, int y, int z,
LightLayer::variety layer, bool propagatedOnly);
public:
void checkLight(LightLayer::variety layer, int xc, int yc, int zc,
bool force = false,
@ -501,11 +511,18 @@ public:
std::vector<std::shared_ptr<Entity> >* getEntities(
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(
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(
const std::type_info& baseClass, AABB* bb,
std::shared_ptr<Entity> source);
virtual std::shared_ptr<Entity> getEntity(int entityId) = 0;
std::vector<std::shared_ptr<Entity> > getAllEntities();
void tileEntityChanged(int x, int y, int z, std::shared_ptr<TileEntity> te);
// unsigned int countInstanceOf(BaseObject::Class *clas);
@ -518,7 +535,8 @@ public:
void addEntities(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,
int face, std::shared_ptr<Entity> ignoreEntity);
int face, std::shared_ptr<Entity> ignoreEntity,
std::shared_ptr<ItemInstance> item);
int getSeaLevel();
Path* findPath(std::shared_ptr<Entity> from, std::shared_ptr<Entity> to,
float maxDist, bool canPassDoors, bool canOpenDoors,
@ -526,10 +544,12 @@ public:
Path* findPath(std::shared_ptr<Entity> from, int xBest, int yBest,
int zBest, float maxDist, bool canPassDoors,
bool canOpenDoors, bool avoidWater, bool canFloat);
bool getDirectSignal(int x, int y, int z, int dir);
bool hasDirectSignal(int x, int y, int z);
bool getSignal(int x, int y, int z, int dir);
int getDirectSignal(int x, int y, int z, int dir);
int getDirectSignalTo(int x, int y, int z);
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);
int getBestNeighborSignal(int x, int y, int z);
// 4J Added maxYDist param
std::shared_ptr<Player> getNearestPlayer(std::shared_ptr<Entity> source,
double maxDist,
@ -554,12 +574,11 @@ public:
byteArray data, bool includeLighting = true);
virtual void disconnect(bool sendDisconnect = true);
void checkSession();
void setTime(__int64 time);
void setOverrideTimeOfDay(
__int64 time); // 4J Added so we can override timeOfDay without
// changing tick time
__int64 getSeed();
__int64 getTime();
void setGameTime(int64_t time);
int64_t getSeed();
int64_t getGameTime();
int64_t getDayTime();
void setDayTime(int64_t newTime);
Pos* getSharedSpawnPos();
void setSpawnPos(int x, int y, int z);
void setSpawnPos(Pos* spawnPos);
@ -571,6 +590,7 @@ public:
virtual void tileEvent(int x, int y, int z, int tile, int b0, int b1);
LevelStorage* getLevelStorage();
LevelData* getLevelData();
GameRules* getGameRules();
virtual void updateSleepingPlayerList();
bool useNewSeaLevel(); // 4J added
bool getHasBeenInCreative(); // 4J Added
@ -588,16 +608,26 @@ public:
std::shared_ptr<SavedData> getSavedData(const std::type_info& clazz,
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(std::shared_ptr<Player> source, int type, int x, int y,
int z, int data);
int getMaxBuildHeight();
int getHeight();
virtual Tickable* makeSoundUpdater(std::shared_ptr<Minecart> minecart);
Random* getRandomFor(int x, int z, int blend);
bool updateLights();
virtual bool isAllEmpty();
double getHorizonHeight();
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,
int y, int z);
@ -605,10 +635,6 @@ public:
int getAuxValueForMap(PlayerUID xuid, int dimension, int centreXC,
int centreZC, int scale);
// 4J added
__int64 m_timeOfDayOverride;
// 4J - optimisation - keep direct reference of underlying cache here
LevelChunk** chunkSourceCache;
int chunkSourceXZSize;
@ -642,6 +668,7 @@ public:
enum ESPAWN_TYPE {
eSpawnType_Egg,
eSpawnType_Breed,
eSpawnType_Portal,
};
bool canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType);

View file

@ -11,10 +11,13 @@
#include "Storage/SparseLightStorage.h"
#include "BlockReplacements.h"
#include "LevelChunk.h"
#include "../Util/BasicTypeContainers.h"
#include "../../Minecraft.Client/MinecraftServer.h"
#include "../../Minecraft.Client/Level/ServerLevel.h"
#include "../../Minecraft.Client/Network/ServerChunkCache.h"
#include "../../Minecraft.Client/Rendering/GameRenderer.h"
#include "../Entities/ItemEntity.h"
#include "../Entities/Mobs/Minecart.h"
#ifdef __PS3__
#include "../../Minecraft.Client/Platform/PS3/PS3Extras/C4JSpursJob.h"
@ -97,6 +100,9 @@ void LevelChunk::init(Level* level, int x, int z) {
MemSect(0);
lowestHeightmap = 256;
inhabitedTime = 0;
// Optimisation brought forward from 1.8.2, change from int to unsigned char
// & this special value changed from -999 to 255
for (int i = 0; i < 16 * 16; i++) {
@ -398,7 +404,7 @@ void LevelChunk::startSharingTilesAndData(int forceMs) {
} else {
// Only force if it has been more than forceMs milliseconds since we
// last wanted to unshare this chunk
__int64 timenow = System::currentTimeMillis();
int64_t timenow = System::currentTimeMillis();
if ((timenow - lastUnsharedTime) < forceMs) {
LeaveCriticalSection(&m_csSharing);
return;
@ -462,7 +468,7 @@ LevelChunk::~LevelChunk() {
bool LevelChunk::isAt(int x, int z) { return x == this->x && z == this->z; }
int LevelChunk::getHeightmap(int x, int z) {
return heightmap[(unsigned)z << 4 | x] & 0xff;
return heightmap[z << 4 | x] & 0xff;
}
int LevelChunk::getHighestSectionPosition() {
@ -555,6 +561,7 @@ void LevelChunk::recalcHeightmap() {
byteArray blockData = byteArray(Level::CHUNK_TILE_COUNT);
getBlockData(blockData);
#endif
lowestHeightmap = Integer::MAX_VALUE;
int min = Level::maxBuildHeight - 1;
for (int x = 0; x < 16; x++)
@ -607,6 +614,7 @@ void LevelChunk::recalcHeightmap() {
#endif
heightmap[(unsigned)z << 4 | x] = (uint8_t)y;
if (y < min) min = y;
if (y < lowestHeightmap) lowestHeightmap = y;
if (!level->dimension->hasCeiling) {
int br = Level::MAX_BRIGHTNESS;
@ -934,6 +942,7 @@ void LevelChunk::recalcHeight(int x, int yStart, int z) {
y1 = y2;
y2 = tmp;
}
if (height < lowestHeightmap) lowestHeightmap = height;
if (!level->dimension->hasCeiling) {
PIXBeginNamedEvent(0, "Light gaps");
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 oldData = data->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z);
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 zOffs = this->z * 16 + z;
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,
z, 0);
// 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()) {
std::shared_ptr<TileEntity> te = getTileEntity(x, y, z);
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
// type %d\n", level->isClientSide?"Client":"Server", _tile,
// 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
// Vita mate
// else if (old > 0 && dynamic_cast<EntityTile *>(Tile::tiles[old]) !=
//NULL)
// NULL)
else if (old > 0 && Tile::tiles[_tile] != NULL &&
Tile::tiles[_tile]->isEntityTile()) {
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) {
if (layer == LightLayer::Sky) {
if (level->dimension->hasCeiling) {
return 0;
}
SparseLightStorage* skyLight =
y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT ? upperSkyLight
: lowerSkyLight;
@ -1229,7 +1252,7 @@ int LevelChunk::getRawBrightness(int x, int y, int z, int skyDampen) {
level->dimension->hasCeiling
? 0
: skyLight->get(x, y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT, z);
if (light > 0) LevelChunk::touchedSky = true;
if (light > 0) touchedSky = true;
light -= skyDampen;
SparseLightStorage* blockLight = y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT
? 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
// insert when we don't want one)
// std::shared_ptr<TileEntity> tileEntity = tileEntities[pos];
// shared_ptr<TileEntity> tileEntity = tileEntities[pos];
EnterCriticalSection(&m_csTileEntities);
std::shared_ptr<TileEntity> tileEntity = nullptr;
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)
//{
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);
//}
@ -1425,6 +1449,8 @@ void LevelChunk::setTileEntity(int x, int y, int z,
"tile!\n");
return;
}
AUTO_VAR(it, tileEntities.find(pos));
if (it != tileEntities.end()) it->second->setRemoved();
tileEntity->clearRemoved();
@ -1471,10 +1497,11 @@ void LevelChunk::load() {
if (entityTags != NULL) {
for (int i = 0; i < entityTags->size(); i++) {
CompoundTag* teTag = entityTags->get(i);
std::shared_ptr<Entity> te =
std::shared_ptr<Entity> ent =
EntityIO::loadStatic(teTag, level);
if (te != NULL) {
addEntity(te);
if (ent != NULL) {
ent->onLoadedFromSave();
addEntity(ent);
}
}
}
@ -1612,6 +1639,33 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
#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
bool LevelChunk::isUnloaded() { return m_bUnloaded; }
#endif
@ -1619,7 +1673,8 @@ bool LevelChunk::isUnloaded() { return m_bUnloaded; }
void LevelChunk::markUnsaved() { this->setUnsaved(true); }
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 yc1 = Mth::floor((bb->y1 + 2) / 16);
if (yc0 < 0) yc0 = 0;
@ -1636,14 +1691,16 @@ void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb,
AUTO_VAR(itEnd, entities->end());
for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) {
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);
std::vector<std::shared_ptr<Entity> >* subs =
e->getSubEntities();
if (subs != NULL) {
for (int j = 0; j < subs->size(); 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);
}
}
@ -1657,7 +1714,8 @@ void LevelChunk::getEntities(std::shared_ptr<Entity> except, 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 yc1 = Mth::floor((bb->y1 + 2) / 16);
@ -1687,25 +1745,30 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb,
bool isAssignableFrom = false;
// Some special cases where the base class is a general type that
// our class may be derived from, otherwise do a direct comparison
// of std::type_info
if (ec == typeid(Player)) {
if (std::dynamic_pointer_cast<Player>(e) != NULL)
isAssignableFrom = true;
} else if (ec == typeid(Mob)) {
if (std::dynamic_pointer_cast<Mob>(e) != NULL)
isAssignableFrom = true;
} else if (ec == typeid(Monster)) {
if (std::dynamic_pointer_cast<Monster>(e) != NULL)
isAssignableFrom = true;
} else if (ec == typeid(Zombie)) {
if (std::dynamic_pointer_cast<Zombie>(e) != NULL)
isAssignableFrom = true;
} else {
Entity* entityPtr = e.get();
if (entityPtr != NULL && ec == typeid(*entityPtr))
isAssignableFrom = true;
// of type_info
if (ec == typeid(Player))
isAssignableFrom = e->instanceof(eTYPE_PLAYER);
else if (ec == typeid(Entity))
isAssignableFrom = e->instanceof(eTYPE_ENTITY);
else if (ec == typeid(Mob))
isAssignableFrom = e->instanceof(eTYPE_MOB);
else if (ec == typeid(LivingEntity))
isAssignableFrom = e->instanceof(eTYPE_LIVINGENTITY);
else if (ec == typeid(ItemEntity))
isAssignableFrom = e->instanceof(eTYPE_ITEMENTITY);
else if (ec == typeid(Minecart))
isAssignableFrom = e->instanceof(eTYPE_MINECART);
else if (ec == typeid(Monster))
isAssignableFrom = e->instanceof(eTYPE_MONSTER);
else if (ec == typeid(Zombie))
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
// baseClass.isAssignableFrom(e.getClass())
}
@ -1736,10 +1799,13 @@ int LevelChunk::countEntities() {
bool LevelChunk::shouldSave(bool force) {
if (dontSave) return false;
if (force) {
if (lastSaveHadEntities && level->getTime() != lastSaveTime)
if ((lastSaveHadEntities && level->getGameTime() != lastSaveTime) ||
m_unsaved) {
return true;
}
} else {
if (lastSaveHadEntities && level->getTime() >= lastSaveTime + 20 * 30)
if (lastSaveHadEntities &&
level->getGameTime() >= lastSaveTime + 20 * 30)
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++)
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0)
>> 1; int len = (y1 - y0) / 2; System::arraycopy(blockLight->data, slot, data,
p, len); p += len;
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
1; int len = (y1 - y0) / 2; System::arraycopy(blockLight->data, slot, data,
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++)
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0)
>> 1; int len = (y1 - y0) / 2; System::arraycopy(skyLight->data, slot, data, p,
len); p += len;
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
1; int len = (y1 - y0) / 2; System::arraycopy(skyLight->data, slot, data, p,
len); p += len;
}
*/
*/
return p;
}
@ -1890,13 +1956,13 @@ int LevelChunk::setBlocksAndData(byteArray data, int x0, int y0, int z0, int x1,
includeLighting ? NULL : tileUpdatedCallback, this,
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++)
{
int slot = x << level->depthBitsPlusFour | z << level->depthBits | y0;
int len = y1 - y0;
System::arraycopy(data, p, &blocks, slot, len);
p += len;
{
int slot = x << level->depthBitsPlusFour | z << level->depthBits | y0;
int len = y1 - y0;
System::arraycopy(data, p, &blocks, slot, len);
p += len;
}*/
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++)
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0)
>> 1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &blockLight->data,
slot, len); p += len;
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &blockLight->data,
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++)
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0)
>> 1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &skyLight->data, slot,
len); p += len;
{
int slot = (x << level->depthBitsPlusFour | z << level->depthBits | y0) >>
1; int len = (y1 - y0) / 2; System::arraycopy(data, p, &skyLight->data,
slot, len); p += len;
}
*/
*/
for (AUTO_VAR(it, tileEntities.begin()); it != tileEntities.end(); ++it) {
it->second->clearCache();
@ -1991,7 +2057,7 @@ len); p += len;
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 +
z * z * 4392871l + z * 389711) ^
l);
@ -2001,15 +2067,15 @@ bool LevelChunk::isEmpty() { return false; }
void LevelChunk::attemptCompression() {
// 4J - removed
#if 0
try {
ByteArrayOutputStream *baos = new ByteArrayOutputStream();
GZIPOutputStream *gzos = new GZIPOutputStream(baos);
DataOutputStream *dos = new DataOutputStream(gzos);
dos.close();
System.out.println("Compressed size: " + baos.toByteArray().length);
} catch (Exception e) {
try {
ByteArrayOutputStream *baos = new ByteArrayOutputStream();
GZIPOutputStream *gzos = new GZIPOutputStream(baos);
DataOutputStream *dos = new DataOutputStream(gzos);
dos.close();
System.out.println("Compressed size: " + baos.toByteArray().length);
} catch (Exception e) {
}
}
#endif
}
@ -2074,20 +2140,32 @@ bool LevelChunk::isYSpaceEmpty(int y1, int y2) {
return false;
// 4J Unused
/*if (y1 < 0) {
y1 = 0;
y1 = 0;
}
if (y2 >= Level.maxBuildHeight) {
y2 = Level.maxBuildHeight - 1;
y2 = Level.maxBuildHeight - 1;
}
for (int y = y1; y <= y2; y += 16) {
LevelChunkSection section = sections[y >> 4];
if (section != null && !section.isEmpty()) {
return false;
}
LevelChunkSection section = sections[y >> 4];
if (section != null && !section.isEmpty()) {
return false;
}
}
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) {
int value = biomes[((unsigned)z << 4) | x] & 0xff;
if (value == 0xff) {
@ -2422,9 +2500,13 @@ int LevelChunk::getBlocksAllocatedSize(int* count0, int* count1, int* count2,
int LevelChunk::getHighestNonEmptyY() {
int highestNonEmptyY = -1;
if (upperBlocks)
highestNonEmptyY = upperBlocks->getHighestNonEmptyY() +
Level::COMPRESSED_CHUNK_SECTION_HEIGHT;
if (upperBlocks) {
int upperNonEmpty = upperBlocks->getHighestNonEmptyY();
if (upperNonEmpty >= 0) {
highestNonEmptyY =
upperNonEmpty + Level::COMPRESSED_CHUNK_SECTION_HEIGHT;
}
}
if (highestNonEmptyY < 0)
highestNonEmptyY = lowerBlocks->getHighestNonEmptyY();
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;
//// 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,
// Level::HALF_CHUNK_TILE_COUNT); lc->getDataData(dataData); offset +=
// 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);
//// 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
// ) && ( ( z & 15 ) == 0 ) )
//{

View file

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

View file

@ -24,6 +24,9 @@ LevelData::LevelData(CompoundTag* tag) {
m_pGenerator =
m_pGenerator->getReplacementForVersion(generatorVersion);
}
if (tag->contains(L"generatorOptions"))
generatorOptions = tag->getString(L"generatorOptions");
}
gameType = GameType::byId(tag->getInt(L"GameType"));
@ -37,7 +40,12 @@ LevelData::LevelData(CompoundTag* tag) {
xSpawn = tag->getInt(L"SpawnX");
ySpawn = tag->getInt(L"SpawnY");
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");
sizeOnDisk = tag->getLong(L"SizeOnDisk");
levelName = tag->getString(L"LevelName");
@ -60,6 +68,12 @@ LevelData::LevelData(CompoundTag* tag) {
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(
L"newSeaLevel"); // 4J added - only use new sea level for newly created
// maps. This read defaults to false. (sea level
@ -95,6 +109,37 @@ LevelData::LevelData(CompoundTag* tag) {
m_xzSize = tag->getInt(L"XZSize");
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::max(m_xzSize, LEVEL_MIN_WIDTH);
@ -108,15 +153,38 @@ LevelData::LevelData(CompoundTag* tag) {
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
if (tag->contains(L"Player"))
if (tag->contains(L"Player"))
{
loadedPlayerTag = tag->getCompound(L"Player");
dimension = loadedPlayerTag->getInt(L"Dimension");
}
}
else
{
this->loadedPlayerTag = NULL;
this->loadedPlayerTag = NULL;
}
*/
dimension = 0;
@ -124,46 +192,48 @@ if (tag->contains(L"Player"))
LevelData::LevelData(LevelSettings* levelSettings,
const std::wstring& levelName) {
this->seed = levelSettings->getSeed();
this->gameType = levelSettings->getGameType();
this->generateMapFeatures = levelSettings->isGenerateMapFeatures();
this->spawnBonusChest = levelSettings->hasStartingBonusItems();
seed = levelSettings->getSeed();
gameType = levelSettings->getGameType();
generateMapFeatures = levelSettings->isGenerateMapFeatures();
spawnBonusChest = levelSettings->hasStartingBonusItems();
this->levelName = levelName;
this->m_pGenerator = levelSettings->getLevelType();
this->hardcore = levelSettings->isHardcore();
m_pGenerator = levelSettings->getLevelType();
hardcore = levelSettings->isHardcore();
generatorOptions = levelSettings->getLevelTypeOptions();
allowCommands = levelSettings->getAllowCommands();
// 4J Stu - Default initers
this->xSpawn = 0;
this->ySpawn = 0;
this->zSpawn = 0;
this->time = -1; // 4J-JEV: Edited: To know when this is uninitialized.
this->lastPlayed = 0;
this->sizeOnDisk = 0;
xSpawn = 0;
ySpawn = 0;
zSpawn = 0;
dayTime = -1; // 4J-JEV: Edited: To know when this is uninitialized.
gameTime = -1;
lastPlayed = 0;
sizeOnDisk = 0;
// this->loadedPlayerTag = NULL; // 4J - we don't store this anymore
this->dimension = 0;
this->version = 0;
this->rainTime = 0;
this->raining = false;
this->thunderTime = 0;
this->thundering = false;
this->allowCommands = levelSettings->getAllowCommands();
this->initialized = false;
this->newSeaLevel =
dimension = 0;
version = 0;
rainTime = 0;
raining = false;
thunderTime = 0;
thundering = false;
initialized = false;
newSeaLevel =
levelSettings
->useNewSeaLevel(); // 4J added - only use new sea level for newly
// created maps (sea level changes in 1.8.2)
this->hasBeenInCreative =
hasBeenInCreative =
levelSettings->getGameType() == GameType::CREATIVE; // 4J added
// 4J-PB for the stronghold position
this->bStronghold = false;
this->xStronghold = 0;
this->yStronghold = 0;
this->zStronghold = 0;
bStronghold = false;
xStronghold = 0;
yStronghold = 0;
zStronghold = 0;
this->xStrongholdEndPortal = 0;
this->zStrongholdEndPortal = 0;
this->bStrongholdEndPortal = false;
xStrongholdEndPortal = 0;
zStrongholdEndPortal = 0;
bStrongholdEndPortal = false;
m_xzSize = levelSettings->getXZSize();
m_hellScale = levelSettings->getHellScale();
@ -179,46 +249,63 @@ LevelData::LevelData(LevelSettings* levelSettings,
++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) {
this->seed = copy->seed;
this->m_pGenerator = copy->m_pGenerator;
this->gameType = copy->gameType;
this->generateMapFeatures = copy->generateMapFeatures;
this->spawnBonusChest = copy->spawnBonusChest;
this->xSpawn = copy->xSpawn;
this->ySpawn = copy->ySpawn;
this->zSpawn = copy->zSpawn;
this->time = copy->time;
this->lastPlayed = copy->lastPlayed;
this->sizeOnDisk = copy->sizeOnDisk;
seed = copy->seed;
m_pGenerator = copy->m_pGenerator;
generatorOptions = copy->generatorOptions;
gameType = copy->gameType;
generateMapFeatures = copy->generateMapFeatures;
spawnBonusChest = copy->spawnBonusChest;
xSpawn = copy->xSpawn;
ySpawn = copy->ySpawn;
zSpawn = copy->zSpawn;
gameTime = copy->gameTime;
dayTime = copy->dayTime;
lastPlayed = copy->lastPlayed;
sizeOnDisk = copy->sizeOnDisk;
// this->loadedPlayerTag = copy->loadedPlayerTag; // 4J -
// we don't store this anymore
this->dimension = copy->dimension;
this->levelName = copy->levelName;
this->version = copy->version;
this->rainTime = copy->rainTime;
this->raining = copy->raining;
this->thunderTime = copy->thunderTime;
this->thundering = copy->thundering;
this->hardcore = copy->hardcore;
this->allowCommands = copy->allowCommands;
this->initialized = copy->initialized;
this->newSeaLevel = copy->newSeaLevel;
this->hasBeenInCreative = copy->hasBeenInCreative;
dimension = copy->dimension;
levelName = copy->levelName;
version = copy->version;
rainTime = copy->rainTime;
raining = copy->raining;
thunderTime = copy->thunderTime;
thundering = copy->thundering;
hardcore = copy->hardcore;
allowCommands = copy->allowCommands;
initialized = copy->initialized;
newSeaLevel = copy->newSeaLevel;
hasBeenInCreative = copy->hasBeenInCreative;
gameRules = copy->gameRules;
// 4J-PB for the stronghold position
this->bStronghold = copy->bStronghold;
this->xStronghold = copy->xStronghold;
this->yStronghold = copy->yStronghold;
this->zStronghold = copy->zStronghold;
bStronghold = copy->bStronghold;
xStronghold = copy->xStronghold;
yStronghold = copy->yStronghold;
zStronghold = copy->zStronghold;
this->xStrongholdEndPortal = copy->xStrongholdEndPortal;
this->zStrongholdEndPortal = copy->zStrongholdEndPortal;
this->bStrongholdEndPortal = copy->bStrongholdEndPortal;
xStrongholdEndPortal = copy->xStrongholdEndPortal;
zStrongholdEndPortal = copy->zStrongholdEndPortal;
bStrongholdEndPortal = copy->bStrongholdEndPortal;
m_xzSize = copy->m_xzSize;
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() {
@ -239,13 +326,15 @@ void LevelData::setTagData(CompoundTag* tag) {
tag->putLong(L"RandomSeed", seed);
tag->putString(L"generatorName", m_pGenerator->getGeneratorName());
tag->putInt(L"generatorVersion", m_pGenerator->getVersion());
tag->putString(L"generatorOptions", generatorOptions);
tag->putInt(L"GameType", gameType->getId());
tag->putBoolean(L"MapFeatures", generateMapFeatures);
tag->putBoolean(L"spawnBonusChest", spawnBonusChest);
tag->putInt(L"SpawnX", xSpawn);
tag->putInt(L"SpawnY", ySpawn);
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"LastPlayed", System::currentTimeMillis());
tag->putString(L"LevelName", levelName);
@ -257,6 +346,8 @@ void LevelData::setTagData(CompoundTag* tag) {
tag->putBoolean(L"hardcore", hardcore);
tag->putBoolean(L"allowCommands", allowCommands);
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"hasBeenInCreative", hasBeenInCreative);
// store the stronghold position
@ -269,10 +360,16 @@ void LevelData::setTagData(CompoundTag* tag) {
tag->putInt(L"StrongholdEndPortalX", xStrongholdEndPortal);
tag->putInt(L"StrongholdEndPortalZ", zStrongholdEndPortal);
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);
}
__int64 LevelData::getSeed() { return seed; }
int64_t LevelData::getSeed() { return seed; }
int LevelData::getXSpawn() { return xSpawn; }
@ -288,9 +385,11 @@ int LevelData::getXStrongholdEndPortal() { return xStrongholdEndPortal; }
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() {
return NULL; // 4J - we don't store this anymore
@ -302,7 +401,7 @@ CompoundTag* LevelData::getLoadedPlayerTag() {
// 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; }
@ -338,9 +437,11 @@ void LevelData::setZStrongholdEndPortal(int 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;
}
@ -371,7 +472,7 @@ int LevelData::getVersion() { return 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; }
@ -405,7 +506,7 @@ void LevelData::setGameType(GameType* gameType) {
// 4J Added
hasBeenInCreative =
hasBeenInCreative || (gameType == GameType::CREATIVE) ||
app.GetGameHostOption(eGameHostOption_CheatsEnabled) > 0;
(app.GetGameHostOption(eGameHostOption_CheatsEnabled) > 0);
}
bool LevelData::useNewSeaLevel() { return newSeaLevel; }
@ -418,6 +519,12 @@ LevelType* LevelData::getGenerator() { return m_pGenerator; }
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::getAllowCommands() { return allowCommands; }
@ -432,6 +539,33 @@ void LevelData::setInitialized(bool initialized) {
this->initialized = initialized;
}
GameRules* LevelData::getGameRules() { return &gameRules; }
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; }

View file

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

View file

@ -7,6 +7,7 @@
#include "../Headers/net.minecraft.world.level.levelgen.synth.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.level.storage.h"
#include "../Headers/net.minecraft.world.entity.h"
#include "RandomLevelSource.h"
#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_scaleNoise_SPU __attribute__((__aligned__(16)));
static PerlinNoise_DataIn g_depthNoise_SPU __attribute__((__aligned__(16)));
// #define DISABLE_SPU_CODE
#endif
const double RandomLevelSource::SNOW_SCALE = 0.3;
const double RandomLevelSource::SNOW_CUTOFF = 0.5;
RandomLevelSource::RandomLevelSource(Level* level, __int64 seed,
RandomLevelSource::RandomLevelSource(Level* level, int64_t seed,
bool generateStructures)
: generateStructures(generateStructures) {
m_XZSize = level->getLevelData()->getXZSize();
#ifdef _LARGE_WORLDS
level->getLevelData()->getMoatFlags(&m_classicEdgeMoat, &m_smallEdgeMoat,
&m_mediumEdgeMoat);
#endif
caveFeature = new LargeCaveFeature();
strongholdFeature = new StrongholdFeature();
villageFeature = new VillageFeature(0, m_XZSize);
villageFeature = new VillageFeature(m_XZSize);
mineShaftFeature = new MineShaftFeature();
scatteredFeature = new RandomScatteredLargeFeature();
canyonFeature = new CanyonFeature();
@ -67,6 +73,8 @@ RandomLevelSource::~RandomLevelSource() {
delete scatteredFeature;
delete canyonFeature;
this->level = level;
delete random;
;
delete lperlinNoise1;
@ -91,6 +99,140 @@ int g_numPrepareHeightCalls = 0;
LARGE_INTEGER g_totalPrepareHeightsTime = {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) {
LARGE_INTEGER startTime;
int xChunks = 16 / CHUNK_WIDTH;
@ -166,50 +308,19 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
double vala = (_s1 - _s0) * zStep;
val -= vala;
for (int z = 0; z < CHUNK_WIDTH; z++) {
///////////////////////////////////////////////////////////////////
// 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
// 4J Stu - I have removed all uses of the new
// getHeightFalloff function for now as we had some
// problems with PS3/PSVita world generation I have
// fixed the non large worlds method, however we
// will be happier if the current builds go out with
// completely old code We can put the new code back
// in mid-november 2014 once those PS3/Vita builds
// are gone (and the PS4 doesn't have world
// enlarging in these either anyway)
int xxx = ((xOffs * 16) + x + (xc * CHUNK_WIDTH));
int zzz = ((zOffs * 16) + z + (zc * CHUNK_WIDTH));
// 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
///////////////////////////////////////////////////////////////////
int emin;
float comp = getHeightFalloff(xxx, zzz, &emin);
// 4J - slightly rearranged this code (as of
// 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
// but is now varied by block above
if ((val += vala) > comp) {
tileId = (uint8_t)Tile::rock_Id;
tileId = (uint8_t)Tile::stone_Id;
} else if (yc * CHUNK_HEIGHT + y < waterHeight) {
tileId = (uint8_t)Tile::calmWater_Id;
}
@ -236,7 +347,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) {
// the edge of the world
if (yc * CHUNK_HEIGHT + y <=
(level->getSeaLevel() - 10))
tileId = Tile::rock_Id;
tileId = Tile::stone_Id;
else if (yc * CHUNK_HEIGHT + y <
level->getSeaLevel())
tileId = Tile::calmWater_Id;
@ -305,7 +416,8 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
if (y <= 1 + random->nextInt(
2)) // 4J - changed to make the bedrock not
// 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;
} else {
@ -313,11 +425,11 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
if (old == 0) {
run = -1;
} else if (old == Tile::rock_Id) {
} else if (old == Tile::stone_Id) {
if (run == -1) {
if (runDepth <= 0) {
top = 0;
material = (uint8_t)Tile::rock_Id;
material = (uint8_t)Tile::stone_Id;
} else if (y >= waterHeight - 4 &&
y <= waterHeight + 1) {
top = b->topMaterial;
@ -343,8 +455,7 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks,
run--;
blocks[offs] = material;
// place a few sandstone blocks beneath sand
// runs
// place a few sandstone blocks beneath sand runs
if (run == 0 && material == Tile::sand_Id) {
run = random->nextInt(4);
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);
if (od < 7 && od < d) {
level->setData(xp + x2, y, zp + z2,
d);
d, Tile::UPDATE_ALL);
}
}
}
}
}
if (hadWater) {
level->setTileAndDataNoUpdate(
xp, y, zp, Tile::calmWater_Id, 7);
level->setTileAndData(xp, y, zp, Tile::calmWater_Id,
7, Tile::UPDATE_CLIENTS);
for (int y2 = 0; y2 < y; y2++) {
level->setTileAndDataNoUpdate(
xp, y2, zp, Tile::calmWater_Id, 8);
level->setTileAndData(xp, y2, zp,
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);
if (RandomLevelSource::FLOATING_ISLANDS) {
if (FLOATING_ISLANDS) {
calcWaterDepths(parent, xt, zt);
}
@ -690,14 +802,15 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Lakes");
if (!hasVillage && pprandom->nextInt(4) == 0) {
int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8;
if (biome != Biome::desert && biome != Biome::desertHills) {
if (!hasVillage && pprandom->nextInt(4) == 0) {
int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8;
LakeFeature* calmWater = new LakeFeature(Tile::calmWater_Id);
calmWater->place(level, pprandom, x, y, z);
delete calmWater;
LakeFeature calmWater(Tile::calmWater_Id);
calmWater.place(level, pprandom, x, y, z);
}
}
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 z = zo + pprandom->nextInt(16) + 8;
if (y < level->seaLevel || pprandom->nextInt(10) == 0) {
LakeFeature* calmLava = new LakeFeature(Tile::calmLava_Id);
calmLava->place(level, pprandom, x, y, z);
delete calmLava;
LakeFeature calmLava(Tile::calmLava_Id);
calmLava.place(level, pprandom, x, y, z);
}
}
PIXEndNamedEvent();
@ -719,10 +831,8 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8;
MonsterRoomFeature* mrf = new MonsterRoomFeature();
if (mrf->place(level, pprandom, x, y, z)) {
}
delete mrf;
MonsterRoomFeature mrf;
mrf.place(level, pprandom, x, y, z);
}
PIXEndNamedEvent();
@ -730,11 +840,16 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
biome->decorate(level, pprandom, xo, zo);
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Process Schematics");
app.processSchematics(parent->getChunk(xt, zt));
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Post process mobs");
MobSpawner::postProcessSpawnMobs(level, biome, xo + 8, zo + 8, 16, 16,
pprandom);
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Update ice and snow");
// 4J - brought forward from 1.2.3 to get snow back in taiga biomes
xo += 8;
zo += 8;
@ -743,17 +858,16 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int y = level->getTopRainBlock(xo + x, zo + z);
if (level->shouldFreezeIgnoreNeighbors(x + xo, y - 1, z + zo)) {
level->setTileNoUpdate(
x + xo, y - 1, z + zo,
Tile::ice_Id); // 4J - changed from setTile, otherwise we
// end up creating a *lot* of dynamic water
// tiles as these ice tiles are set
level->setTileAndData(x + xo, y - 1, z + zo, Tile::ice_Id, 0,
Tile::UPDATE_CLIENTS);
}
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;
}
@ -774,6 +888,10 @@ std::vector<Biome::MobSpawnerData*>* RandomLevelSource::getMobsAt(
if (biome == NULL) {
return NULL;
}
if (mobCategory == MobCategory::monster &&
scatteredFeature->isSwamphut(x, y, z)) {
return scatteredFeature->getSwamphutEnemies();
}
return biome->getMobs(mobCategory);
}
@ -784,3 +902,13 @@ TilePos* RandomLevelSource::findNearestMapFeature(
}
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;
public:
RandomLevelSource(Level* level, __int64 seed, bool generateStructures);
RandomLevelSource(Level* level, int64_t seed, bool generateStructures);
~RandomLevelSource();
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);
public:
@ -93,4 +99,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName,
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) {
__int64 nanoTime = System::nanoTime();
int64_t nanoTime = System::nanoTime();
LevelChunk* chunk = capsulated->load(level, x, z);
timeSpentLoading += System::nanoTime() - nanoTime;
loadCount++;
@ -22,7 +22,7 @@ LevelChunk* ChunkStorageProfilerDecorator::load(Level* level, int x, int z) {
}
void ChunkStorageProfilerDecorator::save(Level* level, LevelChunk* levelChunk) {
__int64 nanoTime = System::nanoTime();
int64_t nanoTime = System::nanoTime();
capsulated->save(level, levelChunk);
timeSpentSaving += System::nanoTime() - nanoTime;
saveCount++;

View file

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

View file

@ -12,6 +12,7 @@ static const int sc_maxCompressTiles = 64;
static CompressedTileStorage_compress_dataIn
g_compressTileDataIn[sc_maxCompressTiles] __attribute__((__aligned__(16)));
static int g_currentCompressTiles = 0;
// #define DISABLE_SPU_CODE
#endif //__PS3__
// 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 z = 0; z < 16; z += 4) {
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
// | INDEX_TYPE_0_BIT_FLAG )
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
// bytes)
int quickCount = allocatedSize / 64;
__int64* pOld = (__int64*)indicesAndData;
__int64* pNew = (__int64*)other->indicesAndData;
int64_t* pOld = (int64_t*)indicesAndData;
int64_t* pNew = (int64_t*)other->indicesAndData;
for (int i = 0; i < quickCount; i++) {
__int64 d0 = pOld[0] ^ pNew[0];
__int64 d1 = pOld[1] ^ pNew[1];
__int64 d2 = pOld[2] ^ pNew[2];
__int64 d3 = pOld[3] ^ pNew[3];
__int64 d4 = pOld[4] ^ pNew[4];
__int64 d5 = pOld[5] ^ pNew[5];
__int64 d6 = pOld[6] ^ pNew[6];
__int64 d7 = pOld[7] ^ pNew[7];
int64_t d0 = pOld[0] ^ pNew[0];
int64_t d1 = pOld[1] ^ pNew[1];
int64_t d2 = pOld[2] ^ pNew[2];
int64_t d3 = pOld[3] ^ pNew[3];
int64_t d4 = pOld[4] ^ pNew[4];
int64_t d5 = pOld[5] ^ pNew[5];
int64_t d6 = pOld[6] ^ pNew[6];
int64_t d7 = pOld[7] ^ pNew[7];
d0 |= d1;
d2 |= d3;
d4 |= d5;
@ -292,7 +293,7 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
int offsets[512];
int memToAlloc = 0;
// static int type0 = 0, type1 = 0, type2 = 0, type4 = 0, type8 = 0,
//chunkTotal = 0;
// chunkTotal = 0;
// Loop round all blocks
for (int i = 0; i < 512; i++) {
@ -327,8 +328,8 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
}
}
#else
__uint64 usedFlags[4] = {0, 0, 0, 0};
__int64 i64_1 = 1; // MGH - instead of 1i64, which is MS specific
uint64_t usedFlags[4] = {0, 0, 0, 0};
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
// 4 tiles in the block
{
@ -374,8 +375,8 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
// chunkTotal++;
// printf("%d: %d (0) %d (1) %d (2) %d (4) %d (8)\n", chunkTotal, type0 /
//chunkTotal, type1 / chunkTotal, type2 / chunkTotal, type4 / chunkTotal,
//type8 / chunkTotal);
// chunkTotal, type1 / chunkTotal, type2 / chunkTotal, type4 / chunkTotal,
// type8 / chunkTotal);
memToAlloc += 1024; // For the indices
unsigned char* newIndicesAndData = (unsigned char*)XPhysicalAlloc(
@ -976,8 +977,8 @@ void CompressedTileStorage::compress(int upgradeBlock /*=-1*/) {
}
#else
__uint64 usedFlags[4] = {0, 0, 0, 0};
__int64 i64_1 =
uint64_t usedFlags[4] = {0, 0, 0, 0};
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 4x4x4 tiles in the block
@ -1076,6 +1077,7 @@ void CompressedTileStorage::compress(int upgradeBlock /*=-1*/) {
memToAlloc, MAXULONG_PTR, 4096,
PAGE_READWRITE); //(unsigned char *)malloc( memToAlloc );
if (newIndicesAndData == NULL) {
DWORD lastError = GetLastError();
#ifndef _DURANGO
MEMORYSTATUS memStatus;
GlobalMemoryStatus(&memStatus);
@ -1380,4 +1382,4 @@ void CompressedTileStorage::reverseIndices(unsigned char* indices) {
for (int i = 0; i < 512; 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
// 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
//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 is represented at 2 bit per tile. Data pointed to is 4 bytes
//describing the 4 possible tiles stored in this block, followed by 64 bytes of
//data (total 68 bytes) 2 - the data for this block is represented at 4 bit per
//tile. Data pointed to is 16 bytes describing the 16 possible tiles stored in
//this block, followed by 128 bytes of data (total 144 bytes) 3 - if bit 2 is 0,
//then this block is represented at 8 bits per tile. Data pointed to is 64
//bytes, offset must be a multiple of 4 (since bit 2 can also be thought of as
//being the low bit of the offset (divided by 2 as in the other cases), and is
//zero)
// 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 is represented at 2 bit per tile. Data pointed to
// is 4 bytes describing the 4 possible tiles stored in this block, followed by
// 64 bytes of data (total 68 bytes) 2 - the data for this
// block is represented at 4 bit per tile. Data pointed to is 16 bytes
// describing the 16 possible tiles stored in this block, followed by 128 bytes
// of data (total 144 bytes) 3 - if bit 2 is 0, then this block is
// represented at 8 bits per tile. Data pointed to is 64 bytes, offset must be a
// multiple of 4 (since bit 2 can also be thought of as being
// 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
//bits per tile. The upper 8 bits of the index store the tile value that is used
//by the entire block.
// bits per tile. The upper 8 bits of the index store the tile value that is
// used by the entire block.
// So:
// oooooooooooooo00 - 1 bit per tile, offset oooooooooooooo0
// oooooooooooooo01 - 2 bits per tile, offset oooooooooooooo0

View file

@ -18,7 +18,7 @@ _MapDataMappings::_MapDataMappings() {
#ifndef _DURANGO
ZeroMemory(xuids, sizeof(PlayerUID) * MAXIMUM_MAP_SAVE_DATA);
#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) {
@ -79,7 +79,7 @@ _MapDataMappings_old::_MapDataMappings_old() {
#ifndef _DURANGO
ZeroMemory(xuids, sizeof(PlayerUID) * MAXIMUM_MAP_SAVE_DATA);
#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) {
@ -100,8 +100,8 @@ void DirectoryLevelStorage::PlayerMappings::addMapping(int id, int centreX,
int centreZ,
int dimension,
int scale) {
__int64 index = (((__int64)(centreZ & 0x1FFFFFFF)) << 34) |
(((__int64)(centreX & 0x1FFFFFFF)) << 5) |
int64_t index = (((int64_t)(centreZ & 0x1FFFFFFF)) << 34) |
(((int64_t)(centreX & 0x1FFFFFFF)) << 5) |
((scale & 0x7) << 2) | (dimension & 0x3);
m_mappings[index] = id;
// 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 dimension,
int scale) {
//__int64 zMasked = centreZ & 0x1FFFFFFF;
//__int64 xMasked = centreX & 0x1FFFFFFF;
//__int64 zShifted = zMasked << 34;
//__int64 xShifted = xMasked << 5;
//int64_t zMasked = centreZ & 0x1FFFFFFF;
//int64_t xMasked = centreX & 0x1FFFFFFF;
//int64_t zShifted = zMasked << 34;
//int64_t xShifted = xMasked << 5;
// app.DebugPrintf("xShifted = %d (0x%016x), zShifted = %I64d
// (0x%016llx)\n", xShifted, xShifted, zShifted, zShifted);
__int64 index = (((__int64)(centreZ & 0x1FFFFFFF)) << 34) |
(((__int64)(centreX & 0x1FFFFFFF)) << 5) |
int64_t index = (((int64_t)(centreZ & 0x1FFFFFFF)) << 34) |
(((int64_t)(centreX & 0x1FFFFFFF)) << 5) |
((scale & 0x7) << 2) | (dimension & 0x3);
AUTO_VAR(it, m_mappings.find(index));
if (it != m_mappings.end()) {
@ -148,7 +148,7 @@ void DirectoryLevelStorage::PlayerMappings::writeMappings(
void DirectoryLevelStorage::PlayerMappings::readMappings(DataInputStream* dis) {
int count = dis->readInt();
for (unsigned int i = 0; i < count; ++i) {
__int64 index = dis->readLong();
int64_t index = dis->readLong();
int id = dis->readInt();
m_mappings[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
/*
File dataFile = File( dir, std::wstring(L"session.lock"));
File dataFile = File( dir, wstring(L"session.lock"));
FileInputStream fis = FileInputStream(dataFile);
DataInputStream dis = DataInputStream(&fis);
dis.close();
@ -260,8 +260,7 @@ LevelData* DirectoryLevelStorage::prepareLevel() {
} else
#endif
{
getSaveFile()->setFilePointer(fileEntry, 0,
SaveFileSeekOrigin::Begin);
getSaveFile()->setFilePointer(fileEntry, 0, NULL, FILE_BEGIN);
#ifdef _LARGE_WORLDS
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
bool DirectoryLevelStorage::load(std::shared_ptr<Player> player) {
bool newPlayer = true;
CompoundTag* DirectoryLevelStorage::load(std::shared_ptr<Player> player) {
CompoundTag* tag = loadPlayerDataTag(player->getXuid());
if (tag != NULL) {
newPlayer = false;
player->load(tag);
delete tag;
}
return newPlayer;
return tag;
}
CompoundTag* DirectoryLevelStorage::loadPlayerDataTag(PlayerUID xuid) {

View file

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

View file

@ -3,6 +3,8 @@
#include "../../Entities/Mobs/Painting.h"
#include "../../Platform/System.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.item.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(ExperienceOrb::create, eTYPE_EXPERIENCEORB, L"XPOrb", 2);
setId(LeashFenceKnotEntity::create, eTYPE_LEASHFENCEKNOT, L"LeashKnot", 8);
setId(Painting::create, eTYPE_PAINTING, L"Painting", 9);
setId(Arrow::create, eTYPE_ARROW, L"Arrow", 10);
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(ThrownEnderpearl::create, eTYPE_THROWNENDERPEARL, L"ThrownEnderpearl",
14);
@ -79,12 +82,24 @@ void EntityIO::staticCtor() {
setId(ThrownExpBottle::create, eTYPE_THROWNEXPBOTTLE, L"ThrownExpBottle",
17);
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(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(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(Monster::create, eTYPE_MONSTER, L"Monster", 49);
@ -126,7 +141,15 @@ void EntityIO::staticCtor() {
setId(LavaSlime::create, eTYPE_LAVASLIME, L"LavaSlime", 62,
eMinecraftColour_Mob_LavaSlime_Colour1,
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,
eMinecraftColour_Mob_Pig_Colour2, IDS_PIG);
@ -148,10 +171,13 @@ void EntityIO::staticCtor() {
eMinecraftColour_Mob_MushroomCow_Colour1,
eMinecraftColour_Mob_MushroomCow_Colour2, IDS_MUSHROOM_COW);
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_Colour2, IDS_OZELOT);
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,
eMinecraftColour_Mob_Villager_Colour1,
@ -162,6 +188,43 @@ void EntityIO::staticCtor() {
// 4J Added
setId(DragonFireball::create, eTYPE_DRAGON_FIREBALL, L"DragonFireball",
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,
@ -172,6 +235,10 @@ std::shared_ptr<Entity> EntityIO::newEntity(const std::wstring& id,
if (it != idCreateMap->end()) {
entityCreateFn create = it->second;
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;
@ -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> 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")));
if (it != idCreateMap->end()) {
entityCreateFn create = it->second;
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) {
@ -204,6 +293,10 @@ std::shared_ptr<Entity> EntityIO::newById(int id, Level* level) {
if (it != numCreateMap->end()) {
entityCreateFn create = it->second;
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) {
@ -225,6 +318,10 @@ std::shared_ptr<Entity> EntityIO::newByEnumType(eINSTANCEOF eType,
if (it2 != numCreateMap->end()) {
entityCreateFn create = it2->second;
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->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; }
@ -70,7 +70,7 @@ GameType* GameType::byName(const std::wstring& name) {
return SURVIVAL;
}
void LevelSettings::_init(__int64 seed, GameType* gameType,
void LevelSettings::_init(int64_t seed, GameType* gameType,
bool generateMapFeatures, bool hardcore,
bool newSeaLevel, LevelType* levelType, int xzSize,
int hellScale) {
@ -82,11 +82,12 @@ void LevelSettings::_init(__int64 seed, GameType* gameType,
this->levelType = levelType;
this->allowCommands = false;
this->startingBonusItems = false;
levelTypeOptions = L"";
m_xzSize = xzSize;
m_hellScale = hellScale;
}
LevelSettings::LevelSettings(__int64 seed, GameType* gameType,
LevelSettings::LevelSettings(int64_t seed, GameType* gameType,
bool generateMapFeatures, bool hardcore,
bool newSeaLevel, LevelType* levelType, int xzSize,
int hellScale)
@ -118,9 +119,14 @@ LevelSettings* LevelSettings::enableSinglePlayerCommands() {
return this;
}
LevelSettings* LevelSettings::setLevelTypeOptions(const std::wstring& options) {
levelTypeOptions = options;
return this;
}
bool LevelSettings::hasStartingBonusItems() { return startingBonusItems; }
__int64 LevelSettings::getSeed() { return seed; }
int64_t LevelSettings::getSeed() { return seed; }
GameType* LevelSettings::getGameType() { return gameType; }
@ -142,3 +148,5 @@ bool LevelSettings::useNewSeaLevel() { return newSeaLevel; }
int LevelSettings::getXZSize() { return m_xzSize; }
int LevelSettings::getHellScale() { return m_hellScale; }
std::wstring LevelSettings::getLevelTypeOptions() { return levelTypeOptions; }

View file

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

View file

@ -27,5 +27,6 @@ public:
virtual int getMaxBuildHeight() = 0;
virtual bool isAllEmpty() = 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() {}
};

View file

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

View file

@ -5,8 +5,8 @@ class GameType;
class LevelSummary {
const std::wstring levelId;
const std::wstring levelName;
const __int64 lastPlayed;
const __int64 sizeOnDisk;
const int64_t lastPlayed;
const int64_t sizeOnDisk;
const bool requiresConversion;
GameType* gameMode;
const bool hardcore;
@ -14,13 +14,13 @@ class LevelSummary {
public:
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);
std::wstring getLevelId();
std::wstring getLevelName();
__int64 getSizeOnDisk();
int64_t getSizeOnDisk();
bool isRequiresConversion();
__int64 getLastPlayed();
int64_t getLastPlayed();
int compareTo(LevelSummary* rhs);
GameType* getGameMode();
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) {
this->id = id;
m_generatorName = generatorName;
m_version = version;
m_selectable = true;
@ -81,12 +82,14 @@ bool LevelType::hasReplacement() { return m_replacement; }
LevelType* LevelType::getLevelType(std::wstring name) {
if (name.length() > 0) {
for (int i = 0; i < 16; i++) {
// Fix: check NULL before accessing member to avoid null dereference
if (levelTypes[i] != NULL &&
(levelTypes[i]->m_generatorName.compare(name) == 0)) {
std::wstring genname = levelTypes[i]->m_generatorName;
if (levelTypes[i] != NULL && (genname.compare(name) == 0)) {
return levelTypes[i];
}
}
}
return NULL;
}
int LevelType::getId() { return id; }

View file

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

View file

@ -33,6 +33,8 @@ MapItemSavedData::HoldingPlayer::HoldingPlayer(std::shared_ptr<Player> player,
tick = 0;
sendPosTick = 0;
step = 0;
hasSentInitial = false;
// java ctor
// this->player = player;
@ -50,6 +52,14 @@ MapItemSavedData::HoldingPlayer::~HoldingPlayer() {
charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket(
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) {
sendPosTick = 4;
@ -129,15 +139,13 @@ charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket(
std::shared_ptr<ServerPlayer> servPlayer =
std::dynamic_pointer_cast<ServerPlayer>(player);
for (int d = 0; d < 10; d++) {
int column = (tick * 11) % (MapItem::IMAGE_WIDTH);
tick++;
if (rowsDirtyMin[column] >= 0) {
int len = rowsDirtyMax[column] - rowsDirtyMin[column] + 1;
int min = rowsDirtyMin[column];
charArray data = charArray(len + 3);
data[0] = 0;
data[0] = HEADER_COLOURS;
data[1] = (char)column;
data[2] = (char)min;
for (unsigned int y = 0; y < data.length - 3; y++) {
@ -157,7 +165,6 @@ MapItemSavedData::MapItemSavedData(const std::wstring& id) : SavedData(id) {
dimension = 0;
scale = 0;
colors = byteArray(MapItem::IMAGE_WIDTH * MapItem::IMAGE_HEIGHT);
step = 0;
}
MapItemSavedData::~MapItemSavedData() {
@ -173,7 +180,7 @@ void MapItemSavedData::load(CompoundTag* tag) {
z = tag->getInt(L"zCenter");
scale = tag->getByte(L"scale");
if (scale < 0) scale = 0;
if (scale > 4) scale = 4;
if (scale > MAX_SCALE) scale = MAX_SCALE;
int width = tag->getShort(L"width");
int height = tag->getShort(L"height");
@ -246,8 +253,7 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
if (it2 != carriedByPlayers.end()) {
carriedByPlayers.erase(it2);
}
it = carriedBy.erase(
std::find(carriedBy.begin(), carriedBy.end(), hp));
it = carriedBy.erase(find(carriedBy.begin(), carriedBy.end(), hp));
} else {
++it;
@ -330,7 +336,9 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
int size = MAP_SIZE - 1;
char rot = (char)((item->getFrame()->dir * 90) * 16 / 360);
if (dimension < 0) {
int s = step / 10;
int s =
(int)(playerLevel->getLevelData()->getDayTime() /
10);
rot = (char)((s * s * 34187121 + s * 121) >> 15 & 15);
}
#ifdef _LARGE_WORLDS
@ -416,7 +424,9 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
rot =
(char)(decorationPlayer->yRot * 16 / 360 + 0.5);
if (dimension < 0) {
int s = step / 10;
int s = (int)(playerLevel->getLevelData()
->getDayTime() /
10);
rot =
(char)((s * s * 34187121 + s * 121) >> 15 &
15);
@ -460,11 +470,10 @@ void MapItemSavedData::tickCarriedBy(std::shared_ptr<Player> player,
}
// float xd = (float) (hp->player->x - x) / (1 <<
// scale); float yd = (float) (hp->player->z - z) / (1 << scale);
// int ww = 64;
// int hh = 64;
// if (xd >= -ww && yd >= -hh && xd <= ww && yd <=
// hh)
// scale); float yd = (float) (hp->player->z - z) /
// (1 << scale); int ww = 64;
// int hh = 64; if (xd >= -ww && yd >= -hh && xd
// <= ww && yd <= hh)
// {
// char img = 0;
// 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) {
if (data[0] == 0) {
if (data[0] == HEADER_COLOURS) {
int xx = data[1] & 0xff;
int yy = data[2] & 0xff;
for (unsigned int y = 0; y < data.length - 3; y++) {
@ -519,7 +528,7 @@ void MapItemSavedData::handleComplexItemData(charArray& data) {
}
setDirty();
} else if (data[0] == 1) {
} else if (data[0] == HEADER_DECORATIONS) {
for (unsigned int i = 0; i < decorations.size(); i++) {
delete decorations[i];
}
@ -546,9 +555,27 @@ void MapItemSavedData::handleComplexItemData(charArray& data) {
decorations.push_back(
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
// 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

View file

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

View file

@ -45,7 +45,7 @@ McRegionChunkStorage::McRegionChunkStorage(ConsoleSaveFile* saveFile,
int count = dis.readInt();
for (int i = 0; i < count; ++i) {
__int64 index = dis.readLong();
int64_t index = dis.readLong();
CompoundTag* tag = NbtIo::read(&dis);
ByteArrayOutputStream bos;
@ -160,6 +160,14 @@ LevelChunk* McRegionChunkStorage::load(Level* level, int x, int z) {
#endif
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;
}

View file

@ -30,7 +30,7 @@ ChunkStorage* McRegionLevelStorage::createChunkStorage(Dimension* dimension) {
std::vector<FileEntry*>* netherFiles =
m_saveFile->getRegionFilesByDimension(1);
if (netherFiles != NULL) {
unsigned int bytesWritten = 0;
DWORD bytesWritten = 0;
for (AUTO_VAR(it, netherFiles->begin());
it != netherFiles->end(); ++it) {
m_saveFile->zeroFile(*it, (*it)->getFileSize(),
@ -99,4 +99,4 @@ void McRegionLevelStorage::saveLevelData(
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->writeInt(lc->x);
dos->writeInt(lc->z);
dos->writeLong(level->getTime());
dos->writeLong(level->getGameTime());
dos->writeLong(lc->inhabitedTime);
PIXBeginNamedEvent(0, "Getting block data");
lc->writeCompressedBlockData(dos);
@ -333,7 +334,8 @@ void OldChunkStorage::save(LevelChunk* lc, Level* level, CompoundTag* tag) {
level->checkSession();
tag->putInt(L"xPos", lc->x);
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
// lighting data for block, data, and sky & block lighting. This wasn't
// 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"z", td.z);
teTag->putInt(L"t", (int)(td.m_delay - levelTime));
teTag->putInt(L"p", td.priorityTilt);
tickTags->add(teTag);
}
@ -453,6 +456,7 @@ void OldChunkStorage::loadEntities(LevelChunk* lc, Level* level,
}
LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
PIXBeginNamedEvent(0, "Loading chunk");
short version = dis->readShort();
int x = dis->readInt();
int z = dis->readInt();
@ -460,6 +464,10 @@ LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
LevelChunk* levelChunk = new LevelChunk(level, x, z);
if (version >= SAVE_FILE_VERSION_CHUNK_INHABITED_TIME) {
levelChunk->inhabitedTime = dis->readLong();
}
levelChunk->readCompressedBlockData(dis);
levelChunk->readCompressedDataData(dis);
levelChunk->readCompressedSkyLightData(dis);
@ -479,13 +487,26 @@ LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
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);
loadEntities(levelChunk, level, tag);
if (tag->contains(L"TileTicks")) {
PIXBeginNamedEvent(0, "Loading TileTicks");
ListTag<CompoundTag>* tileTicks =
(ListTag<CompoundTag>*)tag->getList(L"TileTicks");
@ -496,13 +517,16 @@ LevelChunk* OldChunkStorage::load(Level* level, DataInputStream* dis) {
level->forceAddTileTick(
teTag->getInt(L"x"), teTag->getInt(L"y"),
teTag->getInt(L"z"), teTag->getInt(L"i"),
teTag->getInt(L"t"));
teTag->getInt(L"t"), teTag->getInt(L"p"));
}
}
PIXEndNamedEvent();
}
delete tag;
PIXEndNamedEvent();
return levelChunk;
}
@ -536,8 +560,8 @@ LevelChunk* OldChunkStorage::load(Level* level, CompoundTag* tag) {
delete[] tag->getByteArray(L"BlockLight").data;
// levelChunk->skyLight = new DataLayer(tag->getByteArray(L"SkyLight"),
//level->depthBits); levelChunk->blockLight = new
//DataLayer(tag->getByteArray(L"BlockLight"), level->depthBits);
// level->depthBits); levelChunk->blockLight = new
// DataLayer(tag->getByteArray(L"BlockLight"), level->depthBits);
delete[] levelChunk->heightmap.data;
levelChunk->heightmap = tag->getByteArray(L"HeightMap");
@ -597,8 +621,17 @@ LevelChunk* OldChunkStorage::load(Level* level, CompoundTag* tag) {
}
#endif
if (tag->contains(L"Biomes")) {
levelChunk->setBiomes(tag->getByteArray(L"Biomes"));
#ifndef _CONTENT_PACKAGE
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);
@ -614,7 +647,7 @@ LevelChunk* OldChunkStorage::load(Level* level, CompoundTag* tag) {
level->forceAddTileTick(
teTag->getInt(L"x"), teTag->getInt(L"y"),
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 {
public:
virtual void save(std::shared_ptr<Player> player) = 0;
virtual bool load(std::shared_ptr<Player>
player) = 0; // 4J Changed return val to bool to
// check if new player or loaded player
virtual CompoundTag* load(std::shared_ptr<Player> player) = 0;
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
virtual void clearOldPlayerFiles() = 0;
virtual void saveMapIdLookup() = 0;
virtual void deleteMapFilesForPlayer(std::shared_ptr<Player> player) = 0;
virtual void saveAllCachedData() = 0;
};
};

View file

@ -3,11 +3,28 @@
#include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.dimension.h"
#include "../../../Minecraft.Client/Level/ServerLevel.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) {
int x = Mth::floor(e->x);
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;
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;
}
if (findPortal(level, e)) {
if (findPortal(e, xOriginal, yOriginal, zOriginal, yRotOriginal)) {
return;
}
createPortal(level, e);
findPortal(level, e);
createPortal(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
// given our smaller nether
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 zc = Mth::floor(e->z);
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--;
}
long hash = ChunkPos::hashCode(xc, zc);
bool updateCache = true;
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;
AUTO_VAR(it, cachedPortals.find(hash));
if (it != cachedPortals.end()) {
PortalPosition* pos = it->second;
closest = 0;
xTarget = pos->x;
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 z = zTarget;
if (updateCache) {
cachedPortals[hash] =
new PortalPosition(x, y, z, level->getGameTime());
cachedPortalKeys.push_back(hash);
}
double xt = x + 0.5;
double yt = y + 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) xt += 0.5;
if (level->getTile(x - 1, y, z) == Tile::portalTile_Id)
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;
if (level->getTile(x, y, z + 1) == Tile::portalTile_Id) zt += 0.5;
int originalDir = e->getPortalEntranceDir();
e->moveTo(xt, yt, zt, e->yRot, 0);
e->xd = e->yd = e->zd = 0;
if (dir > Direction::UNDEFINED) {
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 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
// creating them floating in mid air over lava
int r = 16 * 3;
@ -317,14 +443,14 @@ bool PortalForcer::createPortal(Level* level, std::shared_ptr<Entity> e) {
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++) {
level->noNeighborUpdate = true;
for (int s = 0; s < 4; s++) {
for (int h = -1; h < 4; h++) {
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;
bool border = s == 0 || s == 3 || h == -1 || h == 3;
level->setTile(
level->setTileAndData(
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 h = -1; h < 4; h++) {
@ -353,3 +479,23 @@ bool PortalForcer::createPortal(Level* level, std::shared_ptr<Entity> e) {
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 PortalForcer {
public:
class PortalPosition : public Pos {
public:
int64_t lastUsed;
PortalPosition(int x, int y, int z, int64_t time);
};
private:
ServerLevel* level;
Random* random;
std::unordered_map<int64_t, PortalPosition*> cachedPortals;
std::vector<int64_t> cachedPortalKeys;
public:
// 4J Stu Added - Java has no ctor, but we need to initialise random
PortalForcer();
PortalForcer(ServerLevel* level);
~PortalForcer();
void force(Level* level, std::shared_ptr<Entity> e);
public:
bool findPortal(Level* level, std::shared_ptr<Entity> e);
public:
bool createPortal(Level* level, std::shared_ptr<Entity> e);
void force(std::shared_ptr<Entity> e, double xOriginal, double yOriginal,
double zOriginal, float yRotOriginal);
bool findPortal(std::shared_ptr<Entity> e, double xOriginal,
double yOriginal, double zOriginal, float yRotOriginal);
bool createPortal(std::shared_ptr<Entity> e);
void tick(int64_t time);
};

View file

@ -3,6 +3,7 @@
#include "../../Headers/net.minecraft.world.level.chunk.h"
#include "../../Headers/net.minecraft.world.level.dimension.h"
#include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.redstone.h"
#include "../../Blocks/Material.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;
xc1 = x1 >> 4;
zc1 = z1 >> 4;
int xc2 = x2 >> 4;
int zc2 = z2 >> 4;
xc1 = (x1 - r) >> 4;
zc1 = (z1 - r) >> 4;
int xc2 = (x2 + r) >> 4;
int zc2 = (z2 + r) >> 4;
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) {
LevelChunkArray* lca = (*chunks)[xc - xc1];
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)) {
allEmpty = false;
}
@ -246,18 +255,8 @@ bool Region::isSolidBlockingTile(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)];
if (tile == NULL) return false;
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;
return level->isTopSolidBlocking(tile, getData(x, y, 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
return (int)layer;
}
if (layer == LightLayer::Sky && level->dimension->hasCeiling) {
return 0;
}
int id = tileId > -1 ? tileId : getTile(x, y, z);
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);
}
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;
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();
bool isAllEmpty();
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 getMaxBuildHeight();
int getDirectSignal(int x, int y, int z, int dir);
LevelChunk* getLevelChunk(int x, int y, int z);

View file

@ -29,7 +29,7 @@ private:
int* chunkTimestamps;
std::vector<bool>* sectorFree;
int sizeDelta;
__int64 _lastModified;
int64_t _lastModified;
bool m_bIsEmpty; // 4J added
public:
@ -37,7 +37,7 @@ public:
~RegionFile();
/* 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 */
int getSizeDelta();

View file

@ -25,7 +25,7 @@ RegionFile* RegionFileCache::_getRegionFile(
// 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" );
MemSect(31);
File file;
@ -109,3 +109,5 @@ DataOutputStream* RegionFileCache::_getChunkDataOutputStream(
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
// files
RegionFileCache() {}
~RegionFileCache();
RegionFile* _getRegionFile(ConsoleSaveFile* saveFile,
const std::wstring& prefix, int chunkX,

View file

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

View file

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

View file

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

View file

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

View file

@ -1,8 +1,8 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "TickNextTickData.h"
__int64 TickNextTickData::C = 0;
int64_t TickNextTickData::C = 0;
TickNextTickData::TickNextTickData(int x, int y, int z, int tileId) {
m_delay = 0;
@ -12,38 +12,47 @@ TickNextTickData::TickNextTickData(int x, int y, int z, int tileId) {
this->y = y;
this->z = z;
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
// dynamic_cast still fail? We cannot dynamic_cast a void*
if (dynamic_cast<TickNextTickData*>((TickNextTickData*)o) != NULL) {
if (o != NULL) {
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;
}
int TickNextTickData::hashCode() const {
// 4jcraft added cast to unsigned
return ((((unsigned)x * 1024 * 1024) + ((unsigned)z * 1024) + (unsigned)y) *
256) +
tileId;
return (((x * 1024 * 1024) + (z * 1024) + y) * 256);
}
TickNextTickData* TickNextTickData::delay(__int64 l) {
this->m_delay = l;
TickNextTickData* TickNextTickData::delay(int64_t l) {
m_delay = l;
return this;
}
void TickNextTickData::setPriorityTilt(int priorityTilt) {
this->priorityTilt = priorityTilt;
}
int TickNextTickData::compareTo(const TickNextTickData* tnd) const {
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;
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
// 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
@ -62,6 +71,5 @@ int TickNextTickData::hash_fnct(const TickNextTickData& k) {
bool TickNextTickData::eq_test(const TickNextTickData& x,
const TickNextTickData& y) {
return (x.x == y.x) && (x.y == y.y) && (x.z == y.z) &&
(x.tileId == y.tileId);
}
return x.equals(&y);
}

View file

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

View file

@ -67,6 +67,8 @@ void WaterLevelChunk::load() {}
void WaterLevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
{}
bool WaterLevelChunk::containsPlayer() { return false; }
void WaterLevelChunk::markUnsaved() {}
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;
}
Random* WaterLevelChunk::getRandom(__int64 l) {
Random* WaterLevelChunk::getRandom(int64_t l) {
return new Random((level->getSeed() + x * x * 4987142 + x * 5947611 +
z * z * 4392871l + z * 389711) ^
l);

View file

@ -36,6 +36,7 @@ public:
void removeTileEntity(int x, int y, int z);
void load();
void unload(bool unloadTileEntities); // 4J - added parameter
bool containsPlayer(); // 4J added
void markUnsaved();
void getEntities(std::shared_ptr<Entity> except, AABB bb,
std::vector<std::shared_ptr<Entity> >& es);
@ -49,7 +50,7 @@ public:
bool includeLighting = true); // 4J - added includeLighting parameter;
bool testSetBlocksAndData(byteArray data, int x0, int y0, int z0, int x1,
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 void reSyncLighting() {}; // 4J added
};