public class CharacterItemModel { private DescriptiveFeatures descriptiveFeatures; private Item item; private final Announcer<ChangeListener> featuresChangeAnnouncer = Announcer.to(ChangeListener.class); public CharacterItemModel(DescriptiveFeatures descriptiveFeatures) { this.descriptiveFeatures = descriptiveFeatures; } public CharacterItemModel(CharacterIdentifier identifier, Item item) { setItem(identifier, item); } public DescriptiveFeatures getDescriptiveFeatures() { return descriptiveFeatures; } public void setItem(Item item) { CharacterIdentifier identifier = descriptiveFeatures.getIdentifier(); setItem(identifier, item); } private void setItem(CharacterIdentifier identifier, Item item) { this.item = item; this.descriptiveFeatures = new LoadedDescriptiveFeatures(identifier, item); Hero hero = (Hero) item.getItemData(); HeroConceptFetcher.fetch(hero).getCaste().addChangeListener(new AnnouncingChangeListener()); HeroDescriptionFetcher.fetch(hero) .getName() .addTextChangedListener( new ObjectValueListener<String>() { @Override public void valueChanged(String newValue) { featuresChangeAnnouncer.announce().changeOccurred(); } }); item.getItemData().getChangeManagement().addDirtyListener(new AnnouncingChangeListener()); } public boolean isLoaded() { return item != null; } public Item getItem() { return item; } public void whenFeaturesChange(ChangeListener listener) { featuresChangeAnnouncer.addListener(listener); } private class AnnouncingChangeListener implements ChangeListener { @Override public void changeOccurred() { featuresChangeAnnouncer.announce().changeOccurred(); } } }
public class CharacterListening implements ICharacterListening { private final Announcer<ICharacterChangeListener> changeControl = Announcer.to(ICharacterChangeListener.class); private final CharacterListenerMapping listenerMapping = new CharacterListenerMapping(changeControl); @Override public void addChangeListener(ICharacterChangeListener changeListener) { changeControl.addListener(changeListener); } public void removeTraitListening(IDefaultTrait trait) { listenerMapping.removeTraitListening(trait); } public void addTraitListening(ITrait trait) { listenerMapping.addTraitListening(trait); } public void fireCharacterChanged() { changeControl.announce().characterChanged(); } public void fireCasteChanged() { changeControl.announce().casteChanged(); } public void fireExperiencedChanged(boolean isExperienced) { changeControl.announce().experiencedChanged(isExperienced); } }
public class MusicDatabasePersister { private final LibraryPersister libaryPersister = new LibraryPersister(); private final SelectionPersister selectionPersister = new SelectionPersister(); private final SearchPersister searchPersister = new SearchPersister(); private final ObjectContainer db; private final Announcer<ITrackDeletionListener> listeners = Announcer.to(ITrackDeletionListener.class); public MusicDatabasePersister(ObjectContainer container) { db = container; libaryPersister.addTrackDeletionListener( new ITrackDeletionListener() { @Override public void trackRemoved(DbMp3Track track) { fireTrackDeleted(track); } }); } public void pruneSelections(DbMp3Track track) { DbMusicSelection[] allSelections = selectionPersister.getAllSelections(db); for (DbMusicSelection selection : allSelections) { selection.removeTracks(new IMp3Track[] {track}); selectionPersister.updateSelection(db, selection); } db.commit(); } private void fireTrackDeleted(DbMp3Track track) { listeners.announce().trackRemoved(track); } public void addTrackDeletionListener(ITrackDeletionListener listener) { listeners.addListener(listener); } public void addLibrary(String libraryName) { libaryPersister.addLibrary(db, libraryName); db.commit(); } public ILibrary[] getAllLibraries() { return libaryPersister.getAllLibraries(db); } public boolean isRegisteredLibrary(String name) { return libaryPersister.isRegisteredLibrary(db, name); } public IMp3Track[] getTracksFromLibrary(String name) { DbLibrary library = libaryPersister.getLibrary(db, name); if (library == null) { return new IMp3Track[0]; } return library.getMp3Items(); } public void addTracks(String name, List<IMp3Track> tracks) { libaryPersister.addTracks(db, name, tracks); db.commit(); } public void updateLibaryName(ILibrary library, String newName) { libaryPersister.updateLibraryName(db, library, newName); db.commit(); } public void removeLibrary(String name) { libaryPersister.removeLibrary(db, name); db.commit(); } public void removeTracksFromLibrary(String name, IMp3Track[] tracks) { for (IMp3Track track : tracks) { libaryPersister.removeTrackFromLibrary(db, name, track); } db.commit(); } public void addSelection(String string) { selectionPersister.updateSelection(db, new DbMusicSelection(string, db)); db.commit(); } public IMusicSelection[] getAllSelections() { return selectionPersister.getAllSelections(db); } public DbMusicSelection getSelectionByName(String name) { return selectionPersister.getSelectionByName(db, name); } public void removeSelection(IMusicSelection selection) { if (selection instanceof DbMusicSelection) { selectionPersister.removeSelection(db, (DbMusicSelection) selection); } else { throw new IllegalArgumentException( "Selection must be of type DbMusicSelection"); //$NON-NLS-1$ } db.commit(); } public void updateTrackInfo(IMp3Track selectedTrack) { if (selectedTrack instanceof DbMp3Track) { selectionPersister.updateTrackInfo(db, (DbMp3Track) selectedTrack); } else { throw new IllegalArgumentException("Track must be of type DbMp3Track"); // $NON-NLS-1$ } db.commit(); } public IMp3Track[] executeSearch(IExtendedSearchParameter[] parameters) { return searchPersister.executeSearch(db, parameters); } public <C> List<C> getAllObjects(Class<C> componentType) { return db.query(componentType); } public <C> void setSimpleObject(C object) { db.set(object); } public void updateSelectionName(IMusicSelection selection, String newName) { DbMusicSelection dbSelection = (DbMusicSelection) selection; dbSelection.setName(newName); selectionPersister.updateSelection(db, dbSelection); db.commit(); } public void updateSelection(IMusicSelection selection) { selectionPersister.updateSelection(db, (DbMusicSelection) selection); } }
public class SpecialtyView extends AbstractTraitView implements ISpecialtyView { private final Announcer<IChangeListener> control = Announcer.to(IChangeListener.class); private final Component abilityLabel; private final Component separatorLabel = new JLabel("-"); // $NON-NLS-1$ private final Component specialtyLabel; private JButton deleteButton; private JPanel traitPanel; private final Icon deleteIcon; public SpecialtyView( IntegerViewFactory configuration, String labelText, Icon deleteIcon, String id, int value, int maxValue) { super(configuration, labelText, value, maxValue, null); this.deleteIcon = deleteIcon; specialtyLabel = new JLabel(id); abilityLabel = new JLabel(labelText); } @SuppressWarnings("serial") public void addComponents(JPanel panel) { this.traitPanel = panel; panel.add(abilityLabel); panel.add(separatorLabel); panel.add(specialtyLabel, new CC().pushX().growX()); panel.add(getValueDisplay().getComponent()); deleteButton = new JButton( new AbstractAction(null, deleteIcon) { @Override public void actionPerformed(ActionEvent e) { fireDeletionPerformed(); } }); deleteButton.setPreferredSize( new Dimension(deleteIcon.getIconWidth() + 4, deleteIcon.getIconHeight() + 4)); panel.add(deleteButton, LayoutUtils.constraintsForImageButton(deleteButton)); } @Override public void addDeleteListener(IChangeListener listener) { control.addListener(listener); } private void fireDeletionPerformed() { control.announce().changeOccurred(); } @Override public void delete() { traitPanel.remove(abilityLabel); traitPanel.remove(separatorLabel); traitPanel.remove(specialtyLabel); traitPanel.remove(getValueDisplay().getComponent()); traitPanel.remove(deleteButton); traitPanel.revalidate(); // Remove this line to keep the positions of specialties constant. traitPanel.repaint(); } @Override public void setDeleteButtonEnabled(boolean enabled) { deleteButton.setEnabled(enabled); } }
public class UpdateChecker implements IUpdateChecker { public static final String Update_Url = "http://anathema.github.com/version/version.txt"; private final IResources resources; private final Announcer<IChangeListener> control = Announcer.to(IChangeListener.class); private IMessageData data; private String remoteVersion; private Boolean success = null; public UpdateChecker(IResources resources) { this.resources = resources; } public void checkForUpdates() { try { String response = getVersionData(); String[] split = response.split("#"); // $NON-NLS-1$ boolean newVersionAvailable = remoteIsNewer(split[1]); this.remoteVersion = split[0]; if (newVersionAvailable) { this.success = true; this.data = new MessageData("Help.UpdateCheck.Outdated", MessageType.INFORMATION); // $NON-NLS-1$ } else { this.success = true; this.data = new MessageData("Help.UpdateCheck.UpToDate", MessageType.INFORMATION); // $NON-NLS-1$ } } catch (IOException e) { this.success = false; this.data = new MessageData("Help.UpdateCheck.IOException", MessageType.ERROR); // $NON-NLS-1$ } catch (Exception e) { this.success = false; this.data = new MessageData( "Help.UpdateCheck.GeneralException", MessageType.ERROR); // $NON-NLS-1$ } control.announce().changeOccurred(); } @Override public Boolean isCheckSuccessful() { return success; } @Override public String getCurrentVersion() { return resources.getString("Anathema.Version.Numeric"); // $NON-NLS-1$ } @Override public String getLatestVersion() { return remoteVersion; } @Override public IMessageData getMessageData() { return data; } private boolean remoteIsNewer(String string) throws ParseException { DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.ENGLISH); Date currentVersionDate = dateFormat.parse(resources.getString("Anathema.Version.Built")); // $NON-NLS-1$ Date remoteVersionDate = dateFormat.parse(string); return currentVersionDate.compareTo(remoteVersionDate) < 0; } private String getVersionData() throws IOException { URL url = new URL(Update_Url); // $NON-NLS-1$ BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); String response = in.readLine(); in.close(); return response; } @Override public void addDataChangedListener(IChangeListener listener) { control.addListener(listener); } }
public class LibraryControl implements ILibraryControl { private final Announcer<ILibraryChangedListener> listenerControl = Announcer.to(ILibraryChangedListener.class); private MusicDatabasePersister musicDataBasePersister; public LibraryControl(MusicDatabasePersister persister) { this.musicDataBasePersister = persister; } @Override public void updateLibrary(ILibrary library, String newName) { musicDataBasePersister.updateLibaryName(library, newName); fireLibraryChanged(newName); } @Override public ILibrary[] getAllLibraries() { return musicDataBasePersister.getAllLibraries(); } @Override public boolean containsLibraryName(String name) { return musicDataBasePersister.isRegisteredLibrary(name); } @Override public void addNewLibrary(String name) { musicDataBasePersister.addLibrary(name); fireLibraryChanged(name); } @Override public void addNewUnnamedLibrary(String unnamedLibraryBaseString) { int count = 1; ILibrary[] allLibraries = getAllLibraries(); ILibrary library = getLibraryByName(allLibraries, createLibrarayName(unnamedLibraryBaseString, count)); while (library != null) { count++; library = getLibraryByName(allLibraries, createLibrarayName(unnamedLibraryBaseString, count)); } String libraryName = createLibrarayName(unnamedLibraryBaseString, count); addNewLibrary(libraryName); } private String createLibrarayName(String unnamedLibraryBaseString, int count) { return unnamedLibraryBaseString + " " + count; // $NON-NLS-1$ } private void fireLibraryChanged(String name) { ILibrary[] allLibraries = getAllLibraries(); ILibrary newLibrary = getLibraryByName(allLibraries, name); listenerControl.announce().librariesChanged(allLibraries, newLibrary); } protected ILibrary getLibraryByName(ILibrary[] allLibraries, String name) { for (ILibrary library : allLibraries) { if (library.getName().equals(name)) { return library; } } return null; } @Override public void addLibraryChangedListener(ILibraryChangedListener listener) { listenerControl.addListener(listener); } @Override public void addTracks(String name, List<IMp3Track> tracks) { musicDataBasePersister.addTracks(name, tracks); } @Override public IMusicFolderWalker createMusicFolderWalker(Path folder) throws IOException { return new MusicFolderWalker(folder); } @Override public void removeLibrary(ILibrary library) { musicDataBasePersister.removeLibrary(library.getName()); fireLibraryChanged(null); } @Override public void removeTracksFromLibrary(ILibrary library, IMp3Track[] tracks) { musicDataBasePersister.removeTracksFromLibrary(library.getName(), tracks); fireLibraryChanged(library.getName()); } @Override public void addTrack(String name, Path mp3File) throws AnathemaException, IOException { List<IMp3Track> tracks = new ArrayList<>(); tracks.add(new FileMp3Track(mp3File)); musicDataBasePersister.addTracks(name, tracks); } }
public class CharmConfiguration implements ICharmConfiguration { private final ISpecialCharmManager manager; private final MartialArtsCharmTree martialArtsCharmTree; private final Map<Identified, ICharmTree> alienTreesByType = new HashMap<Identified, ICharmTree>(); private final Map<Identified, ILearningCharmGroup[]> nonMartialArtsGroupsByType = new HashMap<Identified, ILearningCharmGroup[]>(); private final Map<ICharacterType, ICharmTemplate> templatesByType = new HashMap<ICharacterType, ICharmTemplate>(); private final ICharacterType[] types; private final ILearningCharmGroupContainer learningCharmGroupContainer = new ILearningCharmGroupContainer() { @Override public ILearningCharmGroup getLearningCharmGroup(ICharm charm) { return getGroup(charm); } }; private ILearningCharmGroup[] martialArtsGroups; private final ICharacterModelContext context; private final Announcer<IChangeListener> control = Announcer.to(IChangeListener.class); private final ICharmProvider provider; private final ICharmGroupArbitrator arbitrator; private List<ICharmFilter> filterSet = new ArrayList<ICharmFilter>(); private PrerequisiteModifyingCharms prerequisiteModifyingCharms; public CharmConfiguration( IHealthConfiguration health, ICharacterModelContext context, ITemplateRegistry registry, ICharmProvider provider) { this.manager = new SpecialCharmManager(this, health, context); this.context = context; this.provider = provider; List<ICharacterType> allCharacterTypes = new ArrayList<ICharacterType>(); ICharmTemplate nativeCharmTemplate = getNativeCharmTemplate(registry); this.arbitrator = new LearningCharmGroupArbitrator(nativeCharmTemplate, context); this.martialArtsCharmTree = new MartialArtsCharmTree(nativeCharmTemplate); this.martialArtsGroups = createGroups(martialArtsCharmTree.getAllCharmGroups()); initCharacterType(nativeCharmTemplate, getNativeCharacterType()); allCharacterTypes.add(getNativeCharacterType()); initAlienTypes(registry, allCharacterTypes); initUniqueTypes(nativeCharmTemplate); initSpecialCharmConfigurations(); types = allCharacterTypes.toArray(new ICharacterType[allCharacterTypes.size()]); filterSet.add(new ObtainableCharmFilter(this)); filterSet.add(new CharacterSourceBookFilter(this)); filterSet.add(new EssenceLevelCharmFilter()); } private ICharmTemplate getNativeCharmTemplate(ITemplateRegistry registry) { IBasicCharacterData basicCharacterContext = context.getBasicCharacterContext(); ITemplateType templateType = basicCharacterContext.getTemplateType(); ICharacterTemplate template = registry.getTemplate(templateType); IMagicTemplate magicTemplate = template.getMagicTemplate(); return magicTemplate.getCharmTemplate(); } @Override public void addCharmLearnListener(ICharmLearnListener listener) { for (ILearningCharmGroup group : getAllGroups()) { group.addCharmLearnListener(listener); } } @Override public ICharmIdMap getCharmIdMap() { List<ICharmIdMap> trees = new ArrayList<ICharmIdMap>(alienTreesByType.values()); trees.add(martialArtsCharmTree); ICharmIdMap[] treeArray = trees.toArray(new ICharmIdMap[trees.size()]); return new GroupedCharmIdMap(treeArray); } @Override public ISpecialCharm[] getSpecialCharms() { return provider.getSpecialCharms( new MartialArtsLearnableArbitrator(martialArtsCharmTree), getCharmIdMap(), getNativeCharacterType()); } private void initSpecialCharmConfigurations() { ICharmIdMap charmIdMap = getCharmIdMap(); ISpecialCharm[] specialCharms = getSpecialCharms(); for (ISpecialCharm specialCharm : specialCharms) { ICharm charm = charmIdMap.getCharmById(specialCharm.getCharmId()); if (charm == null) { continue; } ILearningCharmGroup group = getGroupById(charm.getCharacterType(), charm.getGroupId()); manager.registerSpecialCharmConfiguration(specialCharm, charm, group); } } private ILearningCharmGroup[] createGroups(ICharmGroup[] charmGroups) { List<ILearningCharmGroup> newGroups = new ArrayList<ILearningCharmGroup>(); ICharmLearnListener mergedListener = new CharmLearnAdapter() { @Override public void charmLearned(ICharm charm) { for (ICharm mergedCharm : charm.getMergedCharms()) { if (!isLearned(mergedCharm) && isLearnableWithoutPrerequisites(mergedCharm) && CharmConfiguration.this.getSpecialCharmConfiguration(mergedCharm) == null) { getGroup(mergedCharm).learnCharm(mergedCharm, isExperienced()); } } for (ICharm child : charm.getLearnChildCharms()) { boolean learnedMerged = false; for (ICharm mergedCharm : child.getMergedCharms()) { learnedMerged = learnedMerged || isLearned(mergedCharm); } if (learnedMerged && isLearnable(child)) { getGroup(child).learnCharm(child, isExperienced()); } } } @Override public void charmForgotten(ICharm charm) { boolean forgetMerges = true; for (ICharm parentCharm : charm.getParentCharms()) { forgetMerges = forgetMerges && isLearned(parentCharm); } if (forgetMerges) { for (ICharm mergedCharm : charm.getMergedCharms()) { if (isLearned(mergedCharm) && isUnlearnableWithoutConsequences(mergedCharm)) { getGroup(mergedCharm).forgetCharm(mergedCharm, isExperienced()); } } } } @Override public void recalculateRequested() { for (ICharm charm : getLearnedCharms(true)) { boolean prereqsMet = true; for (ICharm parent : charm.getParentCharms()) { for (String subeffectRequirement : charm.getParentSubeffects()) { if (getSubeffectParent(subeffectRequirement).equals(parent.getId())) { ISpecialCharmConfiguration config = getSpecialCharmConfiguration(getSubeffectParent(subeffectRequirement)); if (config instanceof IMultipleEffectCharmConfiguration) { IMultipleEffectCharmConfiguration mConfig = (IMultipleEffectCharmConfiguration) config; prereqsMet = prereqsMet && mConfig .getEffectById(getSubeffect(subeffectRequirement)) .isLearned(); } if (config instanceof IMultiLearnableCharmConfiguration) { IMultiLearnableCharmConfiguration mConfig = (IMultiLearnableCharmConfiguration) config; String effect = getSubeffect(subeffectRequirement); int requiredCount = Integer.parseInt(effect.replace("Repurchase", "")); prereqsMet = mConfig.getCurrentLearnCount() >= requiredCount; } } } } if (!prereqsMet) { getGroup(charm).forgetCharm(charm, isExperienced()); } } } }; for (ICharmGroup charmGroup : charmGroups) { ILearningCharmGroup group = new LearningCharmGroup( getLearnStrategy(), charmGroup, this, learningCharmGroupContainer, this); newGroups.add(group); group.addCharmLearnListener(mergedListener); } return newGroups.toArray(new ILearningCharmGroup[newGroups.size()]); } private String getSubeffectParent(String subeffect) { return subeffect.split("\\.")[0] + "." + subeffect.split("\\.")[1]; } private String getSubeffect(String subeffect) { return subeffect.split("\\.")[3]; } @Override public ILearningCharmGroup[] getAllGroups() { List<ILearningCharmGroup> allGroups = new ArrayList<ILearningCharmGroup>(); for (ILearningCharmGroup[] groups : nonMartialArtsGroupsByType.values()) { allGroups.addAll(Arrays.asList(groups)); } allGroups.addAll(Arrays.asList(martialArtsGroups)); return allGroups.toArray(new ILearningCharmGroup[allGroups.size()]); } private ICharmTemplate getCharmTemplate(ICharacterType type) { return templatesByType.get(type); } private ICharacterType getCharacterType(String charmId) { String characterType = charmId.substring(0, charmId.indexOf(".")); // $NON-NLS-1$ for (ICharacterType type : types) { if (type.getId().equals(characterType)) { return type; } } throw new IllegalArgumentException( "Charm Id did not contain a valid character type"); //$NON-NLS-1$ } @Override public String getCharmTrueName(String charmId) { return provider.getCharmRename(charmId); } @Override public ICharm getCharmById(String charmId) { charmId = getCharmTrueName(charmId); ICharm charm = martialArtsCharmTree.getCharmById(charmId); if (charm != null) { return charm; } ICharacterType characterType = getCharacterType(charmId); charm = getCharmTree(characterType).getCharmById(charmId); if (charm != null) { return charm; } ICharmTemplate charmTemplate = templatesByType.get(getNativeCharacterType()); if (charmTemplate.hasUniqueCharms()) { IUniqueCharmType uniqueType = charmTemplate.getUniqueCharmType(); charm = getCharmTree(uniqueType.getId()).getCharmById(charmId); if (charm != null) { return charm; } } throw new IllegalArgumentException( "No charm found for id \"" + charmId + "\""); // $NON-NLS-1$ //$NON-NLS-2$ } private ICharmIdMap getCharmTree(Identified type) { return alienTreesByType.get(type); } @Override public ICharm[] getCreationLearnedCharms() { List<ICharm> allLearnedCharms = new ArrayList<ICharm>(); for (ILearningCharmGroup group : getAllGroups()) { Collections.addAll(allLearnedCharms, group.getCreationLearnedCharms()); } return allLearnedCharms.toArray(new ICharm[allLearnedCharms.size()]); } @Override public ILearningCharmGroup[] getCharmGroups(Identified type) { if (MartialArtsUtilities.MARTIAL_ARTS.equals(type)) { return martialArtsGroups; } return Functions.forMap(nonMartialArtsGroupsByType, new ILearningCharmGroup[0]).apply(type); } private ILearningCharmGroup[] getMartialArtsGroups() { return getCharmGroups(MartialArtsUtilities.MARTIAL_ARTS); } @Override public ICharm[] getLearnedCharms(boolean experienced) { List<ICharm> allLearnedCharms = new ArrayList<ICharm>(); for (ILearningCharmGroup group : getAllGroups()) { Collections.addAll(allLearnedCharms, group.getCreationLearnedCharms()); if (experienced) { Collections.addAll(allLearnedCharms, group.getExperienceLearnedCharms()); } } return allLearnedCharms.toArray(new ICharm[allLearnedCharms.size()]); } @Override public ISpecialCharmConfiguration getSpecialCharmConfiguration(ICharm charm) { return manager.getSpecialCharmConfiguration(charm); } private void initCharacterType(ICharmTemplate charmTemplate, ICharacterType type) { CharmTree charmTree = new CharmTree(charmTemplate); alienTreesByType.put(type, charmTree); ILearningCharmGroup[] groups = createGroups(charmTree.getAllCharmGroups()); nonMartialArtsGroupsByType.put(type, groups); templatesByType.put(type, charmTemplate); } private void initUniqueTypes(ICharmTemplate charmTemplate) { if (!charmTemplate.hasUniqueCharms()) { return; } IUniqueCharmType type = charmTemplate.getUniqueCharmType(); CharmTree charmTree = new CharmTree(charmTemplate.getUniqueCharms()); ILearningCharmGroup[] groups = createGroups(charmTree.getAllCharmGroups()); nonMartialArtsGroupsByType.put(type.getId(), groups); alienTreesByType.put(type.getId(), charmTree); } private ICharmTemplate getCharmTemplate(ITemplateRegistry registry, ICharacterType type) { ICharacterTemplate defaultTemplate = registry.getDefaultTemplate(type); if (defaultTemplate == null) { return null; } return defaultTemplate.getMagicTemplate().getCharmTemplate(); } private void initAlienTypes(ITemplateRegistry registry, List<ICharacterType> characterTypes) { for (ICharacterType type : CharacterType.values()) { if (characterTypes.contains(type)) { continue; } ICharmTemplate charmTemplate = getCharmTemplate(registry, type); if (charmTemplate != null && charmTemplate.canLearnCharms()) { initCharacterType(charmTemplate, type); characterTypes.add(type); } } } private ICharacterType getNativeCharacterType() { return context.getBasicCharacterContext().getCharacterType(); } @Override public void unlearnAllAlienCharms() { for (ILearningCharmGroup[] groups : nonMartialArtsGroupsByType.values()) { for (ILearningCharmGroup group : groups) { if (group.getCharacterType() != getNativeCharacterType()) { group.forgetAll(); } } } for (ILearningCharmGroup group : martialArtsGroups) { group.unlearnExclusives(); } } @Override public ILearningCharmGroup getGroup(String characterTypeId, String groupName) { ICharacterType characterType = characterTypeId == null ? getNativeCharacterType() : CharacterType.getById(characterTypeId); return getGroupById(characterType, groupName); } @Override public ICharacterType[] getCharacterTypes(boolean includeAlienTypes) { if (!includeAlienTypes) { return new ICharacterType[] {getNativeCharacterType()}; } return types; } public void initListening() { context .getCharacterListening() .addChangeListener( new GlobalCharacterChangeAdapter() { @Override public void characterChanged() { verifyCharms(); fireLearnConditionsChanged(); } }); addCharmLearnListener( new CharmLearnAdapter() { @Override public void charmForgotten(ICharm charm) { fireLearnConditionsChanged(); } @Override public void charmLearned(ICharm charm) { fireLearnConditionsChanged(); } }); } private void verifyCharms() { if (!context.isFullyLoaded()) { return; } List<ICharm> charmsToUnlearn = new ArrayList<ICharm>(); for (ICharm charm : this.getLearnedCharms(true)) { boolean prerequisitesForCharmAreNoLongerMet = !isLearnable(charm); boolean charmCanBeUnlearned = isUnlearnable(charm); if (prerequisitesForCharmAreNoLongerMet && charmCanBeUnlearned) { charmsToUnlearn.add(charm); } } for (ICharm charm : charmsToUnlearn) { ILearningCharmGroup group = learningCharmGroupContainer.getLearningCharmGroup(charm); boolean learnedAtCreation = group.isLearned(charm, false); boolean learnedWithExperience = !learnedAtCreation; group.forgetCharm(charm, learnedWithExperience); } } @Override public void addLearnableListener(IChangeListener listener) { control.addListener(listener); } private void fireLearnConditionsChanged() { control.announce().changeOccurred(); } private ICharmLearnStrategy getLearnStrategy() { return context.getCharmContext().getCharmLearnStrategy(); } @Override public final boolean isLearnable(ICharm charm) { if (isAlienCharm(charm)) { ICasteType casteType = context.getBasicCharacterContext().getCasteType(); if (!getCharmTemplateForCharacterType().isAllowedAlienCharms(casteType)) { return false; } if (charm.hasAttribute(ICharmData.NATIVE)) { return false; } } if (charm.isBlockedByAlternative(context.getMagicCollection())) { return false; } if (isMartialArtsCharm(charm)) { boolean isSiderealFormCharm = isFormCharm(charm) && hasLevel(Sidereal, charm); MartialArtsCharmConfiguration martialArtsConfiguration = new DefaultMartialArtsCharmConfiguration( this, context.getMagicCollection(), context.getBasicCharacterContext()); if (isSiderealFormCharm && !martialArtsConfiguration.isAnyCelestialStyleCompleted()) { return false; } if (!getMartialArtsRulesForCharacterType() .isCharmAllowed(charm, martialArtsConfiguration, isExperienced())) { return false; } } ICharm[] learnedCharms = getLearnedCharms(true); for (IndirectCharmRequirement requirement : charm.getAttributeRequirements()) { if (!requirement.isFulfilled(learnedCharms)) { return false; } } if (!(new CharmTraitRequirementChecker(getPrerequisiteModifyingCharms(), context, this) .areTraitMinimumsSatisfied(charm))) { return false; } for (ICharm parentCharm : charm.getLearnPrerequisitesCharms(this)) { if (!isLearnable(parentCharm)) { return false; } } return true; } private boolean isExperienced() { return context.getBasicCharacterContext().isExperienced(); } private MartialArtsRules getMartialArtsRulesForCharacterType() { return getCharmTemplateForCharacterType().getMartialArtsRules(); } private ICharmTemplate getCharmTemplateForCharacterType() { return getCharmTemplate(getNativeCharacterType()); } private PrerequisiteModifyingCharms getPrerequisiteModifyingCharms() { if (prerequisiteModifyingCharms == null) { this.prerequisiteModifyingCharms = new PrerequisiteModifyingCharms(getSpecialCharms()); } return prerequisiteModifyingCharms; } protected boolean isLearnableWithoutPrerequisites(ICharm charm) { if (!isLearnable(charm)) { return false; } for (ICharm parentCharm : charm.getLearnPrerequisitesCharms(this)) { if (!isLearned(parentCharm)) { return false; } } return true; } @Override public boolean isLearned(String charmId) { ICharm charm = getCharmById(charmId); return charm != null && isLearned(charm); } public final boolean isUnlearnable(ICharm charm) { ILearningCharmGroup group = getGroup(charm); return group.isUnlearnable(charm); } protected boolean isUnlearnableWithoutConsequences(ICharm charm) { ILearningCharmGroup group = getGroup(charm); return group.isUnlearnableWithoutConsequences(charm); } @Override public boolean isAlienCharm(ICharm charm) { return !isMartialArtsCharm(charm) && isAlienType(charm.getCharacterType()); } private boolean isAlienType(ICharacterType characterType) { return characterType != getNativeCharacterType(); } @Override public ISpecialCharmConfiguration getSpecialCharmConfiguration(String charmId) { ICharm charm = getCharmById(charmId); return getSpecialCharmConfiguration(charm); } @Override public final boolean isCompulsiveCharm(ICharm charm) { String[] compulsiveCharmIDs = context.getAdditionalRules().getCompulsiveCharmIDs(); return net.sf.anathema.lib.lang.ArrayUtilities.containsValue(compulsiveCharmIDs, charm.getId()); } @Override public final boolean isLearned(ICharm charm) { ILearningCharmGroup group = getGroup(charm); return group != null && group.isLearned(charm); } private ILearningCharmGroup getGroupById(ICharacterType characterType, String groupId) { List<ILearningCharmGroup> candidateGroups = new ArrayList<ILearningCharmGroup>(); Collections.addAll(candidateGroups, getCharmGroups(characterType)); Collections.addAll(candidateGroups, getMartialArtsGroups()); ICharmTemplate charmTemplate = templatesByType.get(characterType); if (charmTemplate.hasUniqueCharms()) { IUniqueCharmType uniqueType = charmTemplate.getUniqueCharmType(); Collections.addAll(candidateGroups, getCharmGroups(uniqueType.getId())); } for (ILearningCharmGroup group : candidateGroups) { if (group.getId().equals(groupId)) { return group; } } throw new IllegalArgumentException( "No charm group defined for Id: " + groupId + "," + characterType); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public final ILearningCharmGroup getGroup(ICharm charm) { return getGroupById(charm.getCharacterType(), charm.getGroupId()); } @Override public ICharm[] getCharms(ICharmGroup charmGroup) { return arbitrator.getCharms(charmGroup); } @Override public List<ICharmFilter> getCharmFilters() { return filterSet; } }
public class DefaultExperiencePointConfiguration implements ExperiencePointConfiguration { public static final ExperiencePointEntry NO_ENTRY = null; private ExperiencePointEntry currentlySelectedEntry = NO_ENTRY; private final List<ExperiencePointEntry> entries = new ArrayList<>(); private final Announcer<ExperiencePointConfigurationListener> control = Announcer.to(ExperiencePointConfigurationListener.class); private final Announcer<ExperienceSelectionListener> selectionAnnouncer = Announcer.to(ExperienceSelectionListener.class); @Override public ExperiencePointEntry[] getAllEntries() { return entries.toArray(new ExperiencePointEntry[entries.size()]); } @Override public ExperiencePointEntry addEntry() { ExperiencePointEntry newEntry = addEntryWithoutEvent(); fireChangeEvent(); return newEntry; } private ExperiencePointEntry addEntryWithoutEvent() { ExperiencePointEntry newEntry = new DefaultExperiencePointEntry(); entries.add(newEntry); return newEntry; } @Override public void removeEntry() { entries.remove(currentlySelectedEntry); fireChangeEvent(); selectForChange(NO_ENTRY); } private void fireChangeEvent() { control.announce().entriesAddedRemovedOrChanged(); } @Override public void addExperiencePointConfigurationListener( ExperiencePointConfigurationListener listener) { control.addListener(listener); } @Override public void addEntrySelectionListener(ExperienceSelectionListener listener) { selectionAnnouncer.addListener(listener); } @Override public int getTotalExperiencePoints() { int sum = 0; for (ExperiencePointEntry entry : getAllEntries()) { if (entry.getExperiencePoints() > 0) { sum += entry.getExperiencePoints(); } } return sum; } @Override public int getExtraSpendings() { int sum = 0; for (ExperiencePointEntry entry : getAllEntries()) { if (entry.getExperiencePoints() < 0) { sum -= entry.getExperiencePoints(); } } return sum; } @Override public void selectForChange(ExperiencePointEntry entry) { this.currentlySelectedEntry = entry; selectionAnnouncer.announce().selectionChanged(entry); } @Override public void updateCurrentSelection(String description, int points) { currentlySelectedEntry.getTextualDescription().setText(description); currentlySelectedEntry.setExperiencePoints(points); fireChangeEvent(); } @Override public ExperiencePointEntry getCurrentSelection() { return currentlySelectedEntry; } }
public class SpellView implements ISpellView { private MagicLearnView magicLearnView; private final JPanel content = new JPanel(new GridDialogLayout(1, false)); private final Announcer<ObjectValueListener> circleControl = Announcer.to(ObjectValueListener.class); private final SpellViewProperties properties; public SpellView(final SpellViewProperties properties) { this.properties = properties; this.magicLearnView = new MagicLearnView() { @Override protected ListSelectionListener createLearnedListListener(JButton button, JList list) { return properties.getRemoveButtonEnabledListener(button, list); } }; } @Override public JComponent getComponent() { return content; } @Override public void initGui(Identified[] circles) { JComponent selectionPanel = createSelectionPanel(circles); IGridDialogLayoutData data = GridDialogLayoutData.FILL_BOTH; content.add(selectionPanel, data); } private JPanel createSelectionPanel(Identified[] circles) { JPanel filterBox = createFilterBox( properties.getCircleLabel(), circles, properties.getCircleSelectionRenderer()); magicLearnView.init(properties); JPanel selectionPanel = new JPanel(new MigLayout(fillWithoutInsets())); selectionPanel.add(filterBox, new CC().wrap()); magicLearnView.addTo(selectionPanel); return selectionPanel; } public JPanel createFilterBox(String label, Object[] objects, ListCellRenderer renderer) { JPanel panel = new JPanel(new GridDialogLayout(2, false)); panel.add(new JLabel(label)); final JComboBox box = new JComboBox(objects); box.setRenderer(renderer); panel.add(box, GridDialogLayoutData.FILL_HORIZONTAL); box.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { circleControl.announce().valueChanged(box.getSelectedItem()); } }); return panel; } @Override public void addMagicViewListener(IMagicViewListener listener) { magicLearnView.addMagicViewListener(listener); } @Override public void addOptionListListener(ListSelectionListener listener) { magicLearnView.addOptionListListener(listener); } @Override public void addSelectionListListener(ListSelectionListener listener) { magicLearnView.addSelectionListListener(listener); } @Override public void addCircleSelectionListener(ObjectValueListener<CircleType> listener) { circleControl.addListener(listener); } @Override public void setLearnedMagic(Object[] spells) { magicLearnView.setLearnedMagic(spells); } @Override public void setMagicOptions(Object[] spells) { magicLearnView.setMagicOptions(spells); } @Override public void addLearnedMagic(Object[] magics) { magicLearnView.addLearnedMagic(magics); } @Override public void addMagicOptions(Identified[] magics, Comparator<Identified> comparator) { magicLearnView.addMagicOptions(magics, comparator); } @Override public void removeLearnedMagic(Object[] magics) { magicLearnView.removeLearnedMagic(magics); } @Override public void removeMagicOptions(Object[] magics) { magicLearnView.removeMagicOptions(magics); } @Override public void clearSelection() { magicLearnView.clearSelection(); } }
public class EquipmentModelImpl implements EquipmentOptionsProvider, EquipmentModel { private final List<IEquipmentItem> naturalWeaponItems = new ArrayList<>(); private final Table<IEquipmentItem, IEquipmentStats, List<IEquipmentStatsOption>> optionsTable = HashBasedTable.create(); private final Announcer<ChangeListener> modelChangeControl = Announcer.to(ChangeListener.class); private final Announcer<ICollectionListener> equipmentItemControl = Announcer.to(ICollectionListener.class); private final EquipmentCollection equipmentItems = new EquipmentCollection(); private IEquipmentTemplateProvider equipmentTemplateProvider; private final ChangeListener itemChangePropagator = this::fireModelChanged; private CharacterType characterType; private MagicalMaterial defaultMaterial; private EquipmentHeroEvaluator dataProvider; private IArmourStats naturalArmor; @Override public Identifier getId() { return ID; } @Override public void initialize(HeroEnvironment environment, Hero hero) { StatsModelFetcher.fetch(hero).addModifierFactory(this); Path dataBaseDirectory = environment.getDataFileProvider().getDataBaseDirectory(DATABASE_FOLDER); EquipmentDirectAccess access = new EquipmentDirectAccess(dataBaseDirectory); ObjectFactory objectFactory = environment.getObjectFactory(); MaterialRules materialRules = new ReflectionMaterialRules(objectFactory); CharacterType characterType = hero.getTemplate().getTemplateType().getCharacterType(); Trait stamina = TraitModelFetcher.fetch(hero).getTrait(AttributeType.Stamina); this.naturalArmor = new DefaultNaturalSoak(stamina, characterType); EquipmentHeroEvaluatorImpl dataProvider = new EquipmentHeroEvaluatorImpl(hero, materialRules); this.characterType = hero.getTemplate().getTemplateType().getCharacterType(); this.defaultMaterial = evaluateDefaultMaterial(materialRules); this.equipmentTemplateProvider = new GsonEquipmentDatabase(access); this.dataProvider = dataProvider; IEquipmentItem item = createItem(new NaturalWeaponTemplate(), null); naturalWeaponItems.add(item); new SpecialtiesCollectionImpl(hero) .addSpecialtyListChangeListener(new SpecialtyPrintRemover(dataProvider)); EssencePoolModelFetcher.fetch(hero).addEssencePoolModifier(this); } @Override public void initializeListening(ChangeAnnouncer announcer) { addChangeListener(new UnspecifiedChangeListener(announcer)); } @Override public EquipmentHeroEvaluator getHeroEvaluator() { return dataProvider; } @Override public EquipmentOptionsProvider getOptionProvider() { return this; } @Override public IArmourStats getNaturalArmor() { return naturalArmor; } private MagicalMaterial evaluateDefaultMaterial(MaterialRules materialRules) { MagicalMaterial defaultMaterial = materialRules.getDefault(characterType); if (defaultMaterial == null) { return MagicalMaterial.Orichalcum; } return defaultMaterial; } @Override public IEquipmentItem[] getNaturalWeapons() { return naturalWeaponItems.toArray(new IEquipmentItem[naturalWeaponItems.size()]); } @Override public boolean canBeRemoved(IEquipmentItem item) { return !naturalWeaponItems.contains(item); } @Override public String[] getAvailableTemplateIds() { return equipmentTemplateProvider.getAllAvailableTemplateIds(); } private IEquipmentTemplate loadEquipmentTemplate(String templateId) { return equipmentTemplateProvider.loadTemplate(templateId); } private IEquipmentItem getSpecialManagedItem(String templateId) { for (IEquipmentItem item : naturalWeaponItems) { if (templateId.equals(item.getTemplateId())) { return item; } } return null; } @Override public MagicalMaterial getDefaultMaterial() { return defaultMaterial; } private List<IEquipmentStatsOption> getOptionsList(IEquipmentItem item, IEquipmentStats stats) { List<IEquipmentStatsOption> list = optionsTable.get(item, stats); if (list == null) { list = new ArrayList<>(); optionsTable.put(item, stats, list); } return list; } @Override public void enableStatOption( IEquipmentItem item, IEquipmentStats stats, IEquipmentStatsOption option) { if (item == null || stats == null) { return; } getOptionsList(item, stats).add(option); fireModelChanged(); } @Override public void disableStatOption( IEquipmentItem item, IEquipmentStats stats, IEquipmentStatsOption option) { if (item == null || stats == null) { return; } getOptionsList(item, stats).remove(option); fireModelChanged(); } @Override public boolean isStatOptionEnabled( IEquipmentItem item, IEquipmentStats stats, IEquipmentStatsOption option) { return item != null && stats != null && getOptionsList(item, stats).contains(option); } @Override public IEquipmentStatsOption[] getEnabledStatOptions(IEquipmentItem item, IEquipmentStats stats) { if (item == null || stats == null) { return new IEquipmentStatsOption[0]; } List<IEquipmentStatsOption> options = getOptionsList(item, stats); return options.toArray(new IEquipmentStatsOption[options.size()]); } @Override public IEquipmentStatsOption[] getEnabledStatOptions(IEquipmentStats stats) { if (stats == null) { return new IEquipmentStatsOption[0]; } List<IEquipmentItem> itemList = new ArrayList<>(); itemList.addAll(naturalWeaponItems); Collections.addAll(itemList, getEquipmentItems()); for (IEquipmentItem item : itemList) { for (IEquipmentStats stat : item.getStats()) { if (stats.equals(stat)) { return getEnabledStatOptions(item, stat); } } } return new IEquipmentStatsOption[0]; } @Override public boolean transferOptions(IEquipmentItem fromItem, IEquipmentItem toItem) { boolean transferred = false; if (fromItem != null && toItem != null) { for (IEquipmentStats fromStats : fromItem.getStats()) { List<IEquipmentStatsOption> specialtyList = optionsTable.remove(fromItem, fromStats); boolean printCheckboxEnabled = fromItem.isPrintEnabled(fromStats); IEquipmentStats toStats = toItem.getStat(fromStats.getId()); if (toStats != null) { transferred = true; if (specialtyList != null) { optionsTable.put(toItem, toStats, specialtyList); } toItem.setPrintEnabled(toStats, printCheckboxEnabled); } } } return transferred; } @Override public IEquipmentItem[] getEquipmentItems() { return equipmentItems.asArray(); } @Override public IEquipmentItem addEquipmentObjectFor(String templateId, MagicalMaterial material) { IEquipmentTemplate template = loadEquipmentTemplate(templateId); if (template == null) { return getSpecialManagedItem(templateId); } return addEquipmentObjectFor(template, material); } private IEquipmentItem addEquipmentObjectFor( IEquipmentTemplate template, MagicalMaterial material) { IEquipmentItem item = createItem(template, material); equipmentItems.add(item); announceItemAndListenForChanges(item); return item; } private IEquipmentItem createItem(IEquipmentTemplate template, MagicalMaterial material) { return new EquipmentItem(template, null, null, material, getHeroEvaluator(), equipmentItems); } @Override public void removeItem(IEquipmentItem item) { equipmentItems.remove(item); announce().itemRemoved(item); item.removeChangeListener(itemChangePropagator); fireModelChanged(); } @SuppressWarnings("unchecked") private ICollectionListener<IEquipmentItem> announce() { return equipmentItemControl.announce(); } @Override public void updateItem(IEquipmentItem item) { fireModelChanged(); } private void fireModelChanged() { modelChangeControl.announce().changeOccurred(); } @Override public void refreshItems() { for (IEquipmentItem item : equipmentItems) { if (canBeRemoved(item)) { IEquipmentItem refreshedItem = refreshItem(item); if (refreshedItem != null) { refreshedItem.setPersonalization(item); getOptionProvider().transferOptions(item, refreshedItem); announceItemAndListenForChanges(refreshedItem); } } } } private void announceItemAndListenForChanges(IEquipmentItem refreshedItem) { announce().itemAdded(refreshedItem); refreshedItem.addChangeListener(itemChangePropagator); fireModelChanged(); } private IEquipmentItem refreshItem(IEquipmentItem item) { String templateId = item.getTemplateId(); MagicalMaterial material = item.getMaterial(); removeItem(item); return addEquipmentObjectFor(templateId, material); } @Override public void addEquipmentObjectListener(ICollectionListener<IEquipmentItem> listener) { equipmentItemControl.addListener(listener); } @Override public MaterialComposition getMaterialComposition(String templateId) { IEquipmentTemplate template = loadEquipmentTemplate(templateId); return template.getComposition(); } @Override public MagicalMaterial getMagicalMaterial(String templateId) { IEquipmentTemplate template = loadEquipmentTemplate(templateId); return template.getMaterial(); } public void addChangeListener(ChangeListener listener) { modelChangeControl.addListener(listener); } @Override public int getMotesExpended() { int total = 0; for (IEquipmentItem item : equipmentItems) { for (IEquipmentStats stats : item.getStats()) { if (stats instanceof ArtifactStats && item.getAttunementState() == ((ArtifactStats) stats).getAttuneType()) { total += ((ArtifactStats) stats).getAttuneCost(); } } } return total; } @Override public HeroStatsModifiers createStatsModifiers(Hero hero) { return CharacterStatsModifiers.extractFromCharacter(hero); } private class SpecialtyPrintRemover implements ChangeListener { private final EquipmentHeroEvaluator dataProvider; public SpecialtyPrintRemover(EquipmentHeroEvaluator dataProvider) { this.dataProvider = dataProvider; } @Override public void changeOccurred() { for (IEquipmentItem item : getEquipmentItems()) { for (IEquipmentStats stats : item.getStats()) { List<IEquipmentStatsOption> list = optionsTable.get(item, stats); if (list == null) { return; } List<IEquipmentStatsOption> optionsList = new ArrayList<>(list); for (IEquipmentStatsOption option : optionsList) { if (!characterStillHasCorrespondingSpecialty(option)) { disableStatOption(item, stats, option); } } } } } private boolean characterStillHasCorrespondingSpecialty(IEquipmentStatsOption option) { AbilityType trait = AbilityType.valueOf(option.getType()); Specialty[] specialties = dataProvider.getSpecialties(trait); return ArrayUtils.contains(specialties, option.getUnderlyingTrait()); } } @Override public String[] getAllAvailableTemplateIds() { return equipmentTemplateProvider.getAllAvailableTemplateIds(); } @Override public IEquipmentTemplate loadTemplate(String templateId) { return equipmentTemplateProvider.loadTemplate(templateId); } }