package net.scapeemulator.game.model.player.skills.woodcutting;
import static net.scapeemulator.game.model.player.skills.Skill.WOODCUTTING;
import java.util.Random;
import net.scapeemulator.game.model.World;
import net.scapeemulator.game.model.object.GroundObjectList.GroundObject;
import net.scapeemulator.game.model.player.Item;
import net.scapeemulator.game.model.player.Player;
import net.scapeemulator.game.model.player.action.ReachObjectAction;
/**
* @author David Insley
*/
public class WoodcuttingAction extends ReachObjectAction {
private enum State {
WALKING, START, CHOPPING
}
private static final Random rand = new Random();
private final TreeType type;
private final GroundObject object;
private final int originalId;
private State state;
private Hatchet hatchet;
public WoodcuttingAction(Player player, TreeType type, GroundObject object) {
super(2, true, player, object, 1, true);
this.type = type;
this.object = object;
originalId = object.getId();
state = State.WALKING;
}
@Override
public void executeAction() {
switch (state) {
case WALKING:
mob.getWalkingQueue().reset();
mob.turnToPosition(object.getCenterPosition());
state = State.START;
return;
case START:
if (!check()) {
stop();
return;
}
mob.sendMessage("You swing your axe at the tree.");
mob.playAnimation(hatchet.getAnimation());
state = State.CHOPPING;
break;
case CHOPPING:
if (!check()) {
stop();
return;
}
mob.playAnimation(hatchet.getAnimation());
int levelDifference = wcLvl() - type.getLevel();
// TODO actual formula
boolean shouldGetLog = rand.nextInt(4) == 0;
if (shouldGetLog) {
mob.getSkillSet().addExperience(WOODCUTTING, type.getXp());
Item log = new Item(type.getLogId());
mob.getInventory().add(log);
mob.sendMessage("You get some " + log.getDefinition().getName().toLowerCase() + ".");
/*
* The chance of the tree depleting is determined by the players level and the
* average number of logs the tree should give.
*/
double logMultiplier = levelDifference >= 50 ? 1.99 : 1.0 + (levelDifference / 50.0);
if (rand.nextInt((int) (type.getAverageLogs() * logMultiplier)) == 0) {
object.setId(type.getStumpId());
mob.cancelAnimation();
World.getWorld().getTaskScheduler().schedule(new RegrowTask(type.getRespawnTicks(), object, originalId));
stop();
return;
}
}
break;
}
}
/**
* Checks to make sure the following conditions are true for the player: level requirement to
* chop the tree, the tree still exists, level appropriate hatchet to use, and a free inventory
* space for a log.
*
* @return true if the player can chop this tree, false otherwise
*/
private boolean check() {
if (!type.getRequirements().hasRequirementsDisplayOne(mob) || object.getId() != originalId) {
return false;
}
hatchet = findHatchet();
if (hatchet == null) {
mob.sendMessage("You do not have an axe which you have the woodcutting level to use.");
return false;
}
if (mob.getInventory().freeSlots() < 1) {
mob.sendMessage("Your inventory is too full to hold any more logs.");
return false;
}
return true;
}
/**
* Alias to get the players current Woodcutting level.
*
* @return players current woodcutting level
*/
private int wcLvl() {
return mob.getSkillSet().getCurrentLevel(WOODCUTTING);
}
/**
* Searches the players weapon and inventory for the best Hatchet they can use.
*
* @return the best Hatchet the player currently has that they can use.
*/
private Hatchet findHatchet() {
Hatchet best = null;
for (Hatchet hatchet : Hatchet.values()) {
if (hatchet.getRequirements().hasRequirements(mob)) {
if (best == null || hatchet.getSpeed() > best.getSpeed()) {
best = hatchet;
}
}
}
return best;
}
}