de.ailis.wlandsuite.game.parts.ActionMap.java Source code

Java tutorial

Introduction

Here is the source code for de.ailis.wlandsuite.game.parts.ActionMap.java

Source

/*
 * $Id$
 * Copyright (C) 2006 Klaus Reimer <k@ailis.de>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

package de.ailis.wlandsuite.game.parts;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import de.ailis.wlandsuite.common.exceptions.GameException;
import de.ailis.wlandsuite.utils.XmlUtils;

/**
 * The Action Map describes the actions of all the map squares.
 *
 * @author Klaus Reimer (k@ailis.de)
 * @version $Revision$
 */

public class ActionMap {
    /** The actions */
    private final int[][] actions;

    /**
     * Constructs a new action map with the specified map size. Map size must be
     * 32 or 64. Any other value throws an IllegalArgumentException.
     *
     * @param mapSize
     *            The map size
     * @throws IllegalArgumentException
     *             If specified size is not 32 and not 64.
     */

    public ActionMap(final int mapSize) {
        // Validate the map size
        if (mapSize != 32 && mapSize != 64) {
            throw new IllegalArgumentException("Illegal map size specified: " + mapSize);
        }

        // Initialize the internal arrays
        this.actions = new int[mapSize][mapSize];
    }

    /**
     * Creates a new Action Map by reading it from the specified input stream.
     * The map size must be specified because it can't be read from the stream
     * automatically. Map size must be 32 or 64. Any other value throws an
     * IllegalArgumentException.
     *
     * @param stream
     *            The input stream to read the action map from
     * @param mapSize
     *            The map size (Must be 32 or 64)
     * @return The newly constructed Action Map
     * @throws IOException
     *             When file operation fails.
     * @throws IllegalArgumentException
     *             If specified size is not 32 and not 64.
     */

    public static ActionMap read(final InputStream stream, final int mapSize) throws IOException {
        ActionMap actionMap;

        // Create the action map
        actionMap = new ActionMap(mapSize);

        // Parse the actions from the stream
        for (int y = 0; y < mapSize; y++) {
            for (int x = 0; x < mapSize; x++) {
                // Read the action from the stream
                actionMap.actions[y][x] = stream.read();
            }
        }

        // Return the newly constructed action map
        return actionMap;
    }

    /**
     * Writes the action map to the specified output stream.
     *
     * @param stream
     *            The output stream to write the action map to
     * @throws IOException
     *             When file operation fails.
     */

    public void write(final OutputStream stream) throws IOException {
        int mapSize;

        // Determine the map size;
        mapSize = this.actions.length;

        // Write the actions
        for (int y = 0; y < mapSize; y++) {
            for (int x = 0; x < mapSize; x++) {
                stream.write(this.actions[y][x]);
            }
        }
    }

    /**
     * Creates and returns a new action map read from XML.
     *
     * @param element
     *            The XML element
     * @param mapSize
     *            The map size
     * @return The action map
     */

    public static ActionMap read(final Element element, final int mapSize) {
        ActionMap actionMap;
        String data;
        int i;
        int b;
        String s;

        // Create the new action map
        actionMap = new ActionMap(mapSize);

        // Parse the actions
        data = element.getTextTrim();
        i = 0;
        for (int y = 0; y < mapSize; y++) {
            for (int x = 0; x < mapSize; x++) {
                try {
                    s = data.substring(i * 3, i * 3 + 2);
                } catch (final StringIndexOutOfBoundsException e) {
                    throw new GameException("Action selector map is corrupt: "
                            + (mapSize * mapSize - (y * mapSize + x)) + " bytes missing");
                }
                if (s.equals(".."))
                    s = "00";
                try {
                    b = Integer.valueOf(s, 16);
                } catch (final NumberFormatException e) {
                    throw new GameException("Illegal data in action selector map at y=" + y + " x=" + x);
                }
                actionMap.actions[y][x] = b;
                i++;
            }
        }

        // Return the newly created action map
        return actionMap;
    }

    /**
     * Returns the action map in XML format.
     *
     * @param actionClassMap
     *            The action class map
     * @return The action map in XML
     */

    public Element toXml(final ActionClassMap actionClassMap) {
        Element element;
        StringWriter text;
        PrintWriter writer;
        int mapSize;

        // Determine the map size
        mapSize = this.actions.length;

        // Create the root XML element
        element = XmlUtils.createElement("actionMap");

        // Write the actions content
        text = new StringWriter();
        writer = new PrintWriter(text);
        writer.println();
        for (int y = 0; y < mapSize; y++) {
            writer.print("    ");
            for (int x = 0; x < mapSize; x++) {
                int b;

                if (x > 0) {
                    writer.print(" ");
                }

                b = this.actions[y][x];
                if (b == 0 && (actionClassMap.getActionClass(x, y) == 0)) {
                    writer.print("..");
                } else {
                    writer.format("%02x", new Object[] { b });
                }
            }
            writer.println();
        }
        writer.print("  ");
        element.add(DocumentHelper.createText(text.toString()));

        // Return the XML element
        return element;
    }

    /**
     * Returns the action at the specified position
     *
     * @param x
     *            The x position
     * @param y
     *            The y position
     * @return The action
     */

    public int getAction(final int x, final int y) {
        return this.actions[y][x];
    }

    /**
     * Sets the action at the specified position.
     *
     * @param x
     *            The x position
     * @param y
     *            The y position
     * @param action
     *            The action to set
     */

    public void setAction(final int x, final int y, final int action) {
        this.actions[y][x] = action;
    }
}