mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-01 12:03:51 +00:00
TU19: merge Minecraft.Client/Level
This commit is contained in:
parent
1c12bedc86
commit
b319cb3cea
|
|
@ -9,9 +9,11 @@
|
|||
#include "../MinecraftServer.h"
|
||||
#include "ServerLevel.h"
|
||||
#include "../Minecraft.h"
|
||||
#include "../Rendering/Particles/FireworksParticles.h"
|
||||
#include "../../Minecraft.World/Entities/Mobs/PrimedTnt.h"
|
||||
#include "../../Minecraft.World/Blocks/Tile.h"
|
||||
#include "../../Minecraft.World/Blocks/TileEntities/TileEntity.h"
|
||||
#include "../../Minecraft.World/Util/JavaMath.h"
|
||||
|
||||
MultiPlayerLevel::ResetInfo::ResetInfo(int x, int y, int z, int tile,
|
||||
int data) {
|
||||
|
|
@ -53,10 +55,10 @@ MultiPlayerLevel::MultiPlayerLevel(ClientConnection* connection,
|
|||
// multiplayer, this should only be set by receiving a packet from the
|
||||
// server (which happens when a player logs in)
|
||||
// setSpawnPos(new Pos(8, 64, 8));
|
||||
// The base ctor already has made some storage, so need to delete that
|
||||
// The base ctor already has made some storage, so need to delete that
|
||||
if (this->savedDataStorage) delete savedDataStorage;
|
||||
if (connection != NULL) {
|
||||
this->savedDataStorage = connection->savedDataStorage;
|
||||
savedDataStorage = connection->savedDataStorage;
|
||||
}
|
||||
unshareCheckX = 0;
|
||||
unshareCheckZ = 0;
|
||||
|
|
@ -88,17 +90,30 @@ void MultiPlayerLevel::shareChunkAt(int x, int z) {
|
|||
|
||||
void MultiPlayerLevel::tick() {
|
||||
PIXBeginNamedEvent(0, "Sky color changing");
|
||||
setTime(getTime() + 1);
|
||||
setGameTime(getGameTime() + 1);
|
||||
if (getGameRules()->getBoolean(GameRules::RULE_DAYLIGHT)) {
|
||||
// 4J: Debug setting added to keep it at day time
|
||||
#ifndef _FINAL_BUILD
|
||||
bool freezeTime =
|
||||
app.DebugSettingsOn() &&
|
||||
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
|
||||
(1L << eDebugSetting_FreezeTime);
|
||||
if (!freezeTime)
|
||||
#endif
|
||||
{
|
||||
setDayTime(getDayTime() + 1);
|
||||
}
|
||||
}
|
||||
/* 4J - change brought forward from 1.8.2
|
||||
int newDark = this->getSkyDarken(1);
|
||||
if (newDark != skyDarken)
|
||||
int newDark = this->getSkyDarken(1);
|
||||
if (newDark != skyDarken)
|
||||
{
|
||||
skyDarken = newDark;
|
||||
for (unsigned int i = 0; i < listeners.size(); i++)
|
||||
{
|
||||
listeners[i]->skyColorChanged();
|
||||
{
|
||||
listeners[i]->skyColorChanged();
|
||||
}
|
||||
}*/
|
||||
}*/
|
||||
PIXEndNamedEvent();
|
||||
|
||||
PIXBeginNamedEvent(0, "Entity re-entry");
|
||||
|
|
@ -128,7 +143,8 @@ if (newDark != skyDarken)
|
|||
for (unsigned int i = 0; i < updatesToReset.size(); i++) {
|
||||
ResetInfo& r = updatesToReset[i];
|
||||
if (--r.ticks == 0) {
|
||||
Level::setTileAndDataNoUpdate(r.x, r.y, r.z, r.tile, r.data);
|
||||
Level::setTileAndData(r.x, r.y, r.z, r.tile, r.data,
|
||||
Tile::UPDATE_ALL);
|
||||
Level::sendTileUpdated(r.x, r.y, r.z);
|
||||
|
||||
// updatesToReset.erase(updatesToReset.begin()+i);
|
||||
|
|
@ -387,7 +403,7 @@ void MultiPlayerLevel::tickTiles() {
|
|||
int xo = cp.x * 16;
|
||||
int zo = cp.z * 16;
|
||||
|
||||
LevelChunk* lc = this->getChunk(cp.x, cp.z);
|
||||
LevelChunk* lc = getChunk(cp.x, cp.z);
|
||||
|
||||
tickClientSideTiles(xo, zo, lc);
|
||||
}
|
||||
|
|
@ -402,8 +418,8 @@ void MultiPlayerLevel::setChunkVisible(int x, int z, bool visible) {
|
|||
chunkCache->drop(x, z);
|
||||
}
|
||||
if (!visible) {
|
||||
this->setTilesDirty(x * 16, 0, z * 16, x * 16 + 15,
|
||||
Level::maxBuildHeight, z * 16 + 15);
|
||||
setTilesDirty(x * 16, 0, z * 16, x * 16 + 15, Level::maxBuildHeight,
|
||||
z * 16 + 15);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +472,7 @@ void MultiPlayerLevel::putEntity(int id, std::shared_ptr<Entity> e) {
|
|||
forced.insert(e);
|
||||
e->entityId = id;
|
||||
if (!addEntity(e)) {
|
||||
this->reEntries.insert(e);
|
||||
reEntries.insert(e);
|
||||
}
|
||||
entitiesById[id] = e;
|
||||
}
|
||||
|
|
@ -498,14 +514,32 @@ void MultiPlayerLevel::removeEntities(
|
|||
Level::removeEntities(list);
|
||||
}
|
||||
|
||||
bool MultiPlayerLevel::setDataNoUpdate(int x, int y, int z, int data) {
|
||||
int t = getTile(x, y, z);
|
||||
bool MultiPlayerLevel::setData(
|
||||
int x, int y, int z, int data, int updateFlags,
|
||||
bool forceUpdate /*=false*/) // 4J added forceUpdate)
|
||||
{
|
||||
// First check if this isn't going to do anything, because if it isn't then
|
||||
// the next stage (of unsharing data) is really quite expensive so far
|
||||
// better to early out here
|
||||
int d = getData(x, y, z);
|
||||
|
||||
if ((d == data)) {
|
||||
// If we early-out, its important that we still do a checkLight here
|
||||
// (which would otherwise have happened as part of
|
||||
// Level::setTileAndDataNoUpdate) This is because since we are
|
||||
// potentially sharing tile/data but not lighting data, it is possible
|
||||
// that the server might tell a client of a lighting update that doesn't
|
||||
// need actioned on the client just because the chunk's data was being
|
||||
// shared with the server when it was set. However, the lighting data
|
||||
// will potentially now be out of sync on the client.
|
||||
checkLight(x, y, z);
|
||||
return false;
|
||||
}
|
||||
// 4J - added - if this is the host, then stop sharing block data with the
|
||||
// server at this point
|
||||
unshareChunkAt(x, z);
|
||||
|
||||
if (Level::setDataNoUpdate(x, y, z, data)) {
|
||||
if (Level::setData(x, y, z, data, updateFlags, forceUpdate)) {
|
||||
// if(m_bEnableResetChanges) updatesToReset.push_back(ResetInfo(x, y, z,
|
||||
// t, d));
|
||||
return true;
|
||||
|
|
@ -515,8 +549,8 @@ bool MultiPlayerLevel::setDataNoUpdate(int x, int y, int z, int data) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MultiPlayerLevel::setTileAndDataNoUpdate(int x, int y, int z, int tile,
|
||||
int data) {
|
||||
bool MultiPlayerLevel::setTileAndData(int x, int y, int z, int tile, int data,
|
||||
int updateFlags) {
|
||||
// First check if this isn't going to do anything, because if it isn't then
|
||||
// the next stage (of unsharing data) is really quite expensive so far
|
||||
// better to early out here
|
||||
|
|
@ -539,24 +573,7 @@ bool MultiPlayerLevel::setTileAndDataNoUpdate(int x, int y, int z, int tile,
|
|||
// server at this point
|
||||
unshareChunkAt(x, z);
|
||||
|
||||
if (Level::setTileAndDataNoUpdate(x, y, z, tile, data)) {
|
||||
// if(m_bEnableResetChanges) updatesToReset.push_back(ResetInfo(x, y, z,
|
||||
// t, d));
|
||||
return true;
|
||||
}
|
||||
// Didn't actually need to stop sharing
|
||||
shareChunkAt(x, z);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MultiPlayerLevel::setTileNoUpdate(int x, int y, int z, int tile) {
|
||||
int t = getTile(x, y, z);
|
||||
int d = getData(x, y, z);
|
||||
// 4J - added - if this is the host, then stop sharing block data with the
|
||||
// server at this point
|
||||
unshareChunkAt(x, z);
|
||||
|
||||
if (Level::setTileNoUpdate(x, y, z, tile)) {
|
||||
if (Level::setTileAndData(x, y, z, tile, data, updateFlags)) {
|
||||
// if(m_bEnableResetChanges) updatesToReset.push_back(ResetInfo(x, y, z,
|
||||
// t, d));
|
||||
return true;
|
||||
|
|
@ -585,7 +602,7 @@ bool MultiPlayerLevel::doSetTileAndData(int x, int y, int z, int tile,
|
|||
// If we're the host, need to tell the renderer for updates even if they
|
||||
// don't change things as the host might have been sharing data and so set
|
||||
// it already, but the renderer won't know to update
|
||||
if ((Level::setTileAndData(x, y, z, tile, data) ||
|
||||
if ((Level::setTileAndData(x, y, z, tile, data, Tile::UPDATE_ALL) ||
|
||||
g_NetworkManager.IsHost())) {
|
||||
if (g_NetworkManager.IsHost() && visuallyImportant) {
|
||||
// 4J Stu - This got removed from the tileUpdated function in TU14.
|
||||
|
|
@ -613,13 +630,15 @@ void MultiPlayerLevel::disconnect(bool sendDisconnect /*= true*/) {
|
|||
}
|
||||
}
|
||||
|
||||
Tickable* MultiPlayerLevel::makeSoundUpdater(
|
||||
std::shared_ptr<Minecart> minecart) {
|
||||
return NULL; // new MinecartSoundUpdater(minecraft->soundEngine, minecart,
|
||||
// minecraft->player);
|
||||
}
|
||||
|
||||
void MultiPlayerLevel::tickWeather() {
|
||||
if (dimension->hasCeiling) return;
|
||||
|
||||
if (lightningTime > 0) {
|
||||
lightningTime--;
|
||||
}
|
||||
|
||||
oRainLevel = rainLevel;
|
||||
if (levelData->isRaining()) {
|
||||
rainLevel += 0.01;
|
||||
|
|
@ -731,6 +750,7 @@ void MultiPlayerLevel::playSound(std::shared_ptr<Entity> entity, int iSound,
|
|||
|
||||
void MultiPlayerLevel::playLocalSound(double x, double y, double z, int iSound,
|
||||
float volume, float pitch,
|
||||
bool distanceDelay /*= false */,
|
||||
float fClipSoundDist) {
|
||||
// float dd = 16;
|
||||
if (volume > 1) fClipSoundDist *= volume;
|
||||
|
|
@ -747,11 +767,50 @@ void MultiPlayerLevel::playLocalSound(double x, double y, double z, int iSound,
|
|||
}
|
||||
|
||||
if (minDistSq < fClipSoundDist * fClipSoundDist) {
|
||||
minecraft->soundEngine->play(iSound, (float)x, (float)y, (float)z,
|
||||
volume, pitch);
|
||||
if (distanceDelay && minDistSq > 10 * 10) {
|
||||
// exhaggerate sound speed effect by making speed of sound ~=
|
||||
// 40 m/s instead of 300 m/s
|
||||
double delayInSeconds = sqrt(minDistSq) / 40.0;
|
||||
minecraft->soundEngine->schedule(
|
||||
iSound, (float)x, (float)y, (float)z, volume, pitch,
|
||||
(int)Math::round(delayInSeconds *
|
||||
SharedConstants::TICKS_PER_SECOND));
|
||||
} else {
|
||||
minecraft->soundEngine->play(iSound, (float)x, (float)y, (float)z,
|
||||
volume, pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPlayerLevel::createFireworks(double x, double y, double z, double xd,
|
||||
double yd, double zd,
|
||||
CompoundTag* infoTag) {
|
||||
minecraft->particleEngine->add(
|
||||
std::shared_ptr<FireworksParticles::FireworksStarter>(
|
||||
new FireworksParticles::FireworksStarter(this, x, y, z, xd, yd, zd,
|
||||
minecraft->particleEngine,
|
||||
infoTag)));
|
||||
}
|
||||
|
||||
void MultiPlayerLevel::setScoreboard(Scoreboard* scoreboard) {
|
||||
this->scoreboard = scoreboard;
|
||||
}
|
||||
|
||||
void MultiPlayerLevel::setDayTime(int64_t newTime) {
|
||||
// 4J: We send daylight cycle rule with host options so don't need this
|
||||
/*if (newTime < 0)
|
||||
{
|
||||
newTime = -newTime;
|
||||
getGameRules()->set(GameRules::RULE_DAYLIGHT, L"false");
|
||||
}
|
||||
else
|
||||
{
|
||||
getGameRules()->set(GameRules::RULE_DAYLIGHT, L"true");
|
||||
}*/
|
||||
|
||||
Level::setDayTime(newTime);
|
||||
}
|
||||
|
||||
void MultiPlayerLevel::removeAllPendingEntityRemovals() {
|
||||
// entities.removeAll(entitiesToRemove);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ private:
|
|||
ResetInfo(int x, int y, int z, int tile, int data);
|
||||
};
|
||||
|
||||
std::vector<ResetInfo> updatesToReset; // 4J - was linked list but vector
|
||||
// seems more appropriate
|
||||
bool m_bEnableResetChanges; // 4J Added
|
||||
std::vector<ResetInfo>
|
||||
updatesToReset; // 4J - was linked list but std::vector seems more
|
||||
// appropriate
|
||||
bool m_bEnableResetChanges; // 4J Added
|
||||
public:
|
||||
void unshareChunkAt(int x, int z); // 4J - added
|
||||
void shareChunkAt(int x, int z); // 4J - added
|
||||
|
|
@ -34,10 +35,11 @@ private:
|
|||
int compressCheckX; // 4J - added
|
||||
int compressCheckZ; // 4J - added
|
||||
std::vector<ClientConnection*>
|
||||
connections; // 4J Stu - Made this a vector as we can have more than
|
||||
// one local connection
|
||||
connections; // 4J Stu - Made this a std::vector as we can have more
|
||||
// than one local connection
|
||||
MultiPlayerChunkCache* chunkCache;
|
||||
Minecraft* minecraft;
|
||||
Scoreboard* scoreboard;
|
||||
|
||||
public:
|
||||
MultiPlayerLevel(ClientConnection* connection, LevelSettings* levelSettings,
|
||||
|
|
@ -79,15 +81,16 @@ public:
|
|||
std::shared_ptr<Entity> removeEntity(int id);
|
||||
virtual void removeEntities(
|
||||
std::vector<std::shared_ptr<Entity> >* list); // 4J Added override
|
||||
virtual bool setDataNoUpdate(int x, int y, int z, int data);
|
||||
virtual bool setTileAndDataNoUpdate(int x, int y, int z, int tile,
|
||||
int data);
|
||||
virtual bool setTileNoUpdate(int x, int y, int z, int tile);
|
||||
virtual bool setData(int x, int y, int z, int data, int updateFlags,
|
||||
bool forceUpdate = false);
|
||||
virtual bool setTileAndData(int x, int y, int z, int tile, int data,
|
||||
int updateFlags);
|
||||
bool doSetTileAndData(int x, int y, int z, int tile, int data);
|
||||
virtual void disconnect(bool sendDisconnect = true);
|
||||
void animateTick(int xt, int yt, int zt);
|
||||
|
||||
protected:
|
||||
virtual Tickable* makeSoundUpdater(std::shared_ptr<Minecart> minecart);
|
||||
virtual void tickWeather();
|
||||
|
||||
static const int ANIMATE_TICK_MAX_PARTICLES = 500;
|
||||
|
|
@ -104,8 +107,14 @@ public:
|
|||
|
||||
virtual void playLocalSound(double x, double y, double z, int iSound,
|
||||
float volume, float pitch,
|
||||
bool distanceDelay = false,
|
||||
float fClipSoundDist = 16.0f);
|
||||
|
||||
virtual void createFireworks(double x, double y, double z, double xd,
|
||||
double yd, double zd, CompoundTag* infoTag);
|
||||
virtual void setScoreboard(Scoreboard* scoreboard);
|
||||
virtual void setDayTime(int64_t newTime);
|
||||
|
||||
// 4J Stu - Added so we can have multiple local connections
|
||||
void addClientConnection(ClientConnection* c) { connections.push_back(c); }
|
||||
void removeClientConnection(ClientConnection* c, bool sendDisconnect);
|
||||
|
|
|
|||
|
|
@ -6,33 +6,36 @@
|
|||
#include "../Player/ServerPlayer.h"
|
||||
#include "../Network/PlayerConnection.h"
|
||||
#include "../Player/EntityTracker.h"
|
||||
#include "../Network/ServerScoreboard.h"
|
||||
#include "../../Minecraft.World/Scores/ScoreboardSaveData.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.dimension.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.storage.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.chunk.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.biome.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.item.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.ai.village.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.player.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.npc.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.global.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.npc.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.entity.player.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.biome.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.chunk.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.dimension.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.levelgen.feature.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.storage.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.scores.h"
|
||||
#include "../../Minecraft.World/Entities/ItemEntity.h"
|
||||
#include "../../Minecraft.World/Entities/Mobs/Arrow.h"
|
||||
#include "../../Minecraft.World/Entities/Mobs/PrimedTnt.h"
|
||||
#include "../../Minecraft.World/Blocks/FallingTile.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.network.packet.h"
|
||||
#include "../../Minecraft.World/Util/Mth.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.level.levelgen.feature.h"
|
||||
#include "../../Minecraft.World/Headers/net.minecraft.world.item.h"
|
||||
#include "../../Minecraft.World/WorldGen/Structures/StructurePiece.h"
|
||||
#include "ServerLevelListener.h"
|
||||
#include "../Minecraft.Client/ServerLevelListener.h"
|
||||
#include "../../Minecraft.World/Util/WeighedTreasure.h"
|
||||
#include "../Textures/Packs/TexturePackRepository.h"
|
||||
#include "../Textures/Packs/DLCTexturePack.h"
|
||||
#include "../../Minecraft.World/Util/ProgressListener.h"
|
||||
#include "../Platform/PS3/PS3Extras/ShutdownManager.h"
|
||||
#include "PS3/PS3Extras/ShutdownManager.h"
|
||||
#include "../Network/PlayerChunkMap.h"
|
||||
|
||||
WeighedTreasureArray ServerLevel::RANDOM_BONUS_ITEMS;
|
||||
|
|
@ -100,7 +103,7 @@ void ServerLevel::staticCtor() {
|
|||
RANDOM_BONUS_ITEMS[17] = new WeighedTreasure(Item::potato_Id, 0, 1, 2, 3);
|
||||
RANDOM_BONUS_ITEMS[18] = new WeighedTreasure(Item::carrots_Id, 0, 1, 2, 3);
|
||||
RANDOM_BONUS_ITEMS[19] =
|
||||
new WeighedTreasure(Tile::mushroom1_Id, 0, 1, 2, 2);
|
||||
new WeighedTreasure(Tile::mushroom_brown_Id, 0, 1, 2, 2);
|
||||
};
|
||||
|
||||
ServerLevel::ServerLevel(MinecraftServer* server,
|
||||
|
|
@ -132,9 +135,25 @@ ServerLevel::ServerLevel(MinecraftServer* server,
|
|||
// of this ctor but setting up early here
|
||||
addListener(new ServerLevelListener(server, this));
|
||||
|
||||
this->tracker = new EntityTracker(this);
|
||||
this->chunkMap = new PlayerChunkMap(
|
||||
this, dimension, server->getPlayers()->getViewDistance());
|
||||
tracker = new EntityTracker(this);
|
||||
chunkMap = new PlayerChunkMap(this, dimension,
|
||||
server->getPlayers()->getViewDistance());
|
||||
|
||||
mobSpawner = new MobSpawner();
|
||||
portalForcer = new PortalForcer(this);
|
||||
scoreboard = new ServerScoreboard(server);
|
||||
|
||||
// shared_ptr<ScoreboardSaveData> scoreboardSaveData =
|
||||
// std::dynamic_pointer_cast<ScoreboardSaveData>(
|
||||
// savedDataStorage->get(typeid(ScoreboardSaveData),
|
||||
// ScoreboardSaveData::FILE_ID) ); if (scoreboardSaveData == NULL)
|
||||
//{
|
||||
// scoreboardSaveData = shared_ptr<ScoreboardSaveData>( new
|
||||
// ScoreboardSaveData() );
|
||||
// savedDataStorage->set(ScoreboardSaveData::FILE_ID, scoreboardSaveData);
|
||||
// }
|
||||
// scoreboardSaveData->setScoreboard(scoreboard);
|
||||
//((ServerScoreboard *) scoreboard)->setSaveData(scoreboardSaveData);
|
||||
|
||||
// This also used to be called in parent ctor, but can't be called until
|
||||
// chunkSource is created. Call now if required.
|
||||
|
|
@ -171,6 +190,9 @@ ServerLevel::ServerLevel(MinecraftServer* server,
|
|||
}
|
||||
|
||||
ServerLevel::~ServerLevel() {
|
||||
delete portalForcer;
|
||||
delete mobSpawner;
|
||||
|
||||
EnterCriticalSection(&m_csQueueSendTileUpdates);
|
||||
for (AUTO_VAR(it, m_queuedSendTileUpdates.begin());
|
||||
it != m_queuedSendTileUpdates.end(); ++it) {
|
||||
|
|
@ -207,34 +229,47 @@ void ServerLevel::tick() {
|
|||
dimension->biomeSource->update();
|
||||
|
||||
if (allPlayersAreSleeping()) {
|
||||
bool somebodyWokeUp = false;
|
||||
if (spawnEnemies && difficulty >= Difficulty::EASY) {
|
||||
}
|
||||
|
||||
if (!somebodyWokeUp) {
|
||||
if (getGameRules()->getBoolean(GameRules::RULE_DAYLIGHT)) {
|
||||
// skip time until new day
|
||||
__int64 newTime = levelData->getTime() + TICKS_PER_DAY;
|
||||
int64_t newTime = levelData->getDayTime() + TICKS_PER_DAY;
|
||||
|
||||
// 4J : WESTY : Changed so that time update goes through stats
|
||||
// tracking update code.
|
||||
// levelData->setTime(newTime - (newTime % TICKS_PER_DAY));
|
||||
setTime(newTime - (newTime % TICKS_PER_DAY));
|
||||
|
||||
awakenAllPlayers();
|
||||
setDayTime(newTime - (newTime % TICKS_PER_DAY));
|
||||
}
|
||||
awakenAllPlayers();
|
||||
}
|
||||
|
||||
PIXBeginNamedEvent(0, "Mob spawner tick");
|
||||
// for Minecraft 1.8, spawn friendlies really rarely - 4J - altered
|
||||
// from once every 400 ticks to 40 ticks as we depend on this a more than
|
||||
// the original since we don't have chunk post-process spawning
|
||||
MobSpawner::tick(this, spawnEnemies,
|
||||
spawnFriendlies && (levelData->getTime() % 40) == 0);
|
||||
if (getGameRules()->getBoolean(GameRules::RULE_DOMOBSPAWNING)) {
|
||||
// Note - these flags are used logically in an inverted way. Mob
|
||||
// spawning is not performed if: (1) finalSpawnEnemies isn't set, and
|
||||
// mob category isn't friendly (2) finalSpawnFriendlies isn't set, and
|
||||
// mob category is friendly (3) finalSpawnPersistent isn't set, and mob
|
||||
// category is persistent
|
||||
bool finalSpawnEnemies =
|
||||
spawnEnemies && ((levelData->getGameTime() % 2) ==
|
||||
0); // Spawn enemies every other tick
|
||||
bool finalSpawnFriendlies =
|
||||
spawnFriendlies && ((levelData->getGameTime() % 40) ==
|
||||
0); // Spawn friendlies once per 40 ticks
|
||||
bool finalSpawnPersistent =
|
||||
finalSpawnFriendlies &&
|
||||
((levelData->getGameTime() % 80) ==
|
||||
0); // All persistents are also friendly - do them once every
|
||||
// other friendly spawning, ie once per 80 ticks
|
||||
mobSpawner->tick(this, finalSpawnEnemies, finalSpawnFriendlies,
|
||||
finalSpawnPersistent);
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
PIXBeginNamedEvent(0, "Chunk source tick");
|
||||
chunkSource->tick();
|
||||
PIXEndNamedEvent();
|
||||
int newDark = this->getOldSkyDarken(1);
|
||||
int newDark = getOldSkyDarken(1);
|
||||
if (newDark != skyDarken) {
|
||||
skyDarken = newDark;
|
||||
if (!SharedConstants::TEXTURE_LIGHTING) // 4J - change brought forward
|
||||
|
|
@ -247,17 +282,12 @@ void ServerLevel::tick() {
|
|||
}
|
||||
}
|
||||
|
||||
PIXBeginNamedEvent(0, "runTileEvents");
|
||||
// run after entity updates
|
||||
runTileEvents();
|
||||
PIXEndNamedEvent();
|
||||
|
||||
// 4J - temporarily disabling saves as they are causing gameplay to
|
||||
// generally stutter quite a lot
|
||||
|
||||
__int64 time = levelData->getTime() + 1;
|
||||
// 4J Stu - Putting this back in, but I have reduced the number of chunks that
|
||||
// save when not forced
|
||||
int64_t time = levelData->getGameTime() + 1;
|
||||
// 4J Stu - Putting this back in, but I have reduced the number of chunks
|
||||
// that save when not forced
|
||||
#ifdef _LARGE_WORLDS
|
||||
if (time % (saveInterval) == (dimension->id + 1))
|
||||
#else
|
||||
|
|
@ -274,7 +304,20 @@ void ServerLevel::tick() {
|
|||
// 4J : WESTY : Changed so that time update goes through stats tracking
|
||||
// update code.
|
||||
// levelData->setTime(time);
|
||||
setTime(time);
|
||||
setGameTime(levelData->getGameTime() + 1);
|
||||
if (getGameRules()->getBoolean(GameRules::RULE_DAYLIGHT)) {
|
||||
// 4J: Debug setting added to keep it at day time
|
||||
#ifndef _FINAL_BUILD
|
||||
bool freezeTime =
|
||||
app.DebugSettingsOn() &&
|
||||
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
|
||||
(1L << eDebugSetting_FreezeTime);
|
||||
if (!freezeTime)
|
||||
#endif
|
||||
{
|
||||
setDayTime(levelData->getDayTime() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
PIXBeginNamedEvent(0, "Tick pending ticks");
|
||||
// if (tickCount % 5 == 0) {
|
||||
|
|
@ -296,8 +339,14 @@ void ServerLevel::tick() {
|
|||
// MemSect(0);
|
||||
PIXEndNamedEvent();
|
||||
|
||||
PIXBeginNamedEvent(0, "Tick portal forcer");
|
||||
portalForcer->tick(getGameTime());
|
||||
PIXEndNamedEvent();
|
||||
|
||||
// repeat after tile ticks
|
||||
PIXBeginNamedEvent(0, "runTileEvents");
|
||||
runTileEvents();
|
||||
PIXEndNamedEvent();
|
||||
|
||||
// 4J Added
|
||||
runQueuedSendTileUpdates();
|
||||
|
|
@ -318,8 +367,7 @@ void ServerLevel::updateSleepingPlayerList() {
|
|||
m_bAtLeastOnePlayerSleeping = false;
|
||||
|
||||
AUTO_VAR(itEnd, players.end());
|
||||
for (std::vector<std::shared_ptr<Player> >::iterator it = players.begin();
|
||||
it != itEnd; it++) {
|
||||
for (AUTO_VAR(it, players.begin()); it != itEnd; it++) {
|
||||
if (!(*it)->isSleeping()) {
|
||||
allPlayersSleeping = false;
|
||||
// break;
|
||||
|
|
@ -477,7 +525,7 @@ void ServerLevel::tickTiles() {
|
|||
m_updateChunkX[iLev][m_updateChunkCount[iLev]] = cp.x;
|
||||
m_updateChunkZ[iLev][m_updateChunkCount[iLev]++] = cp.z;
|
||||
|
||||
LevelChunk* lc = this->getChunk(cp.x, cp.z);
|
||||
LevelChunk* lc = getChunk(cp.x, cp.z);
|
||||
tickClientSideTiles(xo, zo, lc);
|
||||
|
||||
if (random->nextInt(prob) == 0 && isRaining() && isThundering()) {
|
||||
|
|
@ -490,23 +538,21 @@ void ServerLevel::tickTiles() {
|
|||
if (isRainingAt(x, y, z)) {
|
||||
addGlobalEntity(std::shared_ptr<LightningBolt>(
|
||||
new LightningBolt(this, x, y, z)));
|
||||
lightningTime = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// 4J - changes here brought forrward from 1.2.3
|
||||
if (random->nextInt(16) == 0) {
|
||||
// 4jcraft added cast to unsigned
|
||||
randValue = (unsigned)randValue * 3 + (unsigned)addend;
|
||||
randValue = randValue * 3 + addend;
|
||||
int val = (randValue >> 2);
|
||||
int x = (val & 15);
|
||||
int z = ((val >> 8) & 15);
|
||||
int yy = this->getTopRainBlock(x + xo, z + zo);
|
||||
int yy = getTopRainBlock(x + xo, z + zo);
|
||||
if (shouldFreeze(x + xo, yy - 1, z + zo)) {
|
||||
setTile(x + xo, yy - 1, z + zo, Tile::ice_Id);
|
||||
setTileAndUpdate(x + xo, yy - 1, z + zo, Tile::ice_Id);
|
||||
}
|
||||
if (isRaining() && shouldSnow(x + xo, yy, z + zo)) {
|
||||
setTile(x + xo, yy, z + zo, Tile::topSnow_Id);
|
||||
setTileAndUpdate(x + xo, yy, z + zo, Tile::topSnow_Id);
|
||||
}
|
||||
if (isRaining()) {
|
||||
Biome* b = getBiome(x + xo, z + zo);
|
||||
|
|
@ -531,26 +577,42 @@ void ServerLevel::tickTiles() {
|
|||
m_updateTrigger->Set(iLev);
|
||||
}
|
||||
|
||||
bool ServerLevel::isTileToBeTickedAt(int x, int y, int z, int tileId) {
|
||||
TickNextTickData td = TickNextTickData(x, y, z, tileId);
|
||||
return find(toBeTicked.begin(), toBeTicked.end(), td) != toBeTicked.end();
|
||||
}
|
||||
|
||||
void ServerLevel::addToTickNextTick(int x, int y, int z, int tileId,
|
||||
int tickDelay) {
|
||||
addToTickNextTick(x, y, z, tileId, tickDelay, 0);
|
||||
}
|
||||
|
||||
void ServerLevel::addToTickNextTick(int x, int y, int z, int tileId,
|
||||
int tickDelay, int priorityTilt) {
|
||||
MemSect(27);
|
||||
TickNextTickData td = TickNextTickData(x, y, z, tileId);
|
||||
int r = 8;
|
||||
if (getInstaTick()) {
|
||||
if (hasChunksAt(td.x - r, td.y - r, td.z - r, td.x + r, td.y + r,
|
||||
td.z + r)) {
|
||||
int id = getTile(td.x, td.y, td.z);
|
||||
if (id == td.tileId && id > 0) {
|
||||
Tile::tiles[id]->tick(this, td.x, td.y, td.z, random);
|
||||
int r = 0;
|
||||
if (getInstaTick() && tileId > 0) {
|
||||
if (Tile::tiles[tileId]->canInstantlyTick()) {
|
||||
r = 8;
|
||||
if (hasChunksAt(td.x - r, td.y - r, td.z - r, td.x + r, td.y + r,
|
||||
td.z + r)) {
|
||||
int id = getTile(td.x, td.y, td.z);
|
||||
if (id == td.tileId && id > 0) {
|
||||
Tile::tiles[id]->tick(this, td.x, td.y, td.z, random);
|
||||
}
|
||||
}
|
||||
MemSect(0);
|
||||
return;
|
||||
} else {
|
||||
tickDelay = 1;
|
||||
}
|
||||
MemSect(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) {
|
||||
if (tileId > 0) {
|
||||
td.delay(tickDelay + levelData->getTime());
|
||||
td.delay(tickDelay + levelData->getGameTime());
|
||||
td.setPriorityTilt(priorityTilt);
|
||||
}
|
||||
EnterCriticalSection(&m_tickNextTickCS);
|
||||
if (tickNextTickSet.find(td) == tickNextTickSet.end()) {
|
||||
|
|
@ -563,11 +625,12 @@ void ServerLevel::addToTickNextTick(int x, int y, int z, int tileId,
|
|||
}
|
||||
|
||||
void ServerLevel::forceAddTileTick(int x, int y, int z, int tileId,
|
||||
int tickDelay) {
|
||||
int tickDelay, int prioTilt) {
|
||||
TickNextTickData td = TickNextTickData(x, y, z, tileId);
|
||||
td.setPriorityTilt(prioTilt);
|
||||
|
||||
if (tileId > 0) {
|
||||
td.delay(tickDelay + levelData->getTime());
|
||||
td.delay(tickDelay + levelData->getGameTime());
|
||||
}
|
||||
EnterCriticalSection(&m_tickNextTickCS);
|
||||
if (tickNextTickSet.find(td) == tickNextTickSet.end()) {
|
||||
|
|
@ -583,12 +646,14 @@ void ServerLevel::tickEntities() {
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
emptyTime = 0;
|
||||
resetEmptyTime();
|
||||
}
|
||||
|
||||
Level::tickEntities();
|
||||
}
|
||||
|
||||
void ServerLevel::resetEmptyTime() { emptyTime = 0; }
|
||||
|
||||
bool ServerLevel::tickPendingTicks(bool force) {
|
||||
EnterCriticalSection(&m_tickNextTickCS);
|
||||
int count = (int)tickNextTickList.size();
|
||||
|
|
@ -602,22 +667,33 @@ bool ServerLevel::tickPendingTicks(bool force) {
|
|||
AUTO_VAR(itTickList, tickNextTickList.begin());
|
||||
for (int i = 0; i < count; i++) {
|
||||
TickNextTickData td = *(itTickList);
|
||||
if (!force && td.m_delay > levelData->getTime()) {
|
||||
if (!force && td.m_delay > levelData->getGameTime()) {
|
||||
break;
|
||||
}
|
||||
|
||||
itTickList = tickNextTickList.erase(itTickList);
|
||||
tickNextTickSet.erase(td);
|
||||
int r = 8;
|
||||
toBeTicked.push_back(td);
|
||||
}
|
||||
|
||||
for (AUTO_VAR(it, toBeTicked.begin()); it != toBeTicked.end();) {
|
||||
TickNextTickData td = *it;
|
||||
it = toBeTicked.erase(it);
|
||||
|
||||
int r = 0;
|
||||
if (hasChunksAt(td.x - r, td.y - r, td.z - r, td.x + r, td.y + r,
|
||||
td.z + r)) {
|
||||
int id = getTile(td.x, td.y, td.z);
|
||||
if (id == td.tileId && id > 0) {
|
||||
if (id > 0 && Tile::isMatching(id, td.tileId)) {
|
||||
Tile::tiles[id]->tick(this, td.x, td.y, td.z, random);
|
||||
}
|
||||
} else {
|
||||
addToTickNextTick(td.x, td.y, td.z, td.tileId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
toBeTicked.clear();
|
||||
|
||||
int count3 = (int)tickNextTickList.size();
|
||||
int count4 = (int)tickNextTickSet.size();
|
||||
|
||||
|
|
@ -640,20 +716,47 @@ std::vector<TickNextTickData>* ServerLevel::fetchTicksInChunk(LevelChunk* chunk,
|
|||
int south = north + 16;
|
||||
delete pos;
|
||||
|
||||
for (AUTO_VAR(it, tickNextTickSet.begin()); it != tickNextTickSet.end();) {
|
||||
TickNextTickData td = *it;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (i == 0) {
|
||||
for (AUTO_VAR(it, tickNextTickList.begin());
|
||||
it != tickNextTickList.end();) {
|
||||
TickNextTickData td = *it;
|
||||
|
||||
if (td.x >= west && td.x < east && td.z >= north && td.z < south) {
|
||||
if (remove) {
|
||||
tickNextTickList.erase(td);
|
||||
it = tickNextTickSet.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
if (td.x >= xMin && td.x < xMax && td.z >= zMin &&
|
||||
td.z < zMax) {
|
||||
if (remove) {
|
||||
tickNextTickSet.erase(td);
|
||||
it = tickNextTickList.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
|
||||
results->push_back(td);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
results->push_back(td);
|
||||
} else {
|
||||
it++;
|
||||
if (!toBeTicked.empty()) {
|
||||
app.DebugPrintf("To be ticked size: %d\n", toBeTicked.size());
|
||||
}
|
||||
for (AUTO_VAR(it, toBeTicked.begin()); it != toBeTicked.end();) {
|
||||
TickNextTickData td = *it;
|
||||
|
||||
if (td.x >= xMin && td.x < xMax && td.z >= zMin &&
|
||||
td.z < zMax) {
|
||||
if (remove) {
|
||||
tickNextTickList.erase(td);
|
||||
it = toBeTicked.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
|
||||
results->push_back(td);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -663,19 +766,14 @@ std::vector<TickNextTickData>* ServerLevel::fetchTicksInChunk(LevelChunk* chunk,
|
|||
|
||||
void ServerLevel::tick(std::shared_ptr<Entity> e, bool actual) {
|
||||
if (!server->isAnimals() &&
|
||||
((e->GetType() & eTYPE_ANIMAL) || (e->GetType() & eTYPE_WATERANIMAL))) {
|
||||
(e->instanceof(eTYPE_ANIMAL) || e->instanceof(eTYPE_WATERANIMAL))) {
|
||||
e->remove();
|
||||
}
|
||||
if (!server->isNpcsEnabled() &&
|
||||
(std::dynamic_pointer_cast<Npc>(e) != NULL)) {
|
||||
e->remove();
|
||||
}
|
||||
if (e->rider.lock() == NULL ||
|
||||
(std::dynamic_pointer_cast<Player>(e->rider.lock()) ==
|
||||
NULL)) // 4J - was !(e->rider instanceof Player)
|
||||
{
|
||||
Level::tick(e, actual);
|
||||
}
|
||||
Level::tick(e, actual);
|
||||
}
|
||||
|
||||
void ServerLevel::forceTick(std::shared_ptr<Entity> e, bool actual) {
|
||||
|
|
@ -715,10 +813,7 @@ bool ServerLevel::mayInteract(std::shared_ptr<Player> player, int xt, int yt,
|
|||
return true;
|
||||
} else if (dimension->id == 0) // 4J Stu - Only limit this in the overworld
|
||||
{
|
||||
int xd = (int)Mth::abs((float)(xt - levelData->getXSpawn()));
|
||||
int zd = (int)Mth::abs((float)(zt - levelData->getZSpawn()));
|
||||
if (xd > zd) zd = xd;
|
||||
return (zd > 16 || server->getPlayers()->isOp(player->name));
|
||||
return !server->isUnderSpawnProtection(this, xt, yt, zt, player);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -891,7 +986,7 @@ void ServerLevel::save(bool force, ProgressListener* progressListener,
|
|||
// if( force && !isClientSide )
|
||||
//{
|
||||
// if (progressListener != NULL)
|
||||
//progressListener->progressStage(IDS_PROGRESS_SAVING_TO_DISC);
|
||||
// progressListener->progressStage(IDS_PROGRESS_SAVING_TO_DISC);
|
||||
// levelStorage->flushSaveFile();
|
||||
// }
|
||||
}
|
||||
|
|
@ -1073,9 +1168,9 @@ void ServerLevel::runTileEvents() {
|
|||
bool ServerLevel::doTileEvent(TileEventData* te) {
|
||||
int t = getTile(te->getX(), te->getY(), te->getZ());
|
||||
if (t == te->getTile()) {
|
||||
Tile::tiles[t]->triggerEvent(this, te->getX(), te->getY(), te->getZ(),
|
||||
te->getParamA(), te->getParamB());
|
||||
return true;
|
||||
return Tile::tiles[t]->triggerEvent(this, te->getX(), te->getY(),
|
||||
te->getZ(), te->getParamA(),
|
||||
te->getParamB());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1101,8 +1196,8 @@ MinecraftServer* ServerLevel::getServer() { return server; }
|
|||
|
||||
EntityTracker* ServerLevel::getTracker() { return tracker; }
|
||||
|
||||
void ServerLevel::setTimeAndAdjustTileTicks(__int64 newTime) {
|
||||
__int64 delta = newTime - levelData->getTime();
|
||||
void ServerLevel::setTimeAndAdjustTileTicks(int64_t newTime) {
|
||||
int64_t delta = newTime - levelData->getGameTime();
|
||||
// 4J - can't directly adjust m_delay in a set as it has a const interator,
|
||||
// since changing values in here might change the ordering of the elements
|
||||
// in the set. Instead move to a vector, do the adjustment, put back in the
|
||||
|
|
@ -1117,11 +1212,34 @@ void ServerLevel::setTimeAndAdjustTileTicks(__int64 newTime) {
|
|||
for (unsigned int i = 0; i < temp.size(); i++) {
|
||||
tickNextTickList.insert(temp[i]);
|
||||
}
|
||||
setTime(newTime);
|
||||
setGameTime(newTime);
|
||||
}
|
||||
|
||||
PlayerChunkMap* ServerLevel::getChunkMap() { return chunkMap; }
|
||||
|
||||
PortalForcer* ServerLevel::getPortalForcer() { return portalForcer; }
|
||||
|
||||
void ServerLevel::sendParticles(const std::wstring& name, double x, double y,
|
||||
double z, int count) {
|
||||
sendParticles(name, x + 0.5f, y + 0.5f, z + 0.5f, count, 0.5f, 0.5f, 0.5f,
|
||||
0.02f);
|
||||
}
|
||||
|
||||
void ServerLevel::sendParticles(const std::wstring& name, double x, double y,
|
||||
double z, int count, double xDist, double yDist,
|
||||
double zDist, double speed) {
|
||||
std::shared_ptr<Packet> packet =
|
||||
std::shared_ptr<LevelParticlesPacket>(new LevelParticlesPacket(
|
||||
name, (float)x, (float)y, (float)z, (float)xDist, (float)yDist,
|
||||
(float)zDist, (float)speed, count));
|
||||
|
||||
for (AUTO_VAR(it, players.begin()); it != players.end(); ++it) {
|
||||
std::shared_ptr<ServerPlayer> player =
|
||||
std::dynamic_pointer_cast<ServerPlayer>(*it);
|
||||
player->connection->send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
// 4J Stu - Sometimes we want to update tiles on the server from the main thread
|
||||
// (eg SignTileEntity when string verify returns)
|
||||
void ServerLevel::queueSendTileUpdate(int x, int y, int z) {
|
||||
|
|
@ -1146,7 +1264,7 @@ void ServerLevel::runQueuedSendTileUpdates() {
|
|||
// removed and added so we can limit the number of itementities created
|
||||
bool ServerLevel::addEntity(std::shared_ptr<Entity> e) {
|
||||
// If its an item entity, and we've got to our capacity, delete the oldest
|
||||
if (std::dynamic_pointer_cast<ItemEntity>(e) != NULL) {
|
||||
if (e->instanceof(eTYPE_ITEMENTITY)) {
|
||||
// printf("Adding item entity count
|
||||
//%d\n",m_itemEntities.size());
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
|
|
@ -1158,7 +1276,7 @@ bool ServerLevel::addEntity(std::shared_ptr<Entity> e) {
|
|||
}
|
||||
// If its an hanging entity, and we've got to our capacity, delete the
|
||||
// oldest
|
||||
else if (std::dynamic_pointer_cast<HangingEntity>(e) != NULL) {
|
||||
else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
|
||||
// printf("Adding item entity count
|
||||
//%d\n",m_itemEntities.size());
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
|
|
@ -1175,7 +1293,7 @@ bool ServerLevel::addEntity(std::shared_ptr<Entity> e) {
|
|||
LeaveCriticalSection(&m_limiterCS);
|
||||
}
|
||||
// If its an arrow entity, and we've got to our capacity, delete the oldest
|
||||
else if (std::dynamic_pointer_cast<Arrow>(e) != NULL) {
|
||||
else if (e->instanceof(eTYPE_ARROW)) {
|
||||
// printf("Adding arrow entity count
|
||||
//%d\n",m_arrowEntities.size());
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
|
|
@ -1187,7 +1305,7 @@ bool ServerLevel::addEntity(std::shared_ptr<Entity> e) {
|
|||
}
|
||||
// If its an experience orb entity, and we've got to our capacity, delete
|
||||
// the oldest
|
||||
else if (std::dynamic_pointer_cast<ExperienceOrb>(e) != NULL) {
|
||||
else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
|
||||
// printf("Adding arrow entity count
|
||||
//%d\n",m_arrowEntities.size());
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
|
|
@ -1200,37 +1318,65 @@ bool ServerLevel::addEntity(std::shared_ptr<Entity> e) {
|
|||
return Level::addEntity(e);
|
||||
}
|
||||
|
||||
// 4J: Returns true if the level is at its limit for this type of entity (only
|
||||
// checks arrows, hanging, item and experience orbs)
|
||||
bool ServerLevel::atEntityLimit(std::shared_ptr<Entity> e) {
|
||||
// TODO: This duplicates code from addEntity above, fix
|
||||
|
||||
bool atLimit = false;
|
||||
|
||||
if (e->instanceof(eTYPE_ITEMENTITY)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
atLimit = m_itemEntities.size() >= MAX_ITEM_ENTITIES;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
atLimit = m_hangingEntities.size() >= MAX_HANGING_ENTITIES;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (e->instanceof(eTYPE_ARROW)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
atLimit = m_arrowEntities.size() >= MAX_ARROW_ENTITIES;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
atLimit = m_experienceOrbEntities.size() >= MAX_EXPERIENCEORB_ENTITIES;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
}
|
||||
|
||||
return atLimit;
|
||||
}
|
||||
|
||||
// Maintain a cound of primed tnt & falling tiles in this level
|
||||
void ServerLevel::entityAddedExtra(std::shared_ptr<Entity> e) {
|
||||
if (std::dynamic_pointer_cast<ItemEntity>(e) != NULL) {
|
||||
if (e->instanceof(eTYPE_ITEMENTITY)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_itemEntities.push_back(e);
|
||||
// printf("entity added: item entity count now
|
||||
//%d\n",m_itemEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<HangingEntity>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_hangingEntities.push_back(e);
|
||||
// printf("entity added: item entity count now
|
||||
//%d\n",m_itemEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<Arrow>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_ARROW)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_arrowEntities.push_back(e);
|
||||
// printf("entity added: arrow entity count now
|
||||
//%d\n",m_arrowEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<ExperienceOrb>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_experienceOrbEntities.push_back(e);
|
||||
// printf("entity added: experience orb entity count now
|
||||
//%d\n",m_arrowEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<PrimedTnt>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_PRIMEDTNT)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_primedTntCount++;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<FallingTile>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_FALLINGTILE)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_fallingTileCount++;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
|
|
@ -1240,7 +1386,7 @@ void ServerLevel::entityAddedExtra(std::shared_ptr<Entity> e) {
|
|||
// Maintain a cound of primed tnt & falling tiles in this level, and remove any
|
||||
// item entities from our list
|
||||
void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
|
||||
if (std::dynamic_pointer_cast<ItemEntity>(e) != NULL) {
|
||||
if (e->instanceof(eTYPE_ITEMENTITY)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
// printf("entity removed: item entity count
|
||||
//%d\n",m_itemEntities.size());
|
||||
|
|
@ -1252,7 +1398,7 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
|
|||
// printf("entity removed: item entity count now
|
||||
//%d\n",m_itemEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<HangingEntity>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
// printf("entity removed: item entity count
|
||||
//%d\n",m_itemEntities.size());
|
||||
|
|
@ -1265,7 +1411,7 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
|
|||
// printf("entity removed: item entity count now
|
||||
//%d\n",m_itemEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<Arrow>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_ARROW)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
// printf("entity removed: arrow entity count
|
||||
//%d\n",m_arrowEntities.size());
|
||||
|
|
@ -1277,7 +1423,7 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
|
|||
// printf("entity removed: arrow entity count now
|
||||
//%d\n",m_arrowEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<ExperienceOrb>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
// printf("entity removed: experience orb entity count
|
||||
//%d\n",m_arrowEntities.size());
|
||||
|
|
@ -1290,11 +1436,11 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
|
|||
// printf("entity removed: experience orb entity count now
|
||||
//%d\n",m_arrowEntities.size());
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<PrimedTnt>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_PRIMEDTNT)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_primedTntCount--;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
} else if (std::dynamic_pointer_cast<FallingTile>(e) != NULL) {
|
||||
} else if (e->instanceof(eTYPE_FALLINGTILE)) {
|
||||
EnterCriticalSection(&m_limiterCS);
|
||||
m_fallingTileCount--;
|
||||
LeaveCriticalSection(&m_limiterCS);
|
||||
|
|
@ -1438,4 +1584,4 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int* flags,
|
|||
if (chunkMap) {
|
||||
chunkMap->flagEntitiesToBeRemoved(flags, removedFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,8 @@ class PlayerChunkMap;
|
|||
|
||||
class ServerLevel : public Level {
|
||||
private:
|
||||
static const int EMPTY_TIME_NO_TICK = SharedConstants::TICKS_PER_SECOND * 3;
|
||||
static const int EMPTY_TIME_NO_TICK =
|
||||
SharedConstants::TICKS_PER_SECOND * 60;
|
||||
|
||||
MinecraftServer* server;
|
||||
EntityTracker* tracker;
|
||||
|
|
@ -35,6 +36,8 @@ public:
|
|||
|
||||
private:
|
||||
bool allPlayersSleeping;
|
||||
PortalForcer* portalForcer;
|
||||
MobSpawner* mobSpawner;
|
||||
int emptyTime;
|
||||
bool m_bAtLeastOnePlayerSleeping; // 4J Added
|
||||
static WeighedTreasureArray
|
||||
|
|
@ -68,10 +71,18 @@ public:
|
|||
protected:
|
||||
void tickTiles();
|
||||
|
||||
private:
|
||||
std::vector<TickNextTickData> toBeTicked;
|
||||
|
||||
public:
|
||||
bool isTileToBeTickedAt(int x, int y, int z, int tileId);
|
||||
void addToTickNextTick(int x, int y, int z, int tileId, int tickDelay);
|
||||
void forceAddTileTick(int x, int y, int z, int tileId, int tickDelay);
|
||||
void addToTickNextTick(int x, int y, int z, int tileId, int tickDelay,
|
||||
int priorityTilt);
|
||||
void forceAddTileTick(int x, int y, int z, int tileId, int tickDelay,
|
||||
int prioTilt);
|
||||
void tickEntities();
|
||||
void resetEmptyTime();
|
||||
bool tickPendingTicks(bool force);
|
||||
std::vector<TickNextTickData>* fetchTicksInChunk(LevelChunk* chunk,
|
||||
bool remove);
|
||||
|
|
@ -89,7 +100,7 @@ public:
|
|||
std::vector<std::shared_ptr<TileEntity> >* getTileEntitiesInRegion(
|
||||
int x0, int y0, int z0, int x1, int y1, int z1);
|
||||
virtual bool mayInteract(std::shared_ptr<Player> player, int xt, int yt,
|
||||
int zt, int id);
|
||||
int zt, int content);
|
||||
|
||||
protected:
|
||||
virtual void initializeLevel(LevelSettings* settings);
|
||||
|
|
@ -141,8 +152,14 @@ protected:
|
|||
public:
|
||||
MinecraftServer* getServer();
|
||||
EntityTracker* getTracker();
|
||||
void setTimeAndAdjustTileTicks(__int64 newTime);
|
||||
void setTimeAndAdjustTileTicks(int64_t newTime);
|
||||
PlayerChunkMap* getChunkMap();
|
||||
PortalForcer* getPortalForcer();
|
||||
void sendParticles(const std::wstring& name, double x, double y, double z,
|
||||
int count);
|
||||
void sendParticles(const std::wstring& name, double x, double y, double z,
|
||||
int count, double xDist, double yDist, double zDist,
|
||||
double speed);
|
||||
|
||||
void queueSendTileUpdate(int x, int y, int z); // 4J Added
|
||||
private:
|
||||
|
|
@ -170,6 +187,8 @@ public:
|
|||
void entityAddedExtra(std::shared_ptr<Entity> e);
|
||||
void entityRemovedExtra(std::shared_ptr<Entity> e);
|
||||
|
||||
bool atEntityLimit(std::shared_ptr<Entity> e); // 4J: Added
|
||||
|
||||
virtual bool newPrimedTntAllowed();
|
||||
virtual bool newFallingTileAllowed();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ ServerLevelListener::ServerLevelListener(MinecraftServer* server,
|
|||
|
||||
// 4J removed -
|
||||
/*
|
||||
void ServerLevelListener::addParticle(const std::wstring& name, double x, double
|
||||
y, double z, double xa, double ya, double za)
|
||||
void ServerLevelListener::addParticle(const wstring& name, double x, double y,
|
||||
double z, double xa, double ya, double za)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
|
@ -67,9 +67,11 @@ void ServerLevelListener::playSound(int iSound, double x, double y, double z,
|
|||
}
|
||||
}
|
||||
|
||||
void ServerLevelListener::playSound(std::shared_ptr<Entity> entity, int iSound,
|
||||
double x, double y, double z, float volume,
|
||||
float pitch, float fClipSoundDist) {
|
||||
void ServerLevelListener::playSoundExceptPlayer(std::shared_ptr<Player> player,
|
||||
int iSound, double x, double y,
|
||||
double z, float volume,
|
||||
float pitch,
|
||||
float fSoundClipDist) {
|
||||
if (iSound < 0) {
|
||||
app.DebugPrintf(
|
||||
"ServerLevelListener received request for sound less than 0, so "
|
||||
|
|
@ -79,8 +81,6 @@ void ServerLevelListener::playSound(std::shared_ptr<Entity> entity, int iSound,
|
|||
// since we're already playing these in the LevelRenderer::playSound.
|
||||
// The PC version does seem to do this and the result is I can stop
|
||||
// walking , and then I'll hear my footstep sound with a delay
|
||||
std::shared_ptr<Player> player =
|
||||
std::dynamic_pointer_cast<Player>(entity);
|
||||
server->getPlayers()->broadcast(
|
||||
player, x, y, z, volume > 1 ? 16 * volume : 16,
|
||||
level->dimension->id,
|
||||
|
|
@ -108,7 +108,13 @@ void ServerLevelListener::levelEvent(std::shared_ptr<Player> source, int type,
|
|||
server->getPlayers()->broadcast(
|
||||
source, x, y, z, 64, level->dimension->id,
|
||||
std::shared_ptr<LevelEventPacket>(
|
||||
new LevelEventPacket(type, x, y, z, data)));
|
||||
new LevelEventPacket(type, x, y, z, data, false)));
|
||||
}
|
||||
|
||||
void ServerLevelListener::globalLevelEvent(int type, int sourceX, int sourceY,
|
||||
int sourceZ, int data) {
|
||||
server->getPlayers()->broadcastAll(std::shared_ptr<LevelEventPacket>(
|
||||
new LevelEventPacket(type, sourceX, sourceY, sourceZ, data, true)));
|
||||
}
|
||||
|
||||
void ServerLevelListener::destroyTileProgress(int id, int x, int y, int z,
|
||||
|
|
|
|||
|
|
@ -27,9 +27,10 @@ public:
|
|||
// level's player array, not just the entity storage
|
||||
virtual void playSound(int iSound, double x, double y, double z,
|
||||
float volume, float pitch, float fClipSoundDist);
|
||||
virtual void playSound(std::shared_ptr<Entity> entity, int iSound, double x,
|
||||
double y, double z, float volume, float pitch,
|
||||
float fClipSoundDist);
|
||||
virtual void playSoundExceptPlayer(std::shared_ptr<Player> player,
|
||||
int iSound, double x, double y, double z,
|
||||
float volume, float pitch,
|
||||
float fSoundClipDist);
|
||||
virtual void setTilesDirty(int x0, int y0, int z0, int x1, int y1, int z1,
|
||||
Level* level); // 4J - added level param
|
||||
virtual void skyColorChanged();
|
||||
|
|
@ -39,5 +40,7 @@ public:
|
|||
int z);
|
||||
virtual void levelEvent(std::shared_ptr<Player> source, int type, int x,
|
||||
int y, int z, int data);
|
||||
virtual void globalLevelEvent(int type, int sourceX, int sourceY,
|
||||
int sourceZ, int data);
|
||||
virtual void destroyTileProgress(int id, int x, int y, int z, int progress);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue