Browse Source

wheat can now only be planted on farmand and satisfy hunger and thirs when eating

Kolja Strohm 2 years ago
parent
commit
41a06f9e2e

+ 5 - 3
FactoryCraft/BasicBlock.cpp

@@ -91,9 +91,6 @@ BasicBlockType::BasicBlockType(int typeId,
 void BasicBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
     BasicBlock* block = dynamic_cast<BasicBlock*>(zBlock);
-    if (!block)
-        throw "DirtBlockType::createSuperBlock was called with a block witch "
-              "is not an instance of BasicBlock";
     block->transparent = transparent;
     block->passable = passable;
     block->hp = (float)getInitialMaxHP();
@@ -119,4 +116,9 @@ BasicBlockType* BasicBlockType::setHardness(float hardness)
 {
     this->hardness = hardness;
     return this;
+}
+
+BasicBlockType* BasicBlockType::setTransparent(bool transparent) {
+    this->transparent = transparent;
+    return this;
 }

+ 1 - 0
FactoryCraft/BasicBlocks.h

@@ -65,4 +65,5 @@ public:
     virtual Block* createBlock(Framework::Vec3<int> position) const override;
     virtual Item* createItem() const override;
     BasicBlockType* setHardness(float hardness);
+    BasicBlockType* setTransparent(bool transparent);
 };

+ 45 - 1
FactoryCraft/Block.cpp

@@ -185,7 +185,8 @@ void Block::onUnloaded()
 
 Framework::Text Block::getTargetUIML()
 {
-    return StaticRegistry<BlockType>::INSTANCE.zElement(typeId)->getTargetUIML();
+    return StaticRegistry<BlockType>::INSTANCE.zElement(typeId)
+        ->getTargetUIML();
 }
 
 void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
@@ -330,6 +331,30 @@ BasicBlockItem::BasicBlockItem(
 {
     this->blockTypeId = blockTypeId;
     placeable = 1;
+    placableProof = [this](const Item* self,
+                        int dimensionId,
+                        Framework::Vec3<int> worldPos) {
+        return Item::canBePlacedAt(dimensionId, worldPos);
+    };
+}
+
+void BasicBlockItem::setPlacableProof(
+    std::function<bool(const Item*, int, Framework::Vec3<int>)> condition,
+    bool andDefault)
+{
+    if (andDefault)
+    {
+        placableProof = [this, condition](const Item* self,
+                            int dimensionId,
+                            Framework::Vec3<int> worldPos) {
+            return Item::canBePlacedAt(dimensionId, worldPos)
+                && condition(self, dimensionId, worldPos);
+        };
+    }
+    else
+    {
+        placableProof = condition;
+    }
 }
 
 bool BasicBlockItem::canBeStackedWith(const Item* zItem) const
@@ -345,6 +370,12 @@ bool BasicBlockItem::canBeStackedWith(const Item* zItem) const
     return 0;
 }
 
+bool BasicBlockItem::canBePlacedAt(
+    int dimensionId, Framework::Vec3<int> worldPos) const
+{
+    return placableProof(this, dimensionId, worldPos);
+}
+
 BasicBlockItemType::BasicBlockItemType(int id,
     const char* name,
     ItemSkillLevelUpRule* levelUpRule,
@@ -401,6 +432,10 @@ Item* BasicBlockItemType::createItem() const
     item->toolId = toolId;
     item->speedModifier = speedModifier;
     item->interactable = 1;
+    if (placableProofState)
+    {
+        item->setPlacableProof(placableProof, placableProofState > 1);
+    }
     return item;
 }
 
@@ -408,4 +443,13 @@ BasicBlockItemType* BasicBlockItemType::setHardness(float hardness)
 {
     this->hardness = hardness;
     return this;
+}
+
+BasicBlockItemType* BasicBlockItemType::setPlacableProof(
+    std::function<bool(const Item*, int, Framework::Vec3<int>)> condition,
+    bool andDefault)
+{
+    placableProofState = 1 + (andDefault ? 1 : 0);
+    placableProof = condition;
+    return this;
 }

+ 10 - 0
FactoryCraft/Block.h

@@ -126,10 +126,15 @@ protected:
     int toolId;
     float speedModifier;
     bool interactable;
+    std::function<bool(const Item*, int, Framework::Vec3<int>)> placableProof;
 
 public:
     BasicBlockItem(int itemTypeId, int blockTypeId, const char* name);
+    void setPlacableProof(
+        std::function<bool(const Item*, int, Framework::Vec3<int>)> condition,
+        bool andDefault);
     virtual bool canBeStackedWith(const Item* zItem) const override;
