Adds armor class and section divider to monster cards.
This commit is contained in:
@@ -4,6 +4,7 @@ import com.majinnaibu.monstercards.helpers.StringHelper;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class Monster {
|
public class Monster {
|
||||||
|
|
||||||
@@ -87,4 +88,200 @@ public class Monster {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getAbilityScore(String abilityScoreName) {
|
||||||
|
if ("strength".equals(abilityScoreName) || "str".equals(abilityScoreName)) {
|
||||||
|
return getStrengthScore();
|
||||||
|
} else if ("dexterity".equals(abilityScoreName) || "dex".equals(abilityScoreName)) {
|
||||||
|
return getDexterityScore();
|
||||||
|
} else if ("constitution".equals(abilityScoreName) || "con".equals(abilityScoreName)) {
|
||||||
|
return getConstitutionScore();
|
||||||
|
} else if ("intelligence".equals(abilityScoreName) || "int".equals(abilityScoreName)) {
|
||||||
|
return getIntelligenceScore();
|
||||||
|
} else if ("wisdom".equals(abilityScoreName) || "wis".equals(abilityScoreName)) {
|
||||||
|
return getWisdomScore();
|
||||||
|
} else if ("charisma".equals(abilityScoreName) || "cha".equals(abilityScoreName)) {
|
||||||
|
return getCharismaScore();
|
||||||
|
} else {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getAbilityModifierForScore(int score) {
|
||||||
|
return (int)Math.floor((score-10)/2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAbilityModifier(String abilityScoreName) {
|
||||||
|
int score = getAbilityScore(abilityScoreName);
|
||||||
|
return getAbilityModifierForScore(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mStrengthScore;
|
||||||
|
public int getStrengthScore() {
|
||||||
|
return mStrengthScore;
|
||||||
|
}
|
||||||
|
public void setStrengthScore(int value) {
|
||||||
|
mStrengthScore = value;
|
||||||
|
}
|
||||||
|
public int getStrengthModifier() {
|
||||||
|
return getAbilityModifierForScore(getStrengthScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mDexterityScore;
|
||||||
|
public int getDexterityScore() {
|
||||||
|
return mDexterityScore;
|
||||||
|
}
|
||||||
|
public void setDexterityScore(int value) {
|
||||||
|
mDexterityScore = value;
|
||||||
|
}
|
||||||
|
public int getDexterityModifier() {
|
||||||
|
return getAbilityModifierForScore(getDexterityScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mConstitutionScore;
|
||||||
|
public int getConstitutionScore() {
|
||||||
|
return mConstitutionScore;
|
||||||
|
}
|
||||||
|
public void setConstitutionScore(int value) {
|
||||||
|
mConstitutionScore = value;
|
||||||
|
}
|
||||||
|
public int getConstitutionModifier() {
|
||||||
|
return getAbilityModifierForScore(getConstitutionScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mIntelligenceScore;
|
||||||
|
public int getIntelligenceScore() {
|
||||||
|
return mIntelligenceScore;
|
||||||
|
}
|
||||||
|
public void setIntelligenceScore(int value) {
|
||||||
|
mIntelligenceScore = value;
|
||||||
|
}
|
||||||
|
public int getIntelligenceModifier() {
|
||||||
|
return getAbilityModifierForScore(getIntelligenceScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mWisdomScore;
|
||||||
|
public int getWisdomScore() {
|
||||||
|
return mWisdomScore;
|
||||||
|
}
|
||||||
|
public void setWisdomScore(int value) {
|
||||||
|
mWisdomScore = value;
|
||||||
|
}
|
||||||
|
public int getWisdomModifier() {
|
||||||
|
return getAbilityModifierForScore(getWisdomScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mCharismaScore;
|
||||||
|
public int getCharismaScore() {
|
||||||
|
return mCharismaScore;
|
||||||
|
}
|
||||||
|
public void setCharismaScore(int value) {
|
||||||
|
mCharismaScore = value;
|
||||||
|
}
|
||||||
|
public int getCharismaModifier() {
|
||||||
|
return getAbilityModifierForScore(getCharismaScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String mArmorName;
|
||||||
|
public String getArmorName() {
|
||||||
|
return mArmorName;
|
||||||
|
}
|
||||||
|
public void setArmorName(String value) {
|
||||||
|
mArmorName = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mShieldBonus;
|
||||||
|
public int getShieldBonus() {
|
||||||
|
return mShieldBonus;
|
||||||
|
}
|
||||||
|
public void setShieldBonus(int value) {
|
||||||
|
mShieldBonus = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mNaturalArmorBonus;
|
||||||
|
public int getNaturalArmorBonus() {
|
||||||
|
return mNaturalArmorBonus;
|
||||||
|
}
|
||||||
|
public void setNaturalArmorBonus(int value) {
|
||||||
|
mNaturalArmorBonus = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String mOtherArmorDescription;
|
||||||
|
public String getOtherArmorDescription() {
|
||||||
|
return mOtherArmorDescription;
|
||||||
|
}
|
||||||
|
public void setOtherArmorDescription(String value) {
|
||||||
|
mOtherArmorDescription = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArmorClass() {
|
||||||
|
boolean hasShield = getShieldBonus() != 0;
|
||||||
|
String armorName = getArmorName();
|
||||||
|
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)) {
|
||||||
|
// 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)) {
|
||||||
|
// 10 + dexMod + 2 for shield + 3 for mage armor "15 (18 with mage armor)" or 17 (shield, 20 with mage armor)
|
||||||
|
return String.format(Locale.US, "%d (%s%d with mage armor)", BASE_ARMOR_CLASS + getDexterityModifier() + getShieldBonus(), hasShield ? "shield, " : "", MAGE_ARMOR_ARMOR_CLASS + getDexterityModifier() + getShieldBonus());
|
||||||
|
} else if ("padded".equals(armorName)) {
|
||||||
|
// 11 + dexMod + 2 for shield "18 (padded armor, shield)"
|
||||||
|
return String.format(Locale.US, "%d (padded%s)", PADDED_ARMOR_ARMOR_CLASS + getDexterityModifier() + getShieldBonus(), hasShield ? ", shield" : "");
|
||||||
|
} else if ("leather".equals(armorName)) {
|
||||||
|
// 11 + dexMod + 2 for shield "18 (leather, shield)"
|
||||||
|
return String.format(Locale.US, "%d (leather%s)", LEATHER_ARMOR_CLASS + getDexterityModifier() + getShieldBonus(), hasShield ? ", shield" : "");
|
||||||
|
} else if ("studded".equals(armorName)) {
|
||||||
|
// 12 + dexMod +2 for shield "17 (studded leather)"
|
||||||
|
return String.format(Locale.US, "%d (studded leather%s)", STUDDED_LEATHER_ARMOR_CLASS + getDexterityModifier() + getShieldBonus(), hasShield ? ", shield" : "");
|
||||||
|
} else if ("hide".equals(armorName)) {
|
||||||
|
// 12 + Min(2, dexMod) + 2 for shield "12 (hide armor)"
|
||||||
|
return String.format(Locale.US, "%d (hide%s)", HIDE_ARMOR_CLASS + Math.min(2, getDexterityModifier()) + getShieldBonus(), hasShield ? ", shield" : "");
|
||||||
|
} else if ("chain shirt".equals(armorName)) {
|
||||||
|
// 13 + Min(2, dexMod) + 2 for shield "12 (chain shirt)"
|
||||||
|
return String.format(Locale.US, "%d (chain shirt%s)", CHAIN_SHIRT_ARMOR_CLASS + Math.min(2, getDexterityModifier()) + getShieldBonus(), hasShield ? ", shield" : "");
|
||||||
|
} else if ("scale mail".equals(armorName)) {
|
||||||
|
// 14 + Min(2, dexMod) + 2 for shield "14 (scale mail)"
|
||||||
|
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" : "");
|
||||||
|
} 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" : "");
|
||||||
|
} else if ("ring mail".equals(armorName)) {
|
||||||
|
// 14 + 2 for shield "14 (ring mail)
|
||||||
|
return String.format(Locale.US, "%d (ring mail%s)", RING_MAIL_ARMOR_CLASS + getShieldBonus(), hasShield ? ", shield" : "");
|
||||||
|
} else if ("chain mail".equals(armorName)) {
|
||||||
|
// 16 + 2 for shield "16 (chain mail)"
|
||||||
|
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": "");
|
||||||
|
} 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": "");
|
||||||
|
} else if ("other".equals(armorName)) {
|
||||||
|
// pure string value shield check does nothing just copies the string from otherArmorDesc
|
||||||
|
return getOtherArmorDescription();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int BASE_ARMOR_CLASS = 10;
|
||||||
|
private static final int MAGE_ARMOR_ARMOR_CLASS = BASE_ARMOR_CLASS + 3;
|
||||||
|
private static final int PADDED_ARMOR_ARMOR_CLASS = BASE_ARMOR_CLASS + 1;
|
||||||
|
private static final int LEATHER_ARMOR_CLASS = BASE_ARMOR_CLASS + 1;
|
||||||
|
private static final int STUDDED_LEATHER_ARMOR_CLASS = BASE_ARMOR_CLASS + 2;
|
||||||
|
private static final int HIDE_ARMOR_CLASS = BASE_ARMOR_CLASS + 2;
|
||||||
|
private static final int CHAIN_SHIRT_ARMOR_CLASS = BASE_ARMOR_CLASS + 3;
|
||||||
|
private static final int SCALE_MAIL_ARMOR_CLASS = BASE_ARMOR_CLASS + 4;
|
||||||
|
private static final int BREASTPLATE_ARMOR_CLASS = BASE_ARMOR_CLASS + 4;
|
||||||
|
private static final int HALF_PLATE_ARMOR_CLASS = BASE_ARMOR_CLASS + 5;
|
||||||
|
private static final int RING_MAIL_ARMOR_CLASS = BASE_ARMOR_CLASS + 4;
|
||||||
|
private static final int CHAIN_MAIL_ARMOR_CLASS = BASE_ARMOR_CLASS + 6;
|
||||||
|
private static final int SPLINT_ARMOR_CLASS = BASE_ARMOR_CLASS + 7;
|
||||||
|
private static final int PLATE_ARMOR_CLASS = BASE_ARMOR_CLASS + 8;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.majinnaibu.monstercards.ui.monster;
|
package com.majinnaibu.monstercards.ui.monster;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.Html;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -32,6 +33,11 @@ public class MonsterFragment extends Fragment {
|
|||||||
monster.setType("fey");
|
monster.setType("fey");
|
||||||
monster.setTag("");
|
monster.setTag("");
|
||||||
monster.setAlignment("neutral good");
|
monster.setAlignment("neutral good");
|
||||||
|
// Armor & Armor Class
|
||||||
|
monster.setArmorName("none");
|
||||||
|
monster.setShieldBonus(0);
|
||||||
|
monster.setNaturalArmorBonus(7);
|
||||||
|
monster.setOtherArmorDescription("14");
|
||||||
// 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);
|
||||||
@@ -48,8 +54,16 @@ public class MonsterFragment extends Fragment {
|
|||||||
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(), new Observer<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(@Nullable String s) {
|
public void onChanged(@Nullable String metaText) {
|
||||||
monsterMeta.setText(s);
|
monsterMeta.setText(metaText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final TextView monsterArmorClass = root.findViewById(R.id.armor_class);
|
||||||
|
monsterViewModel.getArmorClass().observe(getViewLifecycleOwner(), new Observer<String>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable String armorText) {
|
||||||
|
monsterArmorClass.setText(Html.fromHtml("<b>Armor Class</b> " + armorText));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ public class MonsterViewModel extends ViewModel {
|
|||||||
mName.setValue("");
|
mName.setValue("");
|
||||||
mMeta = new MutableLiveData<>();
|
mMeta = new MutableLiveData<>();
|
||||||
mMeta.setValue("");
|
mMeta.setValue("");
|
||||||
|
mArmorClass = new MutableLiveData<>();
|
||||||
|
mArmorClass.setValue("");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MutableLiveData<String> mName;
|
private MutableLiveData<String> mName;
|
||||||
@@ -24,11 +27,16 @@ public class MonsterViewModel extends ViewModel {
|
|||||||
public LiveData<String> getMeta() {
|
public LiveData<String> getMeta() {
|
||||||
return mMeta;
|
return mMeta;
|
||||||
}
|
}
|
||||||
|
private MutableLiveData<String> mArmorClass;
|
||||||
|
public LiveData<String> getArmorClass() {
|
||||||
|
return mArmorClass;
|
||||||
|
}
|
||||||
|
|
||||||
private Monster mMonster;
|
private Monster mMonster;
|
||||||
public void setMonster(Monster monster) {
|
public void setMonster(Monster monster) {
|
||||||
mMonster = monster;
|
mMonster = monster;
|
||||||
mName.setValue(mMonster.getName());
|
mName.setValue(mMonster.getName());
|
||||||
mMeta.setValue(mMonster.getMeta());
|
mMeta.setValue(mMonster.getMeta());
|
||||||
|
mArmorClass.setValue(mMonster.getArmorClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
9
app/src/main/res/drawable/ic_section_divider.xml
Normal file
9
app/src/main/res/drawable/ic_section_divider.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="800.5dp"
|
||||||
|
android:height="20.5dp"
|
||||||
|
android:viewportWidth="800.5"
|
||||||
|
android:viewportHeight="20.5">
|
||||||
|
<path
|
||||||
|
android:pathData="M0.5,0l-0.5,20.5l800.5,-20.5l-800,0z"
|
||||||
|
android:fillColor="#9b2818"/>
|
||||||
|
</vector>
|
||||||
@@ -41,5 +41,33 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/name"
|
app:layout_constraintTop_toBottomOf="@+id/name"
|
||||||
tools:text="Tiny fey, neutral good" />
|
tools:text="Tiny fey, neutral good" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/divider1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="8dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:contentDescription="@string/section_divider"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/ic_section_divider"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/meta" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/armor_class"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/divider1"
|
||||||
|
tools:text="Armor Class 15" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
@@ -6,4 +6,5 @@
|
|||||||
<string name="title_library">Library</string>
|
<string name="title_library">Library</string>
|
||||||
<string name="action_search">Search</string>
|
<string name="action_search">Search</string>
|
||||||
<string name="label_search_query">Query</string>
|
<string name="label_search_query">Query</string>
|
||||||
|
<string name="section_divider">section divider</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user