ソースを参照

fix some issues with fluid blocks and make water occure in grassland bioms

Kolja Strohm 1 年間 前
コミット
14eb0c6c4b

+ 1 - 1
FactoryCraft/BasicBlock.cpp

@@ -77,7 +77,7 @@ BasicBlockType::BasicBlockType(int typeId,
     ModelInfo model,
     std::function<Block*(Framework::Vec3<int>)> creatBlockCustom,
     const char* name)
-    : BlockType(typeId, 0, model, 1, 100, 0, name),
+    : BlockType(typeId, 0, model, 1, 100, 0, name, false),
       itemType(itemTypeId),
       transparent(0),
       passable(0),

+ 25 - 2
FactoryCraft/BlockType.cpp

@@ -14,7 +14,8 @@ BlockType::BlockType(int id,
     bool needsClientInstance,
     int initialMaxHP,
     bool lightSource,
-    const char* name)
+    const char* name,
+    bool needModelSubscription)
     : ReferenceCounter(),
       id(id),
       model(model),
@@ -22,6 +23,7 @@ BlockType::BlockType(int id,
       needsClientInstance(needsClientInstance),
       lightSource(lightSource),
       name(name),
+      needModelSubscription(needModelSubscription),
       defaultBlock(defaultBlock)
 {
     StaticRegistry<BlockType>::INSTANCE.registerT(this, id);
@@ -146,7 +148,10 @@ void BlockType::saveBlock(Block* zBlock, Framework::StreamWriter* zWriter) const
 Item* BlockType::getItemFromBlock(Block* zBlock) const
 {
     Item* result = createItem();
-    createSuperItem(zBlock, result);
+    if (result)
+    {
+        createSuperItem(zBlock, result);
+    }
     return result;
 }
 
@@ -205,4 +210,22 @@ BlockType* BlockType::initializeDefault()
 const char* BlockType::getName() const
 {
     return name;
+}
+
+const bool BlockType::doesNeedModelSubscription() const
+{
+    return needModelSubscription;
+}
+
+void BlockType::writeTypeInfo(StreamWriter* zWriter) const
+{
+    int id = getId();
+    zWriter->schreibe((char*)&id, 4);
+    bool inst = doesNeedClientInstance();
+    zWriter->schreibe((char*)&inst, 1);
+    bool sub = doesNeedModelSubscription();
+    zWriter->schreibe((char*)&sub, 1);
+    int maxHp = getInitialMaxHP();
+    zWriter->schreibe((char*)&maxHp, 4);
+    getModel().writeTo(zWriter);
 }

+ 6 - 1
FactoryCraft/BlockType.h

@@ -54,6 +54,7 @@ private:
     const bool needsClientInstance;
     bool lightSource;
     const char* name;
+    const bool needModelSubscription;
 
 protected:
     Block* defaultBlock;
@@ -62,7 +63,9 @@ protected:
         ModelInfo model,
         bool needsClientInstance,
         int initialMaxHP,
-        bool lightSource, const char *name);
+        bool lightSource,
+        const char* name,
+        bool needModelSubscription);
     virtual ~BlockType();
 
     virtual void loadSuperBlock(
@@ -92,6 +95,8 @@ public:
     bool isLightSource() const;
     BlockType* initializeDefault();
     const char* getName() const;
+    const bool doesNeedModelSubscription() const;
+    void writeTypeInfo(Framework::StreamWriter* zWriter) const;
 };
 
 const Block* getDefaultBlock(Framework::Either<Block*, int> b);

+ 3 - 3
FactoryCraft/Constants.h

@@ -5,9 +5,9 @@
 #define WORLD_HEIGHT             500
 #define BIOM_GENERATION_Z_OFFSET 100
 #define AIR_LEVEL_Z_OFFSET       99
-#define WATER_LEVEL              150
-#define MIN_AIR_LEVEL            100
-#define MAX_AIR_LEVEL            400
+#define WATER_LEVEL              200
+#define MIN_AIR_LEVEL            50
+#define MAX_AIR_LEVEL            450
 #define NUM_TICK_WORKERS         4
 #define ITEM_CACHE_SIZE          256
 #define DEFAULT_VIEW_DISTANCE    5

