package net.alcuria.umbracraft; import net.alcuria.umbracraft.definitions.Definition; import net.alcuria.umbracraft.definitions.FlagDefinition; import net.alcuria.umbracraft.definitions.ListDefinition; import net.alcuria.umbracraft.definitions.anim.AnimationCollectionDefinition; import net.alcuria.umbracraft.definitions.anim.AnimationDefinition; import net.alcuria.umbracraft.definitions.anim.AnimationGroupDefinition; import net.alcuria.umbracraft.definitions.anim.AnimationListDefinition; import net.alcuria.umbracraft.definitions.anim.BattleAnimationGroupDefinition; import net.alcuria.umbracraft.definitions.area.AreaDefinition; import net.alcuria.umbracraft.definitions.config.ConfigDefinition; import net.alcuria.umbracraft.definitions.enemy.EnemyDefinition; import net.alcuria.umbracraft.definitions.enemy.EnemyGroupDefinition; import net.alcuria.umbracraft.definitions.entity.EntityDefinition; import net.alcuria.umbracraft.definitions.hero.HeroDefinition; import net.alcuria.umbracraft.definitions.items.ItemDefinition; import net.alcuria.umbracraft.definitions.map.MapDefinition; import net.alcuria.umbracraft.definitions.npc.ScriptDefinition; import net.alcuria.umbracraft.definitions.skill.SkillDefinition; import net.alcuria.umbracraft.definitions.tileset.TilesetDefinition; import net.alcuria.umbracraft.editor.Editor; import net.alcuria.umbracraft.editor.modules.VariableDefinition; import net.alcuria.umbracraft.engine.entities.Entity; import net.alcuria.umbracraft.util.O; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.ObjectMap; /** A database class to maintain all {@link Definition} classes from disk. The * returned objects are never copied to new objects, so care should be taken * when modifying Definitions returned from this class. By default, the * {@link Game} and {@link Editor} contain a reference to a Db object, so any * additional copies are likely unnecessary. TODO: refactor this using generics, * enumerate all the types, or something. * @author Andrew Keturi */ @SuppressWarnings({ "unchecked", "rawtypes" }) public final class Db { public static enum DefinitionReference { ANIMATION_COLLECTION("animationcollection", ListDefinition.class), ANIMATION_GROUP("animationgroup", ListDefinition.class), ANIMATIONS("animations", AnimationListDefinition.class), AREAS("areas", ListDefinition.class), BATTLE_ANIM_GROUP("battleanimationgroup", ListDefinition.class), CONFIG("configuration", ConfigDefinition.class), ENEMIES("enemies", ListDefinition.class), ENEMY_GROUPS("enemygroups", ListDefinition.class), ENTITIES("entities", ListDefinition.class), FLAGS( "flags", ListDefinition.class), HEROES("heroes", ListDefinition.class), ITEMS("items", ListDefinition.class), MAPS("map", ListDefinition.class), SCRIPTS("scripts", ListDefinition.class), SKILLS("skills", ListDefinition.class), TILESETS("tilesets", ListDefinition.class), VARIABLES("variables", ListDefinition.class); public Class<? extends Definition> clazz; public String id; DefinitionReference(String id, Class<? extends Definition> clazz) { this.id = id; this.clazz = clazz; } } private final ObjectMap<String, Definition> definitions; public Db() { // deserialize all definitions definitions = new ObjectMap<>(); Json json = new Json(); json.setIgnoreUnknownFields(true); for (DefinitionReference reference : DefinitionReference.values()) { final String name = reference.id; final FileHandle handle = Gdx.files.external("umbracraft/" + name + ".json"); if (handle.exists() && Gdx.app.getType() == ApplicationType.Desktop) { definitions.put(name, json.fromJson(reference.clazz, handle)); } else { final FileHandle internalHandle = Gdx.files.internal("db/" + name + ".json"); if (internalHandle.exists()) { definitions.put(name, json.fromJson(reference.clazz, internalHandle)); } else { try { definitions.put(name, reference.clazz.newInstance()); } catch (InstantiationException | IllegalAccessException e) { Game.error("Could not instantiate class: " + reference.clazz); e.printStackTrace(); } } } } } /** Finds and returns an animation definition. Throws a null pointer * exception if not found. * @param name the name of the animation definition */ public AnimationDefinition anim(String name) { return anims().get(name); } /** @param name the id of an {@link AnimationCollectionDefinition} * @return an {@link AnimationCollectionDefinition} from the db */ public AnimationCollectionDefinition animCollection(String name) { return (AnimationCollectionDefinition) animCollections().get(name); } /** @return all {@link AnimationCollectionDefinition} objects in the db */ public ListDefinition<AnimationCollectionDefinition> animCollections() { O.notNull(definitions); ListDefinition<AnimationCollectionDefinition> definition = (ListDefinition<AnimationCollectionDefinition>) definitions.get("animationcollection"); return definition; } /** @param id the identifier of the {@link AnimationGroupDefinition} * @return an {@link AnimationGroupDefinition} from the db */ public AnimationGroupDefinition animGroup(String id) { return (AnimationGroupDefinition) animGroups().get(id); } /** @return all {@link AnimationGroupDefinition} objects in the db */ public ListDefinition<AnimationGroupDefinition> animGroups() { O.notNull(definitions); ListDefinition<AnimationGroupDefinition> definition = (ListDefinition<AnimationGroupDefinition>) definitions.get("animationgroup"); return definition; } /** @return all {@link AnimationDefinition} objects in the db */ public ObjectMap<String, AnimationDefinition> anims() { O.notNull(definitions); return ((AnimationListDefinition) definitions.get("animations")).animations; } /** @param id the identifier of the area * @return the {@link AreaDefinition} in the db */ public AreaDefinition area(final String id) { return (AreaDefinition) areas().get(id); } /** @return all {@link AreaDefinition} objects */ public ListDefinition<AreaDefinition> areas() { return (ListDefinition<AreaDefinition>) O.notNull(definitions).get("areas"); } /** @param id the identifier in the db * @return a single {@link BattleAnimationGroupDefinition} */ public BattleAnimationGroupDefinition battleAnimGroup(String id) { return (BattleAnimationGroupDefinition) battleAnimGroups().get(id); } /** @return all {@link BattleAnimationGroupDefinition} objects in the db */ public ListDefinition battleAnimGroups() { O.notNull(definitions); return (ListDefinition<BattleAnimationGroupDefinition>) definitions.get("battleanimationgroup"); } /** @return the {@link ConfigDefinition} from the database. */ public ConfigDefinition config() { return (ConfigDefinition) definitions.get("configuration"); } /** @return all enemies */ public ListDefinition enemies() { O.notNull(definitions); return (ListDefinition<EnemyDefinition>) definitions.get("enemies"); } /** @param name the id of the {@link EnemyDefinition} * @return a single {@link EnemyDefinition} */ public EnemyDefinition enemy(String name) { return (EnemyDefinition) enemies().get(name); } /** @param id the id of the {@link EnemyGroupDefinition} * @return the {@link EnemyGroupDefinition} */ public EnemyGroupDefinition enemyGroup(String id) { return (EnemyGroupDefinition) enemyGroups().get(id); } /** @return all {@link EnemyGroupDefinition} objects in the db */ public ListDefinition<EnemyGroupDefinition> enemyGroups() { O.notNull(definitions); return (ListDefinition<EnemyGroupDefinition>) definitions.get("enemygroups"); } /** @return all {@link EntityDefinition} objects in the database. */ public ListDefinition<EntityDefinition> entities() { O.notNull(definitions); return (ListDefinition<EntityDefinition>) definitions.get("entities"); } /** @param id the {@link EntityDefinition}'s id * @return an {@link Entity} in the db */ public EntityDefinition entity(String id) { O.notNull(definitions); ListDefinition<EntityDefinition> definition = (ListDefinition<EntityDefinition>) definitions.get("entities"); return (EntityDefinition) definition.get(id); } /** @param id the identifier of the flag * @return the {@link FlagDefinition} in the db */ public FlagDefinition flag(String id) { return (FlagDefinition) flags().get(id); } /** @return all {@link FlagDefinition} objects in the database */ public ListDefinition<FlagDefinition> flags() { O.notNull(definitions); return (ListDefinition<FlagDefinition>) definitions.get("flags"); } /** @param id the ID of a {@link HeroDefinition} * @return the {@link HeroDefinition} with that ID in the database. */ public HeroDefinition hero(String id) { return (HeroDefinition) heroes().get(id); } /** @return all {@link HeroDefinition} objects in the db */ public ListDefinition<HeroDefinition> heroes() { O.notNull(definitions); ListDefinition<HeroDefinition> definition = (ListDefinition<HeroDefinition>) definitions.get("heroes"); return definition; } /** @param id the {@link ItemDefinition} id * @return the {@link ItemDefinition} in the db */ public ItemDefinition item(String id) { return (ItemDefinition) items().get(id); } /** @return all {@link ItemDefinition} objects in the db */ public ListDefinition<ItemDefinition> items() { O.notNull(definitions); return (ListDefinition<ItemDefinition>) definitions.get("items"); } public <T extends Definition> ListDefinition<T> list(Class<T> list, DefinitionReference reference) { O.notNull(definitions); return (ListDefinition<T>) definitions.get(reference.id); } /** @param name the name of the map * @return the {@link MapDefinition} from the database */ public MapDefinition map(String name) { O.notNull(definitions); ListDefinition<MapDefinition> definition = (ListDefinition<MapDefinition>) definitions.get("map"); return (MapDefinition) definition.get(name); } /** @param id A script ID * @return the {@link ScriptDefinition} with that particular ID in the * database */ public ScriptDefinition script(String id) { return (ScriptDefinition) scripts().get(id); } /** @return all {@link FlagDefinition} objects in the database */ public ListDefinition<ScriptDefinition> scripts() { O.notNull(definitions); return (ListDefinition<ScriptDefinition>) definitions.get("scripts"); } /** Gets a {@link SkillDefinition} from the DB * @param id the skill's id * @return the {@link SkillDefinition} */ public SkillDefinition skill(String id) { return (SkillDefinition) skills().get(id); } /** @return all {@link SkillDefinition} objects in the database */ public ListDefinition<SkillDefinition> skills() { O.notNull(definitions); return (ListDefinition<SkillDefinition>) definitions.get("skills"); } /** Gets a {@link TilesetDefinition} from the DB * @param id the tileset's id * @return the {@link TilesetDefinition} */ public TilesetDefinition tileset(String id) { return (TilesetDefinition) tilesets().get(id); } /** @return all {@link TilesetDefinition} objects in the database */ public ListDefinition<TilesetDefinition> tilesets() { O.notNull(definitions); return (ListDefinition<TilesetDefinition>) definitions.get("tilesets"); } /** @param id a variable id * @return a {@link VariableDefinition} with the given id */ public VariableDefinition variable(String id) { return (VariableDefinition) variables().get(id); } /** @return all {@link VariableDefinition} objects in the database */ public ListDefinition<VariableDefinition> variables() { O.notNull(definitions); return (ListDefinition<VariableDefinition>) definitions.get("variables"); } }