Crossfire JXClient, Trunk
SpellsManager.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff
19  * Copyright (C) 2006-2017,2019-2023 Andreas Kirschbaum
20  * Copyright (C) 2010-2012,2014-2018,2020-2023 Nicolas Weeger
21  */
22 
23 package com.realtime.crossfire.jxclient.spells;
24 
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.concurrent.CopyOnWriteArrayList;
40 import java.util.stream.Collectors;
41 import org.jetbrains.annotations.NotNull;
42 import org.jetbrains.annotations.Nullable;
43 
50 public class SpellsManager {
51 
55  public static final int UPD_SP_MANA = 1;
56 
60  public static final int UPD_SP_GRACE = 2;
61 
65  public static final int UPD_SP_DAMAGE = 4;
66 
70  @NotNull
71  private final List<Spell> spells = new CopyOnWriteArrayList<>();
72 
76  @NotNull
77  private final List<Spell> filteredSpells = new CopyOnWriteArrayList<>();
78 
83  private int skillFilter = -1;
84 
89  @NotNull
90  private final Map<String, Spell> unknownSpells = new HashMap<>();
91 
96  @NotNull
98 
103  @NotNull
104  private final Comparator<Spell> spellNameComparator = new SpellComparator();
105 
110  @NotNull
111  @SuppressWarnings("FieldCanBeLocal")
113 
114  @Override
115  public void start() {
116  // ignore
117  }
118 
119  @Override
120  public void metaserver() {
121  // ignore
122  }
123 
124  @Override
125  public void preConnecting(@NotNull final String serverInfo) {
126  // ignore
127  }
128 
129  @Override
130  public void connecting(@NotNull final String serverInfo) {
131  spells.clear();
132  spellSkills.clear();
133  filteredSpells.clear();
134  }
135 
136  @Override
137  public void connecting(@NotNull final ClientSocketState clientSocketState, @NotNull final String param) {
138  // ignore
139  }
140 
141  @Override
142  public void connected() {
143  // ignore
144  }
145 
146  @Override
147  public void connectFailed(@NotNull final String reason) {
148  // ignore
149  }
150 
151  };
152 
156  private final SkillSet skillSet;
157 
161  private final Stats stats;
162 
166  private final Skill skillAll = new Skill("All spell skills");
167 
171  private final List<Skill> spellSkills = new ArrayList<>();
172 
179  public SpellsManager(@NotNull final GuiStateManager guiStateManager, @NotNull final SkillSet skillSet, @NotNull final Stats stats) {
180  guiStateManager.addGuiStateListener(guiStateListener);
181  this.skillSet = skillSet;
182  this.stats = stats;
183  }
184 
189  public void addCrossfireSpellChangedListener(@NotNull final SpellsManagerListener listener) {
190  listeners.add(listener);
191  }
192 
197  public void removeCrossfireSpellChangedListener(@NotNull final SpellsManagerListener listener) {
198  listeners.remove(listener);
199  }
200 
216  public void addSpell(final int tag, final int level, final int castingTime, final int mana, final int grace, final int damage, final int skill, final int path, final int faceNum, @NotNull final String spellName, @NotNull final String message) {
217  final Spell key = new Spell(spellName, skillSet, stats);
218  key.setParameters(faceNum, tag, message, level, castingTime, mana, grace, damage, skill, path); // set spell path which is used in the comparator
219 
220  int index = Collections.binarySearch(spells, key, spellNameComparator);
221  final Spell spell;
222  if (index < 0) {
223  final Spell existingSpell;
224  synchronized (unknownSpells) {
225  existingSpell = unknownSpells.remove(spellName);
226  }
227  if (existingSpell == null) {
228  spell = key;
229  } else {
230  spell = existingSpell;
231  spell.setParameters(faceNum, tag, message, level, castingTime, mana, grace, damage, skill, path);
232  }
233  index = -index-1;
234  spells.add(index, spell);
235  } else {
236  spell = spells.get(index);
237  spell.setParameters(faceNum, tag, message, level, castingTime, mana, grace, damage, skill, path);
238  }
239 
240  rebuildSkills();
241  filterSpells();
242 
243  for (SpellsManagerListener listener : listeners) {
244  listener.spellAdded(index);
245  }
246  }
247 
256  public void updateSpell(final int flags, final int tag, final int mana, final int grace, final int damage) {
257  for (Spell spell : spells) {
258  if (spell.getTag() == tag) {
259  spell.updateParameters((flags&UPD_SP_MANA) != 0, mana, (flags&UPD_SP_GRACE) != 0, grace, (flags&UPD_SP_DAMAGE) != 0, damage);
260  break;
261  }
262  }
263  }
264 
269  public void deleteSpell(final int tag) {
270  int index = 0;
271  for (Spell spell : spells) {
272  if (spell.getTag() == tag) {
273  deleteSpellByIndex(index);
274  break;
275  }
276  index++;
277  }
278  rebuildSkills();
279  filterSpells();
280  }
281 
286  private void deleteSpellByIndex(final int index) {
287  final Spell spell = spells.remove(index);
288  synchronized (unknownSpells) {
289  unknownSpells.put(spell.getName(), spell);
290  }
291 
292  for (SpellsManagerListener listener : listeners) {
293  listener.spellRemoved(index);
294  }
295 
296  spell.setUnknown(true);
297 
298  rebuildSkills();
299  }
300 
306  @Nullable
307  public Spell getSpell(@NotNull final String spellName) {
308  for (Spell spell : spells) {
309  if (spell.getName().equals(spellName)) {
310  return spell;
311  }
312  }
313 
314  Spell result = null;
315  for (Spell spell : spells) {
316  if (spell.getName().startsWith(spellName)) {
317  //noinspection VariableNotUsedInsideIf
318  if (result != null) {
319  // prefix is not unique => pretend the spell does not exist
320  return null;
321  }
322  result = spell;
323  }
324  }
325 
326  return result;
327  }
328 
333  @NotNull
334  public Collection<Spell> getAllSpells() {
335  return Collections.unmodifiableList(filteredSpells);
336  }
337 
342  @NotNull
343  public Collection<Spell> getFilteredSpells() {
344  return Collections.unmodifiableList(filteredSpells);
345  }
346 
351  public int getFilteredSpellsCount() {
352  return filteredSpells.size();
353  }
354 
361  @Nullable
362  public Spell getFilteredSpell(final int index) {
363  try {
364  return filteredSpells.get(index);
365  } catch (final IndexOutOfBoundsException ignored) {
366  return null;
367  }
368  }
369 
375  public boolean displaysFace(final int faceNum) {
376  for (Spell spell : spells) {
377  if (spell.getFaceNum() == faceNum) {
378  return true;
379  }
380  }
381 
382  return false;
383  }
384 
388  public void selectCharacter() {
389  spells.clear();
390  filteredSpells.clear();
391  }
392 
397  public void filterSkill(final int index) {
398  if (index < 0 || index >= spellSkills.size()) {
399  return;
400  }
401 
402  final int id = skillSet.getSkillId(spellSkills.get(index).toString());
403 
404  if (skillFilter == id) {
405  return;
406  }
407 
408  skillFilter = id;
409  filterSpells();
410 
411  for (SpellsManagerListener listener : listeners) {
412  listener.spellAdded(0);
413  }
414  }
415 
419  private void filterSpells() {
420  filteredSpells.clear();
421  filteredSpells.addAll(spells.stream().filter(spell -> skillFilter == -1 || spell.getSkill() == skillFilter).collect(Collectors.toList()));
422  }
423 
427  private void rebuildSkills() {
428  spellSkills.clear();
429  for (Spell spell : spells) {
430  final Skill skill = skillSet.getSkill(spell.getSkill());
431  if (skill != null && !spellSkills.contains(skill)) {
432  spellSkills.add(skill);
433  }
434  }
435  spellSkills.sort(Comparator.comparing(Skill::toString));
436  spellSkills.add(0, skillAll);
437  }
438 
443  public int getSpellSkills() {
444  return spellSkills.size();
445  }
446 
452  @Nullable
453  public Skill getSpellSkill(final int index) {
454  return 0 <= index && index < spellSkills.size() ? spellSkills.get(index) : null;
455  }
456 
457 }
com.realtime.crossfire.jxclient.spells.SpellsManager.selectCharacter
void selectCharacter()
Definition: SpellsManager.java:388
com.realtime.crossfire.jxclient.spells.SpellsManager.skillAll
final Skill skillAll
Definition: SpellsManager.java:166
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.spells.SpellsManager.guiStateListener
final GuiStateListener guiStateListener
Definition: SpellsManager.java:112
com.realtime.crossfire.jxclient.spells.SpellsManager.filterSpells
void filterSpells()
Definition: SpellsManager.java:419
com.realtime.crossfire.jxclient.spells.SpellsManager.addSpell
void addSpell(final int tag, final int level, final int castingTime, final int mana, final int grace, final int damage, final int skill, final int path, final int faceNum, @NotNull final String spellName, @NotNull final String message)
Definition: SpellsManager.java:216
com.realtime.crossfire.jxclient.spells.Spell.setUnknown
void setUnknown(final boolean unknown)
Definition: Spell.java:231
com.realtime.crossfire.jxclient.skills.Skill.toString
String toString()
Definition: Skill.java:145
com.realtime.crossfire.jxclient.spells.SpellsManager.deleteSpellByIndex
void deleteSpellByIndex(final int index)
Definition: SpellsManager.java:286
com.realtime.crossfire.jxclient.guistate.ClientSocketState
Definition: ClientSocketState.java:30
com.realtime.crossfire.jxclient.spells.Spell.getName
String getName()
Definition: Spell.java:198
com.realtime.crossfire.jxclient.spells.SpellsManager.getSpellSkill
Skill getSpellSkill(final int index)
Definition: SpellsManager.java:453
com.realtime.crossfire.jxclient.spells.SpellsManager.filteredSpells
final List< Spell > filteredSpells
Definition: SpellsManager.java:77
com.realtime.crossfire.jxclient.spells.SpellsManager.listeners
final EventListenerList2< SpellsManagerListener > listeners
Definition: SpellsManager.java:97
com.realtime.crossfire.jxclient.util.EventListenerList2
Definition: EventListenerList2.java:37
com.realtime.crossfire.jxclient.spells.SpellsManager.removeCrossfireSpellChangedListener
void removeCrossfireSpellChangedListener(@NotNull final SpellsManagerListener listener)
Definition: SpellsManager.java:197
com.realtime.crossfire.jxclient.skills.Skill
Definition: Skill.java:35
com.realtime.crossfire.jxclient.stats.Stats
Definition: Stats.java:44
com.realtime.crossfire.jxclient.spells.SpellsManager.updateSpell
void updateSpell(final int flags, final int tag, final int mana, final int grace, final int damage)
Definition: SpellsManager.java:256
com.realtime.crossfire.jxclient.spells.SpellsManager.spellNameComparator
final Comparator< Spell > spellNameComparator
Definition: SpellsManager.java:104
com.realtime.crossfire.jxclient.spells.SpellsManager.SpellsManager
SpellsManager(@NotNull final GuiStateManager guiStateManager, @NotNull final SkillSet skillSet, @NotNull final Stats stats)
Definition: SpellsManager.java:179
com.realtime.crossfire.jxclient.skills.SkillSet.getSkillId
int getSkillId(final String name)
Definition: SkillSet.java:202
com.realtime.crossfire.jxclient.spells.SpellsManager.spells
final List< Spell > spells
Definition: SpellsManager.java:71
com.realtime.crossfire.jxclient.spells.Spell.setParameters
void setParameters(final int faceNum, final int tag, @NotNull final String message, final int level, final int castingTime, final int mana, final int grace, final int damage, final int skill, final int path)
Definition: Spell.java:251
com.realtime.crossfire.jxclient.spells.SpellsManager.rebuildSkills
void rebuildSkills()
Definition: SpellsManager.java:427
com.realtime.crossfire.jxclient.guistate.GuiStateManager
Definition: GuiStateManager.java:34
com.realtime.crossfire.jxclient.guistate
Definition: ClientSocketState.java:23
com.realtime.crossfire.jxclient.spells.SpellsManager.getFilteredSpells
Collection< Spell > getFilteredSpells()
Definition: SpellsManager.java:343
com.realtime.crossfire.jxclient.skills
Definition: Skill.java:23
com.realtime.crossfire.jxclient.spells.Spell
Definition: Spell.java:37
com.realtime.crossfire.jxclient.guistate.GuiStateListener
Definition: GuiStateListener.java:32
com.realtime.crossfire.jxclient.spells.SpellsManager.unknownSpells
final Map< String, Spell > unknownSpells
Definition: SpellsManager.java:90
com.realtime.crossfire.jxclient.spells.SpellsManager.UPD_SP_GRACE
static final int UPD_SP_GRACE
Definition: SpellsManager.java:60
com.realtime.crossfire.jxclient.spells.SpellsManager.filterSkill
void filterSkill(final int index)
Definition: SpellsManager.java:397
com.realtime.crossfire.jxclient.spells.SpellsManager
Definition: SpellsManager.java:50
com.realtime.crossfire.jxclient.spells.SpellsManager.displaysFace
boolean displaysFace(final int faceNum)
Definition: SpellsManager.java:375
com.realtime.crossfire.jxclient.spells.SpellsManager.stats
final Stats stats
Definition: SpellsManager.java:161
com.realtime.crossfire.jxclient.spells.SpellsManager.addCrossfireSpellChangedListener
void addCrossfireSpellChangedListener(@NotNull final SpellsManagerListener listener)
Definition: SpellsManager.java:189
com.realtime.crossfire.jxclient.util
Definition: Codec.java:23
com.realtime.crossfire.jxclient.skills.SkillSet.getSkill
Skill getSkill(final int id)
Definition: SkillSet.java:192
com.realtime.crossfire.jxclient.spells.SpellsManager.UPD_SP_MANA
static final int UPD_SP_MANA
Definition: SpellsManager.java:55
com.realtime.crossfire.jxclient.spells.SpellsManager.getSpell
Spell getSpell(@NotNull final String spellName)
Definition: SpellsManager.java:307
com.realtime.crossfire.jxclient.spells.SpellsManager.getFilteredSpellsCount
int getFilteredSpellsCount()
Definition: SpellsManager.java:351
com.realtime.crossfire.jxclient.spells.SpellsManager.deleteSpell
void deleteSpell(final int tag)
Definition: SpellsManager.java:269
com.realtime.crossfire
com.realtime.crossfire.jxclient.spells.SpellsManager.UPD_SP_DAMAGE
static final int UPD_SP_DAMAGE
Definition: SpellsManager.java:65
com.realtime
com
com.realtime.crossfire.jxclient.spells.SpellsManager.skillFilter
int skillFilter
Definition: SpellsManager.java:83
com.realtime.crossfire.jxclient.spells.SpellsManager.getSpellSkills
int getSpellSkills()
Definition: SpellsManager.java:443
com.realtime.crossfire.jxclient.spells.SpellsManager.getFilteredSpell
Spell getFilteredSpell(final int index)
Definition: SpellsManager.java:362
com.realtime.crossfire.jxclient.skills.SkillSet
Definition: SkillSet.java:39
com.realtime.crossfire.jxclient.spells.SpellsManager.getAllSpells
Collection< Spell > getAllSpells()
Definition: SpellsManager.java:334
com.realtime.crossfire.jxclient.spells.SpellsManagerListener
Definition: SpellsManagerListener.java:31
com.realtime.crossfire.jxclient.spells.SpellsManager.skillSet
final SkillSet skillSet
Definition: SpellsManager.java:156
com.realtime.crossfire.jxclient.stats
Definition: ActiveSkillWatcher.java:23
com.realtime.crossfire.jxclient.spells.SpellsManager.spellSkills
final List< Skill > spellSkills
Definition: SpellsManager.java:171
com.realtime.crossfire.jxclient.spells.SpellComparator
Definition: SpellComparator.java:34