+ 2 - 1
FactoryCraft/FastNoiseWrapper.cpp

@@ -26,5 +26,6 @@ int FastNoiseWrapper::getSeed() const
 double FastNoiseWrapper::getNoise(double x, double y, double z)
 {
     // scale the noise from 0 to 1
-    return (noise->GetNoise(x, y, z) * multiplier + 1) / 2;
+    return (noise->GetNoise(x * multiplier, y * multiplier, z * multiplier) + 1)
+         / 2;
 }

+ 47 - 23
FactoryCraft/FluidBlock.cpp

@@ -14,6 +14,7 @@ FluidBlock::FluidBlock(int typeId, Framework::Vec3<int> pos)
     tickSource = 1;
     interactable = 0;
     fluidAmount = 0;
+    lastBroadcastedAmount = fluidAmount;
 }
 
 FluidBlock::~FluidBlock() {}
@@ -43,18 +44,17 @@ bool FluidBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
                     zNeighbours[getDirectionIndex(Direction::BOTTOM)]);
                 if (below->fluidAmount < 1000)
                 {
-                    int transferAmount
-                        = MIN(this->fluidAmount, 1000 - below->fluidAmount);
-                    below->fluidAmount += transferAmount;
-                    this->fluidAmount -= transferAmount;
+                    short transferAmount
+                        = (short)MIN(this->fluidAmount, (short)1000 - below->fluidAmount);
+                    below->fluidAmount = (short)(below->fluidAmount + transferAmount);
+                    this->fluidAmount = (short)(this->fluidAmount - transferAmount);
                 }
             }
-            int neighborCount = 0;
+            short neighborCount = 0;
             Inventory* others[4];
             for (int i = 1; i < 5; i++)
             {
-                if (neighbourTypes[i] == BlockTypeEnum::FLUID && zNeighbours[i]
-                    && zNeighbours[i]->zBlockType()->getId() == typeId)
+                if (neighbourTypes[i] == typeId && zNeighbours[i])
                 {
                     others[neighborCount] = zNeighbours[i];
                     neighborCount++;
@@ -73,8 +73,8 @@ bool FluidBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
                 }
                 // order other fluids increasing by fluid amount
                 sortByAmound(otherFluids, neighborCount);
-                int distCount = 0;
-                int targetAmount = 0;
+                short distCount = 0;
+                short targetAmount = 0;
                 for (int i = 1; i <= neighborCount; i++)
                 {
                     int fluidAmount = this->fluidAmount;
@@ -84,8 +84,8 @@ bool FluidBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
                     }
                     if (fluidAmount / (i + 1) > this->fluidAmount)
                     {
-                        targetAmount = fluidAmount / (i + 1);
-                        distCount = i;
+                        targetAmount = (short)(fluidAmount / (i + 1));
+                        distCount = (short)i;
                     }
                     else
                     {
@@ -94,26 +94,46 @@ bool FluidBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
                 }
                 for (int i = 0; i < distCount; i++)
                 {
-                    int transferAmount
-                        = targetAmount - otherFluids[i]->fluidAmount;
-                    otherFluids[i]->fluidAmount += transferAmount;
-                    this->fluidAmount -= transferAmount;
+                    short transferAmount
+                        = (short)(targetAmount - otherFluids[i]->fluidAmount);
+                    otherFluids[i]->fluidAmount
+                        = (short)(otherFluids[i]->fluidAmount + transferAmount);
+                    this->fluidAmount = (short)(this->fluidAmount - transferAmount);
                 }
-                // TODO: distribute fluids
             } // unlock
             neighborCount = 0;
-            for (int i = 1; i < 5; i++)
+            for (int i = 0; i < 6; i++)
             {
-                int neighbor = neighbourTypes[i];
-                if (neighbor == BlockTypeEnum::AIR
-                    && fluidAmount > neighborCount + 1)
+                if (getDirectionFromIndex(i) != Direction::BOTTOM
+                    && getDirectionFromIndex(i) != Direction::TOP)
                 {
-                    nextFlow |= 1 << i;
-                    neighborCount++;
+                    int neighbor = neighbourTypes[i];
+                    if (neighbor == BlockTypeEnum::AIR
+                        && fluidAmount > neighborCount + 1)
+                    {
+                        nextFlow |= 1 << i;
+                        neighborCount++;
+                    }
                 }
             }
         }
     }
