aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/ServerLevel.h
blob: 77a5cb7829b992533c9140a9b7ec923041fe5a54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#pragma once
#include "..\Minecraft.World\net.minecraft.world.level.h"
#include "..\Minecraft.World\JavaIntHash.h"
class ServerChunkCache;
class MinecraftServer;
class Node;
class EntityTracker;
class PlayerChunkMap;
using namespace std;

class ServerLevel : public Level
{
private:
	static const int EMPTY_TIME_NO_TICK = SharedConstants::TICKS_PER_SECOND * 60;

	MinecraftServer *server;
	EntityTracker *tracker;
	PlayerChunkMap *chunkMap;

	CRITICAL_SECTION				m_tickNextTickCS;	// 4J added
	set<TickNextTickData, TickNextTickDataKeyCompare> tickNextTickList; // 4J Was TreeSet
	unordered_set<TickNextTickData, TickNextTickDataKeyHash, TickNextTickDataKeyEq> tickNextTickSet; // 4J Was HashSet

	vector<Pos *> m_queuedSendTileUpdates; // 4J added
	CRITICAL_SECTION m_csQueueSendTileUpdates;

protected:
	int saveInterval;

public:
	ServerChunkCache *cache;
	bool canEditSpawn;
	bool noSave;
private:
	bool allPlayersSleeping;
	PortalForcer *portalForcer;
	MobSpawner *mobSpawner;
	int emptyTime;
	bool m_bAtLeastOnePlayerSleeping; // 4J Added
	static WeighedTreasureArray RANDOM_BONUS_ITEMS;	// 4J - brought forward from 1.3.2

	vector<TileEventData> tileEvents[2];
	int activeTileEventsList;
public:
	static void staticCtor();
	ServerLevel(MinecraftServer *server, shared_ptr<LevelStorage>levelStorage, const wstring& levelName, int dimension, LevelSettings *levelSettings);
	~ServerLevel();
	void tick();
	Biome::MobSpawnerData *getRandomMobSpawnAt(MobCategory *mobCategory, int x, int y, int z);
	void updateSleepingPlayerList();
protected:
	void awakenAllPlayers();

private:
	void stopWeather();

public:
	bool allPlayersAreSleeping();
	void validateSpawn();

protected:
	void tickTiles();

private:
	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 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);
	vector<TickNextTickData> *fetchTicksInChunk(LevelChunk *chunk, bool remove);
	virtual void tick(shared_ptr<Entity> e, bool actual);
	void forceTick(shared_ptr<Entity> e, bool actual);
	bool AllPlayersAreSleeping()			{ return allPlayersSleeping;} // 4J added for a message to other players
	bool isAtLeastOnePlayerSleeping()		{ return m_bAtLeastOnePlayerSleeping;}
protected:
	ChunkSource *createChunkSource();	// 4J - was virtual, but was called from parent ctor
public:
	vector<shared_ptr<TileEntity> > *getTileEntitiesInRegion(int x0, int y0, int z0, int x1, int y1, int z1);
	virtual bool mayInteract(shared_ptr<Player> player, int xt, int yt, int zt, int content);
protected:
	virtual void initializeLevel(LevelSettings *settings);
	virtual void setInitialSpawn(LevelSettings *settings);
	void generateBonusItemsNearSpawn();	// 4J - brought forward from 1.3.2

public:
	Pos *getDimensionSpecificSpawn();

	void Suspend(); // 4j Added for XboxOne PLM

	void save(bool force, ProgressListener *progressListener, bool bAutosave=false);
	void saveToDisc(ProgressListener *progressListener, bool autosave); // 4J Added

private:
	void saveLevelData();

	typedef unordered_map<int, shared_ptr<Entity> , IntKeyHash2, IntKeyEq> intEntityMap;
	intEntityMap entitiesById;	// 4J - was IntHashMap, using same hashing function as this uses
protected:
	virtual void entityAdded(shared_ptr<Entity> e);
	virtual void entityRemoved(shared_ptr<Entity> e);
public:
	shared_ptr<Entity> getEntity(int id);
	virtual bool addGlobalEntity(shared_ptr<Entity> e);
	void broadcastEntityEvent(shared_ptr<Entity> e, byte event);
	virtual shared_ptr<Explosion> explode(shared_ptr<Entity> source, double x, double y, double z, float r, bool fire, bool destroyBlocks);
	virtual void tileEvent(int x, int y, int z, int tile, int b0, int b1);

private:
	void runTileEvents();
	bool doTileEvent(TileEventData *te);

public:
	void closeLevelStorage();
protected:
	virtual void tickWeather();

public:
	MinecraftServer *getServer();
	EntityTracker *getTracker();
	void setTimeAndAdjustTileTicks(int64_t newTime);
	PlayerChunkMap *getChunkMap();
	PortalForcer *getPortalForcer();
	void sendParticles(const wstring &name, double x, double y, double z, int count);
	void sendParticles(const 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:
	void runQueuedSendTileUpdates();// 4J Added

	// 4J - added for implementation of finite limit to number of item entities, tnt and falling block entities
public:

	static const int MAX_HANGING_ENTITIES = 400;
	static const int MAX_ITEM_ENTITIES = 200;
	static const int MAX_ARROW_ENTITIES = 200;
	static const int MAX_EXPERIENCEORB_ENTITIES = 50;
	static const int MAX_PRIMED_TNT = 20;
	static const int MAX_FALLING_TILE = 20;

	int							m_primedTntCount;
	int							m_fallingTileCount;
	CRITICAL_SECTION			m_limiterCS;
	list< shared_ptr<Entity> >	m_itemEntities;
	list< shared_ptr<Entity> >	m_hangingEntities;
	list< shared_ptr<Entity> >	m_arrowEntities;
	list< shared_ptr<Entity> >	m_experienceOrbEntities;

	virtual bool addEntity(shared_ptr<Entity> e);
	void entityAddedExtra(shared_ptr<Entity> e);
	void entityRemovedExtra(shared_ptr<Entity> e);

	bool atEntityLimit(shared_ptr<Entity> e); // 4J: Added

	virtual bool newPrimedTntAllowed();
	virtual bool newFallingTileAllowed();

	void flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFound);		// 4J added

	// 4J added
	static const int MAX_UPDATES = 256;

	// Each of these need to be duplicated for each level in the current game. As we currently only have 2 (over/nether), making this constant
	static Level 				*m_level[3];
	static int					m_updateChunkX[3][LEVEL_CHUNKS_TO_UPDATE_MAX];
	static int					m_updateChunkZ[3][LEVEL_CHUNKS_TO_UPDATE_MAX];
	static int					m_updateChunkCount[3];
	static int					m_updateTileX[3][MAX_UPDATES];
	static int					m_updateTileY[3][MAX_UPDATES];
	static int					m_updateTileZ[3][MAX_UPDATES];
	static int					m_updateTileCount[3];
	static int					m_randValue[3];

	static C4JThread::EventArray*	m_updateTrigger;
	static CRITICAL_SECTION		m_updateCS[3];

	static C4JThread*			m_updateThread;
	static int 	runUpdate(void* lpParam);

};