Feroov Posted May 6, 2023 Posted May 6, 2023 I have a flying mob that basically moves like a ghast, I have a custom projectile, it is a AbstractArrow type not fireball, well my accuracy is not quite there yet, on some distances, it is perfectly accurate and on some distances inaccurate, this is my current attack goal: public static class RaybeamAttackGoal extends Goal { private final Celestroid mob; private final Celestroid rangedAttackMob; @Nullable private LivingEntity target; private int attackTime = -1; private int seeTime; private final int statecheck; private final double attackIntervalMin, attackIntervalMax, speedModifier; private final float attackRadius, attackRadiusSqr; public RaybeamAttackGoal(Celestroid celestroid, double speedIn, double dpsIn, float rangeIn, int state) { this(celestroid, speedIn, dpsIn, dpsIn, rangeIn, state); } public RaybeamAttackGoal(Celestroid gunswine, double speedIn, double atckIntervalMin, double atckIntervalMax, float atckRadius, int state) { this.rangedAttackMob = gunswine; this.mob = gunswine; this.speedModifier = speedIn; this.attackIntervalMin = atckIntervalMin; this.attackIntervalMax = atckIntervalMax; this.attackRadius = atckRadius; this.attackRadiusSqr = atckRadius * atckRadius; this.statecheck = state; this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); } public boolean canUse() { LivingEntity livingentity = this.mob.getTarget(); if (livingentity != null && livingentity.isAlive()) { this.target = livingentity; return true; } else { return false; } } public boolean canContinueToUse() { return this.canUse() || !this.mob.getNavigation().isDone(); } public void stop() { this.target = null; this.seeTime = 0; this.attackTime = -1; } public boolean requiresUpdateEveryTick() { return true; } public void tick() { double d0 = this.mob.distanceToSqr(this.target.getX(), this.target.getY(), this.target.getZ()); boolean flag = this.mob.getSensing().hasLineOfSight(this.target); if (flag) { ++this.seeTime; } else { this.seeTime = 0; } if (!(d0 > (double)this.attackRadiusSqr) && this.seeTime >= 5) { this.mob.getNavigation().stop(); } else { this.mob.getNavigation().moveTo(this.target, this.speedModifier); } this.mob.getLookControl().setLookAt(this.target, 30.0F, 30.0F); if (--this.attackTime == 0) { if (!flag) { return; } float f = (float)Math.sqrt(d0) / this.attackRadius; float f1 = Mth.clamp(f, 0.1F, 1.0F); this.rangedAttackMob.performRangedAttack(this.target, f1); this.attackTime = Mth.floor(f * (float)(this.attackIntervalMax - this.attackIntervalMin) + (float)this.attackIntervalMin); } else if (this.attackTime < 0) { this.attackTime = Mth.floor(Mth.lerp(Math.sqrt(d0) / (double)this.attackRadius, (double)this.attackIntervalMin, (double)this.attackIntervalMax)); } } } public void performRangedAttack(LivingEntity livingEntity, float p_32142_) { RaygunBeam beam = new RaygunBeam(this.level, this); double d0 = livingEntity.getX() - this.getX(); double d1 = livingEntity.getY(-3.3333333333333333D) - beam.getY(); double d2 = livingEntity.getZ() - this.getZ(); double d3 = Math.sqrt(d0 * d0 + d2 * d2); beam.shoot(d0, d1 + d3 * (double)0.2F, d2, 1.6F,0f); this.playSound(SoundEventsSTLCON.RAYGUN_SHOOT.get(), 2.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); this.level.addFreshEntity(beam); } What can I do or refactor so that the accuracy is basically like a fireball of the ghast, I tried actually creating a similar way of how ghast is made, so I did create before another projectile for testing purposes, which used same functionality as a fireball, then the accuracy was perfect as I wanted but obviously the projectile wouldn't do damage to the player. Thank you so much in advance cheers Quote
sFXprt Posted May 7, 2023 Posted May 7, 2023 //From AbstractSkeleton.class //shoot() method parameters (x,y,z,velocity,inaccuracy) abstractarrow.shoot(d0, d1 + d3 * (double)0.2F, d2, 1.6F, (float)(14 - this.level.getDifficulty().getId() * 4)); as you see in the last parameter its adjusting the inaccuracy of the shoot from a hardcoded number subtracted by the current world difficulty * 4. Now if you set it to 0 and it'll be accurate and increasing the velocity makes it deal more damage and is a factor in the trajectory of the arrow. I think what you are trying to compare are two different things, the arrow first of all has drop off which compared to a fireball does not drop off and keeps its velocity constant. I have pulled the code from the Vanilla Ghast and Fireball to show you what it does compared to the Arrow This is the code the Ghast uses to shoot a fireball if (this.chargeTime == 20) { double d1 = 4.0D; Vec3 vec3 = this.ghast.getViewVector(1.0F); double d2 = livingentity.getX() - (this.ghast.getX() + vec3.x * 4.0D); double d3 = livingentity.getY(0.5D) - (0.5D + this.ghast.getY(0.5D)); double d4 = livingentity.getZ() - (this.ghast.getZ() + vec3.z * 4.0D); if (!this.ghast.isSilent()) { level.levelEvent((Player)null, 1016, this.ghast.blockPosition(), 0); } LargeFireball largefireball = new LargeFireball(level, this.ghast, d2, d3, d4, this.ghast.getExplosionPower()); largefireball.setPos(this.ghast.getX() + vec3.x * 4.0D, this.ghast.getY(0.5D) + 0.5D, largefireball.getZ() + vec3.z * 4.0D); level.addFreshEntity(largefireball); this.chargeTime = -40; } This is the AbstractHurtingProjectile.class code that calls when its spawned in the world public void tick() { Entity entity = this.getOwner(); if (this.level.isClientSide || (entity == null || !entity.isRemoved()) && this.level.hasChunkAt(this.blockPosition())) { super.tick(); if (this.shouldBurn()) { this.setSecondsOnFire(1); } HitResult hitresult = ProjectileUtil.getHitResult(this, this::canHitEntity); if (hitresult.getType() != HitResult.Type.MISS && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, hitresult)) { this.onHit(hitresult); } this.checkInsideBlocks(); Vec3 vec3 = this.getDeltaMovement(); double d0 = this.getX() + vec3.x; double d1 = this.getY() + vec3.y; double d2 = this.getZ() + vec3.z; ProjectileUtil.rotateTowardsMovement(this, 0.2F); float f = this.getInertia(); if (this.isInWater()) { for(int i = 0; i < 4; ++i) { float f1 = 0.25F; this.level.addParticle(ParticleTypes.BUBBLE, d0 - vec3.x * 0.25D, d1 - vec3.y * 0.25D, d2 - vec3.z * 0.25D, vec3.x, vec3.y, vec3.z); } f = 0.8F; } this.setDeltaMovement(vec3.add(this.xPower, this.yPower, this.zPower).scale((double)f)); this.level.addParticle(this.getTrailParticle(), d0, d1 + 0.5D, d2, 0.0D, 0.0D, 0.0D); this.setPos(d0, d1, d2); } else { this.discard(); } } AbstractArrow.class tick() method, the area in where it checks if a block was hit or not if (this.inGround && !flag) { if (this.lastState != blockstate && this.shouldFall()) { this.startFalling(); } else if (!this.level.isClientSide) { this.tickDespawn(); } ++this.inGroundTime; } ShouldFall check and StartFalling method private boolean shouldFall() { return this.inGround && this.level.noCollision((new AABB(this.position(), this.position())).inflate(0.06D)); } private void startFalling() { this.inGround = false; Vec3 vec3 = this.getDeltaMovement(); this.setDeltaMovement(vec3.multiply((double)(this.random.nextFloat() * 0.2F), (double)(this.random.nextFloat() * 0.2F), (double)(this.random.nextFloat() * 0.2F))); this.life = 0; } as you see the arrow is more complex in physics compared to the fireball, if you want it to be just as accurate as the fireball I think you would have to override a custom extended AbstractArrow or just outright make your own version of the AbstractArrow class Quote
sFXprt Posted May 7, 2023 Posted May 7, 2023 You also mentioned you made a similar projectile like the Ghast does what class did you derive it from AbstractHurtingProjectile or AbstractArrow? Quote
Feroov Posted May 7, 2023 Author Posted May 7, 2023 1 hour ago, sFXprt said: You also mentioned you made a similar projectile like the Ghast does what class did you derive it from AbstractHurtingProjectile or AbstractArrow? Like you mentioned how I could make my own AbstractArrow, I actually went on creating my own AbstractHurtingProjectile since I think the previous one I made the testing purpose one was AbstractArrow if I recall. Everything is working as intended now so, thank you so much for your time appreciate it, and yes I had some issues regarding where it shoots, so I copied/used over ghast as you mentioned ♥ 1 Quote
sFXprt Posted May 9, 2023 Posted May 9, 2023 On 5/7/2023 at 3:20 AM, Feroov said: Like you mentioned how I could make my own AbstractArrow, I actually went on creating my own AbstractHurtingProjectile since I think the previous one I made the testing purpose one was AbstractArrow if I recall. Everything is working as intended now so, thank you so much for your time appreciate it, and yes I had some issues regarding where it shoots, so I copied/used over ghast as you mentioned ♥ Nice glad to see you got it working man! Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.