+    return 1;
+}
+
+void FluidBlock::broadcastAmount()
+{
+    if (lastBroadcastedAmount != fluidAmount)
+    {
+        lastBroadcastedAmount = fluidAmount;
+        NetworkMessage* changeMsg = new NetworkMessage();
+        changeMsg->addressBlock(this);
+        char* msg = new char[3];
+        msg[0] = 2; // fluid amount change
+        *(short*)(msg + 1) = fluidAmount;
+        changeMsg->setMessage(msg, 3);
+        Game::INSTANCE->broadcastMessage(changeMsg);
+    }
 }
 
 void FluidBlock::onPostTick()
@@ -145,6 +165,10 @@ void FluidBlock::onPostTick()
                             .zElement(BlockTypeEnum::AIR)
                             ->createBlockAt(getPos(), 0));
             }
+            else
+            {
+                broadcastAmount();
+            }
         });
     }
 }
@@ -217,7 +241,7 @@ void FluidBlock::sortByAmound(FluidBlock** array, int count)
 }
 
 FluidBlockType::FluidBlockType(int id, ModelInfo model, const char* name)
-    : BlockType(id, 0, model, 1, 10, 0, name)
+    : BlockType(id, 0, model, 1, 10, 0, name, true)
 {}
 
 void FluidBlockType::loadSuperBlock(

+ 2 - 0
FactoryCraft/FluidBlock.h

@@ -10,12 +10,14 @@ class FluidBlock : public Block
 private:
     Directions flowDir;
     short fluidAmount;
+    short lastBroadcastedAmount;
     int nextFlow;
 
 protected:
     virtual bool onTick(
         TickQueue* zQueue, int numTicks, bool& blocked) override;
     virtual void onPostTick() override;
+    void broadcastAmount();
 
 public:
     FluidBlock(int typeId, Framework::Vec3<int> pos);

+ 1 - 7
FactoryCraft/Game.cpp

@@ -243,13 +243,7 @@ void GameClient::sendTypes()
     for (int i = 0; i < count; i++)
     {
         BlockType* t = StaticRegistry<BlockType>::INSTANCE.zElement(i);
-        int id = t->getId();
-        client->zForegroundWriter()->schreibe((char*)&id, 4);
-        bool inst = t->doesNeedClientInstance();
-        client->zForegroundWriter()->schreibe((char*)&inst, 1);
-        int maxHp = t->getInitialMaxHP();
-        client->zForegroundWriter()->schreibe((char*)&maxHp, 4);
-        t->getModel().writeTo(client->zForegroundWriter());
+        t->writeTypeInfo(client->zForegroundWriter());
     }
     count = 0;
     for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)

+ 1 - 1
FactoryCraft/Grass.cpp

@@ -66,7 +66,7 @@ void GrassBlock::onDestroy()
 
 GrassBlockType::GrassBlockType(
     int typeId, int itemTypeId, ModelInfo model, const char* name)
-    : BlockType(typeId, 0, model, 1, 10, 0, name),
+    : BlockType(typeId, 0, model, 1, 10, 0, name, false),
       itemType(itemTypeId),
       transparent(true),
       passable(true),

+ 13 - 2
FactoryCraft/GrasslandBiom.cpp

@@ -8,6 +8,7 @@
 #include "FastNoiseWrapper.h"
 #include "NoBlock.h"
 #include "TreeTemplate.h"
+#include "RandNoise.h"
 
 GrasslandBiom::GrasslandBiom()
     : BiomGenerator()
@@ -36,11 +37,15 @@ GrasslandBiom::GrasslandBiom()
     undergroundDirdNoise = 0;
     surfaceSandNoise = 0;
     undergroundGravelNoise = 0;