+    virtual bool canBePlacedAt(int dimensionId, Framework::Vec3<int> worldPos) const override;
 
     friend BasicBlockItemType;
     friend BlockType;
@@ -144,6 +149,8 @@ protected:
     int toolId;
     float speedModifier;
     int blockTypeId;
+    char placableProofState;
+    std::function<bool(const Item*, int, Framework::Vec3<int>)> placableProof;
 
     virtual void loadSuperItem(
         Item* zItem, Framework::StreamReader* zReader) const override;
@@ -159,4 +166,7 @@ public:
         ModelInfo model,
         int blockTypeId);
     BasicBlockItemType* setHardness(float hardness);
+    BasicBlockItemType* setPlacableProof(
+        std::function<bool(const Item*, int, Framework::Vec3<int>)> condition,
+        bool andDefault);
 };

+ 16 - 15
FactoryCraft/Entity.cpp

@@ -37,7 +37,8 @@ void ActionTarget::applyItemSkillOnTarget(
 {
     if (entityId >= 0)
     {
-        // TODO: get entity from game and apply skill
+        Entity* target = Game::INSTANCE->zEntity(entityId);
+        if (target) zItemSkill->use(zActor, zUsedItem, target);
     }
     else
     {
@@ -49,20 +50,20 @@ void ActionTarget::applyItemSkillOnTarget(
 
 void ActionTarget::placeBlock(Entity* zActor, Item* zItem)
 {
-    // TODO: check stamina of actor
-    auto zB = Game::INSTANCE->zBlockAt(blockPos + getDirection(targetBlockSide),
-        zActor->getCurrentDimensionId());
-    if ((zB.isA() && zB.getA()->zBlockType()->getId() == BlockTypeEnum::AIR)
-        || (zB.isB() && zB.isB() == BlockTypeEnum::AIR))
+    if (zActor->getStamina() > 0.2f)
     {
-        Block* block = zItem->zPlacedBlockType()->createBlockAt(
-            blockPos + getDirection(targetBlockSide), zItem);
-        if (block)
+        if (zItem->canBePlacedAt(zActor->getCurrentDimensionId(),
+                blockPos + getDirection(targetBlockSide)))
         {
-            Game::INSTANCE->zDimension(zActor->getCurrentDimensionId())
-                ->placeBlock(block->getPos(), block);
-            zItem->onPlaced();
-            // TODO: decrese stamina of actor
+            Block* block = zItem->zPlacedBlockType()->createBlockAt(
+                blockPos + getDirection(targetBlockSide), zItem);
+            if (block)
+            {
+                Game::INSTANCE->zDimension(zActor->getCurrentDimensionId())
+                    ->placeBlock(block->getPos(), block);
+                zItem->onPlaced();
+                zActor->setStamina(zActor->getStamina() - 0.2f);
+            }
         }
     }
 }
@@ -191,11 +192,11 @@ void Entity::onDeath()
 void Entity::useItem(int typeId, Item* zItem)
 {
     if (zItem && zItem->isEatable())
-    { // TODO: eat item
+    { // eat item
         zItem->applyFoodEffects(this);
     }
     else if (zItem && zItem->isPlaceable())
-    { // TODO: place item
+    { // place item
         if (placeBlockCooldown <= 0)
         {
             cs.lock();

+ 0 - 3
FactoryCraft/Grass.cpp

@@ -79,9 +79,6 @@ GrassBlockType::GrassBlockType(
 void GrassBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
     GrassBlock* block = dynamic_cast<GrassBlock*>(zBlock);
-    if (!block)
-        throw "GrassBlockType::createSuperBlock was called with a block "
-              "witch is not an instance of GrassBlock";
     block->transparent = transparent;
     block->passable = passable;
     block->hp = (float)getInitialMaxHP();

+ 8 - 3
FactoryCraft/GrowingPlant.cpp

@@ -2,14 +2,19 @@
 
 #include "Game.h"
 
+GrowthState::GrowthState()
+    : percentage(1),
+      model("", "", 0)
+{}
+
 GrowthState::GrowthState(float percentage, ModelInfo model)
     : percentage(percentage),
       model(model)
 {}
 
-GrowthState::GrowthState()
-    : percentage(1),
-      model("", "", 0)
+GrowthState::GrowthState(const GrowthState& right)
+    : percentage(right.percentage),
+      model(right.model)
 {}
 
 GrowthState& GrowthState::operator=(const GrowthState& right)

+ 2 - 1
FactoryCraft/GrowingPlant.h

@@ -7,8 +7,9 @@ class GrowingPlantBlockType;
 
 struct GrowthState
 {
-    GrowthState(float percentage, ModelInfo model);
     GrowthState();
+    GrowthState(float percentage, ModelInfo model);
+    GrowthState(const GrowthState& right);
 
     GrowthState& operator=(const GrowthState& right);
 

+ 21 - 2
FactoryCraft/Item.cpp

@@ -2,6 +2,8 @@
 
 #include <Text.h>
 
+#include "Game.h"
+
 Item::Item(int itemTypeId, const char* name)
     : ReferenceCounter(),
       itemTypeId(itemTypeId),
@@ -17,7 +19,9 @@ Item::Item(int itemTypeId, const char* name)
       usable(0),
       maxStackSize(50),
       name(name)
-{}
+{
+    foodEffect = [](Entity* e) {};
+}
 
 void Item::setHp(float hp)
 {
@@ -31,6 +35,11 @@ void Item::setDurability(float durability)
 
 void Item::tick() {}
 
+void Item::setFoodEffect(std::function<void(Entity*)> foodEffect)
+{
+    this->foodEffect = foodEffect;
+}
+
 const ItemType* Item::zItemType() const
 {
     return StaticRegistry<ItemType>::INSTANCE.zElement(itemTypeId);
@@ -106,6 +115,13 @@ bool Item::canBeStackedWith(const Item* zItem) const
         && name.istGleich(zItem->name);
 }
 
+bool Item::canBePlacedAt(int dimensionId, Vec3<int> worldPos) const
+{
+    auto b = Game::INSTANCE->zBlockAt(worldPos, dimensionId);
+    return (b.isA() && b.getA()->zBlockType()->getId() == BlockTypeEnum::AIR)
+        || (b.isB() && b.getB() == BlockTypeEnum::AIR);
+}
+
 void Item::onPlaced()
 {
     hp = 0;
@@ -117,7 +133,10 @@ Framework::Text Item::getTooltipUIML() const
          + "</text></tip>";
 }
 
-void Item::applyInventoryEffects(Entity* zTarget) {}
+void Item::applyInventoryEffects(Entity* zTarget)
+{
+    foodEffect(zTarget);
+}
 
 void Item::removeInventoryEffects(Entity* zTarget) {}
 

+ 3 - 0
FactoryCraft/Item.h

@@ -24,6 +24,7 @@ protected:
     bool usable;
     int maxStackSize;
     Framework::Text name;
+    std::function<void(Entity*)> foodEffect;
     Item(int itemTypeId, const char* name);
 
 public:
@@ -31,6 +32,7 @@ public:
     void setDurability(float durability);
     virtual void tick();
 
+    void setFoodEffect(std::function<void(Entity*)> foodEffect);
     const ItemType* zItemType() const;
     int getTypeId() const;
     const BlockType* zPlacedBlockType() const;
@@ -45,6 +47,7 @@ public:
     int getMaxStackSize() const;
     float getMaxHp() const;
     virtual bool canBeStackedWith(const Item* zItem) const;
+    virtual bool canBePlacedAt(int dimensionId, Framework::Vec3<int> worldPos) const;
     virtual void onPlaced();
     virtual Framework::Text getTooltipUIML() const;
 

+ 0 - 3
FactoryCraft/LightSources.cpp

@@ -81,9 +81,6 @@ void BasicLightSourceBlockType::createSuperBlock(
     Block* zBlock, Item* zItem) const
 {
     BasicLightSource* block = dynamic_cast<BasicLightSource*>(zBlock);
-    if (!block)
-        throw "BasicLightSourceBlockType::createSuperBlock was called with a "
-              "block witch is not an instance of BasicLightSource";
     block->transparent = transparent;
     block->passable = passable;
     block->hp = (float)getInitialMaxHP();

+ 29 - 3
FactoryCraft/StaticInitializerOrder.cpp

@@ -20,6 +20,7 @@
 #include "AddEntityUpdate.h"
 #include "EntityRemovedUpdate.h"
 // Multiblocks
+#include "Game.h"
 #include "Hoe.h"
 #include "LightSources.h"
 #include "MultiblockTree.h"
@@ -217,6 +218,8 @@ void initializeBlockTypes()
                  "blocks.ltdb/farmland.png",
                  "blocks.ltdb/dirt.png"}),
          "Farmland"))
+        ->setTransparent(1)
+        ->setHardness(0.1f)
         ->initializeDefault();
     (new GrowingPlantBlockType(BlockTypeEnum::WHEAT_SEED,
          ModelInfo("grass", "plants.ltdb/wheatseeds.png", 16).setTransparent(),
@@ -500,14 +503,32 @@ void initializeItemTypes()
          0,
          ModelInfo("grass", "plants.ltdb/wheatseeds.png", 16),
          BlockTypeEnum::WHEAT_SEED))
-        ->setHardness(0.1f);
+        ->setHardness(0.1f)
+        ->setPlacableProof(
+            [](const Item* self,
+                int dimensionId,
+                Framework::Vec3<int> worldPos) {
+                if (worldPos.z > 0)
+                {
+                    auto below = Game::INSTANCE->zBlockAt(
+                        worldPos + getDirection(Direction::BOTTOM),
+                        dimensionId);
+                    return (below.isA()
+                               && below.getA()->zBlockType()->getId()
+                                      == BlockTypeEnum::FARMLAND)
+                        || (below.isB()
+                               && below.getB() == BlockTypeEnum::FARMLAND);
+                }
+                return (bool)0;
+            },
+            1);
     (new NoBlockItemType(ItemTypeEnum::WHEAT,
         "Wheat",
         0,
         0,
         ModelInfo("grass", "plants.ltdb/wheat.png", 16),
         []() {
-            return ItemType::createBasicItem(ItemTypeEnum::WHEAT,
+            Item *item = ItemType::createBasicItem(ItemTypeEnum::WHEAT,
                 "Wheat",
                 1.f,
                 1.f,
@@ -518,7 +539,12 @@ void initializeItemTypes()
                 0,
                 1,
                 0,
-                50); // TODO: add food increment on eating
+                50);
+            item->setFoodEffect([](Entity* zEntity) {
+                zEntity->setHunger(zEntity->getHunger() + 0.5f);
+                zEntity->setThirst(zEntity->getThirst() + 1.f); // TODO: remove thirst addition when water exists
+            });
+            return item;
         }));
 }
 

+ 0 - 8
FactoryCraft/StoneTool.cpp

@@ -17,9 +17,6 @@ void StoneToolItemType::loadSuperItemSkill(
     ItemSkill* zSkill, Framework::StreamReader* zReader) const
 {
     StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
-    if (!skill)
-        throw "StoneToolItemType::loadSuperItemSkill was called with an "
-              "invalid skill";
     zReader->lese((char*)&skill->level, 4);
     zReader->lese((char*)&skill->xp, 4);
     zReader->lese((char*)&skill->maxXP, 4);
@@ -29,9 +26,6 @@ void StoneToolItemType::saveSuperItemSkill(
     const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
 {
     const StoneToolSkill* skill = dynamic_cast<const StoneToolSkill*>(zSkill);
-    if (!skill)
-        throw "StoneToolItemType::saveSuperItemSkill was called with an "
-              "invalid skill";
     zWriter->schreibe((char*)&skill->level, 4);
     zWriter->schreibe((char*)&skill->xp, 4);
     zWriter->schreibe((char*)&skill->maxXP, 4);
@@ -55,8 +49,6 @@ StoneToolLevelUpRule::StoneToolLevelUpRule()
 void StoneToolLevelUpRule::applyOn(ItemSkill* zSkill)
 {
     StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
-    if (!skill)
-        throw "StoneToolLevelUpRule::applyOn was called with an invalid skill";
     if (skill->xp >= skill->maxXP)
     {
         skill->level++;

+ 0 - 9
FactoryCraft/TreeSeblingBlock.cpp

@@ -85,9 +85,6 @@ TreeSeblingBlockType::TreeSeblingBlockType(int typeId,
 void TreeSeblingBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
     TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
-    if (!block)
-        throw "TreeSeblingBlockType::createSuperBlock was called with a block "
-              "witch is not an instance of TreeSeblingBlock";
     block->transparent = transparent;
     block->passable = passable;
     block->hp = (float)getInitialMaxHP();
@@ -103,9 +100,6 @@ void TreeSeblingBlockType::loadSuperBlock(
     Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
 {
     TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
-    if (!block)
-        throw "TreeSeblingBlockType::loadSuperBlock was called with a block "
-              "witch is not an instance of TreeSeblingBlock";
     zReader->lese((char*)&block->seblingTicks, 4);
     zReader->lese((char*)&block->seblingTicksMax, 4);
     int id;
@@ -120,9 +114,6 @@ void TreeSeblingBlockType::saveSuperBlock(
     Block* zBlock, Framework::StreamWriter* zWriter) const
 {
     TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
-    if (!block)
-        throw "TreeSeblingBlockType::saveSuperBlock was called with a block "
-              "witch is not an instance of TreeSeblingBlock";
     zWriter->schreibe((char*)&block->seblingTicks, 4);
     zWriter->schreibe((char*)&block->seblingTicksMax, 4);
     int id = block->wood->getId();