Browse Source

clients does now decide on wich chunks they subscribe for changes

Kolja Strohm 2 years ago
parent
commit
3e8a23cce5

+ 0 - 21
FactoryCraft/AddChunkUpdate.cpp

@@ -1,21 +0,0 @@
-#include <Punkt.h>
-
-#include "AddChunkUpdate.h"
-#include "Chunk.h"
-#include "Globals.h"
-
-AddChunkUpdateType::AddChunkUpdateType()
-	: WorldUpdateType(ID)
-{}
-
-
-void AddChunkUpdateType::applyUpdate(Framework::StreamReader* zReader)
-{
-	Framework::Punkt center;
-	zReader->lese((char*)&center.x, 4);
-	zReader->lese((char*)&center.y, 4);
-	std::cout << "downloading chunk " << center.x << ", " << center.y << "\n";
-	Chunk* chunk = new Chunk(center);
-	chunk->load(zReader);
-	currentGame->setChunk(chunk);
-}

+ 0 - 14
FactoryCraft/AddChunkUpdate.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include "WorldUpdate.h"
-
-class AddChunkUpdateType : WorldUpdateType
-{
-	REGISTRABLE(AddChunkUpdateType)
-
-protected:
-	AddChunkUpdateType();
-	void applyUpdate(Framework::StreamReader* zReader) override;
-};
-
-REGISTER(AddChunkUpdateType, WorldUpdateType)

+ 25 - 2
FactoryCraft/Chunk.cpp

@@ -18,11 +18,34 @@ Chunk::Chunk(Framework::Punkt location, Framework::StreamReader* zReader)
 }
 
 Chunk::~Chunk()
-{}
+{
+	char msg = 1; // remove observer
+	network->zFactoryClient()->chunkAPIRequest(location, &msg, 1);
+}
 
 void Chunk::api(char* message)
 {
-	// TODO: implement api
+	switch (message[0])
+	{
+	case 0: // set block
+	{
+		int index = *(int*)(message + 1);
+		int id = *(int*)(message + 5);
+		Framework::Vec3<int> location((index / WORLD_HEIGHT) / CHUNK_SIZE, (index / WORLD_HEIGHT) % CHUNK_SIZE, index % WORLD_HEIGHT);
+		if (blockTypes[id]->doesNeedInstance())
+		{
+			Block* zB = blockTypes[id]->createBlock(location);
+			setBlock(zB);
+		}
+		else
+		{
+			Block* zB = zBlockAt(location);
+			if (zB)
+				removeBlock(zB);
+		}
+		break;
+	}
+	}
 }
 
 Block* Chunk::zBlockAt(Framework::Vec3<int> location)

+ 20 - 9
FactoryCraft/Dimension.cpp

@@ -7,8 +7,6 @@
 
 using namespace Framework;
 
-#define MAX_VIEW_DISTANCE CHUNK_SIZE * 8
-
 Dimension::Dimension()
 	: chunks(new Trie<Chunk>()),
 	entities(new RCArray<Entity>())
@@ -67,6 +65,19 @@ void Dimension::api(char* message)
 			b->api(message + 13);
 		break;
 	}
+	case 4: // add new chunck
+	{
+		Punkt center;
+		center.x = *(int*)(message + 1);
+		center.y = *(int*)(message + 5);
+		ByteArrayReader reader(message + 9, INT_MAX, 0);
+		std::cout << "downloading chunk " << center.x << ", " << center.y << "\n";
+		Chunk* chunk = new Chunk(center);
+		chunk->load(&reader);
+		setChunk(chunk, center);
+		currentGame->onChunkAdded(center);
+		break;
+	}
 	}
 }
 
@@ -106,7 +117,7 @@ void Dimension::addEntity(Entity* entity)
 	currentGame->setVisibility(entity, 1);
 }
 
