#include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.effect.h" #include "../../Util/SharedConstants.h" #include "../../Util/JavaMath.h" #include "ThrownPotion.h" const double ThrownPotion::SPLASH_RANGE = 4.0; const double ThrownPotion::SPLASH_RANGE_SQ = ThrownPotion::SPLASH_RANGE * ThrownPotion::SPLASH_RANGE; void ThrownPotion::_init() { // 4J Stu - This function call had to be moved here from the Entity ctor to // ensure that the derived version of the function is called this->defineSynchedData(); potionItem = nullptr; } ThrownPotion::ThrownPotion(Level* level) : Throwable(level) { _init(); } ThrownPotion::ThrownPotion(Level* level, std::shared_ptr mob, int potionValue) : Throwable(level, mob) { _init(); potionItem = std::shared_ptr( new ItemInstance(Item::potion, 1, potionValue)); } ThrownPotion::ThrownPotion(Level* level, std::shared_ptr mob, std::shared_ptr potion) : Throwable(level, mob) { _init(); potionItem = potion; } ThrownPotion::ThrownPotion(Level* level, double x, double y, double z, int potionValue) : Throwable(level, x, y, z) { _init(); potionItem = std::shared_ptr( new ItemInstance(Item::potion, 1, potionValue)); } ThrownPotion::ThrownPotion(Level* level, double x, double y, double z, std::shared_ptr potion) : Throwable(level, x, y, z) { _init(); potionItem = potion; } float ThrownPotion::getGravity() { return 0.05f; } float ThrownPotion::getThrowPower() { return 0.5f; } float ThrownPotion::getThrowUpAngleOffset() { return -20; } void ThrownPotion::setPotionValue(int potionValue) { if (potionItem == NULL) potionItem = std::shared_ptr(new ItemInstance(Item::potion, 1, 0)); potionItem->setAuxValue(potionValue); } int ThrownPotion::getPotionValue() { if (potionItem == NULL) potionItem = std::shared_ptr(new ItemInstance(Item::potion, 1, 0)); return potionItem->getAuxValue(); } void ThrownPotion::onHit(HitResult* res) { if (!level->isClientSide) { std::vector* mobEffects = Item::potion->getMobEffects(potionItem); if (mobEffects != NULL && !mobEffects->empty()) { AABB* aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); std::vector >* entitiesOfClass = level->getEntitiesOfClass(typeid(LivingEntity), aoe); if (entitiesOfClass != NULL && !entitiesOfClass->empty()) { // for (Entity e : entitiesOfClass) for (AUTO_VAR(it, entitiesOfClass->begin()); it != entitiesOfClass->end(); ++it) { // shared_ptr e = *it; std::shared_ptr e = std::dynamic_pointer_cast(*it); double dist = distanceToSqr(e); if (dist < SPLASH_RANGE_SQ) { double scale = 1.0 - (sqrt(dist) / SPLASH_RANGE); if (e == res->entity) { scale = 1; } // for (MobEffectInstance effect : mobEffects) for (AUTO_VAR(itMEI, mobEffects->begin()); itMEI != mobEffects->end(); ++itMEI) { MobEffectInstance* effect = *itMEI; int id = effect->getId(); if (MobEffect::effects[id]->isInstantenous()) { MobEffect::effects[id]->applyInstantenousEffect( getOwner(), e, effect->getAmplifier(), scale); } else { int duration = (int)(scale * (double)effect->getDuration() + .5); if (duration > SharedConstants::TICKS_PER_SECOND) { e->addEffect(new MobEffectInstance( id, duration, effect->getAmplifier())); } } } } } } delete entitiesOfClass; } level->levelEvent(LevelEvent::PARTICLES_POTION_SPLASH, (int)Math::round(x), (int)Math::round(y), (int)Math::round(z), getPotionValue()); remove(); } } void ThrownPotion::readAdditionalSaveData(CompoundTag* tag) { Throwable::readAdditionalSaveData(tag); if (tag->contains(L"Potion")) { potionItem = ItemInstance::fromTag(tag->getCompound(L"Potion")); } else { setPotionValue(tag->getInt(L"potionValue")); } if (potionItem == NULL) remove(); } void ThrownPotion::addAdditonalSaveData(CompoundTag* tag) { Throwable::addAdditonalSaveData(tag); if (potionItem != NULL) tag->putCompound(L"Potion", potionItem->save(new CompoundTag())); }