Migrates Monster class to be storable in roomdb.

This commit is contained in:
2021-04-17 20:43:19 -07:00
parent fbe60150d5
commit c6e8be3bd1
26 changed files with 1613 additions and 1291 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@
/.idea/workspace.xml /.idea/workspace.xml
/.idea/navEditor.xml /.idea/navEditor.xml
/.idea/assetWizardSettings.xml /.idea/assetWizardSettings.xml
/.idea/dictionaries
.DS_Store .DS_Store
/build /build
/captures /captures

16
.idea/saveactions_settings.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SaveActionSettings">
<option name="actions">
<set>
<option value="activate" />
<option value="activateOnShortcut" />
<option value="activateOnBatch" />
<option value="noActionIfCompileErrors" />
<option value="organizeImports" />
<option value="reformat" />
</set>
</option>
<option name="configurationPath" value="" />
</component>
</project>

View File

@@ -87,4 +87,5 @@ dependencies {
// optional - Test helpers // optional - Test helpers
//testImplementation "androidx.room:room-testing:$room_version" //testImplementation "androidx.room:room-testing:$room_version"
implementation 'com.google.code.gson:gson:2.8.6'
} }

View File

@@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "a9371223372fb64522cc40f5529ada09", "identityHash": "db1293d2f490940b55ca1f4f56b21b1a",
"entities": [ "entities": [
{ {
"tableName": "Monster", "tableName": "Monster",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`id`))", "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, `blindsight_range` INTEGER NOT NULL DEFAULT 0, `is_blind_beyond_blindsight_range` INTEGER NOT NULL DEFAULT false, `darkvision_range` INTEGER NOT NULL DEFAULT 0, `tremorsense_range` INTEGER NOT NULL DEFAULT 0, `truesight_range` INTEGER NOT NULL DEFAULT 0, `telepathy_range` INTEGER NOT NULL DEFAULT 0, `understands_but_description` TEXT DEFAULT '', `skills` TEXT, `damage_immunities` TEXT, `damage_resistances` TEXT, `damage_vulnerabilities` TEXT, `condition_immunities` TEXT, `languages` TEXT, `abilities` TEXT, `actions` TEXT, `reactions` TEXT, `lair_actions` TEXT, `legendary_actions` TEXT, `regional_actions` TEXT, PRIMARY KEY(`id`))",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@@ -20,6 +20,405 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true, "notNull": true,
"defaultValue": "''" "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": "blindsightRange",
"columnName": "blindsight_range",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "isBlindBeyondBlindsightRange",
"columnName": "is_blind_beyond_blindsight_range",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
},
{
"fieldPath": "darkvisionRange",
"columnName": "darkvision_range",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "tremorsenseRange",
"columnName": "tremorsense_range",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
},
{
"fieldPath": "truesightRange",
"columnName": "truesight_range",
"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": "skills",
"columnName": "skills",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "damageImmunities",
"columnName": "damage_immunities",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "damageResistances",
"columnName": "damage_resistances",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "damageVulnerabilities",
"columnName": "damage_vulnerabilities",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "conditionImmunities",
"columnName": "condition_immunities",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "languages",
"columnName": "languages",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "abilities",
"columnName": "abilities",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "reactions",
"columnName": "reactions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lairActions",
"columnName": "lair_actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "legendaryActions",
"columnName": "legendary_actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "regionalActions",
"columnName": "regional_actions",
"affinity": "TEXT",
"notNull": false
} }
], ],
"primaryKey": { "primaryKey": {
@@ -35,7 +434,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "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, 'a9371223372fb64522cc40f5529ada09')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'db1293d2f490940b55ca1f4f56b21b1a')"
] ]
} }
} }

View File

@@ -0,0 +1,73 @@
## Monster
id: UUID as TEXT // doesn't exist in the iOS model
abilities: Set<Trait> converted to JSON as TEXT
actions: Set<Trait> converted to JSON as TEXT
alignment: String as TEXT
armor_type: Enum<String> as TEXT
blindsight_range: int as INTEGER
burrow_speed: int as INTEGER
can_hover: boolean as INTEGER
challenge_rating: Enum<String> as TEXT
charisma_saving_throw_advantage
charisma_saving_throw_proficiency
charisma_score: int as INTEGER
climb_speed: int as INTEGER
condition_immunities: Set<String> converted to JSON as TEXT
constitution_saving_throw_advantage
constitution_saving_throw_proficiency
constitution_score: int as INTEGER
//other_armor_description: String as TEXT
custom_challenge_rating_description: String as TEXT
custom_hit_points_description: String
custom_proficiency_bonus: int as INTEGER
custom_speed_description: String as TEXT
damage_immunities: Set<String> converted to JSON as TEXT
damage_resistances: Set<String> converted to JSON as TEXT
damage_vulnerabilities: Set<String> converted to JSON as TEXT
darkvision_range: int as INTEGER
dexterity_saving_throw_advantage
dexterity_saving_throw_proficiency
dexterity_score: int as INTEGER
fly_speed: int as INTEGER
has_custom_hit_points: boolean as INTEGER
has_custom_speed: boolean as INTEGER
// has_shield
hit_dice: int as INTEGER
intelligence_saving_throw_advantage
intelligence_saving_throw_proficiency
intelligence_score: int as INTEGER
is_blind_beyond_blindsight_range: boolean as INTEGER
lair_actions
languages: Set<Language> converted to JSON as TEXT
legendary_actions
name: String as TEXT
natural_armor_bonus: int as INTEGER
other_armor_description: String as TEXT
reactions
regional_actions
// senses
shield_bonus: int as INTEGER
size: String as TEXT
strength_saving_throw_advantage
strength_saving_throw_proficiency
strength_score: int as INTEGER
tag: String as TEXT // subtype || tag
swim_speed: int as INTEGER
telepathy_range: int as INTEGER
tremorsense_range: int as INTEGER
truesight_range: int as INTEGER
type: String as TEXT
understands_but_description: String as TEXT
walk_speed: int as INTEGER
wisdom_saving_throw_advantage
wisdom_saving_throw_proficiency
wisdom_score: int as INTEGER
// tracked as relationship (don't do this)
skills: Set<Skill> converted to JSON as TEXT
## Skill
// ability_score_name String defaults to "strength"
// advantage String defaults to "none"
// name String defaults to ""
// proficiency String defaults to "none"