-void Dimension::setChunk(Chunk* chunk, Punkt center, World* zWorld)
+void Dimension::setChunk(Chunk* chunk, Punkt center)
 {
 	char addr[8];
 	getAddrOfWorld(center, addr);
@@ -114,7 +125,7 @@ void Dimension::setChunk(Chunk* chunk, Punkt center, World* zWorld)
 	cs.lock();
 	if (old)
 	{
-		zWorld->setVisibility(old, 0);
+		currentGame->setVisibility(old, 0);
 		int index = 0;
 		for (auto iterator = chunkList.begin(); iterator; ++iterator, ++index)
 		{
@@ -133,7 +144,7 @@ void Dimension::setChunk(Chunk* chunk, Punkt center, World* zWorld)
 	chunks->set(addr, 8, chunk);
 	if (chunk)
 	{
-		zWorld->setVisibility(chunk, 1);
+		currentGame->setVisibility(chunk, 1);
 	}
 	cs.unlock();
 }
@@ -143,21 +154,21 @@ bool Dimension::hasChunck(int x, int y) const
 	return zChunk(Punkt(x, y));
 }
 
-void Dimension::removeDistantChunks(Punkt wPos, World* zWorld)
+void Dimension::removeDistantChunks(Punkt wPos)
 {
 	Array<int> removed;
 	int index = 0;
 	for (Chunk* chunk : chunkList)
 	{
-		if ((chunk->getCenter() - wPos).getLength() > MAX_VIEW_DISTANCE)
+		if ((chunk->getCenter() - wPos).getLength() > MAX_VIEW_DISTANCE * 2)
 			removed.add(index, 0);
 		index++;
 	}
 	for (int i : removed)
 	{
 		Chunk* chunk = chunkList.get(i);
-		zWorld->setVisibility(chunk, 0);
-		setChunk(0, chunk->getCenter(), zWorld);
+		currentGame->setVisibility(chunk, 0);
+		setChunk(0, chunk->getCenter());
 	}
 }
 

+ 2 - 2
FactoryCraft/Dimension.h

@@ -27,10 +27,10 @@ public:
 	Block* zBlock(Framework::Vec3<int> location);
 	Block* getBlock(Framework::Vec3<int> location);
 	void addEntity(Entity* entity);
-	void setChunk(Chunk* chunk, Framework::Punkt center, World* zWorld);
+	void setChunk(Chunk* chunk, Framework::Punkt center);
 	bool hasChunck(int x, int y) const;
 	Chunk* zChunk(Framework::Punkt wPos) const;
-	void removeDistantChunks(Framework::Punkt wPos, World* zWorld);
+	void removeDistantChunks(Framework::Punkt wPos);
 	void setBlock(Block* block);
 	void removeBlock(Block* zBlock);
 	Entity* zEntity(int id);

+ 15 - 0
FactoryCraft/FactoryClient.cpp

@@ -231,6 +231,21 @@ void FactoryClient::entityAPIRequest(int entityId, char* message, unsigned short
 	cs.unlock();
 }
 
+void FactoryClient::chunkAPIRequest(Punkt center, char* message, unsigned short length)
+{
+	length += 10;
+	cs.lock();
+	foreground->sende((char*)&length, 2);
+	char type = 1;
+	foreground->sende(&type, 1);
+	type = 0;
+	foreground->sende(&type, 1);
+	foreground->sende((char*)&center.x, 4);
+	foreground->sende((char*)&center.y, 4);
+	foreground->sende(message, length - 10);
+	cs.unlock();
+}
+
 void FactoryClient::inventoryAPIRequest(Framework::Either<int, Framework::VecN<int, 4>> target, char* message, unsigned short length)
 {
 	if (!foreground)

+ 2 - 0
FactoryCraft/FactoryClient.h

@@ -7,6 +7,7 @@
 #include <Critical.h>
 #include <VecN.h>
 #include <Either.h>
+#include <Punkt.h>
 
 class FactoryClient : public Framework::ReferenceCounter
 {
@@ -32,5 +33,6 @@ public:
 	void endMessageReading(bool bg);
 	void sendPlayerAction(char* data, unsigned short length);
 	void entityAPIRequest(int entityId, char* message, unsigned short length);
+	void chunkAPIRequest(Framework::Punkt center, char* message, unsigned short length);
 	void inventoryAPIRequest(Framework::Either<int, Framework::VecN<int, 4>> target, char* message, unsigned short length);
 };

+ 0 - 2
FactoryCraft/FactoryCraft.vcxproj

@@ -170,7 +170,6 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     </CustomBuildStep>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="AddChunkUpdate.cpp" />
     <ClCompile Include="AddEntityUpdate.cpp" />
     <ClCompile Include="Area.cpp" />
     <ClCompile Include="Block.cpp" />
@@ -226,7 +225,6 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClInclude Include="FactoryClient.h" />
     <ClInclude Include="Game.h" />
     <ClInclude Include="Globals.h" />
-    <ClInclude Include="AddChunkUpdate.h" />
     <ClInclude Include="Initialisierung.h" />
     <ClInclude Include="InventoryView.h" />
     <ClInclude Include="ItemBar.h" />

+ 0 - 6
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -58,9 +58,6 @@
     <ClCompile Include="WorldUpdate.cpp">
       <Filter>world\update</Filter>
     </ClCompile>
-    <ClCompile Include="AddChunkUpdate.cpp">
-      <Filter>world\update</Filter>
-    </ClCompile>
     <ClCompile Include="BlockType.cpp">
       <Filter>world</Filter>
     </ClCompile>
@@ -165,9 +162,6 @@
     <ClInclude Include="WorldUpdate.h">
       <Filter>world\update</Filter>
     </ClInclude>
-    <ClInclude Include="AddChunkUpdate.h">
-      <Filter>world\update</Filter>
-    </ClInclude>
     <ClInclude Include="Globals.h">
       <Filter>static</Filter>
     </ClInclude>

+ 0 - 1
FactoryCraft/StaticInitializerOrder.cpp

@@ -12,7 +12,6 @@ const c *c::INSTANCE = new c();
 // order of includes determines the ids
 
 // world updates
-#include "AddChunkUpdate.h"
 #include "PlaceBlockUpdate.h"
 #include "BlockRemovedUpdate.h"
 #include "AddEntityUpdate.h"

+ 48 - 2
FactoryCraft/World.cpp

@@ -101,7 +101,37 @@ void World::update(bool background)
 	if (player)
 	{
 		renderedWorld->lock();
-		currentDimension->removeDistantChunks({ (int)player->getPos().x, (int)player->getPos().y }, this);
+		currentDimension->removeDistantChunks({ (int)player->getPos().x, (int)player->getPos().y });
+		Punkt currentChunk = getChunkCenter((int)player->getX(), (int)player->getY());
+		for (int x = -CHUNK_VISIBILITY_RANGE; x <= CHUNK_VISIBILITY_RANGE; x++)
+		{
+			for (int y = -CHUNK_VISIBILITY_RANGE; y <= CHUNK_VISIBILITY_RANGE; y++)
+			{
+				Chunk* zC = currentDimension->zChunk(currentChunk + Punkt(x * CHUNK_SIZE, y * CHUNK_SIZE));
+				if (!zC)
+				{
+					char msg[1];
+					msg[0] = 0; // add observer and request chaunk data
+					Punkt pos = currentChunk + Punkt(x * CHUNK_SIZE, y * CHUNK_SIZE);
+					subLock.lock();
+					bool found = 0;
+					for (Punkt p : subscriptions)
+					{
+						if (p == pos)
+						{
+							found = 1;
+							break;
+						}
+					}
+					if (!found)
+					{
+						network->zFactoryClient()->chunkAPIRequest(pos, msg, 1);
+						subscriptions.add(pos);
+					}
+					subLock.unlock();
+				}
+			}
+		}
 		renderedWorld->unlock();
 	}
 }
@@ -110,7 +140,7 @@ void World::setChunk(Chunk* chunk)
 {
 	zScreenPtr->lock();
 	renderedWorld->lock();
-	currentDimension->setChunk(chunk, chunk->getCenter(), this);
+	currentDimension->setChunk(chunk, chunk->getCenter());
 	renderedWorld->unlock();
 	zScreenPtr->unlock();
 }
@@ -251,4 +281,20 @@ void World::lockWorld()
 void World::unlockWorld()
 {
 	renderedWorld->unlock();
+}
+
+void World::onChunkAdded(Punkt pos)
+{
+	subLock.lock();
+	int index = 0;
+	for (Punkt p : subscriptions)
+	{
+		if (p == pos)
+		{
+			subscriptions.remove(index);
+			break;
+		}
+		index++;
+	}
+	subLock.unlock();
 }

+ 6 - 0
FactoryCraft/World.h

@@ -8,6 +8,9 @@
 #include "Dimension.h"
 #include "PlayerKam.h"
 
+#define CHUNK_VISIBILITY_RANGE 6
+#define MAX_VIEW_DISTANCE CHUNK_SIZE * CHUNK_VISIBILITY_RANGE
+
 class World : public Framework::Thread
 {
 private:
@@ -21,6 +24,8 @@ private:
 	bool firstMessage;
 	int ownEntityId;
 	Framework::Model3D* currentTarget;
+	Array<Punkt> subscriptions;
+	Critical subLock;
 
 public:
 	World(Framework::Bildschirm3D* zScreen);
@@ -44,4 +49,5 @@ public:
 	void setTarget(Framework::Model3D* zTarget);
 	void lockWorld();
 	void unlockWorld();
+	void onChunkAdded(Punkt pos);
 };

BIN
FactoryCraft/error_core_memory_dump.dmp