|
@@ -0,0 +1,367 @@
|
|
|
|
+#include "FluidContainer.h"
|
|
|
|
+
|
|
|
|
+#include <TextFeld.h>
|
|
|
|
+
|
|
|
|
+#include "FluidBlock.h"
|
|
|
|
+#include "Game.h"
|
|
|
|
+
|
|
|
|
+FluidContainerItem::FluidContainerItem(int itemTypeId, const char* name)
|
|
|
|
+ : Item(itemTypeId, name),
|
|
|
|
+ fluidTypeId(0),
|
|
|
|
+ fluidAmount(0)
|
|
|
|
+{
|
|
|
|
+ placeable = 1;
|
|
|
|
+ usable = 1;
|
|
|
|
+ eatable = 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const BlockType* FluidContainerItem::zPlacedBlockType() const
|
|
|
|
+{
|
|
|
|
+ return fluidTypeId && fluidAmount >= 1000 ? StaticRegistry<BlockType>::INSTANCE.zElement(fluidTypeId) : 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FluidContainerItem::canBeStackedWith(const Item* zItem) const
|
|
|
|
+{
|
|
|
|
+ const FluidContainerItem* other
|
|
|
|
+ = dynamic_cast<const FluidContainerItem*>(zItem);
|
|
|
|
+ if (!other) return false;
|
|
|
|
+ return Item::canBeStackedWith(zItem) && other->fluidTypeId == fluidTypeId
|
|
|
|
+ && other->fluidAmount == fluidAmount;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FluidContainerItem::canBePlacedAt(
|
|
|
|
+ const int dimensionId, Framework::Vec3<int> worldPos) const
|
|
|
|
+{
|
|
|
|
+ if (fluidAmount >= 1000)
|
|
|
|
+ {
|
|
|
|
+ Dimension* dim = Game::INSTANCE->zDimension(dimensionId);
|
|
|
|
+ if (dim)
|
|
|
|
+ {
|
|
|
|
+ const Block* block = dim->zBlockOrDefault(worldPos);
|
|
|
|
+ if (block)
|
|
|
|
+ {
|
|
|
|
+ if (block->zBlockType()->getId() == BlockTypeEnum::AIR)
|
|
|
|
+ return true;
|
|
|
|
+ if (block->zBlockType()->getId() == fluidTypeId)
|
|
|
|
+ {
|
|
|
|
+ const FluidBlock* fluidBlock
|
|
|
|
+ = dynamic_cast<const FluidBlock*>(block);
|
|
|
|
+ return fluidBlock && fluidBlock->getDistanceToSource() > 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItem::onPlaced()
|
|
|
|
+{
|
|
|
|
+ setAmount(fluidAmount - 1000);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Framework::Text FluidContainerItem::getTooltipUIML() const
|
|
|
|
+{
|
|
|
|
+ Framework::Text uiml = "<tip><text width=\"auto\" height=\"auto\">";
|
|
|
|
+ uiml.append() << getName();
|
|
|
|
+ if (fluidTypeId != 0)
|
|
|
|
+ {
|
|
|
|
+ uiml.append() << "\nFluid: "
|
|
|
|
+ << StaticRegistry<BlockType>::INSTANCE
|
|
|
|
+ .zElement(fluidTypeId)
|
|
|
|
+ ->getName()
|
|
|
|
+ << "\nAmount: " << fluidAmount << " L";
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ uiml.append() << "\nEmpty";
|
|
|
|
+ }
|
|
|
|
+ uiml.append() << "</text></tip>";
|
|
|
|
+ return uiml;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FluidContainerItem::applyFoodEffects(Entity* zTarget)
|
|
|
|
+{
|
|
|
|
+ if (fluidTypeId)
|
|
|
|
+ {
|
|
|
|
+ const FluidBlockType* fluidType = dynamic_cast<const FluidBlockType*>(
|
|
|
|
+ StaticRegistry<BlockType>::INSTANCE.zElement(fluidTypeId));
|
|
|
|
+ if (fluidType && fluidType->getFoodEffect())
|
|
|
|
+ {
|
|
|
|
+ return fluidType->getFoodEffect()(this, zTarget);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FluidContainerItem::canApplyFoodEffectsFully(Entity* zTarget) const
|
|
|
|
+{
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int FluidContainerItem::getAmount() const
|
|
|
|
+{
|
|
|
|
+ return fluidAmount;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItem::setAmount(int amount)
|
|
|
|
+{
|
|
|
|
+ fluidAmount = amount;
|
|
|
|
+ if (!fluidAmount)
|
|
|
|
+ {
|
|
|
|
+ fluidTypeId = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int FluidContainerItem::getFluidTypeId() const
|
|
|
|
+{
|
|
|
|
+ return fluidTypeId;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItem::setFluidTypeId(int fluidTypeId)
|
|
|
|
+{
|
|
|
|
+ this->fluidTypeId = fluidTypeId;
|
|
|
|
+ if (!fluidTypeId)
|
|
|
|
+ {
|
|
|
|
+ fluidAmount = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+FluidContainerItemSkill::FluidContainerItemSkill(int itemTypeId)
|
|
|
|
+ : ItemSkill(itemTypeId),
|
|
|
|
+ level(1),
|
|
|
|
+ xp(0.f),
|
|
|
|
+ maxXP(10.f)
|
|
|
|
+{}
|
|
|
|
+
|
|
|
|
+bool FluidContainerItemSkill::use(
|
|
|
|
+ Entity* zActor, Item* zUsedItem, Block* zTarget)
|
|
|
|
+{
|
|
|
|
+ FluidContainerItem* usedItem = dynamic_cast<FluidContainerItem*>(zUsedItem);
|
|
|
|
+ if (usedItem)
|
|
|
|
+ {
|
|
|
|
+ if (zTarget->zBlockType()->isFluid() && zTarget->getHP() > 0)
|
|
|
|
+ {
|
|
|
|
+ FluidBlock* fluidBlock = dynamic_cast<FluidBlock*>(zTarget);
|
|
|
|
+ if (fluidBlock)
|
|
|
|
+ {
|
|
|
|
+ if (!usedItem->getFluidTypeId()
|
|
|
|
+ || usedItem->getFluidTypeId()
|
|
|
|
+ == fluidBlock->zBlockType()->getId())
|
|
|
|
+ {
|
|
|
|
+ const FluidContainerItemType* usedItemType
|
|
|
|
+ = dynamic_cast<const FluidContainerItemType*>(
|
|
|
|
+ usedItem->zItemType());
|
|
|
|
+ if (usedItemType)
|
|
|
|
+ {
|
|
|
|
+ if (usedItem->getAmount() + 1000
|
|
|
|
+ <= usedItemType->getMaxFluidAmount())
|
|
|
|
+ {
|
|
|
|
+ usedItem->setFluidTypeId(
|
|
|
|
+ fluidBlock->zBlockType()->getId());
|
|
|
|
+ usedItem->setAmount(usedItem->getAmount() + 1000);
|
|
|
|
+ zTarget->setHP(0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FluidContainerItemSkill::use(
|
|
|
|
+ Entity* zActor, Item* zUsedItem, Entity* zTarget)
|
|
|
|
+{
|
|
|
|
+ // TODO: get milk from cows and something else from other mobs
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+FluidContainerItemSkillLevelUpRule::FluidContainerItemSkillLevelUpRule()
|
|
|
|
+ : ItemSkillLevelUpRule()
|
|
|
|
+{}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemSkillLevelUpRule::applyOn(ItemSkill* zSkill)
|
|
|
|
+{
|
|
|
|
+ FluidContainerItemSkill* skill
|
|
|
|
+ = dynamic_cast<FluidContainerItemSkill*>(zSkill);
|
|
|
|
+ if (skill->xp >= skill->maxXP)
|
|
|
|
+ {
|
|
|
|
+ skill->level++;
|
|
|
|
+ skill->xp = 0;
|
|
|
|
+ skill->maxXP = skill->maxXP * 2;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemType::loadSuperItem(
|
|
|
|
+ Item* zItem, Framework::StreamReader* zReader) const
|
|
|
|
+{
|
|
|
|
+ ItemType::loadSuperItem(zItem, zReader);
|
|
|
|
+ FluidContainerItem* item = dynamic_cast<FluidContainerItem*>(zItem);
|
|
|
|
+ if (item)
|
|
|
|
+ {
|
|
|
|
+ zReader->lese((char*)&item->fluidTypeId, 4);
|
|
|
|
+ zReader->lese((char*)&item->fluidAmount, 4);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::loadSuperItem: "
|
|
|
|
+ "zItem is not a FluidContainerItem\n";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemType::saveSuperItem(
|
|
|
|
+ const Item* zItem, Framework::StreamWriter* zWriter) const
|
|
|
|
+{
|
|
|
|
+ ItemType::saveSuperItem(zItem, zWriter);
|
|
|
|
+ const FluidContainerItem* item
|
|
|
|
+ = dynamic_cast<const FluidContainerItem*>(zItem);
|
|
|
|
+ if (item)
|
|
|
|
+ {
|
|
|
|
+ zWriter->schreibe((char*)&item->fluidTypeId, 4);
|
|
|
|
+ zWriter->schreibe((char*)&item->fluidAmount, 4);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::saveSuperItem: "
|
|
|
|
+ "zItem is not a FluidContainerItem\n";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemType::loadSuperItemSkill(
|
|
|
|
+ ItemSkill* zSkill, Framework::StreamReader* zReader) const
|
|
|
|
+{
|
|
|
|
+ ItemType::loadSuperItemSkill(zSkill, zReader);
|
|
|
|
+ FluidContainerItemSkill* skill
|
|
|
|
+ = dynamic_cast<FluidContainerItemSkill*>(zSkill);
|
|
|
|
+ if (skill)
|
|
|
|
+ {
|
|
|
|
+ zReader->lese((char*)&skill->level, 4);
|
|
|
|
+ zReader->lese((char*)&skill->xp, 4);
|
|
|
|
+ zReader->lese((char*)&skill->maxXP, 4);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::loadSuperItemSkill: "
|
|
|
|
+ "zSkill is not a FluidContainerItemSkill\n";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemType::saveSuperItemSkill(
|
|
|
|
+ const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
|
|
|
|
+{
|
|
|
|
+ ItemType::saveSuperItemSkill(zSkill, zWriter);
|
|
|
|
+ const FluidContainerItemSkill* skill
|
|
|
|
+ = dynamic_cast<const FluidContainerItemSkill*>(zSkill);
|
|
|
|
+ if (skill)
|
|
|
|
+ {
|
|
|
|
+ zWriter->schreibe((char*)&skill->level, 4);
|
|
|
|
+ zWriter->schreibe((char*)&skill->xp, 4);
|
|
|
|
+ zWriter->schreibe((char*)&skill->maxXP, 4);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::saveSuperItemSkill: "
|
|
|
|
+ "zSkill is not a FluidContainerItemSkill\n";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+FluidContainerItemType::FluidContainerItemType(
|
|
|
|
+ int typeId, const char* name, ModelInfo model)
|
|
|
|
+ : ItemType(
|
|
|
|
+ typeId, name, new FluidContainerItemSkillLevelUpRule(), 0, model),
|
|
|
|
+ maxFluidAmount(1000)
|
|
|
|
+{}
|
|
|
|
+
|
|
|
|
+Item* FluidContainerItemType::createItem() const
|
|
|
|
+{
|
|
|
|
+ Item* result = new FluidContainerItem(getId(), getName());
|
|
|
|
+ return result;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+ItemSkill* FluidContainerItemType::createDefaultItemSkill() const
|
|
|
|
+{
|
|
|
|
+ return new FluidContainerItemSkill(getId());
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemType::setItemAttribute(
|
|
|
|
+ Item* zItem, Framework::Text name, Framework::JSON::JSONValue* zValue) const
|
|
|
|
+{
|
|
|
|
+ FluidContainerItem* item = dynamic_cast<FluidContainerItem*>(zItem);
|
|
|
|
+ if (!item)
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
|
|
|
|
+ "zItem is not a FluidContainerItem\n";
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (name.istGleich("fluidType"))
|
|
|
|
+ {
|
|
|
|
+ if (zValue->getType() == Framework::JSON::JSONType::STRING)
|
|
|
|
+ {
|
|
|
|
+ int id = ItemType::getTypeId(zValue->asString()->getString());
|
|
|
|
+ if (id)
|
|
|
|
+ {
|
|
|
|
+ item->fluidTypeId = id;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
|
|
|
|
+ "'fluidType' is not a valid type name\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
|
|
|
|
+ "'fluidType' is not a string or string\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (name.istGleich("fluidAmount"))
|
|
|
|
+ {
|
|
|
|
+ if (zValue->getType() == Framework::JSON::JSONType::NUMBER)
|
|
|
|
+ {
|
|
|
|
+ item->fluidAmount = (int)zValue->asNumber()->getNumber();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
|
|
|
|
+ "'fluidAmount' is not a number\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ItemType::setItemAttribute(zItem, name, zValue);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FluidContainerItemType::addItemAttributes(
|
|
|
|
+ Item* zItem, Framework::JSON::JSONObject* zItemObjet) const
|
|
|
|
+{
|
|
|
|
+ FluidContainerItem* item = dynamic_cast<FluidContainerItem*>(zItem);
|
|
|
|
+ if (!item)
|
|
|
|
+ {
|
|
|
|
+ std::cout << "ERROR: FluidContainerItemType::addItemAttributes: "
|
|
|
|
+ "zItem is not a FluidContainerItem\n";
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ ItemType::addItemAttributes(zItem, zItemObjet);
|
|
|
|
+ if (item->fluidTypeId)
|
|
|
|
+ {
|
|
|
|
+ zItemObjet->addValue("fluidType",
|
|
|
|
+ new Framework::JSON::JSONString(
|
|
|
|
+ StaticRegistry<ItemType>::INSTANCE.zElement(item->fluidTypeId)
|
|
|
|
+ ->getName()));
|
|
|
|
+ zItemObjet->addValue(
|
|
|
|
+ "fluidAmount", new Framework::JSON::JSONNumber(item->fluidAmount));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int FluidContainerItemType::getMaxFluidAmount() const
|
|
|
|
+{
|
|
|
|
+ return maxFluidAmount;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+FluidContainerItemType* FluidContainerItemType::setMaxFluidAmount(
|
|
|
|
+ int maxFluidAmount)
|
|
|
|
+{
|
|
|
|
+ this->maxFluidAmount = maxFluidAmount;
|
|
|
|
+ return this;
|
|
|
|
+}
|