From 1e1cf1309d2c9a7ed180b7fccb8498f232c74689 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Sun, 20 Jun 2021 02:14:48 -0700 Subject: [PATCH] Fixes default values for array/set properties of monsters in db. Removes individual senses properties and replaces with a Set. --- .../3.json | 483 ++++++++++++++++++ .../majinnaibu/monstercards/AppDatabase.java | 2 +- .../monstercards/MonsterCardsApplication.java | 43 +- .../monstercards/data/DevContent.java | 10 +- .../monstercards/models/Monster.java | 63 +-- .../ui/editmonster/EditMonsterViewModel.java | 74 +-- 6 files changed, 543 insertions(+), 132 deletions(-) create mode 100644 app/schemas/com.majinnaibu.monstercards.AppDatabase/3.json diff --git a/app/schemas/com.majinnaibu.monstercards.AppDatabase/3.json b/app/schemas/com.majinnaibu.monstercards.AppDatabase/3.json new file mode 100644 index 0000000..72ecdb6 --- /dev/null +++ b/app/schemas/com.majinnaibu.monstercards.AppDatabase/3.json @@ -0,0 +1,483 @@ +{ + "formatVersion": 1, + "database": { + "version": 3, + "identityHash": "7c3c3ed79c7002102e7af7cfd21c23e0", + "entities": [ + { + "tableName": "monsters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL DEFAULT '', `size` TEXT NOT NULL DEFAULT '', `type` TEXT NOT NULL DEFAULT '', `subtype` TEXT NOT NULL DEFAULT '', `alignment` TEXT NOT NULL DEFAULT '', `strength_score` INTEGER NOT NULL DEFAULT 10, `strength_saving_throw_advantage` TEXT DEFAULT 'none', `strength_saving_throw_proficiency` TEXT DEFAULT 'none', `dexterity_score` INTEGER NOT NULL DEFAULT 10, `dexterity_saving_throw_advantage` TEXT DEFAULT 'none', `dexterity_saving_throw_proficiency` TEXT DEFAULT 'none', `constitution_score` INTEGER NOT NULL DEFAULT 10, `constitution_saving_throw_advantage` TEXT DEFAULT 'none', `constitution_saving_throw_proficiency` TEXT DEFAULT 'none', `intelligence_score` INTEGER NOT NULL DEFAULT 10, `intelligence_saving_throw_advantage` TEXT DEFAULT 'none', `intelligence_saving_throw_proficiency` TEXT DEFAULT 'none', `wisdom_score` INTEGER NOT NULL DEFAULT 10, `wisdom_saving_throw_advantage` TEXT DEFAULT 'none', `wisdom_saving_throw_proficiency` TEXT DEFAULT 'none', `charisma_score` INTEGER NOT NULL DEFAULT 10, `charisma_saving_throw_advantage` TEXT DEFAULT 'none', `charisma_saving_throw_proficiency` TEXT DEFAULT 'none', `armor_type` TEXT DEFAULT 'none', `shield_bonus` INTEGER NOT NULL DEFAULT 0, `natural_armor_bonus` INTEGER NOT NULL DEFAULT 0, `other_armor_description` TEXT DEFAULT '', `hit_dice` INTEGER NOT NULL DEFAULT 1, `has_custom_hit_points` INTEGER NOT NULL, `custom_hit_points_description` TEXT DEFAULT '', `walk_speed` INTEGER NOT NULL DEFAULT 0, `burrow_speed` INTEGER NOT NULL DEFAULT 0, `climb_speed` INTEGER NOT NULL DEFAULT 0, `fly_speed` INTEGER NOT NULL DEFAULT 0, `can_hover` INTEGER NOT NULL DEFAULT false, `swim_speed` INTEGER NOT NULL DEFAULT 0, `has_custom_speed` INTEGER NOT NULL DEFAULT false, `custom_speed_description` TEXT, `challenge_rating` TEXT DEFAULT '1', `custom_challenge_rating_description` TEXT DEFAULT '', `custom_proficiency_bonus` INTEGER NOT NULL DEFAULT 0, `telepathy_range` INTEGER NOT NULL DEFAULT 0, `understands_but_description` TEXT DEFAULT '', `senses` TEXT DEFAULT '[]', `skills` TEXT DEFAULT '[]', `damage_immunities` TEXT DEFAULT '[]', `damage_resistances` TEXT DEFAULT '[]', `damage_vulnerabilities` TEXT DEFAULT '[]', `condition_immunities` TEXT DEFAULT '[]', `languages` TEXT DEFAULT '[]', `abilities` TEXT DEFAULT '[]', `actions` TEXT DEFAULT '[]', `reactions` TEXT DEFAULT '[]', `lair_actions` TEXT DEFAULT '[]', `legendary_actions` TEXT DEFAULT '[]', `regional_actions` TEXT DEFAULT '[]', PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "subtype", + "columnName": "subtype", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "alignment", + "columnName": "alignment", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "strengthScore", + "columnName": "strength_score", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "10" + }, + { + "fieldPath": "strengthSavingThrowAdvantage", + "columnName": "strength_saving_throw_advantage", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "strengthSavingThrowProficiency", + "columnName": "strength_saving_throw_proficiency", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "dexterityScore", + "columnName": "dexterity_score", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "10" + }, + { + "fieldPath": "dexteritySavingThrowAdvantage", + "columnName": "dexterity_saving_throw_advantage", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "dexteritySavingThrowProficiency", + "columnName": "dexterity_saving_throw_proficiency", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "constitutionScore", + "columnName": "constitution_score", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "10" + }, + { + "fieldPath": "constitutionSavingThrowAdvantage", + "columnName": "constitution_saving_throw_advantage", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "constitutionSavingThrowProficiency", + "columnName": "constitution_saving_throw_proficiency", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "intelligenceScore", + "columnName": "intelligence_score", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "10" + }, + { + "fieldPath": "intelligenceSavingThrowAdvantage", + "columnName": "intelligence_saving_throw_advantage", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "intelligenceSavingThrowProficiency", + "columnName": "intelligence_saving_throw_proficiency", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "wisdomScore", + "columnName": "wisdom_score", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "10" + }, + { + "fieldPath": "wisdomSavingThrowAdvantage", + "columnName": "wisdom_saving_throw_advantage", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "wisdomSavingThrowProficiency", + "columnName": "wisdom_saving_throw_proficiency", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "charismaScore", + "columnName": "charisma_score", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "10" + }, + { + "fieldPath": "charismaSavingThrowAdvantage", + "columnName": "charisma_saving_throw_advantage", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "charismaSavingThrowProficiency", + "columnName": "charisma_saving_throw_proficiency", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "armorType", + "columnName": "armor_type", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'none'" + }, + { + "fieldPath": "shieldBonus", + "columnName": "shield_bonus", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "naturalArmorBonus", + "columnName": "natural_armor_bonus", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "otherArmorDescription", + "columnName": "other_armor_description", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "''" + }, + { + "fieldPath": "hitDice", + "columnName": "hit_dice", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "hasCustomHP", + "columnName": "has_custom_hit_points", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customHPDescription", + "columnName": "custom_hit_points_description", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "''" + }, + { + "fieldPath": "walkSpeed", + "columnName": "walk_speed", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "burrowSpeed", + "columnName": "burrow_speed", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "climbSpeed", + "columnName": "climb_speed", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "flySpeed", + "columnName": "fly_speed", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "canHover", + "columnName": "can_hover", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "false" + }, + { + "fieldPath": "swimSpeed", + "columnName": "swim_speed", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "hasCustomSpeed", + "columnName": "has_custom_speed", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "false" + }, + { + "fieldPath": "customSpeedDescription", + "columnName": "custom_speed_description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "challengeRating", + "columnName": "challenge_rating", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'1'" + }, + { + "fieldPath": "customChallengeRatingDescription", + "columnName": "custom_challenge_rating_description", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "''" + }, + { + "fieldPath": "customProficiencyBonus", + "columnName": "custom_proficiency_bonus", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "telepathyRange", + "columnName": "telepathy_range", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "understandsButDescription", + "columnName": "understands_but_description", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "''" + }, + { + "fieldPath": "senses", + "columnName": "senses", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "skills", + "columnName": "skills", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "damageImmunities", + "columnName": "damage_immunities", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "damageResistances", + "columnName": "damage_resistances", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "damageVulnerabilities", + "columnName": "damage_vulnerabilities", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "conditionImmunities", + "columnName": "condition_immunities", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "languages", + "columnName": "languages", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "abilities", + "columnName": "abilities", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "actions", + "columnName": "actions", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "reactions", + "columnName": "reactions", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "lairActions", + "columnName": "lair_actions", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "legendaryActions", + "columnName": "legendary_actions", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + }, + { + "fieldPath": "regionalActions", + "columnName": "regional_actions", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'[]'" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "ftsVersion": "FTS4", + "ftsOptions": { + "tokenizer": "simple", + "tokenizerArgs": [], + "contentTable": "monsters", + "languageIdColumnName": "", + "matchInfo": "FTS4", + "notIndexedColumns": [], + "prefixSizes": [], + "preferredOrder": "ASC" + }, + "contentSyncTriggers": [ + "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_monsters_fts_BEFORE_UPDATE BEFORE UPDATE ON `monsters` BEGIN DELETE FROM `monsters_fts` WHERE `docid`=OLD.`rowid`; END", + "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_monsters_fts_BEFORE_DELETE BEFORE DELETE ON `monsters` BEGIN DELETE FROM `monsters_fts` WHERE `docid`=OLD.`rowid`; END", + "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_monsters_fts_AFTER_UPDATE AFTER UPDATE ON `monsters` BEGIN INSERT INTO `monsters_fts`(`docid`, `name`, `size`, `type`, `subtype`, `alignment`) VALUES (NEW.`rowid`, NEW.`name`, NEW.`size`, NEW.`type`, NEW.`subtype`, NEW.`alignment`); END", + "CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_monsters_fts_AFTER_INSERT AFTER INSERT ON `monsters` BEGIN INSERT INTO `monsters_fts`(`docid`, `name`, `size`, `type`, `subtype`, `alignment`) VALUES (NEW.`rowid`, NEW.`name`, NEW.`size`, NEW.`type`, NEW.`subtype`, NEW.`alignment`); END" + ], + "tableName": "monsters_fts", + "createSql": "CREATE VIRTUAL TABLE IF NOT EXISTS `${TABLE_NAME}` USING FTS4(`name` TEXT, `size` TEXT, `type` TEXT, `subtype` TEXT, `alignment` TEXT, content=`monsters`)", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "size", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subtype", + "columnName": "subtype", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "alignment", + "columnName": "alignment", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7c3c3ed79c7002102e7af7cfd21c23e0')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java b/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java index 051b092..14d6d6e 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java +++ b/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java @@ -16,7 +16,7 @@ import com.majinnaibu.monstercards.models.Monster; import com.majinnaibu.monstercards.models.MonsterFTS; @SuppressWarnings("unused") -@Database(entities = {Monster.class, MonsterFTS.class}, version = 2) +@Database(entities = {Monster.class, MonsterFTS.class}, version = 3) @TypeConverters({ ArmorTypeConverter.class, ChallengeRatingConverter.class, diff --git a/app/src/main/java/com/majinnaibu/monstercards/MonsterCardsApplication.java b/app/src/main/java/com/majinnaibu/monstercards/MonsterCardsApplication.java index ede2471..575720e 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/MonsterCardsApplication.java +++ b/app/src/main/java/com/majinnaibu/monstercards/MonsterCardsApplication.java @@ -13,15 +13,38 @@ import com.majinnaibu.monstercards.init.FlipperInitializer; public class MonsterCardsApplication extends Application { + private static final Migration MIGRATION_1_2 = new Migration(1, 2) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + // rename table monster to monsters + database.execSQL("ALTER TABLE monster RENAME TO monsters"); + // create the fts view + database.execSQL("CREATE VIRTUAL TABLE IF NOT EXISTS `monsters_fts` USING FTS4(`name` TEXT, `size` TEXT, `type` TEXT, `subtype` TEXT, `alignment` TEXT, content=`monsters`)"); + // build the initial full text search index + database.execSQL("INSERT INTO monsters_fts(monsters_fts) VALUES('rebuild')"); + + } + }; + private static final Migration MIGRATION_2_3 = new Migration(2, 3) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + // Add the senses column + database.execSQL("ALTER TABLE monsters ADD COLUMN 'senses' TEXT DEFAULT '[]'"); + database.execSQL("CREATE TABLE new_monsters (`id` TEXT NOT NULL, `name` TEXT NOT NULL DEFAULT '', `size` TEXT NOT NULL DEFAULT '', `type` TEXT NOT NULL DEFAULT '', `subtype` TEXT NOT NULL DEFAULT '', `alignment` TEXT NOT NULL DEFAULT '', `strength_score` INTEGER NOT NULL DEFAULT 10, `strength_saving_throw_advantage` TEXT DEFAULT 'none', `strength_saving_throw_proficiency` TEXT DEFAULT 'none', `dexterity_score` INTEGER NOT NULL DEFAULT 10, `dexterity_saving_throw_advantage` TEXT DEFAULT 'none', `dexterity_saving_throw_proficiency` TEXT DEFAULT 'none', `constitution_score` INTEGER NOT NULL DEFAULT 10, `constitution_saving_throw_advantage` TEXT DEFAULT 'none', `constitution_saving_throw_proficiency` TEXT DEFAULT 'none', `intelligence_score` INTEGER NOT NULL DEFAULT 10, `intelligence_saving_throw_advantage` TEXT DEFAULT 'none', `intelligence_saving_throw_proficiency` TEXT DEFAULT 'none', `wisdom_score` INTEGER NOT NULL DEFAULT 10, `wisdom_saving_throw_advantage` TEXT DEFAULT 'none', `wisdom_saving_throw_proficiency` TEXT DEFAULT 'none', `charisma_score` INTEGER NOT NULL DEFAULT 10, `charisma_saving_throw_advantage` TEXT DEFAULT 'none', `charisma_saving_throw_proficiency` TEXT DEFAULT 'none', `armor_type` TEXT DEFAULT 'none', `shield_bonus` INTEGER NOT NULL DEFAULT 0, `natural_armor_bonus` INTEGER NOT NULL DEFAULT 0, `other_armor_description` TEXT DEFAULT '', `hit_dice` INTEGER NOT NULL DEFAULT 1, `has_custom_hit_points` INTEGER NOT NULL, `custom_hit_points_description` TEXT DEFAULT '', `walk_speed` INTEGER NOT NULL DEFAULT 0, `burrow_speed` INTEGER NOT NULL DEFAULT 0, `climb_speed` INTEGER NOT NULL DEFAULT 0, `fly_speed` INTEGER NOT NULL DEFAULT 0, `can_hover` INTEGER NOT NULL DEFAULT false, `swim_speed` INTEGER NOT NULL DEFAULT 0, `has_custom_speed` INTEGER NOT NULL DEFAULT false, `custom_speed_description` TEXT, `challenge_rating` TEXT DEFAULT '1', `custom_challenge_rating_description` TEXT DEFAULT '', `custom_proficiency_bonus` INTEGER NOT NULL DEFAULT 0, `telepathy_range` INTEGER NOT NULL DEFAULT 0, `understands_but_description` TEXT DEFAULT '', `senses` TEXT DEFAULT '[]', `skills` TEXT DEFAULT '[]', `damage_immunities` TEXT DEFAULT '[]', `damage_resistances` TEXT DEFAULT '[]', `damage_vulnerabilities` TEXT DEFAULT '[]', `condition_immunities` TEXT DEFAULT '[]', `languages` TEXT DEFAULT '[]', `abilities` TEXT DEFAULT '[]', `actions` TEXT DEFAULT '[]', `reactions` TEXT DEFAULT '[]', `lair_actions` TEXT DEFAULT '[]', `legendary_actions` TEXT DEFAULT '[]', `regional_actions` TEXT DEFAULT '[]', PRIMARY KEY(`id`))"); + database.execSQL("INSERT INTO new_monsters(id, name, size, type, subtype, alignment, strength_score, strength_saving_throw_advantage, strength_saving_throw_proficiency, dexterity_score, dexterity_saving_throw_advantage, dexterity_saving_throw_proficiency, constitution_score, constitution_saving_throw_advantage, constitution_saving_throw_proficiency, intelligence_score, intelligence_saving_throw_advantage, intelligence_saving_throw_proficiency, wisdom_score, wisdom_saving_throw_advantage, wisdom_saving_throw_proficiency, charisma_score, charisma_saving_throw_advantage, charisma_saving_throw_proficiency, armor_type, shield_bonus, natural_armor_bonus, other_armor_description, hit_dice, has_custom_hit_points, custom_hit_points_description, walk_speed, burrow_speed, climb_speed, fly_speed, can_hover, swim_speed, has_custom_speed, custom_speed_description, challenge_rating, custom_challenge_rating_description, custom_proficiency_bonus, telepathy_range, understands_but_description, senses, skills, damage_immunities, damage_resistances, damage_vulnerabilities, condition_immunities, languages, abilities, actions, reactions, lair_actions, legendary_actions, regional_actions) SELECT id, name, size, type, subtype, alignment, strength_score, strength_saving_throw_advantage, strength_saving_throw_proficiency, dexterity_score, dexterity_saving_throw_advantage, dexterity_saving_throw_proficiency, constitution_score, constitution_saving_throw_advantage, constitution_saving_throw_proficiency, intelligence_score, intelligence_saving_throw_advantage, intelligence_saving_throw_proficiency, wisdom_score, wisdom_saving_throw_advantage, wisdom_saving_throw_proficiency, charisma_score, charisma_saving_throw_advantage, charisma_saving_throw_proficiency, armor_type, shield_bonus, natural_armor_bonus, other_armor_description, hit_dice, has_custom_hit_points, custom_hit_points_description, walk_speed, burrow_speed, climb_speed, fly_speed, can_hover, swim_speed, has_custom_speed, custom_speed_description, challenge_rating, custom_challenge_rating_description, custom_proficiency_bonus, telepathy_range, understands_but_description, senses, skills, damage_immunities, damage_resistances, damage_vulnerabilities, condition_immunities, languages, abilities, actions, reactions, lair_actions, legendary_actions, regional_actions FROM monsters"); + database.execSQL("DROP TABLE monsters"); + database.execSQL("ALTER TABLE new_monsters RENAME TO monsters"); + } + }; private MonsterRepository m_monsterLibraryRepository; - public MonsterRepository getMonsterRepository() { - return m_monsterLibraryRepository; - } public MonsterCardsApplication() { } + public MonsterRepository getMonsterRepository() { + return m_monsterLibraryRepository; + } // Called when the application is starting, before any other application objects have been created. // Overriding this method is totally optional! @@ -35,6 +58,7 @@ public class MonsterCardsApplication extends Application { // .fallbackToDestructiveMigration() AppDatabase m_db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "monsters") .addMigrations(MIGRATION_1_2) + .addMigrations(MIGRATION_2_3) .fallbackToDestructiveMigrationOnDowngrade() // .fallbackToDestructiveMigration() .build(); @@ -55,17 +79,4 @@ public class MonsterCardsApplication extends Application { public void onLowMemory() { super.onLowMemory(); } - - private static final Migration MIGRATION_1_2 = new Migration(1, 2) { - @Override - public void migrate(@NonNull SupportSQLiteDatabase database) { - // rename table monster to monsters - database.execSQL("ALTER TABLE monster RENAME TO monsters"); - // create the fts view - database.execSQL("CREATE VIRTUAL TABLE IF NOT EXISTS `monsters_fts` USING FTS4(`name` TEXT, `size` TEXT, `type` TEXT, `subtype` TEXT, `alignment` TEXT, content=`monsters`)"); - // build the initial full text search index - database.execSQL("INSERT INTO monsters_fts(monsters_fts) VALUES('rebuild')"); - - } - }; } diff --git a/app/src/main/java/com/majinnaibu/monstercards/data/DevContent.java b/app/src/main/java/com/majinnaibu/monstercards/data/DevContent.java index f337c31..5a3fc5f 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/data/DevContent.java +++ b/app/src/main/java/com/majinnaibu/monstercards/data/DevContent.java @@ -10,6 +10,7 @@ import com.majinnaibu.monstercards.models.Monster; import com.majinnaibu.monstercards.models.Skill; import com.majinnaibu.monstercards.models.Trait; +@SuppressWarnings("unused") public final class DevContent { public static Monster createSampleMonster() { Monster monster = new Monster(); @@ -80,11 +81,10 @@ public final class DevContent { // Condition Immunities monster.conditionImmunities.add("blinded"); // Senses - monster.blindsightRange = 10; - monster.isBlindBeyondBlindsightRange = true; - monster.darkvisionRange = 20; - monster.tremorsenseRange = 30; - monster.truesightRange = 40; + monster.senses.add("blindsight 10 ft. (blind beyond this range)"); + monster.senses.add("darkvision 20 ft."); + monster.senses.add("tremorsense 30 ft."); + monster.senses.add("truesight 40 ft."); monster.telepathyRange = 20; monster.understandsButDescription = "doesn't care"; // Languages diff --git a/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java b/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java index 101ffac..da50796 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java +++ b/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java @@ -159,61 +159,49 @@ public class Monster { @ColumnInfo(name = "custom_proficiency_bonus", defaultValue = "0") public int customProficiencyBonus; - @ColumnInfo(name = "blindsight_range", defaultValue = "0") - public int blindsightRange; - - @ColumnInfo(name = "is_blind_beyond_blindsight_range", defaultValue = "false") - public boolean isBlindBeyondBlindsightRange; - - @ColumnInfo(name = "darkvision_range", defaultValue = "0") - public int darkvisionRange; - - @ColumnInfo(name = "tremorsense_range", defaultValue = "0") - public int tremorsenseRange; - - @ColumnInfo(name = "truesight_range", defaultValue = "0") - public int truesightRange; - @ColumnInfo(name = "telepathy_range", defaultValue = "0") public int telepathyRange; @ColumnInfo(name = "understands_but_description", defaultValue = "") public String understandsButDescription; - @ColumnInfo(name = "skills") + @ColumnInfo(name = "senses", defaultValue = "[]") + public Set senses; + + @ColumnInfo(name = "skills", defaultValue = "[]") public Set skills; - @ColumnInfo(name = "damage_immunities") + @ColumnInfo(name = "damage_immunities", defaultValue = "[]") public Set damageImmunities; - @ColumnInfo(name = "damage_resistances") + @ColumnInfo(name = "damage_resistances", defaultValue = "[]") public Set damageResistances; - @ColumnInfo(name = "damage_vulnerabilities") + @ColumnInfo(name = "damage_vulnerabilities", defaultValue = "[]") public Set damageVulnerabilities; - @ColumnInfo(name = "condition_immunities") + @ColumnInfo(name = "condition_immunities", defaultValue = "[]") public Set conditionImmunities; - @ColumnInfo(name = "languages") + @ColumnInfo(name = "languages", defaultValue = "[]") public Set languages; - @ColumnInfo(name = "abilities") + @ColumnInfo(name = "abilities", defaultValue = "[]") public Set abilities; - @ColumnInfo(name = "actions") + @ColumnInfo(name = "actions", defaultValue = "[]") public Set actions; - @ColumnInfo(name = "reactions") + @ColumnInfo(name = "reactions", defaultValue = "[]") public Set reactions; - @ColumnInfo(name = "lair_actions") + @ColumnInfo(name = "lair_actions", defaultValue = "[]") public Set lairActions; - @ColumnInfo(name = "legendary_actions") + @ColumnInfo(name = "legendary_actions", defaultValue = "[]") public Set legendaryActions; - @ColumnInfo(name = "regional_actions") + @ColumnInfo(name = "regional_actions", defaultValue = "[]") public Set regionalActions; public Monster() { @@ -247,11 +235,6 @@ public class Monster { challengeRating = ChallengeRating.ONE; customChallengeRatingDescription = ""; customProficiencyBonus = 0; - blindsightRange = 0; - isBlindBeyondBlindsightRange = false; - darkvisionRange = 0; - tremorsenseRange = 0; - truesightRange = 0; telepathyRange = 0; understandsButDescription = ""; strengthSavingThrowAdvantage = AdvantageType.NONE; @@ -269,6 +252,7 @@ public class Monster { skills = new HashSet<>(); + senses = new HashSet<>(); damageImmunities = new HashSet<>(); damageResistances = new HashSet<>(); damageVulnerabilities = new HashSet<>(); @@ -651,21 +635,8 @@ public class Monster { } public String getSensesDescription() { - ArrayList parts = new ArrayList<>(); - if (blindsightRange > 0) { - parts.add(String.format("blindsight %d ft.%s", blindsightRange, isBlindBeyondBlindsightRange ? " (blind beyond this radius)" : "")); - } - if (darkvisionRange > 0) { - parts.add(String.format("darkvision %d ft.", darkvisionRange)); - } - if (tremorsenseRange > 0) { - parts.add(String.format("tremorsense %d ft.", tremorsenseRange)); - } - if (truesightRange > 0) { - parts.add(String.format("truesight %d ft.", truesightRange)); - } + ArrayList parts = new ArrayList<>(senses); parts.add(String.format("passive Perception %d", 10 + getWisdomModifier())); - return StringHelper.join(", ", parts); } diff --git a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java index 3eb6385..6fa13a8 100644 --- a/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java +++ b/app/src/main/java/com/majinnaibu/monstercards/ui/editmonster/EditMonsterViewModel.java @@ -74,14 +74,10 @@ public class EditMonsterViewModel extends ViewModel { private final ChangeTrackedLiveData mChallengeRating; private final ChangeTrackedLiveData mCustomChallengeRatingDescription; private final ChangeTrackedLiveData mCustomProficiencyBonus; - private final ChangeTrackedLiveData mBlindsightRange; - private final ChangeTrackedLiveData mIsBlindBeyondBlindsightRange; - private final ChangeTrackedLiveData mDarkvisionRange; - private final ChangeTrackedLiveData mTremorsenseRange; - private final ChangeTrackedLiveData mTruesightRange; private final ChangeTrackedLiveData mTelepathyRange; private final ChangeTrackedLiveData mUnderstandsButDescription; private final ChangeTrackedLiveData> mSkills; + private final ChangeTrackedLiveData> mSenses; private final ChangeTrackedLiveData> mDamageImmunities; private final ChangeTrackedLiveData> mDamageResistances; private final ChangeTrackedLiveData> mDamageVulnerabilities; @@ -144,14 +140,10 @@ public class EditMonsterViewModel extends ViewModel { mChallengeRating = new ChangeTrackedLiveData<>(ChallengeRating.ONE_EIGHTH, onDirtied); mCustomChallengeRatingDescription = new ChangeTrackedLiveData<>("", onDirtied); mCustomProficiencyBonus = new ChangeTrackedLiveData<>(0, onDirtied); - mBlindsightRange = new ChangeTrackedLiveData<>(0, onDirtied); - mIsBlindBeyondBlindsightRange = new ChangeTrackedLiveData<>(false, onDirtied); - mDarkvisionRange = new ChangeTrackedLiveData<>(0, onDirtied); - mTremorsenseRange = new ChangeTrackedLiveData<>(0, onDirtied); - mTruesightRange = new ChangeTrackedLiveData<>(0, onDirtied); mTelepathyRange = new ChangeTrackedLiveData<>(0, onDirtied); mUnderstandsButDescription = new ChangeTrackedLiveData<>("", onDirtied); mSkills = new ChangeTrackedLiveData<>(new ArrayList<>(), onDirtied); + mSenses = new ChangeTrackedLiveData<>(new ArrayList<>(), onDirtied); mDamageImmunities = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied); mDamageResistances = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied); mDamageVulnerabilities = new ChangeTrackedLiveData<>(new HashSet<>(), onDirtied); @@ -209,21 +201,15 @@ public class EditMonsterViewModel extends ViewModel { mChallengeRating.resetValue(monster.challengeRating); mCustomChallengeRatingDescription.resetValue(monster.customChallengeRatingDescription); mCustomProficiencyBonus.resetValue(monster.customProficiencyBonus); - mBlindsightRange.resetValue(monster.blindsightRange); - mIsBlindBeyondBlindsightRange.resetValue(monster.isBlindBeyondBlindsightRange); - mDarkvisionRange.resetValue(monster.darkvisionRange); - mTremorsenseRange.resetValue(monster.tremorsenseRange); - mTruesightRange.resetValue(monster.truesightRange); mTelepathyRange.resetValue(monster.telepathyRange); mUnderstandsButDescription.resetValue(monster.understandsButDescription); ArrayList skills = new ArrayList<>(monster.skills); - if (skills.size() == 0) { - skills.add(new Skill("Acrobatics", AbilityScore.STRENGTH)); - skills.add(new Skill("Stealth", AbilityScore.DEXTERITY)); - } Collections.sort(skills, (skill1, skill2) -> skill1.name.compareToIgnoreCase(skill2.name)); mSkills.resetValue(skills); + ArrayList senses = new ArrayList<>(monster.senses); + Collections.sort(senses, String::compareToIgnoreCase); + mSenses.resetValue(senses); mDamageImmunities.resetValue(monster.damageImmunities); mDamageResistances.resetValue(monster.damageResistances); mDamageVulnerabilities.resetValue(monster.damageVulnerabilities); @@ -750,46 +736,6 @@ public class EditMonsterViewModel extends ViewModel { return mCustomProficiencyBonus.getValue().toString(); } - public LiveData getBlindsightRange() { - return mBlindsightRange; - } - - public void setBlindsightRange(int blindsightRange) { - mBlindsightRange.setValue(blindsightRange); - } - - public LiveData getIsBlindBeyondBlindsightRange() { - return mIsBlindBeyondBlindsightRange; - } - - public void setIsBlindBeyondBlindsightRange(boolean isBlindBeyondBlindsightRange) { - mIsBlindBeyondBlindsightRange.setValue(isBlindBeyondBlindsightRange); - } - - public LiveData getDarkvisionRange() { - return mDarkvisionRange; - } - - public void setDarkvisionRange(int darkvisionRange) { - mDarkvisionRange.setValue(darkvisionRange); - } - - public LiveData getTremorsenseRange() { - return mTremorsenseRange; - } - - public void setTremorsenseRange(int tremorsenseRange) { - mTremorsenseRange.setValue(tremorsenseRange); - } - - public LiveData getTruesightRange() { - return mTruesightRange; - } - - public void setTruesightRange(int truesightRange) { - mTruesightRange.setValue(truesightRange); - } - public LiveData getTelepathyRange() { return mTelepathyRange; } @@ -810,6 +756,10 @@ public class EditMonsterViewModel extends ViewModel { return mSkills; } + public List getSensesArray() { + return mSenses.getValue(); + } + // TODO: add getters and setters for lists of strings (Senses, Damage Immunities, Damage Resistances, Damage Vulnerabilities, and Condition Immunities) // TODO: add getters and setters for Languages // TODO: add getters and setters for traits (Abilities, Actions, Reactions, Lair Actions, Legendary Actions, and Regional Actions) @@ -859,14 +809,10 @@ public class EditMonsterViewModel extends ViewModel { monster.challengeRating = mChallengeRating.getValue(); monster.customChallengeRatingDescription = mCustomChallengeRatingDescription.getValue(); monster.customProficiencyBonus = mCustomProficiencyBonus.getValue(); - monster.blindsightRange = mBlindsightRange.getValue(); - monster.isBlindBeyondBlindsightRange = mIsBlindBeyondBlindsightRange.getValue(); - monster.darkvisionRange = mDarkvisionRange.getValue(); - monster.tremorsenseRange = mTremorsenseRange.getValue(); - monster.truesightRange = mTruesightRange.getValue(); monster.telepathyRange = mTelepathyRange.getValue(); monster.understandsButDescription = mUnderstandsButDescription.getValue(); monster.skills = new HashSet<>(mSkills.getValue()); + monster.senses = new HashSet<>(mSenses.getValue()); monster.damageImmunities = mDamageImmunities.getValue(); monster.damageResistances = mDamageResistances.getValue(); monster.damageVulnerabilities = mDamageVulnerabilities.getValue();