View File

@@ -4,12 +4,29 @@ import androidx.room.Database;
import androidx.room.RoomDatabase; import androidx.room.RoomDatabase;
import androidx.room.TypeConverters; import androidx.room.TypeConverters;
import com.majinnaibu.monstercards.converters.UUIDConverter;
import com.majinnaibu.monstercards.data.MonsterDAO; import com.majinnaibu.monstercards.data.MonsterDAO;
import com.majinnaibu.monstercards.data.converters.ArmorTypeConverter;
import com.majinnaibu.monstercards.data.converters.ChallengeRatingConverter;
import com.majinnaibu.monstercards.data.converters.SetOfLanguageConverter;
import com.majinnaibu.monstercards.data.converters.SetOfSavingThrowConverter;
import com.majinnaibu.monstercards.data.converters.SetOfSkillConverter;
import com.majinnaibu.monstercards.data.converters.SetOfStringConverter;
import com.majinnaibu.monstercards.data.converters.SetOfTraitConverter;
import com.majinnaibu.monstercards.data.converters.UUIDConverter;
import com.majinnaibu.monstercards.models.Monster; import com.majinnaibu.monstercards.models.Monster;
@SuppressWarnings("unused")
@Database(entities = {Monster.class}, version = 1) @Database(entities = {Monster.class}, version = 1)
@TypeConverters({UUIDConverter.class}) @TypeConverters({
ArmorTypeConverter.class,
ChallengeRatingConverter.class,
SetOfLanguageConverter.class,
SetOfSavingThrowConverter.class,
SetOfSkillConverter.class,
SetOfStringConverter.class,
SetOfTraitConverter.class,
UUIDConverter.class,
})
public abstract class AppDatabase extends RoomDatabase { public abstract class AppDatabase extends RoomDatabase {
public abstract MonsterDAO monsterDAO(); public abstract MonsterDAO monsterDAO();
} }

View File

@@ -0,0 +1,18 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.majinnaibu.monstercards.data.enums.ArmorType;
public class ArmorTypeConverter {
@TypeConverter
public static String fromArmorType(ArmorType armorType) {
return armorType.stringValue;
}
@TypeConverter
public static ArmorType armorTypeFromStringValue(String stringValue) {
return ArmorType.valueOfString(stringValue);
}
}

View File

@@ -0,0 +1,18 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.majinnaibu.monstercards.data.enums.ChallengeRating;
public class ChallengeRatingConverter {
@TypeConverter
public static String fromChallengeRating(ChallengeRating challengeRating) {
return challengeRating.stringValue;
}
@TypeConverter
public static ChallengeRating challengeRatingFromStringValue(String stringValue) {
return ChallengeRating.valueOfString(stringValue);
}
}

View File

@@ -0,0 +1,28 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.majinnaibu.monstercards.models.Language;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
public class SetOfLanguageConverter {
@TypeConverter
public static String fromSetOfLanguage(Set<Language> languages) {
Gson gson = new Gson();
return gson.toJson(languages);
}
@TypeConverter
public static Set<Language> setOfLanguageFromString(String string) {
Gson gson = new Gson();
Type setType = new TypeToken<HashSet<Language>>() {
}.getType();
return gson.fromJson(string, setType);
}
}

View File

@@ -0,0 +1,31 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.majinnaibu.monstercards.models.SavingThrow;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
public class SetOfSavingThrowConverter {
@TypeConverter
public static String fromSetOfSavingThrow(Set<SavingThrow> savingThrows) {
Gson gson = new Gson();
SavingThrow[] saves = new SavingThrow[savingThrows.size()];
savingThrows.toArray(saves);
return gson.toJson(saves);
}
@TypeConverter
public static Set<SavingThrow> setOfSavingThrowFromString(String string) {
Gson gson = new Gson();
Type setType = new TypeToken<HashSet<SavingThrow>>() {
}.getType();
return gson.fromJson(string, setType);
}
}

View File

@@ -0,0 +1,28 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.majinnaibu.monstercards.models.Skill;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
public class SetOfSkillConverter {
@TypeConverter
public static String fromSetOfSkill(Set<Skill> skills) {
Gson gson = new Gson();
return gson.toJson(skills);
}
@TypeConverter
public static Set<Skill> setOfSkillFromString(String string) {
Gson gson = new Gson();
Type setType = new TypeToken<HashSet<Skill>>() {
}.getType();
return gson.fromJson(string, setType);
}
}

View File

@@ -0,0 +1,27 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
public class SetOfStringConverter {
@TypeConverter
public static String fromSetOfString(Set<String> strings) {
Gson gson = new Gson();
return gson.toJson(strings);
}
@TypeConverter
public static Set<String> setOfStringFromString(String string) {
Gson gson = new Gson();
Type setType = new TypeToken<HashSet<String>>() {
}.getType();
return gson.fromJson(string, setType);
}
}

View File

@@ -0,0 +1,27 @@
package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.majinnaibu.monstercards.models.Trait;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
public class SetOfTraitConverter {
@TypeConverter
public static String fromSetOfTrait(Set<Trait> traits) {
Gson gson = new Gson();
return gson.toJson(traits);
}
@TypeConverter
public static Set<Trait> setOfTraitFromString(String string) {
Gson gson = new Gson();
Type setType = new TypeToken<HashSet<Trait>>() {
}.getType();
return gson.fromJson(string, setType);
}
}

View File

@@ -1,4 +1,4 @@
package com.majinnaibu.monstercards.converters; package com.majinnaibu.monstercards.data.converters;
import androidx.room.TypeConverter; import androidx.room.TypeConverter;

View File

