Search in sources :

Example 31 with LivingEntity

use of org.bukkit.entity.LivingEntity in project MagicPlugin by elBukkit.

the class EntityMageData method tick.

public void tick(Mage mage) {
    List<MageTrigger> intervalTriggers = getTriggers(MageTriggerType.INTERVAL);
    if (intervalTriggers == null)
        return;
    Entity entity = mage.getLivingEntity();
    Creature creature = (entity instanceof Creature) ? (Creature) entity : null;
    if (requiresTarget && (creature == null || creature.getTarget() == null))
        return;
    if (requiresWand != null && entity instanceof LivingEntity) {
        LivingEntity li = (LivingEntity) entity;
        ItemStack itemInHand = li.getEquipment().getItemInMainHand();
        if (itemInHand == null || itemInHand.getType() != requiresWand.getType())
            return;
    }
    for (MageTrigger trigger : intervalTriggers) {
        trigger.execute(mage);
    }
}
Also used : LivingEntity(org.bukkit.entity.LivingEntity) Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) Creature(org.bukkit.entity.Creature) ItemStack(org.bukkit.inventory.ItemStack) MageTrigger(com.elmakers.mine.bukkit.magic.MageTrigger)

Example 32 with LivingEntity

use of org.bukkit.entity.LivingEntity in project MagicPlugin by elBukkit.

the class PotionEffectAction method perform.

@Override
public SpellResult perform(CastContext context) {
    Entity entity = context.getTargetEntity();
    if (!(entity instanceof LivingEntity)) {
        return SpellResult.NO_TARGET;
    }
    LivingEntity targetEntity = (LivingEntity) entity;
    context.registerPotionEffects(targetEntity);
    boolean effected = false;
    if (addEffects != null && addEffects.size() > 0) {
        effected = true;
        CompatibilityUtils.applyPotionEffects(targetEntity, addEffects);
    }
    if (removeEffects != null) {
        Collection<PotionEffect> currentEffects = targetEntity.getActivePotionEffects();
        for (PotionEffect effect : currentEffects) {
            PotionEffectType removeType = effect.getType();
            if (removeEffects.contains(removeType) && effect.getDuration() < Integer.MAX_VALUE / 4) {
                targetEntity.removePotionEffect(removeType);
                effected = true;
            }
        }
    }
    return effected ? SpellResult.CAST : SpellResult.NO_TARGET;
}
Also used : LivingEntity(org.bukkit.entity.LivingEntity) Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) PotionEffect(org.bukkit.potion.PotionEffect) PotionEffectType(org.bukkit.potion.PotionEffectType)

Example 33 with LivingEntity

use of org.bukkit.entity.LivingEntity in project MagicPlugin by elBukkit.

the class ProjectileAction method start.

