#include "BasicBlocks.h" #include "AddEntityUpdate.h" #include "Game.h" #include "ItemEntity.h" #include "ModelInfo.h" #include "TreeSeblingBlock.h" BasicBlock::BasicBlock(int typeId, Framework::Vec3 pos, int dimensionId) : BasicBlock(typeId, pos, dimensionId, false) {} BasicBlock::BasicBlock( int typeId, Framework::Vec3 pos, int dimensionId, bool hasInventory) : Block(typeId, pos, dimensionId, hasInventory) {} bool BasicBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked) { return 0; } void BasicBlock::onPostTick() {} BasicBlockType::BasicBlockType(Framework::Text itemTypeName, ModelInfo* model, Framework::Text name, int mapColor, bool modelSubscription, float hardness, Framework::RCArray groupNames) : BlockType(0, model, 1, 100, 0, name, modelSubscription, mapColor, groupNames, hardness), itemTypeName(itemTypeName), transparent(0), passable(0), speedModifier(1.f), interactable(1) {} bool BasicBlockType::initialize(Game* zGame) { if (itemTypeName.getLength()) { itemTypeId = zGame->getItemTypeId(itemTypeName); } else { itemTypeId = 0; } return itemTypeId >= 0 && BlockType::initialize(zGame); } void BasicBlockType::createSuperBlock(Block* zBlock, Item* zItem) const { BasicBlock* 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); } Block* BasicBlockType::createBlock( Framework::Vec3 position, int dimensionId) const { return new BasicBlock(getId(), position, dimensionId); } Item* BasicBlockType::createItem() const { return Game::INSTANCE->zItemType(itemTypeId)->createItem(); } Framework::Text BasicBlockType::getItemTypeName() const { return itemTypeName; } ItemType* BasicBlockType::createItemType() const { return new BasicBlockItemType(getItemTypeName(), new ModelInfo(zModel()->getModelPath(), zModel()->getTexturePaths(), zModel()->isTransparent(), zModel()->getSize() / 2.f), transparent, passable, getHardness(), speedModifier, getItemTypeName(), 0, 50, getGroupNames()); } int BasicBlockType::getItemTypeId() const { return itemTypeId; } void BasicBlockType::setTransparent(bool transparent) { this->transparent = transparent; } bool BasicBlockType::isTransparent() const { return transparent; } void BasicBlockType::setPassable(bool passable) { this->passable = passable; } bool BasicBlockType::isPassable() const { return passable; } void BasicBlockType::setSpeedModifier(float speedModifier) { this->speedModifier = speedModifier; } float BasicBlockType::getSpeedModifier() const { return speedModifier; } void BasicBlockType::setInteractable(bool interactable) { this->interactable = interactable; } BasicBlockTypeFactory::BasicBlockTypeFactory() : SubTypeFactory() {} BasicBlockType* BasicBlockTypeFactory::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 BasicBlockType( zJson->zValue("itemType")->asString()->getString(), Game::INSTANCE->zTypeRegistry()->fromJson( zJson->zValue("model")), zJson->zValue("name")->asString()->getString(), (int)zJson->zValue("mapColor")->asString()->getString(), zJson->zValue("modelSubscription")->asBool()->getBool(), (float)zJson->zValue("hardness")->asNumber()->getNumber(), groupNames); } Framework::JSON::JSONObject* BasicBlockTypeFactory::toJson( BasicBlockType* 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( "mapColor", new Framework::JSON::JSONString(zObject->getMapColor())); result->addValue("modelSubscription", new Framework::JSON::JSONBool(zObject->doesNeedModelSubscription())); result->addValue( "hardness", new Framework::JSON::JSONNumber(zObject->getHardness())); 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* BasicBlockTypeFactory::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() ->withRequiredString("mapColor") ->finishString() ->withRequiredBool("modelSubscription") ->withDefault(false) ->finishBool() ->withRequiredNumber("hardness") ->withDefault(1.0) ->finishNumber() ->withRequiredArray("groupNames") ->withDefault(new Framework::JSON::JSONArray()) ->addAcceptedStringInArray() ->finishString() ->finishArray() ->finishObject(); } Framework::Text BasicBlockTypeFactory::getTypeToken() const { return "basicBlock"; } AdditionalItemSpawningBlock::AdditionalItemSpawningBlock( int typeId, Framework::Vec3 pos, int dimensionId) : BasicBlock(typeId, pos, dimensionId) {} void AdditionalItemSpawningBlock::addSpawn(SpawnConfig config) { spawns.add(config); } void AdditionalItemSpawningBlock::onDestroy() { for (const SpawnConfig& config : spawns) { if ((double)rand() / RAND_MAX < config.chance) { int amount = config.min + (int)((config.max - config.min) * ((double)rand() / RAND_MAX)); if (amount > 0) { ItemStack* spawnedItems = Game::INSTANCE->zItemType(config.typeId) ->createItemStack(amount); if (spawnedItems) { ItemEntity* itemEntity = (ItemEntity*)Game::INSTANCE ->zEntityType(EntityTypeEnum::ITEM) ->createEntity(location + Framework::Vec3( 0.5f, 0.5f, 0.5f), getDimensionId(), Game::INSTANCE->getNextEntityId()); itemEntity->unsaveAddItem(spawnedItems, NO_DIRECTION, 0); spawnedItems->release(); Game::INSTANCE->requestWorldUpdate( new AddEntityUpdate(itemEntity, getDimensionId())); } } } } BasicBlock::onDestroy(); } void AdditionalItemSpawningBlockType::createSuperBlock( Block* zBlock, Item* zItem) const { AdditionalItemSpawningBlock* block = dynamic_cast(zBlock); if (block) { for (const SpawnConfig& config : spawns) { block->addSpawn(config); } } BasicBlockType::createSuperBlock(zBlock, zItem); } AdditionalItemSpawningBlockType::AdditionalItemSpawningBlockType( Framework::Text itemTypeName, ModelInfo* model, Framework::Text name, int mapColor, bool modelSubscription, float hardness, Framework::Array spawns, Framework::RCArray groupNames) : BasicBlockType(itemTypeName, model, name, mapColor, modelSubscription, hardness, groupNames), spawns(spawns) {} bool AdditionalItemSpawningBlockType::initialize(Game* zGame) { for (auto iterator = spawns.begin(); iterator; iterator++) { int itemTypeId = Game::INSTANCE->getItemTypeId(iterator.val().itemTypeName); if (itemTypeId < 0) { return false; } iterator.set({iterator.val().min, iterator.val().max, iterator.val().chance, iterator.val().itemTypeName, itemTypeId}); } return BasicBlockType::initialize(zGame); } Block* AdditionalItemSpawningBlockType::createBlock( Framework::Vec3 position, int dimensionId) const { AdditionalItemSpawningBlock* block = new AdditionalItemSpawningBlock(getId(), position, dimensionId); return block; } const Framework::Array& AdditionalItemSpawningBlockType::getSpawns() const { return spawns; } AdditionalItemSpawningBlockTypeFactory::AdditionalItemSpawningBlockTypeFactory() : SubTypeFactory() {} AdditionalItemSpawningBlockType* AdditionalItemSpawningBlockTypeFactory::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())); } Framework::Array spawns; Framework::JSON::JSONArray* spawnsJson = zJson->zValue("spawns")->asArray(); for (int i = 0; i < spawnsJson->getLength(); i++) { Framework::JSON::JSONObject* spawnJson = spawnsJson->zValue(i)->asObject(); spawns.add(SpawnConfig{ (int)spawnJson->zValue("min")->asNumber()->getNumber(), (int)spawnJson->zValue("max")->asNumber()->getNumber(), (float)spawnJson->zValue("chance")->asNumber()->getNumber(), spawnJson->zValue("itemType")->asString()->getString(), 0, }); } return new AdditionalItemSpawningBlockType( zJson->zValue("itemType")->asString()->getString(), Game::INSTANCE->zTypeRegistry()->fromJson( zJson->zValue("model")), zJson->zValue("name")->asString()->getString(), (int)zJson->zValue("mapColor")->asString()->getString(), zJson->zValue("modelSubscription")->asBool()->getBool(), (float)zJson->zValue("hardness")->asNumber()->getNumber(), spawns, groupNames); } Framework::JSON::JSONObject* AdditionalItemSpawningBlockTypeFactory::toJson( AdditionalItemSpawningBlockType* 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( "mapColor", new Framework::JSON::JSONString(zObject->getMapColor())); result->addValue("modelSubscription", new Framework::JSON::JSONBool(zObject->doesNeedModelSubscription())); result->addValue( "hardness", new Framework::JSON::JSONNumber(zObject->getHardness())); Framework::JSON::JSONArray* spawns = new Framework::JSON::JSONArray(); for (const SpawnConfig& config : zObject->getSpawns()) { Framework::JSON::JSONObject* spawn = new Framework::JSON::JSONObject(); spawn->addValue( "itemType", new Framework::JSON::JSONString(config.itemTypeName)); spawn->addValue( "chance", new Framework::JSON::JSONNumber(config.chance)); spawn->addValue("min", new Framework::JSON::JSONNumber(config.min)); spawn->addValue("max", new Framework::JSON::JSONNumber(config.max)); spawns->addValue(spawn); } result->addValue("spawns", spawns); 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* AdditionalItemSpawningBlockTypeFactory::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() ->withRequiredString("mapColor") ->finishString() ->withRequiredBool("modelSubscription") ->withDefault(false) ->finishBool() ->withRequiredNumber("hardness") ->withDefault(1.0) ->finishNumber() ->withRequiredAttribute("spawns", JSON::Validator::JSONValidator::buildForArray() ->addAcceptedObjectInArray() ->withRequiredString("itemType") ->finishString() ->withRequiredNumber("chance") ->finishNumber() ->withRequiredNumber("min") ->finishNumber() ->withRequiredNumber("max") ->finishNumber() ->finishObject() ->finishArray()) ->withRequiredArray("groupNames") ->withDefault(new Framework::JSON::JSONArray()) ->addAcceptedStringInArray() ->finishString() ->finishArray() ->finishObject(); } Framework::Text AdditionalItemSpawningBlockTypeFactory::getTypeToken() const { return "additionalItemsBlockType"; }