// Near Infinity - An Infinity Engine Browser and Editor // Copyright (C) 2001 - 2005 Jon Olav Hauglid // See LICENSE.txt for license information package org.infinity.resource.are.viewer; import java.awt.Image; import java.awt.Point; import java.nio.file.Files; import java.nio.file.Path; import org.infinity.datatype.Bitmap; import org.infinity.datatype.DecNumber; import org.infinity.datatype.HexNumber; import org.infinity.datatype.SectionCount; import org.infinity.datatype.SectionOffset; import org.infinity.datatype.StringRef; import org.infinity.datatype.TextEdit; import org.infinity.gui.layeritem.AbstractLayerItem; import org.infinity.gui.layeritem.IconLayerItem; import org.infinity.icon.Icons; import org.infinity.resource.Profile; import org.infinity.resource.Viewable; import org.infinity.resource.are.AreResource; import org.infinity.resource.are.AutomapNote; import org.infinity.resource.are.viewer.icon.ViewerIcons; import org.infinity.resource.key.FileResourceEntry; import org.infinity.resource.to.StrRefEntry; import org.infinity.resource.to.StrRefEntry2; import org.infinity.resource.to.StringEntry; import org.infinity.resource.to.StringEntry2; import org.infinity.resource.to.TohResource; import org.infinity.resource.to.TotResource; import org.infinity.util.io.FileManager; /** * Handles specific layer type: ARE/Automap Note (except for PST) */ public class LayerObjectAutomap extends LayerObject { private static final Image[] Icon = {Icons.getImage(ViewerIcons.class, ViewerIcons.ICON_ITM_AUTOMAP_1), Icons.getImage(ViewerIcons.class, ViewerIcons.ICON_ITM_AUTOMAP_2)}; private static Point Center = new Point(26, 26); private final AutomapNote note; private final Point location = new Point(); private IconLayerItem item; public LayerObjectAutomap(AreResource parent, AutomapNote note) { super(ViewerConstants.RESOURCE_ARE, "Automap", AutomapNote.class, parent); this.note = note; init(); } @Override public Viewable getViewable() { return note; } @Override public Viewable[] getViewables() { return new Viewable[]{note}; } @Override public AbstractLayerItem getLayerItem() { return item; } @Override public AbstractLayerItem getLayerItem(int type) { return (type == 0) ? item : null; } @Override public AbstractLayerItem[] getLayerItems() { return new AbstractLayerItem[]{item}; } @Override public void reload() { init(); } @Override public void update(double zoomFactor) { if (item != null) { item.setItemLocation((int)(location.x*zoomFactor + (zoomFactor / 2.0)), (int)(location.y*zoomFactor + (zoomFactor / 2.0))); } } @Override public Point getMapLocation() { return location; } @Override public Point[] getMapLocations() { return new Point[]{location}; } private void init() { if (note != null) { String msg = ""; try { location.x = ((DecNumber)note.getAttribute(AutomapNote.ARE_AUTOMAP_LOCATION_X)).getValue(); location.y = ((DecNumber)note.getAttribute(AutomapNote.ARE_AUTOMAP_LOCATION_Y)).getValue(); if (((Bitmap)note.getAttribute(AutomapNote.ARE_AUTOMAP_TEXT_LOCATION)).getValue() == 1) { // fetching string from dialog.tlk msg = ((StringRef)note.getAttribute(AutomapNote.ARE_AUTOMAP_TEXT)).toString(); } else { // fetching string from talk override msg = "[user-defined]"; try { int srcStrref = ((StringRef)note.getAttribute(AutomapNote.ARE_AUTOMAP_TEXT)).getValue(); if (srcStrref > 0) { String path = getParentStructure().getResourceEntry().getActualPath().toString(); path = path.replace(getParentStructure().getResourceEntry().getResourceName(), ""); if (Profile.isEnhancedEdition()) { // processing new TOH structure Path tohFile = FileManager.resolve(path, "DEFAULT.TOH"); if (Files.exists(tohFile)) { FileResourceEntry tohEntry = new FileResourceEntry(tohFile); TohResource toh = new TohResource(tohEntry); SectionOffset so = (SectionOffset)toh.getAttribute(TohResource.TOH_OFFSET_ENTRIES); SectionCount sc = (SectionCount)toh.getAttribute(TohResource.TOH_NUM_ENTRIES); if (so != null && sc != null && sc.getValue() > 0) { for (int i = 0, count = sc.getValue(), curOfs = so.getValue(); i < count; i++) { StrRefEntry2 strref = (StrRefEntry2)toh.getAttribute(curOfs, false); if (strref != null) { int v = ((StringRef)strref.getAttribute(StrRefEntry2.TOH_STRREF_OVERRIDDEN)).getValue(); if (v == srcStrref) { int sofs = ((HexNumber)strref.getAttribute(StrRefEntry2.TOH_STRREF_OFFSET_STRING)).getValue(); StringEntry2 se = (StringEntry2)toh.getAttribute(so.getValue() + sofs, false); if (se != null) { msg = ((TextEdit)se.getAttribute(StringEntry2.TOH_STRING_TEXT)).toString(); } break; } curOfs += strref.getSize(); } } } } } else { // processing legacy TOH/TOT structures Path tohFile = FileManager.resolve(path, "DEFAULT.TOH"); Path totFile = FileManager.resolve(path, "DEFAULT.TOT"); if (Files.exists(tohFile) && Files.exists(totFile)) { FileResourceEntry tohEntry = new FileResourceEntry(tohFile); FileResourceEntry totEntry = new FileResourceEntry(totFile); TohResource toh = new TohResource(tohEntry); TotResource tot = new TotResource(totEntry); SectionCount sc = (SectionCount)toh.getAttribute(TohResource.TOH_NUM_ENTRIES); if (sc != null && sc.getValue() > 0) { for (int i = 0, count = sc.getValue(), curOfs = 0x14; i < count; i++) { StrRefEntry strref = (StrRefEntry)toh.getAttribute(curOfs, false); if (strref != null) { int v = ((StringRef)strref.getAttribute(StrRefEntry.TOH_STRREF_OVERRIDDEN)).getValue(); if (v == srcStrref) { int sofs = ((HexNumber)strref.getAttribute(StrRefEntry.TOH_STRREF_OFFSET_TOT_STRING)).getValue(); StringEntry se = (StringEntry)tot.getAttribute(sofs, false); if (se != null) { msg = ((TextEdit)se.getAttribute(StringEntry.TOT_STRING_TEXT)).toString(); } break; } curOfs += strref.getSize(); } } } } } } } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } // Using cached icons Image[] icon; String keyIcon = String.format("%1$s%2$s", SharedResourceCache.createKey(Icon[0]), SharedResourceCache.createKey(Icon[1])); if (SharedResourceCache.contains(SharedResourceCache.Type.ICON, keyIcon)) { icon = ((ResourceIcon)SharedResourceCache.get(SharedResourceCache.Type.ICON, keyIcon)).getData(); SharedResourceCache.add(SharedResourceCache.Type.ICON, keyIcon); } else { icon = Icon; SharedResourceCache.add(SharedResourceCache.Type.ICON, keyIcon, new ResourceIcon(keyIcon, icon)); } item = new IconLayerItem(location, note, msg, icon[0], Center); item.setName(getCategory()); item.setToolTipText(msg); item.setImage(AbstractLayerItem.ItemState.HIGHLIGHTED, icon[1]); item.setVisible(isVisible()); } } }