package net.scapeemulator.game.model.player.skills.prayer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.scapeemulator.game.model.player.Player;
import net.scapeemulator.game.model.player.requirement.PrayerPointRequirement;
import net.scapeemulator.game.model.player.skills.Skill;
import net.scapeemulator.game.msg.impl.ConfigMessage;
/**
* @author David Insley
*/
public class Prayers {
private final Player player;
private final Set<Prayer> activePrayers;
private final Map<Integer, Double> bonuses;
/**
* The rate at which prayer points are drained per tick.
*/
private int drainRate;
/**
* The current prayer point drain counter. Once it reaches 1000 a prayer point is removed from
* the player.
*/
private int drainCounter;
public Prayers(Player player) {
this.player = player;
activePrayers = new HashSet<>();
bonuses = new HashMap<>();
}
public void toggle(Prayer prayer) {
if (prayer == null) {
return;
}
if (activePrayers.contains(prayer)) {
player.send(new ConfigMessage(prayer.getConfigId(), 0));
drainRate -= prayer.getDrainRate();
activePrayers.remove(prayer);
if (player.getHeadIcon().getPrayer() == prayer) {
player.setHeadIcon(HeadIcon.NONE);
player.appearanceUpdated();
}
} else {
if (!prayer.getRequirements().hasRequirementsDisplayOne(player)) {
return;
}
player.send(new ConfigMessage(prayer.getConfigId(), 1));
drainRate += prayer.getDrainRate();
// TODO change when you can have summoning + other icon
if (prayer.getHeadIcon() != null) {
player.setHeadIcon(prayer.getHeadIcon());
player.appearanceUpdated();
}
Iterator<Prayer> it = activePrayers.iterator();
while (it.hasNext()) {
Prayer activePrayer = it.next();
if (prayer.conflicts(activePrayer)) {
player.send(new ConfigMessage(activePrayer.getConfigId(), 0));
drainRate -= activePrayer.getDrainRate();
it.remove();
}
}
activePrayers.add(prayer);
}
calculateBonuses();
}
// Not happy with this design for bonuses. Should rewrite.
/**
* Iterates through all active prayers and sets the bonus for each skill.
*/
private void calculateBonuses() {
bonuses.clear();
for (Prayer activePrayer : activePrayers) {
int skillId = activePrayer.getTypes()[0].getSkillId();
if (skillId < 0) {
continue;
}
switch (activePrayer) {
// Tier one prayer bonuses
case THICK_SKIN:
case BURST_OF_STRENGTH:
case CLARITY_OF_THOUGHT:
case SHARP_EYE:
case MYSTIC_WILL:
bonuses.put(skillId, 1.05);
break;
// Tier two prayer bonuses
case ROCK_SKIN:
case SUPERHUMAN_STRENGTH:
case IMPROVED_REFLEXES:
case HAWK_EYE:
case MYSTIC_LORE:
bonuses.put(skillId, 1.1);
break;
// Tier three prayer bonuses
case STEEL_SKIN:
case ULTIMATE_STRENGTH:
case INCREDIBLE_REFLEXES:
case EAGLE_EYE:
case MYSTIC_MIGHT:
bonuses.put(skillId, 1.15);
break;
case CHIVALRY:
bonuses.put(Skill.ATTACK, 1.15);
bonuses.put(Skill.STRENGTH, 1.18);
bonuses.put(Skill.DEFENCE, 1.2);
break;
case PIETY:
bonuses.put(Skill.ATTACK, 1.2);
bonuses.put(Skill.STRENGTH, 1.23);
bonuses.put(Skill.DEFENCE, 1.25);
break;
default:
break;
}
}
}
/**
* Deactivates all active prayers.
*/
public void deactivateAll() {
for (Prayer activePrayer : activePrayers) {
player.send(new ConfigMessage(activePrayer.getConfigId(), 0));
}
if (player.getHeadIcon() != HeadIcon.NONE) {
player.setHeadIcon(HeadIcon.NONE);
player.appearanceUpdated();
}
activePrayers.clear();
bonuses.clear();
drainCounter = 0;
drainRate = 0;
}
/**
* Called once per tick, increments the prayer drain counter using the drain rate of all active
* prayers and then removes prayer points from the player if necessary.
*/
public void tick() {
if (drainRate > 0) {
int prayerBonus = player.getCombatBonuses().getPrayerBonus();
double modifier = 1 + (prayerBonus * (0.01 / 0.3));
int modifiedDrainRate = (int) (drainRate / modifier);
drainCounter += modifiedDrainRate;
int drain = drainCounter / 1000;
player.reducePrayerPoints(drain);
drainCounter -= drain * 1000;
if (!PrayerPointRequirement.NON_ZERO_POINTS.hasRequirement(player)) {
deactivateAll();
player.sendMessage("You have run out of Prayer points.");
}
}
}
public double getPrayerBonus(int skillId) {
if (bonuses.containsKey(skillId)) {
return bonuses.get(skillId);
}
return 1;
}
public boolean prayerActive(Prayer prayer) {
return activePrayers.contains(prayer);
}
public boolean protectingItem() {
return activePrayers.contains(Prayer.PROTECT);
}
}