// 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.itm; import java.nio.ByteBuffer; import javax.swing.JComponent; import org.infinity.datatype.Bitmap; import org.infinity.datatype.DecNumber; import org.infinity.datatype.Flag; import org.infinity.datatype.PriTypeBitmap; import org.infinity.datatype.ProRef; import org.infinity.datatype.ResourceRef; import org.infinity.datatype.SecTypeBitmap; import org.infinity.datatype.SectionCount; import org.infinity.datatype.UnsignDecNumber; import org.infinity.gui.StructViewer; import org.infinity.resource.AbstractAbility; import org.infinity.resource.AbstractStruct; import org.infinity.resource.AddRemovable; import org.infinity.resource.Effect; import org.infinity.resource.HasAddRemovable; import org.infinity.resource.HasViewerTabs; import org.infinity.resource.Profile; import org.infinity.resource.ResourceFactory; import org.infinity.util.io.StreamUtils; public final class Ability extends AbstractAbility implements AddRemovable, HasAddRemovable, HasViewerTabs { // ITM/Ability-specific field labels (more fields defined in AbstractAbility) public static final String ITM_ABIL = "Item ability"; public static final String ITM_ABIL_IDENTIFY_TO_USE = "Identify to use?"; public static final String ITM_ABIL_DICE_SIZE_ALT = "Alternate dice size"; public static final String ITM_ABIL_LAUNCHER_REQUIRED = "Launcher required"; public static final String ITM_ABIL_DICE_COUNT_ALT = "Alternate # dice thrown"; public static final String ITM_ABIL_SPEED = "Speed"; public static final String ITM_ABIL_DAMAGE_BONUS_ALT = "Alternate damage bonus"; public static final String ITM_ABIL_PRIMARY_TYPE = "Primary type (school)"; public static final String ITM_ABIL_SECONDARY_TYPE = "Secondary type"; public static final String ITM_ABIL_WHEN_DRAINED = "When drained"; public static final String ITM_ABIL_FLAGS = "Flags"; public static final String ITM_ABIL_ANIM_OVERHAND = "Animation: Overhand swing %"; public static final String ITM_ABIL_ANIM_BACKHAND = "Animation: Backhand swing %"; public static final String ITM_ABIL_ANIM_THRUST = "Animation: Thrust %"; public static final String ITM_ABIL_IS_ARROW = "Is arrow?"; public static final String ITM_ABIL_IS_BOLT = "Is bolt?"; public static final String ITM_ABIL_IS_BULLET = "Is bullet?"; public static final String[] s_noyes = {"No", "Yes"}; public static final String[] s_drain = {"Item remains", "Item vanishes", "Replace with used up", "Item recharges"}; public static final String[] s_launcher = {"None", "Bow", "Crossbow", "Sling"}; public static final String[] s_abilityuse = {"", "Weapon slots", "", "Item slots", "Gem?"}; public static final String[] s_recharge = { "No flags set", "Add strength bonus", "Breakable", "EE: Damage strength bonus", "EE: THAC0 strength bonus", "", "", "", "", "", "", "Hostile", "Recharge after resting", "", "", "", "", "Bypass armor", "Keen edge", "", "", "", "", "", "", "", "Ex: Toggle backstab", "Ex: Cannot target invisible"}; Ability() throws Exception { super(null, ITM_ABIL, StreamUtils.getByteBuffer(56), 0); } Ability(AbstractStruct superStruct, ByteBuffer buffer, int offset, int number) throws Exception { super(superStruct, ITM_ABIL + " " + number, buffer, offset); } // --------------------- Begin Interface HasAddRemovable --------------------- @Override public AddRemovable[] getAddRemovables() throws Exception { return new AddRemovable[]{new Effect()}; } @Override public AddRemovable confirmAddEntry(AddRemovable entry) throws Exception { return entry; } @Override public boolean confirmRemoveEntry(AddRemovable entry) throws Exception { return true; } // --------------------- End Interface HasAddRemovable --------------------- //--------------------- Begin Interface AddRemovable --------------------- @Override public boolean canRemove() { return true; } //--------------------- End Interface AddRemovable --------------------- // --------------------- Begin Interface HasViewerTabs --------------------- @Override public int getViewerTabCount() { return 1; } @Override public String getViewerTabName(int index) { return StructViewer.TAB_VIEW; } @Override public JComponent getViewerTab(int index) { return new ViewerAbility(this); } @Override public boolean viewerTabAddedBefore(int index) { return true; } // --------------------- End Interface HasViewerTabs --------------------- @Override public int read(ByteBuffer buffer, int offset) throws Exception { if (Profile.getEngine() == Profile.Engine.BG2 || Profile.isEnhancedEdition()) { addField(new Bitmap(buffer, offset, 1, ABILITY_TYPE, s_type)); addField(new Bitmap(buffer, offset + 1, 1, ITM_ABIL_IDENTIFY_TO_USE, s_noyes)); addField(new Bitmap(buffer, offset + 2, 1, ABILITY_LOCATION, s_abilityuse)); addField(new DecNumber(buffer, offset + 3, 1, ITM_ABIL_DICE_SIZE_ALT)); addField(new ResourceRef(buffer, offset + 4, ABILITY_ICON, "BAM")); addField(new Bitmap(buffer, offset + 12, 1, ABILITY_TARGET, s_targettype)); addField(new UnsignDecNumber(buffer, offset + 13, 1, ABILITY_NUM_TARGETS)); addField(new DecNumber(buffer, offset + 14, 2, ABILITY_RANGE)); addField(new Bitmap(buffer, offset + 16, 1, ITM_ABIL_LAUNCHER_REQUIRED, s_launcher)); addField(new DecNumber(buffer, offset + 17, 1, ITM_ABIL_DICE_COUNT_ALT)); addField(new DecNumber(buffer, offset + 18, 1, ITM_ABIL_SPEED)); addField(new DecNumber(buffer, offset + 19, 1, ITM_ABIL_DAMAGE_BONUS_ALT)); addField(new DecNumber(buffer, offset + 20, 2, ABILITY_HIT_BONUS)); addField(new DecNumber(buffer, offset + 22, 1, ABILITY_DICE_SIZE)); addField(new PriTypeBitmap(buffer, offset + 23, 1, ITM_ABIL_PRIMARY_TYPE)); addField(new DecNumber(buffer, offset + 24, 1, ABILITY_DICE_COUNT)); addField(new SecTypeBitmap(buffer, offset + 25, 1, ITM_ABIL_SECONDARY_TYPE)); } else { addField(new Bitmap(buffer, offset, 1, ABILITY_TYPE, s_type)); addField(new Bitmap(buffer, offset + 1, 1, ITM_ABIL_IDENTIFY_TO_USE, s_noyes)); addField(new Bitmap(buffer, offset + 2, 2, ABILITY_LOCATION, s_abilityuse)); addField(new ResourceRef(buffer, offset + 4, ABILITY_ICON, "BAM")); addField(new Bitmap(buffer, offset + 12, 2, ABILITY_TARGET, s_targettype)); addField(new DecNumber(buffer, offset + 14, 2, ABILITY_RANGE)); addField(new Bitmap(buffer, offset + 16, 2, ITM_ABIL_LAUNCHER_REQUIRED, s_launcher)); addField(new DecNumber(buffer, offset + 18, 2, ITM_ABIL_SPEED)); addField(new DecNumber(buffer, offset + 20, 2, ABILITY_HIT_BONUS)); addField(new DecNumber(buffer, offset + 22, 2, ABILITY_DICE_SIZE)); addField(new DecNumber(buffer, offset + 24, 2, ABILITY_DICE_COUNT)); } addField(new DecNumber(buffer, offset + 26, 2, ABILITY_DAMAGE_BONUS)); addField(new Bitmap(buffer, offset + 28, 2, ABILITY_DAMAGE_TYPE, s_dmgtype)); addField(new SectionCount(buffer, offset + 30, 2, ABILITY_NUM_EFFECTS, Effect.class)); addField(new DecNumber(buffer, offset + 32, 2, ABILITY_FIRST_EFFECT_INDEX)); addField(new DecNumber(buffer, offset + 34, 2, ABILITY_NUM_CHARGES)); addField(new Bitmap(buffer, offset + 36, 2, ITM_ABIL_WHEN_DRAINED, s_drain)); addField(new Flag(buffer, offset + 38, 4, ITM_ABIL_FLAGS, s_recharge)); if (ResourceFactory.resourceExists("PROJECTL.IDS")) { addField(new ProRef(buffer, offset + 42, ABILITY_PROJECTILE)); } else if (Profile.getEngine() == Profile.Engine.PST) { addField(new Bitmap(buffer, offset + 42, 2, ABILITY_PROJECTILE, s_proj_pst)); } else if (Profile.getEngine() == Profile.Engine.IWD || Profile.getEngine() == Profile.Engine.IWD2) { addField(new Bitmap(buffer, offset + 42, 2, ABILITY_PROJECTILE, s_proj_iwd)); } else { addField(new Bitmap(buffer, offset + 42, 2, ABILITY_PROJECTILE, s_projectile)); } addField(new DecNumber(buffer, offset + 44, 2, ITM_ABIL_ANIM_OVERHAND)); addField(new DecNumber(buffer, offset + 46, 2, ITM_ABIL_ANIM_BACKHAND)); addField(new DecNumber(buffer, offset + 48, 2, ITM_ABIL_ANIM_THRUST)); addField(new Bitmap(buffer, offset + 50, 2, ITM_ABIL_IS_ARROW, s_noyes)); addField(new Bitmap(buffer, offset + 52, 2, ITM_ABIL_IS_BOLT, s_noyes)); addField(new Bitmap(buffer, offset + 54, 2, ITM_ABIL_IS_BULLET, s_noyes)); return offset + 56; } }