00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.spells;
00023
00024 import com.realtime.crossfire.jxclient.guistate.ClientSocketState;
00025 import com.realtime.crossfire.jxclient.guistate.GuiStateListener;
00026 import com.realtime.crossfire.jxclient.guistate.GuiStateManager;
00027 import com.realtime.crossfire.jxclient.skills.SkillSet;
00028 import com.realtime.crossfire.jxclient.stats.Stats;
00029 import com.realtime.crossfire.jxclient.util.EventListenerList2;
00030 import java.util.Collections;
00031 import java.util.Comparator;
00032 import java.util.HashMap;
00033 import java.util.Iterator;
00034 import java.util.List;
00035 import java.util.Map;
00036 import java.util.concurrent.CopyOnWriteArrayList;
00037 import org.jetbrains.annotations.NotNull;
00038 import org.jetbrains.annotations.Nullable;
00039
00045 public class SpellsManager implements Iterable<Spell> {
00046
00050 public static final int UPD_SP_MANA = 1;
00051
00055 public static final int UPD_SP_GRACE = 2;
00056
00060 public static final int UPD_SP_DAMAGE = 4;
00061
00065 @NotNull
00066 private final List<Spell> spells = new CopyOnWriteArrayList<Spell>();
00067
00072 @NotNull
00073 private final Map<String, Spell> unknownSpells = new HashMap<String, Spell>();
00074
00079 @NotNull
00080 private final EventListenerList2<SpellsManagerListener> listeners = new EventListenerList2<SpellsManagerListener>(SpellsManagerListener.class);
00081
00086 @NotNull
00087 private final Comparator<Spell> spellNameComparator = new SpellComparator();
00088
00093 @NotNull
00094 private final GuiStateListener guiStateListener = new GuiStateListener() {
00095
00096 @Override
00097 public void start() {
00098
00099 }
00100
00101 @Override
00102 public void metaserver() {
00103
00104 }
00105
00106 @Override
00107 public void preConnecting(@NotNull final String serverInfo) {
00108
00109 }
00110
00111 @Override
00112 public void connecting(@NotNull final String serverInfo) {
00113 spells.clear();
00114 }
00115
00116 @Override
00117 public void connecting(@NotNull final ClientSocketState clientSocketState) {
00118
00119 }
00120
00121 @Override
00122 public void connected() {
00123
00124 }
00125
00126 @Override
00127 public void connectFailed(@NotNull final String reason) {
00128
00129 }
00130
00131 };
00132
00136 private final SkillSet skillSet;
00137
00141 private final Stats stats;
00142
00149 public SpellsManager(@NotNull final GuiStateManager guiStateManager, @NotNull final SkillSet skillSet, @NotNull final Stats stats) {
00150 guiStateManager.addGuiStateListener(guiStateListener);
00151 this.skillSet = skillSet;
00152 this.stats = stats;
00153 }
00154
00159 public void addCrossfireSpellChangedListener(@NotNull final SpellsManagerListener listener) {
00160 listeners.add(listener);
00161 }
00162
00167 public void removeCrossfireSpellChangedListener(@NotNull final SpellsManagerListener listener) {
00168 listeners.remove(listener);
00169 }
00170
00186 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) {
00187 final Spell key = new Spell(spellName, skillSet, stats);
00188 key.setParameters(faceNum, tag, message, level, castingTime, mana, grace, damage, skill, path);
00189
00190 int index = Collections.binarySearch(spells, key, spellNameComparator);
00191 final Spell spell;
00192 if (index < 0) {
00193 final Spell existingSpell;
00194 synchronized (unknownSpells) {
00195 existingSpell = unknownSpells.remove(spellName);
00196 }
00197 if (existingSpell != null) {
00198 spell = existingSpell;
00199 spell.setParameters(faceNum, tag, message, level, castingTime, mana, grace, damage, skill, path);
00200 } else {
00201 spell = key;
00202 }
00203 index = -index-1;
00204 spells.add(index, spell);
00205 } else {
00206 spell = spells.get(index);
00207 spell.setParameters(faceNum, tag, message, level, castingTime, mana, grace, damage, skill, path);
00208 }
00209
00210 for (final SpellsManagerListener listener : listeners.getListeners()) {
00211 listener.spellAdded(index);
00212 }
00213 }
00214
00223 public void updateSpell(final int flags, final int tag, final int mana, final int grace, final int damage) {
00224 for (final Spell spell : spells) {
00225 if (spell.getTag() == tag) {
00226 spell.updateParameters((flags&UPD_SP_MANA) != 0, mana, (flags&UPD_SP_GRACE) != 0, grace, (flags&UPD_SP_DAMAGE) != 0, damage);
00227 break;
00228 }
00229 }
00230 }
00231
00236 public void deleteSpell(final int tag) {
00237 int index = 0;
00238 for (final Spell spell : spells) {
00239 if (spell.getTag() == tag) {
00240 deleteSpellByIndex(index);
00241 break;
00242 }
00243 index++;
00244 }
00245 }
00246
00251 private void deleteSpellByIndex(final int index) {
00252 final Spell spell = spells.remove(index);
00253 synchronized (unknownSpells) {
00254 unknownSpells.put(spell.getName(), spell);
00255 }
00256
00257 for (final SpellsManagerListener listener : listeners.getListeners()) {
00258 listener.spellRemoved(index);
00259 }
00260
00261 spell.setUnknown(true);
00262 }
00263
00270 @NotNull
00271 public Spell getSpell(@NotNull final String spellName) {
00272 for (final Spell spell : spells) {
00273 if (spell.getName().equals(spellName)) {
00274 return spell;
00275 }
00276 }
00277
00278 final Spell spell = new Spell(spellName, skillSet, stats);
00279 spell.setUnknown(true);
00280 synchronized (unknownSpells) {
00281 unknownSpells.put(spell.getName(), spell);
00282 }
00283 return spell;
00284 }
00285
00289 @Override
00290 public Iterator<Spell> iterator() {
00291 return Collections.unmodifiableList(spells).iterator();
00292 }
00293
00298 public int getSpells() {
00299 return spells.size();
00300 }
00301
00307 @Nullable
00308 public Spell getSpell(final int index) {
00309 return 0 <= index && index < spells.size() ? spells.get(index) : null;
00310 }
00311
00317 public boolean displaysFace(final int faceNum) {
00318 for (final Spell spell : spells) {
00319 if (spell.getFaceNum() == faceNum) {
00320 return true;
00321 }
00322 }
00323
00324 return false;
00325 }
00326
00330 public void selectCharacter() {
00331 spells.clear();
00332 }
00333
00334 }