@Override
public SpellResult start(CastContext context) {
    MageController controller = context.getController();
    Mage mage = context.getMage();
    // Modify with wand power
    // Turned some of this off for now
    // int count = this.count * mage.getRadiusMultiplier();
    // int speed = this.speed * damageMultiplier;
    int size = (int) (mage.getRadiusMultiplier() * this.size);
    double damageMultiplier = mage.getDamageMultiplier("projectile");
    double damage = damageMultiplier * this.damage;
    float radiusMultiplier = mage.getRadiusMultiplier();
    float spread = this.spread;
    if (radiusMultiplier > 1) {
        spread = spread / radiusMultiplier;
    }
    Random random = context.getRandom();
    Class<?> projectileType = NMSUtils.getBukkitClass("net.minecraft.server.Entity" + projectileTypeName);
    if (!CompatibilityUtils.isValidProjectileClass(projectileType)) {
        controller.getLogger().warning("Bad projectile class: " + projectileTypeName);
        return SpellResult.FAIL;
    }
    // Prepare parameters
    Location location = sourceLocation.getLocation(context);
    Vector direction = location.getDirection();
    if (startDistance > 0) {
        location = location.clone().add(direction.clone().multiply(startDistance));
    }
    // Spawn projectiles
    LivingEntity shootingEntity = context.getLivingEntity();
    ProjectileSource source = null;
    if (shootingEntity != null) {
        source = shootingEntity;
    }
    for (int i = 0; i < count; i++) {
        try {
            // Spawn a new projectile
            Projectile projectile = CompatibilityUtils.spawnProjectile(projectileType, location, direction, source, speed, spread, i > 0 ? spread : 0, random);
            if (projectile == null) {
                return SpellResult.FAIL;
            }
            if (shootingEntity != null) {
                projectile.setShooter(shootingEntity);
            }
            if (projectile instanceof Fireball) {
                Fireball fireball = (Fireball) projectile;
                fireball.setIsIncendiary(useFire);
                fireball.setYield(size);
            }
            if (projectile instanceof Arrow) {
                Arrow arrow = (Arrow) projectile;
                if (useFire) {
                    arrow.setFireTicks(300);
                }
                if (damage > 0) {
                    CompatibilityUtils.setDamage(projectile, damage);
                }
                if (tickIncrease > 0) {
                    CompatibilityUtils.decreaseLifespan(projectile, tickIncrease);
                }
                if (pickupStatus != null && !pickupStatus.isEmpty()) {
                    CompatibilityUtils.setPickupStatus(arrow, pickupStatus);
                }
            }
            if (!breakBlocks) {
                projectile.setMetadata("cancel_explosion", new FixedMetadataValue(controller.getPlugin(), true));
            }
            track(context, projectile);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    return checkTracking(context);
}
Also used : Arrow(org.bukkit.entity.Arrow) FixedMetadataValue(org.bukkit.metadata.FixedMetadataValue) Projectile(org.bukkit.entity.Projectile) LivingEntity(org.bukkit.entity.LivingEntity) MageController(com.elmakers.mine.bukkit.api.magic.MageController) Fireball(org.bukkit.entity.Fireball) Random(java.util.Random) Mage(com.elmakers.mine.bukkit.api.magic.Mage) ProjectileSource(org.bukkit.projectiles.ProjectileSource) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location) SourceLocation(com.elmakers.mine.bukkit.magic.SourceLocation)

Example 34 with LivingEntity

use of org.bukkit.entity.LivingEntity in project MagicPlugin by elBukkit.

the class RepairItemAction method perform.

@Override
public SpellResult perform(CastContext context) {
    Entity entity = context.getTargetEntity();
    if (entity instanceof LivingEntity && (armor || heldItem)) {
        boolean repaired = false;
        LivingEntity li = (LivingEntity) entity;
        EntityEquipment equipment = li.getEquipment();
        if (equipment == null) {
            return SpellResult.NO_TARGET;
        }
        if (armor) {
            ItemStack item = equipment.getHelmet();
            repaired = repair(context, item) || repaired;
            item = equipment.getChestplate();
            repaired = repair(context, item) || repaired;
            item = equipment.getLeggings();
            repaired = repair(context, item) || repaired;
            item = equipment.getBoots();
            repaired = repair(context, item) || repaired;
        }
        if (heldItem) {
            ItemStack item = equipment.getItemInMainHand();
            repaired = repair(context, item) || repaired;
        }
        return repaired ? SpellResult.CAST : SpellResult.NO_TARGET;
    }
    if (entity == null || !(entity instanceof Item)) {
        return SpellResult.NO_TARGET;
    }
    Item item = (Item) entity;
    ItemStack itemStack = item.getItemStack();
    return repair(context, itemStack) ? SpellResult.CAST : SpellResult.NO_TARGET;
}
Also used : LivingEntity(org.bukkit.entity.LivingEntity) Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) Item(org.bukkit.entity.Item) EntityEquipment(org.bukkit.inventory.EntityEquipment) ItemStack(org.bukkit.inventory.ItemStack)

Example 35 with LivingEntity

use of org.bukkit.entity.LivingEntity in project MagicPlugin by elBukkit.