+    grassNoise = 0;
 }
 
 GrasslandBiom::~GrasslandBiom()
 {
     if (heightNoise) heightNoise->release();
+    if (grassNoise) grassNoise->release();
+    if (undergroundGravelNoise) undergroundGravelNoise->release();
+    if (undergroundDirdNoise) undergroundDirdNoise->release();
 }
 
 Framework::Either<Block*, int> GrasslandBiom::generateAboveSurfaceBlock(
@@ -53,9 +58,14 @@ Framework::Either<Block*, int> GrasslandBiom::generateAboveSurfaceBlock(
     auto below
         = partialGeneratedChunk->zBlockAt(Framework::Vec3<int>(cx, cy, z - 1));
     if ((below.isA()
-            && below.getA()->zBlockType()->getId() == BlockTypeEnum::DIRT)
+        && below.getA()->zBlockType()->getId() == BlockTypeEnum::DIRT)
         || (below.isB() && below.getB() == BlockTypeEnum::DIRT))
-        return BlockTypeEnum::GRASS;
+    {
+        if (grassNoise->getNoise((double)x, (double)y, (double)z) > 0.75)
+        {
+            return BlockTypeEnum::GRASS;
+        }
+    }
     return BlockTypeEnum::AIR;
 }
 
@@ -123,6 +133,7 @@ void GrasslandBiom::setSeed(int seed)
     noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_ValueCubic);
     noise->SetFrequency(0.1f);
     surfaceSandNoise = new FastNoiseWrapper(noise, seed + 2);
+    grassNoise = new RandNoise(seed + 3);
 }
 
 Noise* GrasslandBiom::zHeightMapNoise()

+ 1 - 0
FactoryCraft/GrasslandBiom.h

@@ -9,6 +9,7 @@ class GrasslandBiom : public BiomGenerator
     Noise* undergroundDirdNoise;
     Noise* surfaceSandNoise;
     Noise* undergroundGravelNoise;
+    Noise* grassNoise;
     // TODO: Noise* anySmallOreNoise;
     // TODO: add water rivers
 

+ 1 - 1
FactoryCraft/GrowingPlant.cpp

@@ -105,7 +105,7 @@ GrowingPlantBlockType::GrowingPlantBlockType(int typeId,
     int blockTypeAfterGrowth,
     const char* readableName,
     int ticksNeeded)
-    : BlockType(typeId, 0, model, 1, 10.f, 0, name),
+    : BlockType(typeId, 0, model, 1, 10.f, 0, name, true),
       transparent(1),
       passable(1),
       hardness(0.1f),

+ 3 - 3
FactoryCraft/Inventory.cpp

@@ -163,9 +163,9 @@ void InventoryInteraction::pushItems(int count, ItemFilter* zFilter)
 }
 
 MultipleInventoryLock::MultipleInventoryLock(Inventory** inventories, int count)
-    : locked(0),
+    : inventories(new Inventory*[count]),
       count(count),
-      inventories(new Inventory*[count])
+      locked(0)
 {
     // sort given inventories in locking order
     bool used[count];
@@ -211,7 +211,7 @@ MultipleInventoryLock::MultipleInventoryLock(Inventory** inventories, int count)
                 }
             }
         }
-        inventories[i] = min;
+        this->inventories[i] = min;
         used[minJ] = 1;
     }
     lock();

+ 1 - 1
FactoryCraft/LightSources.cpp

@@ -69,7 +69,7 @@ void BasicLightSource::onPostTick() {}
 
 BasicLightSourceBlockType::BasicLightSourceBlockType(
     int typeId, int itemTypeId, ModelInfo model, const char* name)
-    : BlockType(typeId, 0, model, 1, 1, 1, name),
+    : BlockType(typeId, 0, model, 1, 1, 1, name, false),
       itemType(itemTypeId),
       transparent(1),
       passable(1),

+ 1 - 1
FactoryCraft/NoBlock.cpp

@@ -1,7 +1,7 @@
 #include "NoBlock.h"
 
 NoBlockBlockType::NoBlockBlockType(int id, const Block* defaultB)
-    : BlockType(id, 0, ModelInfo("", "", 0), 0, 1, 0, ""),
+    : BlockType(id, 0, ModelInfo("", "", 0), 0, 1, 0, "", false),
       defaultB(defaultB)
 {}
 

+ 4 - 6
FactoryCraft/TickQueue.cpp

