Migrates Monster class to be storable in roomdb.

This commit is contained in:
2021-04-17 20:43:19 -07:00
committed by Tom Hicks
parent ca6a319bd9
commit b5834f3db2
18 changed files with 1218 additions and 1257 deletions

1
Android/.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

View File

@@ -9,7 +9,6 @@
<option value="noActionIfCompileErrors" /> <option value="noActionIfCompileErrors" />
<option value="organizeImports" /> <option value="organizeImports" />
<option value="reformat" /> <option value="reformat" />
<option value="rearrange" />
</set> </set>
</option> </option>
<option name="configurationPath" value="" /> <option name="configurationPath" value="" />

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

@@ -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;
@Database(entities = {Monster.class}, version=1) @SuppressWarnings("unused")
@TypeConverters({UUIDConverter.class}) @Database(entities = {Monster.class}, version = 1)
@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

@@ -1,18 +0,0 @@
package com.majinnaibu.monstercards.converters;
import androidx.room.TypeConverter;
import java.util.UUID;
public class UUIDConverter {
@TypeConverter
public static String fromUUID(UUID uuid) {
return uuid.toString();
}
@TypeConverter
public static UUID uuidFromString(String string) {
return UUID.fromString(string);
}
}

View File

@@ -1,6 +1,5 @@
package com.majinnaibu.monstercards.data.converters; package com.majinnaibu.monstercards.data.converters;
import androidx.annotation.NonNull;
import androidx.room.TypeConverter; import androidx.room.TypeConverter;
import com.majinnaibu.monstercards.data.enums.ArmorType; import com.majinnaibu.monstercards.data.enums.ArmorType;
@@ -8,7 +7,7 @@ import com.majinnaibu.monstercards.data.enums.ArmorType;
public class ArmorTypeConverter { public class ArmorTypeConverter {
@TypeConverter @TypeConverter
public static String fromArmorType(@NonNull ArmorType armorType) { public static String fromArmorType(ArmorType armorType) {
return armorType.stringValue; return armorType.stringValue;
} }

View File

@@ -1,6 +1,5 @@
package com.majinnaibu.monstercards.data.converters; package com.majinnaibu.monstercards.data.converters;
import androidx.annotation.NonNull;
import androidx.room.TypeConverter; import androidx.room.TypeConverter;
import com.majinnaibu.monstercards.data.enums.ChallengeRating; import com.majinnaibu.monstercards.data.enums.ChallengeRating;
@@ -8,7 +7,7 @@ import com.majinnaibu.monstercards.data.enums.ChallengeRating;
public class ChallengeRatingConverter { public class ChallengeRatingConverter {
@TypeConverter @TypeConverter
public static String fromChallengeRating(@NonNull ChallengeRating challengeRating) { public static String fromChallengeRating(ChallengeRating challengeRating) {
return challengeRating.stringValue; return challengeRating.stringValue;
} }

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,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,15 +1,13 @@
package com.majinnaibu.monstercards.data.converters; package com.majinnaibu.monstercards.data.converters;
import androidx.annotation.NonNull;
import androidx.room.TypeConverter; import androidx.room.TypeConverter;
import java.util.UUID; import java.util.UUID;
public class UUIDConverter { public class UUIDConverter {
@NonNull
@TypeConverter @TypeConverter
public static String fromUUID(@NonNull UUID uuid) { public static String fromUUID(UUID uuid) {
return uuid.toString(); return uuid.toString();
} }

View File

@@ -5,7 +5,7 @@ public enum AbilityScore {
STRENGTH("strength", "Strength", "STR"), STRENGTH("strength", "Strength", "STR"),
DEXTERITY("dexterity", "Dexterity", "DEX"), DEXTERITY("dexterity", "Dexterity", "DEX"),
CONSTITUTION("constitution", "Constitution", "CON"), CONSTITUTION("constitution", "Constitution", "CON"),
INTELLIGENCE("intelligence", "Intelligence", "INT"), INTELLIGENCE("intellligence", "Intelligence", "INT"),
WISDOM("wisdom", "Wisdom", "WIS"), WISDOM("wisdom", "Wisdom", "WIS"),
CHARISMA("charisma", "Charisma", "CHA"), CHARISMA("charisma", "Charisma", "CHA"),
; ;

View File

@@ -3,7 +3,7 @@ package com.majinnaibu.monstercards.data.enums;
public enum ProficiencyType { public enum ProficiencyType {
NONE("none", "None", ""), NONE("none", "None", ""),
PROFICIENT("proficient", "Proficient", "P"), PROFICIENT("proficient", "Proficient", "P"),
EXPERTISE("expertise", "Expertise", "Ex"), EXPERTISE("experties", "Expertise", "Ex"),
; ;
public final String displayName; public final String displayName;

View File

@@ -1,25 +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,68 +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;
public void setName(String name) { this.advantageType = advantageType;
mName = name; this.proficiencyType = proficiencyType;
}
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

@@ -1,11 +1,6 @@
package com.majinnaibu.monstercards.models; package com.majinnaibu.monstercards.models;
import androidx.annotation.Nullable; public class Trait {
import java.util.Comparator;
import java.util.Objects;
public class Trait implements Comparator<Trait>, Comparable<Trait> {
public String name; public String name;
public String description; public String description;
@@ -14,36 +9,4 @@ public class Trait implements Comparator<Trait>, Comparable<Trait> {
this.name = name; this.name = name;
this.description = description; this.description = description;
} }
@Override
public int compareTo(Trait o) {
return compare(this, o);
}
@Override
public int compare(Trait o1, Trait o2) {
int result = o1.name.compareToIgnoreCase(o2.name);
if (result != 0) {
return result;
}
return o1.description.compareToIgnoreCase(o2.description);
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Trait)) {
return false;
}
Trait otherTrait = (Trait) obj;
if (!Objects.equals(this.name, otherTrait.name)) {
return false;
}
if (!Objects.equals(this.description, otherTrait.description)) {
return false;
}
return true;
}
} }

View File

@@ -14,22 +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.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 {
@@ -42,290 +41,219 @@ public class MonsterFragment extends Fragment {
// TODO: remove this block make the monster ID a parameter to the view and get the monster from saved data (sqlite) // TODO: remove this block make the monster ID a parameter to the view and get the monster from saved data (sqlite)
Monster monster = new Monster(); Monster monster = new Monster();
// 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
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);
View root = inflater.inflate(R.layout.fragment_monster, container, false); View root = inflater.inflate(R.layout.fragment_monster, container, false);
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) {
@@ -348,6 +276,28 @@ public class MonsterFragment extends Fragment {
monsterAbilities.addView(tvAbility); monsterAbilities.addView(tvAbility);
} }
} }
});
final LinearLayout monsterActions = root.findViewById(R.id.actions);
monsterViewModel.getActions().observe(getViewLifecycleOwner(), actions -> {
Context context = getContext();
DisplayMetrics displayMetrics = null;
if (context != null) {
Resources resources = context.getResources();
if (resources != null) {
displayMetrics = resources.getDisplayMetrics();
}
}
monsterActions.removeAllViews();
if (actions != null) {
for (String action : actions) {
TextView tvAction = new TextView(getContext());
tvAction.setText(Html.fromHtml(CommonMarkHelper.toHtml(action)));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, displayMetrics);
tvAction.setLayoutParams(layoutParams);
monsterActions.addView(tvAction);
}
} }
}); });