// 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;
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.HexNumber;
import org.infinity.datatype.IdsBitmap;
import org.infinity.datatype.ResourceRef;
import org.infinity.datatype.TextString;
import org.infinity.datatype.Unknown;
import org.infinity.gui.StructViewer;
import org.infinity.resource.AbstractStruct;
import org.infinity.resource.AddRemovable;
import org.infinity.resource.HasAddRemovable;
import org.infinity.resource.HasViewerTabs;
import org.infinity.resource.Profile;
import org.infinity.resource.StructEntry;
import org.infinity.resource.cre.CreResource;
import org.infinity.util.io.StreamUtils;
public final class Actor extends AbstractStruct implements AddRemovable, HasViewerTabs, HasAddRemovable
{
// ARE/Actor-specific field labels
public static final String ARE_ACTOR = "Actor";
public static final String ARE_ACTOR_NAME = "Name";
public static final String ARE_ACTOR_POS_X = "Position: X";
public static final String ARE_ACTOR_POS_Y = "Position: Y";
public static final String ARE_ACTOR_DEST_X = "Destination: X";
public static final String ARE_ACTOR_DEST_Y = "Destination: Y";
public static final String ARE_ACTOR_FLAGS = "Flags";
public static final String ARE_ACTOR_IS_SPAWNED = "Is spawned?";
public static final String ARE_ACTOR_DIFFICULTY = "Difficulty";
public static final String ARE_ACTOR_ANIMATION = "Animation";
public static final String ARE_ACTOR_ORIENTATION = "Orientation";
public static final String ARE_ACTOR_EXPIRY_TIME = "Expiry time";
public static final String ARE_ACTOR_WANDER_DISTANCE = "Wander distance";
public static final String ARE_ACTOR_FOLLOW_DISTANCE = "Follow distance";
public static final String ARE_ACTOR_PRESENT_AT = "Present at";
public static final String ARE_ACTOR_NUM_TIMES_TALKED_TO = "# times talked to";
public static final String ARE_ACTOR_DIALOG = "Dialogue";
public static final String ARE_ACTOR_SCRIPT_OVERRIDE = "Override script";
public static final String ARE_ACTOR_SCRIPT_SPECIAL_1 = "Special 1 script";
public static final String ARE_ACTOR_SCRIPT_SPECIAL_2 = "Special 2 script";
public static final String ARE_ACTOR_SCRIPT_SPECIAL_3 = "Special 3 script";
public static final String ARE_ACTOR_SCRIPT_COMBAT = "Combat script";
public static final String ARE_ACTOR_SCRIPT_MOVEMENT = "Movement script";
public static final String ARE_ACTOR_SCRIPT_TEAM = "Team script";
public static final String ARE_ACTOR_SCRIPT_GENERAL = "General script";
public static final String ARE_ACTOR_SCRIPT_CLASS = "Class script";
public static final String ARE_ACTOR_SCRIPT_RACE = "Race script";
public static final String ARE_ACTOR_SCRIPT_DEFAULT = "Default script";
public static final String ARE_ACTOR_SCRIPT_SPECIFICS = "Specifics script";
public static final String ARE_ACTOR_CHARACTER = "Character";
public static final String ARE_ACTOR_OFFSET_CRE_STRUCTURE = "CRE structure offset";
public static final String ARE_ACTOR_SIZE_CRE_STRUCTURE = "CRE structure size";
public static final String ARE_ACTOR_CRE_FILE = "CRE file";
public static final String[] s_orientation = { "South", "SSW", "SW", "WSW", "West", "WNW", "NW", "NNW",
"North", "NNE", "NE", "ENE", "East", "ESE", "SE", "SSE" };
public static final String[] s_noyes = {"No", "Yes"};
public static final String[] s_flags = {"CRE attached", "CRE not attached", "Has seen party",
"Toggle invulnerability", "Override script name"};
public static final String[] s_schedule = {"Not active", "00:30-01:29", "01:30-02:29", "02:30-03:29",
"03:30-04:29", "04:30-05:29", "05:30-06:29", "06:30-07:29",
"07:30-08:29", "08:30-09:29", "09:30-10:29", "10:30-11:29",
"11:30-12:29", "12:30-13:29", "13:30-14:29", "14:30-15:29",
"15:30-16:29", "16:30-17:29", "17:30-18:29", "18:30-19:29",
"19:30-20:29", "20:30-21:29", "21:30-22:29", "22:30-23:29",
"23:30-00:29"};
public static final String[] s_diff = {"None", "Level 1", "Level 2", "Level 3"};
public Actor() throws Exception
{
super(null, ARE_ACTOR, StreamUtils.getByteBuffer(272), 0);
}
public Actor(AbstractStruct superStruct, ByteBuffer buffer, int offset, int nr) throws Exception
{
super(superStruct, ARE_ACTOR + " " + nr, buffer, offset);
}
//--------------------- Begin Interface AddRemovable ---------------------
@Override
public boolean canRemove()
{
return true;
}
//--------------------- End Interface AddRemovable ---------------------
// --------------------- Begin Interface HasAddRemovable ---------------------
@Override
public AddRemovable[] getAddRemovables()
{
return new AddRemovable[]{};
}
@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 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 ViewerActor(this);
}
@Override
public boolean viewerTabAddedBefore(int index)
{
return true;
}
// --------------------- End Interface HasViewerTabs ---------------------
@Override
protected void datatypeAddedInChild(AbstractStruct child, AddRemovable datatype)
{
super.datatypeAddedInChild(child, datatype);
if (child instanceof CreResource)
((DecNumber)getAttribute(ARE_ACTOR_SIZE_CRE_STRUCTURE)).setValue(child.getSize());
}
@Override
protected void datatypeRemoved(AddRemovable datatype)
{
if (datatype instanceof CreResource) {
((DecNumber)getAttribute(ARE_ACTOR_SIZE_CRE_STRUCTURE)).setValue(0);
((HexNumber)getAttribute(ARE_ACTOR_OFFSET_CRE_STRUCTURE)).setValue(0);
}
}
@Override
protected void datatypeRemovedInChild(AbstractStruct child, AddRemovable datatype)
{
super.datatypeRemovedInChild(child, datatype);
if (child instanceof CreResource)
((DecNumber)getAttribute(ARE_ACTOR_SIZE_CRE_STRUCTURE)).setValue(child.getSize());
}
void updateCREOffset()
{
StructEntry entry = getField(getFieldCount() - 1);
if (entry instanceof CreResource)
((HexNumber)getAttribute(ARE_ACTOR_OFFSET_CRE_STRUCTURE)).setValue(entry.getOffset());
}
@Override
public int read(ByteBuffer buffer, int offset) throws Exception
{
addField(new TextString(buffer, offset, 32, ARE_ACTOR_NAME));
addField(new DecNumber(buffer, offset + 32, 2, ARE_ACTOR_POS_X));
addField(new DecNumber(buffer, offset + 34, 2, ARE_ACTOR_POS_Y));
addField(new DecNumber(buffer, offset + 36, 2, ARE_ACTOR_DEST_X));
addField(new DecNumber(buffer, offset + 38, 2, ARE_ACTOR_DEST_Y));
addField(new Flag(buffer, offset + 40, 4, ARE_ACTOR_FLAGS, s_flags));
addField(new Bitmap(buffer, offset + 44, 2, ARE_ACTOR_IS_SPAWNED, s_noyes));
if (Profile.getEngine() == Profile.Engine.IWD2) {
addField(new Unknown(buffer, offset + 46, 1));
addField(new Flag(buffer, offset + 47, 1, ARE_ACTOR_DIFFICULTY, s_diff));
}
else {
addField(new Unknown(buffer, offset + 46, 2));
}
addField(new IdsBitmap(buffer, offset + 48, 4, ARE_ACTOR_ANIMATION, "ANIMATE.IDS"));
addField(new Bitmap(buffer, offset + 52, 2, ARE_ACTOR_ORIENTATION, s_orientation));
addField(new Unknown(buffer, offset + 54, 2));
addField(new DecNumber(buffer, offset + 56, 4, ARE_ACTOR_EXPIRY_TIME));
addField(new DecNumber(buffer, offset + 60, 2, ARE_ACTOR_WANDER_DISTANCE));
addField(new DecNumber(buffer, offset + 62, 2, ARE_ACTOR_FOLLOW_DISTANCE));
addField(new Flag(buffer, offset + 64, 4, ARE_ACTOR_PRESENT_AT, s_schedule));
addField(new DecNumber(buffer, offset + 68, 4, ARE_ACTOR_NUM_TIMES_TALKED_TO));
addField(new ResourceRef(buffer, offset + 72, ARE_ACTOR_DIALOG, "DLG"));
addField(new ResourceRef(buffer, offset + 80, ARE_ACTOR_SCRIPT_OVERRIDE, "BCS"));
if (Profile.getEngine() == Profile.Engine.IWD2) {
addField(new ResourceRef(buffer, offset + 88, ARE_ACTOR_SCRIPT_SPECIAL_3, "BCS"));
addField(new ResourceRef(buffer, offset + 96, ARE_ACTOR_SCRIPT_SPECIAL_2, "BCS"));
addField(new ResourceRef(buffer, offset + 104, ARE_ACTOR_SCRIPT_COMBAT, "BCS"));
addField(new ResourceRef(buffer, offset + 112, ARE_ACTOR_SCRIPT_MOVEMENT, "BCS"));
addField(new ResourceRef(buffer, offset + 120, ARE_ACTOR_SCRIPT_TEAM, "BCS"));
}
else {
addField(new ResourceRef(buffer, offset + 88, ARE_ACTOR_SCRIPT_GENERAL, "BCS"));
addField(new ResourceRef(buffer, offset + 96, ARE_ACTOR_SCRIPT_CLASS, "BCS"));
addField(new ResourceRef(buffer, offset + 104, ARE_ACTOR_SCRIPT_RACE, "BCS"));
addField(new ResourceRef(buffer, offset + 112, ARE_ACTOR_SCRIPT_DEFAULT, "BCS"));
addField(new ResourceRef(buffer, offset + 120, ARE_ACTOR_SCRIPT_SPECIFICS, "BCS"));
}
if (buffer.get(offset + 128) == 0x2a) { // *
addField(new TextString(buffer, offset + 128, 8, ARE_ACTOR_CHARACTER));
}
else {
addField(new ResourceRef(buffer, offset + 128, ARE_ACTOR_CHARACTER, "CRE"));
}
HexNumber creOffset = new HexNumber(buffer, offset + 136, 4, ARE_ACTOR_OFFSET_CRE_STRUCTURE);
addField(creOffset);
DecNumber creSize = new DecNumber(buffer, offset + 140, 4, ARE_ACTOR_SIZE_CRE_STRUCTURE);
addField(creSize);
if (Profile.getEngine() == Profile.Engine.IWD2) {
addField(new ResourceRef(buffer, offset + 144, ARE_ACTOR_SCRIPT_SPECIAL_1, "BCS"));
addField(new Unknown(buffer, offset + 152, 120));
}
else {
addField(new Unknown(buffer, offset + 144, 128));
}
if (creOffset.getValue() > 0 && creSize.getValue() >= 0x2d4) {
addField(new CreResource(this, ARE_ACTOR_CRE_FILE, buffer, creOffset.getValue()));
}
return offset + 272;
}
}