#include "TreeSeblingBlock.h" #include "BasicBlocks.h" #include "Game.h" #include "NoBlock.h" #include "RandNoise.h" #include "TreeTemplate.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) { tickSource = 1; } 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->getWoodType() == wood && tree->getLeavesType() == leaves; })) { Game::INSTANCE->zDimension(dim)->placeBlock( pos, BlockTypeEnum::AIR); } }); } } Framework::Text TreeSeblingBlock::getTargetUIML() { return Text("") + Game::INSTANCE->zBlockType(typeId)->getName() + "\n" + "Growth: " + Text((int)(seblingTicks / (float)seblingTicksMax * 100.f)) + "%"; } TreeSeblingBlockType::TreeSeblingBlockType(Framework::Text itemTypeName, ModelInfo* model, Framework::Text woodTypeName, Framework::Text leavesTypeName, Framework::Text name, int mapColor, float hardness, Framework::RCArray groupNames) : BlockType( 0, model, true, 10, false, name, false, mapColor, groupNames, hardness), itemTypeName(itemTypeName), transparent(true), passable(true), speedModifier(0.5f), interactable(1), woodTypeName(woodTypeName), leavesTypeName(leavesTypeName) {} 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); } Framework::Text TreeSeblingBlockType::getItemTypeName() const { return itemTypeName; } Framework::Text TreeSeblingBlockType::getWoodTypeName() const { return woodTypeName; } Framework::Text TreeSeblingBlockType::getLeavesTypeName() const { return leavesTypeName; } 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() : SubTypeFactory() {} TreeSeblingBlockType* TreeSeblingBlockTypeFactory::fromJson( Framework::JSON::JSONObject* zJson) const { Framework::RCArray groupNames; for (Framework::JSON::JSONValue* value : *zJson->zValue("groupNames")->asArray()) { groupNames.add(new Framework::Text(value->asString()->getString())); } return new TreeSeblingBlockType( zJson->zValue("itemType")->asString()->getString(), Game::INSTANCE->zTypeRegistry()->fromJson( zJson->zValue("model")), zJson->zValue("woodType")->asString()->getString(), zJson->zValue("leavesType")->asString()->getString(), zJson->zValue("name")->asString()->getString(), (int)zJson->zValue("mapColor")->asString()->getString(), (float)zJson->zValue("hardness")->asNumber()->getNumber(), groupNames); } Framework::JSON::JSONObject* TreeSeblingBlockTypeFactory::toJson( TreeSeblingBlockType* zObject) const { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); result->addValue("itemType", new Framework::JSON::JSONString(zObject->getItemTypeName())); result->addValue( "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel())); result->addValue( "name", new Framework::JSON::JSONString(zObject->getName())); result->addValue( "hardness", new Framework::JSON::JSONNumber(zObject->getHardness())); result->addValue( "mapColor", new Framework::JSON::JSONString(zObject->getMapColor())); result->addValue("woodType", new Framework::JSON::JSONString(zObject->getWoodTypeName())); result->addValue("leavesType", new Framework::JSON::JSONString(zObject->getLeavesTypeName())); Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray(); for (Framework::Text* groupName : zObject->getGroupNames()) { groupNames->addValue(new Framework::JSON::JSONString(*groupName)); } result->addValue("groupNames", groupNames); return result; } Framework::JSON::Validator::JSONValidator* TreeSeblingBlockTypeFactory::getValidator( Framework::JSON::Validator::ObjectValidationBuilder< Framework::JSON::Validator::JSONValidator>* builder) const { return builder->withRequiredString("itemType") ->finishString() ->withRequiredAttribute( "model", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredString("name") ->finishString() ->withRequiredNumber("hardness") ->withDefault(1.0) ->finishNumber() ->withRequiredString("mapColor") ->finishString() ->withRequiredString("woodType") ->finishString() ->withRequiredString("leavesType") ->finishString() ->withRequiredArray("groupNames") ->withDefault(new Framework::JSON::JSONArray()) ->addAcceptedStringInArray() ->finishString() ->finishArray() ->finishObject(); } Framework::Text TreeSeblingBlockTypeFactory::getTypeToken() const { return "treeSapling"; }