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/navEditor.xml
/.idea/assetWizardSettings.xml
/.idea/dictionaries
.DS_Store
/build
/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
//testImplementation "androidx.room:room-testing:$room_version"
implementation 'com.google.code.gson:gson:2.8.6'
}

View File

@@ -2,11 +2,11 @@
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "a9371223372fb64522cc40f5529ada09",
"identityHash": "db1293d2f490940b55ca1f4f56b21b1a",
"entities": [
{
"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": [
{
"fieldPath": "id",
@@ -20,6 +20,405 @@
"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": "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": {
@@ -35,7 +434,7 @@
"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, '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.TypeConverters;
import com.majinnaibu.monstercards.converters.UUIDConverter;
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;
@SuppressWarnings("unused")
@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 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;

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;
import java.util.Comparator;
import java.util.Locale;
import android.annotation.SuppressLint;
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> {
private String mName;
private String mAbilityScoreName;
private String mNote;
public String name;
public AbilityScore abilityScore;
public AdvantageType advantageType;
public ProficiencyType proficiencyType;
public Skill(String name, String abilityScoreName) {
mName = name;
mAbilityScoreName = abilityScoreName;
mNote = "";
public Skill(String name, AbilityScore abilityScore) {
this(name, abilityScore, AdvantageType.NONE, ProficiencyType.PROFICIENT);
}
public Skill(String name, String abilityScoreName, String note) {
mName = name;
mAbilityScoreName = abilityScoreName;
mNote = note;
public Skill(String name, AbilityScore abilityScore, AdvantageType advantageType) {
this(name, abilityScore, advantageType, ProficiencyType.PROFICIENT);
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getAbilityScoreName() {
return mAbilityScoreName;
}
public void setAbilityScoreName(String abilityScoreName) {
mAbilityScoreName = abilityScoreName;
}
public String getNote() {
return mNote;
public Skill(String name, AbilityScore abilityScore, AdvantageType advantageType, ProficiencyType proficiencyType) {
this.name = name;
this.abilityScore = abilityScore;
this.advantageType = advantageType;
this.proficiencyType = proficiencyType;
}
public int getSkillBonus(Monster monster) {
int bonus = monster.getAbilityModifier(mAbilityScoreName);
if (" (ex)".equals(getNote())) {
bonus += 2 * monster.getProficiencyBonus();
} else {
bonus += monster.getProficiencyBonus();
int modifier = monster.getAbilityModifier(abilityScore);
switch (proficiencyType) {
case PROFICIENT:
return modifier + monster.getProficiencyBonus();
case EXPERTISE:
return modifier + monster.getProficiencyBonus() * 2;
case NONE:
default:
return modifier;
}
return bonus;
}
public String getText(Monster 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
public int compareTo(Skill o) {
return this.getName().compareToIgnoreCase(o.getName());
return this.name.compareToIgnoreCase(o.name);
}
@Override
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 androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
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.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.Monster;
import com.majinnaibu.monstercards.models.SavingThrow;
import com.majinnaibu.monstercards.models.Skill;
import java.util.List;
import com.majinnaibu.monstercards.models.Trait;
@SuppressWarnings("FieldCanBeLocal")
public class MonsterFragment extends Fragment {
@@ -45,81 +43,94 @@ public class MonsterFragment extends Fragment {
// Name
monster.name = "Pixie";
// Meta
monster.setSize("tiny");
monster.setType("fey");
monster.setTag("");
monster.setAlignment("neutral good");
monster.size = "tiny";
monster.type = "fey";
monster.subtype = "";
monster.alignment = "neutral good";
monster.armorType = ArmorType.NONE;
// Armor & Armor Class
monster.setArmorName("none");
monster.setShieldBonus(0);
monster.setNaturalArmorBonus(7);
monster.setOtherArmorDescription("14");
monster.shieldBonus = 0;
monster.naturalArmorBonus = 7;
monster.otherArmorDescription = "14";
// Hit Points
monster.setHitDice(1);
monster.setCustomHP(false);
monster.setHPText("11 (2d8 + 2)");
monster.setSpeed("10");
monster.setBurrowSpeed("0");
monster.setClimbSpeed("0");
monster.setFlySpeed("30");
monster.setHover(false);
monster.setSwimSpeed("0");
monster.setCustomSpeed(false);
monster.setSpeedDescription("30 ft., swim 30 ft.");
monster.hitDice = 1;
monster.hasCustomHP = false;
monster.customHPDescription = "11 (2d8 + 2)";
monster.walkSpeed = 10;
monster.burrowSpeed = 0;
monster.climbSpeed = 0;
monster.flySpeed = 30;
monster.canHover = false;
monster.swimSpeed = 0;
monster.hasCustomSpeed = false;
monster.customSpeedDescription = "30 ft., swim 30 ft.";
// Ability Scores
monster.setStrengthScore(Integer.parseInt("2"));
monster.setDexterityScore(Integer.parseInt("20"));
monster.setConstitutionScore(Integer.parseInt("8"));
monster.setIntelligenceScore(Integer.parseInt("10"));
monster.setWisdomScore(Integer.parseInt("14"));
monster.setCharismaScore(Integer.parseInt("15"));
monster.strengthScore = Integer.parseInt("2");
monster.dexterityScore = Integer.parseInt("20");
monster.constitutionScore = Integer.parseInt("8");
monster.intelligenceScore = Integer.parseInt("10");
monster.wisdomScore = Integer.parseInt("14");
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
monster.addSavingThrow(new SavingThrow("str", 0));
monster.addSavingThrow(new SavingThrow("dex", 1));
monster.addSavingThrow(new SavingThrow("con", 2));
monster.addSavingThrow(new SavingThrow("int", 3));
monster.addSavingThrow(new SavingThrow("wis", 4));
monster.addSavingThrow(new SavingThrow("cha", 5));
monster.strengthSavingThrowAdvantage = AdvantageType.NONE;
monster.strengthSavingThrowProficiency = ProficiencyType.NONE;
monster.dexteritySavingThrowAdvantage = AdvantageType.ADVANTAGE;
monster.dexteritySavingThrowProficiency = ProficiencyType.PROFICIENT;
monster.constitutionSavingThrowAdvantage = AdvantageType.DISADVANTAGE;
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
monster.addSkill(new Skill("perception", "wis"));
monster.addSkill(new Skill("stealth", "dexterity"));
monster.skills.add(new Skill("perception", AbilityScore.WISDOM));
monster.skills.add(new Skill("stealth", AbilityScore.DEXTERITY));
// Damage Types
monster.addDamageType(new DamageType("acid", " (Vulnerable)", "v"));
monster.addDamageType(new DamageType("bludgeoning", " (Vulnerable)", "v"));
monster.addDamageType(new DamageType("cold", " (Resistant)", "r"));
monster.addDamageType(new DamageType("fire", " (Resistant)", "r"));
monster.addDamageType(new DamageType("force", " (Immune)", "i"));
monster.addDamageType(new DamageType("lightning", " (Immune)", "i"));
monster.addDamageType(new DamageType("necrotic", " (Vulnerable)", "v"));
monster.addDamageType(new DamageType("piercing", " (Resistant)", "r"));
monster.addDamageType(new DamageType("poison", " (Immune)", "i"));
monster.damageImmunities.add("force");
monster.damageImmunities.add("lightning");
monster.damageImmunities.add("poison");
monster.damageResistances.add("cold");
monster.damageResistances.add("fire");
monster.damageResistances.add("piercing");
monster.damageVulnerabilities.add("acid");
monster.damageVulnerabilities.add("bludgeoning");
monster.damageVulnerabilities.add("necrotic");
// Condition Immunities
monster.addConditionImmunity("blinded");
monster.conditionImmunities.add("blinded");
// Senses
monster.setBlindsight("10");
monster.setIsBlind(true);
monster.setDarkvision("20");
monster.setTremorsense("30");
monster.setTruesight("40");
monster.setTelepathy(20);
monster.setUnderstandsBut("doesn't care");
monster.blindsightRange = 10;
monster.isBlindBeyondBlindsightRange = true;
monster.darkvisionRange = 20;
monster.tremorsenseRange = 30;
monster.truesightRange = 40;
monster.telepathyRange = 20;
monster.understandsButDescription = "doesn't care";
// Languages
monster.addLanguage(new Language("English", true));
monster.addLanguage(new Language("Steve", false));
monster.addLanguage(new Language("Spanish", true));
monster.addLanguage(new Language("French", true));
monster.addLanguage(new Language("Mermataur", false));
monster.addLanguage(new Language("Goldfish", false));
monster.languages.add(new Language("English", true));
monster.languages.add(new Language("Steve", false));
monster.languages.add(new Language("Spanish", true));
monster.languages.add(new Language("French", true));
monster.languages.add(new Language("Mermataur", false));
monster.languages.add(new Language("Goldfish", false));
// Challenge Rating
monster.setChallengeRating("*");
monster.setCustomChallengeRating("Infinite (0XP)");
monster.setCustomProficiencyBonus(4);
monster.challengeRating = ChallengeRating.CUSTOM;
monster.customChallengeRatingDescription = "Infinite (0XP)";
monster.customProficiencyBonus = 4;
// 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.addAbility(new Ability("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("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("Amphibious", "The dragon can breathe air and water."));
monster.abilities.add(new Trait("Legendary Resistance (3/Day)", "If the dragon fails a saving throw, it can choose to succeed instead."));
// 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
monsterViewModel = new ViewModelProvider(this).get(MonsterViewModel.class);
@@ -127,209 +138,123 @@ public class MonsterFragment extends Fragment {
monsterViewModel.setMonster(monster);
final TextView monsterName = root.findViewById(R.id.name);
monsterViewModel.getName().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String name) {
monsterName.setText(name);
}
});
monsterViewModel.getName().observe(getViewLifecycleOwner(), name -> monsterName.setText(name));
final TextView monsterMeta = root.findViewById(R.id.meta);
monsterViewModel.getMeta().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String metaText) {
monsterMeta.setText(metaText);
}
});
monsterViewModel.getMeta().observe(getViewLifecycleOwner(), metaText -> monsterMeta.setText(metaText));
final TextView monsterArmorClass = root.findViewById(R.id.armor_class);
monsterViewModel.getArmorClass().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String armorText) {
monsterArmorClass.setText(Html.fromHtml("<b>Armor Class</b> " + armorText));
}
});
monsterViewModel.getArmorClass().observe(getViewLifecycleOwner(), armorText -> monsterArmorClass.setText(Html.fromHtml("<b>Armor Class</b> " + armorText)));
final TextView monsterHitPoints = root.findViewById(R.id.hit_points);
monsterViewModel.getHitPoints().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String hitPoints) {
monsterHitPoints.setText(Html.fromHtml("<b>Hit Points</b> " + hitPoints));
}
});
monsterViewModel.getHitPoints().observe(getViewLifecycleOwner(), hitPoints -> monsterHitPoints.setText(Html.fromHtml("<b>Hit Points</b> " + hitPoints)));
final TextView monsterSpeed = root.findViewById(R.id.speed);
monsterViewModel.getSpeed().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String speed) {
monsterSpeed.setText(Html.fromHtml("<b>Speed</b> " + speed));
}
});
monsterViewModel.getSpeed().observe(getViewLifecycleOwner(), speed -> monsterSpeed.setText(Html.fromHtml("<b>Speed</b> " + speed)));
final TextView monsterStrength = root.findViewById(R.id.strength);
monsterViewModel.getStrength().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String strength) {
monsterStrength.setText(strength);
}
});
monsterViewModel.getStrength().observe(getViewLifecycleOwner(), strength -> monsterStrength.setText(strength));
final TextView monsterDexterity = root.findViewById(R.id.dexterity);
monsterViewModel.getDexterity().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String dexterity) {
monsterDexterity.setText(dexterity);
}
});
monsterViewModel.getDexterity().observe(getViewLifecycleOwner(), dexterity -> monsterDexterity.setText(dexterity));
final TextView monsterConstitution = root.findViewById(R.id.constitution);
monsterViewModel.getConstitution().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String constitution) {
monsterConstitution.setText(constitution);
}
});
monsterViewModel.getConstitution().observe(getViewLifecycleOwner(), constitution -> monsterConstitution.setText(constitution));
final TextView monsterIntelligence = root.findViewById(R.id.intelligence);
monsterViewModel.getIntelligence().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String intelligence) {
monsterIntelligence.setText(intelligence);
}
});
monsterViewModel.getIntelligence().observe(getViewLifecycleOwner(), intelligence -> monsterIntelligence.setText(intelligence));
final TextView monsterWisdom = root.findViewById(R.id.wisdom);
monsterViewModel.getWisdom().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String wisdom) {
monsterWisdom.setText(wisdom);
}
});
monsterViewModel.getWisdom().observe(getViewLifecycleOwner(), wisdom -> monsterWisdom.setText(wisdom));
final TextView monsterCharisma = root.findViewById(R.id.charisma);
monsterViewModel.getCharisma().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String charisma) {
monsterCharisma.setText(charisma);
}
});
monsterViewModel.getCharisma().observe(getViewLifecycleOwner(), charisma -> monsterCharisma.setText(charisma));
final TextView monsterSavingThrows = root.findViewById(R.id.saving_throws);
monsterViewModel.getSavingThrows().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String savingThrows) {
monsterViewModel.getSavingThrows().observe(getViewLifecycleOwner(), savingThrows -> {
if (StringHelper.isNullOrEmpty(savingThrows)) {
monsterSavingThrows.setVisibility(View.GONE);
} else {
monsterSavingThrows.setVisibility(View.VISIBLE);
}
monsterSavingThrows.setText(Html.fromHtml("<b>Saving Throws</b> " + savingThrows));
}
});
final TextView monsterSkills = root.findViewById(R.id.skills);
monsterViewModel.getSkills().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String skills) {
monsterViewModel.getSkills().observe(getViewLifecycleOwner(), skills -> {
if (StringHelper.isNullOrEmpty(skills)) {
monsterSkills.setVisibility(View.GONE);
} else {
monsterSkills.setVisibility(View.VISIBLE);
}
monsterSkills.setText(Html.fromHtml("<b>Skills</b> " + skills));
}
});
final TextView monsterDamageVulnerabilities = root.findViewById(R.id.damage_vulnerabilities);
monsterViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String damageType) {
monsterViewModel.getDamageVulnerabilities().observe(getViewLifecycleOwner(), damageType -> {
if (StringHelper.isNullOrEmpty(damageType)) {
monsterDamageVulnerabilities.setVisibility(View.GONE);
} else {
monsterDamageVulnerabilities.setVisibility(View.VISIBLE);
}
monsterDamageVulnerabilities.setText(Html.fromHtml("<b>Damage Vulnerabilities</b> " + damageType));
}
});
final TextView monsterDamageResistances = root.findViewById(R.id.damage_resistances);
monsterViewModel.getDamageResistances().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String damageType) {
monsterViewModel.getDamageResistances().observe(getViewLifecycleOwner(), damageType -> {
if (StringHelper.isNullOrEmpty(damageType)) {
monsterDamageResistances.setVisibility(View.GONE);
} else {
monsterDamageResistances.setVisibility(View.VISIBLE);
}
monsterDamageResistances.setText(Html.fromHtml("<b>Damage Resistances</b> " + damageType));
}
});
final TextView monsterDamageImmunities = root.findViewById(R.id.damage_immunities);
monsterViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String damageType) {
monsterViewModel.getDamageImmunities().observe(getViewLifecycleOwner(), damageType -> {
if (StringHelper.isNullOrEmpty(damageType)) {
monsterDamageImmunities.setVisibility(View.GONE);
} else {
monsterDamageImmunities.setVisibility(View.VISIBLE);
}
monsterDamageImmunities.setText(Html.fromHtml("<b>Damage Immunities</b> " + damageType));
}
});
final TextView monsterConditionImmunities = root.findViewById(R.id.condition_immunities);
monsterViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String conditionImmunities) {
monsterViewModel.getConditionImmunities().observe(getViewLifecycleOwner(), conditionImmunities -> {
if (StringHelper.isNullOrEmpty(conditionImmunities)) {
monsterConditionImmunities.setVisibility(View.GONE);
} else {
monsterConditionImmunities.setVisibility(View.VISIBLE);
}
monsterConditionImmunities.setText(Html.fromHtml("<b>Condition Immunities</b> " + conditionImmunities));
}
});
final TextView monsterSenses = root.findViewById(R.id.senses);
monsterViewModel.getSenses().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String senses) {
monsterViewModel.getSenses().observe(getViewLifecycleOwner(), senses -> {
if (StringHelper.isNullOrEmpty(senses)) {
monsterSenses.setVisibility(View.GONE);
} else {
monsterSenses.setVisibility(View.VISIBLE);
}
monsterSenses.setText(Html.fromHtml("<b>Senses</b> " + senses));
}
});
final TextView monsterLanguages = root.findViewById(R.id.languages);
monsterViewModel.getLanguages().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String languages) {
monsterViewModel.getLanguages().observe(getViewLifecycleOwner(), languages -> {
if (StringHelper.isNullOrEmpty(languages)) {
monsterLanguages.setVisibility(View.GONE);
} else {
monsterLanguages.setVisibility(View.VISIBLE);
}
monsterLanguages.setText(Html.fromHtml("<b>Languages</b> " + languages));
}
});
final TextView monsterChallenge = root.findViewById(R.id.challenge);
monsterViewModel.getChallenge().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String challengeRating) {
monsterChallenge.setText(Html.fromHtml("<b>Challenge</b> " + challengeRating));
}
});
monsterViewModel.getChallenge().observe(getViewLifecycleOwner(), challengeRating -> monsterChallenge.setText(Html.fromHtml("<b>Challenge</b> " + challengeRating)));
final LinearLayout monsterAbilities = root.findViewById(R.id.abilities);
monsterViewModel.getAbilities().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> abilities) {
monsterViewModel.getAbilities().observe(getViewLifecycleOwner(), abilities -> {
Context context = getContext();
DisplayMetrics displayMetrics = null;
if (context != null) {
@@ -352,13 +277,10 @@ public class MonsterFragment extends Fragment {
monsterAbilities.addView(tvAbility);
}
}
}
});
final LinearLayout monsterActions = root.findViewById(R.id.actions);
monsterViewModel.getActions().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> actions) {
monsterViewModel.getActions().observe(getViewLifecycleOwner(), actions -> {
Context context = getContext();
DisplayMetrics displayMetrics = null;
if (context != null) {
@@ -378,7 +300,6 @@ public class MonsterFragment extends Fragment {
monsterActions.addView(tvAction);
}
}
}
});
return root;