package net.scapeemulator.game.model.mob.combat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import net.scapeemulator.game.GameServer;
import net.scapeemulator.game.model.mob.Mob;
public class Hits {
private final Mob mob;
private final Queue<Hit> hitQueue = new LinkedList<>();
private final Map<Mob, Hit> history = new HashMap<>();
private final Hit[] hits = new Hit[2];
private int historyTimer;
public Hits(Mob mob) {
this.mob = mob;
}
public boolean updated(int index) {
return hits[index - 1] != null;
}
public void tick() {
for (int i = 0; i < hits.length; i++) {
if (hits[i] == null && hitQueue.size() > 0) {
Hit hit = hitQueue.poll();
hit.setTimestamp(GameServer.getInstance().getTickTimestamp());
addToHistory(hit);
hits[i] = hit;
}
}
if (historyTimer > 0) {
if (--historyTimer == 0) {
history.clear();
}
}
}
public void addToHistory(Hit hit) {
if (hit.source == mob) {
// Don't add self damage, doesn't matter
return;
}
if (history.containsKey(hit.source)) {
history.get(hit.source).damage += hit.damage;
} else {
history.put(hit.source, new Hit(hit.source, hit.type, hit.damage));
}
history.get(hit.source).tickTimestamp = GameServer.getInstance().getTickTimestamp();
}
public Mob getMostDamageDealt() {
Hit mostDamage = null;
for (Hit hit : history.values()) {
if (mostDamage == null || hit.damage > mostDamage.damage) {
mostDamage = hit;
}
}
if (mostDamage != null) {
return mostDamage.source;
}
return null;
}
public void reset() {
hits[0] = null;
hits[1] = null;
}
public void clearQueue() {
hitQueue.clear();
}
public void addHit(Mob source, HitType type, int damage) {
Hit hit = new Hit(source, type, damage);
hitQueue.add(hit);
historyTimer = 50;
}
public int getDamage(int index) {
return hits[index - 1].damage;
}
public int getType(int index) {
return hits[index - 1].type.ordinal();
}
public Hit getMostRecentCombatHit() {
Hit recent = null;
for (Hit h : history.values()) {
// Don't want poison/disease to count as active combat
if (h.type == HitType.ZERO || h.type == HitType.NORMAL) {
if (recent == null || h.tickTimestamp > recent.tickTimestamp) {
recent = h;
}
}
}
return recent;
}
public class Hit implements Comparable<Hit> {
private HitType type;
private int damage;
private final Mob source;
private int tickTimestamp;
public Hit(Mob source, HitType type, int damage) {
this.source = source;
this.type = type;
this.damage = damage;
}
public Mob getSource() {
return source;
}
public int getTimestamp() {
return tickTimestamp;
}
private void setTimestamp(int timestamp) {
tickTimestamp = timestamp;
}
@Override
public int compareTo(Hit compare) {
return damage - compare.damage;
}
}
}