// Finds points on a line extending infinitely through the points startLoc and endLoc intersecting // a circle centered at circleLoc private List<Location> getCollisionPoints( Location startLoc, Location endLoc, Location circleLoc, double radiusSquared) { Vector delta = vectorFromLocations(startLoc, endLoc); Vector circleLocInTermsOfStart = vectorFromLocations(startLoc, circleLoc); boolean flipped = false; if (delta.getX() == 0) { flipped = true; flipXZ(delta); flipXZ(circleLocInTermsOfStart); } circleLocInTermsOfStart.add(new Vector(0.5, 0, 0.5)); double slope = delta.getZ() / delta.getX(); double circleX = circleLocInTermsOfStart.getX(); double circleZ = circleLocInTermsOfStart.getZ(); double circleXSquared = circleX * circleX; double circleZSquared = circleZ * circleZ; List<Double> xs = getSolutions( slope * slope + 1, -(2 * circleZ * slope + 2 * circleX), circleXSquared + circleZSquared - radiusSquared); List<Location> results = new ArrayList<Location>(); for (double x : xs) { Vector offset = new Vector(x, 0, x * slope); if (flipped) flipXZ(offset); results.add(startLoc.clone().add(offset)); } return results; }
@Override public SpellResult step(CastContext context) { if (entity == null) { return SpellResult.FAIL; } SpellResult result = super.step(context); Location target = actionContext.getTargetLocation(); // TODO: locationOffset and velocityOffset should be made relative if (locationOffset != null) { target = target.clone().add(locationOffset); } if (doVelocity) { Vector velocity = this.velocity.clone().multiply(distanceTravelledThisTick); if (velocityOffset != null) { velocity = velocity.add(velocityOffset); } entity.setVelocity(velocity); } Location currentLocation = entity.getLocation(); if (doTeleport) { if (!orient) { target.setYaw(currentLocation.getYaw()); target.setPitch(currentLocation.getPitch()); } entity.teleport(target); } return result; }
/** * Set the location of the item and put it on the right place on the block * * @param location The location of the item/shop block */ private void setLocation(Location location) { this.location = location.getBlock().getLocation(); // simply clear everything after the comma. Vector vec = this.location.toVector(); vec.add(new Vector(0.5, 0.6, 0.5)); this.location = vec.toLocation(this.location.getWorld()); if (getItem() != null) { getItem().teleport(this.location); } }
/** * Find a suitable location for a player to teleport to in the given world. This method uses * WorldBorder as the configuration source. * * @param world World to teleport to * @return Location to teleport to */ private Location findSuitableLocationWB(World world) { BorderData borderData = WorldBorder.plugin.GetWorldBorder(world.getName()); if (borderData == null) { // throw new IllegalStateException(String.format("World %1$s isn't configured in // WorldBorder.", world.getName())); return null; } for (int i = 0; i < 100; i++) { Vector position = new Vector(borderData.getX(), 0.0, borderData.getZ()); // Get a uniform-area random position within the world border's geometry boolean isRound = (borderData.getShape() == null) ? true : borderData.getShape(); if (isRound) { position.add( getRandomPointInEllipse(random, borderData.getRadiusX(), borderData.getRadiusZ())); } else { position.add( getRandomPointInRectangle(random, borderData.getRadiusX(), borderData.getRadiusZ())); } // Ensure there's a solid block to stand on Block highestBlock = world.getHighestBlockAt(position.getBlockX(), position.getBlockZ()); if (highestBlock == null) continue; highestBlock = highestBlock.getRelative(0, -1, 0); // Because the javadocs are wrong. if (highestBlock == null) continue; if (highestBlock.getY() < 1 || highestBlock.getY() >= world.getMaxHeight() - 2) continue; if (highestBlock.isLiquid()) continue; position.setX((double) position.getBlockX() + 0.5); position.setY(highestBlock.getY() + 2); position.setZ((double) position.getBlockZ() + 0.5); return position.toLocation(world, getRandomYaw(), 0.0f); } return null; }
private Collection<GlowPlayer> damageEntities() { float power = this.power; this.power *= 2f; Collection<GlowPlayer> affectedPlayers = new ArrayList<>(); Collection<GlowLivingEntity> entities = getNearbyEntities(); for (GlowLivingEntity entity : entities) { double disDivPower = distanceTo(entity) / (double) this.power; if (disDivPower > 1.0D) continue; Vector vecDistance = distanceToHead(entity); if (vecDistance.length() == 0.0) continue; vecDistance.normalize(); double basicDamage = calculateDamage(entity, disDivPower); int explosionDamage = (int) ((basicDamage * basicDamage + basicDamage) * 4 * (double) power + 1.0D); if (!(entity instanceof GlowHumanEntity)) { EntityDamageEvent.DamageCause damageCause; if (source == null || source.getType() == EntityType.PRIMED_TNT) { damageCause = EntityDamageEvent.DamageCause.BLOCK_EXPLOSION; } else { damageCause = EntityDamageEvent.DamageCause.ENTITY_EXPLOSION; } entity.damage(explosionDamage, source, damageCause); } double enchantedDamage = calculateEnchantedDamage(basicDamage, entity); vecDistance.multiply(enchantedDamage); Vector currentVelocity = entity.getVelocity(); currentVelocity.add(vecDistance); entity.setVelocity(currentVelocity); if (entity instanceof GlowPlayer) { affectedPlayers.add((GlowPlayer) entity); } } this.power = power; return affectedPlayers; }
public boolean advance() { Vector dir = loc.getDirection(); dir.add(new Vector(0.0f, -0.008, 0.0f)); // Apply 'gravity' loc.setDirection(dir); loc.add(dir.multiply(speed)); loc.getWorld().createExplosion(loc, 0.0f, false); if (ItemManager.getId(loc.getBlock()) != CivData.AIR) { return true; } if (loc.distance(startLoc) > maxRange) { return true; } return false; }
/** * Get next block * * @return next block position */ public boolean getNextBlock() { prevPos = targetPos; do { curDistance += checkDistance; targetPosDouble.add(offset); targetPos = targetPosDouble.toBlockVector(); } while (curDistance <= maxDistance && targetPos.getBlockX() == prevPos.getBlockX() && targetPos.getBlockY() == prevPos.getBlockY() && targetPos.getBlockZ() == prevPos.getBlockZ()); if (curDistance > maxDistance) { return false; } return true; }
protected void applyForce() { if (!isActive()) return; // Calculate speeds based on previous delta, to try to adjust for server lag float timeDeltaSeconds = (System.currentTimeMillis() - lastTick) / 1000.0f; Vector force = new Vector(0, gravity * timeDeltaSeconds, 0); float elevateMagnitude = (float) elevateRate * timeDeltaSeconds; float speedMinMagnitude = (float) minSpeed * timeDeltaSeconds; float speedMaxMagnitude = (float) maxSpeed * timeDeltaSeconds; Location playerLocation = player.getLocation(); float pitch = playerLocation.getPitch(); float yaw = playerLocation.getYaw(); Vector scaledForce = force.clone(); // scaled based on distance from target height /// this is the main levitate action int playerHeight = playerLocation.getBlockY(); int heightDelta = targetHeight - playerHeight; if (heightDelta > 0) { int heightBoost = heightDelta > 16 ? 16 : heightDelta; scaledForce.multiply(heightBoost); } else if (heightDelta < 0) { scaledForce.setY(0); } // Trying out a suggestion, in a hacky way- adjust pitch so that "level" is really looking // down a bit pitch += 15; // Adjust target height based on aim Vector aim = new Vector( (0 - Math.sin(Math.toRadians(yaw))), (0 - Math.sin(Math.toRadians(pitch))), Math.cos(Math.toRadians(yaw))); aim.normalize(); // only ascend if aiming mostly up, and if near the target if (heightDelta < 5 && pitch < -45) { hoverHeight += (elevateMagnitude * aim.getY()); // We'll let the player go up higher than max height. if (hoverHeight > 255) hoverHeight = 255; if (hoverHeight < defaultHoverHeight) hoverHeight = defaultHoverHeight; updateTargetHeight(); } // Periodically poll for ground level changes if (checkCounter++ > checkFrequency) { checkForGround(); } // Steer- faster at higher altitudes, and scaled based on angle away from center (look up or // down to stop) float multiplier = speedMinMagnitude; if (!player.isSneaking()) { int heightFactor = hoverHeight > maxSpeedAtElevation ? maxSpeedAtElevation : (int) hoverHeight; multiplier *= (float) speedMaxMagnitude * heightFactor / maxSpeedAtElevation; } float verticalMultipler = 1.0f - (float) Math.abs(aim.getY()); aim.multiply(multiplier * verticalMultipler); aim.setY(0); scaledForce.add(aim); // Logger.getLogger("Minecraft").info("Applying force: (" + scaledForce.getX() + ", " + // scaledForce.getY() + ", "+ scaledForce.getZ() + ")"); player.setVelocity(scaledForce); this.lastTick = System.currentTimeMillis(); }
public static void moveUp(Entity entity, double speed) { Vector velocity = new Vector(0.0, speed, 0.0); // .normalize().multiply(-speed); entity.setVelocity(velocity.add(randomDir())); }
@Override public SpellResult perform(CastContext context) { Entity sourceEntity = context.getEntity(); Location sourceLocation = context.getEyeLocation().clone(); Entity targetEntity = context.getTargetEntity(); Location targetLocation = context.getTargetLocation(); if (targetLocation != null) { targetLocation = targetLocation.clone(); } Vector direction = context.getDirection().normalize(); if (sourceLocation == null) { return SpellResult.LOCATION_REQUIRED; } if (targetSelf) { targetEntity = sourceEntity; targetLocation = sourceLocation; } else if (targetEntityLocation && targetEntity != null) { targetLocation = targetEntity.getLocation(); } if (attachBlock) { Block previousBlock = context.getPreviousBlock(); if (previousBlock != null) { Location current = targetLocation; targetLocation = previousBlock.getLocation(); context.getBrush().setTarget(current, targetLocation); } } if (sourceOffset != null) { sourceLocation = sourceLocation.add(sourceOffset); } if (targetOffset != null && targetLocation != null) { targetLocation = targetLocation.add(targetOffset); } if (randomSourceOffset != null) { sourceLocation = RandomUtils.randomizeLocation(sourceLocation, randomSourceOffset); } if (randomTargetOffset != null && targetLocation != null) { targetLocation = RandomUtils.randomizeLocation(targetLocation, randomTargetOffset); } if (targetDirection != null && targetLocation != null) { targetLocation.setDirection(targetDirection); } if (sourceDirection != null) { sourceLocation.setDirection(sourceDirection); direction = sourceDirection.clone(); } if (targetDirectionOffset != null && targetLocation != null) { targetLocation.setDirection(targetLocation.getDirection().add(targetDirectionOffset)); } if (sourceDirectionOffset != null) { sourceLocation.setDirection(direction.add(sourceDirectionOffset)); } if (sourceDirectionSpeed != null) { sourceLocation = sourceLocation.add(direction.clone().multiply(sourceDirectionSpeed)); } if (targetDirectionSpeed != null && targetLocation != null) { targetLocation = targetLocation.add(direction.clone().multiply(targetDirectionSpeed)); } if (sourceAtTarget && targetLocation != null) { sourceLocation.setX(targetLocation.getX()); sourceLocation.setY(targetLocation.getY()); sourceLocation.setZ(targetLocation.getZ()); sourceLocation.setWorld(targetLocation.getWorld()); } if (persistTarget) { context.setTargetLocation(targetLocation); } CastContext newContext = createContext(context, sourceEntity, sourceLocation, targetEntity, targetLocation); return super.perform(newContext); }
@Override public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) { if (state == SpellCastState.NORMAL) { if (projectileClass != null) { Projectile projectile = player.launchProjectile(projectileClass); playSpellEffects(EffectPosition.PROJECTILE, projectile); playTrackingLinePatterns( EffectPosition.DYNAMIC_CASTER_PROJECTILE_LINE, player.getLocation(), projectile.getLocation(), player, projectile); projectile.setBounce(false); MagicSpells.getVolatileCodeHandler().setGravity(projectile, projectileHasGravity); if (velocity > 0) { projectile.setVelocity(player.getLocation().getDirection().multiply(velocity)); } if (horizSpread > 0 || vertSpread > 0) { Vector v = projectile.getVelocity(); v.add( new Vector( (random.nextDouble() - .5) * horizSpread, (random.nextDouble() - .5) * vertSpread, (random.nextDouble() - .5) * horizSpread)); projectile.setVelocity(v); } if (applySpellPowerToVelocity) { projectile.setVelocity(projectile.getVelocity().multiply(power)); } projectile.setMetadata( METADATA_KEY, new FixedMetadataValue(MagicSpells.plugin, "ProjectileSpell_" + internalName)); projectiles.put( projectile, new ProjectileInfo( player, power, (effectInterval > 0 ? new RegularProjectileMonitor(projectile) : null))); playSpellEffects(EffectPosition.CASTER, projectile); } else if (projectileItem != null) { Item item = player.getWorld().dropItem(player.getEyeLocation(), projectileItem.clone()); MagicSpells.getVolatileCodeHandler().setGravity(item, projectileHasGravity); Vector v = player.getLocation().getDirection().multiply(velocity > 0 ? velocity : 1); if (horizSpread > 0 || vertSpread > 0) { v.add( new Vector( (random.nextDouble() - .5) * horizSpread, (random.nextDouble() - .5) * vertSpread, (random.nextDouble() - .5) * horizSpread)); } if (applySpellPowerToVelocity) { v.multiply(power); } item.setVelocity(v); item.setPickupDelay(10); itemProjectiles.put( item, new ProjectileInfo(player, power, new ItemProjectileMonitor(item))); playSpellEffects(EffectPosition.CASTER, item); } } return PostCastAction.HANDLE_NORMALLY; }