@@ -0,0 +1,31 @@
package com.majinnaibu.monstercards.data.enums;
@SuppressWarnings("unused")
public enum AbilityScore {
STRENGTH("strength", "Strength", "STR"),
DEXTERITY("dexterity", "Dexterity", "DEX"),
CONSTITUTION("constitution", "Constitution", "CON"),
INTELLIGENCE("intellligence", "Intelligence", "INT"),
WISDOM("wisdom", "Wisdom", "WIS"),
CHARISMA("charisma", "Charisma", "CHA"),
;
public final String displayName;
public final String shortDisplayName;
public final String stringValue;
AbilityScore(String stringValue, String displayName, String shortDisplayName) {
this.displayName = displayName;
this.stringValue = stringValue;
this.shortDisplayName = shortDisplayName;
}
public static AbilityScore valueOfString(String string) {
for (AbilityScore abilityScore : values()) {
if (abilityScore.stringValue.equals(string)) {
return abilityScore;
}
}
return AbilityScore.STRENGTH;
}
}

View File

@@ -0,0 +1,27 @@
package com.majinnaibu.monstercards.data.enums;
public enum AdvantageType {
NONE("none", "None", ""),
ADVANTAGE("advantage", "Advantage", "A"),
DISADVANTAGE("disadvantage", "Disadvantage", "D"),
;
public final String displayName;
public final String stringValue;
public final String label;
AdvantageType(String stringValue, String displayName, String label) {
this.displayName = displayName;
this.stringValue = stringValue;
this.label = label;
}
public static AdvantageType valueOfString(String string) {
for (AdvantageType advantageType : values()) {
if (advantageType.stringValue.equals(string)) {
return advantageType;
}
}
return AdvantageType.NONE;
}
}

View File

@@ -0,0 +1,41 @@
package com.majinnaibu.monstercards.data.enums;
@SuppressWarnings("unused")
public enum ArmorType {
NONE("none", "None", 10),
NATURAL_ARMOR("natural armor", "Natural Armor", 10),
MAGE_ARMOR("mage armor", "Mage Armor", 10),
PADDED("padded", "Padded", 11),
LEATHER("leather", "Leather", 11),
STUDDED_LEATHER("studded", "Studded Leather", 12),
HIDE("hide", "Hide", 12),
CHAIN_SHIRT("chain shirt", "Chain Shirt", 13),
SCALE_MAIL("scale mail", "Scale Mail", 14),
BREASTPLATE("breastplate", "Breastplate", 14),
HALF_PLATE("half plate", "Half Plate", 15),
RING_MAIL("ring mail", "Ring Mail", 14),
CHAIN_MAIL("chain mail", "Chain Mail", 16),
SPLINT_MAIL("splint", "Splint Mail", 17),
PLATE_MAIL("plate", "Plate Mail", 18),
OTHER("other", "Other", 10),
;
public final String displayName;
public final String stringValue;
public final int baseArmorClass;
ArmorType(String stringValue, String displayName, int baseArmorClass) {
this.displayName = displayName;
this.stringValue = stringValue;
this.baseArmorClass = baseArmorClass;
}
public static ArmorType valueOfString(String string) {
for (ArmorType armorType : values()) {
if (armorType.stringValue.equals(string)) {
return armorType;
}
}
return ArmorType.NONE;
}
}

View File

@@ -0,0 +1,60 @@
package com.majinnaibu.monstercards.data.enums;
@SuppressWarnings("unused")
public enum ChallengeRating {
CUSTOM("custom", "Custom", 0),
ZERO("zero", "0 (10 XP)", 2),
ONE_EIGHTH("1/8", "1/8 (25 XP)", 2),
ONE_QUARTER("1/4", "1/4 (50 XP)", 2),
ONE_HALF("1/2", "1/2 (100 XP)", 2),
ONE("1", "1 (200 XP)", 2),
TWO("2", "2 (450 XP)", 2),
THREE("3", "3 (700 XP)", 2),
FOUR("4", "4 (1,100 XP)", 2),
FIVE("5", "5 (1,800 XP)", 3),
SIX("6", "6 (2,300 XP)", 3),
SEVEN("7", "7 (2,900 XP)", 3),
EIGHT("8", "8 (3,900 XP)", 3),
NINE("9", "9 (5,000 XP)", 4),
TEN("10", "10 (5,900 XP)", 4),
ELEVEN("11", "11 (7,200 XP)", 4),
TWELVE("12", "12 (8,400 XP)", 4),
THIRTEEN("13", "13 (10,000 XP)", 5),
FOURTEEN("14", "14 (11,500 XP)", 5),
FIFTEEN("15", "15 (13,000 XP)", 5),
SIXTEEN("16", "16 (15,000 XP)", 5),
SEVENTEEN("17", "17 (18,000 XP)", 6),
EIGHTEEN("18", "18 (20,000 XP)", 6),
NINETEEN("19", "19 (22,000 XP)", 6),
TWENTY("20", "20 (25,000 XP)", 6),
TWENTY_ONE("21", "21 (33,000 XP)", 7),
TWENTY_TWO("22", "22 (41,000 XP)", 7),
TWENTY_THREE("23", "23 (50,000 XP)", 7),
TWENTY_FOUR("24", "24 (62,000 XP)", 7),
TWENTY_FIVE("25", "25 (75,000 XP)", 8),
TWENTY_SIX("26", "26 (90,000 XP)", 8),
TWENTY_SEVEN("27", "27 (105,000 XP)", 8),
TWENTY_EIGHT("28", "28 (120,000 XP)", 8),
TWENTY_NINE("29", "29 (135,000 XP)", 9),
THIRTY("30", "30 (155,000 XP)", 9),
;
public final String displayName;
public final String stringValue;
public final int proficiencyBonus;
ChallengeRating(String stringValue, String displayName, int proficiencyBonus) {
this.displayName = displayName;
this.stringValue = stringValue;
this.proficiencyBonus = proficiencyBonus;
}
public static ChallengeRating valueOfString(String string) {
for (ChallengeRating challengeRating : values()) {
if (challengeRating.stringValue.equals(string)) {
return challengeRating;
}
}
return ChallengeRating.ONE;
}
}

