|
@@ -0,0 +1,178 @@
|
|
|
+#include "GrowingPlant.h"
|
|
|
+
|
|
|
+#include "Game.h"
|
|
|
+
|
|
|
+GrowthState::GrowthState(float percentage, ModelInfo model)
|
|
|
+ : percentage(percentage),
|
|
|
+ model(model)
|
|
|
+{}
|
|
|
+
|
|
|
+GrowthState::GrowthState()
|
|
|
+ : percentage(1),
|
|
|
+ model("", "", 0)
|
|
|
+{}
|
|
|
+
|
|
|
+GrowthState& GrowthState::operator=(const GrowthState& right)
|
|
|
+{
|
|
|
+ percentage = right.percentage;
|
|
|
+ model = ModelInfo(right.model);
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+GrowingPlantBlock::GrowingPlantBlock(int typeId,
|
|
|
+ const ItemType* zTool,
|
|
|
+ Framework::Vec3<int> pos,
|
|
|
+ int maxTicks,
|
|
|
+ const char* name,
|
|
|
+ int blockTypeAfterGrowth)
|
|
|
+ : Block(typeId, zTool, pos, 0),
|
|
|
+ seblingTicks(0),
|
|
|
+ seblingTicksMax(maxTicks),
|
|
|
+ name(name),
|
|
|
+ states(),
|
|
|
+ blockTypeAfterGrowth(blockTypeAfterGrowth),
|
|
|
+ plantSpawned(0),
|
|
|
+ modelUpdated(0)
|
|
|
+{
|
|
|
+ tickSource = 1;
|
|
|
+}
|
|
|
+
|
|
|
+bool GrowingPlantBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
|
|
|
+{
|
|
|
+ float beforePercentage = seblingTicks / (float)seblingTicksMax;
|
|
|
+ seblingTicks += (float)numTicks;
|
|
|
+ if ((int)(seblingTicks / (float)seblingTicksMax * 100.f)
|
|
|
+ != (int)(beforePercentage * 100.f))
|
|
|
+ {
|
|
|
+ Game::INSTANCE->blockTargetChanged(this);
|
|
|
+ }
|
|
|
+ for (const GrowthState& state : states)
|
|
|
+ {
|
|
|
+ if ((state.percentage > beforePercentage || !modelUpdated)
|
|
|
+ && state.percentage <= seblingTicks / (float)seblingTicksMax)
|
|
|
+ {
|
|
|
+ updateModel(state.model);
|
|
|
+ modelUpdated = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+void GrowingPlantBlock::onPostTick()
|
|
|
+{
|
|
|
+ if (seblingTicks >= (float)seblingTicksMax && !plantSpawned)
|
|
|
+ {
|
|
|
+ plantSpawned = 1;
|
|
|
+ Game::INSTANCE->doLater([this]() {
|
|
|
+ Game::INSTANCE->zDimension(getDimensionId())
|
|
|
+ ->placeBlock(getPos(), blockTypeAfterGrowth);
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Text GrowingPlantBlock::getTargetUIML()
|
|
|
+{
|
|
|
+ return Text("<targetInfo><text width=\"auto\" height=\"auto\">") + name
|
|
|
+ + "\n" + "Growth: "
|
|
|
+ + Text((int)(seblingTicks / (float)seblingTicksMax * 100.f))
|
|
|
+ + "%</text></targetInfo>";
|
|
|
+}
|
|
|
+
|
|
|
+GrowingPlantBlock* GrowingPlantBlock::addGrowthState(GrowthState state)
|
|
|
+{
|
|
|
+ int index = 0;
|
|
|
+ for (const GrowthState& s : states)
|
|
|
+ {
|
|
|
+ if (s.percentage > state.percentage)
|
|
|
+ {
|
|
|
+ states.add(state, index);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ states.add(state);
|
|
|
+ return this;
|
|
|
+}
|
|
|
+
|
|
|
+GrowingPlantlockType::GrowingPlantlockType(int typeId,
|
|
|
+ ModelInfo model,
|
|
|
+ const char* name,
|
|
|
+ int blockTypeAfterGrowth,
|
|
|
+ const char* readableName,
|
|
|
+ int ticksNeeded)
|
|
|
+ : BlockType(typeId, 0, model, 1, 10.f, 0, name),
|
|
|
+ transparent(1),
|
|
|
+ passable(1),
|
|
|
+ hardness(0.1f),
|
|
|
+ zTool(0),
|
|
|
+ speedModifier(0.3f),
|
|
|
+ interactable(1),
|
|
|
+ states(),
|
|
|
+ blockTypeAfterGrowth(blockTypeAfterGrowth),
|
|
|
+ readableName(readableName),
|
|
|
+ ticksNeeded(ticksNeeded)
|
|
|
+{}
|
|
|
+
|
|
|
+GrowingPlantlockType* GrowingPlantlockType::setHardness(float hardness)
|
|
|
+{
|
|
|
+ this->hardness = hardness;
|
|
|
+ return this;
|
|
|
+}
|
|
|
+
|
|
|
+GrowingPlantlockType* GrowingPlantlockType::addGrowthState(
|
|
|
+ float growthPercentage, ModelInfo model)
|
|
|
+{
|
|
|
+ states.add(GrowthState(growthPercentage, model));
|
|
|
+ return this;
|
|
|
+}
|
|
|
+
|
|
|
+void GrowingPlantlockType::createSuperBlock(Block* zBlock, Item* zItem) const
|
|
|
+{
|
|
|
+ GrowingPlantlockType* block = dynamic_cast<GrowingPlantlockType*>(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->hardness = hardness;
|
|
|
+ block->zTool = zTool;
|
|
|
+ block->speedModifier = speedModifier;
|
|
|
+ block->interactable = interactable;
|
|
|
+ BlockType::createSuperBlock(zBlock, zItem);
|
|
|
+}
|
|
|
+
|
|
|
+void GrowingPlantlockType::loadSuperBlock(
|
|
|
+ Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
|
|
|
+{
|
|
|
+ BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
|
|
|
+ GrowingPlantBlock* block = dynamic_cast<GrowingPlantBlock*>(zBlock);
|
|
|
+ zReader->lese((char*)&block->seblingTicks, 4);
|
|
|
+}
|
|
|
+
|
|
|
+void GrowingPlantlockType::saveSuperBlock(
|
|
|
+ Block* zBlock, Framework::StreamWriter* zWriter) const
|
|
|
+{
|
|
|
+ BlockType::saveSuperBlock(zBlock, zWriter);
|
|
|
+ GrowingPlantBlock* block = dynamic_cast<GrowingPlantBlock*>(zBlock);
|
|
|
+ zWriter->schreibe((char*)&block->seblingTicks, 4);
|
|
|
+}
|
|
|
+
|
|
|
+Item* GrowingPlantlockType::createItem() const
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+Block* GrowingPlantlockType::createBlock(Framework::Vec3<int> position) const
|
|
|
+{
|
|
|
+ GrowingPlantBlock* block = new GrowingPlantBlock(getId(),
|
|
|
+ zTool,
|
|
|
+ position,
|
|
|
+ ticksNeeded,
|
|
|
+ readableName,
|
|
|
+ blockTypeAfterGrowth);
|
|
|
+ for (const GrowthState& state : states)
|
|
|
+ {
|
|
|
+ block->addGrowthState(state);
|
|
|
+ }
|
|
|
+ return block;
|
|
|
+}
|