November 29, 20186 yr 13 minutes ago, TheRPGAdventurer said: does this needs to be a static or a loop? This is a bit more involved than that. This presumably needs to happen within the corresponding AI. When the AI begins it's job you calculate the angle. Then each tick you do angle = angle + NUM(you need to figure out the NUM yourself but effectively this is the speed of circling) and do the rest of the movement-related actions.
November 29, 20186 yr Author /* ** 2013 July 28 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. */ package com.TheRPGAdventurer.ROTD.server.entity.ai.air; import com.TheRPGAdventurer.ROTD.DragonMountsConfig; import com.TheRPGAdventurer.ROTD.server.entity.EntityTameableDragon; import com.TheRPGAdventurer.ROTD.server.entity.ai.EntityAIDragonBase; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.DimensionType; /** * Dragon AI for instant landing, if left unmounted in air. * * @author Nico Bergemann <barracuda415 at yahoo.de> */ public class EntityAIDragonLandAndCommenceFlyByAttack extends EntityAIDragonBase { private final double speed; private BlockPos landingPos; public EntityAIDragonLandAndCommenceFlyByAttack(EntityTameableDragon dragon, double speed) { super(dragon); this.speed = speed; setMutexBits(1); } public BlockPos findLandingArea(BlockPos pos) { for (int Y = 1; Y <= 2; Y++) { for (int Z = 1; Z <= 2; Z++) { for (int X = 1; X <= 2; X++) { world.getBlockState(new BlockPos(X, Y, Z)).getMaterial().isSolid(); { pos = pos.down(); } } } } return pos; } private boolean findLandingBlock() { // get current entity position landingPos = dragon.getPosition(); // add some variance int followRange = MathHelper.floor(getFollowRange()); int ox = followRange - random.nextInt(followRange) * 2; int oz = followRange - random.nextInt(followRange) * 2; landingPos = landingPos.add(ox, 0, oz); // get ground block if (dragon.world.provider.getDimensionType() == DimensionType.NETHER) { landingPos = findLandingArea(landingPos); } else { landingPos = dragon.world.getHeight(landingPos); } // make sure the block below is solid return world.getBlockState(landingPos.down()).getMaterial().isSolid(); } @Override public boolean shouldExecute() { return !dragon.isInWater() && !dragon.isInLava() && dragon.isFlying() && dragon.getControllingPlayer() == null && findLandingBlock() && dragon.getRevengeTarget() == null; } @Override public boolean shouldContinueExecuting() { return dragon.isFlying() && dragon.getControllingPlayer() == null && !dragon.getNavigator().noPath(); } @Override public void startExecuting() { EntityLivingBase target = dragon.getAttackTarget(); boolean commenceAttackPath = target != null && dragon.getControllingPlayer() == null; boolean commencAttackFlying = commenceAttackPath && !target.onGround; // try to fly to ground block position // if (!tryMoveToBlockPos(landingPos, speed)) { // probably too high, so simply descend vertically // tryMoveToBlockPos(dragon.getPosition().down(4), speed); // } if(!tryToCircleBlockPos(new BlockPos(-8678, 126, 497), speed)) { tryToCircleBlockPos(new BlockPos(-8678, 126, 497), speed); } } } this is where i tried for a test, i used a blockpos where i am close to. protected boolean tryToCircleBlockPos(BlockPos midPoint, double speed) { Vec3d vec1 = dragon.getPositionVector().subtract(midPoint.getX(),midPoint.getY(),midPoint.getZ()); Vec3d vec2 = new Vec3d(0,0,1); // "calculate the angle between these 2 vectors" I hope vec3d is compat with Blockpos Vec3i double a = Math.acos((vec1.dotProduct(vec2)) / (vec1.lengthVector() * vec2.lengthVector())); double r = 12; // radius is now a constant double x = midPoint.getX() + r * Math.cos(a); // x = playerX + r * cos(a) as stated double y = midPoint.getY() + 20; // y = playerY + NUM as stated double z = midPoint.getZ() + r * Math.sin(a); // z = playerZ + r * sin(a) as stated return dragon.getNavigator().tryMoveToXYZ(x + 0.5, y + 0.5, z + 0.5, speed); // no more adding }
November 29, 20186 yr Which part of my previous message did you not understand? 25 minutes ago, V0idWa1k3r said: When the AI begins it's job you calculate the angle. Then each tick you do angle = angle + NUM(you need to figure out the NUM yourself but effectively this is the speed of circling) and do the rest of the movement-related actions. This means that you need to do things at 2 different points of your AI. When the AI starts executing you calculate the angle. No, don't tell the dragon to move anywhere or do anything at all. Just calculate the angle and store it in a field. Nothing more. While the AI continually executes(aka each tick) you take that angle, add some number to it and do the rest of the calculations with it. I don't remember the method names in the AI class and am currently not home so I can't look them up but they should be fairly obvious.
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.