View File

@@ -0,0 +1,27 @@
package com.majinnaibu.monstercards.data.enums;
public enum ProficiencyType {
NONE("none", "None", ""),
PROFICIENT("proficient", "Proficient", "P"),
EXPERTISE("experties", "Expertise", "Ex"),
;
public final String displayName;
public final String stringValue;
public final String label;
ProficiencyType(String stringValue, String displayName, String label) {
this.displayName = displayName;
this.stringValue = stringValue;
this.label = label;
}
public static ProficiencyType valueOfString(String string) {
for (ProficiencyType proficiencyType : values()) {
if (proficiencyType.stringValue.equals(string)) {
return proficiencyType;
}
}
return ProficiencyType.NONE;
}
}

View File

@@ -1,29 +0,0 @@
package com.majinnaibu.monstercards.models;
public class Ability {
public Ability(String name, String description) {
mName = name;
mDescription = description;
}
private String mName;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
private String mDescription;
public String getDescription() {
return mDescription;
}
public void setDescription(String description) {
mDescription = description;
}
}

View File

@@ -1,29 +0,0 @@
package com.majinnaibu.monstercards.models;
public class Action {
public Action(String name, String description) {
mName = name;
mDescription = description;
}
private String mName;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
private String mDescription;
public String getDescription() {
return mDescription;
}
public void setDescription(String description) {
mDescription = description;
}
}

View File

@@ -1,41 +0,0 @@
package com.majinnaibu.monstercards.models;
public class DamageType {
public DamageType(String name, String note, String type) {
mName = name;
mNote = note;
mType = type;
}
private String mName;
public String getName() {
return mName;
}
public void setName(String value) {
mName = value;
}
private String mNote;
public String getNote() {
return mNote;
}
public void setNote(String value) {
mNote = value;
}
private String mType;
public String getType() {
return mType;
}
public void setType(String value) {
mType = value;
}
}

View File

@@ -1,70 +1,69 @@
package com.majinnaibu.monstercards.models; package com.majinnaibu.monstercards.models;
import java.util.Comparator; import android.annotation.SuppressLint;
import java.util.Locale;
import com.majinnaibu.monstercards.data.enums.AbilityScore;
import com.majinnaibu.monstercards.data.enums.AdvantageType;
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
import java.util.Comparator;
@SuppressLint("DefaultLocale")
public class Skill implements Comparator<Skill>, Comparable<Skill> { public class Skill implements Comparator<Skill>, Comparable<Skill> {
private String mName; public String name;
private String mAbilityScoreName; public AbilityScore abilityScore;
private String mNote; public AdvantageType advantageType;
public ProficiencyType proficiencyType;
public Skill(String name, String abilityScoreName) { public Skill(String name, AbilityScore abilityScore) {
mName = name; this(name, abilityScore, AdvantageType.NONE, ProficiencyType.PROFICIENT);
mAbilityScoreName = abilityScoreName;
mNote = "";
} }
public Skill(String name, String abilityScoreName, String note) { public Skill(String name, AbilityScore abilityScore, AdvantageType advantageType) {
mName = name; this(name, abilityScore, advantageType, ProficiencyType.PROFICIENT);
mAbilityScoreName = abilityScoreName;
mNote = note;
} }
public String getName() { public Skill(String name, AbilityScore abilityScore, AdvantageType advantageType, ProficiencyType proficiencyType) {
return mName; this.name = name;
} this.abilityScore = abilityScore;
this.advantageType = advantageType;
public void setName(String name) { this.proficiencyType = proficiencyType;
mName = name;
}
public String getAbilityScoreName() {
return mAbilityScoreName;
}
public void setAbilityScoreName(String abilityScoreName) {
mAbilityScoreName = abilityScoreName;
}
public String getNote() {
return mNote;
} }
public int getSkillBonus(Monster monster) { public int getSkillBonus(Monster monster) {
int bonus = monster.getAbilityModifier(mAbilityScoreName); int modifier = monster.getAbilityModifier(abilityScore);
if (" (ex)".equals(getNote())) { switch (proficiencyType) {
bonus += 2 * monster.getProficiencyBonus(); case PROFICIENT:
} else { return modifier + monster.getProficiencyBonus();
bonus += monster.getProficiencyBonus(); case EXPERTISE:
return modifier + monster.getProficiencyBonus() * 2;
case NONE:
default:
return modifier;
} }
return bonus;
} }
public String getText(Monster monster) { public String getText(Monster monster) {
int bonus = getSkillBonus(monster); int bonus = getSkillBonus(monster);
return String.format(Locale.US, "%s%s %d", mName.substring(0, 1), mName.substring(1), bonus); return String.format(
"%s%s %+d%s",
name.substring(0, 1),
name.substring(1),
bonus,
advantageType == AdvantageType.ADVANTAGE ? " A" : advantageType == AdvantageType.DISADVANTAGE ? " D" : ""
);
} }
@Override @Override
public int compareTo(Skill o) { public int compareTo(Skill o) {
return this.getName().compareToIgnoreCase(o.getName()); return this.name.compareToIgnoreCase(o.name);
} }
@Override @Override
public int compare(Skill o1, Skill o2) { public int compare(Skill o1, Skill o2) {
return o1.getName().compareToIgnoreCase(o2.getName()); return o1.name.compareToIgnoreCase(o2.name);
} }
} }

View File

@@ -0,0 +1,12 @@
package com.majinnaibu.monstercards.models;
public class Trait {
public String name;
public String description;
public Trait(String name, String description) {
this.name = name;
this.description = description;
}
}

View File

