Class AbstractLobbingProjectile

java.lang.Object
net.minecraftforge.common.capabilities.CapabilityProvider<net.minecraft.world.entity.Entity>
net.minecraft.world.entity.Entity
net.minecraft.world.entity.projectile.Projectile
nokunami.floral_warfare.common.entity.projectile.AbstractPlantProjectile
nokunami.floral_warfare.common.entity.projectile.AbstractLobbingProjectile
All Implemented Interfaces:
net.minecraft.commands.CommandSource, net.minecraft.world.entity.TraceableEntity, net.minecraft.world.level.entity.EntityAccess, net.minecraft.world.Nameable, net.minecraftforge.common.capabilities.ICapabilityProvider, net.minecraftforge.common.capabilities.ICapabilityProviderImpl<net.minecraft.world.entity.Entity>, net.minecraftforge.common.capabilities.ICapabilitySerializable<net.minecraft.nbt.CompoundTag>, net.minecraftforge.common.extensions.IForgeEntity, net.minecraftforge.common.util.INBTSerializable<net.minecraft.nbt.CompoundTag>
Direct Known Subclasses:
CabbageProjectile, KernelProjectile, MelonProjectile, ScatterPumpkinSeedProjectile, SolarPeaProjectile

public class AbstractLobbingProjectile extends AbstractPlantProjectile
  • Nested Class Summary

    Nested classes/interfaces inherited from class net.minecraft.world.entity.Entity

    net.minecraft.world.entity.Entity.MoveFunction, net.minecraft.world.entity.Entity.MovementEmission, net.minecraft.world.entity.Entity.RemovalReason

    Nested classes/interfaces inherited from class net.minecraftforge.common.capabilities.CapabilityProvider

    net.minecraftforge.common.capabilities.CapabilityProvider.AsField<B extends net.minecraftforge.common.capabilities.ICapabilityProviderImpl<B>>
  • Field Summary

    Fields inherited from class nokunami.floral_warfare.common.entity.projectile.AbstractPlantProjectile

    effects, ignoredEntities, inGround, inGroundTime, lastState, piercedAndKilled, piercingIgnore, potion

    Fields inherited from class net.minecraft.world.entity.Entity

    BASE_TICKS_REQUIRED_TO_FREEZE, blocksBuilding, BOARDING_COOLDOWN, boardingCooldown, BREATHING_DISTANCE_BELOW_EYES, DATA_POSE, DATA_SHARED_FLAGS_ID, DEFAULT_BB_HEIGHT, DEFAULT_BB_WIDTH, DELTA_AFFECTED_BY_BLOCKS_BELOW_0_2, DELTA_AFFECTED_BY_BLOCKS_BELOW_0_5, DELTA_AFFECTED_BY_BLOCKS_BELOW_1_0, ENTITY_COUNTER, entityData, fallDistance, firstTick, FLAG_FALL_FLYING, FLAG_GLOWING, FLAG_ONFIRE, fluidHeight, flyDist, forgeFluidTypeHeight, FREEZE_HURT_FREQUENCY, hasImpulse, horizontalCollision, hurtMarked, ID_TAG, invulnerableTime, isInPowderSnow, isInsidePortal, mainSupportingBlockPos, MAX_ENTITY_TAG_COUNT, minorHorizontalCollision, moveDist, noCulling, noPhysics, PASSENGERS_TAG, portalEntrancePos, portalTime, random, stringUUID, stuckSpeedMultiplier, tickCount, TOTAL_AIR_SUPPLY, uuid, UUID_TAG, verticalCollision, verticalCollisionBelow, walkDist, walkDistO, wasEyeInWater, wasInPowderSnow, wasOnFire, wasTouchingWater, xo, xOld, xRotO, yo, yOld, yRotO, zo, zOld

    Fields inherited from interface net.minecraft.commands.CommandSource

    NULL
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    AbstractLobbingProjectile(net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.projectile.Projectile> type, double pX, double pY, double pZ, net.minecraft.world.level.Level level)
     
     
    AbstractLobbingProjectile(net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.projectile.Projectile> type, net.minecraft.world.entity.LivingEntity shooter, net.minecraft.world.level.Level level)
     
     
    AbstractLobbingProjectile(net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.projectile.Projectile> type, net.minecraft.world.level.Level level)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    addAdditionalSaveData(@NotNull net.minecraft.nbt.CompoundTag tag)
     
    net.minecraft.world.phys.Vec3
    calculateLobVelocity(net.minecraft.world.phys.Vec3 origin, net.minecraft.world.phys.Vec3 target, int maxTicks, double desiredPeakY)
    Solves a complete lob arc from origin to target whose apex reaches desiredPeakY.
    protected double
    computeDesiredPeakY(double originY, double hDist, double headroom)
    Computes the desired arc peak height (in world Y) for a given horizontal distance and available headroom.
    protected net.minecraft.world.phys.EntityHitResult
    findHitEntity(net.minecraft.world.phys.Vec3 startVec, net.minecraft.world.phys.Vec3 endVec)
     
    double
     
    void
    getDirectShotRange(double range)
     
    protected float
    getEyeHeight(@NotNull net.minecraft.world.entity.Pose pPose, @NotNull net.minecraft.world.entity.EntityDimensions pSize)
     
    double
     
    double
     
    double
     
    protected float
     
    double
     
    boolean
     
    void
    lobProjectile(net.minecraft.world.entity.Entity shooter, float velocity, double damage, double distToShooter, net.minecraft.world.entity.LivingEntity enemy)
    Launches this projectile at the shooter's current mob target.
    void
    lobProjectile(net.minecraft.world.entity.Mob shooter, float velocity, double damage, double distToShooter)
     
    protected double
    measureHeadroom(net.minecraft.world.level.Level level, net.minecraft.world.phys.Vec3 from, net.minecraft.world.phys.Vec3 to)
    Casts HEADROOM_SAMPLES short rays straight up at evenly-spaced points along the shooter-to-target line and returns the minimum clearance found.
    protected void
    onHitBlock(@NotNull net.minecraft.world.phys.BlockHitResult result)
     
    protected void
    onHitEntity(@NotNull net.minecraft.world.phys.EntityHitResult result)
     
    protected net.minecraft.world.phys.Vec3
    predictTargetPosition(net.minecraft.world.phys.Vec3 spawnPos, net.minecraft.world.entity.LivingEntity enemy, double headroom, int maxTicks)
    Predicts where enemy will be when the arc arrives, using a three-pass XZ-only iterative lead.
    protected void
    readAdditionalSaveData(@NotNull net.minecraft.nbt.CompoundTag tag)
     
    void
    setFriction(double friction)
     
    void
    setSplashDamage(double damage)
     
    void
    setSplashRadius(double radius)
     
    void
    setup(int i)
     
    void
    setWeight(double weight)
     
    void
    shouldSplash(boolean splash)
     
    void
     

    Methods inherited from class net.minecraft.world.entity.projectile.Projectile

    getAddEntityPacket, getEffectSource, getOwner, lerpMotion, lerpRotation, mayInteract, onHit, ownedBy, recreateFromPacket, setOwner, shoot, shootFromRotation, updateRotation

    Methods inherited from class net.minecraft.world.entity.Entity

    absMoveTo, absMoveTo, acceptsFailure, acceptsSuccess, addDeltaMovement, addPassenger, addTag, animateHurt, awardKillScore, baseTick, blockPosition, broadcastToPlayer, calculateUpVector, calculateViewVector, canAddPassenger, canBeCollidedWith, canBeHitByProjectile, canChangeDimensions, canCollideWith, canEnterPose, canFreeze, canRide, canSpawnSprintParticle, canSprint, canTrample, canUpdate, canUpdate, captureDrops, captureDrops, causeFallDamage, changeDimension, changeDimension, checkBelowWorld, checkDespawn, checkFallDamage, checkInsideBlocks, checkSlowFallDistance, checkSupportingBlock, chunkPosition, clearFire, closerThan, closerThan, collideBoundingBox, copyPosition, couldAcceptPassenger, createCommandSourceStack, createHoverEvent, damageSources, dampensVibrations, discard, dismountsUnderwater, dismountTo, displayFireAnimation, distanceTo, distanceToSqr, distanceToSqr, distanceToSqr, doEnchantDamageEffects, doWaterSplashEffect, ejectPassengers, equals, extinguishFire, fillCrashReportCategory, findDimensionEntryPoint, fireImmune, fixupDimensions, gameEvent, gameEvent, getAirSupply, getAllSlots, getArmorSlots, getBbHeight, getBbWidth, getBlockExplosionResistance, getBlockJumpFactor, getBlockPosBelowThatAffectsMyMovement, getBlockSpeedFactor, getBlockStateOn, getBlockStateOnLegacy, getBlockX, getBlockY, getBlockZ, getBoundingBox, getBoundingBoxForCulling, getBoundingBoxForPose, getCollisionHorizontalEscapeVector, getCommandSenderWorld, getControlledVehicle, getControllingPassenger, getCustomName, getDeltaMovement, getDimensionChangingDelay, getDimensions, getDimensionsForge, getDirection, getDismountLocationForPassenger, getDisplayName, getEncodeId, getEntityData, getExitPortal, getEyeHeight, getEyeHeight, getEyeHeightAccess, getEyeInFluidType, getEyePosition, getEyePosition, getEyeY, getFeetBlockState, getFireImmuneTicks, getFirstPassenger, getFluidHeight, getFluidJumpThreshold, getFluidTypeHeight, getForward, getHandHoldingItemAngle, getHandSlots, getId, getIndirectPassengers, getLeashOffset, getLeashOffset, getLightLevelDependentMagicValue, getLightProbePosition, getLookAngle, getMaxAirSupply, getMaxFallDistance, getMaxHeightFluidType, getMotionDirection, getMovementEmission, getMyRidingOffset, getName, getNameTagOffsetY, getOnPos, getOnPos, getOnPosLegacy, getPassengers, getPassengersAndSelf, getPassengersRidingOffset, getPercentFrozen, getPermissionLevel, getPersistentData, getPickRadius, getPickResult, getPistonPushReaction, getPortalCooldown, getPortalWaitTime, getPose, getPosition, getPositionCodec, getPrimaryStepSoundBlockPos, getRandomX, getRandomY, getRandomZ, getRelativePortalPosition, getRemainingFireTicks, getRemovalReason, getRootVehicle, getRopeHoldPosition, getRotationVector, getScoreboardName, getSelfAndPassengers, getServer, getSharedFlag, getSlot, getSoundSource, getStringUUID, getSwimHighSpeedSplashSound, getSwimSound, getSwimSplashSound, getTags, getTeam, getTeamColor, getTicksFrozen, getTicksRequiredToFreeze, getType, getTypeName, getUpVector, getUUID, getVehicle, getViewScale, getViewVector, getViewXRot, getViewYRot, getVisualRotationYInDegrees, getX, getX, getXRot, getY, getY, getYHeadRot, getYRot, getZ, getZ, handleDamageEvent, handleInsidePortal, handleNetherPortal, hasControllingPassenger, hasCustomName, hasExactlyOnePlayerPassenger, hasGlowingTag, hashCode, hasIndirectPassenger, hasPassenger, hasPassenger, hasPermissions, hasPose, hurt, ignoreExplosion, interact, interactAt, is, isAddedToWorld, isAlive, isAlliedTo, isAlliedTo, isAlwaysTicking, isColliding, isControlledByLocalInstance, isCrouching, isCurrentlyGlowing, isCustomNameVisible, isDescending, isDiscrete, isEffectiveAi, isEyeInFluid, isFlapping, isFree, isFreezing, isFullyFrozen, isHorizontalCollisionMinor, isIgnoringBlockTriggers, isInFluidType, isInFluidType, isInLava, isInvisible, isInvisibleTo, isInvulnerable, isInvulnerableTo, isInWall, isInWater, isInWaterOrBubble, isInWaterOrRain, isInWaterRainOrBubble, isNoGravity, isOnFire, isOnPortalCooldown, isOnRails, isPassenger, isPassengerOfSameVehicle, isPickable, isPushable, isPushedByFluid, isRemoved, isShiftKeyDown, isSilent, isSpectator, isSprinting, isSteppingCarefully, isSupportedBy, isSuppressingBounce, isSwimming, isUnderWater, isVehicle, isVisuallyCrawling, isVisuallySwimming, kill, killedEntity, lavaHurt, lerpHeadTo, lerpTo, level, limitPistonMovement, load, lookAt, makeBoundingBox, makeStuckInBlock, markHurt, maxUpStep, maybeBackOffFromEdge, mirror, moveRelative, moveTo, moveTo, moveTo, moveTo, moveTowardsClosestSpace, newDoubleList, newFloatList, nextStep, onAboveBubbleCol, onAddedToWorld, onBelowWorld, onClientRemoval, onFlap, onGround, onInsideBlock, onInsideBubbleColumn, onlyOpCanSetNbt, onPassengerTurned, onRemovedFromWorld, onSyncedDataUpdated, onSyncedDataUpdated, pick, playCombinationStepSounds, playEntityOnFireExtinguishedSound, playerTouch, playMuffledStepSound, playSound, playSound, playStepSound, playSwimSound, position, positionRider, positionRider, processFlappingMovement, processPortalCooldown, push, push, reapplyPosition, refreshDimensions, remove, removeAfterChangingDimensions, removePassenger, removeTag, removeVehicle, repositionEntityAfterLoad, resetFallDistance, restoreFrom, revive, rideTick, rotate, save, saveAsPassenger, saveWithoutId, sendSystemMessage, setAirSupply, setBoundingBox, setCustomName, setCustomNameVisible, setDeltaMovement, setDeltaMovement, setFluidTypeHeight, setGlowingTag, setId, setInvisible, setInvulnerable, setIsInPowderSnow, setItemSlot, setLevel, setLevelCallback, setMaxUpStep, setNoGravity, setOldPosAndRot, setOnGround, setOnGroundWithKnownMovement, setPortalCooldown, setPortalCooldown, setPos, setPos, setPose, setPosRaw, setRemainingFireTicks, setRemoved, setRot, setSecondsOnFire, setSharedFlag, setSharedFlagOnFire, setShiftKeyDown, setSilent, setSprinting, setSwimming, setTicksFrozen, setUUID, setViewScale, setXRot, setYBodyRot, setYHeadRot, setYRot, shouldBeSaved, shouldBlockExplode, shouldInformAdmins, shouldRender, shouldShowName, showVehicleHealth, skipAttackInteraction, spawnAtLocation, spawnAtLocation, spawnAtLocation, spawnAtLocation, spawnSprintParticle, startRiding, startRiding, startSeenByPlayer, stopRiding, stopSeenByPlayer, syncPacketPositionCodec, teleportRelative, teleportTo, teleportTo, teleportToWithTicket, thunderHit, toString, touchingUnloadedChunk, trackingPosition, tryCheckInsideBlocks, turn, unRide, unsetRemoved, updateDynamicGameEventListener, updateFluidHeightAndDoFluidPushing, updateFluidHeightAndDoFluidPushing, updateFluidHeightAndDoFluidPushing, updateInWaterStateAndDoFluidPushing, updateSwimming, waterSwimSound

    Methods inherited from class net.minecraftforge.common.capabilities.CapabilityProvider

    areCapsCompatible, areCapsCompatible, deserializeCaps, gatherCapabilities, gatherCapabilities, gatherCapabilities, getCapabilities, getCapability, invalidateCaps, reviveCaps, serializeCaps

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait

    Methods inherited from interface net.minecraft.commands.CommandSource

    alwaysAccepts

    Methods inherited from interface net.minecraftforge.common.capabilities.ICapabilityProvider

    getCapability, getCapability

    Methods inherited from interface net.minecraftforge.common.extensions.IForgeEntity

    canBeRiddenUnderFluidType, canFluidExtinguish, canHydrateInFluidType, canRiderInteract, canStartSwimming, canSwimInFluidType, deserializeNBT, getClassification, getEyeHeightForge, getFluidFallDistanceModifier, getFluidMotionScale, getParts, getPickedResult, getSoundFromFluidType, getStepHeight, hasCustomOutlineRendering, isEyeInFluidType, isInFluidType, isInFluidType, isInFluidType, isMultipartEntity, isPushedByFluid, serializeNBT, shouldRiderSit, shouldUpdateFluidWhileBoating
  • Constructor Details

    • AbstractLobbingProjectile

      public AbstractLobbingProjectile(net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.projectile.Projectile> type, net.minecraft.world.level.Level level)
    • AbstractLobbingProjectile

      protected AbstractLobbingProjectile(net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.projectile.Projectile> type, double pX, double pY, double pZ, net.minecraft.world.level.Level level)
    • AbstractLobbingProjectile

      public AbstractLobbingProjectile(net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.projectile.Projectile> type, net.minecraft.world.entity.LivingEntity shooter, net.minecraft.world.level.Level level)
  • Method Details

    • addAdditionalSaveData

      protected void addAdditionalSaveData(@NotNull @NotNull net.minecraft.nbt.CompoundTag tag)
      Overrides:
      addAdditionalSaveData in class AbstractPlantProjectile
    • readAdditionalSaveData

      protected void readAdditionalSaveData(@NotNull @NotNull net.minecraft.nbt.CompoundTag tag)
      Overrides:
      readAdditionalSaveData in class AbstractPlantProjectile
    • getEyeHeight

      protected float getEyeHeight(@NotNull @NotNull net.minecraft.world.entity.Pose pPose, @NotNull @NotNull net.minecraft.world.entity.EntityDimensions pSize)
      Overrides:
      getEyeHeight in class net.minecraft.world.entity.Entity
    • isSplash

      public boolean isSplash()
    • shouldSplash

      public void shouldSplash(boolean splash)
    • getSplashDamage

      public double getSplashDamage()
    • setSplashDamage

      public void setSplashDamage(double damage)
    • getSplashRadius

      public double getSplashRadius()
    • setSplashRadius

      public void setSplashRadius(double radius)
    • getFriction

      public double getFriction()
    • setFriction

      public void setFriction(double friction)
    • getWeight

      public double getWeight()
    • setWeight

      public void setWeight(double weight)
    • getDirectShotRange

      public double getDirectShotRange()
    • getDirectShotRange

      public void getDirectShotRange(double range)
    • measureHeadroom

      protected double measureHeadroom(net.minecraft.world.level.Level level, net.minecraft.world.phys.Vec3 from, net.minecraft.world.phys.Vec3 to)
      Casts HEADROOM_SAMPLES short rays straight up at evenly-spaced points along the shooter-to-target line and returns the minimum clearance found.
    • computeDesiredPeakY

      protected double computeDesiredPeakY(double originY, double hDist, double headroom)
      Computes the desired arc peak height (in world Y) for a given horizontal distance and available headroom.
      • Peak scales linearly from 1.5 blocks at close range up to 8.0 blocks at 30.0 blocks distance.
      • The result is then clamped to headroom - ARC_CEILING_MARGIN so the arc never hits the ceiling.
      • Always at least 0.3 blocks above origin.
      Parameters:
      originY - Y of the projectile spawn point
      hDist - horizontal distance to target
      headroom - vertical clearance above the path from measureHeadroom()
      Returns:
      desired world-Y of the arc apex
    • calculateLobVelocity

      @Nullable public net.minecraft.world.phys.Vec3 calculateLobVelocity(net.minecraft.world.phys.Vec3 origin, net.minecraft.world.phys.Vec3 target, int maxTicks, double desiredPeakY)
      Solves a complete lob arc from origin to target whose apex reaches desiredPeakY.

      How it works

      1. Binary-search for the initial vertical speed vy0 that produces the desired apex height.
      2. Simulate that vy0 forward to find the tick T at which the projectile descends through target.y.
      3. Compute the horizontal speed vh = hDist / hFactor(T) that covers the horizontal distance in exactly T ticks.

      Because vy0 and vh are solved independently, the resulting speed can be anything. Unlike the old pitch-range solver this approach directly controls the shape of the arc (peak height) rather than the angle, which is what actually governs how the arc looks.

      Parameters:
      origin - projectile spawn position
      target - aim point (enemy body centre, already predicted)
      maxTicks - flight-time search horizon
      desiredPeakY - desired world-Y of the arc apex
      Returns:
      launch velocity, or null if hDist is zero
    • predictTargetPosition

      protected net.minecraft.world.phys.Vec3 predictTargetPosition(net.minecraft.world.phys.Vec3 spawnPos, net.minecraft.world.entity.LivingEntity enemy, double headroom, int maxTicks)
      Predicts where enemy will be when the arc arrives, using a three-pass XZ-only iterative lead.

      Why XZ-only?

      getDeltaMovement().y of a grounded entity is typically −0.08 (Minecraft's resting gravity step). Using that value directly predicted the target 2–3 blocks underground at long range, causing every shot to land just behind the target's feet. Ignoring the Y component entirely — and always aiming at body-centre Y — completely eliminates that error for grounded targets while still leading properly for jumping or airborne ones (because we aim at the body-centre Y at the time of the shot, which is correct for on-ground targets and a good approximation for airborne ones).

      Stationary guard

      If the enemy's XZ speed is below 0.001 blocks²/tick² (≈ 0.032 blocks/tick) the method returns the current body centre directly, skipping all passes and avoiding any drift from scaling a near-zero vector.

    • lobProjectile

      public void lobProjectile(net.minecraft.world.entity.Mob shooter, float velocity, double damage, double distToShooter)
    • lobProjectile

      public void lobProjectile(net.minecraft.world.entity.Entity shooter, float velocity, double damage, double distToShooter, net.minecraft.world.entity.LivingEntity enemy)
      Launches this projectile at the shooter's current mob target.

      Close range (≤ getDirectShotRange() blocks): fires straight at the target's body centre — no arc, no prediction.

      Far range:

      1. Measure headroom along the shooter→target line.
      2. Compute desired arc peak from distance + headroom.
      3. Predict where the target will be when the arc arrives (three-pass XZ lead; skipped for stationary targets).
      4. Solve and fire the arc.
    • setup

      public void setup(int i)
    • tick

      public void tick()
      Overrides:
      tick in class AbstractPlantProjectile
    • getWaterInertia

      protected float getWaterInertia()
    • findHitEntity

      protected net.minecraft.world.phys.EntityHitResult findHitEntity(net.minecraft.world.phys.Vec3 startVec, net.minecraft.world.phys.Vec3 endVec)
      Overrides:
      findHitEntity in class AbstractPlantProjectile
    • onHitEntity

      protected void onHitEntity(@NotNull @NotNull net.minecraft.world.phys.EntityHitResult result)
      Overrides:
      onHitEntity in class AbstractPlantProjectile
    • onHitBlock

      protected void onHitBlock(@NotNull @NotNull net.minecraft.world.phys.BlockHitResult result)
      Overrides:
      onHitBlock in class AbstractPlantProjectile