Skip to content

Commit

Permalink
Make shoot command sane
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Aug 12, 2013
1 parent 91010f4 commit eaca7ed
Showing 1 changed file with 131 additions and 126 deletions.
Expand Up @@ -37,193 +37,198 @@
*/

public class ShootCommand extends AbstractCommand {

@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {

for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {

if (!scriptEntry.hasObject("origin")
&& arg.matchesArgumentType(dEntity.class)
if (!scriptEntry.hasObject("origin")
&& arg.matchesPrefix("origin, o, source, shooter, s")) {
// Entity arg
scriptEntry.addObject("origin", arg.asType(dEntity.class).setPrefix("entity"));
scriptEntry.addObject("origin", arg.asElement());
}

else if (!scriptEntry.hasObject("entities")
&& arg.matchesArgumentList(dEntity.class)) {
// Entity arg
scriptEntry.addObject("entities", ((dList) arg.asType(dList.class)).filter(dEntity.class));
}


else if (!scriptEntry.hasObject("destination")
&& arg.matchesArgumentType(dLocation.class)) {
&& arg.matchesPrefix("destination, dest")) {
// Location arg
scriptEntry.addObject("destination", arg.asType(dLocation.class));
scriptEntry.addObject("destination", arg.asElement());
}

else if (!scriptEntry.hasObject("duration")
&& arg.matchesArgumentType(Duration.class)
&& arg.matchesPrefix("duration, d")) {
// Add value
scriptEntry.addObject("duration", arg.asType(Duration.class));
scriptEntry.addObject("duration", arg.asElement());
}

else if (!scriptEntry.hasObject("speed")
&& arg.matchesPrimitive(aH.PrimitiveType.Double)
&& arg.matchesPrefix("speed, s")) {
// Add value
scriptEntry.addObject("speed", arg.asElement());
}

else if (!scriptEntry.hasObject("height")
&& arg.matchesPrimitive(aH.PrimitiveType.Double)
&& arg.matchesPrefix("height, h")) {
// Add value
scriptEntry.addObject("height", arg.asElement());
}

else if (!scriptEntry.hasObject("script")
&& arg.matchesArgumentType(dScript.class)) {
&& arg.matchesPrefix("script")) {
// add value
scriptEntry.addObject("script", arg.asType(dScript.class));
scriptEntry.addObject("script", arg.asElement());
}

else if (!scriptEntry.hasObject("entities")
&& arg.matchesArgumentList(dEntity.class)) {
// Entity arg
scriptEntry.addObject("entities", ((dList) arg.asType(dList.class)).filter(dEntity.class));
}

else {
dB.echoDebug("Ignoring unrecognized argument: " + arg.getPrefixAndValue());
}
}

// Use the NPC or player's locations as the origin if one is not specified

scriptEntry.defaultObject("origin",
scriptEntry.hasNPC() ? scriptEntry.getNPC().getDenizenEntity() : null,
scriptEntry.hasPlayer() ? scriptEntry.getPlayer().getDenizenEntity() : null);

if (!scriptEntry.hasObject("origin")) {
dEntity origin = (scriptEntry.hasNPC() ? scriptEntry.getNPC().getDenizenEntity() :
(scriptEntry.hasPlayer() ? scriptEntry.getPlayer().getDenizenEntity() : null));
if (origin == null) {
throw new InvalidArgumentsException(Messages.ERROR_INVALID_ENTITY, "origin");
}
scriptEntry.addObject("origin", new Element(origin.toString()));
}

// Use a default speed of 1.5 if one is not specified

scriptEntry.defaultObject("speed", new Element(1.5));
scriptEntry.defaultObject("height", new Element(0));
scriptEntry.defaultObject("duration", Duration.valueOf("80t"));

if (!scriptEntry.hasObject("speed"))
scriptEntry.addObject("speed", new Element("1.5"));
if (!scriptEntry.hasObject("height"))
scriptEntry.addObject("height", new Element("0"));
if (!scriptEntry.hasObject("duration"))
scriptEntry.addObject("duration", new Element("80t"));
if (!scriptEntry.hasObject("script"))
scriptEntry.addObject("script", new Element("null"));

// Check to make sure required arguments have been filled

if ((!scriptEntry.hasObject("entities")))
throw new InvalidArgumentsException(Messages.ERROR_MISSING_OTHER, "entities");

if ((!scriptEntry.hasObject("origin")))
throw new InvalidArgumentsException(Messages.ERROR_MISSING_OTHER, "ORIGIN");
}

@SuppressWarnings("unchecked")
@Override
@SuppressWarnings("unchecked")
@Override
public void execute(final ScriptEntry scriptEntry) throws CommandExecutionException {
// Get objects

dEntity shooter = (dEntity) scriptEntry.getObject("origin");
LivingEntity shooterEntity = shooter.getLivingEntity();
final dLocation destination = scriptEntry.hasObject("location") ?
(dLocation) scriptEntry.getObject("location") :
new dLocation(shooterEntity.getEyeLocation().add(
shooterEntity.getEyeLocation().getDirection()
.multiply(40)));

List<dEntity> entities = (List<dEntity>) scriptEntry.getObject("entities");
final Element speed = (Element) scriptEntry.getObject("speed");
final dScript script = (dScript) scriptEntry.getObject("script");
final double height = ((Element) scriptEntry.getObject("height")).asDouble();
final int maxTicks = ((Duration) scriptEntry.getObject("duration")).getTicksAsInt() / 2;


dEntity shooter = dEntity.valueOf(scriptEntry.getElement("origin").asString());
if (shooter == null) {
throw new CommandExecutionException(Messages.ERROR_INVALID_ENTITY, "origin");
}
LivingEntity shooterEntity = shooter.getLivingEntity();
dLocation destination;
if (scriptEntry.hasObject("destination"))
destination = dLocation.valueOf(scriptEntry.getElement("destination").asString());
else {
destination = new dLocation(shooterEntity.getEyeLocation().add(shooterEntity.getEyeLocation().getDirection().multiply(40)));
dB.echoDebug("Defaulting destination.");
}

List<dEntity> entities = (List<dEntity>) scriptEntry.getObject("entities");
Element speed = scriptEntry.getElement("speed");
final dScript script = dScript.valueOf(scriptEntry.getElement("script").asString());
final double height = scriptEntry.getElement("height").asDouble();
final int maxTicks = (Duration.valueOf(scriptEntry.getElement("duration").asString())).getTicksAsInt() / 2;

// Report to dB
dB.report(getName(), aH.debugObj("origin", shooter) +
aH.debugObj("entities", entities.toString()) +
aH.debugObj("destination", destination) +
aH.debugObj("speed", speed) +
(script != null ? aH.debugObj("script", script) : ""));

aH.debugObj("entities", entities.toString()) +
aH.debugObj("destination", destination) +
aH.debugObj("height", height) +
aH.debugObj("speed", speed) +
(script != null ? aH.debugObj("script", script) : ""));

// If the shooter is an NPC, always rotate it to face the destination
// of the projectile, but if the shooter is a player, only rotate him/her
// if he/she is not looking in the correct general direction

if (shooter.isNPC() || !Rotation.isFacingLocation(shooterEntity, destination, 45))
Rotation.faceLocation(shooterEntity, destination);

if (shooter.identify().startsWith("n@") ||
Rotation.isFacingLocation(shooterEntity, destination, 45) == false) {

Rotation.faceLocation(shooterEntity, destination);
}

Location origin = shooterEntity.getEyeLocation().add(
shooterEntity.getEyeLocation().getDirection())
.subtract(0, 0.4, 0);
Location origin = shooterEntity.getEyeLocation().add(shooterEntity.getEyeLocation().getDirection()).subtract(0, 0.4, 0);

// Go through all the entities, spawning/teleporting and rotating them
for (dEntity entity : entities) {

if (entity.isSpawned() == false) {
entity.spawnAt(origin);
}
else {
entity.teleport(origin);
}

if (!entity.isSpawned())
entity.spawnAt(origin);
else
entity.teleport(origin);
Rotation.faceLocation(entity.getBukkitEntity(), destination);

if (entity.getBukkitEntity() instanceof Projectile) {
((Projectile) entity.getBukkitEntity()).setShooter(shooter.getLivingEntity());
}
if (entity.getBukkitEntity() instanceof Projectile)
((Projectile) entity.getBukkitEntity()).setShooter(shooter.getLivingEntity());
}

Position.mount(Conversion.convert(entities));

// Only use the last projectile in the task below
final Entity lastEntity = entities.get(entities.size() - 1).getBukkitEntity();
final Vector v2 = destination.toVector();
final double firespeed = speed.asDouble();

BukkitRunnable task = new BukkitRunnable() {

int runs = 0;

public void run() {

if (runs < maxTicks && lastEntity.isValid())
{
Vector v1 = lastEntity.getLocation().toVector();
Vector v2 = destination.toVector();
Vector v3 = v2.clone().subtract(v1).normalize().multiply(speed.asDouble());
lastEntity.setVelocity(v3);
runs++;
// Check if the entity is close to its destination
if (Math.abs(v2.getX() - v1.getX()) < 2 && Math.abs(v2.getY() - v1.getY()) < 2
&& Math.abs(v2.getZ() - v1.getZ()) < 2) {
runs = maxTicks;
}
// Check if the entity has collided with something
// using the most basic possible calculation
if (lastEntity.getLocation().add(v3).getBlock().getType().toString().equals("AIR") == false) {

runs = maxTicks;
}
}
else {

this.cancel();
runs = 0;
if (script != null)
{
Map<String, String> context = new HashMap<String, String>();
context.put("1", lastEntity.getLocation().getX() + "," + lastEntity.getLocation().getY() + "," + lastEntity.getLocation().getZ() + "," + lastEntity.getLocation().getWorld().getName());
context.put("2", "e@" + lastEntity.getEntityId());
int runs = 0;

public void run() {

if (runs < maxTicks && lastEntity.isValid())
{
Vector v1 = lastEntity.getLocation().toVector();
Vector v3 = v2.clone().subtract(v1).normalize().multiply(firespeed);

lastEntity.setVelocity(v3);
runs++;

// Check if the entity is close to its destination

if (Math.abs(v2.getX() - v1.getX()) < 2 && Math.abs(v2.getY() - v1.getY()) < 2
&& Math.abs(v2.getZ() - v1.getZ()) < 2) {

runs = maxTicks;
}

// Check if the entity has collided with something
// using the most basic possible calculation

if (!lastEntity.getLocation().add(v3).getBlock().getType().toString().equals("AIR")) {

runs = maxTicks;
}
}
else {

this.cancel();
runs = 0;

if (script != null)
{
Map<String, String> context = new HashMap<String, String>();
context.put("1", lastEntity.getLocation().getX() + "," + lastEntity.getLocation().getY() + "," +
lastEntity.getLocation().getZ() + "," + lastEntity.getLocation().getWorld().getName());
context.put("2", "e@" + lastEntity.getEntityId());

((TaskScriptContainer) script.getContainer()).setSpeed(new Duration(0))
.runTaskScript(scriptEntry.getPlayer(), scriptEntry.getNPC(), context);
}
}
}
};
.runTaskScript(scriptEntry.getPlayer(), scriptEntry.getNPC(), context);
}

}
}
};

task.runTaskTimer(denizen, 0, 2);
task.runTaskTimer(denizen, 0, 2);
}

}
}

0 comments on commit eaca7ed

Please sign in to comment.