#include "Animal.h" #include "AddEntityUpdate.h" #include "Game.h" #include "ItemEntity.h" #include "ItemStack.h" #include "TypeRegistry.h" Animal::Animal( int typeId, Framework::Vec3 location, int dimensionId, int entityId) : Entity(typeId, location, dimensionId, entityId) {} Animal::~Animal() { if (ai) { ai->release(); } } void Animal::onDeath() { if (!removed) { 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())); } } } } } Entity::onDeath(); } void Animal::setSpawns(const Framework::Array& spawnConfig) { spawns = spawnConfig; } void Animal::setAI(AnimalAI* ai) { if (this->ai) { this->ai->release(); } this->ai = ai; } bool Animal::interact(Item* zItem, Entity* zActor) { return false; } void Animal::takeDamage(Entity* zSource, float damage) { if (damage > 0) { ai->onDamage(zSource, damage); } Entity::takeDamage(zSource, damage); } void Animal::tick(const Dimension* zDimension) { Entity::tick(zDimension); } AnimalEntityType::AnimalEntityType(Framework::Text name, ModelInfo* model) : EntityType(name, model) {} AnimalEntityType::~AnimalEntityType() { if (ai) { ai->release(); } } void AnimalEntityType::loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader) const { EntityType::loadSuperEntity(zEntity, zReader); } void AnimalEntityType::saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter) const { EntityType::saveSuperEntity(zEntity, zWriter); } Entity* AnimalEntityType::createEntity( Framework::Vec3 position, int dimensionId, int entityId) const { Animal* result = new Animal(getId(), position, dimensionId, entityId); result->setAI(Game::INSTANCE->zTypeRegistry()->fromJson(ai)); result->setSpawns(spawns); return result; } AnimalEntityTypeFactory::AnimalEntityTypeFactory() : SubTypeFactory() {} AnimalEntityType* AnimalEntityTypeFactory::createValue( Framework::JSON::JSONObject* zJson) const { Framework::Text name = zJson->zValue("typeName")->asString()->getString(); AnimalEntityType* result = new AnimalEntityType(name, Game::INSTANCE->zTypeRegistry()->fromJson( zJson->zValue("model"))); return result; } void AnimalEntityTypeFactory::fromJson( AnimalEntityType* zResult, Framework::JSON::JSONObject* zJson) const { Framework::JSON::JSONArray* spawnsJson = zJson->zValue("spawns")->asArray(); for (int i = 0; i < spawnsJson->getLength(); i++) { Framework::JSON::JSONObject* spawnJson = spawnsJson->zValue(i)->asObject(); zResult->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, }); } zResult->ai = zJson->getValue("ai")->asObject(); } void AnimalEntityTypeFactory::toJson( AnimalEntityType* zObject, Framework::JSON::JSONObject* zResult) const { Framework::JSON::JSONArray* spawnsJson = new Framework::JSON::JSONArray(); for (int i = 0; i < zObject->spawns.getEintragAnzahl(); i++) { SpawnConfig spawn = zObject->spawns.get(i); Framework::JSON::JSONObject* spawnJson = new Framework::JSON::JSONObject(); spawnJson->addValue("min", new Framework::JSON::JSONNumber(spawn.min)); spawnJson->addValue("max", new Framework::JSON::JSONNumber(spawn.max)); spawnJson->addValue( "chance", new Framework::JSON::JSONNumber(spawn.chance)); spawnJson->addValue( "itemType", new Framework::JSON::JSONString(spawn.itemTypeName)); spawnsJson->addValue(spawnJson); } zResult->addValue("spawns", spawnsJson); zResult->addValue( "typeName", new Framework::JSON::JSONString(zObject->getName())); zResult->addValue( "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel())); zResult->addValue("ai", zObject->ai->clone()); } Framework::Text AnimalEntityTypeFactory::getTypeToken() const { return "animal"; } JSONObjectValidationBuilder* AnimalEntityTypeFactory::addToValidator( JSONObjectValidationBuilder* builder) const { return builder ->withRequiredAttribute("spawns", Framework::JSON::Validator::JSONValidator::buildForArray() ->addAcceptedObjectInArray() ->withRequiredString("itemType") ->finishString() ->withRequiredNumber("chance") ->finishNumber() ->withRequiredNumber("min") ->finishNumber() ->withRequiredNumber("max") ->finishNumber() ->finishObject() ->finishArray()) ->withRequiredString("typeName") ->finishString() ->withRequiredAttribute("model", Game::INSTANCE->zTypeRegistry()->getValidator()); }