#include "TreeSeblingBlock.h" #include "BasicBlocks.h" #include "Dimension.h" #include "Game.h" #include "NoBlock.h" #include "RandNoise.h" #include "TreeTemplate.h" #include "WorldGenerator.h" TreeSeblingBlock::TreeSeblingBlock(int typeId, Framework::Vec3 pos, int dimensionId, const BlockType* wood, const BlockType* leaves) : Block(typeId, pos, dimensionId, 0), seblingTicks(0), seblingTicksMax(10000), wood(wood), leaves(leaves) {} bool TreeSeblingBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked) { int lastPercentage = (int)(seblingTicks / (float)seblingTicksMax * 100.f); seblingTicks += 1; if ((int)(seblingTicks / (float)seblingTicksMax * 100.f) != lastPercentage) { Game::INSTANCE->blockTargetChanged(this); } return 0; } void TreeSeblingBlock::onPostTick() { if ((int)seblingTicks >= seblingTicksMax) { Game::INSTANCE->doLater([wood = wood, leaves = leaves, pos = getPos(), dim = getDimensionId()]() { // the tree sebling object will be deleted during this operation RandNoise noise((int)time(0)); if (!Game::INSTANCE->zGenerator()->spawnStructure(pos, dim, [wood = wood, leaves = leaves](GeneratorTemplate* tmpl) { TreeTemplate* tree = dynamic_cast(tmpl); return tree && tree->zWoodType() == wood && tree->zLeavesType() == leaves; })) { Game::INSTANCE->zDimension(dim)->placeBlock( pos, BlockTypeEnum::AIR); } }); } } TickSourceType TreeSeblingBlock::isTickSource() const { return TickSourceType::EACH_TICK; } Framework::Text TreeSeblingBlock::getTargetUIML() { return Framework::Text("") + Game::INSTANCE->zBlockType(typeId)->getName() + "\n" + "Growth: " + Framework::Text((int)(seblingTicks / (float)seblingTicksMax * 100.f)) + "%"; } TreeSeblingBlockType::TreeSeblingBlockType() : BlockType(), transparent(true), passable(true), speedModifier(0.5f), interactable(1) {} bool TreeSeblingBlockType::initialize(Game* zGame) { if (itemTypeName.getLength()) { itemTypeId = zGame->getItemTypeId(itemTypeName); } else { itemTypeId = 0; } woodTypeId = zGame->getBlockTypeId(woodTypeName); leavesTypeId = zGame->getBlockTypeId(leavesTypeName); return itemTypeId >= 0 && BlockType::initialize(zGame); } void TreeSeblingBlockType::setItemTypeName(Framework::Text itemTypeName) { this->itemTypeName = itemTypeName; } Framework::Text TreeSeblingBlockType::getItemTypeName() const { return itemTypeName; } void TreeSeblingBlockType::setWoodTypeName(Framework::Text woodTypeName) { this->woodTypeName = woodTypeName; } Framework::Text TreeSeblingBlockType::getWoodTypeName() const { return woodTypeName; } void TreeSeblingBlockType::setLeavesTypeName(Framework::Text leavesTypeName) { this->leavesTypeName = leavesTypeName; } Framework::Text TreeSeblingBlockType::getLeavesTypeName() const { return leavesTypeName; } void TreeSeblingBlockType::setTransparent(bool transparent) { this->transparent = transparent; } bool TreeSeblingBlockType::isTransparent() const { return transparent; } void TreeSeblingBlockType::setPassable(bool passable) { this->passable = passable; } bool TreeSeblingBlockType::isPassable() const { return passable; } void TreeSeblingBlockType::setSpeedModifier(float speedModifier) { this->speedModifier = speedModifier; } float TreeSeblingBlockType::getSpeedModifier() const { return speedModifier; } void TreeSeblingBlockType::setInteractable(bool interactable) { this->interactable = interactable; } bool TreeSeblingBlockType::isInteractable() const { return interactable; } ItemType* TreeSeblingBlockType::createItemType() const { return new BasicBlockItemType(getItemTypeName(), new ModelInfo(zModel()->getModelPath(), zModel()->getTexturePaths(), zModel()->isTransparent(), zModel()->getSize() / 2.f), transparent, passable, getHardness(), speedModifier, getName(), 0, 50, getGroupNames()); } void TreeSeblingBlockType::createSuperBlock(Block* zBlock, Item* zItem) const { TreeSeblingBlock* block = dynamic_cast(zBlock); block->transparent = transparent; block->passable = passable; block->hp = (float)getInitialMaxHP(); block->maxHP = (float)getInitialMaxHP(); block->hardness = getHardness(); block->speedModifier = speedModifier; block->interactable = interactable; BlockType::createSuperBlock(zBlock, zItem); } void TreeSeblingBlockType::loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const { TreeSeblingBlock* block = dynamic_cast(zBlock); zReader->lese((char*)&block->seblingTicks, 4); zReader->lese((char*)&block->seblingTicksMax, 4); int id; zReader->lese((char*)&id, 4); block->wood = Game::INSTANCE->zBlockType(id); zReader->lese((char*)&id, 4); block->leaves = Game::INSTANCE->zBlockType(id); BlockType::loadSuperBlock(zBlock, zReader, dimensionId); } void TreeSeblingBlockType::saveSuperBlock( Block* zBlock, Framework::StreamWriter* zWriter) const { TreeSeblingBlock* block = dynamic_cast(zBlock); zWriter->schreibe((char*)&block->seblingTicks, 4); zWriter->schreibe((char*)&block->seblingTicksMax, 4); int id = block->wood->getId(); zWriter->schreibe((char*)&id, 4); id = block->leaves->getId(); zWriter->schreibe((char*)&id, 4); BlockType::saveSuperBlock(zBlock, zWriter); } Item* TreeSeblingBlockType::createItem() const { return Game::INSTANCE->zItemType(itemTypeId)->createItem(); } Block* TreeSeblingBlockType::createBlock( Framework::Vec3 position, int dimensionId) const { return new TreeSeblingBlock(getId(), position, dimensionId, Game::INSTANCE->zBlockType(woodTypeId), Game::INSTANCE->zBlockType(leavesTypeId)); } TreeSeblingBlockTypeFactory::TreeSeblingBlockTypeFactory() : BlockTypeFactoryBase() {} TreeSeblingBlockType* TreeSeblingBlockTypeFactory::createValue( Framework::JSON::JSONObject* zJson) const { return new TreeSeblingBlockType(); } void TreeSeblingBlockTypeFactory::fromJson( TreeSeblingBlockType* zResult, Framework::JSON::JSONObject* zJson) const { zResult->setItemTypeName( zJson->zValue("itemType")->asString()->getString()); zResult->setWoodTypeName( zJson->zValue("woodType")->asString()->getString()); zResult->setLeavesTypeName( zJson->zValue("leavesType")->asString()->getString()); zResult->setTransparent(zJson->zValue("transparent")->asBool()->getBool()); zResult->setPassable(zJson->zValue("passable")->asBool()->getBool()); zResult->setSpeedModifier( (float)zJson->zValue("speedModifier")->asNumber()->getNumber()); zResult->setInteractable( zJson->zValue("interactable")->asBool()->getBool()); BlockTypeFactoryBase::fromJson(zResult, zJson); } void TreeSeblingBlockTypeFactory::toJson( TreeSeblingBlockType* zObject, Framework::JSON::JSONObject* zResult) const { zResult->addValue("itemType", new Framework::JSON::JSONString(zObject->getItemTypeName())); zResult->addValue("woodType", new Framework::JSON::JSONString(zObject->getWoodTypeName())); zResult->addValue("leavesType", new Framework::JSON::JSONString(zObject->getLeavesTypeName())); zResult->addValue("transparent", new Framework::JSON::JSONNumber(zObject->isTransparent())); zResult->addValue( "passable", new Framework::JSON::JSONNumber(zObject->isPassable())); zResult->addValue("speedModifier", new Framework::JSON::JSONNumber(zObject->getSpeedModifier())); zResult->addValue("interactable", new Framework::JSON::JSONNumber(zObject->isInteractable())); BlockTypeFactoryBase::toJson(zObject, zResult); } JSONObjectValidationBuilder* TreeSeblingBlockTypeFactory::addToValidator( JSONObjectValidationBuilder* builder) const { return BlockTypeFactoryBase::addToValidator( builder->withRequiredString("itemType") ->finishString() ->withRequiredString("woodType") ->finishString() ->withRequiredString("leavesType") ->finishString() ->withRequiredBool("transparent") ->withDefault(true) ->finishBool() ->withRequiredBool("passable") ->withDefault(true) ->finishBool() ->withRequiredNumber("speedModifier") ->withDefault(0.5) ->finishNumber() ->withRequiredBool("interactable") ->withDefault(true) ->finishBool()); } Framework::Text TreeSeblingBlockTypeFactory::getTypeToken() const { return "treeSapling"; }