Have this sitting on desktop for a while, old code. Some things could be better like getting the next rotation. It's object oriented so a player can run multiple cannons at once.. Use the code for revision, resource, or make it work for yourself. Enjoy..
Code:
package com.elvarg.game.content;
import java.util.ArrayList;
import java.util.List;
import com.elvarg.game.entity.impl.object.GameObject;
import com.elvarg.game.entity.impl.object.ObjectManager;
import com.elvarg.game.entity.impl.object.impl.DwarfMultiCannon;
import com.elvarg.game.entity.impl.player.Player;
import com.elvarg.game.model.Animation;
import com.elvarg.game.model.Item;
import com.elvarg.game.model.Position;
import com.elvarg.game.model.container.impl.Bank;
import com.elvarg.game.task.Task;
import com.elvarg.game.task.TaskManager;
/**
* Handles the dwarf cannon
*
* @author 2012 <https://www.rune-server.ee/members/dexter+morgan/>
*
* TODO: Picking up separate cannon pieces
* TODO: Clipped projectiles
*
*/
public class DwarfCannon {
/**
* All the cannons
*/
private static List<DwarfMultiCannon> cannons = new ArrayList<DwarfMultiCannon>();
/**
* The build animation
*/
private static final Animation BUILD = new Animation(827);
/**
* The cannon ids
*/
private static final Item[] CANNON = { new Item(6), new Item(8), new Item(10), new Item(12) };
/**
* The cannon parts
*/
private static final int[] CANNON_PARTS = { 7, 8, 9, 6 };
/**
* Distance to build
*/
private static final int DISTANCE_TO_BUILD = 5;
/**
* Set up a cannon for the player and add the cannon to the list of active
* cannons.
*/
public static void setup(Player player) {
/*
* The cannon
*/
DwarfMultiCannon cannon = forUser(player.getUsername());
/*
* Has cannon
*/
if (cannon != null) {
player.sendMessage("You already have a cannon setup");
// return;
}
/*
* Cant build
*/
for (GameObject other : cannons) {
if (other.getPosition().getDistance(player.getPosition()) < DISTANCE_TO_BUILD) {
player.sendMessage("You are trying to build too close to another cannon");
// return;
}
}
/*
* Check items
*/
if (!player.getInventory().contains(CANNON)) {
player.getPacketSender().sendMessage("You don't have all the components to build the cannon.");
return;
}
/*
* Reset movement
*/
player.getMovementQueue().reset();
player.getMovementQueue().resetFollowing();
/*
* The building position
*/
Position buildingPosition = player.getPosition().clone();
/*
* The base
*/
player.setPositionToFace(buildingPosition);
/*
* The dwarf cannon
*/
DwarfMultiCannon componenet = new DwarfMultiCannon(player.getUsername(), 6, buildingPosition);
cannons.add(componenet);
/*
* The building
*/
TaskManager.submit(new Task(1) {
/*
* The ticks
*/
int tick = 0;
/*
* The components
*/
int components = 0;
@Override
protected void execute() {
/*
* Finished
*/
if (tick >= 12) {
stop();
return;
}
/*
* New cannon piece
*/
DwarfMultiCannon componenet = new DwarfMultiCannon(player.getUsername(), CANNON_PARTS[components],
buildingPosition);
/*
* Build
*/
if (tick % 3 == 0) {
player.performAnimation(BUILD);
}
/*
* Add
*/
if (tick % 3 == 1) {
/*
* Delete piece
*/
player.getInventory().delete(CANNON[components]);
/*
* Add object
*/
ObjectManager.register(componenet, true);
components++;
}
tick++;
}
});
}
/**
* Picking up the cannon
*
* @param player
* the player
* @param object
* the object
*/
public static void pickup(Player player, GameObject object) {
DwarfMultiCannon cannon = forId(object);
if (cannon == null) {
return;
}
if (!cannon.getOwner().equalsIgnoreCase(player.getUsername())) {
player.getPacketSender().sendMessage("This isn't your cannon.");
return;
}
player.performAnimation(BUILD);
if (cannon.getTask() != null) {
cannon.getTask().stop();
}
ObjectManager.deregister(cannon, true);
for (Item item : CANNON) {
if (player.getInventory().getFreeSlots() < 1) {
player.getBank(Bank.getTabForItem(player, item.getId())).add(item);
player.getPacketSender().sendMessage(item.getDefinition().getName() + " has been sent to your bank.");
} else {
player.getInventory().add(item);
}
}
Item balls = new Item(2, cannon.getBalls());
if (player.getInventory().getFreeSlots() < 1) {
player.getBank(Bank.getTabForItem(player, 2)).add(balls);
player.getPacketSender().sendMessage(balls.getDefinition().getName() + " has been sent to your bank.");
} else {
player.getInventory().add(balls);
}
}
/**
* The dwarf cannon shooting
*
* @param player
* the player
* @param object
* the cannon
*/
public static void shoot(Player player, GameObject object) {
/*
* The cannon
*/
DwarfMultiCannon cannon = forPosition(object.getPosition());
/*
* No cannon
*/
if (cannon == null) {
player.getPacketSender().sendMessage("Invalid cannon");
return;
}
/*
* Not cannon
*/
if (!cannon.getOwner().equalsIgnoreCase(player.getUsername())) {
player.getPacketSender().sendMessage("This isn't your cannon.");
return;
}
/*
* The balls to add
*/
int ballsToAdd = 30 - cannon.getBalls();
/*
* The existing amount
*/
int ballsAmount = player.getInventory().getAmount(2);
/*
* Fixing amount
*/
if (ballsToAdd > ballsAmount) {
ballsToAdd = ballsAmount;
}
/*
* No balls
*/
if (ballsToAdd == 0) {
/*
* Doesnt have any
*/
if (ballsAmount == 0) {
player.getPacketSender().sendMessage("You need some cannon balls to fire a cannon.");
return;
}
player.getPacketSender().sendMessage("You cannot add anymore cannon balls to your cannon.");
return;
}
/*
* Adds balls to cannon
*/
player.getInventory().delete(new Item(2, ballsToAdd));
cannon.setBalls(cannon.getBalls() + ballsToAdd);
/*
* Added
*/
player.getPacketSender()
.sendMessage("Cannon balls: " + cannon.getBalls() + " " + (ballsToAdd > 0 ? "+ " + ballsToAdd : ""));
/*
* Already shooting
*/
if (cannon.isShooting()) {
return;
}
/*
* Start shooting
*/
cannon.setShooting(true);
cannon.setTask(new Task(1) {
@Override
protected void execute() {
/*
* No ball
*/
if (cannon.getBalls() == 0) {
player.getPacketSender().sendMessage("Your cannon has ran out of cannon balls.");
cannon.setShooting(false);
stop();
return;
}
/*
* Rotate
*/
cannon.rotate();
/*
* Fire
*/
cannon.fire();
/*
* Decay timer
*/
if (System.currentTimeMillis() - cannon.getTime() > 60_000 * 20 && !cannon.isDecayWarning()) {
cannon.setDecayWarning(true);
player.getPacketSender().sendMessage("Your cannnon has almost decayed!");
} else if (System.currentTimeMillis() - cannon.getTime() > 60_000 * 25 && cannon.isDecayWarning()) {
ObjectManager.deregister(cannon, true);
player.getPacketSender().sendMessage("Your cannnon has fully decayed!");
stop();
}
}
});
TaskManager.submit(cannon.getTask());
}
/**
* Gets the cannon by id
*
* @param object
* the object
* @return the cannon
*/
private static DwarfMultiCannon forId(GameObject object) {
for (DwarfMultiCannon cannon : cannons) {
if (cannon == null) {
continue;
}
if (cannon.getId() == object.getId()) {
return cannon;
}
}
return null;
}
/**
* Gets the cannon by position
*
* @param position
* the position
* @return the cannon
*/
private static DwarfMultiCannon forPosition(Position position) {
for (DwarfMultiCannon cannon : cannons) {
if (cannon == null) {
continue;
}
if (cannon.getPosition().sameAs(position)) {
return cannon;
}
}
return null;
}
/**
* Gets the cannon by user
*
* @param user
* the user
* @return the cannon
*/
private static DwarfMultiCannon forUser(String user) {
for (DwarfMultiCannon cannon : cannons) {
if (cannon == null) {
continue;
}
if (cannon.getOwner().equals(user)) {
return cannon;
}
}
return null;
}
/**
* Gets the cannons
*
* @return the cannons
*/
public List<DwarfMultiCannon> getCannons() {
return cannons;
}
}
Code:
package com.elvarg.game.entity.impl.object.impl;
import java.util.ArrayList;
import java.util.Optional;
import com.elvarg.game.World;
import com.elvarg.game.content.combat.CombatFactory;
import com.elvarg.game.content.combat.hit.HitDamage;
import com.elvarg.game.content.combat.hit.HitMask;
import com.elvarg.game.content.combat.hit.PendingHit;
import com.elvarg.game.entity.impl.npc.NPC;
import com.elvarg.game.entity.impl.object.GameObject;
import com.elvarg.game.entity.impl.player.Player;
import com.elvarg.game.model.Animation;
import com.elvarg.game.model.Position;
import com.elvarg.game.model.Projectile;
import com.elvarg.game.model.Skill;
import com.elvarg.game.task.Task;
import com.elvarg.game.task.TaskManager;
import com.elvarg.util.Misc;
/**
* Represents the dwarf multi cannon
*
* @author 2012 <https://www.rune-server.ee/members/dexter+morgan/>
*
*/
public class DwarfMultiCannon extends GameObject {
/**
* Rotations
*/
public enum Rotation {
NORTH(new Animation(516)),
NORTH_EAST(new Animation(517)),
EAST(new Animation(518)),
SOUTH_EAST(new Animation(519)),
SOUTH(new Animation(520)),
SOUTH_WEST(new Animation(521)),
WEST(new Animation(514)),
NORTH_WEST(new Animation(515)),
;
/**
* The animation
*/
private Animation animation;
/**
* Represents a rotation of a cannon
*
* @param animation
* the animation
*/
Rotation(Animation animation) {
this.setAnimation(animation);
}
/**
* Sets the animation
*
* @return the animation
*/
public Animation getAnimation() {
return animation;
}
/**
* Sets the animation
*
* @param animation
* the animation
*/
public void setAnimation(Animation animation) {
this.animation = animation;
}
}
/**
* The max damage
*/
public static final int MAX_DAMAGE = 30;
/**
* The max range
*/
private static final int MAX_RANGE = 8;
/**
* The time
*/
private long time;
/**
* The owner
*/
private String owner;
/**
* Whether shooting
*/
private boolean shooting;
/**
* The balls
*/
private int balls;
/**
* The task
*/
private Task task;
/**
* The rotation
*/
private Rotation rotation;
/**
* Sent the decay warning
*/
private boolean decayWarning;
/**
* The dwarf multi cannon
*
* @param spawnedFor
* the spawned for
* @param id
* the id
* @param position
* the position
*/
public DwarfMultiCannon(String owner, int id, Position position) {
super(id, position);
this.setOwner(owner);
this.setTime(System.currentTimeMillis());
this.setShooting(false);
this.setBalls(0);
this.setTask(null);
this.setRotation(Rotation.NORTH);
this.setDecayWarning(false);
}
/**
* The cannon rotating
*/
public void rotate() {
switch (rotation) {
case NORTH:
rotation = Rotation.NORTH_EAST;
break;
case NORTH_EAST:
rotation = Rotation.EAST;
break;
case EAST:
rotation = Rotation.SOUTH_EAST;
break;
case SOUTH_EAST:
rotation = Rotation.SOUTH;
break;
case SOUTH:
rotation = Rotation.SOUTH_WEST;
break;
case SOUTH_WEST:
rotation = Rotation.WEST;
break;
case WEST:
rotation = Rotation.NORTH_WEST;
break;
case NORTH_WEST:
rotation = Rotation.NORTH;
break;
}
performAnimation(rotation.getAnimation());
}
/**
* The dwarf cannon firing
*
* @param cannon
* the cannon
*/
public void fire() {
/*
* The shots fired
*/
int shots = 0;
/*
* Loop through targets
*/
for (NPC npc : getTargets(this)) {
/*
* Invalid target
*/
if (npc == null) {
continue;
}
/*
* Possible two shot
*/
if (shots > 1) {
return;
}
/*
* Shots fired
*/
shots++;
/*
* First hit
*/
sendHit(npc);
/*
* Possible double hit
*/
if (Misc.getRandom(3) == 1) {
TaskManager.submit(new Task(1) {
@Override
protected void execute() {
sendHit(npc);
stop();
}
});
}
}
}
/**
* Sending hit to npc
*
* @param npc
* the npc
*/
private void sendHit(NPC npc) {
/*
* No balls
*/
if (getBalls() == 0) {
return;
}
/*
* Send projectile
*/
new Projectile(this, npc, 53, 0, 30, 20, 20, 32).sendProjectile();
/*
* The attacker
*/
Optional<Player> attacker = World.getPlayerByName(getOwner());
/*
* Deduct cannon ball
*/
setBalls(getBalls() - 1);
/*
* Adds damage
*/
if (attacker.isPresent()) {
PendingHit hit = new PendingHit(attacker.get(), npc);
attacker.get().getSkillManager().addExperience(Skill.RANGED, hit.getTotalDamage() * 4);
npc.getCombat().getHitQueue().addPendingHit(hit);
} else {
int damage = Misc.getRandom(MAX_DAMAGE);
npc.getCombat().getHitQueue()
.addPendingDamage(new HitDamage(damage, damage > 0 ? HitMask.RED : HitMask.BLUE));
}
}
/**
* Gets the targets
*
* @param cannon
* the cannon
* @return the targets
*/
private ArrayList<NPC> getTargets(DwarfMultiCannon cannon) {
/*
* The targets
*/
ArrayList<NPC> targets = new ArrayList<NPC>();
/*
* The local npcs
*/
for (NPC local : getLocalNpcs(cannon)) {
/*
* Invalid
*/
if (local == null) {
continue;
}
/*
* Non attackable
*/
if (!local.getDefinition().isAttackable()) {
continue;
}
/*
* Too far
*/
if (cannon.getPosition().getDistance(local.getPosition()) > MAX_RANGE) {
continue;
}
/*
* Dead
*/
if (World.getPlayerByName(getOwner()).isPresent()) {
if (!CombatFactory.validTarget(World.getPlayerByName(getOwner()).get(), local)) {
continue;
}
}
/*
* The cannon x
*/
int cannonX = cannon.getPosition().getX();
/*
* The cannon y
*/
int cannonY = cannon.getPosition().getY();
/*
* The local npc x
*/
int localX = local.getPosition().getX();
/*
* The local npc y
*/
int localY = local.getPosition().getY();
/*
* Get targets based on location
*/
switch (cannon.getRotation()) {
case NORTH:
if (localY > cannonY && localX >= cannonX - 1 && localX <= cannonX + 1)
targets.add(local);
break;
case NORTH_EAST:
if (localX >= cannonX + 1 && localY >= cannonY + 1)
targets.add(local);
break;
case EAST:
if (localX > cannonX && localY >= cannonY - 1 && localY <= cannonY + 1)
targets.add(local);
break;
case SOUTH_EAST:
if (localY <= cannonY - 1 && localX >= cannonX + 1)
targets.add(local);
break;
case SOUTH:
if (localY < cannonY && localX >= cannonX - 1 && localX <= cannonX + 1)
targets.add(local);
break;
case SOUTH_WEST:
if (localX <= cannonX - 1 && localY <= cannonY - 1)
targets.add(local);
break;
case WEST:
if (localX < cannonX && localY >= cannonY - 1 && localY <= cannonY + 1)
targets.add(local);
break;
case NORTH_WEST:
if (localX <= cannonX - 1 && localY >= cannonY + 1)
targets.add(local);
break;
}
}
return targets;
}
/**
* Gets the local npcs
*
* @return the npcs
*/
public ArrayList<NPC> getLocalNpcs(DwarfMultiCannon cannon) {
/*
* The local npcs
*/
ArrayList<NPC> npcs = new ArrayList<NPC>();
/*
* Loop through the world
*/
for (NPC npc : World.getNpcs()) {
/*
* Invalid
*/
if (npc == null) {
continue;
}
/*
* Within range
*/
if (npc.getPosition().isWithinDistance(cannon.getPosition(), MAX_RANGE)) {
npcs.add(npc);
}
}
return npcs;
}
/**
* Sets the time
*
* @return the time
*/
public long getTime() {
return time;
}
/**
* Sets the time
*
* @param time
* the time
*/
public void setTime(long time) {
this.time = time;
}
/**
* Sets the owner
*
* @return the owner
*/
public String getOwner() {
return owner;
}
/**
* Sets the owner
*
* @param owner
* the owner
*/
public void setOwner(String owner) {
this.owner = owner;
}
/**
* Sets the shooting
*
* @return the shooting
*/
public boolean isShooting() {
return shooting;
}
/**
* Sets the shooting
*
* @param shooting
* the shooting
*/
public void setShooting(boolean shooting) {
this.shooting = shooting;
}
/**
* Sets the balls
*
* @return the balls
*/
public int getBalls() {
return balls;
}
/**
* Sets the balls
*
* @param balls
* the balls
*/
public void setBalls(int balls) {
this.balls = balls;
}
/**
* Sets the task
*
* @return the task
*/
public Task getTask() {
return task;
}
/**
* Sets the task
*
* @param task
* the task
*/
public void setTask(Task task) {
this.task = task;
}
/**
* Sets the rotation
*
* @return the rotation
*/
public Rotation getRotation() {
return rotation;
}
/**
* Sets the rotation
*
* @param rotation
* the rotation
*/
public void setRotation(Rotation rotation) {
this.rotation = rotation;
}
/**
* Sets the decayWarning
*
* @return the decayWarning
*/
public boolean isDecayWarning() {
return decayWarning;
}
/**
* Sets the decayWarning
*
* @param decayWarning
* the decayWarning
*/
public void setDecayWarning(boolean decayWarning) {
this.decayWarning = decayWarning;
}
}