mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-07 10:17:14 +00:00
TU19: merge Minecraft.World/Level
This commit is contained in:
parent
29522d1ac9
commit
86e08af338
362
Minecraft.World/Level/BaseMobSpawner.cpp
Normal file
362
Minecraft.World/Level/BaseMobSpawner.cpp
Normal 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;
|
||||
}
|
||||
69
Minecraft.World/Level/BaseMobSpawner.h
Normal file
69
Minecraft.World/Level/BaseMobSpawner.h
Normal 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;
|
||||
};
|
||||
17
Minecraft.World/Level/Calendar.cpp
Normal file
17
Minecraft.World/Level/Calendar.cpp
Normal 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;
|
||||
}
|
||||
9
Minecraft.World/Level/Calendar.h
Normal file
9
Minecraft.World/Level/Calendar.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
class Calendar {
|
||||
public:
|
||||
Calendar();
|
||||
|
||||
static unsigned int GetDayOfMonth();
|
||||
static unsigned int GetMonth();
|
||||
};
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -43,4 +43,5 @@ public:
|
|||
NULL); // 4J - added toBlow parameter
|
||||
playerVec3Map* getHitPlayers();
|
||||
Vec3* getHitPlayerKnockback(std::shared_ptr<Player> player);
|
||||
std::shared_ptr<LivingEntity> getSourceMob();
|
||||
};
|
||||
191
Minecraft.World/Level/GameRules.cpp
Normal file
191
Minecraft.World/Level/GameRules.cpp
Normal 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;
|
||||
}*/
|
||||
54
Minecraft.World/Level/GameRules.h
Normal file
54
Minecraft.World/Level/GameRules.h
Normal 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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ) )
|
||||
//{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
8
Minecraft.World/Level/Redstone.cpp
Normal file
8
Minecraft.World/Level/Redstone.cpp
Normal 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;
|
||||
8
Minecraft.World/Level/Redstone.h
Normal file
8
Minecraft.World/Level/Redstone.h
Normal 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;
|
||||
};
|
||||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
};
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue