package com.asteria.game.character.combat.prayer;
import com.asteria.game.character.combat.Combat;
import com.asteria.game.character.player.Player;
import com.asteria.game.character.player.skill.Skills;
import com.asteria.task.Task;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
/**
* A task that periodically drains prayer points for {@link Player}s. It
* utilizes the same formula to used on actual Runescape.
*
* @author lare96 <http://github.org/lare96>
*/
public final class CombatPrayerTask extends Task {
/**
* The player to drain prayer points.
*/
private final Player player;
/**
* A set containing the tick counts for all activated {@link CombatPrayer}s.
*/
private final Multiset<CombatPrayer> counter = HashMultiset.create();
/**
* Creates a new {@link CombatPrayerTask}.
*
* @param player
* the player to drain prayer points.
*/
public CombatPrayerTask(Player player) {
super(1, false);
super.attach(player);
this.player = player;
}
@Override
public void execute() {
// Checks if the EnumSet is empty, or in other words in no prayers are
// currently active. If so cancel the task.
if (player.getPrayerActive().isEmpty()) {
this.cancel();
return;
}
// Iterate through all of the currently activated prayers, determine if
// a prayer point can be drained, and last but not least if a prayer
// point can be drained then determine if the player is out of points.
for (CombatPrayer prayer : player.getPrayerActive()) {
if (counter.add(prayer, 1) >= drainFormula(prayer)) {
player.getSkills()[Skills.PRAYER].decreaseLevel(1);
Skills.refresh(player, Skills.PRAYER);
counter.setCount(prayer, 0);
// Determine if the player is out of points, if they are then
// break from the loop and cancel the task.
if (checkPrayer())
break;
}
}
}
/**
* Determines if the {@link Player}s prayer has ran out.
*
* @return {@code true} if the player ran out of prayer, {@code false}
* otherwise.
*/
private boolean checkPrayer() {
if (player.getSkills()[Skills.PRAYER].getLevel() < 1) {
player.getMessages().sendMessage("You've run out of prayer points!");
CombatPrayer.deactivateAll(player);
this.cancel();
return true;
}
return false;
}
/**
* Calculates the amount of ticks needed to drain a single prayer point when
* using {@code prayer}. This method utilizes {@link Player}s prayer bonus
* and the prayer drain rate.
*
* @param prayer
* the prayer to calculate for.
* @return the amount of ticks needed to drain a prayer point.
*/
private int drainFormula(CombatPrayer prayer) {
double rate = prayer.getDrainRate();
double addFactor = 1;
double divideFactor = 30;
double bonus = player.getBonus()[Combat.BONUS_PRAYER];
double tick = 600;
double second = 1000;
return (int) (((rate + (addFactor + bonus / divideFactor)) * second) / tick);
}
}