package net.scapeemulator.game.dispatcher.npc;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.scapeemulator.game.GameServer;
import net.scapeemulator.game.model.Option;
import net.scapeemulator.game.model.World;
import net.scapeemulator.game.model.definition.NPCDefinitions;
import net.scapeemulator.game.model.mob.action.InitiateCombatAction;
import net.scapeemulator.game.model.npc.NPC;
import net.scapeemulator.game.model.player.Player;
import net.scapeemulator.game.model.player.skills.magic.CombatSpell;
import net.scapeemulator.game.model.player.skills.magic.Spell;
import net.scapeemulator.game.model.player.skills.magic.Spellbook;
import net.scapeemulator.game.util.HandlerContext;
/**
* @author Hadyn Richard
*/
public class NPCDispatcher {
/**
* The mapping for all of the handler lists.
*/
private Map<Option, List<NPCHandler>> handlerLists = new HashMap<>();
/**
* Constructs a new {@link NPCDispatcher};
*/
public NPCDispatcher() {
for (Option option : Option.values()) {
if (option.equals(Option.ALL)) {
continue;
}
handlerLists.put(option, new LinkedList<NPCHandler>());
}
}
/**
* Binds a handler to this dispatcher.
*
* @param handler The handler to bind.
*/
public void bind(NPCHandler handler) {
if (handler.getOption().equals(Option.ALL)) {
for (Entry<Option, List<NPCHandler>> entry : handlerLists.entrySet()) {
entry.getValue().add(handler);
}
} else {
List<NPCHandler> list = handlerLists.get(handler.getOption());
list.add(handler);
}
}
public void unbindAll() {
for (List<?> list : handlerLists.values()) {
list.clear();
}
}
/**
* Gets the name of the option for an item.
*
* @param id The item id.
* @param option The option.
* @return The option name.
*/
private static String getOptionName(int id, Option option) {
String optionName = NPCDefinitions.forId(id).getOptions()[option.toInteger()];
return optionName == null ? "null" : optionName.toLowerCase();
}
public void handleMagic(Player player, int interfaceId, int childId, int id) {
if (player.actionsBlocked()) {
return;
}
Spellbook spellbook = player.getSpellbook();
if (interfaceId != spellbook.getInterfaceId()) {
return;
}
Spell spell = spellbook.getSpell(childId);
if (spell == null) {
return;
}
NPC npc = World.getWorld().getNpcs().get(id);
if (npc == null || !player.getPosition().isWithinScene(npc.getPosition()) || npc.isHidden()) {
return;
}
player.turnToTarget(npc);
if (!npc.alive() || !npc.getDefinition().isAttackable()) {
player.getWalkingQueue().reset();
return;
}
switch (spell.getType()) {
case DAMAGE:
case EFFECT_MOB:
player.getCombatHandler().setNextSpell((CombatSpell) spell);
player.startAction(new InitiateCombatAction(player, npc, true));
break;
case ITEM:
case TELEPORT:
return;
}
}
public void handle(Player player, int id, Option option) {
if (player.actionsBlocked()) {
return;
}
NPC npc = World.getWorld().getNpcs().get(id);
if (npc == null || !player.getPosition().isWithinScene(npc.getPosition()) || npc.isHidden()) {
return;
}
if (option == Option.TWO) { // TODO move to a handler
player.turnToTarget(npc);
if (!npc.alive() || !npc.getDefinition().isAttackable()) {
return;
}
player.startAction(new InitiateCombatAction(player, npc));
return;
}
List<NPCHandler> handlers = handlerLists.get(option);
if (handlers != null) {
String optionName = getOptionName(npc.getType(), option);
System.out.println("NPC dispatcher [opt=" + option + "; type=" + npc.getType() + "; optname=" + optionName + "]");
HandlerContext context = new HandlerContext();
for (NPCHandler handler : handlers) {
/* Handle the message parameters */
handler.handle(player, npc, optionName, context);
/* Stop propagating the message further if a stop is requested */
if (context.doStop()) {
break;
}
}
}
}
public static NPCDispatcher getInstance() {
return GameServer.getInstance().getMessageDispatcher().getNpcDispatcher();
}
}