#include "stdafx.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.tile.h" #include "net.minecraft.world.phys.h" #include "net.minecraft.world.item.h" #include "net.minecraft.world.effect.h" #include "SharedConstants.h" #include "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, shared_ptr mob, int potionValue) : Throwable(level,mob) { _init(); potionItem = shared_ptr( new ItemInstance(Item::potion, 1, potionValue)); } ThrownPotion::ThrownPotion(Level *level, shared_ptr mob, 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 = shared_ptr( new ItemInstance(Item::potion, 1, potionValue)); } ThrownPotion::ThrownPotion(Level *level, double x, double y, double z, 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 = shared_ptr( new ItemInstance(Item::potion, 1, 0) ); potionItem->setAuxValue(potionValue); } int ThrownPotion::getPotionValue() { if (potionItem == NULL) potionItem = shared_ptr( new ItemInstance(Item::potion, 1, 0) ); return potionItem->getAuxValue(); } void ThrownPotion::onHit(HitResult *res) { if (!level->isClientSide) { vector *mobEffects = Item::potion->getMobEffects(potionItem); if (mobEffects != NULL && !mobEffects->empty()) { AABB *aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); 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; shared_ptr e = 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())); }