TU19: merge Minecraft.Client/Level

This commit is contained in:
Tropical
2026-03-21 20:29:13 -05:00
parent 1c12bedc86
commit b319cb3cea
6 changed files with 417 additions and 175 deletions

View File

@@ -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);
}
}
}