diff --git a/Android/app/schemas/com.majinnaibu.monstercards.AppDatabase/1.json b/Android/app/schemas/com.majinnaibu.monstercards.AppDatabase/1.json index 83ab2bc..f92e587 100644 --- a/Android/app/schemas/com.majinnaibu.monstercards.AppDatabase/1.json +++ b/Android/app/schemas/com.majinnaibu.monstercards.AppDatabase/1.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "db1293d2f490940b55ca1f4f56b21b1a", + "identityHash": "a9371223372fb64522cc40f5529ada09", "entities": [ { "tableName": "Monster", - "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`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`id`))", "fields": [ { "fieldPath": "id", @@ -20,405 +20,6 @@ "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": { @@ -434,7 +35,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, 'db1293d2f490940b55ca1f4f56b21b1a')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a9371223372fb64522cc40f5529ada09')" ] } } \ No newline at end of file diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java b/Android/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java index 7b27aa6..fc44923 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/AppDatabase.java @@ -4,27 +4,12 @@ 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.ListOfTraitsConverter; -import com.majinnaibu.monstercards.data.converters.SetOfLanguageConverter; -import com.majinnaibu.monstercards.data.converters.SetOfSkillConverter; -import com.majinnaibu.monstercards.data.converters.SetOfStringConverter; -import com.majinnaibu.monstercards.data.converters.UUIDConverter; import com.majinnaibu.monstercards.models.Monster; -import com.majinnaibu.monstercards.models.MonsterFTS; -@Database(entities = {Monster.class, MonsterFTS.class}, version = 3) -@TypeConverters({ - ArmorTypeConverter.class, - ChallengeRatingConverter.class, - ListOfTraitsConverter.class, - SetOfLanguageConverter.class, - SetOfSkillConverter.class, - SetOfStringConverter.class, - UUIDConverter.class, -}) +@Database(entities = {Monster.class}, version=1) +@TypeConverters({UUIDConverter.class}) public abstract class AppDatabase extends RoomDatabase { public abstract MonsterDAO monsterDAO(); } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/converters/UUIDConverter.java b/Android/app/src/main/java/com/majinnaibu/monstercards/converters/UUIDConverter.java new file mode 100644 index 0000000..b1effc8 --- /dev/null +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/converters/UUIDConverter.java @@ -0,0 +1,18 @@ +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); + } +} diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/data/MonsterDAO.java b/Android/app/src/main/java/com/majinnaibu/monstercards/data/MonsterDAO.java index 9671790..5295e92 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/data/MonsterDAO.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/data/MonsterDAO.java @@ -4,7 +4,6 @@ package com.majinnaibu.monstercards.data; import androidx.room.Dao; import androidx.room.Delete; import androidx.room.Insert; -import androidx.room.OnConflictStrategy; import androidx.room.Query; import com.majinnaibu.monstercards.models.Monster; @@ -16,24 +15,18 @@ import io.reactivex.rxjava3.core.Flowable; @Dao public interface MonsterDAO { - @Query("SELECT * FROM monsters") + @Query("SELECT * FROM monster") Flowable> getAll(); - @Query("SELECT * FROM monsters WHERE id IN (:monsterIds)") + @Query("SELECT * FROM monster WHERE id IN (:monsterIds)") Flowable> loadAllByIds(String[] monsterIds); - @Query("SELECT * FROM monsters WHERE name LIKE :name LIMIT 1") + @Query("SELECT * FROM monster WHERE name LIKE :name LIMIT 1") Flowable findByName(String name); - @Query("SELECT monsters.* FROM monsters JOIN monsters_fts ON monsters.oid = monsters_fts.docid WHERE monsters_fts MATCH :searchText") - Flowable> search(String searchText); - @Insert Completable insertAll(Monster... monsters); - @Insert(onConflict = OnConflictStrategy.REPLACE) - Completable save(Monster... monsters); - @Delete Completable delete(Monster monster); } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java b/Android/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java index 61aff23..e755fed 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/models/Monster.java @@ -1,5 +1,11 @@ package com.majinnaibu.monstercards.models; +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.Ignore; +import androidx.room.PrimaryKey; + import com.majinnaibu.monstercards.helpers.StringHelper; import java.util.ArrayList; @@ -9,11 +15,23 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.UUID; +@Entity public class Monster { + @PrimaryKey + @NonNull + public UUID id; + + @NonNull + @ColumnInfo(defaultValue = "") + public String name; + public Monster() { + name = ""; mAbilities = new ArrayList<>(); + mActions = new ArrayList<>(); mConditionImmunities = new HashSet<>(); mDamageTypes = new HashSet<>(); mLanguages = new HashSet<>(); @@ -21,42 +39,46 @@ public class Monster { mSkills = new HashSet<>(); } - private String mName; - public String getName() { - return mName; - } - public void setName(String value) { - mName = value; - } - + @Ignore() private String mSize; + public String getSize() { return mSize; } + public void setSize(String value) { mSize = value; } + @Ignore() private String mType; + public String getType() { return mType; } + public void setType(String value) { mType = value; } + @Ignore() private String mTag; + public String getTag() { return mTag; } + public void setTag(String value) { mTag = value; } + @Ignore() private String mAlignment; + public String getAlignment() { return mAlignment; } + public void setAlignment(String value) { mAlignment = value; } @@ -120,7 +142,7 @@ public class Monster { } public static int getAbilityModifierForScore(int score) { - return (int)Math.floor((score-10)/2.0); + return (int) Math.floor((score - 10) / 2.0); } public int getAbilityModifier(String abilityScoreName) { @@ -128,100 +150,136 @@ public class Monster { return getAbilityModifierForScore(score); } + @Ignore() private int mStrengthScore; + public int getStrengthScore() { return mStrengthScore; } + public void setStrengthScore(int value) { mStrengthScore = value; } + public int getStrengthModifier() { return getAbilityModifierForScore(getStrengthScore()); } + @Ignore() private int mDexterityScore; + public int getDexterityScore() { return mDexterityScore; } + public void setDexterityScore(int value) { mDexterityScore = value; } + public int getDexterityModifier() { return getAbilityModifierForScore(getDexterityScore()); } + @Ignore() private int mConstitutionScore; + public int getConstitutionScore() { return mConstitutionScore; } + public void setConstitutionScore(int value) { mConstitutionScore = value; } + public int getConstitutionModifier() { return getAbilityModifierForScore(getConstitutionScore()); } + @Ignore() private int mIntelligenceScore; + public int getIntelligenceScore() { return mIntelligenceScore; } + public void setIntelligenceScore(int value) { mIntelligenceScore = value; } + public int getIntelligenceModifier() { return getAbilityModifierForScore(getIntelligenceScore()); } + @Ignore() private int mWisdomScore; + public int getWisdomScore() { return mWisdomScore; } + public void setWisdomScore(int value) { mWisdomScore = value; } + public int getWisdomModifier() { return getAbilityModifierForScore(getWisdomScore()); } + @Ignore() private int mCharismaScore; + public int getCharismaScore() { return mCharismaScore; } + public void setCharismaScore(int value) { mCharismaScore = value; } + public int getCharismaModifier() { return getAbilityModifierForScore(getCharismaScore()); } + @Ignore() private String mArmorName; + public String getArmorName() { return mArmorName; } + public void setArmorName(String value) { mArmorName = value; } + @Ignore() private int mShieldBonus; + public int getShieldBonus() { return mShieldBonus; } + public void setShieldBonus(int value) { mShieldBonus = value; } + @Ignore() private int mNaturalArmorBonus; + public int getNaturalArmorBonus() { return mNaturalArmorBonus; } + public void setNaturalArmorBonus(int value) { mNaturalArmorBonus = value; } + @Ignore() private String mOtherArmorDescription; + public String getOtherArmorDescription() { return mOtherArmorDescription; } + public void setOtherArmorDescription(String value) { mOtherArmorDescription = value; } @@ -232,7 +290,7 @@ public class Monster { if (StringHelper.isNullOrEmpty(armorName) || "none".equals(armorName)) { // 10 + dexMod + 2 for shieldBonus "15" or "17 (shield)" return String.format(Locale.US, "%d%s", BASE_ARMOR_CLASS + getDexterityModifier() + getShieldBonus(), hasShield ? " (shield)" : ""); - } else if("natural armor".equals(armorName)) { + } else if ("natural armor".equals(armorName)) { // 10 + dexMod + naturalArmorBonus + 2 for shieldBonus "16 (natural armor)" or "18 (natural armor, shield)" return String.format(Locale.US, "%d (natural armor%s)", BASE_ARMOR_CLASS + getDexterityModifier() + getNaturalArmorBonus() + getShieldBonus(), hasShield ? ", shield" : ""); } else if ("mage armor".equals(armorName)) { @@ -258,7 +316,7 @@ public class Monster { return String.format(Locale.US, "%d (scale mail%s)", SCALE_MAIL_ARMOR_CLASS + Math.min(2, getDexterityModifier()) + getShieldBonus(), hasShield ? ", shield" : ""); } else if ("breastplate".equals(armorName)) { // 14 + Min(2, dexMod) + 2 for shield "16 (breastplate)" - return String.format(Locale.US, "%d (breastplate%s)", BREASTPLATE_ARMOR_CLASS +Math.min(2, getDexterityModifier()) + getShieldBonus(), hasShield ? ", shield" : ""); + return String.format(Locale.US, "%d (breastplate%s)", BREASTPLATE_ARMOR_CLASS + Math.min(2, getDexterityModifier()) + getShieldBonus(), hasShield ? ", shield" : ""); } else if ("half plate".equals(armorName)) { // 15 + Min(2, dexMod) + 2 for shield "17 (half plate)" return String.format(Locale.US, "%d (half plate%s)", HALF_PLATE_ARMOR_CLASS + Math.min(2, getDexterityModifier()) + getShieldBonus(), hasShield ? ", shield" : ""); @@ -270,10 +328,10 @@ public class Monster { return String.format(Locale.US, "%d (chain mail%s)", CHAIN_MAIL_ARMOR_CLASS + getShieldBonus(), hasShield ? ", shield" : ""); } else if ("splint".equals(armorName)) { // 17 + 2 for shield "17 (splint)" - return String.format(Locale.US, "%d (splint%s)", SPLINT_ARMOR_CLASS + getShieldBonus(), hasShield ? ", shield": ""); + return String.format(Locale.US, "%d (splint%s)", SPLINT_ARMOR_CLASS + getShieldBonus(), hasShield ? ", shield" : ""); } else if ("plate".equals(armorName)) { // 18 + 2 for shield "18 (plate)" - return String.format(Locale.US, "%d (plate%s)", PLATE_ARMOR_CLASS + getShieldBonus(), hasShield ? ", shield": ""); + return String.format(Locale.US, "%d (plate%s)", PLATE_ARMOR_CLASS + getShieldBonus(), hasShield ? ", shield" : ""); } else if ("other".equals(armorName)) { // pure string value shield check does nothing just copies the string from otherArmorDesc return getOtherArmorDescription(); @@ -297,26 +355,35 @@ public class Monster { private static final int SPLINT_ARMOR_CLASS = BASE_ARMOR_CLASS + 7; private static final int PLATE_ARMOR_CLASS = BASE_ARMOR_CLASS + 8; + @Ignore() private int mHitDice; + public int getHitDice() { return mHitDice; } + public void setHitDice(int value) { mHitDice = value; } + @Ignore() private boolean mCustomHP; + public boolean getCustomHP() { return mCustomHP; } + public void setCustomHP(boolean value) { mCustomHP = value; } + @Ignore() private String mHPText; + public String getHPText() { return mHPText; } + public void setHPText(String value) { mHPText = value; } @@ -328,6 +395,9 @@ public class Monster { int hitDice = getHitDice(); int dieSize = getHitDieForSize(getSize()); int conMod = getConstitutionModifier(); + // For PC style calculations use this + //int hpTotal = (int) Math.max(1, Math.ceil(dieSize + conMod + (hitDice - 1) * ((dieSize + 1) / 2.0 + conMod))); + // For monster style calculations use this int hpTotal = (int) Math.max(1, Math.ceil(hitDice * ((dieSize + 1) / 2.0 + conMod))); return String.format(Locale.US, "%d (%dd%d %+d)", hpTotal, hitDice, dieSize, conMod * hitDice); } @@ -351,66 +421,90 @@ public class Monster { } } + @Ignore() private String mSpeed; + public String getSpeed() { return mSpeed; } + public void setSpeed(String value) { mSpeed = value; } + @Ignore() private String mBurrowSpeed; + public String getBurrowSpeed() { return mBurrowSpeed; } + public void setBurrowSpeed(String value) { mBurrowSpeed = value; } + @Ignore() private String mClimbSpeed; + public String getClimbSpeed() { return mClimbSpeed; } + public void setClimbSpeed(String value) { mClimbSpeed = value; } + @Ignore() private String mFlySpeed; + public String getFlySpeed() { return mFlySpeed; } + public void setFlySpeed(String value) { mFlySpeed = value; } + @Ignore() private boolean mHover; + public boolean getHover() { return mHover; } + public void setHover(boolean value) { mHover = value; } + @Ignore() private String mSwimSpeed; + public String getSwimSpeed() { return mSwimSpeed; } + public void setSwimSpeed(String value) { mSwimSpeed = value; } + @Ignore() private boolean mCustomSpeed; + public boolean getCustomSpeed() { return mCustomSpeed; } + public void setCustomSpeed(boolean value) { mCustomSpeed = value; } + @Ignore() private String mSpeedDescription; + public String getSpeedDescription() { return mSpeedDescription; } + public void setSpeedDescription(String value) { mSpeedDescription = value; } @@ -469,16 +563,21 @@ public class Monster { return String.format(Locale.US, "%d (%+d)", getCharismaScore(), getCharismaModifier()); } + @Ignore() private HashSet mSavingThrows; + public Set getSavingThrows() { return mSavingThrows; } + public void addSavingThrow(SavingThrow savingThrow) { mSavingThrows.add(savingThrow); } + public void removeSavingThrow(SavingThrow savingThrow) { mSavingThrows.remove(savingThrow); } + public void clearSavingThrows() { mSavingThrows.clear(); } @@ -495,7 +594,7 @@ public class Monster { } String name = st.getName(); - sb.append(String.format(Locale.US, "%s%s %+d", name.substring(0,1).toUpperCase(Locale.US), name.substring(1), getAbilityModifier(name) + getProficiencyBonus())); + sb.append(String.format(Locale.US, "%s%s %+d", name.substring(0, 1).toUpperCase(Locale.US), name.substring(1), getAbilityModifier(name) + getProficiencyBonus())); isFirst = false; } return sb.toString(); @@ -506,61 +605,61 @@ public class Monster { if ("*".equals(challengeRating)) { return getCustomProficiencyBonus(); } else if ( - "0".equals(challengeRating) || - "1/8".equals(challengeRating) || - "1/4".equals(challengeRating) || - "1/2".equals(challengeRating) || - "1".equals(challengeRating) || - "2".equals(challengeRating) || - "3".equals(challengeRating) || - "4".equals(challengeRating) + "0".equals(challengeRating) || + "1/8".equals(challengeRating) || + "1/4".equals(challengeRating) || + "1/2".equals(challengeRating) || + "1".equals(challengeRating) || + "2".equals(challengeRating) || + "3".equals(challengeRating) || + "4".equals(challengeRating) ) { return 2; } else if ( - "5".equals(challengeRating) || - "6".equals(challengeRating) || - "7".equals(challengeRating) || - "8".equals(challengeRating) + "5".equals(challengeRating) || + "6".equals(challengeRating) || + "7".equals(challengeRating) || + "8".equals(challengeRating) ) { return 3; } else if ( - "9".equals(challengeRating) || - "10".equals(challengeRating) || - "11".equals(challengeRating) || - "12".equals(challengeRating) + "9".equals(challengeRating) || + "10".equals(challengeRating) || + "11".equals(challengeRating) || + "12".equals(challengeRating) ) { return 4; } else if ( - "13".equals(challengeRating) || - "14".equals(challengeRating) || - "15".equals(challengeRating) || - "16".equals(challengeRating) + "13".equals(challengeRating) || + "14".equals(challengeRating) || + "15".equals(challengeRating) || + "16".equals(challengeRating) ) { return 5; } else if ( - "17".equals(challengeRating) || - "18".equals(challengeRating) || - "19".equals(challengeRating) || - "20".equals(challengeRating) + "17".equals(challengeRating) || + "18".equals(challengeRating) || + "19".equals(challengeRating) || + "20".equals(challengeRating) ) { return 6; } else if ( - "21".equals(challengeRating) || - "22".equals(challengeRating) || - "23".equals(challengeRating) || - "24".equals(challengeRating) + "21".equals(challengeRating) || + "22".equals(challengeRating) || + "23".equals(challengeRating) || + "24".equals(challengeRating) ) { return 7; } else if ( - "25".equals(challengeRating) || - "26".equals(challengeRating) || - "27".equals(challengeRating) || - "28".equals(challengeRating) + "25".equals(challengeRating) || + "26".equals(challengeRating) || + "27".equals(challengeRating) || + "28".equals(challengeRating) ) { return 8; } else if ( - "29".equals(challengeRating) || - "30".equals(challengeRating) + "29".equals(challengeRating) || + "30".equals(challengeRating) ) { return 9; } else { @@ -568,41 +667,55 @@ public class Monster { } } + @Ignore() private String mChallengeRating; + public String getChallengeRating() { return mChallengeRating; } + public void setChallengeRating(String challengeRating) { mChallengeRating = challengeRating; // TODO: update proficiency bonus based on CR } + @Ignore() private String mCustomChallengeRating; + public String getCustomChallengeRating() { return mCustomChallengeRating; } + public void setCustomChallengeRating(String challengeRating) { mCustomChallengeRating = challengeRating; } + @Ignore() private int mCustomProficiencyBonus; + public int getCustomProficiencyBonus() { return mCustomProficiencyBonus; } + public void setCustomProficiencyBonus(int proficiencyBonus) { mCustomProficiencyBonus = proficiencyBonus; } + @Ignore() private HashSet mSkills; + public Set getSkills() { return mSkills; } + public void addSkill(Skill skill) { mSkills.add(skill); } + public void removeSkill(Skill skill) { mSkills.remove(skill); } + public void clearSkill(Skill skill) { mSkills.clear(); } @@ -624,17 +737,22 @@ public class Monster { return sb.toString(); } + @Ignore() private HashSet mDamageTypes; + public Set getDamageTypes() { return mDamageTypes; } + public void addDamageType(DamageType damageType) { // TODO: make this remove the damage type with the same name if it exists first mDamageTypes.add(damageType); } + public void removeDamageType(DamageType damageType) { mDamageTypes.remove(damageType); } + public void clearDamageTypes() { mDamageTypes.clear(); } @@ -649,6 +767,7 @@ public class Monster { Collections.sort(vulnerabilities); return StringHelper.oxfordJoin(", ", ", and ", " and ", vulnerabilities); } + public String getDamageResistancesDescription() { ArrayList vulnerabilities = new ArrayList<>(); for (DamageType damageType : mDamageTypes) { @@ -659,6 +778,7 @@ public class Monster { Collections.sort(vulnerabilities); return StringHelper.oxfordJoin(", ", ", and ", " and ", vulnerabilities); } + public String getDamageImmunitiesDescription() { ArrayList vulnerabilities = new ArrayList<>(); for (DamageType damageType : mDamageTypes) { @@ -670,18 +790,23 @@ public class Monster { return StringHelper.oxfordJoin(", ", ", and ", " and ", vulnerabilities); } + @Ignore() private HashSet mConditionImmunities; + public Set getConditionImmunities() { return mConditionImmunities; } + public void addConditionImmunity(String condition) { // TODO: filter out duplicates mConditionImmunities.add(condition); } + public void removeConditionImmunity(String condition) { // TODO: make sure this works even though we're using strings mConditionImmunities.remove(condition); } + public void clearConditionImmunities() { mConditionImmunities.clear(); } @@ -692,42 +817,57 @@ public class Monster { return StringHelper.oxfordJoin(", ", ", and ", " and ", immunities); } + @Ignore() private String mBlindsight; + public String getBlindsight() { return mBlindsight; } + public void setBlindsight(String value) { mBlindsight = value; } + @Ignore() private boolean mIsBlind; + public boolean getIsBlind() { return mIsBlind; } + public void setIsBlind(boolean value) { mIsBlind = value; } + @Ignore() private String mDarkvision; + public String getDarkvision() { return mDarkvision; } + public void setDarkvision(String value) { mDarkvision = value; } + @Ignore() private String mTremorsense; + public String getTremorsense() { return mTremorsense; } + public void setTremorsense(String value) { mTremorsense = value; } + @Ignore() private String mTruesight; + public String getTruesight() { return mTruesight; } + public void setTruesight(String value) { mTruesight = value; } @@ -756,32 +896,43 @@ public class Monster { return StringHelper.join(", ", parts); } + @Ignore() private HashSet mLanguages; + public Set getLanguages() { return mLanguages; } + public void addLanguage(Language value) { mLanguages.add(value); } + public void removeLanguage(Language value) { mLanguages.remove(value); } + public void clearLanguages() { mLanguages.clear(); } + @Ignore() private int mTelepathy; + public int getTelepathy() { return mTelepathy; } + public void setTelepathy(int value) { mTelepathy = value; } + @Ignore() private String mUnderstandsBut; + public String getUnderstandsBut() { return mUnderstandsBut; } + public void setUnderstandsBut(String value) { mUnderstandsBut = value; } @@ -919,16 +1070,21 @@ public class Monster { } } + @Ignore() private ArrayList mAbilities; + public List getAbilities() { return mAbilities; } + public void addAbility(Ability ability) { mAbilities.add(ability); } + public void removeAbility(Ability ability) { mAbilities.remove(ability); } + public void clearAbilities() { mAbilities.clear(); } @@ -959,7 +1115,7 @@ public class Monster { public int getSavingThrow(String name) { Set sts = getSavingThrows(); - for(SavingThrow st : sts) { + for (SavingThrow st : sts) { if (name.equals(st.getName())) { return getAbilityModifier(name) + getProficiencyBonus(); } @@ -979,4 +1135,31 @@ public class Monster { return getProficiencyBonus() + getAbilityModifier(abilityScoreName); } + public List getActionDescriptions() { + ArrayList actions = new ArrayList<>(); + for (Action action : getActions()) { + actions.add(getPlaceholderReplacedText(String.format("__%s__ %s", action.getName(), action.getDescription()))); + } + return actions; + } + + @Ignore() + private ArrayList mActions; + + public List getActions() { + return mActions; + } + + public void addAction(Action ability) { + mActions.add(ability); + } + + public void removeAction(Action ability) { + mActions.remove(ability); + } + + public void clearActions() { + mActions.clear(); + } + } diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java index 2b8b1ee..32c707b 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterFragment.java @@ -42,7 +42,7 @@ 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) Monster monster = new Monster(); // Name - monster.setName("Pixie"); + monster.name ="Pixie"; // Meta monster.setSize("tiny"); monster.setType("fey"); diff --git a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java index 2d28237..24b507a 100644 --- a/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java +++ b/Android/app/src/main/java/com/majinnaibu/monstercards/ui/monster/MonsterViewModel.java @@ -13,105 +13,79 @@ public class MonsterViewModel extends ViewModel { public MonsterViewModel() { mMonster = null; - mName = new MutableLiveData<>(); - mName.setValue(""); - mMeta = new MutableLiveData<>(); - mMeta.setValue(""); + mAbilities = new MutableLiveData<>(); + mAbilities.setValue(new ArrayList()); + mActions = new MutableLiveData<>(); + mActions.setValue(new ArrayList()); mArmorClass = new MutableLiveData<>(); mArmorClass.setValue(""); + mChallenge = new MutableLiveData<>(); + mChallenge.setValue(""); + mCharisma = new MutableLiveData<>(); + mCharisma.setValue(""); + mConditionImmunities = new MutableLiveData<>(); + mConditionImmunities.setValue(""); + mConstitution = new MutableLiveData<>(); + mConstitution.setValue(""); + mDamageImmunities = new MutableLiveData<>(); + mDamageImmunities.setValue(""); + mDamageResistances = new MutableLiveData<>(); + mDamageResistances.setValue(""); + mDamageVulnerabilities = new MutableLiveData<>(); + mDamageVulnerabilities.setValue(""); + mDexterity = new MutableLiveData<>(); + mDexterity.setValue(""); mHitPoints = new MutableLiveData<>(); mHitPoints.setValue(""); + mIntelligence = new MutableLiveData<>(); + mIntelligence.setValue(""); + mLanguages = new MutableLiveData<>(); + mLanguages.setValue(""); + mMeta = new MutableLiveData<>(); + mMeta.setValue(""); + mName = new MutableLiveData<>(); + mName.setValue(""); + mSavingThrows = new MutableLiveData<>(); + mSavingThrows.setValue(""); + mSenses = new MutableLiveData<>(); + mSenses.setValue(""); + mSkills = new MutableLiveData<>(); + mSkills.setValue(""); mSpeed = new MutableLiveData<>(); mSpeed.setValue(""); mStrength = new MutableLiveData<>(); mStrength.setValue(""); - mDexterity = new MutableLiveData<>(); - mDexterity.setValue(""); - mConstitution = new MutableLiveData<>(); - mConstitution.setValue(""); - mIntelligence = new MutableLiveData<>(); - mIntelligence.setValue(""); mWisdom = new MutableLiveData<>(); mWisdom.setValue(""); - mCharisma = new MutableLiveData<>(); - mCharisma.setValue(""); - mSavingThrows = new MutableLiveData<>(); - mSavingThrows.setValue(""); - mSkills = new MutableLiveData<>(); - mSkills.setValue(""); - mDamageVulnerabilities = new MutableLiveData<>(); - mDamageVulnerabilities.setValue(""); - mDamageResistances = new MutableLiveData<>(); - mDamageResistances.setValue(""); - mDamageImmunities = new MutableLiveData<>(); - mDamageImmunities.setValue(""); - mConditionImmunities = new MutableLiveData<>(); - mConditionImmunities.setValue(""); - mSenses = new MutableLiveData<>(); - mSenses.setValue(""); - mLanguages = new MutableLiveData<>(); - mLanguages.setValue(""); - mChallenge = new MutableLiveData<>(); - mChallenge.setValue(""); - mAbilities = new MutableLiveData<>(); - mAbilities.setValue(new ArrayList()); } - private MutableLiveData mName; - public LiveData getName() { - return mName; + private MutableLiveData> mAbilities; + public LiveData> getAbilities() { + return mAbilities; } - private MutableLiveData mMeta; - public LiveData getMeta() { - return mMeta; + private MutableLiveData> mActions; + public LiveData> getActions() { + return mActions; } private MutableLiveData mArmorClass; public LiveData getArmorClass() { return mArmorClass; } - private MutableLiveData mHitPoints; - public LiveData getHitPoints() { - return mHitPoints; - } - private MutableLiveData mSpeed; - public LiveData getSpeed() { - return mSpeed; - } - private MutableLiveData mStrength; - public LiveData getStrength() { - return mStrength; - } - private MutableLiveData mDexterity; - public LiveData getDexterity() { - return mDexterity; - } - private MutableLiveData mConstitution; - public LiveData getConstitution() { - return mConstitution; - } - private MutableLiveData mIntelligence; - public LiveData getIntelligence() { - return mIntelligence; - } - private MutableLiveData mWisdom; - public LiveData getWisdom() { - return mWisdom; + private MutableLiveData mChallenge; + public LiveData getChallenge() { + return mChallenge; } private MutableLiveData mCharisma; public LiveData getCharisma() { return mCharisma; } - private MutableLiveData mSavingThrows; - public LiveData getSavingThrows() { - return mSavingThrows; + private MutableLiveData mConditionImmunities; + public LiveData getConditionImmunities() { + return mConditionImmunities; } - private MutableLiveData mSkills; - public LiveData getSkills() { - return mSkills; - } - private MutableLiveData mDamageVulnerabilities; - public LiveData getDamageVulnerabilities() { - return mDamageVulnerabilities; + private MutableLiveData mConstitution; + public LiveData getConstitution() { + return mConstitution; } private MutableLiveData mDamageResistances; public LiveData getDamageResistances() { @@ -121,50 +95,84 @@ public class MonsterViewModel extends ViewModel { public LiveData getDamageImmunities() { return mDamageImmunities; } - private MutableLiveData mConditionImmunities; - public LiveData getConditionImmunities() { - return mConditionImmunities; + private MutableLiveData mDamageVulnerabilities; + public LiveData getDamageVulnerabilities() { + return mDamageVulnerabilities; } - private MutableLiveData mSenses; - public LiveData getSenses() { - return mSenses; + private MutableLiveData mDexterity; + public LiveData getDexterity() { + return mDexterity; + } + private MutableLiveData mHitPoints; + public LiveData getHitPoints() { + return mHitPoints; + } + private MutableLiveData mIntelligence; + public LiveData getIntelligence() { + return mIntelligence; } private MutableLiveData mLanguages; public LiveData getLanguages() { return mLanguages; } - private MutableLiveData mChallenge; - public LiveData getChallenge() { - return mChallenge; + private MutableLiveData mMeta; + public LiveData getMeta() { + return mMeta; } - private MutableLiveData> mAbilities; - public LiveData> getAbilities() { - return mAbilities; + private MutableLiveData mName; + public LiveData getName() { + return mName; + } + private MutableLiveData mSavingThrows; + public LiveData getSavingThrows() { + return mSavingThrows; + } + private MutableLiveData mSenses; + public LiveData getSenses() { + return mSenses; + } + private MutableLiveData mSkills; + public LiveData getSkills() { + return mSkills; + } + private MutableLiveData mSpeed; + public LiveData getSpeed() { + return mSpeed; + } + private MutableLiveData mStrength; + public LiveData getStrength() { + return mStrength; + } + private MutableLiveData mWisdom; + public LiveData getWisdom() { + return mWisdom; } private Monster mMonster; public void setMonster(Monster monster) { mMonster = monster; - mName.setValue(mMonster.getName()); - mMeta.setValue(mMonster.getMeta()); + + mAbilities.setValue(mMonster.getAbilityDescriptions()); + mActions.setValue(mMonster.getActionDescriptions()); mArmorClass.setValue(mMonster.getArmorClass()); + mChallenge.setValue(mMonster.getChallengeRatingDescription()); + mCharisma.setValue(monster.getCharismaDescription()); + mConditionImmunities.setValue(mMonster.getConditionImmunitiesDescription()); + mConstitution.setValue(monster.getConstitutionDescription()); + mDamageImmunities.setValue(mMonster.getDamageImmunitiesDescription()); + mDamageResistances.setValue(mMonster.getDamageResistancesDescription()); + mDamageVulnerabilities.setValue(mMonster.getDamageVulnerabilitiesDescription()); + mDexterity.setValue(monster.getDexterityDescription()); mHitPoints.setValue(mMonster.getHitPoints()); + mIntelligence.setValue(monster.getIntelligenceDescription()); + mLanguages.setValue(mMonster.getLanguagesDescription()); + mMeta.setValue(mMonster.getMeta()); + mName.setValue(mMonster.name); + mSavingThrows.setValue(monster.getSavingThrowsDescription()); + mSenses.setValue(monster.getSensesDescription()); + mSkills.setValue(monster.getSkillsDescription()); mSpeed.setValue(mMonster.getSpeedText()); mStrength.setValue(monster.getStrengthDescription()); - mDexterity.setValue(monster.getDexterityDescription()); - mConstitution.setValue(monster.getConstitutionDescription()); - mIntelligence.setValue(monster.getIntelligenceDescription()); mWisdom.setValue(monster.getWisdomDescription()); - mCharisma.setValue(monster.getCharismaDescription()); - mSavingThrows.setValue(monster.getSavingThrowsDescription()); - mSkills.setValue(monster.getSkillsDescription()); - mDamageVulnerabilities.setValue(mMonster.getDamageVulnerabilitiesDescription()); - mDamageResistances.setValue(mMonster.getDamageResistancesDescription()); - mDamageImmunities.setValue(mMonster.getDamageImmunitiesDescription()); - mConditionImmunities.setValue(mMonster.getConditionImmunitiesDescription()); - mSenses.setValue(monster.getSensesDescription()); - mLanguages.setValue(mMonster.getLanguagesDescription()); - mChallenge.setValue(mMonster.getChallengeRatingDescription()); - mAbilities.setValue(mMonster.getAbilityDescriptions()); } } \ No newline at end of file