the class CustomProjectileAction method step.

@Override
public SpellResult step(CastContext context) {
    long now = System.currentTimeMillis();
    if (now < nextUpdate) {
        return SpellResult.PENDING;
    }
    if (attachedDeadline > 0) {
        Entity targetEntity = actionContext.getTargetEntity();
        if (attachedOffset != null && targetEntity != null) {
            Location targetLocation = targetEntity.getLocation();
            targetLocation.add(attachedOffset);
            actionContext.setTargetLocation(targetLocation);
            if (effectLocation != null) {
                effectLocation.updateFrom(targetLocation);
            }
        }
        if (now > attachedDeadline) {
            return finishAttach();
        }
        return SpellResult.PENDING;
    }
    if (now > deadline) {
        return miss();
    }
    if (targetSelfDeadline > 0 && now > targetSelfDeadline && actionContext != null) {
        targetSelfDeadline = 0;
        actionContext.setTargetsCaster(true);
    }
    nextUpdate = now + interval;
    // Check for initialization required
    // TODO: Move this to start()?
    Location projectileLocation = null;
    if (velocity == null) {
        projectileLocation = sourceLocation.getLocation(context).clone();
        /* This feels confusing however...
             * Looking straight down in Minecraft gives a pitch of 90
             * While looking straight up is a pitch of -90
             * We don't want to normalize these values as other functions need the non-normalize numbers.
             * So if the projectile pitch value is found to be higher or lower than the min or max, it's set to the min or max respectively
             */
        if (pitchMin < projectileLocation.getPitch()) {
            projectileLocation.setPitch(pitchMin);
        } else if (pitchMax > projectileLocation.getPitch()) {
            projectileLocation.setPitch(pitchMax);
        }
        launchLocation = projectileLocation.clone();
        velocity = projectileLocation.getDirection().clone().normalize();
        if (spread > 0) {
            Random random = context.getRandom();
            velocity.setX(velocity.getX() + (random.nextDouble() * spread - spread / 2));
            velocity.setY(velocity.getY() + (random.nextDouble() * spread - spread / 2));
            velocity.setZ(velocity.getZ() + (random.nextDouble() * spread - spread / 2));
            velocity.normalize();
        }
        if (startDistance != 0) {
            projectileLocation.add(velocity.clone().multiply(startDistance));
        }
        if (reverseDirection) {
            velocity = velocity.multiply(-1);
        }
        projectileLocation.setDirection(velocity);
        actionContext.setTargetLocation(projectileLocation);
        actionContext.setTargetEntity(null);
        actionContext.setDirection(velocity);
        // Start up projectile FX
        startProjectileEffects(context, projectileEffectKey);
        context.getMage().sendDebugMessage(ChatColor.BLUE + "Projectile launched from " + ChatColor.GRAY + projectileLocation.toVector() + ChatColor.BLUE, 7);
    } else {
        projectileLocation = actionContext.getTargetLocation();
        if (effectLocation != null) {
            effectLocation.updateFrom(projectileLocation);
            effectLocation.setDirection(velocity);
        }
    }
    // Check plan
    if (plan != null && !plan.isEmpty()) {
        PlanStep next = plan.peek();
        if ((next.distance > 0 && distanceTravelled > next.distance) || (next.time > 0 && flightTime > next.time) || (next.returnBuffer > 0 && returnDistanceAway != null && returnDistanceAway < next.returnBuffer)) {
            plan.remove();
            if (next.parameters != null) {
                modifyParameters(next.parameters);
            }
            if (next.effectsKey != null) {
                startProjectileEffects(context, next.effectsKey);
            }
            context.getMage().sendDebugMessage("Changing flight plan at distance " + ((int) distanceTravelled) + " and time " + flightTime, 4);
            if (resetTimeOnPathChange) {
                flightTime = 0;
            }
        }
    }
    if (updateLaunchLocation) {
        launchLocation = context.getCastLocation().clone();
    }
    // Advance position
    // We default to 50 ms travel time (one tick) for the first iteration.
    long delta = lastUpdate > 0 ? now - lastUpdate : 50;
    lastUpdate = now;
    flightTime += delta;
    // Apply gravity, drag or other velocity modifiers
    Vector targetVelocity = null;
    if (trackEntity) {
        Entity targetEntity = context.getTargetEntity();
        if (targetEntity != null && targetEntity.isValid() && context.canTarget(targetEntity)) {
            Location targetLocation = targetEntity instanceof LivingEntity ? ((LivingEntity) targetEntity).getEyeLocation() : targetEntity.getLocation();
            targetVelocity = targetLocation.toVector().subtract(projectileLocation.toVector()).normalize();
        }
    } else if (trackCursorRange > 0) {
        /* We need to first find out where the player is looking and multiply it by how far the player wants the whip to extend
             * Finally after all that, we adjust the velocity of the projectile to go towards the cursor point
             */
        Vector playerCursor = context.getMage().getDirection().clone().normalize();
        Vector targetPoint = playerCursor.multiply(trackCursorRange);
        Vector worldPoint = targetPoint.add(context.getMage().getEyeLocation().clone().toVector());
        Vector projectileOffset = worldPoint.subtract(projectileLocation.clone().toVector());
        targetVelocity = projectileOffset.normalize();
    } else if (reorient) {
        targetVelocity = context.getMage().getDirection().clone().normalize();
    } else {
        if (gravity > 0) {
            // Reduce / change speed based on gravity
            velocity.normalize().multiply(speed);
            velocity.setY(velocity.getY() - gravity * delta / 50);
            speed = velocity.length();
            velocity.normalize();
        }
        if (drag > 0) {
            speed -= drag * delta / 50;
            if (speed <= 0) {
                return miss();
            }
        }
    }
    if (targetVelocity != null) {
        if (trackSpeed > 0) {
            double steerDistanceSquared = trackSpeed * trackSpeed;
            double distanceSquared = targetVelocity.distanceSquared(velocity);
            if (distanceSquared <= steerDistanceSquared) {
                velocity = targetVelocity;
            } else {
                Vector targetDirection = targetVelocity.subtract(velocity).normalize().multiply(steerDistanceSquared);
                velocity.add(targetDirection);
            }
        } else {
            velocity = targetVelocity;
        }
        launchLocation.setDirection(velocity);
    }
    if (velocityTransform != null) {
        targetVelocity = velocityTransform.get(launchLocation, (double) flightTime / 1000);
        // with targeting and range-checking
        if (targetVelocity != null) {
            speed = targetVelocity.length();
            if (speed > 0) {
                targetVelocity.normalize();
            } else {
                targetVelocity.setX(1);
            }
            velocity = targetVelocity;
        }
    }
    if (returnToCaster) {
        Vector targetLocation = context.getMage().getEyeLocation().toVector();
        if (returnOffset != null) {
            targetLocation.add(returnOffset);
        }
        if (returnRelativeOffset != null) {
            Vector relativeOffset = VectorUtils.rotateVector(returnRelativeOffset, context.getMage().getEyeLocation());
            targetLocation.add(relativeOffset);
        }
        Vector projectileOffset = targetLocation.clone().subtract(projectileLocation.toVector());
        returnDistanceAway = projectileOffset.length();
        velocity = projectileOffset.normalize();
    }
    if (projectileFollowPlayer) {
        Vector currentLocation = context.getMage().getLocation().toVector();
        if (previousLocation != null) {
            Vector offset = currentLocation.clone().subtract(previousLocation);
            previousLocation = currentLocation;
            velocity = velocity.add(offset);
        } else {
            previousLocation = currentLocation;
        }
    }
    projectileLocation.setDirection(velocity);
    // Advance targeting to find Entity or Block
    distanceTravelledThisTick = speed * delta / 1000;
    if (range > 0) {
        distanceTravelledThisTick = Math.min(distanceTravelledThisTick, range - distanceTravelled);
    }
    context.addWork((int) Math.ceil(distanceTravelledThisTick));
    Location targetLocation;
    Targeting.TargetingResult targetingResult = Targeting.TargetingResult.MISS;
    Target target = null;
    if (!ignoreTargeting) {
        targeting.start(projectileLocation);
        target = targeting.target(actionContext, distanceTravelledThisTick);
        targetingResult = targeting.getResult();
        targetLocation = target.getLocation();
        boolean keepGoing = distanceTravelled < minRange;
        Location tempLocation = projectileLocation.clone();
        int checkIterations = 0;
        while (keepGoing) {
            // TODO if all of these distance() calls are necessary, they should be optimized to distanceSquared()
            if (targetingResult == Targeting.TargetingResult.MISS) {
                keepGoing = false;
            } else if (targetingResult != null && targetLocation.distance(projectileLocation) + distanceTravelled >= minRange) {
                keepGoing = false;
            } else if (targetLocation.distance(projectileLocation) + distanceTravelled >= minEntityRange && targetingResult == Targeting.TargetingResult.ENTITY) {
                keepGoing = false;
            } else if (targetLocation.distance(projectileLocation) + distanceTravelled >= minBlockRange && targetingResult == Targeting.TargetingResult.BLOCK) {
                keepGoing = false;
            } else if (targetLocation.distance(projectileLocation) >= distanceTravelledThisTick) {
                keepGoing = false;
            } else if (checkIterations > 1000) {
                keepGoing = false;
            } else {
                if (tempLocation.distance(projectileLocation) < targetLocation.distance(projectileLocation)) {
                    tempLocation.add(velocity.clone().multiply(targetLocation.distance(projectileLocation) + 0.1));
                } else {
                    tempLocation.add(velocity.clone().multiply(0.2));
                }
                actionContext.setTargetLocation(tempLocation);
                actionContext.setTargetEntity(null);
                actionContext.setDirection(velocity);
                // TODO: This whole procedure, particularly retargeting, is going to be very costly
                // This is hopefully an easier way
                targeting.start(tempLocation);
                target = targeting.target(actionContext, distanceTravelledThisTick - tempLocation.distance(projectileLocation));
                targetingResult = targeting.getResult();
                targetLocation = target.getLocation();
                checkIterations++;
            }
        }
    }
    if (targetingResult == Targeting.TargetingResult.MISS) {
        if (hasBlockMissEffects && target != null) {
            actionContext.setTargetLocation(target.getLocation());
            actionContext.playEffects("blockmiss");
        }
        targetLocation = projectileLocation.clone().add(velocity.clone().multiply(distanceTravelledThisTick));
        context.getMage().sendDebugMessage(ChatColor.DARK_BLUE + "Projectile miss: " + ChatColor.DARK_PURPLE + " at " + targetLocation.getBlock().getType() + " : " + targetLocation.toVector() + " from range of " + distanceTravelledThisTick + " over time " + delta, 14);
    } else {
        if (hasPreHitEffects) {
            actionContext.playEffects("prehit");
        }
        targetLocation = target.getLocation();
        // Debugging
        if (targetLocation == null) {
            targetLocation = projectileLocation;
            context.getLogger().warning("Targeting hit, with no target location: " + targetingResult + " with " + targeting.getTargetType() + " from " + context.getSpell().getName());
        }
        context.getMage().sendDebugMessage(ChatColor.BLUE + "Projectile hit: " + ChatColor.LIGHT_PURPLE + targetingResult.name().toLowerCase() + ChatColor.BLUE + " at " + ChatColor.GOLD + targetLocation.getBlock().getType() + ChatColor.BLUE + " from " + ChatColor.GRAY + projectileLocation.getBlock() + ChatColor.BLUE + " to " + ChatColor.GRAY + targetLocation.toVector() + ChatColor.BLUE + " from range of " + ChatColor.GOLD + distanceTravelledThisTick + ChatColor.BLUE + " over time " + ChatColor.DARK_PURPLE + delta, 8);
        distanceTravelledThisTick = targetLocation.distance(projectileLocation);
    }
    distanceTravelled += distanceTravelledThisTick;
    effectDistanceTravelled += distanceTravelledThisTick;
    // Max Height check
    int y = targetLocation.getBlockY();
    boolean maxHeight = y >= targetLocation.getWorld().getMaxHeight();
    boolean minHeight = y <= 0;
    if (maxHeight) {
        targetLocation.setY(targetLocation.getWorld().getMaxHeight());
    } else if (minHeight) {
        targetLocation.setY(0);
    }
    if (hasTickEffects && effectDistanceTravelled > tickSize) {
        // Sane limit here
        Vector speedVector = velocity.clone().multiply(tickSize);
        for (int i = 0; i < 256; i++) {
            actionContext.setTargetLocation(projectileLocation);
            actionContext.playEffects(tickEffectKey);
            projectileLocation.add(speedVector);
            effectDistanceTravelled -= tickSize;
            if (effectDistanceTravelled < tickSize)
                break;
        }
    }
    actionContext.setTargetLocation(targetLocation);
    if (target != null) {
        actionContext.setTargetEntity(target.getEntity());
    }
    if (hasStepEffects) {
        actionContext.playEffects("step");
    }
    if (maxHeight || minHeight) {
        return miss();
    }
    if (range > 0 && distanceTravelled >= range) {
        return miss();
    }
    Block block = targetLocation.getBlock();
    if (!block.getChunk().isLoaded()) {
        return miss();
    }
    if (distanceTravelled < minRange && targetingResult != null) {
        // TODO : Should this be < ?
        if (distanceTravelled >= minBlockRange && targetingResult == Targeting.TargetingResult.BLOCK) {
            return miss();
        }
        if (distanceTravelled >= minEntityRange && targetingResult == Targeting.TargetingResult.ENTITY) {
            return miss();
        }
    } else if (targetingResult == Targeting.TargetingResult.BLOCK) {
        return hitBlock(block);
    } else if (targetingResult == Targeting.TargetingResult.ENTITY) {
        return hitEntity(target);
    }
    if (hasTickActions) {
        return startActions("tick");
    }
    return SpellResult.PENDING;
}
Also used : Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) Targeting(com.elmakers.mine.bukkit.utility.Targeting) LivingEntity(org.bukkit.entity.LivingEntity) Target(com.elmakers.mine.bukkit.utility.Target) Random(java.util.Random) Block(org.bukkit.block.Block) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location) SourceLocation(com.elmakers.mine.bukkit.magic.SourceLocation) DynamicLocation(de.slikey.effectlib.util.DynamicLocation)

Aggregations

LivingEntity (org.bukkit.entity.LivingEntity)324 Entity (org.bukkit.entity.Entity)170 Player (org.bukkit.entity.Player)123 Location (org.bukkit.Location)72 EventHandler (org.bukkit.event.EventHandler)64 Vector (org.bukkit.util.Vector)60 ItemStack (org.bukkit.inventory.ItemStack)47 ArrayList (java.util.ArrayList)41 ISoliniaLivingEntity (com.solinia.solinia.Interfaces.ISoliniaLivingEntity)37 PotionEffect (org.bukkit.potion.PotionEffect)34 CoreStateInitException (com.solinia.solinia.Exceptions.CoreStateInitException)30 Block (org.bukkit.block.Block)24 Mage (com.elmakers.mine.bukkit.api.magic.Mage)22 Projectile (org.bukkit.entity.Projectile)20 BukkitRunnable (org.bukkit.scheduler.BukkitRunnable)18 FixedMetadataValue (org.bukkit.metadata.FixedMetadataValue)17 ISoliniaPlayer (com.solinia.solinia.Interfaces.ISoliniaPlayer)16 Target (com.elmakers.mine.bukkit.utility.Target)15 World (org.bukkit.World)14 Creature (org.bukkit.entity.Creature)14