RuneHive-Game
Loading...
Searching...
No Matches
CombatListenerManager.java
Go to the documentation of this file.
1package com.runehive.game.world.entity.combat.attack.listener;
2
3import com.runehive.game.world.entity.combat.strategy.CombatStrategy;
4import com.runehive.game.world.entity.mob.npc.Npc;
5import com.runehive.game.world.entity.mob.player.Player;
6import io.github.classgraph.*;
7import org.apache.logging.log4j.LogManager;
8import org.apache.logging.log4j.Logger;
9
10import java.lang.annotation.Annotation;
11import java.lang.reflect.Constructor;
12import java.util.*;
13
14/**
15 * @author StanTheWoman
16 */
17public final class CombatListenerManager {
18
19 private static final Logger logger = LogManager.getLogger(CombatListenerManager.class);
20
21 private static final Map<Integer, Set<CombatListenerSet>> ITEM_LISTENERS = new HashMap<>();
22 public static final Map<Integer, CombatListener<Npc>> NPC_LISTENERS = new HashMap<>();
23 public static final Map<Integer, CombatStrategy<Npc>> NPC_STRATEGIES = new HashMap<>();
24
25 public static void load() {
26 loadItems("com.runehive.game.world.entity.combat.attack.listener.item");
27 loadNpcs("com.runehive.game.world.entity.combat.attack.listener.npc");
28 }
29
30 private static void loadItems(final String pkg) {
31 try (final ScanResult scanResult =
32 new ClassGraph()
33 .enableClassInfo()
34 .enableMethodInfo()
35 .enableAnnotationInfo()
36 .acceptPackages(pkg)
37 .scan()) {
38 for (final ClassInfo classInfo : scanResult.getClassesWithAnnotation(ItemCombatListenerSignature.class)) {
39 try {
40 final MethodInfoList constructorInfos = classInfo.getDeclaredConstructorInfo();
41 final MethodInfo constructorInfo = constructorInfos.get(0);
42 final Constructor<?> constructor = constructorInfo.loadClassAndGetConstructor();
43
44 final Object instance = constructor.newInstance();
45 @SuppressWarnings("unchecked") final CombatListener<Player> listener = (CombatListener<Player>) instance;
46
47 final AnnotationInfo annotationInfo = classInfo.getAnnotationInfo(ItemCombatListenerSignature.class);
48 final Annotation annotation = annotationInfo.loadClassAndInstantiate();
50
51 for (int item : meta.items()) {
52 Set<CombatListenerSet> set = ITEM_LISTENERS.getOrDefault(item, new HashSet<>());
53 set.add(new CombatListenerSet(meta.items(), meta.requireAll(), listener));
54 ITEM_LISTENERS.put(item, set);
55 }
56 } catch (Exception ex) {
57 logger.error(String.format("Error loading item set combat listener=%s", classInfo.getSimpleName()), ex);
58 }
59 }
60 }
61 logger.info(String.format("Loaded: %d item set combat listeners.", ITEM_LISTENERS.size()));
62 }
63
64 private static void loadNpcs(final String pkg) {
65 try (final ScanResult scanResult =
66 new ClassGraph()
67 .enableClassInfo()
68 .enableMethodInfo()
69 .enableAnnotationInfo()
70 .acceptPackages(pkg)
71 .scan()) {
72 for (final ClassInfo classInfo : scanResult.getClassesWithAnnotation(NpcCombatListenerSignature.class)) {
73 try {
74 final MethodInfoList constructorInfos = classInfo.getDeclaredConstructorInfo();
75 final MethodInfo constructorInfo = constructorInfos.get(0);
76 final Constructor<?> constructor = constructorInfo.loadClassAndGetConstructor();
77
78 final Object instance = constructor.newInstance();
79 @SuppressWarnings("unchecked") final CombatListener<Npc> listener = (CombatListener<Npc>) instance;
80
81 final AnnotationInfo annotationInfo = classInfo.getAnnotationInfo(NpcCombatListenerSignature.class);
82 final Annotation annotation = annotationInfo.loadClassAndInstantiate();
84
85 for (int npc : meta.npcs()) {
87 }
88 } catch (Exception ex) {
89 logger.error(String.format("Error loading npc combat listener=%s", classInfo.getSimpleName()), ex);
90 }
91 }
92 }
93 logger.info(String.format("Loaded: %d npc combat listeners.", NPC_LISTENERS.size()));
94 }
95
96 public static void addListener(Player player, int id) {
97 Set<CombatListenerSet> sets = ITEM_LISTENERS.get(id);
98
99 if (sets == null) {
100 return;
101 }
102
103 for (CombatListenerSet set : sets) {
104 if (set.requireAll && !player.equipment.containsAll(set.set)) {
105 continue;
106 }
107
108 if (!set.requireAll && !player.equipment.containsAny(set.set)) {
109 continue;
110 }
111
112 player.getCombat().addListener(set.listener);
113 }
114 }
115
116 public static void removeListener(Player player, int id) {
117 Set<CombatListenerSet> sets = ITEM_LISTENERS.get(id);
118
119 if (sets == null) {
120 return;
121 }
122
123 for (CombatListenerSet set : sets) {
124 if (set.requireAll && player.equipment.containsAll(set.set)) {
125 continue;
126 }
127
128 if (!set.requireAll && player.equipment.containsAny(set.set)) {
129 continue;
130 }
131
132 player.getCombat().removeListener(set.listener);
133 }
134 }
135
136 public static final class CombatListenerSet {
137 private final int[] set;
138 private final boolean requireAll;
140
142 this.set = set;
143 this.requireAll = requireAll;
144 this.listener = listener;
145 }
146
147 @Override
148 public boolean equals(Object obj) {
149 if (obj == this)
150 return true;
151 if (obj instanceof CombatListenerSet) {
153 return Arrays.equals(other.set, set) && other.requireAll == requireAll;
154 }
155 return false;
156 }
157
158 @Override
159 public int hashCode() {
160 return Objects.hash(set, requireAll);
161 }
162
163 @Override
164 public String toString() {
165 return "ItemSet[set=" + Arrays.toString(set) + ", requireAll=" + requireAll + "]";
166 }
167 }
168}
CombatListenerSet(int[] set, boolean requireAll, CombatListener< Player > listener)
This class represents a character controlled by a player.
Definition Player.java:125
Combat< Player > getCombat()
The combat of the mob.
Definition Player.java:759
final boolean containsAny(int... identifiers)
Determines if this container contains any identifiers.
final boolean containsAll(int... identifiers)
Determines if this container contains all identifiers.
A combat attack is used to describe what the attacking and defending mobs should do in each stage of ...