neon.resources.builder.ModLoader.java Source code

Java tutorial

Introduction

Here is the source code for neon.resources.builder.ModLoader.java

Source

/*
 *   Neon, a roguelike engine.
 *   Copyright (C) 2013 - Maarten Driesen
 * 
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package neon.resources.builder;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import neon.core.Engine;
import neon.core.event.TaskQueue;
import neon.resources.*;
import neon.resources.quest.RQuest;
import neon.systems.files.FileSystem;
import neon.systems.files.StringTranslator;
import neon.systems.files.XMLTranslator;

import org.jdom2.*;

public class ModLoader {
    private String path;
    private TaskQueue queue;
    private FileSystem files;
    private ResourceManager resources;

    public ModLoader(String mod, TaskQueue queue, FileSystem files, ResourceManager resources) {
        this.queue = queue;
        this.files = files;
        this.resources = resources;

        try {
            path = files.mount(mod);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public RMod loadMod(CGame game, CClient client) {
        // main.xml laden
        Element mod = files.getFile(new XMLTranslator(), path, "main.xml").getRootElement();

        // cc.xml laden
        Element cc = null;
        if (files.exists(path, "cc.xml")) {
            cc = files.getFile(new XMLTranslator(), path, "cc.xml").getRootElement();
        }

        RMod rmod = new RMod(mod, cc);
        rmod.addMaps(initMaps(path, "maps"));

        initMain(client, mod);
        if (mod.getName().equals("extension")) {
            if (!resources.hasResource(mod.getChild("master").getText(), "mods")) {
                System.err.println("Extension master not found: " + path + ".");
            }
        }

        // terrain
        if (files.exists(path, "terrain.xml")) {
            initTerrain(path, "terrain.xml");
        }

        // books
        if (files.listFiles(path, "books") != null) {
            initBooks(path, "books"); // laden voor items, anders vindt book zijn text niet
        }

        // items
        initItems(path, "items.xml"); // items
        initItems(path, "crafting.xml"); // crafting

        // themes (na terrain en items, want themes bevatten terrain en items)
        initThemes(path, "themes", "dungeons.xml"); // dungeons
        initThemes(path, "themes", "zones.xml"); // zones
        initThemes(path, "themes", "regions.xml"); // regions

        // creatures
        initCreatures(path, "monsters.xml"); // species
        initCreatures(path, "npc.xml"); // people

        // scripts
        if (files.listFiles(path, "scripts") != null) {
            initScripts(path, "scripts");
        }

        // events
        if (files.exists(path, "events.xml")) {
            initTasks(path, "events.xml");
        }

        // character creation
        if (files.exists(path, "cc.xml")) {
            initCC(game, path, "cc.xml");
        }

        // random quests
        if (files.listFiles(path, "quests") != null) {
            initQuests(path, "quests");
        }

        // magic
        initMagic(path, "spells.xml"); // spells
        initMagic(path, "alchemy.xml"); // alchemy
        initMagic(path, "signs.xml"); // birth signs
        initMagic(path, "tattoos.xml"); // tattoos

        return rmod;
    }

    private void initMain(CClient client, Element info) {
        if (info.getChild("title") != null) {
            client.setTitle(info.getChild("title").getText());
        }
        if (info.getChild("currency") != null) {
            if (info.getChild("currency").getAttributeValue("big") != null) {
                client.setBig(info.getChild("currency").getAttributeValue("big"));
            }
            if (info.getChild("currency").getAttributeValue("small") != null) {
                client.setSmall(info.getChild("currency").getAttributeValue("small"));
            }
        }
    }

    private void initQuests(String... file) {
        try {
            for (String s : files.listFiles(file)) {
                s = s.substring(s.lastIndexOf("/") + 1);
                String quest = s.substring(s.lastIndexOf(File.separator) + 1);
                Document doc = files.getFile(new XMLTranslator(), path, "quests", quest);
                resources.addResource(new RQuest(quest.replace(".xml", ""), doc.getRootElement()), "quest");
            }
        } catch (Exception e) { // gebeurt bij .svn directory
            e.printStackTrace();
            Engine.getLogger().fine("Error loading quest in mod " + path);
        }
    }

    private void initBooks(String... file) {
        try {
            for (String s : files.listFiles(file)) {
                s = s.substring(s.lastIndexOf("/") + 1);
                String id = s.substring(s.lastIndexOf(File.separator) + 1);
                Resource book = new RText(id, files, path, "books", id);
                resources.addResource(book, "text");
            }
        } catch (Exception e) {
            Engine.getLogger().fine("No books in mod " + path);
        }
    }

    private ArrayList<String[]> initMaps(String... file) {
        ArrayList<String[]> maps = new ArrayList<String[]>();
        for (String s : files.listFiles(file)) {
            /* gefoefel met separators om jar of folder files te krijgen:
             * substrings moeten er allebei instaan als het om jars gaat
             */
            s = s.substring(s.lastIndexOf("/") + 1);
            s = s.substring(s.lastIndexOf(File.separator) + 1);
            String[] map = { path, "maps", s };
            maps.add(map);
        }
        return maps;
    }

    private void initCreatures(String... file) {
        if (files.exists(file)) {
            Element creatures = files.getFile(new XMLTranslator(), file).getRootElement();
            for (Element c : creatures.getChildren()) {
                switch (c.getName()) {
                case "npc":
                    resources.addResource(new RPerson(c));
                    break;
                case "list":
                    resources.addResource(new LCreature(c));
                    break;
                default:
                    resources.addResource(new RCreature(c));
                    break;
                }
            }
        }
    }

    private void initItems(String... file) {
        if (files.exists(file)) {
            Element items = files.getFile(new XMLTranslator(), file).getRootElement();
            for (Element e : items.getChildren()) {
                switch (e.getName()) {
                case "book":
                case "scroll":
                    resources.addResource(new RItem.Text(e));
                    break;
                case "weapon":
                    resources.addResource(new RWeapon(e));
                    break;
                case "craft":
                    resources.addResource(new RCraft(e), "craft");
                    break;
                case "door":
                    resources.addResource(new RItem.Door(e));
                    break;
                case "potion":
                    resources.addResource(new RItem.Potion(e));
                    break;
                case "container":
                    resources.addResource(new RItem.Container(e));
                    break;
                case "list":
                    resources.addResource(new LItem(e));
                    break;
                case "armor":
                case "clothing":
                    resources.addResource(new RClothing(e));
                    break;
                default:
                    resources.addResource(new RItem(e));
                    break;
                }
            }
        }
    }

    private void initTerrain(String... file) {
        Element terrain = files.getFile(new XMLTranslator(), file).getRootElement();
        for (Element e : terrain.getChildren()) {
            resources.addResource(new RTerrain(e), "terrain");
        }
    }

    private void initThemes(String... file) {
        if (files.exists(file)) {
            Element themes = files.getFile(new XMLTranslator(), file).getRootElement();
            for (Element theme : themes.getChildren()) {
                switch (theme.getName()) {
                case "dungeon":
                    resources.addResource(new RDungeonTheme(theme), "theme");
                    break;
                case "zone":
                    resources.addResource(new RZoneTheme(theme), "theme");
                    break;
                case "region":
                    resources.addResource(new RRegionTheme(theme), "theme");
                    break;
                }
            }
        }
    }

    private void initMagic(String... file) {
        if (files.exists(file)) {
            Element spells = files.getFile(new XMLTranslator(), file).getRootElement();
            for (Element resource : spells.getChildren()) {
                switch (resource.getName()) {
                case "sign":
                    resources.addResource(new RSign(resource), "magic");
                    break;
                case "tattoo":
                    resources.addResource(new RTattoo(resource), "magic");
                    break;
                case "recipe":
                    resources.addResource(new RRecipe(resource), "magic");
                    break;
                case "list":
                    resources.addResource(new LSpell(resource), "magic");
                    break;
                case "power":
                    resources.addResource(new RSpell.Power(resource), "magic");
                    break;
                case "enchant":
                    resources.addResource(new RSpell.Enchantment(resource), "magic");
                    break;
                default:
                    resources.addResource(new RSpell(resource), "magic");
                    break;
                }
            }
        }
    }

    private void initScripts(String... file) {
        try {
            for (String s : files.listFiles(file)) {
                s = s.substring(s.lastIndexOf("/") + 1);
                s = s.substring(s.lastIndexOf(File.separator) + 1);
                String[] path = new String[file.length + 1];
                path[file.length] = s;
                System.arraycopy(file, 0, path, 0, file.length);
                RScript script = new RScript(s.replaceAll(".js", ""), files.getFile(new StringTranslator(), path));
                resources.addResource(script, "script");
            }
        } catch (Exception e) {
            Engine.getLogger().fine("No scripts in mod " + path);
        }
    }

    /*
     * Initializes all character creation data.
     * 
     * @param file
     */
    private void initCC(CGame game, String... file) {
        Element cc = files.getFile(new XMLTranslator(), file).getRootElement();
        int x = Integer.parseInt(cc.getChild("map").getAttributeValue("x"));
        int y = Integer.parseInt(cc.getChild("map").getAttributeValue("y"));
        if (cc.getChild("map").getAttributeValue("z") != null) {
            game.setStartZone(Integer.parseInt(cc.getChild("map").getAttributeValue("z")));
        }
        game.getStartPosition().setLocation(x, y);
        String[] path = { file[0], "maps", cc.getChild("map").getAttributeValue("path") + ".xml" };
        game.setStartMap(path);
        for (Element e : cc.getChildren("race")) {
            game.getPlayableRaces().add(e.getText());
        }
        for (Element e : cc.getChildren("item")) {
            game.getStartingItems().add(e.getText());
        }
        for (Element e : cc.getChildren("spell")) {
            game.getStartingSpells().add(e.getText());
        }
    }

    private void initTasks(String... file) {
        Document doc = files.getFile(new XMLTranslator(), file);
        for (Element e : doc.getRootElement().getChildren()) {
            String[] ticks = e.getAttributeValue("tick").split(":");
            RScript rs = (RScript) resources.getResource(e.getAttributeValue("script"), "script");
            if (ticks.length == 1) { // ene tick: gewoon toevoegen op dat tijdstip
                queue.add(rs.script, Integer.parseInt(ticks[0]), 0, 0);
            } else if (ticks.length == 2) { // twee ticks
                if (!ticks[0].isEmpty()) {
                    ticks[0] = "0";
                }
                if (!ticks[1].isEmpty()) { // indien periode 0, maar 1 keer uitvoeren
                    queue.add(rs.script, Integer.parseInt(ticks[0]), 0, 0);
                } else { // anders met periode vanaf start
                    queue.add(rs.script, Integer.parseInt(ticks[0]), Integer.parseInt(ticks[1]), 0);
                }
            } else if (ticks.length == 3) { // drie ticks
                if (!ticks[2].isEmpty()) {
                    ticks[2] = "0";
                }
                if (!ticks[1].isEmpty() || ticks[1].equals("0")) { // indien periode 0, enkel op begin en eind uitvoeren
                    queue.add(rs.script, Integer.parseInt(ticks[0]), 0, 0);
                    queue.add(rs.script, Integer.parseInt(ticks[2]), 0, 0);
                } else { // anders met periode vanaf start tot stop
                    queue.add(rs.script, Integer.parseInt(ticks[0]), Integer.parseInt(ticks[1]),
                            Integer.parseInt(ticks[2]));
                }
            }
        }
    }
}