@@ -26,10 +26,8 @@ void TickQueue::startNextTick(Framework::Array<Tickable*>* zSources)
     if (count >= maxSize)
     {
         Tickable** temp = new Tickable*[count + 1000];
-        memcpy(queue, temp, sizeof(Tickable*) * maxSize);
-        memset(temp + sizeof(Tickable*) * maxSize,
-            0,
-            sizeof(Tickable*) * (count + 1000 - maxSize));
+        memcpy(temp, queue, sizeof(Tickable*) * maxSize);
+        memset(temp + maxSize, 0, sizeof(Tickable*) * (count + 1000 - maxSize));
         maxSize = count + 1000;
         delete[] queue;
         queue = temp;
@@ -46,8 +44,8 @@ void TickQueue::addToQueue(Tickable* zBlock)
     if (writePosition >= maxSize)
     {
         Tickable** temp = new Tickable*[maxSize + 1000];
-        memcpy(queue, temp, sizeof(Tickable*) * maxSize);
-        memset(temp + sizeof(Tickable*) * maxSize, 0, sizeof(Tickable*) * 1000);
+        memcpy(temp, queue, sizeof(Tickable*) * maxSize);
+        memset(temp + maxSize, 0, sizeof(Tickable*) * 1000);
         maxSize += 1000;
         delete[] queue;
         queue = temp;

+ 1 - 1
FactoryCraft/TreeSeblingBlock.cpp

@@ -70,7 +70,7 @@ TreeSeblingBlockType::TreeSeblingBlockType(int typeId,
     int woodType,
     int leavesType,
     const char* name)
-    : BlockType(typeId, 0, model, 1, 10, 0, name),
+    : BlockType(typeId, 0, model, 1, 10, 0, name, false),
       itemType(itemTypeId),
       transparent(true),
       passable(true),

BIN
Windows Version/Framework.dll


+ 19 - 4
Windows Version/Start.cpp

@@ -33,6 +33,8 @@ void updateView()
         = position
         + Vec3<int>(img->getBreite() / 2, img->getHeight() / 2, 0) / zoom;
     int counter = 0;
+    double min = INFINITY;
+    double max = -INFINITY;
     for (int i = 0; i < img->getBreite(); i++)
     {
         for (int j = 0; j < img->getHeight(); j++)
@@ -42,6 +44,14 @@ void updateView()
             pos /= zoom;
             pos += position;
 			double noise = wrapper->getNoise(pos.x, pos.y, pos.z);
+            if (noise > max)
+            {
+                max = noise;
+            }
+            if (noise < min)
+            {
+                min = noise;
+            }
             if (showValue)
             {
                 int value = (int)(noise * 255);
@@ -67,18 +77,23 @@ void updateView()
               << " " << maxP.y << " at height " << position.z << " with border "
               << border2 << " to "
               << border << " true for " << percentage << "% of "
-              << (img->getBreite() / zoom) * (img->getHeight() / zoom) << " blocks"
+              << (img->getBreite() / zoom) * (img->getHeight() / zoom)
+              << " blocks. Min: " << min << " Max: " << max
               << std::endl;
 }
 
 int main()
 {
     Framework::initFramework();
+    FastNoiseLite* noise = new FastNoiseLite(0);
+    noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_ValueCubic);
+    wrapper = new FastNoiseWrapper(noise, 0);
+    ((FastNoiseWrapper*)wrapper)->setMultiplier(0.2f);
     /* FastNoiseLite* noise = new FastNoiseLite(0);
     noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_ValueCubic);
     noise->SetFrequency(3.f);
     wrapper = new FastNoiseWrapper(noise, 0);*/
-    FastNoiseLite* n = new FastNoiseLite(0);
+    /* FastNoiseLite* n = new FastNoiseLite(0);
     n->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_Cellular);
     n->SetFrequency(0.005f);
     n->SetRotationType3D(FastNoiseLite::RotationType3D::RotationType3D_None);
@@ -98,10 +113,10 @@ int main()
     wrapper = new FastNoiseWrapper(n, 0);
     wrapper = new ShapedNoise(wrapper);
     ((ShapedNoise*)wrapper)->setNeighborOffset(4.f);
-    wrapper = new RandNoise(34255);
+    wrapper = new RandNoise(34255);*/
 
     img = new Bild();
-    img->neuBild(800, 800, 0xFF000000);
+    img->neuBild(1600, 1600, 0xFF000000);
 
     BildZ* view = new BildZ();
     view->setBildZ(img);