@Override public MovingObjectPosition collisionRayTrace(Vec3 startVec, Vec3 endVec) { Block block = new Block(Material.rock); // It's possible for the startVec to be embedded in a lump (causing it // to hit the opposite side), so we must move it farther away Vec3 d = startVec.subtract(endVec); double scale = 5.2; // Diagonal of a 3³. (Was initially using incrScale = 2) // This isn't quite right; the dVector would properly be normalized here // & rescaled to the max diameter. But we can survive without it. // Unnormalized length of dVector is 6m in surviavl mode IIRC. This'll // be way longer than it needs to be. // Why is it + instead of -? Hmm. startVec = startVec.add(SpaceUtil.scale(d, scale)); MovingObjectPosition shortest = null; for (int i = 0; i < parts.size(); i++) { ClayLump lump = parts.get(i); lump.toRotatedBlockBounds(this, block); MovingObjectPosition mop = block.collisionRayTrace(worldObj, pos, startVec, endVec); if (mop != null) { mop.subHit = i; if (shortest == null) { shortest = mop; } else { Vec3 s = shortest.hitVec; Vec3 m = mop.hitVec; s = new Vec3(s.xCoord, s.yCoord, s.zCoord); m = new Vec3(m.xCoord, m.yCoord, m.zCoord); startVec = startVec.subtract(s).subtract(m); if (m.lengthVector() < s.lengthVector()) { shortest = mop; } } } } return shortest; // return super.collisionRayTrace(w, pos, startVec, endVec); }
@Override public void doAttack(int ticks, EntityFinalBoss boss, World w, Random rand) { if (ticks % 5 == 0) { Vec3 start = Vec3.createVectorHelper(boss.posX, boss.posY + 0.5, boss.posZ); AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox( start.xCoord - 50, start.yCoord - 50, start.zCoord - 50, start.xCoord + 50, start.yCoord + 50, start.zCoord + 50); for (Object o : w.getEntitiesWithinAABB(EntityPlayer.class, bounds)) { EntityPlayer pl = (EntityPlayer) o; // For some reason, the server's position is normal, but // the client's position is 1.62 higher Vec3 end = Vec3.createVectorHelper(pl.posX, pl.posY + (w.isRemote ? 0 : 1.62), pl.posZ); Vec3 vec = start.subtract(end).normalize(); vec.xCoord /= 2; vec.yCoord /= 2; vec.zCoord /= 2; double lastDistSq = -1; Vec3 pos = Vec3.createVectorHelper(start.xCoord, start.yCoord, start.zCoord); boolean hit = true; while (true) { pos = pos.addVector(vec.xCoord, vec.yCoord, vec.zCoord); if (w.getBlock( (int) Math.floor(pos.xCoord), (int) Math.floor(pos.yCoord), (int) Math.floor(pos.zCoord)) .isOpaqueCube()) { hit = false; break; } if (lastDistSq >= 0 && pos.squareDistanceTo(end) > lastDistSq) { break; } w.spawnParticle("witchMagic", pos.xCoord, pos.yCoord, pos.zCoord, 0, 0, 0); lastDistSq = pos.squareDistanceTo(end); } if (hit) { pl.attackEntityFrom( DamageSource.causeMobDamage(boss).setDamageBypassesArmor(), pl.getMaxHealth() / 4); } } } }
/** * Tests whether a clear line of sight between the two blocks exists. Tests against bounding * boxes, ignores liquids. This function tries to ignore hitting the starting block by moving pos0 * to the respective edge of the start block's bounding box if this happens. At least one * coordinate of pos0 has to be outside of the start block's bounding box for this to work. * * @param world * @param cc0 coordinates of start block * @param cc1 coordinates of target block * @param pos0 exact start position * @param pos1 exact target position * @return true if clear LOS exists. false if there are obstacles between start and target. */ public static boolean canBlocksSeeOther( World world, ChunkCoordinates cc0, ChunkCoordinates cc1, Vec3 pos0, Vec3 pos1) { MovingObjectPosition mop = world.rayTraceBlocks(pos0, pos1); if (mop != null && mop.blockX == cc0.posX && mop.blockY == cc0.posY && mop.blockZ == cc0.posZ) { AxisAlignedBB aabb0 = world .getBlock(cc0.posX, cc0.posY, cc0.posZ) .getCollisionBoundingBoxFromPool(world, cc0.posX, cc0.posY, cc0.posZ); Vec3 rayTraceDiff = pos0.subtract(mop.hitVec).normalize(); // move starting point to the edge of the bounding box in main direction of raytrace double restartVecX; double restartVecY; double restartVecZ; if (pos0.xCoord >= aabb0.minX && pos0.xCoord <= aabb0.maxX) { restartVecX = (rayTraceDiff.xCoord > 0.5) ? aabb0.maxX : (rayTraceDiff.xCoord < (-0.5)) ? aabb0.minX : pos0.xCoord; } else { restartVecX = pos0.xCoord; } if (pos0.yCoord >= aabb0.minY && pos0.yCoord <= aabb0.maxY) { restartVecY = (rayTraceDiff.yCoord > 0.5) ? aabb0.maxY : (rayTraceDiff.yCoord < (-0.5)) ? aabb0.minY : pos0.yCoord; } else { restartVecY = pos0.yCoord; } if (pos0.zCoord >= aabb0.minZ && pos0.zCoord <= aabb0.maxZ) { restartVecZ = (rayTraceDiff.zCoord > 0.5) ? aabb0.maxZ : (rayTraceDiff.zCoord < (-0.5)) ? aabb0.minZ : pos0.zCoord; } else { restartVecZ = pos0.zCoord; } Vec3 restartVec = Vec3.createVectorHelper(restartVecX, restartVecY, restartVecZ); mop = world.rayTraceBlocks(restartVec, pos1); } return mop == null || (mop.blockX == cc1.posX && mop.blockY == cc1.posY && mop.blockZ == cc1.posZ); }
protected void renderBeam( Vec3 from, Vec3 to, Vec3 offest, Color color, ResourceLocation texture, float tickness, T viewer) { if (texture != null) Minecraft.getMinecraft().renderEngine.bindTexture(texture); RenderUtils.applyColor(color); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_LIGHTING); double distance = from.subtract(to).lengthVector(); double v = -viewer.worldObj.getWorldTime() * 0.2; glPushMatrix(); glTranslated(from.xCoord, from.yCoord, from.zCoord); glRotated(-viewer.getRotationYawHead(), 0, 1, 0); glRotated(viewer.rotationPitch, 1, 0, 0); glTranslated(offest.xCoord, offest.yCoord, offest.zCoord); Tessellator t = Tessellator.instance; t.startDrawingQuads(); t.addVertexWithUV(tickness, 0, 0, 0, v); t.addVertexWithUV(tickness, 0, distance, 0, v + distance * 1.5); t.addVertexWithUV(-tickness, 0, distance, 1, v + distance * 1.5); t.addVertexWithUV(-tickness, 0, 0, 1, v); t.addVertexWithUV(0, tickness, 0, 0, v); t.addVertexWithUV(0, tickness, distance, 0, v + distance * 1.5); t.addVertexWithUV(0, -tickness, distance, 1, v + distance * 1.5); t.addVertexWithUV(0, -tickness, 0, 1, v); t.draw(); glPopMatrix(); glEnable(GL_CULL_FACE); glDisable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
private Vec3 getRelativeDistance(EntityMagnet magnet) { Vec3 magnetPos = Vec3.createVectorHelper(magnet.posX, magnet.posY, magnet.posZ); Vec3 turtlePos = getTurtlePosition().addVector(0.5, 0.5, 0.5); Vec3 dist = turtlePos.subtract(magnetPos); ForgeDirection side = getTurtleFacing(); switch (side) { case NORTH: return Vec3.createVectorHelper(-dist.zCoord, dist.yCoord, dist.xCoord); case SOUTH: return Vec3.createVectorHelper(dist.zCoord, dist.yCoord, -dist.xCoord); case EAST: return Vec3.createVectorHelper(dist.xCoord, dist.yCoord, dist.zCoord); case WEST: return Vec3.createVectorHelper(-dist.xCoord, dist.yCoord, -dist.zCoord); default: return dist; } }
@Override public void update() { AxisAlignedBB bbox = PortalgunMod.portalBlock .getCollisionBoundingBox(worldObj, this.getPos(), worldObj.getBlockState(this.getPos())) .expand(0, 1, 0.1); List<Entity> ents = worldObj.getEntitiesWithinAABB(Entity.class, bbox); for (Entity entityIn : ents) { Portal portal = this; if (portal.linked != null) { Vec3 thisPortal = new Vec3(pos.getX(), pos.getY(), pos.getZ()); BlockPos otherPortalBP = portal.linked.getPos(); Vec3 otherPortal = new Vec3(otherPortalBP.getX(), otherPortalBP.getY(), otherPortalBP.getZ()); Vec3 diff = otherPortal.subtract(thisPortal); Vec3 newPos = entityIn.getPositionVector().add(diff); entityIn.motionZ = -entityIn.motionZ; entityIn.setLocationAndAngles( newPos.xCoord, newPos.yCoord, newPos.zCoord + 0.2, entityIn.getRotationYawHead() + 180, entityIn.rotationPitch); entityIn.prevRotationYaw = entityIn.rotationYaw; entityIn.prevRotationPitch = entityIn.rotationPitch; if (entityIn instanceof EntityPlayerSP) { EntityPlayerSP SPplayer = (EntityPlayerSP) entityIn; SPplayer.prevRenderArmYaw = SPplayer.renderArmYaw += 180; SPplayer.prevRotationYawHead = SPplayer.rotationYawHead += 180; } } } }