@@ -14,23 +14,21 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import com.majinnaibu.monstercards.R; import com.majinnaibu.monstercards.R;
import com.majinnaibu.monstercards.data.enums.AbilityScore;
import com.majinnaibu.monstercards.data.enums.AdvantageType;
import com.majinnaibu.monstercards.data.enums.ArmorType;
import com.majinnaibu.monstercards.data.enums.ChallengeRating;
import com.majinnaibu.monstercards.data.enums.ProficiencyType;
import com.majinnaibu.monstercards.helpers.CommonMarkHelper; import com.majinnaibu.monstercards.helpers.CommonMarkHelper;
import com.majinnaibu.monstercards.helpers.StringHelper; import com.majinnaibu.monstercards.helpers.StringHelper;
import com.majinnaibu.monstercards.models.Ability;
import com.majinnaibu.monstercards.models.Action;
import com.majinnaibu.monstercards.models.DamageType;
import com.majinnaibu.monstercards.models.Language; import com.majinnaibu.monstercards.models.Language;
import com.majinnaibu.monstercards.models.Monster; import com.majinnaibu.monstercards.models.Monster;
import com.majinnaibu.monstercards.models.SavingThrow;
import com.majinnaibu.monstercards.models.Skill; import com.majinnaibu.monstercards.models.Skill;
import com.majinnaibu.monstercards.models.Trait;
import java.util.List;
@SuppressWarnings("FieldCanBeLocal") @SuppressWarnings("FieldCanBeLocal")
public class MonsterFragment extends Fragment { public class MonsterFragment extends Fragment {
@@ -45,81 +43,94 @@ public class MonsterFragment extends Fragment {
// Name // Name
monster.name = "Pixie"; monster.name = "Pixie";
// Meta // Meta
monster.setSize("tiny"); monster.size = "tiny";
monster.setType("fey"); monster.type = "fey";
monster.setTag(""); monster.subtype = "";
monster.setAlignment("neutral good"); monster.alignment = "neutral good";
monster.armorType = ArmorType.NONE;
// Armor & Armor Class // Armor & Armor Class
monster.setArmorName("none"); monster.shieldBonus = 0;
monster.setShieldBonus(0); monster.naturalArmorBonus = 7;
monster.setNaturalArmorBonus(7); monster.otherArmorDescription = "14";
monster.setOtherArmorDescription("14");
// Hit Points // Hit Points
monster.setHitDice(1); monster.hitDice = 1;
monster.setCustomHP(false); monster.hasCustomHP = false;
monster.setHPText("11 (2d8 + 2)"); monster.customHPDescription = "11 (2d8 + 2)";
monster.setSpeed("10"); monster.walkSpeed = 10;
monster.setBurrowSpeed("0"); monster.burrowSpeed = 0;
monster.setClimbSpeed("0"); monster.climbSpeed = 0;
monster.setFlySpeed("30"); monster.flySpeed = 30;
monster.setHover(false); monster.canHover = false;
monster.setSwimSpeed("0"); monster.swimSpeed = 0;
monster.setCustomSpeed(false); monster.hasCustomSpeed = false;
monster.setSpeedDescription("30 ft., swim 30 ft."); monster.customSpeedDescription = "30 ft., swim 30 ft.";
// Ability Scores // Ability Scores
monster.setStrengthScore(Integer.parseInt("2")); monster.strengthScore = Integer.parseInt("2");
monster.setDexterityScore(Integer.parseInt("20")); monster.dexterityScore = Integer.parseInt("20");
monster.setConstitutionScore(Integer.parseInt("8")); monster.constitutionScore = Integer.parseInt("8");
monster.setIntelligenceScore(Integer.parseInt("10")); monster.intelligenceScore = Integer.parseInt("10");
monster.setWisdomScore(Integer.parseInt("14")); monster.wisdomScore = Integer.parseInt("14");
monster.setCharismaScore(Integer.parseInt("15")); monster.charismaScore = Integer.parseInt("15");
// monster.strengthScore = 10;
// monster.dexterityScore = 10;
// monster.constitutionScore = 10;
// monster.intelligenceScore = 10;
// monster.wisdomScore = 10;
// monster.charismaScore = 10;
// Saving Throws // Saving Throws
monster.addSavingThrow(new SavingThrow("str", 0)); monster.strengthSavingThrowAdvantage = AdvantageType.NONE;
monster.addSavingThrow(new SavingThrow("dex", 1)); monster.strengthSavingThrowProficiency = ProficiencyType.NONE;
monster.addSavingThrow(new SavingThrow("con", 2)); monster.dexteritySavingThrowAdvantage = AdvantageType.ADVANTAGE;
monster.addSavingThrow(new SavingThrow("int", 3)); monster.dexteritySavingThrowProficiency = ProficiencyType.PROFICIENT;
monster.addSavingThrow(new SavingThrow("wis", 4)); monster.constitutionSavingThrowAdvantage = AdvantageType.DISADVANTAGE;
monster.addSavingThrow(new SavingThrow("cha", 5)); monster.constitutionSavingThrowProficiency = ProficiencyType.EXPERTISE;
monster.intelligenceSavingThrowAdvantage = AdvantageType.NONE;
monster.intelligenceSavingThrowProficiency = ProficiencyType.EXPERTISE;
monster.wisdomSavingThrowAdvantage = AdvantageType.ADVANTAGE;
monster.wisdomSavingThrowProficiency = ProficiencyType.PROFICIENT;
monster.charismaSavingThrowAdvantage = AdvantageType.DISADVANTAGE;
monster.charismaSavingThrowProficiency = ProficiencyType.NONE;
//Skills //Skills
monster.addSkill(new Skill("perception", "wis")); monster.skills.add(new Skill("perception", AbilityScore.WISDOM));
monster.addSkill(new Skill("stealth", "dexterity")); monster.skills.add(new Skill("stealth", AbilityScore.DEXTERITY));
// Damage Types // Damage Types
monster.addDamageType(new DamageType("acid", " (Vulnerable)", "v")); monster.damageImmunities.add("force");
monster.addDamageType(new DamageType("bludgeoning", " (Vulnerable)", "v")); monster.damageImmunities.add("lightning");
monster.addDamageType(new DamageType("cold", " (Resistant)", "r")); monster.damageImmunities.add("poison");
monster.addDamageType(new DamageType("fire", " (Resistant)", "r")); monster.damageResistances.add("cold");
monster.addDamageType(new DamageType("force", " (Immune)", "i")); monster.damageResistances.add("fire");
monster.addDamageType(new DamageType("lightning", " (Immune)", "i")); monster.damageResistances.add("piercing");
monster.addDamageType(new DamageType("necrotic", " (Vulnerable)", "v")); monster.damageVulnerabilities.add("acid");
monster.addDamageType(new DamageType("piercing", " (Resistant)", "r")); monster.damageVulnerabilities.add("bludgeoning");
monster.addDamageType(new DamageType("poison", " (Immune)", "i")); monster.damageVulnerabilities.add("necrotic");
// Condition Immunities // Condition Immunities
monster.addConditionImmunity("blinded"); monster.conditionImmunities.add("blinded");
// Senses // Senses
monster.setBlindsight("10"); monster.blindsightRange = 10;
monster.setIsBlind(true); monster.isBlindBeyondBlindsightRange = true;
monster.setDarkvision("20"); monster.darkvisionRange = 20;
monster.setTremorsense("30"); monster.tremorsenseRange = 30;
monster.setTruesight("40"); monster.truesightRange = 40;
monster.setTelepathy(20); monster.telepathyRange = 20;
monster.setUnderstandsBut("doesn't care"); monster.understandsButDescription = "doesn't care";
// Languages // Languages
monster.addLanguage(new Language("English", true)); monster.languages.add(new Language("English", true));
monster.addLanguage(new Language("Steve", false)); monster.languages.add(new Language("Steve", false));
monster.addLanguage(new Language("Spanish", true)); monster.languages.add(new Language("Spanish", true));
monster.addLanguage(new Language("French", true)); monster.languages.add(new Language("French", true));
monster.addLanguage(new Language("Mermataur", false)); monster.languages.add(new Language("Mermataur", false));
monster.addLanguage(new Language("Goldfish", false)); monster.languages.add(new Language("Goldfish", false));
// Challenge Rating // Challenge Rating
monster.setChallengeRating("*"); monster.challengeRating = ChallengeRating.CUSTOM;
monster.setCustomChallengeRating("Infinite (0XP)"); monster.customChallengeRatingDescription = "Infinite (0XP)";
monster.setCustomProficiencyBonus(4); monster.customProficiencyBonus = 4;
// Abilities // Abilities
monster.addAbility(new Ability("Spellcasting", "The acolyte is a 1st-level spellcaster. Its spellcasting ability is Wisdom (spell save DC [WIS SAVE], [WIS ATK] to hit with spell attacks). The acolyte has following cleric spells prepared:\n\n\n> Cantrips (at will): _light, sacred flame, thaumaturgy_\n> 1st level (3 slots): _bless, cure wounds, sanctuary_")); monster.abilities.add(new Trait("Spellcasting", "The acolyte is a 1st-level spellcaster. Its spellcasting ability is Wisdom (spell save DC [WIS SAVE], [WIS ATK] to hit with spell attacks). The acolyte has following cleric spells prepared:\n\n\n> Cantrips (at will): _light, sacred flame, thaumaturgy_\n> 1st level (3 slots): _bless, cure wounds, sanctuary_"));
monster.addAbility(new Ability("Amphibious", "The dragon can breathe air and water.")); monster.abilities.add(new Trait("Amphibious", "The dragon can breathe air and water."));
monster.addAbility(new Ability("Legendary Resistance (3/Day)", "If the dragon fails a saving throw, it can choose to succeed instead.")); monster.abilities.add(new Trait("Legendary Resistance (3/Day)", "If the dragon fails a saving throw, it can choose to succeed instead."));
// Actions // Actions
monster.addAction(new Action("Club", "_Melee Weapon Attack:_ [STR ATK] to hit, reach 5 ft., one target. _Hit:_ 2 (1d4) bludgeoning damage.")); monster.actions.add(new Trait("Club", "_Melee Weapon Attack:_ [STR ATK] to hit, reach 5 ft., one target. _Hit:_ 2 (1d4) bludgeoning damage."));
// END remove block // END remove block
monsterViewModel = new ViewModelProvider(this).get(MonsterViewModel.class); monsterViewModel = new ViewModelProvider(this).get(MonsterViewModel.class);
@@ -127,209 +138,123 @@ public class MonsterFragment extends Fragment {
monsterViewModel.setMonster(monster); monsterViewModel.setMonster(monster);
final TextView monsterName = root.findViewById(R.id.name); final TextView monsterName = root.findViewById(R.id.name);
monsterViewModel.getName().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getName().observe(getViewLifecycleOwner(), name -> monsterName.setText(name));
@Override
public void onChanged(@Nullable String name) {
monsterName.setText(name);
}
});
final TextView monsterMeta = root.findViewById(R.id.meta); final TextView monsterMeta = root.findViewById(R.id.meta);
monsterViewModel.getMeta().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getMeta().observe(getViewLifecycleOwner(), metaText -> monsterMeta.setText(metaText));
@Override
public void onChanged(@Nullable String metaText) {
monsterMeta.setText(metaText);
}
});
final TextView monsterArmorClass = root.findViewById(R.id.armor_class); final TextView monsterArmorClass = root.findViewById(R.id.armor_class);
monsterViewModel.getArmorClass().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getArmorClass().observe(getViewLifecycleOwner(), armorText -> monsterArmorClass.setText(Html.fromHtml("<b>Armor Class</b> " + armorText)));
@Override
public void onChanged(@Nullable String armorText) {
monsterArmorClass.setText(Html.fromHtml("<b>Armor Class</b> " + armorText));
}
});
final TextView monsterHitPoints = root.findViewById(R.id.hit_points); final TextView monsterHitPoints = root.findViewById(R.id.hit_points);
monsterViewModel.getHitPoints().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> monsterHitPoints.setText(Html.fromHtml("<b>Hit Points</b> " + hitPoints)));
@Override
public void onChanged(String hitPoints) {
monsterHitPoints.setText(Html.fromHtml("<b>Hit Points</b> " + hitPoints));
}
});
final TextView monsterSpeed = root.findViewById(R.id.speed); final TextView monsterSpeed = root.findViewById(R.id.speed);
monsterViewModel.getSpeed().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> monsterSpeed.setText(Html.fromHtml("<b>Speed</b> " + speed)));
@Override
public void onChanged(String speed) {
monsterSpeed.setText(Html.fromHtml("<b>Speed</b> " + speed));
}
});
final TextView monsterStrength = root.findViewById(R.id.strength); final TextView monsterStrength = root.findViewById(R.id.strength);
monsterViewModel.getStrength().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getStrength().observe(getViewLifecycleOwner(), strength -> monsterStrength.setText(strength));
@Override
public void onChanged(String strength) {
monsterStrength.setText(strength);
}
});
final TextView monsterDexterity = root.findViewById(R.id.dexterity); final TextView monsterDexterity = root.findViewById(R.id.dexterity);
monsterViewModel.getDexterity().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getDexterity().observe(getViewLifecycleOwner(), dexterity -> monsterDexterity.setText(dexterity));
@Override
public void onChanged(String dexterity) {
monsterDexterity.setText(dexterity);
}
});
final TextView monsterConstitution = root.findViewById(R.id.constitution); final TextView monsterConstitution = root.findViewById(R.id.constitution);
monsterViewModel.getConstitution().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getConstitution().observe(getViewLifecycleOwner(), constitution -> monsterConstitution.setText(constitution));
@Override
public void onChanged(String constitution) {
monsterConstitution.setText(constitution);
}
});
final TextView monsterIntelligence = root.findViewById(R.id.intelligence); final TextView monsterIntelligence = root.findViewById(R.id.intelligence);
monsterViewModel.getIntelligence().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getIntelligence().observe(getViewLifecycleOwner(), intelligence -> monsterIntelligence.setText(intelligence));
@Override
public void onChanged(String intelligence) {
monsterIntelligence.setText(intelligence);
}
});
final TextView monsterWisdom = root.findViewById(R.id.wisdom); final TextView monsterWisdom = root.findViewById(R.id.wisdom);
monsterViewModel.getWisdom().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getWisdom().observe(getViewLifecycleOwner(), wisdom -> monsterWisdom.setText(wisdom));
@Override
public void onChanged(String wisdom) {
monsterWisdom.setText(wisdom);
}
});
final TextView monsterCharisma = root.findViewById(R.id.charisma); final TextView monsterCharisma = root.findViewById(R.id.charisma);
monsterViewModel.getCharisma().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getCharisma().observe(getViewLifecycleOwner(), charisma -> monsterCharisma.setText(charisma));
@Override
public void onChanged(String charisma) {
monsterCharisma.setText(charisma);
}
});
final TextView monsterSavingThrows = root.findViewById(R.id.saving_throws); final TextView monsterSavingThrows = root.findViewById(R.id.saving_throws);
monsterViewModel.getSavingThrows().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getSavingThrows().observe(getViewLifecycleOwner(), savingThrows -> {
@Override
public void onChanged(String savingThrows) {
if (StringHelper.isNullOrEmpty(savingThrows)) { if (StringHelper.isNullOrEmpty(savingThrows)) {
monsterSavingThrows.setVisibility(View.GONE); monsterSavingThrows.setVisibility(View.GONE);
} else { } else {
monsterSavingThrows.setVisibility(View.VISIBLE); monsterSavingThrows.setVisibility(View.VISIBLE);
} }
monsterSavingThrows.setText(Html.fromHtml("<b>Saving Throws</b> " + savingThrows)); monsterSavingThrows.setText(Html.fromHtml("<b>Saving Throws</b> " + savingThrows));
}
}); });
final TextView monsterSkills = root.findViewById(R.id.skills); final TextView monsterSkills = root.findViewById(R.id.skills);
monsterViewModel.getSkills().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> {
@Override
public void onChanged(String skills) {
if (StringHelper.isNullOrEmpty(skills)) { if (StringHelper.isNullOrEmpty(skills)) {
monsterSkills.setVisibility(View.GONE); monsterSkills.setVisibility(View.GONE);
} else { } else {
monsterSkills.setVisibility(View.VISIBLE); monsterSkills.setVisibility(View.VISIBLE);
} }
monsterSkills.setText(Html.fromHtml("<b>Skills</b> " + skills)); monsterSkills.setText(Html.fromHtml("<b>Skills</b> " + skills));
}
}); });
final TextView monsterDamageVulnerabilities = root.findViewById(R.id.damage_vulnerabilities); final TextView monsterDamageVulnerabilities = root.findViewById(R.id.damage_vulnerabilities);
monsterViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageType -> {
@Override
public void onChanged(String damageType) {
if (StringHelper.isNullOrEmpty(damageType)) { if (StringHelper.isNullOrEmpty(damageType)) {
monsterDamageVulnerabilities.setVisibility(View.GONE); monsterDamageVulnerabilities.setVisibility(View.GONE);
} else { } else {
monsterDamageVulnerabilities.setVisibility(View.VISIBLE); monsterDamageVulnerabilities.setVisibility(View.VISIBLE);
} }
monsterDamageVulnerabilities.setText(Html.fromHtml("<b>Damage Vulnerabilities</b> " + damageType)); monsterDamageVulnerabilities.setText(Html.fromHtml("<b>Damage Vulnerabilities</b> " + damageType));
}
}); });
final TextView monsterDamageResistances = root.findViewById(R.id.damage_resistances); final TextView monsterDamageResistances = root.findViewById(R.id.damage_resistances);
monsterViewModel.getDamageResistances().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getDamageResistances().observe(getViewLifecycleOwner(), damageType -> {
@Override
public void onChanged(String damageType) {
if (StringHelper.isNullOrEmpty(damageType)) { if (StringHelper.isNullOrEmpty(damageType)) {
monsterDamageResistances.setVisibility(View.GONE); monsterDamageResistances.setVisibility(View.GONE);
} else { } else {
monsterDamageResistances.setVisibility(View.VISIBLE); monsterDamageResistances.setVisibility(View.VISIBLE);
} }
monsterDamageResistances.setText(Html.fromHtml("<b>Damage Resistances</b> " + damageType)); monsterDamageResistances.setText(Html.fromHtml("<b>Damage Resistances</b> " + damageType));
}
}); });
final TextView monsterDamageImmunities = root.findViewById(R.id.damage_immunities); final TextView monsterDamageImmunities = root.findViewById(R.id.damage_immunities);
monsterViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageType -> {
@Override
public void onChanged(String damageType) {
if (StringHelper.isNullOrEmpty(damageType)) { if (StringHelper.isNullOrEmpty(damageType)) {
monsterDamageImmunities.setVisibility(View.GONE); monsterDamageImmunities.setVisibility(View.GONE);
} else { } else {
monsterDamageImmunities.setVisibility(View.VISIBLE); monsterDamageImmunities.setVisibility(View.VISIBLE);
} }
monsterDamageImmunities.setText(Html.fromHtml("<b>Damage Immunities</b> " + damageType)); monsterDamageImmunities.setText(Html.fromHtml("<b>Damage Immunities</b> " + damageType));
}
}); });
final TextView monsterConditionImmunities = root.findViewById(R.id.condition_immunities); final TextView monsterConditionImmunities = root.findViewById(R.id.condition_immunities);
monsterViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> {
@Override
public void onChanged(String conditionImmunities) {
if (StringHelper.isNullOrEmpty(conditionImmunities)) { if (StringHelper.isNullOrEmpty(conditionImmunities)) {
monsterConditionImmunities.setVisibility(View.GONE); monsterConditionImmunities.setVisibility(View.GONE);
} else { } else {
monsterConditionImmunities.setVisibility(View.VISIBLE); monsterConditionImmunities.setVisibility(View.VISIBLE);
} }
monsterConditionImmunities.setText(Html.fromHtml("<b>Condition Immunities</b> " + conditionImmunities)); monsterConditionImmunities.setText(Html.fromHtml("<b>Condition Immunities</b> " + conditionImmunities));
}
}); });
final TextView monsterSenses = root.findViewById(R.id.senses); final TextView monsterSenses = root.findViewById(R.id.senses);
monsterViewModel.getSenses().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> {
@Override
public void onChanged(String senses) {
if (StringHelper.isNullOrEmpty(senses)) { if (StringHelper.isNullOrEmpty(senses)) {
monsterSenses.setVisibility(View.GONE); monsterSenses.setVisibility(View.GONE);
} else { } else {
monsterSenses.setVisibility(View.VISIBLE); monsterSenses.setVisibility(View.VISIBLE);
} }
monsterSenses.setText(Html.fromHtml("<b>Senses</b> " + senses)); monsterSenses.setText(Html.fromHtml("<b>Senses</b> " + senses));
}
}); });
final TextView monsterLanguages = root.findViewById(R.id.languages); final TextView monsterLanguages = root.findViewById(R.id.languages);
monsterViewModel.getLanguages().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getLanguages().observe(getViewLifecycleOwner(), languages -> {
@Override
public void onChanged(String languages) {
if (StringHelper.isNullOrEmpty(languages)) { if (StringHelper.isNullOrEmpty(languages)) {
monsterLanguages.setVisibility(View.GONE); monsterLanguages.setVisibility(View.GONE);
} else { } else {
monsterLanguages.setVisibility(View.VISIBLE); monsterLanguages.setVisibility(View.VISIBLE);
} }
monsterLanguages.setText(Html.fromHtml("<b>Languages</b> " + languages)); monsterLanguages.setText(Html.fromHtml("<b>Languages</b> " + languages));
}
}); });
final TextView monsterChallenge = root.findViewById(R.id.challenge); final TextView monsterChallenge = root.findViewById(R.id.challenge);
monsterViewModel.getChallenge().observe(getViewLifecycleOwner(), new Observer<String>() { monsterViewModel.getChallenge().observe(getViewLifecycleOwner(), challengeRating -> monsterChallenge.setText(Html.fromHtml("<b>Challenge</b> " + challengeRating)));
@Override
public void onChanged(String challengeRating) {
monsterChallenge.setText(Html.fromHtml("<b>Challenge</b> " + challengeRating));
}
});
final LinearLayout monsterAbilities = root.findViewById(R.id.abilities); final LinearLayout monsterAbilities = root.findViewById(R.id.abilities);
monsterViewModel.getAbilities().observe(getViewLifecycleOwner(), new Observer<List<String>>() { monsterViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> {
@Override
public void onChanged(List<String> abilities) {
Context context = getContext(); Context context = getContext();
DisplayMetrics displayMetrics = null; DisplayMetrics displayMetrics = null;
if (context != null) { if (context != null) {
@@ -352,13 +277,10 @@ public class MonsterFragment extends Fragment {
monsterAbilities.addView(tvAbility); monsterAbilities.addView(tvAbility);
} }
} }
}
}); });
final LinearLayout monsterActions = root.findViewById(R.id.actions); final LinearLayout monsterActions = root.findViewById(R.id.actions);
monsterViewModel.getActions().observe(getViewLifecycleOwner(), new Observer<List<String>>() { monsterViewModel.getActions().observe(getViewLifecycleOwner(), actions -> {
@Override
public void onChanged(List<String> actions) {
Context context = getContext(); Context context = getContext();
DisplayMetrics displayMetrics = null; DisplayMetrics displayMetrics = null;
if (context != null) { if (context != null) {
@@ -378,7 +300,6 @@ public class MonsterFragment extends Fragment {
monsterActions.addView(tvAction); monsterActions.addView(tvAction);
} }
} }
}
}); });
return root; return root;