package com.asteria.game.character.player;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import plugin.minigames.fightcaves.FightCavesHandler;
import com.asteria.game.GameConstants;
import com.asteria.game.character.Animation;
import com.asteria.game.character.AnimationPriority;
import com.asteria.game.character.CharacterDeath;
import com.asteria.game.character.Flag;
import com.asteria.game.character.combat.prayer.CombatPrayer;
import com.asteria.game.character.player.content.WeaponInterface;
import com.asteria.game.character.player.minigame.Minigame;
import com.asteria.game.character.player.minigame.MinigameHandler;
import com.asteria.game.character.player.skill.Skills;
import com.asteria.game.item.Item;
import com.asteria.game.item.ItemNode;
import com.asteria.game.item.ItemNodeManager;
import com.asteria.game.item.ItemNodeStatic;
import com.asteria.game.item.container.Equipment;
import com.asteria.game.location.Position;
import com.asteria.utility.RandomGen;
import com.google.common.collect.Ordering;
/**
* The {@link CharacterDeath} implementation that is dedicated to managing the
* death process for all {@link Player}s.
*
* @author lare96 <http://github.com/lare96>
*/
public final class PlayerDeath extends CharacterDeath<Player> {
/**
* The random generator instance that will generate random numbers.
*/
private final RandomGen random = new RandomGen();
/**
* Creates a new {@link PlayerDeath}.
*
* @param player
* the player who has died and needs the death process.
*/
public PlayerDeath(Player player) {
super(player);
}
@Override
public void preDeath(Player character) {
character.animation(new Animation(0x900, AnimationPriority.HIGH));
character.setSkillAction(false);
character.getTradeSession().reset(false);
}
@Override
public void death(Player character) {
Optional<Player> killer = character.getCombatBuilder().getDamageCache().calculateKiller();
Optional<Minigame> optional = MinigameHandler.search(character);
killer.ifPresent(k -> k.getMessages().sendMessage(
random.random(GameConstants.DEATH_MESSAGES).replaceAll("-victim-", character.getFormatUsername()).replaceAll("-killer-",
k.getFormatUsername())));
if (optional.isPresent()) {
optional.get().onDeath(character);
if (!optional.get().canKeepItems(character)) {
if (character.getRights().less(Rights.ADMINISTRATOR)) {
calculateDropItems(character, killer);
}
}
killer.ifPresent(k -> optional.get().onKill(k, character));
character.move(optional.get().deathPosition(character));
return;
}
if (character.getRights().less(Rights.ADMINISTRATOR)) {
calculateDropItems(character, killer);
character.move(new Position(3093, 3244));
}
}
@Override
public void postDeath(Player character) {
character.getMessages().sendCloseWindows();
character.getCombatBuilder().reset();
character.getCombatBuilder().getDamageCache().clear();
character.getTolerance().reset();
character.getSpecialPercentage().set(100);
character.getMessages().sendByteState(301, 0);
character.setSpecialActivated(false);
character.getSkullTimer().set(0);
character.setSkullIcon(FightCavesHandler.isChampion(character) ? Player.RED_SKULL : -1);
character.getTeleblockTimer().set(0);
character.animation(new Animation(65535));
WeaponInterface.execute(character, character.getEquipment().get(Equipment.WEAPON_SLOT));
character.getMessages().sendMessage(
character.getRights().less(Rights.ADMINISTRATOR) ? "Oh dear, you're dead!"
: "You are unaffected by death because of your rank.");
character.getMessages().sendWalkable(65535);
CombatPrayer.deactivateAll(character);
Skills.restoreAll(character);
character.getFlags().set(Flag.APPEARANCE);
}
/**
* Calculates and drops all of the items from {@code character} for
* {@code killer}.
*
* @param character
* the character whose items are being dropped.
* @param killer
* the killer who the items are being dropped for.
*/
private void calculateDropItems(Player character, Optional<Player> killer) {
List<Item> keep = new LinkedList<>();
List<Item> items = new LinkedList<>();
character.getEquipment().forEach($it -> {
if($it.getDefinition().isTradeable()) {
items.add($it);
} else {
keep.add($it);
}
});
character.getInventory().forEach($it -> {
if ($it.getDefinition().isTradeable()) {
items.add($it);
} else {
keep.add($it);
}
});
if (items.size() > 0) {
character.getEquipment().clear();
character.getInventory().clear();
character.getEquipment().refresh();
character.getInventory().refresh();
int amount = character.getSkullTimer().get() > 0 ? 0 : 3;
if (CombatPrayer.isActivated(character, CombatPrayer.PROTECT_ITEM))
amount++;
if (amount > 0) {
items.sort(new Ordering<Item>() {
@Override
public int compare(Item left, Item right) {
return Integer.compare(left.getDefinition().getGeneralPrice(), right.getDefinition().getGeneralPrice());
}
}.reverse());
for (Iterator<Item> it = items.iterator(); it.hasNext();) {
Item next = it.next();
if (amount == 0) {
break;
}
character.getInventory().add(new Item(next.getId()));
if (next.getDefinition().isStackable() && next.getAmount() > 1) {
next.decrementAmountBy(1);
} else {
it.remove();
}
amount--;
}
}
ItemNodeManager.register(!killer.isPresent() ? new ItemNodeStatic(new Item(526), character.getPosition()) : new ItemNode(
new Item(526), character.getPosition(), killer.get()));
items.stream().forEach(
item -> ItemNodeManager.register(!killer.isPresent() ? new ItemNodeStatic(item, character.getPosition()) : new ItemNode(
item, character.getPosition(), killer.get())));
character.getInventory().addAll(keep);
} else {
ItemNodeManager.register(!killer.isPresent() ? new ItemNodeStatic(new Item(526), character.getPosition()) : new ItemNode(
new Item(526), character.getPosition(), killer.get()));
}
}
}