diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..91178d1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,43 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+*.pydevproject
+.project
+.metadata
+bin/**
+tmp/**
+tmp/**/*
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
diff --git a/.hg_archival.txt b/.hg_archival.txt
new file mode 100644
index 0000000..04e2a31
--- /dev/null
+++ b/.hg_archival.txt
@@ -0,0 +1,5 @@
+repo: 914aff8c7379c73e4430fc8d7b68b3893eef7c50
+node: 53cffbe32a610eba9f4da289daa0d55b0b2c5bae
+branch: default
+latesttag: null
+latesttagdistance: 153
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..1da9fe1
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,5 @@
+syntax: glob
+
+*.class
+*.orig
+*.apk
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..302b5a1
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/BookIcon/BookIconVector.svg b/assets/BookIcon/BookIconVector.svg
new file mode 100644
index 0000000..c96f15f
--- /dev/null
+++ b/assets/BookIcon/BookIconVector.svg
@@ -0,0 +1,358 @@
+
+
+
+
diff --git a/assets/BookIcon/FeatureGraphic.svg b/assets/BookIcon/FeatureGraphic.svg
new file mode 100644
index 0000000..8e364f2
--- /dev/null
+++ b/assets/BookIcon/FeatureGraphic.svg
@@ -0,0 +1,616 @@
+
+
+
+
diff --git a/assets/BookIcon/PromoGraphic.svg b/assets/BookIcon/PromoGraphic.svg
new file mode 100644
index 0000000..71ed88f
--- /dev/null
+++ b/assets/BookIcon/PromoGraphic.svg
@@ -0,0 +1,614 @@
+
+
+
+
diff --git a/assets/BookIcon/TileIconVector.svg b/assets/BookIcon/TileIconVector.svg
new file mode 100644
index 0000000..e0e13d7
--- /dev/null
+++ b/assets/BookIcon/TileIconVector.svg
@@ -0,0 +1,457 @@
+
+
+
+
diff --git a/assets/BookIcon/TileIcon_xhdpi.png b/assets/BookIcon/TileIcon_xhdpi.png
new file mode 100644
index 0000000..d2726df
Binary files /dev/null and b/assets/BookIcon/TileIcon_xhdpi.png differ
diff --git a/assets/BookIcon/bookicon_xhdpi.png b/assets/BookIcon/bookicon_xhdpi.png
new file mode 100644
index 0000000..e900bf7
Binary files /dev/null and b/assets/BookIcon/bookicon_xhdpi.png differ
diff --git a/assets/BookIcon/rect3878.png b/assets/BookIcon/rect3878.png
new file mode 100644
index 0000000..484874b
Binary files /dev/null and b/assets/BookIcon/rect3878.png differ
diff --git a/assets/feature_graphic.png b/assets/feature_graphic.png
new file mode 100644
index 0000000..98c512d
Binary files /dev/null and b/assets/feature_graphic.png differ
diff --git a/assets/icons/quill_hdpi.png b/assets/icons/quill_hdpi.png
new file mode 100644
index 0000000..f18de05
Binary files /dev/null and b/assets/icons/quill_hdpi.png differ
diff --git a/assets/icons/quill_hdpi.xcf b/assets/icons/quill_hdpi.xcf
new file mode 100644
index 0000000..94324d2
Binary files /dev/null and b/assets/icons/quill_hdpi.xcf differ
diff --git a/assets/icons/quill_ldpi.png b/assets/icons/quill_ldpi.png
new file mode 100644
index 0000000..5bb9604
Binary files /dev/null and b/assets/icons/quill_ldpi.png differ
diff --git a/assets/icons/quill_ldpi.xcf b/assets/icons/quill_ldpi.xcf
new file mode 100644
index 0000000..2f5ebf0
Binary files /dev/null and b/assets/icons/quill_ldpi.xcf differ
diff --git a/assets/icons/quill_mdpi.png b/assets/icons/quill_mdpi.png
new file mode 100644
index 0000000..b70e0e2
Binary files /dev/null and b/assets/icons/quill_mdpi.png differ
diff --git a/assets/icons/quill_mdpi.xcf b/assets/icons/quill_mdpi.xcf
new file mode 100644
index 0000000..31c6470
Binary files /dev/null and b/assets/icons/quill_mdpi.xcf differ
diff --git a/assets/icons/quill_xhdpi.png b/assets/icons/quill_xhdpi.png
new file mode 100644
index 0000000..04518ba
Binary files /dev/null and b/assets/icons/quill_xhdpi.png differ
diff --git a/assets/icons/quill_xhdpi.xcf b/assets/icons/quill_xhdpi.xcf
new file mode 100644
index 0000000..5aaffa6
Binary files /dev/null and b/assets/icons/quill_xhdpi.xcf differ
diff --git a/assets/iconsV2/icon_ldpi.png b/assets/iconsV2/icon_ldpi.png
new file mode 100644
index 0000000..54b77b3
Binary files /dev/null and b/assets/iconsV2/icon_ldpi.png differ
diff --git a/assets/iconsV2/icon_ldpi.xcf b/assets/iconsV2/icon_ldpi.xcf
new file mode 100644
index 0000000..9b4ac3b
Binary files /dev/null and b/assets/iconsV2/icon_ldpi.xcf differ
diff --git a/assets/iconsV2/icon_mdpi.xcf b/assets/iconsV2/icon_mdpi.xcf
new file mode 100644
index 0000000..eb692f7
Binary files /dev/null and b/assets/iconsV2/icon_mdpi.xcf differ
diff --git a/assets/iconsV2/icon_xhdpi_shitty.png b/assets/iconsV2/icon_xhdpi_shitty.png
new file mode 100644
index 0000000..d4f8915
Binary files /dev/null and b/assets/iconsV2/icon_xhdpi_shitty.png differ
diff --git a/assets/iconsV2/icon_xhdpi_shitty.xcf b/assets/iconsV2/icon_xhdpi_shitty.xcf
new file mode 100644
index 0000000..d9ba5bc
Binary files /dev/null and b/assets/iconsV2/icon_xhdpi_shitty.xcf differ
diff --git a/assets/play store icon.png b/assets/play store icon.png
new file mode 100644
index 0000000..78c8569
Binary files /dev/null and b/assets/play store icon.png differ
diff --git a/assets/promo_banner.png b/assets/promo_banner.png
new file mode 100644
index 0000000..c2d7df5
Binary files /dev/null and b/assets/promo_banner.png differ
diff --git a/assets/screenshots/character sheet abilities.png b/assets/screenshots/character sheet abilities.png
new file mode 100644
index 0000000..73af320
Binary files /dev/null and b/assets/screenshots/character sheet abilities.png differ
diff --git a/assets/screenshots/character sheet skills.png b/assets/screenshots/character sheet skills.png
new file mode 100644
index 0000000..8ff07ab
Binary files /dev/null and b/assets/screenshots/character sheet skills.png differ
diff --git a/assets/screenshots/character sheet spells.png b/assets/screenshots/character sheet spells.png
new file mode 100644
index 0000000..c37bb51
Binary files /dev/null and b/assets/screenshots/character sheet spells.png differ
diff --git a/assets/screenshots/dice roller.png b/assets/screenshots/dice roller.png
new file mode 100644
index 0000000..e185005
Binary files /dev/null and b/assets/screenshots/dice roller.png differ
diff --git a/assets/screenshots/initiative tracker.png b/assets/screenshots/initiative tracker.png
new file mode 100644
index 0000000..a630f51
Binary files /dev/null and b/assets/screenshots/initiative tracker.png differ
diff --git a/assets/screenshots/main menu.jpg b/assets/screenshots/main menu.jpg
new file mode 100644
index 0000000..a41ee25
Binary files /dev/null and b/assets/screenshots/main menu.jpg differ
diff --git a/assets/screenshots/main menu.png b/assets/screenshots/main menu.png
new file mode 100644
index 0000000..34e9a09
Binary files /dev/null and b/assets/screenshots/main menu.png differ
diff --git a/assets/screenshots/party manager.png b/assets/screenshots/party manager.png
new file mode 100644
index 0000000..50ef9df
Binary files /dev/null and b/assets/screenshots/party manager.png differ
diff --git a/assets/screenshots/party skill checker.png b/assets/screenshots/party skill checker.png
new file mode 100644
index 0000000..c644201
Binary files /dev/null and b/assets/screenshots/party skill checker.png differ
diff --git a/assets/screenshots/pointbuy calculator.png b/assets/screenshots/pointbuy calculator.png
new file mode 100644
index 0000000..1974af8
Binary files /dev/null and b/assets/screenshots/pointbuy calculator.png differ
diff --git a/ic_launcher-web.png b/ic_launcher-web.png
new file mode 100644
index 0000000..3e4fc52
Binary files /dev/null and b/ic_launcher-web.png differ
diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar
new file mode 100644
index 0000000..feaf44f
Binary files /dev/null and b/libs/android-support-v4.jar differ
diff --git a/libs/google-gson-2.2.2/LICENSE b/libs/google-gson-2.2.2/LICENSE
new file mode 100644
index 0000000..892eaed
--- /dev/null
+++ b/libs/google-gson-2.2.2/LICENSE
@@ -0,0 +1,203 @@
+Google Gson
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2008-2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/libs/google-gson-2.2.2/README b/libs/google-gson-2.2.2/README
new file mode 100644
index 0000000..a0562cc
--- /dev/null
+++ b/libs/google-gson-2.2.2/README
@@ -0,0 +1,7 @@
+Gson is a Java library that can be used to convert a Java object into its
+JSON representation. It can also be used to convert a JSON string into an
+equivalent Java object. Gson can work with arbitrary Java objects including
+pre-existing objects that you do not have source-code of.
+
+Complete Gson documentation is available at its project page
+http://code.google.com/p/google-gson
diff --git a/libs/google-gson-2.2.2/gson-2.2.2-javadoc.jar b/libs/google-gson-2.2.2/gson-2.2.2-javadoc.jar
new file mode 100644
index 0000000..2958b0d
Binary files /dev/null and b/libs/google-gson-2.2.2/gson-2.2.2-javadoc.jar differ
diff --git a/libs/google-gson-2.2.2/gson-2.2.2-sources.jar b/libs/google-gson-2.2.2/gson-2.2.2-sources.jar
new file mode 100644
index 0000000..db8fb05
Binary files /dev/null and b/libs/google-gson-2.2.2/gson-2.2.2-sources.jar differ
diff --git a/libs/google-gson-2.2.2/gson-2.2.2.jar b/libs/google-gson-2.2.2/gson-2.2.2.jar
new file mode 100644
index 0000000..f2108e0
Binary files /dev/null and b/libs/google-gson-2.2.2/gson-2.2.2.jar differ
diff --git a/lint.xml b/lint.xml
new file mode 100644
index 0000000..ee0eead
--- /dev/null
+++ b/lint.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..0840b4a
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-15
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..7685126
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,3 @@
+Readme
+
+Now different
\ No newline at end of file
diff --git a/res/drawable-hdpi/character_sheet_icon.png b/res/drawable-hdpi/character_sheet_icon.png
new file mode 100644
index 0000000..24fbc2c
Binary files /dev/null and b/res/drawable-hdpi/character_sheet_icon.png differ
diff --git a/res/drawable-hdpi/dice_roller_icon.png b/res/drawable-hdpi/dice_roller_icon.png
new file mode 100644
index 0000000..b55ee7b
Binary files /dev/null and b/res/drawable-hdpi/dice_roller_icon.png differ
diff --git a/res/drawable-hdpi/ic_action_search.png b/res/drawable-hdpi/ic_action_search.png
new file mode 100644
index 0000000..af82946
Binary files /dev/null and b/res/drawable-hdpi/ic_action_search.png differ
diff --git a/res/drawable-hdpi/ic_launcher_quillsword.png b/res/drawable-hdpi/ic_launcher_quillsword.png
new file mode 100644
index 0000000..a2f1a38
Binary files /dev/null and b/res/drawable-hdpi/ic_launcher_quillsword.png differ
diff --git a/res/drawable-hdpi/initiative_icon.png b/res/drawable-hdpi/initiative_icon.png
new file mode 100644
index 0000000..e1fb31a
Binary files /dev/null and b/res/drawable-hdpi/initiative_icon.png differ
diff --git a/res/drawable-hdpi/party_icon.png b/res/drawable-hdpi/party_icon.png
new file mode 100644
index 0000000..0c74bd5
Binary files /dev/null and b/res/drawable-hdpi/party_icon.png differ
diff --git a/res/drawable-hdpi/rate_meme.png b/res/drawable-hdpi/rate_meme.png
new file mode 100644
index 0000000..a748da3
Binary files /dev/null and b/res/drawable-hdpi/rate_meme.png differ
diff --git a/res/drawable-hdpi/skill_checker_icon.png b/res/drawable-hdpi/skill_checker_icon.png
new file mode 100644
index 0000000..38748a4
Binary files /dev/null and b/res/drawable-hdpi/skill_checker_icon.png differ
diff --git a/res/drawable-hdpi/stat_calc_icon.png b/res/drawable-hdpi/stat_calc_icon.png
new file mode 100644
index 0000000..fa39644
Binary files /dev/null and b/res/drawable-hdpi/stat_calc_icon.png differ
diff --git a/res/drawable-ldpi/character_sheet_icon.png b/res/drawable-ldpi/character_sheet_icon.png
new file mode 100644
index 0000000..8e904a9
Binary files /dev/null and b/res/drawable-ldpi/character_sheet_icon.png differ
diff --git a/res/drawable-ldpi/dice_roller_icon.png b/res/drawable-ldpi/dice_roller_icon.png
new file mode 100644
index 0000000..cf4f5fa
Binary files /dev/null and b/res/drawable-ldpi/dice_roller_icon.png differ
diff --git a/res/drawable-ldpi/ic_launcher_quillsword.png b/res/drawable-ldpi/ic_launcher_quillsword.png
new file mode 100644
index 0000000..7b0e623
Binary files /dev/null and b/res/drawable-ldpi/ic_launcher_quillsword.png differ
diff --git a/res/drawable-ldpi/initiative_icon.png b/res/drawable-ldpi/initiative_icon.png
new file mode 100644
index 0000000..fdf0bce
Binary files /dev/null and b/res/drawable-ldpi/initiative_icon.png differ
diff --git a/res/drawable-ldpi/party_icon.png b/res/drawable-ldpi/party_icon.png
new file mode 100644
index 0000000..ac79258
Binary files /dev/null and b/res/drawable-ldpi/party_icon.png differ
diff --git a/res/drawable-ldpi/rate_meme.png b/res/drawable-ldpi/rate_meme.png
new file mode 100644
index 0000000..f317a76
Binary files /dev/null and b/res/drawable-ldpi/rate_meme.png differ
diff --git a/res/drawable-ldpi/skill_checker_icon.png b/res/drawable-ldpi/skill_checker_icon.png
new file mode 100644
index 0000000..81b1209
Binary files /dev/null and b/res/drawable-ldpi/skill_checker_icon.png differ
diff --git a/res/drawable-ldpi/stat_calc_icon.png b/res/drawable-ldpi/stat_calc_icon.png
new file mode 100644
index 0000000..a7b1943
Binary files /dev/null and b/res/drawable-ldpi/stat_calc_icon.png differ
diff --git a/res/drawable-mdpi/character_sheet_icon.png b/res/drawable-mdpi/character_sheet_icon.png
new file mode 100644
index 0000000..f9aa75e
Binary files /dev/null and b/res/drawable-mdpi/character_sheet_icon.png differ
diff --git a/res/drawable-mdpi/dice_roller_icon.png b/res/drawable-mdpi/dice_roller_icon.png
new file mode 100644
index 0000000..c4c935c
Binary files /dev/null and b/res/drawable-mdpi/dice_roller_icon.png differ
diff --git a/res/drawable-mdpi/ic_action_search.png b/res/drawable-mdpi/ic_action_search.png
new file mode 100644
index 0000000..293933e
Binary files /dev/null and b/res/drawable-mdpi/ic_action_search.png differ
diff --git a/res/drawable-mdpi/ic_launcher_quillsword.png b/res/drawable-mdpi/ic_launcher_quillsword.png
new file mode 100644
index 0000000..53f0d76
Binary files /dev/null and b/res/drawable-mdpi/ic_launcher_quillsword.png differ
diff --git a/res/drawable-mdpi/initiative_icon.png b/res/drawable-mdpi/initiative_icon.png
new file mode 100644
index 0000000..5282ba0
Binary files /dev/null and b/res/drawable-mdpi/initiative_icon.png differ
diff --git a/res/drawable-mdpi/party_icon.png b/res/drawable-mdpi/party_icon.png
new file mode 100644
index 0000000..37bddb0
Binary files /dev/null and b/res/drawable-mdpi/party_icon.png differ
diff --git a/res/drawable-mdpi/rate_meme.png b/res/drawable-mdpi/rate_meme.png
new file mode 100644
index 0000000..d6d1344
Binary files /dev/null and b/res/drawable-mdpi/rate_meme.png differ
diff --git a/res/drawable-mdpi/skill_checker_icon.png b/res/drawable-mdpi/skill_checker_icon.png
new file mode 100644
index 0000000..5f23efa
Binary files /dev/null and b/res/drawable-mdpi/skill_checker_icon.png differ
diff --git a/res/drawable-mdpi/stat_calc_icon.png b/res/drawable-mdpi/stat_calc_icon.png
new file mode 100644
index 0000000..8fd3bee
Binary files /dev/null and b/res/drawable-mdpi/stat_calc_icon.png differ
diff --git a/res/drawable-xhdpi/character_sheet_icon.png b/res/drawable-xhdpi/character_sheet_icon.png
new file mode 100644
index 0000000..ba60748
Binary files /dev/null and b/res/drawable-xhdpi/character_sheet_icon.png differ
diff --git a/res/drawable-xhdpi/dice_roller_icon.png b/res/drawable-xhdpi/dice_roller_icon.png
new file mode 100644
index 0000000..fd0c2cf
Binary files /dev/null and b/res/drawable-xhdpi/dice_roller_icon.png differ
diff --git a/res/drawable-xhdpi/ic_action_search.png b/res/drawable-xhdpi/ic_action_search.png
new file mode 100644
index 0000000..d126803
Binary files /dev/null and b/res/drawable-xhdpi/ic_action_search.png differ
diff --git a/res/drawable-xhdpi/ic_launcher_quillsword.png b/res/drawable-xhdpi/ic_launcher_quillsword.png
new file mode 100644
index 0000000..c59f1ef
Binary files /dev/null and b/res/drawable-xhdpi/ic_launcher_quillsword.png differ
diff --git a/res/drawable-xhdpi/initiative_icon.png b/res/drawable-xhdpi/initiative_icon.png
new file mode 100644
index 0000000..2ee1373
Binary files /dev/null and b/res/drawable-xhdpi/initiative_icon.png differ
diff --git a/res/drawable-xhdpi/party_icon.png b/res/drawable-xhdpi/party_icon.png
new file mode 100644
index 0000000..84b4b83
Binary files /dev/null and b/res/drawable-xhdpi/party_icon.png differ
diff --git a/res/drawable-xhdpi/rate_meme.png b/res/drawable-xhdpi/rate_meme.png
new file mode 100644
index 0000000..5b7127e
Binary files /dev/null and b/res/drawable-xhdpi/rate_meme.png differ
diff --git a/res/drawable-xhdpi/skill_checker_icon.png b/res/drawable-xhdpi/skill_checker_icon.png
new file mode 100644
index 0000000..feea34f
Binary files /dev/null and b/res/drawable-xhdpi/skill_checker_icon.png differ
diff --git a/res/drawable-xhdpi/stat_calc_icon.png b/res/drawable-xhdpi/stat_calc_icon.png
new file mode 100644
index 0000000..c5e65fe
Binary files /dev/null and b/res/drawable-xhdpi/stat_calc_icon.png differ
diff --git a/res/layout/about_screen.xml b/res/layout/about_screen.xml
new file mode 100644
index 0000000..cfd9a3e
--- /dev/null
+++ b/res/layout/about_screen.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/activity_ability_calculator.xml b/res/layout/activity_ability_calculator.xml
new file mode 100644
index 0000000..9e65282
--- /dev/null
+++ b/res/layout/activity_ability_calculator.xml
@@ -0,0 +1,323 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_character_sheet_abilities.xml b/res/layout/activity_character_sheet_abilities.xml
new file mode 100644
index 0000000..34ccdc6
--- /dev/null
+++ b/res/layout/activity_character_sheet_abilities.xml
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_main_menu.xml b/res/layout/activity_main_menu.xml
new file mode 100644
index 0000000..f186408
--- /dev/null
+++ b/res/layout/activity_main_menu.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/res/layout/activity_party_manager.xml b/res/layout/activity_party_manager.xml
new file mode 100644
index 0000000..599836a
--- /dev/null
+++ b/res/layout/activity_party_manager.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_party_member_editor.xml b/res/layout/activity_party_member_editor.xml
new file mode 100644
index 0000000..42fd632
--- /dev/null
+++ b/res/layout/activity_party_member_editor.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_ptdice_roller.xml b/res/layout/activity_ptdice_roller.xml
new file mode 100644
index 0000000..476ebc6
--- /dev/null
+++ b/res/layout/activity_ptdice_roller.xml
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_ptinitiative_tracker.xml b/res/layout/activity_ptinitiative_tracker.xml
new file mode 100644
index 0000000..15ac108
--- /dev/null
+++ b/res/layout/activity_ptinitiative_tracker.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/activity_skill_checker.xml b/res/layout/activity_skill_checker.xml
new file mode 100644
index 0000000..51437e3
--- /dev/null
+++ b/res/layout/activity_skill_checker.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/calculator_custom_race_dialog.xml b/res/layout/calculator_custom_race_dialog.xml
new file mode 100644
index 0000000..0e1cfa0
--- /dev/null
+++ b/res/layout/calculator_custom_race_dialog.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_armor_dialog.xml b/res/layout/character_armor_dialog.xml
new file mode 100644
index 0000000..ed98a59
--- /dev/null
+++ b/res/layout/character_armor_dialog.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_armor_fragment.xml b/res/layout/character_armor_fragment.xml
new file mode 100644
index 0000000..952b0a0
--- /dev/null
+++ b/res/layout/character_armor_fragment.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_armor_row.xml b/res/layout/character_armor_row.xml
new file mode 100644
index 0000000..f627729
--- /dev/null
+++ b/res/layout/character_armor_row.xml
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_combat_stats_fragment.xml b/res/layout/character_combat_stats_fragment.xml
new file mode 100644
index 0000000..c30564f
--- /dev/null
+++ b/res/layout/character_combat_stats_fragment.xml
@@ -0,0 +1,1253 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_feats_dialog.xml b/res/layout/character_feats_dialog.xml
new file mode 100644
index 0000000..8012353
--- /dev/null
+++ b/res/layout/character_feats_dialog.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_feats_fragment.xml b/res/layout/character_feats_fragment.xml
new file mode 100644
index 0000000..a5e1da2
--- /dev/null
+++ b/res/layout/character_feats_fragment.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_fluff_dialog.xml b/res/layout/character_fluff_dialog.xml
new file mode 100644
index 0000000..db3d6e9
--- /dev/null
+++ b/res/layout/character_fluff_dialog.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_fluff_fragment.xml b/res/layout/character_fluff_fragment.xml
new file mode 100644
index 0000000..a9d7c7d
--- /dev/null
+++ b/res/layout/character_fluff_fragment.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_fluff_row.xml b/res/layout/character_fluff_row.xml
new file mode 100644
index 0000000..2b9777c
--- /dev/null
+++ b/res/layout/character_fluff_row.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_inventory_dialog.xml b/res/layout/character_inventory_dialog.xml
new file mode 100644
index 0000000..00956a1
--- /dev/null
+++ b/res/layout/character_inventory_dialog.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_inventory_fragment.xml b/res/layout/character_inventory_fragment.xml
new file mode 100644
index 0000000..320a1c8
--- /dev/null
+++ b/res/layout/character_inventory_fragment.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_inventory_row.xml b/res/layout/character_inventory_row.xml
new file mode 100644
index 0000000..098d9fa
--- /dev/null
+++ b/res/layout/character_inventory_row.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_skill_row.xml b/res/layout/character_skill_row.xml
new file mode 100644
index 0000000..325cb11
--- /dev/null
+++ b/res/layout/character_skill_row.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_skills_dialog.xml b/res/layout/character_skills_dialog.xml
new file mode 100644
index 0000000..8043184
--- /dev/null
+++ b/res/layout/character_skills_dialog.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_skills_fragment.xml b/res/layout/character_skills_fragment.xml
new file mode 100644
index 0000000..3267760
--- /dev/null
+++ b/res/layout/character_skills_fragment.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_spellbook_dialog.xml b/res/layout/character_spellbook_dialog.xml
new file mode 100644
index 0000000..d1eae06
--- /dev/null
+++ b/res/layout/character_spellbook_dialog.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_spellbook_fragment.xml b/res/layout/character_spellbook_fragment.xml
new file mode 100644
index 0000000..0a8b65c
--- /dev/null
+++ b/res/layout/character_spellbook_fragment.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_spellbook_row.xml b/res/layout/character_spellbook_row.xml
new file mode 100644
index 0000000..7d11a3f
--- /dev/null
+++ b/res/layout/character_spellbook_row.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_weapon_dialog.xml b/res/layout/character_weapon_dialog.xml
new file mode 100644
index 0000000..39ac216
--- /dev/null
+++ b/res/layout/character_weapon_dialog.xml
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_weapon_fragment.xml b/res/layout/character_weapon_fragment.xml
new file mode 100644
index 0000000..2afeb8d
--- /dev/null
+++ b/res/layout/character_weapon_fragment.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/character_weapon_row.xml b/res/layout/character_weapon_row.xml
new file mode 100644
index 0000000..665cf34
--- /dev/null
+++ b/res/layout/character_weapon_row.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/main_menu_row.xml b/res/layout/main_menu_row.xml
new file mode 100644
index 0000000..9050426
--- /dev/null
+++ b/res/layout/main_menu_row.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/party_member_stat_dialog.xml b/res/layout/party_member_stat_dialog.xml
new file mode 100644
index 0000000..bbac2c7
--- /dev/null
+++ b/res/layout/party_member_stat_dialog.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/party_member_stat_row.xml b/res/layout/party_member_stat_row.xml
new file mode 100644
index 0000000..b2ab1ac
--- /dev/null
+++ b/res/layout/party_member_stat_row.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/party_roll_row.xml b/res/layout/party_roll_row.xml
new file mode 100644
index 0000000..2d49686
--- /dev/null
+++ b/res/layout/party_roll_row.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/spinner_plain.xml b/res/layout/spinner_plain.xml
new file mode 100644
index 0000000..5e4f95e
--- /dev/null
+++ b/res/layout/spinner_plain.xml
@@ -0,0 +1,8 @@
+
+
diff --git a/res/menu/activity_character_list.xml b/res/menu/activity_character_list.xml
new file mode 100644
index 0000000..cde5e1c
--- /dev/null
+++ b/res/menu/activity_character_list.xml
@@ -0,0 +1,6 @@
+
diff --git a/res/menu/activity_main_menu.xml b/res/menu/activity_main_menu.xml
new file mode 100644
index 0000000..cfc10fd
--- /dev/null
+++ b/res/menu/activity_main_menu.xml
@@ -0,0 +1,6 @@
+
diff --git a/res/menu/activity_ptdice_roller.xml b/res/menu/activity_ptdice_roller.xml
new file mode 100644
index 0000000..cfc10fd
--- /dev/null
+++ b/res/menu/activity_ptdice_roller.xml
@@ -0,0 +1,6 @@
+
diff --git a/res/menu/activity_ptinitiative_tracker.xml b/res/menu/activity_ptinitiative_tracker.xml
new file mode 100644
index 0000000..cfc10fd
--- /dev/null
+++ b/res/menu/activity_ptinitiative_tracker.xml
@@ -0,0 +1,6 @@
+
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
new file mode 100644
index 0000000..1ae597c
--- /dev/null
+++ b/res/values-large/dimens.xml
@@ -0,0 +1,7 @@
+
+
+ 8dp
+ 16dp
+ 16dp
+
+
\ No newline at end of file
diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml
new file mode 100644
index 0000000..5b109b0
--- /dev/null
+++ b/res/values-v11/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-v14/styles.xml b/res/values-v14/styles.xml
new file mode 100644
index 0000000..5b109b0
--- /dev/null
+++ b/res/values-v14/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100644
index 0000000..6e5e111
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,27 @@
+
+ 14sp
+ 12sp
+ 100sp
+ 250dp
+
+ 60dp
+ 60dp
+ 160dp
+
+ 160dp
+ 160dp
+ 50sp
+
+ 5dp
+ 10dp
+ 5dp
+
+ 40sp
+ 3dp
+ 1dp
+ 2dp
+ 1dp
+ 50sp
+
+ 1dp
+
\ No newline at end of file
diff --git a/res/values/integers.xml b/res/values/integers.xml
new file mode 100644
index 0000000..890dd60
--- /dev/null
+++ b/res/values/integers.xml
@@ -0,0 +1,117 @@
+
+
+
+ 30
+ 9999
+
+ 6
+
+ 20
+
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+
+ 0
+ 1
+ 2
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 10
+
+
+ 0
+ 0
+ 2
+ 0
+ 2
+ -2
+
+
+
+ 0
+ 2
+ -2
+ 2
+ 0
+ 0
+
+
+
+ -2
+ 2
+ 0
+ 0
+ 0
+ 2
+
+
+
+ -2
+ 0
+ 2
+ 0
+ 0
+ 2
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+ 1
+ 3
+ 5
+ 0
+ 3
+ 5
+ 1
+ 5
+ 1
+ 1
+ 5
+ 4
+ 5
+ 3
+ 3
+ 3
+ 3
+ 3
+ 3
+ 3
+ 3
+ 3
+ 3
+ 3
+ 4
+ 5
+ 4
+ 1
+ 4
+ 1
+ 3
+ 1
+ 4
+ 0
+ 5
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..7c8c7e3
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,706 @@
+
+
+
+ Pathfinder Toolkit
+ Settings
+ Pathfinder Toolkit
+ Pointbuy Calculator
+ Character Sheet
+ Initiative Tracker
+ Party Skill Checker
+ Party Manager
+ Party Member Editor
+ ""
+ Autofill
+
+ Icon for main menu item
+
+
+ About
+ Open Game License
+ Version:
+ Development
+ Pathfinder Toolkit was developed by Gorden Larson and Trevor Siemens, operating as the Lateensoft group, using the Paizo Publishing, LLC Community Use Policy and Open Game License 1.0a. (viewable at http://paizo.com/pathfinderRPG/prd/openGameLicense.html )
+ If you have any feedback for us, or encounter any bugs in this app, please email us at info@lateensoft.host56.com
+ Community Use Notice
+ This application uses trademarks and/or copyrights owned by Paizo Publishing, LLC, which are used under Paizo\'s Community Use Policy. We are expressly prohibited from charging you to use or access this content. This application is not published, endorsed, or specifically approved by Paizo Publishing. For more information about Paizo\'s Community Use Policy, please visit paizo.com/communityuse. For more information about Paizo Publishing and Paizo products, please visit paizo.com.
+ Product Identity:
+
+
+
+
+
+
+ Dice Roller
+ Characters
+ Initiative Tracker
+ Party Skill Checker
+ Party Manager
+ Pointbuy Calculator
+
+ Please rate our app!
+ Rate
+ Later
+
+
+ Inventory
+ Weapons
+ Armor
+ Feats / S.A.
+ Skills
+ Abilities
+ Fluff
+ Spells
+ Combat Stats
+ Characters
+ New Character
+ Delete Character
+ Select Character
+ Create new character?
+ Are you sure you want to delete\u0020
+ \u003F \u000AThis action cannot be undone.
+
+
+ Dice Roller
+ Single Roll Mode
+ XdY Roll Mode
+ Cumulative Rolls Mode
+ d4
+ d6
+ d8
+ d10
+ d12
+ d20
+ d%
+ Sum =
+ Roll
+ Reset
+
+
+
+ STR
+ DEX
+ CON
+ INT
+ WIS
+ CHA
+
+
+ Fortitude
+ Reflex
+ Will
+
+
+ Value
+ STR
+ DEX
+ CON
+ INT
+ WIS
+ CHA
+ Final\nScore
+ Racial\nMod
+ -
+ +
+ Ability
+ Score
+ Mod.
+ Points:
+
+
+
+ Acrobatics
+ Appraise
+ Bluff
+ Climb
+ Craft
+ Diplomacy
+ Disable Device
+ Disguise
+ Escape Artist
+ Fly
+ Handle Animal
+ Heal
+ Intimidate
+ Knowledge (Arcana)
+ Knowledge (Dungeoneering)
+ Knowledge (Engineering)
+ Knowledge (Geography)
+ Knowledge (History)
+ Knowledge (Local)
+ Knowledge (Nature)
+ Knowledge (Nobility)
+ Knowledge (Planes)
+ Knowledge (Religion)
+ Linguistics
+ Perception
+ Perform
+ Profession
+ Ride
+ Sense Motive
+ Sleight of Hand
+ Spellcraft
+ Stealth
+ Survival
+ Swim
+ Use Magic Device
+
+
+
+ Export to new char
+ Export to existing char
+
+ Human
+ Dwarf
+ Elf
+ Halfling
+ Gnome
+ Half-Elf
+ Half-Orc
+ Custom Race
+
+ Custom Race: Set Modifiers
+
+ -10
+ -9
+ -8
+ -7
+ -6
+ -5
+ -4
+ -3
+ -2
+ -1
+ 0
+ +1
+ +2
+ +3
+ +4
+ +5
+ +6
+ +7
+ +8
+ +9
+ +10
+
+
+
+
+
+ -
+ HP:
+ Total:
+ DR:
+ Wounds:
+ Non-Lethal Dmg:
+ Base Speed:
+ Initiative:
+ =
+ FORT:
+ REF:
+ WILL:
+ Base
+ Ability Mod
+ Magic Mod
+ Temp Mod
+
+ Dex Mod
+
+ +
+
+ Misc Mod
+
+ AC:
+ = 10 +
+ Armor Bonus
+ Shield Bonus
+ Size Mod
+
+ Natural Armor
+ Deflect. Mod
+ Touch:
+ Flat Footed:
+ Spell Resistance:
+ BAB:
+ Primary
+ /
+ Second/Third/\u2026
+ CMB:
+ BAB
+ Strength Mod
+ CMD:
+ = 10 + CMB +
+
+
+ Total
+ Ability Mod.
+ Rank
+ Misc Mod.
+ Class Skill
+ Armor Check Penalty
+
+
+ +
+ Qty.
+ Item Name
+ Wt.
+ Cont.
+ Quantity
+ Weight
+ Contained
+ Total Wt:
+ gp:
+ Gold
+
+
+ Add Armor
+ Name: \u0020
+ Weight: \u0020
+ Size: \u0020
+ ACP: \u0020
+ ASF: \u0020
+ Special Properties:\u0020
+ Special Properties
+ AC: \u0020
+ Speed: \u0020
+ Max Dex: \u0020
+ New Armor
+
+ -20
+ -19
+ -18
+ -17
+ -16
+ -15
+ -14
+ -13
+ -12
+ -11
+ -10
+ -9
+ -8
+ -7
+ -6
+ -5
+ -4
+ -3
+ -2
+ -1
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+
+
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+
+
+ S
+ M
+ L
+
+
+ 0 ft.
+ 5 ft.
+ 10 ft.
+ 15 ft.
+ 20 ft.
+ 25 ft.
+ 30 ft.
+ 35 ft.
+ 40 ft.
+ 45 ft.
+ 50 ft.
+ 55 ft.
+ 60 ft.
+ 65 ft.
+ 70 ft.
+ 75 ft.
+ 80 ft.
+ 85 ft.
+ 90 ft.
+ 95 ft.
+ 100 ft.
+ 105 ft.
+ 110 ft.
+ 115 ft.
+ 120 ft.
+
+
+
+ 0%
+ 5%
+ 10%
+ 15%
+ 20%
+ 25%
+ 30%
+ 35%
+ 40%
+ 45%
+ 50%
+ 55%
+ 60%
+ 65%
+ 70%
+ 75%
+ 80%
+ 85%
+ 90%
+ 95%
+
+
+
+ Add Weapon
+ Name: \u0020
+ Weight: \u0020
+ Size: \u0020
+ Critical: \u0020
+ Range:
+ Special Properties:\u0020
+ Ammo: \u0020
+ Damage: \u0020
+ Attack:\u0020
+ Attack:\u0020
+ Type:\u0020
+ New Weapon\u0020
+ ""
+
+
+ -10
+ -9
+ -8
+ -7
+ -6
+ -5
+ -4
+ -3
+ -2
+ -1
+ +0
+ +1
+ +2
+ +3
+ +4
+ +5
+ +6
+ +7
+ +8
+ +9
+ +10
+ +11
+ +12
+ +13
+ +14
+ +15
+ +16
+ +17
+ +18
+ +19
+ +20
+ +21
+ +22
+ +23
+ +24
+ +25
+ +26
+ +27
+ +28
+ +29
+ +30
+ +31
+ +32
+ +33
+ +34
+ +35
+ +36
+ +37
+ +38
+ +39
+ +40
+
+
+
+ 0x
+ 1x
+ 2x
+ 3x
+ 4x
+
+
+
+ 10–20
+ 11–20
+ 12–20
+ 13–20
+ 14–20
+ 15–20
+ 16–20
+ 17–20
+ 18–20
+ 19–20
+ 20
+
+
+
+ S
+ P
+ B
+ P\/B
+ S\/B
+ S\/P
+ S\/P\/B
+
+
+
+ 0 ft\.
+ 5 ft\.
+ 10 ft\.
+ 15 ft\.
+ 20 ft\.
+ 25 ft\.
+ 30 ft\.
+ 35 ft\.
+ 40 ft\.
+ 45 ft\.
+ 50 ft\.
+ 55 ft\.
+ 60 ft\.
+ 65 ft\.
+ 70 ft\.
+ 75 ft\.
+ 80 ft\.
+ 85 ft\.
+ 90 ft\.
+ 95 ft\.
+ 100 ft\.
+
+
+
+
+ Add Feat or Special Ability
+ Description
+ Name
+
+
+ Name
+ Alignment
+ XP
+ Next Level XP
+ Class
+ Race
+ Deity
+ Level
+ Size
+ Gender
+ Height
+ Weight
+ Eyes
+ Hair
+ Languages
+ Description
+
+
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+
+
+ -10
+ -9
+ -8
+ -7
+ -6
+ -5
+ -4
+ -3
+ -2
+ -1
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+
+
+
+
+ Mod
+ Temp\nMod
+ Temp\nScore
+
+
+ Level
+ +
+ Name
+ Prepared
+ Description
+ Spell Name
+ New Spell
+ Delete
+ OK
+ Cancel
+
+
+
+ Reset
+ Add Encounter Member
+ Roll for Initiative!
+ New Character
+ Add a new character or NPC to this encounter?
+ Reset Encounter
+ Reset the encounter? Tap \"Use Default\" to completely reset to the current party as it is shown in the Party Manager.
+ Use Default
+
+
+ Roll
+
+ Fort Save
+ Reflex Save
+ Will Save
+ Bluff
+ Disguise
+ Perception
+ Sense Motive
+ Stealth
+
+
+
+ Parties
+ New Party
+ Delete Party
+ Party Name:
+ Party name
+ Character Name:
+ Character name
+ Value
+ New Party Member
+ Add a new member to this party?
+
+
+ Initiative
+ AC
+ Touch
+ Flat Footed
+ Spell Resistance
+ Damage Reduction
+ CMD
+ Fortitude Save
+ Reflex Save
+ Will Save
+ Bluff Skill Bonus
+ Disguise Skill Bonus
+ Perception Skill Bonus
+ Sense Motive Skill Bonus
+ Stealth Skill Bonus
+
+
+ Done
+ Delete Party Member
+ PM_INDEX
+ PARTY_ID
+
+
\ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..538f998
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTCharacterSheetActivity.java b/src/com/lateensoft/pathfinder/toolkit/PTCharacterSheetActivity.java
new file mode 100644
index 0000000..b358282
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTCharacterSheetActivity.java
@@ -0,0 +1,482 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import com.lateensoft.pathfinder.toolkit.character.PTCharacter;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterAbilityFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterCombatStatsFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterFeatsFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterFluffFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterInventoryFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterSkillsFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacterSpellBookFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTArmorFragment;
+import com.lateensoft.pathfinder.toolkit.character.PTSkillsAdapter;
+import com.lateensoft.pathfinder.toolkit.character.PTWeaponsFragment;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+
+//Currently an alternative to PTCharacterSheet, using the actionbar with tabs
+public class PTCharacterSheetActivity extends Activity implements
+ DialogInterface.OnClickListener {
+
+ private final int MENU_ITEM_CHARACTER_LIST = 0;
+ private final int MENU_ITEM_NEW_CHARACTER = 1;
+ private final int MENU_ITEM_DELETE_CHARACTER = 2;
+ private final int MENU_ITEM_AUTOFILL = 3;
+
+ private static final int STR_KEY = 0;
+ static final int DEX_KEY = 1;
+ static final int CON_KEY = 2;
+ static final int INT_KEY = 3;
+ static final int WIS_KEY = 4;
+ static final int CHA_KEY = 5;
+
+ static final int FORT_KEY = 0;
+ static final int REF_KEY = 1;
+ static final int WILL_KEY = 2;
+
+ static final int TAB_INDEX_FLUFF = 0;
+ static final int TAB_INDEX_ABILITIES = 2;
+
+ private final String TAG = "PTCharacterSheetActivity";
+
+ private ActionBar mActionBar;
+ public PTCharacter mCharacter;
+
+ private PTDatabaseManager mSQLManager;
+ private PTUserPrefsManager mUserPrefsManager;
+
+ private int mDialogMode;
+ private int mCharacterSelectedInDialog;
+
+ private boolean isPerformingOnCreate;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ isPerformingOnCreate = true;
+ // Notice that setContentView() is not used, because we use the root
+ // android.R.id.content as the container for each fragment
+ // setup action bar for tabs
+ mActionBar = getActionBar();
+ mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+ mActionBar.setDisplayHomeAsUpEnabled(true);
+
+ mSQLManager = new PTDatabaseManager(getApplicationContext());
+ mUserPrefsManager = new PTUserPrefsManager(this.getApplicationContext());
+
+ loadCurrentCharacter();
+ mCharacterSelectedInDialog = mCharacter.mID;
+
+ isPerformingOnCreate = false;
+ }
+
+ private void setUpTabs() {
+ // Fluff
+ Tab tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_fluff)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_fluff),
+ PTCharacterFluffFragment.class));
+ mActionBar.addTab(tab);
+
+ // Combat Stats
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_combat_stats)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_combat_stats),
+ PTCharacterCombatStatsFragment.class));
+ mActionBar.addTab(tab);
+
+ // Abilities
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_abilities)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_abilities),
+ PTCharacterAbilityFragment.class));
+ mActionBar.addTab(tab);
+
+ // Skills
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_skills)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_skills),
+ PTCharacterSkillsFragment.class));
+ mActionBar.addTab(tab);
+
+ // Inventory
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_inventory)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_inventory),
+ PTCharacterInventoryFragment.class));
+ mActionBar.addTab(tab);
+
+ // Armor
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_armor)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_armor),
+ PTArmorFragment.class));
+ mActionBar.addTab(tab);
+
+ // Weapons
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_weapons)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_weapons),
+ PTWeaponsFragment.class));
+ mActionBar.addTab(tab);
+
+ // Feats
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_feats)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_feats),
+ PTCharacterFeatsFragment.class));
+ mActionBar.addTab(tab);
+
+ // Spells
+ tab = mActionBar
+ .newTab()
+ .setText(R.string.tab_character_spells)
+ .setTabListener(
+ new TabListener(this,
+ getString(R.string.tab_character_spells),
+ PTCharacterSpellBookFragment.class));
+ mActionBar.addTab(tab);
+ }
+
+ /**
+ * Load the currently set character in shared prefs If there is no character
+ * set in user prefs, it automatically generates a new one.
+ */
+ public void loadCurrentCharacter() {
+ int currentCharacterID = mUserPrefsManager.getSelectedCharacter();
+
+ if (currentCharacterID == -1) { // There was no current character set in
+ // shared prefs
+ Log.v(TAG, "Default character add");
+ addNewCharacter();
+ } else {
+ Log.v(TAG, "Loading character");
+ mCharacter = mSQLManager.getCharacter(currentCharacterID);
+ forceFragmentSaveUpdate();
+
+ }
+ Log.v(TAG, "Loaded character: " + mCharacter.mID);
+ }
+
+ /**
+ * Generates a new character and sets it to the current character. Reloads
+ * the fragments.
+ */
+ public void addNewCharacter() {
+ mCharacter = mSQLManager.addNewCharacter("New Adventurer",
+ this.getApplicationContext());
+ mUserPrefsManager.setSelectedCharacter(mCharacter.mID);
+ forceFragmentSaveUpdate();
+ Log.v(TAG, "Added new character");
+ }
+
+ /**
+ * Deletes the current character and loads the first in the list, or creates
+ * a new blank one, if there was only one.
+ */
+ public void deleteCurrentCharacter() {
+ int currentCharacterIndex = 0;
+ int currentCharacterID = mCharacter.mID;
+ int characterIDs[] = mSQLManager.getCharacterIDs();
+
+ for (int i = 0; i < characterIDs.length; i++) {
+ if (currentCharacterID == characterIDs[i])
+ currentCharacterIndex = i;
+ }
+
+ if (characterIDs.length == 1) {
+ addNewCharacter();
+ } else if (currentCharacterIndex == 0) {
+ mUserPrefsManager.setSelectedCharacter(characterIDs[1]);
+ loadCurrentCharacter();
+ } else {
+ mUserPrefsManager.setSelectedCharacter(characterIDs[0]);
+ loadCurrentCharacter();
+ }
+
+ mSQLManager.deleteCharacter(currentCharacterID);
+ Log.v(TAG, "Deleted current character: " + currentCharacterID);
+ }
+
+ public void updateCharacterDatabase() {
+ mSQLManager.updateCharacter(mCharacter);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here
+
+ switch (item.getItemId()) {
+ case android.R.id.home: // Tapped the back button on the action bar,
+ // to
+ // return to main menu
+ finish();
+ break;
+ case MENU_ITEM_CHARACTER_LIST: // Tapped character list button
+ mDialogMode = MENU_ITEM_CHARACTER_LIST;
+ showCharacterDialog();
+ break;
+ case MENU_ITEM_NEW_CHARACTER:
+ // Add new character
+ mDialogMode = MENU_ITEM_NEW_CHARACTER;
+ showCharacterDialog();
+ break;
+ case MENU_ITEM_DELETE_CHARACTER:
+ // Delete character
+ mDialogMode = MENU_ITEM_DELETE_CHARACTER;
+ showCharacterDialog();
+ break;
+
+ case MENU_ITEM_AUTOFILL:
+ int selectedTab = mActionBar.getSelectedNavigationIndex();
+ //forceFragmentSaveUpdate();
+
+ /*if(selectedTab == 0) {
+ mActionBar.selectTab(mActionBar.getTabAt(TAB_INDEX_ABILITIES));
+ } else {
+ mActionBar.selectTab(mActionBar.getTabAt(TAB_INDEX_FLUFF));
+ }*/
+ mActionBar.selectTab(mActionBar.getTabAt(TAB_INDEX_FLUFF));
+ autoFill();
+ mActionBar.selectTab(mActionBar.getTabAt(selectedTab));
+ break;
+ }
+ }
+
+ return true;
+
+ }
+
+ private void autoFill() {
+ mCharacter.getCombatStatSet().setACDexMod(mCharacter.getAbilitySet()
+ .getAbilityScore(DEX_KEY).getModifier());
+ mCharacter.getCombatStatSet().setInitDexMod(mCharacter.getAbilitySet()
+ .getAbilityScore(DEX_KEY).getModifier());
+ mCharacter.getCombatStatSet().setCMDDexMod(mCharacter.getAbilitySet()
+ .getAbilityScore(DEX_KEY).getModifier());
+ mCharacter.getSaveSet().getSave(REF_KEY).setAbilityMod(mCharacter.getAbilitySet()
+ .getAbilityScore(DEX_KEY).getModifier());
+
+ mCharacter.getCombatStatSet().setStrengthMod(mCharacter.getAbilitySet()
+ .getAbilityScore(STR_KEY).getModifier());
+
+ mCharacter.getSaveSet().getSave(FORT_KEY).setAbilityMod(mCharacter.getAbilitySet()
+ .getAbilityScore(CON_KEY).getModifier());
+
+ mCharacter.getSaveSet().getSave(WILL_KEY).setAbilityMod(mCharacter.getAbilitySet()
+ .getAbilityScore(WIS_KEY).getModifier());
+
+ int key;
+
+ for(int i = 0; i < mCharacter.getSkillSet().getSkills().length; i++) {
+ key = mCharacter.getSkillSet().getSkill(i).getKeyAbilityKey();
+ mCharacter.getSkillSet().getSkill(i).setAbilityMod(
+ mCharacter.getAbilitySet().getAbilityScore(key).getModifier());
+ }
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Initialize the global menu items
+
+ MenuItem characterListItem = menu.add(Menu.NONE,
+ MENU_ITEM_CHARACTER_LIST, Menu.NONE,
+ R.string.menu_item_character_list);
+ characterListItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ MenuItem newCharacterItem = menu.add(Menu.NONE,
+ MENU_ITEM_NEW_CHARACTER, Menu.NONE,
+ R.string.menu_item_new_character);
+ newCharacterItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+
+ MenuItem deleteCharacterItem = menu.add(Menu.NONE,
+ MENU_ITEM_DELETE_CHARACTER, Menu.NONE,
+ R.string.menu_item_delete_character);
+ deleteCharacterItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+
+
+ MenuItem autoFillItem = menu.add(Menu.NONE,
+ MENU_ITEM_AUTOFILL, Menu.NONE,
+ R.string.auto_fill);
+ autoFillItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+
+
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+
+ return true;
+ }
+
+ private void showCharacterDialog() {
+ mCharacterSelectedInDialog = mCharacter.mID; // actual current character
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+ switch (mDialogMode) {
+ case MENU_ITEM_CHARACTER_LIST:
+ builder.setTitle(getString(R.string.select_character_dialog_header));
+
+ String[] characterList = mSQLManager.getCharacterNames();
+ int characterIDs[] = mSQLManager.getCharacterIDs();
+ int currentCharacterIndex = 0;
+
+ for (int i = 0; i < characterIDs.length; i++) {
+ if (mCharacterSelectedInDialog == characterIDs[i])
+ currentCharacterIndex = i;
+ }
+
+ builder.setSingleChoiceItems(characterList, currentCharacterIndex,
+ this).setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ case MENU_ITEM_NEW_CHARACTER:
+ builder.setTitle(getString(R.string.menu_item_new_character));
+ builder.setMessage("Create new character?")
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ case MENU_ITEM_DELETE_CHARACTER:
+ builder.setTitle(getString(R.string.menu_item_delete_character));
+ builder.setMessage(
+ getString(R.string.delete_character_dialog_message_1)
+ + mCharacter.getName()
+ + getString(R.string.delete_character_dialog_message_2))
+ .setPositiveButton(R.string.delete_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+
+ }
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ // Click method for the character selection dialog
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ performPositiveDialogAction();
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ default:
+ // Set the currently selected character in the dialog
+ mCharacterSelectedInDialog = mSQLManager.getCharacterIDs()[selection];
+ Log.v(TAG, "Selected character " + mCharacterSelectedInDialog);
+ break;
+
+ }
+ }
+
+ /**
+ * Called when dialog positive button is tapped
+ */
+ public void performPositiveDialogAction() {
+ switch (mDialogMode) {
+ case MENU_ITEM_CHARACTER_LIST:
+ // Check if "currently selected" character is the same as saved one
+ if (mCharacterSelectedInDialog != mCharacter.mID) {
+ forceFragmentSaveUpdate();
+ updateCharacterDatabase(); // Ensures any data changed on the
+ // character in the current fragment
+ // is saved
+ mUserPrefsManager
+ .setSelectedCharacter(mCharacterSelectedInDialog);
+ loadCurrentCharacter();
+ }
+ break;
+
+ case MENU_ITEM_NEW_CHARACTER:
+ forceFragmentSaveUpdate();
+ updateCharacterDatabase();
+ addNewCharacter();
+ break;
+
+ case MENU_ITEM_DELETE_CHARACTER:
+ forceFragmentSaveUpdate();
+ deleteCurrentCharacter();
+ break;
+
+ }
+
+ }
+
+ /**
+ * Depending on the use, this forces the current tab to save its values to
+ * mCharacter, and updates them. Ends with current tab set to Fluff.
+ */
+ public void forceFragmentSaveUpdate() {
+ if (!isPerformingOnCreate) {
+ // Forces resume of first tab, even if on it already. Should be the least resource consuming tab.
+ mActionBar.selectTab(mActionBar.getTabAt(7));
+ mActionBar.selectTab(mActionBar.getTabAt(0));
+ }
+ }
+
+ public PTCharacter getCurrentCharacter() {
+ return mCharacter;
+ }
+
+ public void setCurrentCharacter(PTCharacter character) {
+ if (character != null)
+ mCharacter = character;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setUpTabs();
+ PTUserPrefsManager userPrefs = new PTUserPrefsManager(this);
+ mActionBar.selectTab(mActionBar.getTabAt(userPrefs.getLastCharacterTab()));
+ isPerformingOnCreate = false;
+ }
+
+ @Override
+ protected void onPause() {
+ PTUserPrefsManager userPrefs = new PTUserPrefsManager(this);
+ userPrefs.setLastCharacterTab(mActionBar.getSelectedNavigationIndex());
+ mActionBar.removeAllTabs(); // Used to prevent fragments from detaching
+ // when app gets killed
+ super.onPause();
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTDiceRollerActivity.java b/src/com/lateensoft/pathfinder/toolkit/PTDiceRollerActivity.java
new file mode 100644
index 0000000..a55ce3f
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTDiceRollerActivity.java
@@ -0,0 +1,285 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import com.lateensoft.pathfinder.toolkit.functional.PTDiceSet;
+
+import android.os.Bundle;
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Intent;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.ToggleButton;
+
+public class PTDiceRollerActivity extends Activity implements OnClickListener,
+ RadioGroup.OnCheckedChangeListener {
+
+ int mCurrentDie = 4;
+ int mDieQuantity = 1;
+ int mRollSum = 0;
+ int mRollMode;
+ PTDiceSet mDiceSet;
+ RadioGroup mRollTypeRadioGroup, mDieTypeRadioGroup;
+ Button mRollButton, mResetButton, mDieQuantityUpButton,
+ mDieQuantityDownButton;
+ TextView mDieQuantityLabel, mRollResultLabel, mRollSumLabel;
+ ListView mRollResultList;
+
+ final String TAG = "PTDiceRollerActivity";
+
+ final int ROLLMODE_SINGLE = 0;
+ final int ROLLMODE_MULTI = 1;
+ final int ROLLMODE_SUM = 2;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_ptdice_roller);
+
+ mDiceSet = new PTDiceSet();
+
+ viewSetup();
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ mRollMode = ROLLMODE_SINGLE;
+ setRollTypeView(R.id.radiotoggleSingleRoll);
+ }
+
+ // Responds to roll type radio toggle buttons
+ public void rollTypeClicked(View view) {
+ ToggleButton toggleButton = (ToggleButton) view;
+
+ if (toggleButton.isChecked()) {
+ mRollTypeRadioGroup.check(view.getId());
+ setRollTypeView(view.getId());
+ } else
+ toggleButton.setChecked(true);
+ }
+
+ // Takes the id of a roll type radio button (usually the one just pressed)
+ // and sets the rest of the layout accordingly
+ public void setRollTypeView(int rollTypeButtonId) {
+ switch (rollTypeButtonId) {
+ case R.id.radiotoggleSingleRoll:
+ mRollMode = ROLLMODE_SINGLE;
+ mResetButton.setEnabled(false);
+ mDieQuantityUpButton.setEnabled(false);
+ mDieQuantityDownButton.setEnabled(false);
+ mDieQuantityLabel.setEnabled(false);
+ mRollSumLabel.setVisibility(View.INVISIBLE);
+ mRollResultList.setVisibility(View.INVISIBLE);
+ break;
+ case R.id.radiotoggleMultiRoll:
+ mRollMode = ROLLMODE_MULTI;
+ mResetButton.setEnabled(true);
+ mDieQuantityUpButton.setEnabled(true);
+ mDieQuantityDownButton.setEnabled(true);
+ mDieQuantityLabel.setEnabled(true);
+ mRollSumLabel.setVisibility(View.INVISIBLE);
+ mRollResultList.setVisibility(View.VISIBLE);
+ break;
+ case R.id.radiotoggleSumRoll:
+ mRollMode = ROLLMODE_SUM;
+ mResetButton.setEnabled(true);
+ mDieQuantityUpButton.setEnabled(true);
+ mDieQuantityDownButton.setEnabled(true);
+ mDieQuantityLabel.setEnabled(true);
+ mRollSumLabel.setVisibility(View.VISIBLE);
+ mRollResultList.setVisibility(View.VISIBLE);
+ break;
+ }
+ }
+
+ // Responds to die type radio toggle buttons
+ public void dieTypeClicked(View view) {
+ ToggleButton toggleButton = (ToggleButton) view;
+
+ if (toggleButton.isChecked()) {
+ mDieTypeRadioGroup.check(view.getId());
+ switch (view.getId()) {
+ case R.id.radiotoggleD4Die:
+ mCurrentDie = 4;
+ break;
+ case R.id.radiotoggleD6Die:
+ mCurrentDie = 6;
+ break;
+ case R.id.radiotoggleD8Die:
+ mCurrentDie = 8;
+ break;
+ case R.id.radiotoggleD10Die:
+ mCurrentDie = 10;
+ break;
+ case R.id.radiotoggleD12Die:
+ mCurrentDie = 12;
+ break;
+ case R.id.radiotoggleD20Die:
+ mCurrentDie = 20;
+ break;
+ case R.id.radiotoggleD100Die:
+ mCurrentDie = 100;
+ break;
+ }
+ } else
+ toggleButton.setChecked(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here
+
+ switch (item.getItemId()) {
+ case android.R.id.home: // Tapped the back button on the action bar,
+ // to
+ // return to main menu
+ finish();
+ break;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+ return true;
+ }
+
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ ToggleButton toggleButton;
+ for (int j = 0; j < group.getChildCount(); j++) {
+ toggleButton = (ToggleButton) group.getChildAt(j);
+ toggleButton.setChecked(toggleButton.getId() == checkedId);
+ }
+ }
+
+ public void resetRolls() {
+ mRollSum = 0;
+ mRollSumLabel.setText(getString(R.string.roller_sum_label) + " "
+ + mRollSum);
+ mDieQuantity = 1;
+ mDieQuantityLabel.setText(Integer.toString(mDieQuantity));
+ refreshRollsListView(null);
+ }
+
+ // Rolls the dice according to the current settings and updates the screen
+ public void rollDice() {
+ int rollResult;
+ int[] rolls = null;
+
+ switch (mRollMode) {
+ case ROLLMODE_SINGLE:
+ mRollResultLabel.setText(Integer.toString(mDiceSet
+ .singleRoll(mCurrentDie)));
+ break;
+ case ROLLMODE_MULTI:
+ rolls = mDiceSet.multiRollWithResults(mDieQuantity, mCurrentDie);
+ rollResult = getMultiRollSum(rolls);
+ mRollResultLabel.setText(Integer.toString(rollResult));
+ refreshRollsListView(rolls);
+ break;
+ case ROLLMODE_SUM:
+ rolls = mDiceSet.multiRollWithResults(mDieQuantity, mCurrentDie);
+ rollResult = getMultiRollSum(rolls);
+ mRollSum += rollResult;
+ if (mRollSum > getResources().getInteger(R.integer.max_roll_sum))
+ mRollSum = getResources().getInteger(R.integer.max_roll_sum);
+ mRollSumLabel.setText(getString(R.string.roller_sum_label) + " "
+ + mRollSum);
+ mRollResultLabel.setText(Integer.toString(rollResult));
+ refreshRollsListView(rolls);
+ break;
+ }
+ }
+
+ public void onClick(View arg0) {
+
+ switch (arg0.getId()) {
+ case R.id.buttonRoll:
+ rollDice();
+ break;
+ case R.id.buttonReset:
+ resetRolls();
+ break;
+ case R.id.buttonPlusDiceNumber:
+ if (mDieQuantity < getResources().getInteger(
+ R.integer.max_dice_per_roll)) {
+ mDieQuantity++;
+ mDieQuantityLabel.setText(Integer.toString(mDieQuantity));
+ }
+ break;
+ case R.id.buttonMinusDiceNumber:
+ if (mDieQuantity > 1) {
+ mDieQuantity--;
+ mDieQuantityLabel.setText(Integer.toString(mDieQuantity));
+ }
+ break;
+ }
+
+ }
+
+ private int getMultiRollSum(int[] rollResults){
+ int rollSum = 0;
+ if(rollResults != null){
+ for(int i = 0; i < rollResults.length; i++){
+ rollSum += rollResults[i];
+ }
+ }
+ return rollSum;
+ }
+
+ private void refreshRollsListView(int[] rollResults){
+ if(rollResults != null){
+ String[] rollResultStrings = new String[rollResults.length];
+ for(int i = 0; i < rollResults.length; i++)
+ rollResultStrings[i] = Integer.toString(rollResults[i]);
+
+ ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, rollResultStrings);
+ mRollResultList.setAdapter(adapter);
+ }
+ else{
+ String[] emptyArray = new String[0];
+ ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, emptyArray);
+ mRollResultList.setAdapter(adapter);
+ }
+ }
+
+ void viewSetup() {
+ mRollTypeRadioGroup = (RadioGroup) findViewById(R.id.toggleGroupRollType);
+ mRollTypeRadioGroup.setOnCheckedChangeListener(this);
+
+ mDieTypeRadioGroup = (RadioGroup) findViewById(R.id.toggleGroupDieType);
+ mDieTypeRadioGroup.setOnCheckedChangeListener(this);
+
+ mDieQuantityUpButton = (Button) findViewById(R.id.buttonPlusDiceNumber);
+ mDieQuantityUpButton.setOnClickListener(this);
+ mDieQuantityDownButton = (Button) findViewById(R.id.buttonMinusDiceNumber);
+ mDieQuantityDownButton.setOnClickListener(this);
+
+ mRollButton = (Button) findViewById(R.id.buttonRoll);
+ mRollButton.setOnClickListener(this);
+ mResetButton = (Button) findViewById(R.id.buttonReset);
+ mResetButton.setOnClickListener(this);
+
+ mDieQuantityLabel = (TextView) findViewById(R.id.textViewDiceNumberPicker);
+ mDieQuantityLabel.setText(Integer.toString(mDieQuantity));
+
+ mRollResultLabel = (TextView) findViewById(R.id.textViewRollResult);
+
+ mRollSumLabel = (TextView) findViewById(R.id.textViewRollSum);
+
+ mRollResultList = (ListView) findViewById(R.id.rollResultListView);
+
+ resetRolls();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTInitiativeTrackerActivity.java b/src/com/lateensoft/pathfinder/toolkit/PTInitiativeTrackerActivity.java
new file mode 100644
index 0000000..f01ae39
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTInitiativeTrackerActivity.java
@@ -0,0 +1,260 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+import com.lateensoft.pathfinder.toolkit.functional.PTDiceSet;
+import com.lateensoft.pathfinder.toolkit.party.PTEncounterMemberEditorActivity;
+import com.lateensoft.pathfinder.toolkit.party.PTParty;
+import com.lateensoft.pathfinder.toolkit.party.PTPartyMember;
+import com.lateensoft.pathfinder.toolkit.party.PTPartyRollAdapter;
+
+import android.os.Bundle;
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.ListView;
+
+public class PTInitiativeTrackerActivity extends Activity implements OnClickListener, OnItemClickListener, android.content.DialogInterface.OnClickListener {
+
+ private final int MENU_ITEM_RESET = 0;
+ private final int MENU_ITEM_ADD_MEMBER = 1;
+ private final String TAG = "PTInitiativeTrackerActivity";
+
+ public PTParty mParty;
+
+ private PTDatabaseManager mSQLManager;
+ private PTUserPrefsManager mUserPrefsManager;
+
+ private int mDialogMode;
+ private boolean mHasRolled;
+
+ private Button mRollInitiativeButton;
+ private ListView mPartyMemberList;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_ptinitiative_tracker);
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ mSQLManager = new PTDatabaseManager(getApplicationContext());
+ mUserPrefsManager = new PTUserPrefsManager(getApplicationContext());
+
+ mRollInitiativeButton = (Button) findViewById(R.id.buttonRollInitiative);
+ mRollInitiativeButton.setOnClickListener(this);
+
+ mPartyMemberList = (ListView) findViewById(R.id.listViewEncounterMembers);
+ mPartyMemberList.setOnItemClickListener(this);
+
+ mHasRolled = false;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here
+
+ switch (item.getItemId()) {
+ case android.R.id.home: // Tapped the back button on the action bar,
+ // to
+ // return to main menu
+ finish();
+ break;
+ case MENU_ITEM_RESET: // Tapped party list button
+ mDialogMode = MENU_ITEM_RESET;
+ showPartyDialog();
+ break;
+ case MENU_ITEM_ADD_MEMBER:
+ mDialogMode = MENU_ITEM_ADD_MEMBER;
+ showPartyDialog();
+ break;
+ }
+ }
+
+ return true;
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuItem partyListItem = menu.add(Menu.NONE,
+ MENU_ITEM_RESET, Menu.NONE,
+ R.string.menu_item_reset_encounter);
+ partyListItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ MenuItem addMemberListItem = menu.add(Menu.NONE,
+ MENU_ITEM_ADD_MEMBER, Menu.NONE,
+ R.string.menu_item_add_encounter_member);
+ addMemberListItem.setIcon(android.R.drawable.ic_menu_add);
+ addMemberListItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ // Initialize the global menu items
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+ return true;
+ }
+
+ private void showPartyDialog() {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+ switch(mDialogMode){
+ case MENU_ITEM_RESET:
+ builder.setTitle(getString(R.string.reset_encounter_dialog_title));
+ builder.setMessage(getString(R.string.reset_encounter_dialog_text))
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this)
+ .setNeutralButton(getString(R.string.use_defualt_party_button), this);
+ break;
+
+
+ case MENU_ITEM_ADD_MEMBER:
+ builder.setTitle(getString(R.string.new_encounter_member_dialog_title));
+ builder.setMessage(getString(R.string.new_encounter_member_dialog_text))
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ }
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ // Click method for the party selection dialog
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ performPositiveDialogAction();
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ case DialogInterface.BUTTON_NEUTRAL:
+ loadDefaultParty();
+ }
+ }
+
+ /**
+ * Called when dialog positive button is tapped
+ */
+ public void performPositiveDialogAction(){
+ switch (mDialogMode){
+ case MENU_ITEM_RESET:
+ resetPartyRolls();
+ break;
+
+ case MENU_ITEM_ADD_MEMBER:
+ launchPartyMemberEditor(mParty.addPartyMember(new PTPartyMember("NPC")));
+ refreshPartyView();
+ break;
+
+ }
+
+ }
+
+
+ /**
+ * Load the current encounter party in shared prefs
+ * If there is no party set in user prefs, it pulls the default currently set in party manager
+ * If there is not current party, an empty party is set
+ */
+ public void loadEncounterParty(){
+
+ PTParty currentEncounterParty = mUserPrefsManager.getEncounterParty();
+ //If there is no saved encounter party, get from party manager
+ //Also, if the encounter party was saved, but previously was empty, get from party manager.
+ if(currentEncounterParty == null || currentEncounterParty.size() == 0){
+ loadDefaultParty();
+ }
+ else{
+ mParty = currentEncounterParty;
+ mHasRolled = false;
+ for(int i = 0; i < mParty.size(); i++)
+ if(mParty.getPartyMember(i).getRolledValue() != 0)
+ mHasRolled = true;
+
+ refreshPartyView();
+ }
+ }
+
+ public void loadDefaultParty(){
+ int currentPartyID = mUserPrefsManager.getSelectedParty();
+ if(currentPartyID >= 0)
+ mParty = mSQLManager.getParty(currentPartyID);
+ else
+ mParty = new PTParty("Empty Party");
+ mUserPrefsManager.setEncounterParty(mParty);
+ mHasRolled = false;
+ refreshPartyView();
+ }
+
+ public void resetPartyRolls(){
+ for(int i = 0; i < mParty.size(); i++){
+ mParty.getPartyMember(i).setRolledValue(0);
+ }
+ mUserPrefsManager.setEncounterParty(mParty);
+ mHasRolled = false;
+ refreshPartyView();
+ }
+
+ private void refreshPartyView(){
+ String[] memberNames = mParty.getNamesByRollValue();
+ int[] memberRollValues = mParty.getRollValuesByRollValue();
+ PTPartyRollAdapter adapter = new PTPartyRollAdapter(this, R.layout.party_roll_row, memberNames, memberRollValues, null);
+ mPartyMemberList.setAdapter(adapter);
+ mRollInitiativeButton.setEnabled(!mHasRolled);
+ }
+
+ /**
+ * launches the party member editor
+ * @param index (the actual index, not the roll value index)
+ */
+ public void launchPartyMemberEditor(int index){
+ Intent intent = new Intent(this, PTEncounterMemberEditorActivity.class);
+ //putting values to intent
+ intent.putExtra(getString(R.string.party_member_index_key), index);
+ startActivity(intent);
+ }
+
+ //When roll initiative button is clicked
+ public void onClick(View view) {
+ PTDiceSet diceSet = new PTDiceSet();
+ int initiativeMod;
+
+ for(int i = 0; i < mParty.size(); i++){
+ initiativeMod = mParty.getPartyMember(i).getInitiative();
+ mParty.getPartyMember(i).setRolledValue(diceSet.singleRoll(20)+initiativeMod);
+ }
+ mUserPrefsManager.setEncounterParty(mParty);
+ mHasRolled = true;
+ loadEncounterParty();
+ }
+
+ //Party member in list was clicked
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ launchPartyMemberEditor(mParty.getPartyMemberIndexByRollValueIndex(position));
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ loadEncounterParty();
+ }
+
+ @Override
+ protected void onPause() {
+ mUserPrefsManager.setEncounterParty(mParty);
+ super.onPause();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTMainMenu.java b/src/com/lateensoft/pathfinder/toolkit/PTMainMenu.java
new file mode 100644
index 0000000..be2f96c
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTMainMenu.java
@@ -0,0 +1,146 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.app.AlertDialog;
+import android.app.ListActivity;
+import android.content.ActivityNotFoundException;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+import android.widget.ListView;
+
+public class PTMainMenu extends ListActivity implements OnClickListener {
+
+ private final String TAG = "PTMainMenu";
+ String mListLabels[];
+ private PTUserPrefsManager mUserPrefsManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mUserPrefsManager = new PTUserPrefsManager(this);
+ PTDatabaseManager SQLManager = new PTDatabaseManager(this.getApplicationContext());
+
+ //Needs to update the database after upgrading
+ if(mUserPrefsManager.checkLastUsedVersion(this)){
+ SQLManager.performUpdates(this);
+ mUserPrefsManager.setLastUsedVersion(this);
+ }
+
+ mListLabels = getResources().getStringArray(R.array.main_menu_array);
+
+ setContentView(R.layout.activity_main_menu);
+
+ setListAdapter(new PTMainMenuAdapter(this,
+ R.layout.main_menu_row, mListLabels));
+
+ showRateDialogIfRequired();
+ }
+
+ private void showRateDialogIfRequired(){
+ if(mUserPrefsManager.checkLastRateTime() && mUserPrefsManager.checkLastRatedVersion(this)){
+ showRateAppPromptDialog();
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+
+ switch (position) {
+ case 0:
+ startActivity(new Intent(this, PTDiceRollerActivity.class));
+ break;
+
+ case 1:
+ startActivity(new Intent(this, PTCharacterSheetActivity.class));
+ break;
+ case 2:
+ startActivity(new Intent(this, PTInitiativeTrackerActivity.class));
+ break;
+ case 3:
+ startActivity(new Intent(this, PTPartySkillCheckerActivity.class));
+ break;
+ case 4:
+ startActivity(new Intent(this, PTPartyManagerActivity.class));
+ break;
+ case 5:
+ startActivity(new Intent(this, PTPointbuyCalculator.class));
+ break;
+ }
+ }
+
+ public void showRateAppPromptDialog(){
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ //Set up dialog layout
+
+ ImageView dialogMemeImage = new ImageView(this);
+ dialogMemeImage.setImageResource(R.drawable.rate_meme);
+ dialogMemeImage.setScaleType(ScaleType.FIT_CENTER);
+
+ builder.setTitle(getString(R.string.rate_dialog_header));
+
+ builder.setView(dialogMemeImage)
+ .setPositiveButton(getString(R.string.rate_dialog_positive_button), this)
+ .setNegativeButton(getString(R.string.rate_dialog_negative_button), this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ //Initialize the global menu items
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+
+ //Add aditional menu items
+ return true;
+ }
+
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if(PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here or leave blank
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+
+ //For dialog
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch(selection){
+ case DialogInterface.BUTTON_POSITIVE:
+ mUserPrefsManager.setLastRatedVersion(this);
+ mUserPrefsManager.setRatePromptTime();
+ Log.v(TAG, "Attempting to open market page");
+ String appPackageName = this.getPackageName();
+ try {
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+appPackageName)));
+ } catch (ActivityNotFoundException e) {
+ Log.v(TAG, "Failed to open market. Attempting in browser.");
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id="+appPackageName)));
+ }
+ break;
+ default:
+ Log.v(TAG, "Delaying rate dialog.");
+ mUserPrefsManager.setRatePromptTime();
+ }
+
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTMainMenuAdapter.java b/src/com/lateensoft/pathfinder/toolkit/PTMainMenuAdapter.java
new file mode 100644
index 0000000..590dc68
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTMainMenuAdapter.java
@@ -0,0 +1,59 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class PTMainMenuAdapter extends ArrayAdapter{
+ Context mContext;
+ int mLayoutResourceId;
+ final int[] mImageIds = {R.drawable.dice_roller_icon, R.drawable.character_sheet_icon, R.drawable.initiative_icon,
+ R.drawable.skill_checker_icon, R.drawable.party_icon, R.drawable.stat_calc_icon};
+ String[] mMenuItemNames = null;
+ String TAG = "PTMainMenuAdapter";
+
+ public PTMainMenuAdapter(Context context, int layoutResourceId, String[] menuItems) {
+ super(context, layoutResourceId, menuItems);
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mMenuItemNames = menuItems;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ MenuItemHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new MenuItemHolder();
+
+ holder.name = (TextView)row.findViewById(R.id.textViewMainLabel);
+ holder.icon = (ImageView)row.findViewById(R.id.imageMainRow);
+
+ row.setTag(holder);
+ }
+ else {
+ holder = (MenuItemHolder)row.getTag();
+ }
+
+ holder.name.setText(mMenuItemNames[position]);
+ holder.icon.setImageResource(mImageIds[position]);
+
+
+ return row;
+ }
+
+ static class MenuItemHolder {
+ TextView name;
+ ImageView icon;
+ }
+
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTPartyManagerActivity.java b/src/com/lateensoft/pathfinder/toolkit/PTPartyManagerActivity.java
new file mode 100644
index 0000000..a71edd5
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTPartyManagerActivity.java
@@ -0,0 +1,331 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+import com.lateensoft.pathfinder.toolkit.party.PTParty;
+import com.lateensoft.pathfinder.toolkit.party.PTPartyMember;
+import com.lateensoft.pathfinder.toolkit.party.PTPartyMemberEditorActivity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ListView;
+
+public class PTPartyManagerActivity extends Activity implements OnClickListener, OnItemClickListener{
+
+ private final int MENU_ITEM_PARTY_LIST = 0;
+ private final int MENU_ITEM_ADD_MEMBER = 1;
+ private final int MENU_ITEM_NEW_PARTY = 2;
+ private final int MENU_ITEM_DELETE_PARTY = 3;
+ private final int DIALOG_MODE_ADD_MEMBER = 4;
+ private final String TAG = "PTPartyManagerActivity";
+
+ public PTParty mParty;
+
+ private PTDatabaseManager mSQLManager;
+ private PTUserPrefsManager mUserPrefsManager;
+
+ private int mDialogMode;
+ private int mPartySelectedInDialog;
+
+ private EditText mPartyNameEditText;
+ private ListView mPartyMemberList;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ setContentView(R.layout.activity_party_manager);
+ mSQLManager = new PTDatabaseManager(getApplicationContext());
+ mUserPrefsManager = new PTUserPrefsManager(getApplicationContext());
+
+ mPartyNameEditText = (EditText) findViewById(R.id.editTextPartyName);
+
+ mPartyMemberList = (ListView) findViewById(R.id.listViewPartyMembers);
+ mPartyMemberList.setOnItemClickListener(this);
+ }
+
+
+ /**
+ * Load the currently set party in shared prefs
+ * If there is no party set in user prefs, it automatically generates a new one.
+ */
+ public void loadCurrentParty(){
+ int currentPartyID = mUserPrefsManager.getSelectedParty();
+
+ if( currentPartyID == -1 ){ //There was no current party set in shared prefs
+ addNewParty();
+ }
+ else{
+ mParty = mSQLManager.getParty(currentPartyID);
+ refreshPartyView();
+
+ }
+ }
+
+ /**
+ * Generates a new party and sets it to the current party.
+ */
+ public void addNewParty(){
+ mParty = mSQLManager.addNewParty("New Party");
+ mUserPrefsManager.setSelectedParty(mParty.mID);
+ refreshPartyView();
+ }
+
+ /**
+ * Deletes the current party and loads the first in the list, or creates a new blank one, if there was only one.
+ */
+ public void deleteCurrentParty(){
+ int currentPartyIndex = 0;
+ int currentPartyID = mParty.mID;
+ int partyIDs[] = mSQLManager.getPartyIDs();
+
+ for(int i = 0; i < partyIDs.length; i++){
+ if(currentPartyID == partyIDs[i])
+ currentPartyIndex = i;
+ }
+
+ if(partyIDs.length == 1){
+ addNewParty();
+ }
+ else if(currentPartyIndex == 0){
+ mUserPrefsManager.setSelectedParty(partyIDs[1]);
+ loadCurrentParty();
+ }
+ else{
+ mUserPrefsManager.setSelectedParty(partyIDs[0]);
+ loadCurrentParty();
+ }
+
+ mSQLManager.deleteParty(currentPartyID);
+ }
+
+ public void updatePartyDatabase(){
+ mParty.setName(mPartyNameEditText.getText().toString());
+ mSQLManager.updateParty(mParty);
+ }
+
+ private void refreshPartyView(){
+ mPartyNameEditText.setText(mParty.getName());
+ String[] memberNames = mParty.getPartyMemberNames();
+ ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, memberNames);
+ mPartyMemberList.setAdapter(adapter);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here
+
+ updatePartyDatabase();
+
+ switch (item.getItemId()) {
+ case android.R.id.home: // Tapped the back button on the action bar,
+ // to
+ // return to main menu
+ finish();
+ break;
+ case MENU_ITEM_PARTY_LIST: // Tapped party list button
+ mDialogMode = MENU_ITEM_PARTY_LIST;
+ showPartyDialog();
+ break;
+ case MENU_ITEM_ADD_MEMBER:
+ mDialogMode = DIALOG_MODE_ADD_MEMBER;
+ showPartyDialog();
+ break;
+ case MENU_ITEM_NEW_PARTY:
+ //Add new party
+ mDialogMode = MENU_ITEM_NEW_PARTY;
+ showPartyDialog();
+ break;
+ case MENU_ITEM_DELETE_PARTY:
+ //Delete party
+ mDialogMode = MENU_ITEM_DELETE_PARTY;
+ showPartyDialog();
+ break;
+ }
+ }
+
+ return true;
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+
+ MenuItem partyListItem = menu.add(Menu.NONE,
+ MENU_ITEM_PARTY_LIST, Menu.NONE,
+ R.string.menu_item_party_list);
+ partyListItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ MenuItem addMemberListItem = menu.add(Menu.NONE,
+ MENU_ITEM_ADD_MEMBER, Menu.NONE,
+ R.string.menu_item_party_list);
+ addMemberListItem.setIcon(android.R.drawable.ic_menu_add);
+ addMemberListItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ MenuItem newPartyItem = menu.add(Menu.NONE,
+ MENU_ITEM_NEW_PARTY, Menu.NONE,
+ R.string.menu_item_new_party);
+ newPartyItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+
+ MenuItem deletePartyItem = menu.add(Menu.NONE,
+ MENU_ITEM_DELETE_PARTY, Menu.NONE,
+ R.string.menu_item_delete_party);
+ deletePartyItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+
+ // Initialize the global menu items
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+
+ return true;
+ }
+
+
+ private void showPartyDialog() {
+ mPartySelectedInDialog = mParty.mID; // actual current party
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+ switch(mDialogMode){
+ case MENU_ITEM_PARTY_LIST:
+ builder.setTitle("Select Party");
+
+ String[] partyList = mSQLManager.getPartyNames();
+ int partyIDs[] = mSQLManager.getPartyIDs();
+ int currentPartyIndex = 0;
+
+ for(int i = 0; i < partyIDs.length; i++){
+ if(mPartySelectedInDialog == partyIDs[i])
+ currentPartyIndex = i;
+ }
+
+ builder.setSingleChoiceItems(partyList, currentPartyIndex, this)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ case MENU_ITEM_NEW_PARTY:
+ builder.setTitle(getString(R.string.menu_item_new_party));
+ builder.setMessage("Create new party?")
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ case MENU_ITEM_DELETE_PARTY:
+ builder.setTitle(getString(R.string.menu_item_delete_party));
+ builder.setMessage(getString(R.string.delete_character_dialog_message_1)+mParty.getName()+
+ getString(R.string.delete_character_dialog_message_2))
+ .setPositiveButton(R.string.delete_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ case DIALOG_MODE_ADD_MEMBER:
+ builder.setTitle(getString(R.string.new_party_member_dialog_title));
+ builder.setMessage(getString(R.string.new_party_member_dialog_text))
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+ break;
+
+ }
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ // Click method for the party selection dialog
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ performPositiveDialogAction();
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ default:
+ // Set the currently selected party in the dialog
+ mPartySelectedInDialog = mSQLManager.getPartyIDs()[selection];
+ break;
+
+ }
+ }
+
+ /**
+ * Called when dialog positive button is tapped
+ */
+ public void performPositiveDialogAction(){
+ switch (mDialogMode){
+ case MENU_ITEM_PARTY_LIST:
+ // Check if "currently selected" party is the same as saved one
+ if(mPartySelectedInDialog != mParty.mID){
+ updatePartyDatabase(); //Ensures any data changed on the party in the current fragment is saved
+ mUserPrefsManager.setSelectedParty(mPartySelectedInDialog);
+ loadCurrentParty();
+ }
+ break;
+
+ case MENU_ITEM_NEW_PARTY:
+ updatePartyDatabase();
+ addNewParty();
+ break;
+
+ case MENU_ITEM_DELETE_PARTY:
+ deleteCurrentParty();
+ break;
+
+ case DIALOG_MODE_ADD_MEMBER:
+ launchPartyMemberEditor(mParty.addPartyMember(new PTPartyMember("New Adventurer")));
+ break;
+
+ }
+
+ }
+
+ public PTParty getCurrentParty(){
+ return mParty;
+ }
+
+ public void setCurrentParty(PTParty party){
+ if(party != null)
+ mParty = party;
+ }
+
+
+ //Party member in list was clicked
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ launchPartyMemberEditor(position);
+
+ }
+
+ public void launchPartyMemberEditor(int partyMemberIndex){
+ Intent intent = new Intent(this, PTPartyMemberEditorActivity.class);
+ //putting values to intent
+ intent.putExtra(getString(R.string.party_member_index_key), partyMemberIndex);
+ intent.putExtra(getString(R.string.party_id_key), mParty.mID);
+ startActivity(intent);
+ }
+
+ @Override
+ protected void onPause() {
+ updatePartyDatabase();
+ super.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ loadCurrentParty();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTPartySkillCheckerActivity.java b/src/com/lateensoft/pathfinder/toolkit/PTPartySkillCheckerActivity.java
new file mode 100644
index 0000000..ff26c67
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTPartySkillCheckerActivity.java
@@ -0,0 +1,225 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+import com.lateensoft.pathfinder.toolkit.functional.PTDiceSet;
+import com.lateensoft.pathfinder.toolkit.party.PTParty;
+import com.lateensoft.pathfinder.toolkit.party.PTPartyRollAdapter;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+
+public class PTPartySkillCheckerActivity extends Activity implements OnClickListener, OnItemSelectedListener{
+
+ private final String TAG = "PTPartySkillCheckerActivity";
+
+ public PTParty mParty;
+
+ private PTDatabaseManager mSQLManager;
+ private PTUserPrefsManager mUserPrefsManager;
+
+ private Button mRollButton;
+ private Spinner mSkillSpinner;
+ private ListView mPartyMemberList;
+
+ private int mSkillSelectedForRoll;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_skill_checker);
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ mSkillSelectedForRoll = 0;
+
+ mSQLManager = new PTDatabaseManager(getApplicationContext());
+ mUserPrefsManager = new PTUserPrefsManager(getApplicationContext());
+
+ mRollButton = (Button) findViewById(R.id.buttonRoll);
+ mRollButton.setOnClickListener(this);
+
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
+ R.array.checkable_skills_array, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+ mSkillSpinner = (Spinner) findViewById(R.id.spinnerSkillToRoll);
+ mSkillSpinner.setAdapter(adapter);
+ mSkillSpinner.setOnItemSelectedListener(this);
+ mSkillSpinner.setSelection(mSkillSelectedForRoll);
+
+ mPartyMemberList = (ListView) findViewById(R.id.listViewPartyMembers);
+
+ loadEncounterParty();
+ resetPartyRolls();
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here
+
+ switch (item.getItemId()) {
+ case android.R.id.home: // Tapped the back button on the action bar,
+ // to
+ // return to main menu
+ finish();
+ break;
+ }
+ }
+
+ return true;
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+
+ // Initialize the global menu items
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+ return true;
+ }
+
+ /**
+ * Load the current encounter party in shared prefs
+ * If there is no party set in user prefs, it pulls the default currently set in party manager
+ * If there is not current party, an empty party is set
+ */
+ public void loadEncounterParty(){
+
+ PTParty currentEncounterParty = mUserPrefsManager.getEncounterParty();
+ //If there is no saved encounter party, get from party manager
+ //Also, if the encounter party was saved, but previously was empty, get from party manager.
+ //Thirdly, if the party in encounter is not rolled (not in an encounter) use default party
+ if(currentEncounterParty == null || currentEncounterParty.size() == 0 || !partyIsInEncounter(currentEncounterParty)){
+ loadDefaultParty();
+ }
+ else{
+ mParty = currentEncounterParty;
+
+ refreshPartyView();
+ }
+ }
+
+ public void loadDefaultParty(){
+ int currentPartyID = mUserPrefsManager.getSelectedParty();
+ if(currentPartyID >= 0)
+ mParty = mSQLManager.getParty(currentPartyID);
+ else
+ mParty = new PTParty("Empty Party");
+ refreshPartyView();
+ }
+
+ private void refreshPartyView(){
+ String[] memberNames = mParty.getNamesByRollValue();
+ int[] memberRollValues = mParty.getRollValuesByRollValue();
+ int[] indexesByRollValue = mParty.getIndexesByRollValue();
+ int[] critValues = null;
+
+ if(mParty.size() > 0) critValues = new int[mParty.size()];
+
+ for(int i = 0; i < mParty.size(); i++){
+ int naturalRollVal = memberRollValues[i] - getSkillModForMember(indexesByRollValue[i]);
+ switch(naturalRollVal){
+ case 20:
+ critValues[i] = PTPartyRollAdapter.CRIT;
+ break;
+ case 1:
+ critValues[i] = PTPartyRollAdapter.CRIT_FUMBLE;
+ break;
+ default:
+ critValues[i] = PTPartyRollAdapter.NO_CRIT;
+ break;
+ }
+ }
+ PTPartyRollAdapter adapter = new PTPartyRollAdapter(this, R.layout.party_roll_row, memberNames, memberRollValues, critValues);
+ mPartyMemberList.setAdapter(adapter);
+ }
+
+ public void resetPartyRolls(){
+ for(int i = 0; i < mParty.size(); i++){
+ mParty.getPartyMember(i).setRolledValue(0);
+ }
+ }
+
+ /**
+ *
+ * @param party
+ * @return true if party is in an encounter (has non zero roll values) false if in reset state
+ */
+ private boolean partyIsInEncounter(PTParty party){
+ for(int i = 0; i < party.size(); i++)
+ if(party.getPartyMember(i).getRolledValue() != 0)
+ return true;
+ return false;
+ }
+
+ //When roll button is clicked
+ public void onClick(View view) {
+ PTDiceSet diceSet = new PTDiceSet();
+ int skillMod;
+
+ for(int i = 0; i < mParty.size(); i++){
+ skillMod = getSkillModForMember(i);
+ mParty.getPartyMember(i).setRolledValue(diceSet.singleRoll(20)+skillMod);
+ }
+ refreshPartyView();
+ }
+
+ private int getSkillModForMember(int partyMemberIndex){
+ switch(mSkillSelectedForRoll){
+ case 0:
+ return mParty.getPartyMember(partyMemberIndex).getFortSave();
+ case 1:
+ return mParty.getPartyMember(partyMemberIndex).getReflexSave();
+ case 2:
+ return mParty.getPartyMember(partyMemberIndex).getWillSave();
+ case 3:
+ return mParty.getPartyMember(partyMemberIndex).getBluffSkillBonus();
+ case 4:
+ return mParty.getPartyMember(partyMemberIndex).getDisguiseSkillBonus();
+ case 5:
+ return mParty.getPartyMember(partyMemberIndex).getPerceptionSkillBonus();
+ case 6:
+ return mParty.getPartyMember(partyMemberIndex).getSenseMotiveSkillBonus();
+ case 7:
+ return mParty.getPartyMember(partyMemberIndex).getStealthSkillBonus();
+ default:
+ return 0;
+ }
+ }
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ refreshPartyView();
+ }
+
+ public void onItemSelected(AdapterView> adapterView, View view, int position,
+ long id) {
+ mSkillSelectedForRoll = position;
+
+ }
+
+ public void onNothingSelected(AdapterView> arg0) {
+ // Do nothing
+
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTPointbuyCalculator.java b/src/com/lateensoft/pathfinder/toolkit/PTPointbuyCalculator.java
new file mode 100644
index 0000000..d3da740
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTPointbuyCalculator.java
@@ -0,0 +1,472 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.character.PTCharacter;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+import com.lateensoft.pathfinder.toolkit.functional.PTDiceSet;
+import com.lateensoft.pathfinder.toolkit.stats.PTAbilityModSet;
+import com.lateensoft.pathfinder.toolkit.stats.PTAbilitySetCalc;
+
+public class PTPointbuyCalculator extends Activity {
+
+ static final int STR_KEY = 0;
+ static final int DEX_KEY = 1;
+ static final int CON_KEY = 2;
+ static final int INT_KEY = 3;
+ static final int WIS_KEY = 4;
+ static final int CHA_KEY = 5;
+ static final int NUM_ABILITIES = 6;
+
+ static final int MENU_ITEM_EXPORT_TO_NEW = 0;
+ private static final int MENU_ITEM_EXPORT_TO_EXISTING = 1;
+
+ static final int CUSTOM_RACE_INDEX = 7;
+
+ PTAbilitySetCalc mAbilitySet;
+ PTAbilityModSet mRacialModSet;
+ HumanRaceModSelectedListener mHumanRaceListener;
+ boolean isHuman;
+
+ Spinner mRacesSpinner;
+
+ Spinner mDialogStrSpinner;
+ Spinner mDialogDexSpinner;
+ Spinner mDialogConSpinner;
+ Spinner mDialogIntSpinner;
+ Spinner mDialogWisSpinner;
+ Spinner mDialogChaSpinner;
+
+ PTDatabaseManager mSQLManager;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_ability_calculator);
+ isHuman = true;
+
+ mAbilitySet = new PTAbilitySetCalc();
+ mRacialModSet = new PTAbilityModSet();
+
+ mRacesSpinner = (Spinner) findViewById(R.id.races_spinner);
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
+ R.array.races_array, android.R.layout.simple_spinner_item);
+ // Specify the layout to use when the list of choices appears
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+ // Apply the adapter to the spinner
+ mRacesSpinner.setAdapter(adapter);
+ mRacesSpinner.setOnItemSelectedListener(new RaceItemSelectedListener());
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ mHumanRaceListener = new HumanRaceModSelectedListener();
+ findViewById(R.id.raceStr).setOnClickListener(mHumanRaceListener);
+ findViewById(R.id.raceDex).setOnClickListener(mHumanRaceListener);
+ findViewById(R.id.raceCon).setOnClickListener(mHumanRaceListener);
+ findViewById(R.id.raceInt).setOnClickListener(mHumanRaceListener);
+ findViewById(R.id.raceWis).setOnClickListener(mHumanRaceListener);
+ findViewById(R.id.raceCha).setOnClickListener(mHumanRaceListener);
+
+ for(int i = 0; i < NUM_ABILITIES; i++) {
+ updateInterfaceAbility(i);
+ }
+ updateInterfaceRaceMods();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuItem exportAbilitySetToNew = menu.add(Menu.NONE,
+ MENU_ITEM_EXPORT_TO_NEW, Menu.NONE,
+ R.string.export_to_new_character);
+ exportAbilitySetToNew.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ MenuItem exportAbilitySetToExisting = menu.add(Menu.NONE,
+ MENU_ITEM_EXPORT_TO_EXISTING, Menu.NONE,
+ R.string.export_to_existing_character);
+ exportAbilitySetToExisting.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+ return true;
+ }
+
+ public class RaceItemSelectedListener implements OnItemSelectedListener {
+ public void onItemSelected(AdapterView> parent, View view,
+ int pos, long id) {
+ // An item was selected. You can retrieve the selected item using
+ // parent.getItemAtPosition(pos)
+ if(parent.getSelectedItemPosition() != CUSTOM_RACE_INDEX) {
+ isHuman = mRacialModSet.setRacialMods((int) parent.getSelectedItemId(),
+ getBaseContext());
+
+ mAbilitySet.applyMods(mRacialModSet);
+
+ updateInterfaceRaceMods();
+ for(int i = 0; i < NUM_ABILITIES; i++) {
+ updateInterfaceAbility(i);
+ }
+ } else {
+ // Custom race
+ showCustomRaceDialog();
+ }
+ }
+
+ public void onNothingSelected(AdapterView> parent) {
+ // Another interface callback
+ }
+ }
+
+ private void showCustomRaceDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+ LayoutInflater inflater = this.getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.calculator_custom_race_dialog, null);
+ mDialogStrSpinner = (Spinner) dialogView.findViewById(R.id.spCustomStrMod);
+ mDialogDexSpinner = (Spinner) dialogView.findViewById(R.id.spCustomDexMod);
+ mDialogConSpinner = (Spinner) dialogView.findViewById(R.id.spCustomConMod);
+ mDialogIntSpinner = (Spinner) dialogView.findViewById(R.id.spCustomIntMod);
+ mDialogWisSpinner = (Spinner) dialogView.findViewById(R.id.spCustomWisMod);
+ mDialogChaSpinner = (Spinner) dialogView.findViewById(R.id.spCustomChaMod);
+
+ setupCustomRaceSpinner(mDialogStrSpinner);
+ setupCustomRaceSpinner(mDialogDexSpinner);
+ setupCustomRaceSpinner(mDialogConSpinner);
+ setupCustomRaceSpinner(mDialogIntSpinner);
+ setupCustomRaceSpinner(mDialogWisSpinner);
+ setupCustomRaceSpinner(mDialogChaSpinner);
+
+ onCustomRaceModSetListener customRaceModSetListener = new onCustomRaceModSetListener();
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, customRaceModSetListener)
+ .setTitle(R.string.calc_custom_race_dialog_title);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ public class onCustomRaceModSetListener implements DialogInterface.OnClickListener {
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ mRacialModSet = getRacialModSetFromDialog();
+
+ isHuman = false;
+
+ mAbilitySet.applyMods(mRacialModSet);
+
+ updateInterfaceRaceMods();
+ for(int i = 0; i < NUM_ABILITIES; i++) {
+ updateInterfaceAbility(i);
+ }
+ }
+ }
+
+ private PTAbilityModSet getRacialModSetFromDialog() {
+ int[] mods = new int[NUM_ABILITIES];
+
+ Resources r = getResources();
+ int offset = r.getInteger(R.integer.calc_custom_option_offset);
+
+ mods[STR_KEY] = mDialogStrSpinner.getSelectedItemPosition() - offset;
+ mods[DEX_KEY] = mDialogDexSpinner.getSelectedItemPosition() - offset;
+ mods[CON_KEY] = mDialogConSpinner.getSelectedItemPosition() - offset;
+ mods[INT_KEY] = mDialogIntSpinner.getSelectedItemPosition() - offset;
+ mods[WIS_KEY] = mDialogWisSpinner.getSelectedItemPosition() - offset;
+ mods[CHA_KEY] = mDialogChaSpinner.getSelectedItemPosition() - offset;
+
+ PTAbilityModSet racialModSet = new PTAbilityModSet();
+ racialModSet.setMods(mods);
+
+ return racialModSet;
+ }
+
+ private void setupCustomRaceSpinner(Spinner spinner) {
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
+ R.array.calc_custom_race_mod_options, android.R.layout.simple_spinner_item);
+
+ Resources r = getResources();
+
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+ spinner.setAdapter(adapter);
+ spinner.setSelection(r.getInteger(R.integer.calc_custom_option_offset));
+ }
+
+ public class HumanRaceModSelectedListener implements OnClickListener {
+ public void onClick(View v) {
+ Resources r = getResources();
+ int id = v.getId();
+
+ if(isHuman == false) {
+ return;
+ }
+
+ switch (id) {
+ case R.id.raceStr:
+ mRacialModSet.setHumanRacialMods(r.getInteger(R.integer.key_strength),
+ getBaseContext());
+ break;
+ case R.id.raceDex:
+ mRacialModSet.setHumanRacialMods(r.getInteger(R.integer.key_dexterity),
+ getBaseContext());
+ break;
+ case R.id.raceCon:
+ mRacialModSet.setHumanRacialMods(r.getInteger(R.integer.key_constitution),
+ getBaseContext());
+ break;
+ case R.id.raceInt:
+ mRacialModSet.setHumanRacialMods(r.getInteger(R.integer.key_intelligence),
+ getBaseContext());
+ break;
+ case R.id.raceWis:
+ mRacialModSet.setHumanRacialMods(r.getInteger(R.integer.key_wisdom),
+ getBaseContext());
+ break;
+ case R.id.raceCha:
+ mRacialModSet.setHumanRacialMods(r.getInteger(R.integer.key_charisma),
+ getBaseContext());
+ break;
+ }
+
+ mAbilitySet.applyMods(mRacialModSet);
+ updateInterfaceRaceMods();
+ for(int i = 0; i < NUM_ABILITIES; i++) {
+ updateInterfaceAbility(i);
+ }
+ }
+
+ public void onNothingSelected(AdapterView> parent) {
+ //deerrrr
+ }
+
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ mSQLManager = new PTDatabaseManager(this);
+
+ switch (item.getItemId()) {
+ case android.R.id.home: //Tapped the back button on the action bar, to return to main menu
+ finish();
+ break;
+ case MENU_ITEM_EXPORT_TO_NEW:
+ PTCharacter character = mSQLManager.addNewCharacter("From calc", this);
+ character.setAbilitySet(mAbilitySet.getAbilitySetPostMods());
+ Resources r = getResources();
+ character.getFluff().setRace(r.getStringArray(R.array.races_array)
+ [mRacesSpinner.getSelectedItemPosition()]);
+
+ PTUserPrefsManager userPrefsManager = new PTUserPrefsManager(this);
+ userPrefsManager.setSelectedCharacter(character.mID);
+ mSQLManager.updateCharacter(character);
+ startActivity(new Intent(this, PTCharacterSheetActivity.class));
+ finish();
+ break;
+ case MENU_ITEM_EXPORT_TO_EXISTING:
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.select_character_dialog_header));
+ String[] characterList = mSQLManager.getCharacterNames();
+
+ onCharacterExportSelectListener exportListener =
+ new onCharacterExportSelectListener();
+
+ builder.setSingleChoiceItems(characterList, -1,
+ exportListener).setPositiveButton(R.string.ok_button_text, exportListener)
+ .setNegativeButton(R.string.cancel_button_text, exportListener);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ break;
+ }
+ }
+ return true;
+ }
+
+ public class onCharacterExportSelectListener implements DialogInterface.OnClickListener {
+ int mCharacterSelectedInDialog;
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ PTCharacter character = mSQLManager.getCharacter(mCharacterSelectedInDialog);
+ character.setAbilitySet(mAbilitySet.getAbilitySetPostMods());
+ Resources r = getResources();
+ character.getFluff().setRace(r.getStringArray(R.array.races_array)
+ [mRacesSpinner.getSelectedItemPosition()]);
+
+ PTUserPrefsManager userPrefsManager = new PTUserPrefsManager(
+ PTPointbuyCalculator.this);
+ userPrefsManager.setSelectedCharacter(character.mID);
+ mSQLManager.updateCharacter(character);
+ startActivity(new Intent(PTPointbuyCalculator.this,
+ PTCharacterSheetActivity.class));
+ finish();
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ default:
+ // Set the currently selected character in the dialog
+ mCharacterSelectedInDialog = mSQLManager.getCharacterIDs()[selection];
+ break;
+
+ }
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ saveState();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ saveState();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ }
+
+ private void saveState() {
+ //Derp
+ }
+
+ public void updateInterfaceRaceMods() {
+ TextView t = new TextView(this);
+ int[] abilityMods = mRacialModSet.getMods();
+ int[] racialModIds = {R.id.raceStr, R.id.raceDex, R.id.raceCon, R.id.raceInt, R.id.raceWis, R.id.raceCha};
+
+ for(int i = 0; i < NUM_ABILITIES; i++) {
+ t = (TextView) findViewById(racialModIds[i]);
+ t.setText(Integer.toString(abilityMods[i]));
+ }
+ }
+
+ public void updateInterfaceAbility(int key) {
+ TextView t = new TextView(this);
+ int[] modIds = {R.id.strMod, R.id.dexMod, R.id.conMod, R.id.intMod, R.id.wisMod, R.id.chaMod};
+ int[] finalScoreIds = {R.id.finStr, R.id.finDex, R.id.finCon, R.id.finInt, R.id.finWis, R.id.finCha};
+ int[] baseScoreIds = {R.id.baseStr, R.id.baseDex, R.id.baseCon, R.id.baseInt, R.id.baseWis, R.id.baseCha};
+ mAbilitySet.applyMods(mRacialModSet);
+
+ t = (TextView) findViewById(modIds[key]);
+ t.setText(Integer.toString(mAbilitySet.getAbilityScorePostMod(key).getModifier()));
+
+ t = (TextView) findViewById(baseScoreIds[key]);
+ t.setText(Integer.toString(mAbilitySet.getAbilityScore(key).getScore()));
+
+ t = (TextView) findViewById(finalScoreIds[key]);
+ t.setText(Integer.toString(mAbilitySet.getAbilityScorePostMod(key).getScore()));
+
+ t = (TextView) findViewById(R.id.textCost);
+ t.setText(Integer.toString(mAbilitySet.getPointBuyCost()));
+ }
+
+ public void incStr(View v) {
+ mAbilitySet.getAbilityScore(STR_KEY).incScore();
+ updateInterfaceAbility(STR_KEY);
+ }
+
+ public void decStr(View v) {
+ mAbilitySet.getAbilityScore(STR_KEY).decScore();
+ updateInterfaceAbility(STR_KEY);
+ }
+
+ public void incDex(View v) {
+ mAbilitySet.getAbilityScore(DEX_KEY).incScore();
+ updateInterfaceAbility(DEX_KEY);
+ }
+
+ public void decDex(View v) {
+ mAbilitySet.getAbilityScore(DEX_KEY).decScore();
+ updateInterfaceAbility(DEX_KEY);
+ }
+
+ public void incCon(View v) {
+ mAbilitySet.getAbilityScore(CON_KEY).incScore();
+ updateInterfaceAbility(CON_KEY);
+ }
+
+ public void decCon(View v) {
+ mAbilitySet.getAbilityScore(CON_KEY).decScore();
+ updateInterfaceAbility(CON_KEY);
+ }
+
+ public void incInt(View v) {
+ mAbilitySet.getAbilityScore(INT_KEY).incScore();
+ updateInterfaceAbility(INT_KEY);
+ }
+
+ public void decInt(View v) {
+ mAbilitySet.getAbilityScore(INT_KEY).decScore();
+ updateInterfaceAbility(INT_KEY);
+ }
+
+ public void incWis(View v) {
+ mAbilitySet.getAbilityScore(WIS_KEY).incScore();
+ updateInterfaceAbility(WIS_KEY);
+ }
+
+ public void decWis(View v) {
+ mAbilitySet.getAbilityScore(WIS_KEY).decScore();
+ updateInterfaceAbility(WIS_KEY);
+ }
+
+ public void incCha(View v) {
+ mAbilitySet.getAbilityScore(CHA_KEY).incScore();
+ updateInterfaceAbility(CHA_KEY);
+ }
+
+ public void decCha(View v) {
+ mAbilitySet.getAbilityScore(CHA_KEY).decScore();
+ updateInterfaceAbility(CHA_KEY);
+ }
+
+ public PTAbilitySetCalc rollXdYDropZ(int x, int y, int z) {
+ PTAbilitySetCalc abilitySet = new PTAbilitySetCalc();
+ PTDiceSet dice = new PTDiceSet();
+ int[] rollSet = dice.multiRollWithResults(x, y);
+ int[] finalRollSet = new int[x - z];
+ int temp = 1;
+ for(int i = 0; i < rollSet.length; i++) {
+ while(temp > 0) {
+ temp = arrayInsertKeepHighest(rollSet[i], finalRollSet);
+ }
+ }
+
+ return abilitySet;
+ }
+
+ private int arrayInsertKeepHighest(int insert, int[] array) {
+ int temp = -1;
+ for(int i = 0; i < array.length; i++) {
+ if(insert > array[i]){
+ temp = array[i];
+ array[i] = insert;
+ }
+ }
+
+ return temp;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/PTSharedMenu.java b/src/com/lateensoft/pathfinder/toolkit/PTSharedMenu.java
new file mode 100644
index 0000000..55e5be7
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/PTSharedMenu.java
@@ -0,0 +1,71 @@
+package com.lateensoft.pathfinder.toolkit;
+
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+public class PTSharedMenu {
+
+ // start at 1000 ensure that we do not interfere with the activity-specific
+ // menu items
+ public static final int MENU_ABOUT = 1000;
+
+ public static void onCreateOptionsMenu(Menu menu, Context context) {
+ menu.add(Menu.NONE, MENU_ABOUT, Menu.NONE, context.getResources()
+ .getString(R.string.shared_menu_about));
+
+ }
+
+ public static boolean onOptionsItemSelected(MenuItem item, Activity caller) {
+ switch (item.getItemId()) {
+ case PTSharedMenu.MENU_ABOUT:
+ showAboutDialog(caller);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private static void showAboutDialog(Activity caller) {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(caller);
+ builder.setTitle(caller.getResources().getString(R.string.shared_menu_about));
+
+ LayoutInflater inflater = caller.getLayoutInflater();
+
+ View dialogView = (View)inflater.inflate(caller.getResources().getLayout(R.layout.about_screen), null);
+ TextView versionText = (TextView)dialogView.findViewById(R.id.textAboutVersion);
+
+ PackageInfo pInfo;
+ try{
+ pInfo = caller.getPackageManager().getPackageInfo(caller.getPackageName(), 0);
+ versionText.setText(caller.getString(R.string.app_version_name) + " " + pInfo.versionName);
+ }catch (NameNotFoundException e) {
+ e.printStackTrace();
+ }
+
+
+ builder.setView(dialogView);
+ builder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ // Closes automatically
+
+ }
+ });
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/TabListener.java b/src/com/lateensoft/pathfinder/toolkit/TabListener.java
new file mode 100644
index 0000000..d899209
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/TabListener.java
@@ -0,0 +1,50 @@
+package com.lateensoft.pathfinder.toolkit;
+
+import android.app.ActionBar.Tab;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.ActionBar;
+import android.app.FragmentTransaction;
+
+public class TabListener implements ActionBar.TabListener {
+ private Fragment mFragment;
+ private final Activity mActivity;
+ private final String mTag;
+ private final Class mClass;
+
+ /** Constructor used each time a new tab is created.
+ * @param activity The host Activity, used to instantiate the fragment
+ * @param tag The identifier tag for the fragment
+ * @param clz The fragment's Class, used to instantiate the fragment
+ */
+ public TabListener(Activity activity, String tag, Class clz) {
+ mActivity = activity;
+ mTag = tag;
+ mClass = clz;
+ }
+
+ /* The following are each of the ActionBar.TabListener callbacks */
+
+ public void onTabSelected(Tab tab, FragmentTransaction ft) {
+ // Check if the fragment is already initialized
+ if (mFragment == null) {
+ // If not, instantiate and add it to the activity
+ mFragment = Fragment.instantiate(mActivity, mClass.getName());
+ ft.add(android.R.id.content, mFragment, mTag);
+ } else {
+ // If it exists, simply attach it in order to show it
+ ft.attach(mFragment);
+ }
+ }
+
+ public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+ if (mFragment != null) {
+ // Detach the fragment, because another one is being attached
+ ft.detach(mFragment);
+ }
+ }
+
+ public void onTabReselected(Tab tab, FragmentTransaction ft) {
+ // User selected the already selected tab. Usually do nothing.
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTArmorAdapter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTArmorAdapter.java
new file mode 100644
index 0000000..41b7ee3
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTArmorAdapter.java
@@ -0,0 +1,78 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.items.PTArmor;
+
+public class PTArmorAdapter extends ArrayAdapter {
+
+ Context mContext;
+ int mLayoutResourceId;
+ PTArmor[] mArmor = null;
+ static final String TAG = "PTArmorAdapter";
+
+ public PTArmorAdapter(Context context, int textViewResourceId,
+ PTArmor[] objects) {
+ super(context, textViewResourceId, objects);
+ mLayoutResourceId = textViewResourceId;
+ mContext = context;
+ mArmor = objects;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ ArmorHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new ArmorHolder();
+
+ holder.name = (TextView)row.findViewById(R.id.armorName);
+ holder.weight = (TextView)row.findViewById(R.id.armorWeight);
+ holder.ACBonus = (TextView)row.findViewById(R.id.armorClass);
+ holder.checkPen = (TextView)row.findViewById(R.id.armorCheckPenalty);
+ holder.maxDex = (TextView)row.findViewById(R.id.armorMaxDex);
+ holder.specialProperties = (TextView)row.findViewById(R.id.armorSpecial);
+ holder.speed = (TextView)row.findViewById(R.id.armorSpeed);
+ holder.size = (TextView)row.findViewById(R.id.armorSize);
+ holder.spellFail = (TextView)row.findViewById(R.id.armorSpellFail);
+
+ row.setTag(holder);
+ } else {
+ holder = (ArmorHolder)row.getTag();
+ }
+
+ holder.name.setText(mArmor[position].getName());
+ holder.weight.setText(Integer.toString(mArmor[position].getWeight()));
+ holder.ACBonus.setText(Integer.toString(mArmor[position].getACBonus()));
+ holder.checkPen.setText(Integer.toString(mArmor[position].getCheckPen()));
+ holder.maxDex.setText(Integer.toString(mArmor[position].getMaxDex()));
+ holder.specialProperties.setText(mArmor[position].getSpecialProperties());
+ holder.speed.setText(mArmor[position].getSpeedString());
+ holder.size.setText((mArmor[position].getSize()));
+ holder.spellFail.setText(Integer.toString(mArmor[position].getSpellFail()) + "%");
+
+ return row;
+ }
+
+ static class ArmorHolder {
+ TextView name;
+ TextView spellFail;
+ TextView weight;
+ TextView ACBonus;
+ TextView checkPen;
+ TextView maxDex;
+ TextView specialProperties;
+ TextView speed;
+ TextView size;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTArmorFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTArmorFragment.java
new file mode 100644
index 0000000..8bb5771
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTArmorFragment.java
@@ -0,0 +1,229 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.items.PTArmor;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+public class PTArmorFragment extends PTCharacterSheetFragment implements
+ OnClickListener, OnItemClickListener, android.content.DialogInterface.OnClickListener{
+
+ static final String TAG = "PTArmorFragment";
+ private static final int AC_SPINNER_OFFSET = 20;
+ private static final int ASF_INCREMENT = 5;
+ private static final int SPEED_INCREMENT = 5;
+ private ListView mListView;
+ int mArmorSelectedForEdit;
+ private Button mAddButton;
+
+ private Spinner mDialogACSpinner;
+ private Spinner mDialogACPSpinner;
+ private Spinner mDialogSizeSpinner;
+ private Spinner mDialogSpeedSpinner;
+ private Spinner mDialogMaxDexSpinner;
+ private Spinner mDialogASFSpinner;
+ private EditText mDialogWeightET;
+ private EditText mDialogNameET;
+ private EditText mDialogSpecialPropertiesET;
+
+ private ViewGroup mContainer;
+
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.v(TAG, "Starting onCreateView");
+
+ mContainer = container;
+
+ View fragmentView = inflater.inflate(R.layout.character_armor_fragment,
+ container, false);
+
+ mAddButton = (Button) fragmentView.findViewById(R.id.buttonAddArmor);
+ mAddButton.setOnClickListener(this);
+
+ mListView = new ListView(container.getContext());
+ mListView = (ListView) fragmentView.findViewById(R.id.lvArmor);
+ refreshArmorListView();
+
+ mListView.setOnItemClickListener(this);
+
+ Log.v(TAG, "Finishing onCreateView");
+ return fragmentView;
+ }
+
+ private void refreshArmorListView() {
+ PTArmorAdapter adapter = new PTArmorAdapter(mContainer.getContext(),
+ R.layout.character_armor_row,
+ mCharacter.getInventory().getArmorArray());
+
+ Log.v(TAG, "Called refreshArmorListView");
+
+ mListView.setAdapter(adapter);
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Log.v(TAG, "Item clicked: " + position);
+ mArmorSelectedForEdit = position;
+ showArmorDialog(mCharacter.getInventory().getArmor(position));
+ }
+
+ public void onClick(View v) {
+ Log.v(TAG, "Add button clicked");
+ mArmorSelectedForEdit = -1;
+ showArmorDialog(null);
+ }
+
+ private void showArmorDialog(PTArmor armor) {
+ if(armor == null) {
+ armor = new PTArmor();
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.character_armor_dialog, null);
+ mDialogACSpinner = (Spinner) dialogView.findViewById(R.id.spArmorClass);
+ mDialogACPSpinner = (Spinner) dialogView.findViewById(R.id.spArmorCheckPenalty);
+ mDialogSizeSpinner = (Spinner) dialogView.findViewById(R.id.spArmorSize);
+ mDialogSpeedSpinner = (Spinner) dialogView.findViewById(R.id.spArmorSpeed);
+ mDialogASFSpinner = (Spinner) dialogView.findViewById(R.id.spArmorSpellFailure);
+ mDialogWeightET = (EditText) dialogView.findViewById(R.id.etArmorWeight);
+ mDialogSpecialPropertiesET = (EditText) dialogView.findViewById(
+ R.id.etArmorSpecialProperties);
+ mDialogNameET = (EditText) dialogView.findViewById(R.id.armorName);
+ mDialogMaxDexSpinner = (Spinner) dialogView.findViewById(R.id.spArmorMaxDex);
+
+ setupSpinner(mDialogACSpinner, R.array.ac_spinner_options);
+ setupSpinner(mDialogACPSpinner, R.array.acp_spinner_options);
+ setupSpinner(mDialogSizeSpinner, R.array.size_spinner_options);
+ setupSpinner(mDialogSpeedSpinner, R.array.speed_spinner_options);
+ setupSpinner(mDialogMaxDexSpinner, R.array.acp_spinner_options);
+ setupSpinner(mDialogASFSpinner, R.array.armor_spell_fail_options);
+
+ if(mArmorSelectedForEdit < 0) {
+ builder.setTitle(R.string.new_armor_title);
+ mDialogACSpinner.setSelection(AC_SPINNER_OFFSET);
+ } else {
+ builder.setTitle(armor.getName()).setNeutralButton(R.string.delete_button_text,
+ this);
+ mDialogNameET.setText(mCharacter.getInventory()
+ .getArmor(mArmorSelectedForEdit).getName());
+ mDialogACSpinner.setSelection((mCharacter.getInventory()
+ .getArmor(mArmorSelectedForEdit).getACBonus()) + AC_SPINNER_OFFSET);
+ mDialogACPSpinner.setSelection(mCharacter.getInventory()
+ .getArmor(mArmorSelectedForEdit).getCheckPen());
+ mDialogSizeSpinner.setSelection(mCharacter.getInventory()
+ .getArmor(mArmorSelectedForEdit).getSizeInt());
+ mDialogMaxDexSpinner.setSelection(armor.getMaxDex());
+ mDialogSpeedSpinner.setSelection(armor.getSpeed()/5);
+ mDialogASFSpinner.setSelection(armor.getSpellFail() / ASF_INCREMENT);
+ mDialogWeightET.setText(Integer.toString(armor.getWeight()));
+ mDialogSpecialPropertiesET.setText(mCharacter.getInventory().getArmor(mArmorSelectedForEdit).getSpecialProperties());
+ }
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ PTArmor armor = getArmorFromDialog();
+
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ Log.v(TAG, "Add.edit armor OK: " + mDialogNameET.getText());
+ if(mArmorSelectedForEdit < 0) {
+ Log.v(TAG, "Adding an armor");
+ if(armor != null) {
+ mCharacter.getInventory().addArmor(armor);
+ refreshArmorListView();
+ }
+ } else {
+ Log.v(TAG, "Editing an armor");
+
+ mCharacter.getInventory().setArmor(armor, mArmorSelectedForEdit);
+ refreshArmorListView();
+ }
+
+ break;
+
+ case DialogInterface.BUTTON_NEUTRAL:
+ Log.v(TAG, "Deleting an armor");
+ mCharacter.getInventory().deleteArmor(mArmorSelectedForEdit);
+ refreshArmorListView();
+ break;
+
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+
+ default:
+ break;
+
+ }
+ }
+
+ private PTArmor getArmorFromDialog() {
+ String name = new String(mDialogNameET.getText().toString());
+ if(name == null || name.contentEquals("")) {
+ return null;
+ }
+
+ int spellFail;
+ int weight;
+
+ String specialProperties = new String(mDialogSpecialPropertiesET.getText().toString());
+ int speed = mDialogSpeedSpinner.getSelectedItemPosition() * SPEED_INCREMENT;
+
+ spellFail = mDialogASFSpinner.getSelectedItemPosition() * ASF_INCREMENT;
+
+ try {
+ weight = Integer.parseInt(mDialogWeightET.getText().toString());
+ } catch (NumberFormatException e) {
+ weight = 1;
+ }
+
+ int size = mDialogSizeSpinner.getSelectedItemPosition();
+ int ac = mDialogACSpinner.getSelectedItemPosition() - AC_SPINNER_OFFSET;
+ int acp = mDialogACPSpinner.getSelectedItemPosition();
+ int maxDex = mDialogMaxDexSpinner.getSelectedItemPosition();
+
+ PTArmor armor = new PTArmor();
+ armor.setName(name);
+ armor.setSpeed(speed);
+ armor.setSpecialProperties(specialProperties);
+ armor.setSpellFail(spellFail);
+ armor.setWeight(weight);
+ armor.setSize(size);
+ armor.setACBonus(ac);
+ armor.setCheckPen(acp);
+ armor.setMaxDex(maxDex);
+ return armor;
+ }
+
+ private void setupSpinner(Spinner spinner, int optionResourceId) {
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
+ optionResourceId, android.R.layout.simple_spinner_item);
+
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+ spinner.setAdapter(adapter);
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacter.java
new file mode 100644
index 0000000..73d7e54
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacter.java
@@ -0,0 +1,99 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.content.Context;
+
+import com.lateensoft.pathfinder.toolkit.stats.PTAbilitySet;
+import com.lateensoft.pathfinder.toolkit.stats.PTCombatStatSet;
+import com.lateensoft.pathfinder.toolkit.stats.PTSaveSet;
+import com.lateensoft.pathfinder.toolkit.stats.PTSkillSet;
+
+public class PTCharacter {
+ PTAbilitySet mAbilitySet;
+ PTAbilitySet mTempAbilitySet;
+ PTCombatStatSet mCombatStatSet;
+ PTSkillSet mSkillSet;
+ PTSaveSet mSaveSet;
+ PTCharacterFluffInfo mFluffInfo;
+ PTCharacterInventory mInventory;
+ public double mGold;
+ PTCharacterFeatList mFeats;
+ PTSpellBook mSpellBook;
+
+ public int mID;
+
+ public PTCharacter(String name, Context context) {
+ mAbilitySet = new PTAbilitySet();
+ mTempAbilitySet = new PTAbilitySet();
+ mCombatStatSet = new PTCombatStatSet();
+ mSkillSet = new PTSkillSet(context);
+ mSaveSet = new PTSaveSet(context);
+ mFluffInfo = new PTCharacterFluffInfo();
+ mInventory = new PTCharacterInventory();
+ mFeats = new PTCharacterFeatList();
+ mSpellBook = new PTSpellBook();
+ mGold = 0;
+ setName(name);
+ mID = 0;
+ }
+
+ public void setAbilitySet(PTAbilitySet abilitySet) {
+ mAbilitySet = abilitySet;
+ }
+
+ public PTAbilitySet getAbilitySet() {
+ return mAbilitySet;
+ }
+
+ public PTAbilitySet getTempAbilitySet() {
+ return mTempAbilitySet;
+ }
+
+ public PTCombatStatSet getCombatStatSet(){
+ return mCombatStatSet;
+ }
+
+ public PTSkillSet getSkillSet() {
+ return mSkillSet;
+ }
+
+ public PTCharacterInventory getInventory(){
+ return mInventory;
+ }
+
+ public void setInventory(PTCharacterInventory newInventory){
+ mInventory = newInventory;
+ }
+
+ public PTCharacterFeatList getFeatList(){
+ return mFeats;
+ }
+
+ public void setFeatList(PTCharacterFeatList newFeats){
+ mFeats = newFeats;
+ }
+
+ public PTCharacterFluffInfo getFluff() {
+ return mFluffInfo;
+ }
+
+ public PTSaveSet getSaveSet(){
+ return mSaveSet;
+ }
+
+ public String getName(){
+ return mFluffInfo.getName();
+ }
+
+ public void setName(String name){
+ if(name != null && name != "")
+ mFluffInfo.setName(name);
+ }
+
+ public PTSpellBook getSpellBook() {
+ return mSpellBook;
+ }
+
+ public void setSpellBook(PTSpellBook spellBook) {
+ mSpellBook = spellBook;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterAbilityFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterAbilityFragment.java
new file mode 100644
index 0000000..646399f
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterAbilityFragment.java
@@ -0,0 +1,167 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+// Untested
+public class PTCharacterAbilityFragment extends PTCharacterSheetFragment {
+ static final String TAG = "PTCharacterAbilityFragment";
+ View mView;
+ Context mContext;
+ AbilityItemSelectedListener[] mAbilityItemSelectedListeners;
+ AbilityItemSelectedListener[] mTempAbilityItemSelectedListeners;
+ //LayoutInflater mInflater;
+ Spinner[] mBaseScoreSpinners;
+ Spinner[] mTempScoreSpinners;
+
+ final int[] modIds = {R.id.strMod, R.id.dexMod, R.id.conMod, R.id.intMod,
+ R.id.wisMod, R.id.chaMod};
+ final int[] tempScoreIds = {R.id.strTempScore, R.id.dexTempScore, R.id.conTempScore,
+ R.id.intTempScore, R.id.wisTempScore, R.id.chaTempScore};
+ final int[] baseScoreIds = {R.id.baseStr, R.id.baseDex, R.id.baseCon, R.id.baseInt,
+ R.id.baseWis, R.id.baseCha};
+ final int[] tempModIds = {R.id.strTempMod, R.id.dexTempMod, R.id.conTempMod,
+ R.id.intTempMod, R.id.wisTempMod, R.id.chaTempMod};
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mContext = container.getContext();
+
+ mView = inflater.inflate(R.layout.activity_character_sheet_abilities,
+ container, false);
+
+ mAbilityItemSelectedListeners = new AbilityItemSelectedListener[modIds.length];
+ mTempAbilityItemSelectedListeners = new AbilityItemSelectedListener[modIds.length];
+
+ setupSpinners(mBaseScoreSpinners, baseScoreIds, mAbilityItemSelectedListeners, false);
+ setupSpinners(mTempScoreSpinners, tempScoreIds, mTempAbilityItemSelectedListeners, true);
+ updateMods(modIds, false);
+ updateMods(tempModIds, true);
+
+ return mView;
+ }
+
+ public void updateInterfaceAbilities() {
+ for(int i = 0; i < modIds.length; i++) {
+ updateInterfaceAbility(i);
+ }
+ }
+
+ public void updateInterfaceAbility(int key) {
+ Spinner s = new Spinner(mContext);
+ TextView tv = new TextView(mContext);
+
+ tv = (TextView) mView.findViewById(modIds[key]);
+ tv.setText(mCharacter.getAbilitySet().getAbilityScore(key).getModifier());
+
+ s = (Spinner) mView.findViewById(baseScoreIds[key]);
+ s.setSelection((mCharacter.getAbilitySet().getAbilityScore(key).getScore()));
+
+ s = (Spinner) mView.findViewById(tempScoreIds[key]);
+ s.setSelection((mCharacter.getTempAbilitySet()
+ .getAbilityScore(key).getScore()));
+
+ tv = (TextView) mView.findViewById(tempModIds[key]);
+ tv.setText((mCharacter.getTempAbilitySet()
+ .getAbilityScore(key).getModifier()));
+ }
+
+ public void setupSpinners(Spinner[] spinners, int viewIds[],
+ AbilityItemSelectedListener[] listeners, boolean isTemp) {
+ spinners = new Spinner[viewIds.length];
+ //mSpinner = (Spinner) mView.findViewById(R.id.baseStr);
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
+ R.array.selectable_values_string, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+
+ for(int i = 0; i < viewIds.length; i++) {
+ listeners[i] = new AbilityItemSelectedListener(isTemp, i);
+ spinners[i] = (Spinner) mView.findViewById(viewIds[i]);
+
+ spinners[i].setAdapter(adapter);
+
+ spinners[i].setOnItemSelectedListener(listeners[i]);
+ if(isTemp) {
+ spinners[i].setSelection(mCharacter.getTempAbilitySet().getAbilityScore(i)
+ .getScore(), true);
+ } else {
+ spinners[i].setSelection(mCharacter.getAbilitySet().getAbilityScore(i).getScore(),
+ true);
+ }
+ }
+ }
+
+ public void updateMods(int viewIds[], boolean isTemp) {
+ TextView tv;
+
+ for(int i = 0; i < viewIds.length; i++) {
+ tv = (TextView) mView.findViewById(viewIds[i]);
+ if(isTemp) {
+ tv.setText(Integer.toString(mCharacter.getTempAbilitySet().getAbilityScore(i)
+ .getModifier()));
+ }
+ else {
+ tv.setText(Integer.toString(mCharacter.getAbilitySet().getAbilityScore(i)
+ .getModifier()));
+ }
+ }
+ }
+
+ public void onResume() {
+ super.onResume();
+ setupSpinners(mBaseScoreSpinners, baseScoreIds, mAbilityItemSelectedListeners, false);
+ setupSpinners(mTempScoreSpinners, tempScoreIds, mTempAbilityItemSelectedListeners, true);
+ updateMods(modIds, false);
+ updateMods(tempModIds, true);
+ }
+
+ public class AbilityItemSelectedListener implements OnItemSelectedListener {
+ int mSourceId;
+ int[] mIds;
+ boolean mIsTemp;
+ int mAbilityIndex;
+
+ public AbilityItemSelectedListener(boolean isTemp, int abilityIndex) {
+ super();
+ mIsTemp = isTemp;
+ mAbilityIndex = abilityIndex;
+ }
+
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+
+ public void onItemSelected(AdapterView> parent, View view,
+ int pos, long id) {
+
+ if(mIsTemp) {
+ mCharacter.getTempAbilitySet().setScore(mAbilityIndex, pos);
+ }
+ else {
+ mCharacter.getAbilitySet().setScore(mAbilityIndex, pos);
+ }
+
+ updateMods(tempModIds, true);
+ updateMods(modIds, false);
+
+ }
+
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterCombatStatsFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterCombatStatsFragment.java
new file mode 100644
index 0000000..9e3044d
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterCombatStatsFragment.java
@@ -0,0 +1,564 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTCharacterCombatStatsFragment extends PTCharacterSheetFragment implements OnFocusChangeListener, OnEditorActionListener {
+
+ final String TAG = "PTCharacterCombatStatsFragment";
+
+ static final int STR_KEY = 0;
+ static final int DEX_KEY = 1;
+ static final int CON_KEY = 2;
+ static final int INT_KEY = 3;
+ static final int WIS_KEY = 4;
+ static final int CHA_KEY = 5;
+
+ static final int FORT_KEY = 0;
+ static final int REF_KEY = 1;
+ static final int WILL_KEY = 2;
+
+ private TextView mCurrentHPTextView;
+ private EditText mTotalHPEditText;
+ private EditText mDamageReductEditText;
+ private EditText mWoundsEditText;
+ private EditText mNonLethalDmgEditText;
+
+ private EditText mBaseSpeedEditText;
+
+ private TextView mInitTextView;
+ private EditText mInitDexEditText;
+ private EditText mInitMiscEditText;
+
+ private TextView mACTextView;
+ private EditText mArmourBonusEditText;
+ private EditText mShieldBonusEditText;
+ private EditText mACDexEditText;
+ private EditText mACSizeEditText;
+ private EditText mNaturalArmourEditText;
+ private EditText mDeflectEditText;
+ private EditText mACMiscEditText;
+ private TextView mACTouchTextView;
+ private TextView mACFFTextView;
+ private EditText mSpellResistEditText;
+
+ private EditText mBABPrimaryEditText;
+ private EditText mBABSecondaryEditText;
+ private TextView mCMBTextView;
+ private EditText mCmbBABEditText;
+ private EditText mCMBStrengthEditText;
+ private EditText mCMBSizeEditText;
+ private TextView mCMDTextView;
+ private EditText mCMDDexEditText;
+
+ private TextView mFortTextView;
+ private EditText mFortBaseEditText;
+ private EditText mFortAbilityModEditText;
+ private EditText mFortMagicModEditText;
+ private EditText mFortMiscModEditText;
+ private EditText mFortTempModEditText;
+
+ private TextView mRefTextView;
+ private EditText mRefBaseEditText;
+ private EditText mRefAbilityModEditText;
+ private EditText mRefMagicModEditText;
+ private EditText mRefMiscModEditText;
+ private EditText mRefTempModEditText;
+
+ private TextView mWillTextView;
+ private EditText mWillBaseEditText;
+ private EditText mWillAbilityModEditText;
+ private EditText mWillMagicModEditText;
+ private EditText mWillMiscModEditText;
+ private EditText mWillTempModEditText;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ View fragmentView = inflater.inflate(
+ R.layout.character_combat_stats_fragment, container, false);
+ setupViews(fragmentView);
+
+ return fragmentView;
+ }
+
+
+ public void updateAllViews(){
+ updateHPViews();
+ updateSpeedViews();
+ updateInitiativeViews();
+ updateACViews();
+ updateBABViews();
+ updateCombatManeuverViews();
+ updateSaveViews();
+ }
+
+ /**
+ * Updates all stats for HP
+ */
+ public void updateHP(){
+ mCharacter.getCombatStatSet().setTotalHP(getEditTextInt(mTotalHPEditText));
+ mCharacter.getCombatStatSet().setWounds(getEditTextInt(mWoundsEditText));
+ mCharacter.getCombatStatSet().setNonLethalDamage(getEditTextInt(mNonLethalDmgEditText));
+ mCharacter.getCombatStatSet().setDamageReduction(getEditTextInt(mDamageReductEditText));
+ updateHPViews();
+ }
+
+ /**
+ * Updates all views for HP
+ */
+ public void updateHPViews(){
+ setIntText(mCurrentHPTextView, mCharacter.getCombatStatSet().getCurrentHP());
+ setIntText(mTotalHPEditText, mCharacter.getCombatStatSet().getTotalHP());
+ setIntText(mWoundsEditText, mCharacter.getCombatStatSet().getWounds());
+ setIntText(mNonLethalDmgEditText, mCharacter.getCombatStatSet().getNonLethalDamage());
+ setIntText(mDamageReductEditText, mCharacter.getCombatStatSet().getDamageReduction());
+ }
+
+ /**
+ * Updates all stats for speed
+ */
+ public void updateSpeed(){
+ mCharacter.getCombatStatSet().setBaseSpeed(getEditTextInt(mBaseSpeedEditText));
+ }
+
+ /**
+ * Updates all views for speed
+ */
+ public void updateSpeedViews(){
+ setIntText(mBaseSpeedEditText, mCharacter.getCombatStatSet().getBaseSpeed());
+ }
+
+ /**
+ * Updates all stats for initiative
+ */
+ public void updateInitiative(){
+ mCharacter.getCombatStatSet().setInitDexMod(getEditTextInt(mInitDexEditText));
+ mCharacter.getCombatStatSet().setInitiativeMiscMod(getEditTextInt(mInitMiscEditText));
+ updateInitiativeViews();
+ }
+
+ /**
+ * Updates all views for initiative
+ */
+ public void updateInitiativeViews(){
+ setIntText(mInitTextView, mCharacter.getCombatStatSet().getInitiativeMod());
+ setIntText(mInitDexEditText, mCharacter.getCombatStatSet().getInitDexMod());
+ setIntText(mInitMiscEditText, mCharacter.getCombatStatSet().getInitiativeMiscMod());
+ }
+
+ /**
+ * Updates all stats for AC
+ */
+ public void updateAC(){
+ mCharacter.getCombatStatSet().setACArmourBonus(getEditTextInt(mArmourBonusEditText));
+ mCharacter.getCombatStatSet().setACShieldBonus(getEditTextInt(mShieldBonusEditText));
+ mCharacter.getCombatStatSet().setACDexMod(getEditTextInt(mACDexEditText));
+ mCharacter.getCombatStatSet().setSizeModifier(getEditTextInt(mACSizeEditText));
+ mCharacter.getCombatStatSet().setNaturalArmour(getEditTextInt(mNaturalArmourEditText));
+ mCharacter.getCombatStatSet().setDeflectionMod(getEditTextInt(mDeflectEditText));
+ mCharacter.getCombatStatSet().setACMiscMod(getEditTextInt(mACMiscEditText));
+ mCharacter.getCombatStatSet().setSpellResistance(getEditTextInt(mSpellResistEditText));
+ updateACViews();
+ }
+
+ /**
+ * Updates all views for ac
+ */
+ public void updateACViews(){
+ setIntText(mACTextView, mCharacter.getCombatStatSet().getTotalAC());
+ setIntText(mACTouchTextView, mCharacter.getCombatStatSet().getTouchAC());
+ setIntText(mACFFTextView, mCharacter.getCombatStatSet().getFlatFootedAC());
+ setIntText(mArmourBonusEditText, mCharacter.getCombatStatSet().getACArmourBonus());
+ setIntText(mShieldBonusEditText, mCharacter.getCombatStatSet().getACShieldBonus());
+ setIntText(mACDexEditText, mCharacter.getCombatStatSet().getACDexMod());
+ updateSizeModViews();
+ setIntText(mNaturalArmourEditText, mCharacter.getCombatStatSet().getNaturalArmour());
+ setIntText(mDeflectEditText, mCharacter.getCombatStatSet().getDeflectionMod());
+ setIntText(mACMiscEditText, mCharacter.getCombatStatSet().getACMiscMod());
+ setIntText(mSpellResistEditText, mCharacter.getCombatStatSet().getSpellResist());
+ }
+
+ /**
+ * Updates all stats for BAB
+ */
+ public void updateBAB(){
+ mCharacter.getCombatStatSet().setBABPrimary(getEditTextInt(mBABPrimaryEditText));
+ mCharacter.getCombatStatSet().setBABSecondary(mBABSecondaryEditText.getText().toString());
+ updateBABViews();
+ }
+
+ public void updateBABViews(){
+ updateCombatManeuverViews();
+ mBABSecondaryEditText.setText(mCharacter.getCombatStatSet().getBABSecondary());
+ }
+
+ /**
+ * Updates all stats for combat maneuvers
+ */
+ public void updateCombatManeuvers(){
+ mCharacter.getCombatStatSet().setBABPrimary(getEditTextInt(mCmbBABEditText));
+ mCharacter.getCombatStatSet().setStrengthMod(getEditTextInt(mCMBStrengthEditText));
+ mCharacter.getCombatStatSet().setSizeModifier(getEditTextInt(mCMBSizeEditText));
+ mCharacter.getCombatStatSet().setCMDDexMod(getEditTextInt(mCMDDexEditText));
+ updateCombatManeuverViews();
+ }
+
+
+ /**
+ * Updates all stats for saves
+ */
+ public void updateSaves() {
+ updateFort();
+ updateRef();
+ updateWill();
+ }
+
+ public void updateFort() {
+ mCharacter.getSaveSet().getSave(0).setBase(getEditTextInt(mFortBaseEditText));
+ mCharacter.getSaveSet().getSave(0).setAbilityMod(getEditTextInt(mFortAbilityModEditText));
+ mCharacter.getSaveSet().getSave(0).setMagicMod(getEditTextInt(mFortMagicModEditText));
+ mCharacter.getSaveSet().getSave(0).setMiscMod(getEditTextInt(mFortMiscModEditText));
+ mCharacter.getSaveSet().getSave(0).setTempMod(getEditTextInt(mFortTempModEditText));
+ }
+
+ public void updateRef() {
+ mCharacter.getSaveSet().getSave(1).setBase(getEditTextInt(mRefBaseEditText));
+ mCharacter.getSaveSet().getSave(1).setAbilityMod(getEditTextInt(mRefAbilityModEditText));
+ mCharacter.getSaveSet().getSave(1).setMagicMod(getEditTextInt(mRefMagicModEditText));
+ mCharacter.getSaveSet().getSave(1).setMiscMod(getEditTextInt(mRefMiscModEditText));
+ mCharacter.getSaveSet().getSave(1).setTempMod(getEditTextInt(mRefTempModEditText));
+ }
+
+ public void updateWill() {
+ mCharacter.getSaveSet().getSave(2).setBase(getEditTextInt(mWillBaseEditText));
+ mCharacter.getSaveSet().getSave(2).setAbilityMod(getEditTextInt(mWillAbilityModEditText));
+ mCharacter.getSaveSet().getSave(2).setMagicMod(getEditTextInt(mWillMagicModEditText));
+ mCharacter.getSaveSet().getSave(2).setMiscMod(getEditTextInt(mWillMiscModEditText));
+ mCharacter.getSaveSet().getSave(2).setTempMod(getEditTextInt(mWillTempModEditText));
+ }
+
+ /**
+ * Updates all views for combat maneuvers
+ */
+ public void updateCombatManeuverViews(){
+ setIntText(mCMBTextView, mCharacter.getCombatStatSet().getCombatManeuverBonus());
+ updatePrimaryBABViews();
+ setIntText(mCMBStrengthEditText, mCharacter.getCombatStatSet().getStrengthMod());
+ updateSizeModViews();
+ setIntText(mCMDTextView, mCharacter.getCombatStatSet().getCombatManeuverDefense());
+ setIntText(mCMDDexEditText, mCharacter.getCombatStatSet().getCMDDexMod());
+ }
+
+ /**
+ * Updates the BAB edit texts in BAB and CMB
+ */
+ public void updatePrimaryBABViews(){
+ setIntText(mBABPrimaryEditText, mCharacter.getCombatStatSet().getBABPrimary());
+ setIntText(mCmbBABEditText, mCharacter.getCombatStatSet().getBABPrimary());
+ }
+
+ /**
+ * Updates the size mod edit texts in AC and CMB
+ */
+ public void updateSizeModViews(){
+ setIntText(mACSizeEditText, mCharacter.getCombatStatSet().getSizeModifier());
+ setIntText(mCMBSizeEditText, mCharacter.getCombatStatSet().getSizeModifier());
+ }
+
+
+ public void setIntText(TextView textView, int number) {
+ textView.setText(Integer.toString(number));
+ }
+
+ public void updateSaveViews() {
+ updateFortSaveViews();
+ updateRefSaveViews();
+ updateWillSaveViews();
+ }
+
+ public void updateFortSaveViews() {
+ setIntText(mFortTextView, mCharacter.getSaveSet().getSave(0).getTotal());
+ setIntText(mFortBaseEditText, mCharacter.getSaveSet().getSave(0).getBase());
+ setIntText(mFortAbilityModEditText, mCharacter.getSaveSet().getSave(0).getAbilityMod());
+ setIntText(mFortMagicModEditText, mCharacter.getSaveSet().getSave(0).getMagicMod());
+ setIntText(mFortMiscModEditText, mCharacter.getSaveSet().getSave(0).getMiscMod());
+ setIntText(mFortTempModEditText, mCharacter.getSaveSet().getSave(0).getTempMod());
+ }
+
+ public void updateRefSaveViews() {
+ setIntText(mRefTextView, mCharacter.getSaveSet().getSave(1).getTotal());
+ setIntText(mRefBaseEditText, mCharacter.getSaveSet().getSave(1).getBase());
+ setIntText(mRefAbilityModEditText, mCharacter.getSaveSet().getSave(1).getAbilityMod());
+ setIntText(mRefMagicModEditText, mCharacter.getSaveSet().getSave(1).getMagicMod());
+ setIntText(mRefMiscModEditText, mCharacter.getSaveSet().getSave(1).getMiscMod());
+ setIntText(mRefTempModEditText, mCharacter.getSaveSet().getSave(1).getTempMod());
+ }
+
+ public void updateWillSaveViews() {
+ setIntText(mWillTextView, mCharacter.getSaveSet().getSave(2).getTotal());
+ setIntText(mWillBaseEditText, mCharacter.getSaveSet().getSave(2).getBase());
+ setIntText(mWillAbilityModEditText, mCharacter.getSaveSet().getSave(2).getAbilityMod());
+ setIntText(mWillMagicModEditText, mCharacter.getSaveSet().getSave(2).getMagicMod());
+ setIntText(mWillMiscModEditText, mCharacter.getSaveSet().getSave(2).getMiscMod());
+ setIntText(mWillTempModEditText, mCharacter.getSaveSet().getSave(2).getTempMod());
+ }
+
+ /**
+ *
+ * @param editText
+ * @return the value in the edit text. Returns Integer.MAX_VALUE if the parse failed
+ */
+ public int getEditTextInt(EditText editText){
+ try{
+ return Integer.parseInt(editText.getText().toString());
+ }catch (NumberFormatException e){
+ return 0;
+ }
+ }
+
+ //Sets edittext listeners
+ public void setEditTextListeners(EditText editText){
+ editText.setOnFocusChangeListener(this);
+ editText.setOnEditorActionListener(this);
+ }
+
+ // Sets up all the text and edit texts
+ public void setupViews(View fragmentView) {
+ mCurrentHPTextView = (TextView) fragmentView
+ .findViewById(R.id.textViewCurrentHP);
+ mTotalHPEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextTotalHP);
+ setEditTextListeners(mTotalHPEditText);
+
+ mDamageReductEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextDamageReduction);
+ setEditTextListeners(mDamageReductEditText);
+
+ mWoundsEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextWounds);
+ setEditTextListeners(mWoundsEditText);
+
+ mNonLethalDmgEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextNonLethalDmg);
+ setEditTextListeners(mNonLethalDmgEditText);
+
+ mBaseSpeedEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextBaseSpeed);
+ setEditTextListeners(mBaseSpeedEditText);
+
+ mInitTextView = (TextView) fragmentView
+ .findViewById(R.id.textViewInitiative);
+ mInitDexEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextInitDexMod);
+ setEditTextListeners(mInitDexEditText);
+
+ mInitMiscEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextInitMiscMod);
+ setEditTextListeners(mInitMiscEditText);
+
+ mACTextView = (TextView) fragmentView.findViewById(R.id.textViewAC);
+ mArmourBonusEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextArmourBonus);
+ setEditTextListeners(mArmourBonusEditText);
+
+ mShieldBonusEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextShieldBonus);
+ setEditTextListeners(mShieldBonusEditText);
+
+ mACDexEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextACDexMod);
+ setEditTextListeners(mACDexEditText);
+
+ mACSizeEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextACSizeMod);
+ setEditTextListeners(mACSizeEditText);
+
+ mNaturalArmourEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextNaturalArmour);
+ setEditTextListeners(mNaturalArmourEditText);
+
+ mDeflectEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextDeflectionMod);
+ setEditTextListeners(mDeflectEditText);
+
+ mACMiscEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextACMiscMod);
+ setEditTextListeners(mACMiscEditText);
+
+ mACTouchTextView = (TextView) fragmentView
+ .findViewById(R.id.textViewTouchAC);
+ mACFFTextView = (TextView) fragmentView
+ .findViewById(R.id.textViewFlatFootedAC);
+ mSpellResistEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextSpellResist);
+ setEditTextListeners(mSpellResistEditText);
+
+
+ mBABPrimaryEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextBABPrimary);
+ setEditTextListeners(mBABPrimaryEditText);
+
+ mBABSecondaryEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextBABSecondary);
+ setEditTextListeners(mBABSecondaryEditText);
+
+ mCMBTextView = (TextView) fragmentView.findViewById(R.id.textViewCMB);
+ mCmbBABEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextCmbBAB);
+ setEditTextListeners(mCmbBABEditText);
+
+ mCMBStrengthEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextCMBStrengthMod);
+ setEditTextListeners(mCMBStrengthEditText);
+
+ mCMBSizeEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextCMBSizeMod);
+ setEditTextListeners(mCMBSizeEditText);
+
+ mCMDTextView = (TextView) fragmentView.findViewById(R.id.textViewCMD);
+ mCMDDexEditText = (EditText) fragmentView
+ .findViewById(R.id.editTextCMDDex);
+ setEditTextListeners(mCMDDexEditText);
+
+ mFortTextView = (TextView) fragmentView.findViewById(R.id.tvFort);
+ mFortBaseEditText = (EditText) fragmentView.findViewById(R.id.etSaveFortBase);
+ mFortAbilityModEditText = (EditText) fragmentView.findViewById(R.id.etSaveFortAbilityMod);
+ mFortMagicModEditText = (EditText) fragmentView.findViewById(R.id.etSaveFortMagicMod);
+ mFortMiscModEditText = (EditText) fragmentView.findViewById(R.id.etSaveFortMiscMod);
+ mFortTempModEditText = (EditText) fragmentView.findViewById(R.id.etSaveFortTempMod);
+ setEditTextListeners(mFortBaseEditText);
+ setEditTextListeners(mFortAbilityModEditText);
+ setEditTextListeners(mFortMagicModEditText);
+ setEditTextListeners(mFortMiscModEditText);
+ setEditTextListeners(mFortTempModEditText);
+
+ mRefTextView = (TextView) fragmentView.findViewById(R.id.tvRef);
+ mRefBaseEditText = (EditText) fragmentView.findViewById(R.id.etSaveRefBase);
+ mRefAbilityModEditText = (EditText) fragmentView.findViewById(R.id.etSaveRefAbilityMod);
+ mRefMagicModEditText = (EditText) fragmentView.findViewById(R.id.etSaveRefMagicMod);
+ mRefMiscModEditText = (EditText) fragmentView.findViewById(R.id.etSaveRefMiscMod);
+ mRefTempModEditText = (EditText) fragmentView.findViewById(R.id.etSaveRefTempMod);
+ setEditTextListeners(mRefBaseEditText);
+ setEditTextListeners(mRefAbilityModEditText);
+ setEditTextListeners(mRefMagicModEditText);
+ setEditTextListeners(mRefMiscModEditText);
+ setEditTextListeners(mRefTempModEditText);
+
+ mWillTextView = (TextView) fragmentView.findViewById(R.id.tvWill);
+ mWillBaseEditText = (EditText) fragmentView.findViewById(R.id.etSaveWillBase);
+ mWillAbilityModEditText = (EditText) fragmentView.findViewById(R.id.etSaveWillAbilityMod);
+ mWillMagicModEditText = (EditText) fragmentView.findViewById(R.id.etSaveWillMagicMod);
+ mWillMiscModEditText = (EditText) fragmentView.findViewById(R.id.etSaveWillMiscMod);
+ mWillTempModEditText = (EditText) fragmentView.findViewById(R.id.etSaveWillTempMod);
+ setEditTextListeners(mWillBaseEditText);
+ setEditTextListeners(mWillAbilityModEditText);
+ setEditTextListeners(mWillMagicModEditText);
+ setEditTextListeners(mWillMiscModEditText);
+ setEditTextListeners(mWillTempModEditText);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateAllViews();
+ }
+
+ @Override
+ public void onPause() {
+ updateHP();
+ updateSpeed();
+ updateInitiative();
+ updateAC();
+ updateBAB();
+ updateCombatManeuvers();
+ updateSaves();
+
+ super.onPause();
+ }
+
+
+ /**
+ * Updates the view which has finished being edited
+ * @param viewID
+ */
+ public void finishedEditing(int viewID){
+ if(viewID == mWoundsEditText.getId() || viewID == mTotalHPEditText.getId()
+ || viewID == mNonLethalDmgEditText.getId() || viewID == mDamageReductEditText.getId())
+ updateHP();
+
+ else if(viewID == mBaseSpeedEditText.getId())
+ updateSpeed();
+
+ else if(viewID == mInitDexEditText.getId() || viewID == mInitMiscEditText.getId())
+ updateInitiative();
+
+ else if(viewID == mArmourBonusEditText.getId() || viewID == mShieldBonusEditText.getId()
+ || viewID == mACDexEditText.getId() || viewID == mACSizeEditText.getId()
+ || viewID == mNaturalArmourEditText.getId() || viewID == mDeflectEditText.getId()
+ || viewID ==mACMiscEditText.getId() || viewID == mSpellResistEditText.getId()){
+ updateAC();
+ updateCombatManeuverViews();
+ }
+
+ else if(viewID == mBABPrimaryEditText.getId() || viewID == mBABSecondaryEditText.getId())
+ updateBAB();
+
+ else if(viewID == mCmbBABEditText.getId() || viewID == mCMBStrengthEditText.getId()
+ || viewID == mCMDDexEditText.getId() || viewID == mCMBSizeEditText.getId()){
+ updateCombatManeuvers();
+ updateACViews();
+ }
+
+ else if(viewID == mFortBaseEditText.getId() || viewID == mFortAbilityModEditText.getId()
+ || viewID == mFortMagicModEditText.getId() || viewID == mFortMiscModEditText.getId()
+ || viewID == mFortTempModEditText.getId()) {
+ updateFort();
+ updateFortSaveViews();
+ }
+
+ else if(viewID == mRefBaseEditText.getId() || viewID == mRefAbilityModEditText.getId()
+ || viewID == mRefMagicModEditText.getId() || viewID == mRefMiscModEditText.getId()
+ || viewID == mRefTempModEditText.getId()) {
+ updateRef();
+ updateRefSaveViews();
+ }
+
+ else if(viewID == mWillBaseEditText.getId() || viewID == mWillAbilityModEditText.getId()
+ || viewID == mWillMagicModEditText.getId() || viewID == mWillMiscModEditText.getId()
+ || viewID == mWillTempModEditText.getId()) {
+ updateWill();
+ updateWillSaveViews();
+ }
+
+ }
+
+ public void onFocusChange(View view, boolean hasFocus) {
+ if(!hasFocus){
+ finishedEditing(view.getId());
+ }
+ }
+
+ public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
+ finishedEditing(view.getId());
+ return false;
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFeatList.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFeatList.java
new file mode 100644
index 0000000..66b5e61
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFeatList.java
@@ -0,0 +1,121 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import java.util.ArrayList;
+
+import android.util.Log;
+
+public class PTCharacterFeatList {
+ private ArrayList mFeats;
+
+ public PTCharacterFeatList(){
+ mFeats = new ArrayList();
+
+ //addFeat(new PTFeat("Sample Feat/Special Ability", "Add useful information here."));
+
+ }
+
+ /**
+ * adds the feat to the list, if there is no feat by the same name
+ * @param newFeat
+ */
+ public void addFeat(PTFeat newFeat){
+ if( newFeat != null ){
+ //If the feat already exists do nothing
+ int i = getIndexOf(newFeat.getName());
+ if(i >= 0){
+ return;
+ }
+
+ for(i = 0; i < mFeats.size(); i++){
+ //Places in alphabetical position
+ if(newFeat.getName().compareToIgnoreCase(getFeat(i).getName()) < 0 ){
+ mFeats.add(i, newFeat);
+ return;
+ }
+ }
+ //If item is to go at the end of the list
+ mFeats.add(newFeat);
+ }
+ }
+
+ /**
+ * Deletes the feat at index.
+ * @param index
+ */
+ public void deleteFeat(int index){
+ if(index >= 0 && index < mFeats.size())
+ mFeats.remove(index);
+ }
+
+ /**
+ * Warning: list will become unsorted if the name is changed.
+ * @param index
+ * @return the feat at index
+ */
+ public PTFeat getFeat(int index){
+ if(index >= 0 && index < mFeats.size())
+ return mFeats.get(index);
+ else return null;
+ }
+
+ /**
+ * Replaces the feat at index with newFeat. If index is outside the bounds of this, or null, it will do nothing. Resorts the list alphabetically
+ * @param newFeat
+ * @param index
+ */
+ public void setFeat(PTFeat newFeat, int index){
+ if(index >= 0 && index < mFeats.size() && newFeat != null){
+ deleteFeat(index);
+ addFeat(newFeat);
+ }
+ }
+
+ /**
+ * returns an array of all the feats in the list
+ * @return an array of PTFeat objects
+ */
+ public PTFeat[] getFeats(){
+ return mFeats.toArray(new PTFeat[mFeats.size()]);
+ }
+
+ /**
+ * returns an array of all the feats names in the list
+ * @return an array of PTFeat objects
+ */
+ public String[] getFeatNames(){
+ String[] featNames = new String[mFeats.size()];
+ for(int i = 0; i < mFeats.size(); i++){
+ featNames[i] = new String(mFeats.get(i).getName());
+ }
+ return featNames;
+ }
+
+ /**
+ * Sets the description of the feat at index
+ * @param index
+ * @param quantity
+ */
+ public void setDescription(int index, String description){
+ if(index >= 0 && index < mFeats.size() && description != null)
+ mFeats.get(index).setDescription(description);
+ }
+
+
+ /**
+ *
+ * @param featName
+ * @return the index of the object with itemName. returns -1 if the item is not in the inventory.
+ */
+ public int getIndexOf(String featName){
+ for(int i = 0; i < mFeats.size(); i++){
+ if(featName.contentEquals(mFeats.get(i).getName())){
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int getNumberOfFeats(){
+ return mFeats.size();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFeatsFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFeatsFragment.java
new file mode 100644
index 0000000..034b920
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFeatsFragment.java
@@ -0,0 +1,177 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.inputmethod.InputMethodManager;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+
+public class PTCharacterFeatsFragment extends PTCharacterSheetFragment implements
+OnClickListener, OnItemClickListener, android.content.DialogInterface.OnClickListener {
+
+ final String TAG = "PTCharacterFeatsFragment";
+ private ListView mFeatsListView;
+ private Button mAddButton;
+
+ private EditText mDialogFeatNameEditText;
+ private EditText mDialogFeatDescEditText;
+
+ private ViewGroup mContainer;
+
+ private int mFeatSelectedForEdit;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ mContainer = container;
+
+ View fragmentView = inflater.inflate(R.layout.character_feats_fragment, container, false);
+
+ mAddButton = (Button) fragmentView.findViewById(R.id.buttonAddFeat);
+ mAddButton.setOnClickListener(this);
+
+ mFeatsListView = (ListView) fragmentView.findViewById(R.id.listViewFeats);
+ refreshFeatsListView();
+ mFeatsListView.setOnItemClickListener(this);
+
+ return fragmentView;
+ }
+
+
+ private void refreshFeatsListView(){
+ String[] featNames = mCharacter.getFeatList().getFeatNames();
+ ArrayAdapter adapter = new ArrayAdapter(mContainer.getContext(), android.R.layout.simple_list_item_1, featNames);
+ mFeatsListView.setAdapter(adapter);
+
+ }
+
+ //Add Feat button was tapped
+ public void onClick(View button) {
+ mFeatSelectedForEdit = -1;
+ showFeatDialog(null);
+
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mFeatSelectedForEdit = position;
+ showFeatDialog(mCharacter.getFeatList().getFeat(position));
+
+ }
+
+ /**
+ * Shows a dialog to add or edit a feat.
+ * @param item
+ */
+ private void showFeatDialog(PTFeat feat) {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ //Set up dialog layout
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.character_feats_dialog, null);
+ mDialogFeatNameEditText = (EditText) dialogView.findViewById(R.id.etDialogFeatName);
+ mDialogFeatDescEditText = (EditText) dialogView.findViewById(R.id.etDialogFeatDescription);
+
+ //Determine if add or edit
+ if(mFeatSelectedForEdit < 0){
+ builder.setTitle("Add New Feat");
+ }
+ else{
+ builder.setTitle("Edit/View Feat")
+ .setNeutralButton(R.string.delete_button_text, this);
+ mDialogFeatNameEditText.setText(feat.getName());
+ mDialogFeatDescEditText.setText(feat.getDescription());
+
+ }
+
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ //OK button tapped
+ case DialogInterface.BUTTON_POSITIVE:
+
+ if(mFeatSelectedForEdit < 0){
+ PTFeat newFeat = getFeatFromDialog();
+ if(newFeat != null){
+ mCharacter.getFeatList().addFeat(newFeat);
+ refreshFeatsListView();
+ }
+ }
+ else{
+ PTFeat editedFeat = getFeatFromDialog();
+ mCharacter.getFeatList().setFeat(editedFeat, mFeatSelectedForEdit);
+ refreshFeatsListView();
+ }
+
+ break;
+ //Cancel Button tapped
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ //Delete Button tapped
+ case DialogInterface.BUTTON_NEUTRAL:
+ mCharacter.getFeatList().deleteFeat(mFeatSelectedForEdit);
+ refreshFeatsListView();
+ default:
+ break;
+ }
+
+ //Close keyboard
+ InputMethodManager iMM = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if(mDialogFeatNameEditText.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogFeatNameEditText.getWindowToken(), 0);
+ else if(mDialogFeatDescEditText.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogFeatDescEditText.getWindowToken(), 0);
+
+ }
+
+
+ private PTFeat getFeatFromDialog() {
+ String name = new String(mDialogFeatNameEditText.getText().toString());
+ if(name == null || name.contentEquals("")){
+ return null;
+ }
+
+ String description = new String(mDialogFeatDescEditText.getText().toString());
+
+ return new PTFeat(name, description);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ refreshFeatsListView();
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFluffFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFluffFragment.java
new file mode 100644
index 0000000..e02efcb
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFluffFragment.java
@@ -0,0 +1,131 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.EditText;
+import android.widget.ListView;
+
+import com.lateensoft.pathfinder.toolkit.PTCharacterSheetActivity;
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTCharacterFluffFragment extends PTCharacterSheetFragment implements
+OnItemClickListener, android.content.DialogInterface.OnClickListener{
+ final String TAG = "PTCharacterFluffFragment";
+ private ListView lv;
+ int mFluffSelectedForEdit;
+
+ private EditText mDialogFluff;
+
+ private ViewGroup mContainer;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ mContainer = container;
+ /*Resources r = getActivity().getBaseContext().getResources();
+
+ String[] tempValues = new String[r.getStringArray(R.array.fluff_fields).length];
+ tempValues = r.getStringArray(R.array.fluff_fields);*/
+
+ View view = inflater.inflate(R.layout.character_fluff_fragment, container, false);
+
+ lv = (ListView) view.findViewById(R.id.fluff_list);
+ refreshFluffListView();
+ lv.setOnItemClickListener(this);
+
+ return view;
+ }
+
+ //An items has been clicked in the list
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mFluffSelectedForEdit = position;
+ showItemDialog(position);
+ }
+
+ /**
+ * Shows a dialog to edit fluff field.
+ * @param item
+ */
+ private void showItemDialog(int fluffIndex) {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ //Set up dialog layout
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.character_fluff_dialog, null);
+ mDialogFluff = (EditText) dialogView.findViewById(R.id.dialogFluffText);
+
+ builder.setTitle(mCharacter.getFluff().getFluffFields(getActivity())[fluffIndex]);
+ mDialogFluff.setText(mCharacter.getFluff().getFluffArray()[fluffIndex]);
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ private void refreshFluffListView() {
+ PTFluffAdapter adapter = new PTFluffAdapter(mContainer.getContext(),
+ R.layout.character_fluff_row,
+ mCharacter.getFluff().getFluffArray());
+ lv.setAdapter(adapter);
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ //OK button tapped
+ case DialogInterface.BUTTON_POSITIVE:
+
+ mCharacter.getFluff().setFluffByIndex(mFluffSelectedForEdit,
+ getFluffValueFromDialog());
+ ((PTCharacterSheetActivity)getActivity()).updateCharacterDatabase();
+ refreshFluffListView();
+
+
+ break;
+ //Cancel Button tapped
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ default:
+ break;
+ }
+
+ //Close keyboard
+ InputMethodManager iMM = (InputMethodManager)getActivity().
+ getSystemService(Context.INPUT_METHOD_SERVICE);
+ if(mDialogFluff.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogFluff.getWindowToken(), 0);
+ }
+
+ private String getFluffValueFromDialog() {
+ String fluffValue = new String(mDialogFluff.getText().toString());
+ return fluffValue;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ refreshFluffListView();
+ }
+
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFluffInfo.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFluffInfo.java
new file mode 100644
index 0000000..bd0525e
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterFluffInfo.java
@@ -0,0 +1,215 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+public class PTCharacterFluffInfo {
+ String mName;
+ String mAlignment;
+ String mXP;
+ String mNextLevelXP;
+ String mXPChange;
+ String mPlayerClass;
+ String mRace;
+ String mDeity;
+ String mLevel;
+ String mSize;
+ String mGender;
+ String mHeight;
+ String mWeight;
+ String mEyes;
+ String mHair;
+ String mLanguages;
+ String mDescription;
+
+ public String[] getFluffArray() {
+ String[] fluffArray = {mName, mAlignment, mXP, mNextLevelXP, mPlayerClass, mRace, mDeity,
+ mLevel, mSize, mGender, mHeight, mWeight, mEyes, mHair, mLanguages, mDescription};
+ return fluffArray;
+ }
+
+ public void setFluffByIndex(int index, String fluffValue) {
+ switch (index) {
+ case 0:
+ mName = fluffValue;
+ break;
+ case 1:
+ mAlignment = fluffValue;
+ break;
+ case 2:
+ mXP = fluffValue;
+ break;
+ case 3:
+ mNextLevelXP = fluffValue;
+ break;
+ case 4:
+ mPlayerClass = fluffValue;
+ break;
+ case 5:
+ mRace = fluffValue;
+ break;
+ case 6:
+ mDeity = fluffValue;
+ break;
+ case 7:
+ mLevel = fluffValue;
+ break;
+ case 8:
+ mSize = fluffValue;
+ break;
+ case 9:
+ mGender = fluffValue;
+ break;
+ case 10:
+ mHeight = fluffValue;
+ break;
+ case 11:
+ mWeight = fluffValue;
+ break;
+ case 12:
+ mEyes = fluffValue;
+ break;
+ case 13:
+ mHair = fluffValue;
+ break;
+ case 14:
+ mLanguages = fluffValue;
+ break;
+ case 15:
+ mDescription = fluffValue;
+ break;
+ }
+ }
+
+ public String[] getFluffFields(Context context) {
+ Resources r = context.getResources();
+
+ return r.getStringArray(R.array.fluff_fields);
+ }
+
+ public PTCharacterFluffInfo() {
+ mName = "";
+ mAlignment = "";
+ mXP = "";
+ mNextLevelXP = "";
+ mXPChange = "";
+ mPlayerClass = "";
+ mRace = "";
+ mDeity = "";
+ mLevel = "";
+ mSize = "";
+ mGender = "";
+ mHeight = "";
+ mWeight = new String("");
+ mEyes = new String("");
+ mHair = new String("");
+ mLanguages = new String("");
+ mDescription = new String("");
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public String getAlignment() {
+ return mAlignment;
+ }
+
+ public void setAlignment(String alignment) {
+ mAlignment = alignment;
+ }
+
+ public String getXP() {
+ return mXP;
+ }
+
+ public void setXp(String XP) {
+ mXP = XP;
+ }
+
+ public String getXPChange() {
+ return mXPChange;
+ }
+
+ public void setXPChange(String XPChange) {
+ mXPChange = XPChange;
+ }
+
+ public String getPlayerClass() {
+ return mPlayerClass;
+ }
+
+ public void setPlayerClass(String playerClass) {
+ mPlayerClass = playerClass;
+ }
+
+ public String getRace() {
+ return mRace;
+ }
+
+ public String getDeity() {
+ return mDeity;
+ }
+
+ public void setDeity(String deity) {
+ mDeity = deity;
+ }
+
+ public String getLevel() {
+ return mLevel;
+ }
+
+ public void setLevel(String level) {
+ mLevel = level;
+ }
+
+ public String getGender() {
+ return mGender;
+ }
+
+ public void setGender(String gender) {
+ mGender = gender;
+ }
+
+ public String getHeight() {
+ return mHeight;
+ }
+
+ public void setHeight(String height) {
+ mHeight = height;
+ }
+
+ public String getWeight() {
+ return mWeight;
+ }
+
+ public void setWeight(String weight) {
+ mWeight = weight;
+ }
+
+ public String getEyes() {
+ return mEyes;
+ }
+
+ public void setEyes(String eyes) {
+ mEyes = eyes;
+ }
+
+ public String getHair() {
+ return mHair;
+ }
+
+ public void setHair(String hair) {
+ mHair = hair;
+ }
+
+ public void setRace(String race) {
+ mRace = race;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterInventory.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterInventory.java
new file mode 100644
index 0000000..198a6e3
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterInventory.java
@@ -0,0 +1,238 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import java.util.ArrayList;
+
+import com.lateensoft.pathfinder.toolkit.items.PTArmor;
+import com.lateensoft.pathfinder.toolkit.items.PTItem;
+import com.lateensoft.pathfinder.toolkit.items.PTWeapon;
+
+public class PTCharacterInventory {
+ private ArrayList mItems;
+ private ArrayList mArmor;
+ private ArrayList mWeapons;
+
+ PTCharacterInventory(){
+ mItems = new ArrayList();
+ mArmor = new ArrayList();
+ mWeapons = new ArrayList();
+
+ //For new inventory, give user sample items
+ addItem(new PTItem("Sample Item", 10, 1, false));
+ addItem(new PTItem("Contained Item (ex. In bag of holding)", 30, 1, true));
+
+ }
+
+ /**
+ * Adds the item into the inventory. It is placed such that the list is alphabetically listed.
+ * @param newItem
+ */
+ public void addItem(PTItem newItem){
+ if( newItem != null ){
+ //If the item already exists in inventory, add to its quantity
+ int i = getIndexOf(newItem.getName());
+ if(i >= 0){
+ int quantity = newItem.getQuantity() + getItem(i).getQuantity();
+ setQuantity(i, quantity);
+ return;
+ }
+
+ for(i = 0; i < mItems.size(); i++){
+ //Places in alphabetical position
+ if(newItem.getName().compareToIgnoreCase(getItem(i).getName()) < 0 ){
+ mItems.add(i, newItem);
+ return;
+ }
+ }
+ //If item is to go at the end of the list
+ mItems.add(newItem);
+ }
+ }
+
+ public void addArmor(PTArmor newArmor) {
+ if( newArmor != null ){
+
+ mArmor.add(newArmor);
+ }
+ }
+
+ public void addWeapon(PTWeapon newWeapon) {
+ if( newWeapon != null ){
+
+ mWeapons.add(newWeapon);
+ }
+ }
+
+ /**
+ * Deletes the item at index.
+ * @param index
+ */
+ public void deleteItem(int index){
+ if(index >= 0 && index < mItems.size())
+ mItems.remove(index);
+ }
+
+ public void deleteArmor(int index) {
+ if(index >=0 && index < mArmor.size())
+ mArmor.remove(index);
+ }
+
+ public void deleteWeapon(int index) {
+ if(index >= 0 && index < mWeapons.size())
+ mWeapons.remove(index);
+ }
+
+ /**
+ *
+ * @param index
+ * @return the item at index
+ */
+ public PTItem getItem(int index){
+ if(index >= 0 && index < mItems.size())
+ return mItems.get(index);
+ else return null;
+ }
+
+ public PTArmor getArmor(int index) {
+ if(index>= 0 && index < mArmor.size())
+ return mArmor.get(index);
+ else return null;
+ }
+
+ public PTWeapon getWeapon(int index) {
+ if(index >= 0 && index < mWeapons.size())
+ return mWeapons.get(index);
+ else return null;
+ }
+
+ /**
+ *
+ * @return new array of armor
+ */
+ public PTArmor[] getArmorArray() {
+ PTArmor[] armorArray = new PTArmor[mArmor.size()];
+ return (PTArmor[]) mArmor.toArray(armorArray);
+ }
+
+ public PTWeapon[] getWeaponArray() {
+ PTWeapon[] weaponArray = new PTWeapon[mWeapons.size()];
+ return (PTWeapon[]) mWeapons.toArray(weaponArray);
+ }
+
+ /**
+ * Replaces the item at index with newItem. If index is outside the bounds of this, or null, it will do nothing. Resorts the inventory alphabetically
+ * @param newItem
+ * @param index
+ */
+ public void setItem(PTItem newItem, int index){
+ if(index >= 0 && index < mItems.size() && newItem != null){
+ deleteItem(index);
+ addItem(newItem);
+ }
+ }
+
+ public void setArmor(PTArmor newArmor, int index) {
+ if(index >= 0 && index < mArmor.size() && newArmor != null) {
+ deleteArmor(index);
+ addArmor(newArmor);
+ }
+ }
+
+ public void setWeapon(PTWeapon newWeapon, int index) {
+ if(index >= 0 && index < mWeapons.size() && newWeapon != null) {
+ deleteWeapon(index);
+ addWeapon(newWeapon);
+ }
+ }
+
+ /**
+ * returns an array of all the objects in the inventory
+ * @return an array of PTItem objects
+ */
+ public PTItem[] getItems(){
+ return mItems.toArray(new PTItem[mItems.size()]);
+ }
+
+ /**
+ * Sets the weight of the item at index
+ * @param index
+ * @param weight
+ */
+ public void setWeight(int index, int weight){
+ if(index >= 0 && index < mItems.size())
+ mItems.get(index).setWeight(weight);
+ }
+
+ /**
+ * Sets the quantity of the item at index
+ * @param index
+ * @param quantity
+ */
+ public void setQuantity(int index, int quantity){
+ if(index >= 0 && index < mItems.size())
+ mItems.get(index).setQuantity(quantity);
+ }
+
+ /**
+ * Sets the item flag of the item at index if it is contained by another container
+ * @param index
+ * @param isContained
+ */
+ public void setContained(int index, boolean isContained){
+ if(index >= 0 && index < mItems.size())
+ mItems.get(index).setIsContained(isContained);
+ }
+
+ /**
+ *
+ * @param itemName
+ * @return the index of the object with itemName. returns -1 if the item is not in the inventory.
+ */
+ public int getIndexOf(String itemName){
+ for(int i = 0; i < mItems.size(); i++){
+ if(itemName.contentEquals(mItems.get(i).getName())){
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int getIndexOfArmor(String itemName){
+ for(int i = 0; i < mArmor.size(); i++){
+ if(itemName.contentEquals(mArmor.get(i).getName())){
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int getNumberOfItems(){
+ return mItems.size();
+ }
+
+ public int getNumberOfArmor() {
+ return mArmor.size();
+ }
+
+ public int getNumberofWeapons() {
+ return mWeapons.size();
+ }
+
+ public int getTotalWeight() {
+ int totalWeight = 0;
+ for(int i = 0; i < mItems.size(); i++) {
+ if(!mItems.get(i).isContained())
+ totalWeight += (mItems.get(i).getWeight())*(mItems.get(i).getQuantity());
+ }
+ for(int i = 0; i < mWeapons.size(); i++) {
+ if(!mWeapons.get(i).isContained())
+ totalWeight += (mWeapons.get(i).getWeight())*(mWeapons.get(i).getQuantity());
+ }
+ for(int i = 0; i < mArmor.size(); i++) {
+ if(!mArmor.get(i).isContained())
+ totalWeight += (mArmor.get(i).getWeight())*(mArmor.get(i).getQuantity());
+ }
+
+ return totalWeight;
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterInventoryFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterInventoryFragment.java
new file mode 100644
index 0000000..828b3ba
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterInventoryFragment.java
@@ -0,0 +1,244 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.items.PTItem;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class PTCharacterInventoryFragment extends PTCharacterSheetFragment implements OnItemClickListener, OnClickListener, android.content.DialogInterface.OnClickListener, OnFocusChangeListener{
+ final String TAG = "PTCharacterInventoryFragment";
+ private ListView mItemsListView;
+ private Button mAddButton;
+ private EditText mGoldEditText;
+ private TextView mTotalWeightText;
+
+ private EditText mDialogItemNameEditText;
+ private EditText mDialogItemQuantityEditText;
+ private EditText mDialogItemWeightEditText;
+ private CheckBox mDialogItemContainedCheckbox;
+
+ private ViewGroup mContainer;
+
+ private int mItemSelectedForEdit;
+ private View mDummyView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ mContainer = container;
+
+ View fragmentView = inflater.inflate(R.layout.character_inventory_fragment,
+ container, false);
+
+ mDummyView = (View) fragmentView.findViewById(R.id.dummyView);
+
+ mAddButton = (Button) fragmentView.findViewById(R.id.buttonAddItem);
+ mAddButton.setOnClickListener(this);
+
+ mGoldEditText = (EditText) fragmentView.findViewById(R.id.editTextGold);
+ mGoldEditText.setOnFocusChangeListener(this);
+ mGoldEditText.setText(Double.toString(mCharacter.mGold));
+
+ mTotalWeightText = (TextView) fragmentView.findViewById(R.id.tvWeightTotal);
+ updateTotalWeight();
+
+ mItemsListView = (ListView) fragmentView.findViewById(R.id.listViewInventory);
+ refreshItemsListView();
+ mItemsListView.setOnItemClickListener(this);
+
+ return fragmentView;
+ }
+
+
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mDummyView.requestFocus();
+ refreshItemsListView();
+ mGoldEditText.setText(Double.toString(mCharacter.mGold));
+ }
+
+ @Override
+ public void onPause() {
+ mCharacter.mGold = Double.parseDouble(mGoldEditText.getText().toString());
+ /*InputMethodManager iMM = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ iMM.hideSoftInputFromInputMethod(mGoldEditText.getWindowToken(), 0);*/
+ super.onPause();
+ }
+
+ private void refreshItemsListView(){
+ PTItem[] items = mCharacter.getInventory().getItems();
+
+ PTInventoryAdapter adapter = new PTInventoryAdapter(mContainer.getContext(), R.layout.character_inventory_row, items);
+ mItemsListView.setAdapter(adapter);
+
+
+
+ }
+
+ private void updateTotalWeight(){
+ int totalWeight = mCharacter.getInventory().getTotalWeight();
+
+ mTotalWeightText.setText(getActivity().getString(R.string.inventory_total_weight_header)
+ +" "+ totalWeight);
+ }
+
+ //An items has been clicked in the list
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mItemSelectedForEdit = position;
+ showItemDialog(mCharacter.getInventory().getItem(position));
+ }
+
+ //The add button was clicked
+ public void onClick(View view) {
+ mItemSelectedForEdit = -1;
+ showItemDialog(null);
+ }
+
+
+ /**
+ * Shows a dialog to add or edit an item.
+ * @param item
+ */
+ private void showItemDialog(PTItem item) {
+
+ mDummyView.requestFocus();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ //Set up dialog layout
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.character_inventory_dialog, null);
+ mDialogItemNameEditText = (EditText) dialogView.findViewById(R.id.etDialogItemName);
+ mDialogItemQuantityEditText = (EditText) dialogView.findViewById(R.id.etDialogItemQuantity);
+ mDialogItemWeightEditText = (EditText) dialogView.findViewById(R.id.etDialogItemWeight);
+ mDialogItemContainedCheckbox = (CheckBox) dialogView.findViewById(R.id.checkboxDialogItemContained);
+
+ //Determine if add or edit
+ if(mItemSelectedForEdit < 0){
+ builder.setTitle("Add Item");
+ }
+ else{
+ builder.setTitle("Edit Item")
+ .setNeutralButton(R.string.delete_button_text, this);
+ mDialogItemNameEditText.setText(item.getName());
+ mDialogItemQuantityEditText.setText(Integer.toString(item.getQuantity()));
+ mDialogItemWeightEditText.setText(Integer.toString(item.getWeight()));
+ mDialogItemContainedCheckbox.setChecked(item.isContained());
+ }
+
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ // Click method for the character selection dialog
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ //OK button tapped
+ case DialogInterface.BUTTON_POSITIVE:
+
+ if(mItemSelectedForEdit < 0){
+ PTItem newItem = getItemFromDialog();
+ if(newItem != null){
+ mCharacter.getInventory().addItem(newItem);
+ refreshItemsListView();
+ updateTotalWeight();
+ }
+ }
+ else{
+ PTItem editedItem = getItemFromDialog();
+ mCharacter.getInventory().setItem(editedItem, mItemSelectedForEdit);
+ refreshItemsListView();
+ updateTotalWeight();
+ }
+
+ break;
+ //Cancel Button tapped
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+ //Delete Button tapped
+ case DialogInterface.BUTTON_NEUTRAL:
+ mCharacter.getInventory().deleteItem(mItemSelectedForEdit);
+ refreshItemsListView();
+ updateTotalWeight();
+ default:
+ break;
+
+ }
+
+ //Close keyboard
+ InputMethodManager iMM = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if(mDialogItemNameEditText.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogItemNameEditText.getWindowToken(), 0);
+ else if(mDialogItemWeightEditText.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogItemWeightEditText.getWindowToken(), 0);
+ else if(mDialogItemQuantityEditText.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogItemQuantityEditText.getWindowToken(), 0);
+ }
+
+
+ //Retrieves a PTItem from the open dialog
+ private PTItem getItemFromDialog(){
+ String name = new String(mDialogItemNameEditText.getText().toString());
+ if(name == null || name.contentEquals("")){
+ return null;
+ }
+
+ int quantity;
+ try{
+ quantity = (int)Double.parseDouble(mDialogItemQuantityEditText.getText().toString());
+ }catch (NumberFormatException e){
+ quantity = 1;
+ }
+
+ int weight;
+ try{
+ weight = (int)Double.parseDouble(mDialogItemWeightEditText.getText().toString());
+ }catch (NumberFormatException e){
+ weight = 1;
+ }
+ boolean contained = mDialogItemContainedCheckbox.isChecked();
+
+ return new PTItem(name, weight, quantity, contained);
+ }
+
+ //Gold Edit text
+ public void onFocusChange(View view, boolean isInFocus) {
+ if(!isInFocus)
+ mCharacter.mGold = Double.parseDouble(mGoldEditText.getText().toString());
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSheetFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSheetFragment.java
new file mode 100644
index 0000000..d30e262
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSheetFragment.java
@@ -0,0 +1,42 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.PTCharacterSheetActivity;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+
+//This is a base class for all fragments in the character sheet activity
+public class PTCharacterSheetFragment extends Fragment{
+ final String TAG = "PTCharacterSheetFragment";
+ public PTCharacter mCharacter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mCharacter = ((PTCharacterSheetActivity)getActivity()).getCurrentCharacter();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @Override
+ public void onPause() {
+ ((PTCharacterSheetActivity)getActivity()).updateCharacterDatabase();
+ super.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mCharacter = ((PTCharacterSheetActivity)getActivity()).getCurrentCharacter();
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSkillsFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSkillsFragment.java
new file mode 100644
index 0000000..720a5e4
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSkillsFragment.java
@@ -0,0 +1,147 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.PTSharedMenu;
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.stats.PTSkill;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.ListView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+public class PTCharacterSkillsFragment extends PTCharacterSheetFragment implements OnClickListener, OnItemClickListener{
+ final String TAG = "PTCharacterSkillsFragment";
+
+ private final int MENU_ITEM_AUTOFILL = 3;
+
+ private ListView mSkillsListView;
+
+ private Spinner mDialogSkillAbilityModSpinner;
+ private Spinner mDialogSkillRankSpinner;
+ private Spinner mDialogSkillMiscModSpinner;
+ private Spinner mDialogSkillACPSpinner;
+ private CheckBox mDialogClassSkillCheckBox;
+
+ private int mSkillSeletedForEdit;
+
+ private ViewGroup mContainer;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ mContainer = container;
+
+ View fragmentView = inflater.inflate(R.layout.character_skills_fragment, container, false);
+
+ mSkillsListView = (ListView) fragmentView.findViewById(R.id.listViewCharacterSkills);
+ PTSkillsAdapter adapter = new PTSkillsAdapter(mContainer.getContext(), R.layout.character_skill_row, mCharacter.getSkillSet());
+ mSkillsListView.setAdapter(adapter);
+ mSkillsListView.setOnItemClickListener(this);
+
+ return fragmentView;
+ }
+
+ /**
+ * Shows a dialog to edit a skill.
+ * @param item
+ */
+ private void showSkillDialog() {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ //Set up dialog layout
+ builder.setTitle("Edit Skill");
+
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.character_skills_dialog, null);
+ TextView skillInfoTextView = (TextView) dialogView.findViewById(R.id.tvDialogSkillName);
+ mDialogSkillAbilityModSpinner = (Spinner) dialogView.findViewById(R.id.spinnerSkillDialogAbility);
+ mDialogSkillRankSpinner = (Spinner) dialogView.findViewById(R.id.spinnerSkillDialogRank);
+ mDialogSkillMiscModSpinner = (Spinner) dialogView.findViewById(R.id.spinnerSkillDialogMisc);
+ mDialogSkillACPSpinner = (Spinner) dialogView.findViewById(R.id.spinnerSkillDialogACP);
+ mDialogClassSkillCheckBox = (CheckBox) dialogView.findViewById(R.id.checkboxDialogClassSkill);
+
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(
+ getActivity(), R.array.skills_selectable_values_string,
+ android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+
+ PTSkill editableSkill = mCharacter.getSkillSet().getSkill(mSkillSeletedForEdit);
+
+ skillInfoTextView.setText(editableSkill.getName()+" ("+editableSkill.getKeyAbility()+")");
+
+ setupDialogSpinner(mDialogSkillAbilityModSpinner, adapter, editableSkill.getAbilityMod());
+ setupDialogSpinner(mDialogSkillRankSpinner, adapter, editableSkill.getRank());
+ setupDialogSpinner(mDialogSkillMiscModSpinner, adapter, editableSkill.getMiscMod());
+ setupDialogSpinner(mDialogSkillACPSpinner, adapter, editableSkill.getArmorCheckPenalty());
+
+ mDialogClassSkillCheckBox.setChecked(editableSkill.isClassSkill());
+
+ builder.setView(dialogView)
+ .setPositiveButton(getString(R.string.ok_button_text), this)
+ .setNegativeButton(getString(R.string.cancel_button_text), this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ private void setupDialogSpinner(Spinner spinner,
+ ArrayAdapter adapter, int currentValue) {
+
+ spinner.setAdapter(adapter);
+ spinner.setSelection(currentValue + 10, true); // +10 is because at
+ // position 0, is value
+ // = -10
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ //OK button tapped
+ case DialogInterface.BUTTON_POSITIVE:
+ mCharacter.getSkillSet().getSkill(mSkillSeletedForEdit).setAbilityMod(mDialogSkillAbilityModSpinner.getSelectedItemPosition()-10);
+ mCharacter.getSkillSet().getSkill(mSkillSeletedForEdit).setRank(mDialogSkillRankSpinner.getSelectedItemPosition()-10);
+ mCharacter.getSkillSet().getSkill(mSkillSeletedForEdit).setMiscMod(mDialogSkillMiscModSpinner.getSelectedItemPosition()-10);
+ mCharacter.getSkillSet().getSkill(mSkillSeletedForEdit).setArmorCheckPenalty(mDialogSkillACPSpinner.getSelectedItemPosition()-10);
+ mCharacter.getSkillSet().getSkill(mSkillSeletedForEdit).setClassSkill(mDialogClassSkillCheckBox.isChecked());
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ //Do nothing
+ break;
+ }
+
+ ((PTSkillsAdapter)mSkillsListView.getAdapter()).updateList(mCharacter.getSkillSet());
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mSkillSeletedForEdit = position;
+ showSkillDialog();
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ((PTSkillsAdapter)mSkillsListView.getAdapter()).updateList(mCharacter.getSkillSet());
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSpellBookFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSpellBookFragment.java
new file mode 100644
index 0000000..c788cee
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTCharacterSpellBookFragment.java
@@ -0,0 +1,234 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.inputmethod.InputMethodManager;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+public class PTCharacterSpellBookFragment extends PTCharacterSheetFragment implements
+ OnClickListener, OnItemClickListener, android.content.DialogInterface.OnClickListener{
+
+ final String TAG = "PTCharacterSpellBookFragment";
+ private ListView mListView;
+ int mSpellSelectedForEdit;
+ private Button mAddButton;
+
+ private EditText mDialogName;
+ private Spinner mDialogLevel;
+ private Spinner mDialogPrepared;
+ private EditText mDialogDescription;
+
+ private ViewGroup mContainer;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mContainer = container;
+
+ View fragmentView = inflater.inflate(R.layout.character_spellbook_fragment,
+ container, false);
+
+ mAddButton = (Button) fragmentView.findViewById(R.id.addSpell);
+ mAddButton.setOnClickListener(this);
+
+ mListView = new ListView(container.getContext());
+ setListViews(fragmentView);
+ refreshSpellListView();
+ setonItemClickListeners();
+
+ return fragmentView;
+ }
+
+ private void setListViews(View fragmentView) {
+ /*for(int i = 0; i < spellListViewIds.length; i++) {
+ mListViews[i] = (ListView) fragmentView.findViewById(spellListViewIds[i]);
+ }*/
+ mListView = (ListView) fragmentView.findViewById(R.id.spells);
+ }
+
+ private void setonItemClickListeners() {
+ /*for(int i = 0; i < mListViews.length; i++) {
+ mListViews[i].setOnItemClickListener(this);
+ }*/
+ mListView.setOnItemClickListener(this);
+ }
+
+ /*private void refreshSpellListViews() {
+ /*for(int i = 0; i < mCharacter.getSpellBook().getNumSpellLevels(); i++) {
+ refreshSpellListView();
+ }
+ refreshSpellListView();
+ }*/
+
+ private void refreshSpellListView() {
+ /*Log.v(TAG, "Creating a SpellBookAdapter for level " + level);
+ PTSpellBookAdapter adapter = new PTSpellBookAdapter(mContainer.getContext(),
+ R.layout.character_spellbook_frow,
+ mCharacter.getSpellBook().getSpells());*/
+
+ PTSpellBookAdapter adapter = new PTSpellBookAdapter(mContainer.getContext(),
+ R.layout.character_spellbook_row,
+ mCharacter.getSpellBook().getSpells());
+
+ Log.v(TAG, "Called refreshSpellListView");
+
+ mListView.setAdapter(adapter);
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Log.v(TAG, "Item clicked: " + position);
+ mSpellSelectedForEdit = position;
+ showSpellDialog(mCharacter.getSpellBook().getSpell(position));
+ }
+
+ /**
+ * Add spell button was tapped
+ */
+ public void onClick(View v) {
+ Log.v(TAG, "Add button clicked");
+ mSpellSelectedForEdit = -1;
+ showSpellDialog(null);
+ }
+
+ private void showSpellDialog(PTSpell spell) {
+ ///PTSpell spell = new PTSpell();
+
+ //spell.setAsOtherSpell(selectedSpell);
+ //mCharacter.getSpellBook().deleteSpell(spell);
+ if(spell == null) {
+ spell = new PTSpell();
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.character_spellbook_dialog, null);
+ mDialogName = (EditText) dialogView.findViewById(R.id.spellName);
+ mDialogLevel = (Spinner) dialogView.findViewById(R.id.spellLevel);
+ mDialogPrepared = (Spinner) dialogView.findViewById(R.id.spellPrepared);
+ mDialogDescription = (EditText) dialogView.findViewById(R.id.spellDescription);
+
+ setupSpinner(mDialogLevel, 10, spell.getLevel());
+ setupSpinner(mDialogPrepared, 5, spell.getPrepared());
+
+ if(mSpellSelectedForEdit < 0) {
+ //Adding a spell
+ builder.setTitle(R.string.new_spell_title);
+ } else {
+ //Editing a spell
+ builder.setTitle(spell.getName()).setNeutralButton(R.string.delete_button_text, this);
+ mDialogName.setText(spell.getName());
+ mDialogDescription.setText(spell.getDescription());
+ mDialogLevel.setSelection(spell.getLevel());
+ mDialogPrepared.setSelection(spell.getPrepared());
+ }
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ private void setupSpinner(Spinner spinner, int options, int pos) {
+ //int[] optionArray = generateOptionArray(options);
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
+ R.array.selectable_values_string, android.R.layout.simple_spinner_item);
+
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+ spinner.setAdapter(adapter);
+ spinner.setSelection(pos, true);
+ }
+
+ private String[] generateOptionArray(int options) {
+ String[] stringOptionArray = new String[options];
+ for(int i = 0; i < options; i++) {
+ stringOptionArray[i] = Integer.toString(i);
+ }
+ return stringOptionArray;
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ PTSpell spell = getSpellFromDialog();
+
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ Log.v(TAG, "Add.edit spell OK: " + mDialogName.getText());
+ if(mSpellSelectedForEdit < 0) {
+ Log.v(TAG, "Adding a spell");
+ if(spell != null) {
+ mCharacter.getSpellBook().addSpell(spell);
+ refreshSpellListView(); //TODO: change to specific level?
+ }
+ } else {
+ Log.v(TAG, "Editing a spell");
+
+ mCharacter.getSpellBook().setSpell(mSpellSelectedForEdit, spell);
+ refreshSpellListView();
+ }
+
+ break;
+
+ case DialogInterface.BUTTON_NEUTRAL:
+ Log.v(TAG, "Deleting a spell");
+ mCharacter.getSpellBook().deleteSpell(mSpellSelectedForEdit);
+ refreshSpellListView();
+ break;
+
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+
+ default:
+ break;
+ }
+
+ //Close keyboard
+ InputMethodManager iMM = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if(mDialogName.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogName.getWindowToken(), 0);
+ else if(mDialogDescription.hasFocus())
+ iMM.hideSoftInputFromInputMethod(mDialogDescription.getWindowToken(), 0);
+ }
+
+ private PTSpell getSpellFromDialog() {
+ String name = new String(mDialogName.getText().toString());
+ if(name == null || name.contentEquals("")) {
+ return null;
+ }
+
+ String description = new String(mDialogDescription.getText().toString());
+
+ int level = mDialogLevel.getSelectedItemPosition();
+ if(level > 10 || level < 0)
+ return null;
+
+ int prepared = mDialogPrepared.getSelectedItemPosition();
+ if(prepared < 0)
+ return null;
+
+ return new PTSpell(name, level, prepared, description);
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTFeat.java b/src/com/lateensoft/pathfinder/toolkit/character/PTFeat.java
new file mode 100644
index 0000000..e065693
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTFeat.java
@@ -0,0 +1,48 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+
+/**
+ * Representation for both Feats and Special abilities
+ * @author trevsiemens
+ *
+ */
+public class PTFeat {
+ private String mName;
+ private String mDescription;
+
+ public PTFeat(){
+ mName = "";
+ mDescription = "";
+ }
+
+ public PTFeat(String name, String description){
+ mName = new String(name);
+ mDescription = new String (description);
+ }
+
+ public PTFeat(PTFeat otherFeat){
+ mName = new String(otherFeat.getName());
+ mDescription = new String (otherFeat.getDescription());
+
+ }
+
+ public void setName(String name){
+ if(name != null){
+ mName = name;
+ }
+ }
+
+ public String getName(){
+ return mName;
+ }
+
+ public void setDescription(String description){
+ if(description != null){
+ mDescription = description;
+ }
+ }
+
+ public String getDescription(){
+ return mDescription;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTFluffAdapter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTFluffAdapter.java
new file mode 100644
index 0000000..6c9cd0a
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTFluffAdapter.java
@@ -0,0 +1,59 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTFluffAdapter extends ArrayAdapter{
+ Context mContext;
+ int mLayoutResourceId;
+ String[] mFluff = null;
+ String TAG = "PTFluffAdapter";
+
+ public PTFluffAdapter(Context context, int layoutResourceId, String[] fluff) {
+ super(context, layoutResourceId, fluff);
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mFluff = fluff;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ FluffHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new FluffHolder();
+
+ holder.label = (TextView)row.findViewById(R.id.fluffLabel);
+ holder.value = (TextView)row.findViewById(R.id.fluffValue);
+
+ row.setTag(holder);
+ }
+ else {
+ holder = (FluffHolder)row.getTag();
+ }
+
+ Resources r = mContext.getResources();
+ holder.label.setText(r.getStringArray(R.array.fluff_fields)[position]);
+ if(mFluff[position] == null) {
+ mFluff[position] = new String("");
+ }
+ holder.value.setText(mFluff[position]);
+
+ return row;
+ }
+
+ static class FluffHolder {
+ TextView label;
+ TextView value;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTInventoryAdapter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTInventoryAdapter.java
new file mode 100644
index 0000000..800c897
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTInventoryAdapter.java
@@ -0,0 +1,75 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.items.PTItem;
+import android.app.Activity;
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTInventoryAdapter extends ArrayAdapter{
+ Context mContext;
+ int mLayoutResourceId;
+ PTItem[] mItems = null;
+ String TAG = "PTInventoryAdapter";
+
+ public PTInventoryAdapter(Context context, int layoutResourceId, PTItem[] items) {
+ super(context, layoutResourceId, items);
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mItems = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ SkillHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new SkillHolder();
+
+ holder.quantity = (TextView)row.findViewById(R.id.tvItemQuantity);
+ holder.name = (TextView)row.findViewById(R.id.tvItemName);
+ holder.weight = (TextView)row.findViewById(R.id.tvItemWeight);
+ holder.contained = (TextView)row.findViewById(R.id.tvItemContained);
+
+ row.setTag(holder);
+ }
+ else {
+ holder = (SkillHolder)row.getTag();
+ }
+
+ holder.quantity.setText(Integer.toString(mItems[position].getQuantity()));
+
+ holder.name.setText(mItems[position].getName());
+
+ holder.weight.setText(Integer.toString(mItems[position].getWeight()));
+
+ if(mItems[position].isContained())
+ holder.contained.setText("\u2713"); //Check mark
+ else holder.contained.setText("");
+
+ return row;
+ }
+
+ static class SkillHolder {
+ TextView quantity;
+ TextView name;
+ TextView weight;
+ TextView contained;
+ }
+
+ public void refill(PTItem[] items){
+ mItems = items;
+ notifyDataSetChanged();
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTSkillsAdapter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTSkillsAdapter.java
new file mode 100644
index 0000000..8ad573f
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTSkillsAdapter.java
@@ -0,0 +1,89 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.stats.PTSkill;
+import com.lateensoft.pathfinder.toolkit.stats.PTSkillSet;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+public class PTSkillsAdapter extends ArrayAdapter {
+ Context mContext;
+ int mLayoutResourceId;
+ PTSkillSet mSkills = null;
+ String TAG = "PTSkillsAdapter";
+
+ public PTSkillsAdapter(Context context, int layoutResourceId,
+ PTSkillSet skillSet) {
+ super(context, layoutResourceId, skillSet.getSkills());
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mSkills = skillSet;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ SkillHolder holder;
+
+ if (row == null) {
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new SkillHolder();
+
+ holder.name = (TextView) row.findViewById(R.id.tvSkillName);
+ holder.total = (TextView) row.findViewById(R.id.tvSkillTotalMod);
+ holder.abilityName = (TextView) row.findViewById(R.id.tvSkillAbility);
+ holder.abilityMod = (TextView) row.findViewById(R.id.tvSkillAbilityMod);
+ holder.rank = (TextView) row.findViewById(R.id.tvSkillRank);
+ holder.miscMod = (TextView) row.findViewById(R.id.tvSkillMisc);
+ holder.armorCheckPenalty = (TextView) row.findViewById(R.id.tvSkillACP);
+ holder.classSkill = (TextView) row.findViewById(R.id.tvClassSkill);
+
+ row.setTag(holder);
+ } else {
+ holder = (SkillHolder) row.getTag();
+ }
+
+ holder.name.setText(mSkills.getSkill(position).getName());
+ holder.total.setText(Integer.toString(mSkills.getSkill(position).getSkillMod()));
+ holder.abilityName.setText(mSkills.getSkill(position).getKeyAbility());
+ holder.abilityMod.setText(Integer.toString(mSkills.getSkill(position).getAbilityMod()));
+ holder.rank.setText(Integer.toString(mSkills.getSkill(position).getRank()));
+ holder.miscMod.setText(Integer.toString(mSkills.getSkill(position).getMiscMod()));
+ holder.armorCheckPenalty.setText(Integer.toString(mSkills.getSkill(position).getArmorCheckPenalty()));
+
+ if(mSkills.getSkill(position).isClassSkill() && mSkills.getSkill(position).getRank() > 0)
+ holder.classSkill.setText(new String("3"));
+ else
+ holder.classSkill.setText(new String("0"));
+
+ return row;
+ }
+
+ public void updateList(PTSkillSet updatedSkillSet){
+ mSkills = updatedSkillSet;
+ notifyDataSetChanged();
+ }
+
+
+ static class SkillHolder {
+ TextView name;
+ TextView total;
+ TextView abilityName;
+ TextView abilityMod;
+ TextView rank;
+ TextView miscMod;
+ TextView armorCheckPenalty;
+ TextView classSkill;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTSpell.java b/src/com/lateensoft/pathfinder/toolkit/character/PTSpell.java
new file mode 100644
index 0000000..9d9414a
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTSpell.java
@@ -0,0 +1,135 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+public class PTSpell {
+ static final String TAG = "PTSpell";
+ String mName;
+ int mPrepared;
+ int mLevel;
+ String mDescription;
+
+ public PTSpell() {
+ mName = new String("");
+ mLevel = 0;
+ mPrepared = 0;
+ mDescription = new String("");
+ }
+
+ public PTSpell(String name) {
+ this();
+ mName = name;
+ }
+
+ public PTSpell(String name, int level) {
+ this(name);
+ mLevel = level;
+ }
+
+ /**
+ *
+ * @param name
+ * @param level
+ * @param prepared
+ * @param description
+ */
+ public PTSpell(String name, int level, int prepared, String description) {
+ this(name, level);
+ mPrepared = prepared;
+ mDescription = description;
+ }
+
+ public PTSpell(PTSpell spell) {
+ this(spell.getName(), spell.getLevel(), spell.getPrepared(), spell.getDescription());
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public void setDescription(String description) {
+ mDescription = description;
+ }
+
+ public int getLevel() {
+ return mLevel;
+ }
+
+ public void setLevel(int level) {
+ mLevel = level;
+ }
+
+ public int getPrepared() {
+ return mPrepared;
+ }
+
+ public boolean isPrepared() {
+ if(mPrepared >= 1)
+ return true;
+ else
+ return false;
+ }
+
+ public void setPrepared(int prepared) {
+ mPrepared = prepared;
+ }
+
+ public void setAsOtherSpell(PTSpell spell) {
+ mName = spell.getName();
+ mLevel = spell.getLevel();
+ mPrepared = spell.getPrepared();
+ mDescription = spell.getDescription();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((mDescription == null) ? 0 : mDescription.hashCode());
+ result = prime * result + mLevel;
+ result = prime * result + ((mName == null) ? 0 : mName.hashCode());
+ result = prime * result + mPrepared;
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ PTSpell other = (PTSpell) obj;
+ if (mDescription == null) {
+ if (other.mDescription != null)
+ return false;
+ } else if (!mDescription.equals(other.mDescription))
+ return false;
+ if (mLevel != other.mLevel)
+ return false;
+ if (mName == null) {
+ if (other.mName != null)
+ return false;
+ } else if (!mName.equals(other.mName))
+ return false;
+ if (mPrepared != other.mPrepared)
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTSpellBook.java b/src/com/lateensoft/pathfinder/toolkit/character/PTSpellBook.java
new file mode 100644
index 0000000..b6223d8
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTSpellBook.java
@@ -0,0 +1,118 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import java.util.ArrayList;
+
+public class PTSpellBook {
+ static final int NUM_SPELL_LEVELS = 10;
+ ArrayList mSpells;
+ int mSpellCount[];
+ //LargestLevelSet mLargestLevelSet;
+
+ public PTSpellBook() {
+ mSpells = new ArrayList();
+
+ /*
+ for(int i = 0; i < mSpells.size(); i++) {
+ mSpells.set(i, new ArrayList());
+ // Dummy spell
+ //mSpells.get(i).add(new PTSpell());
+ }*/
+ //mSpells.add(new PTSpell());
+ }
+
+ /*
+ public PTSpellBook(PTSpell[][] spells) {
+ setSpells(spells);
+ }*/
+ /*
+ public PTSpell[] getSpells(int level) {
+ if(level < 0 || mSpells.isEmpty() || mSpells == null || mSpells.get(level) == null
+ || mSpells.get(level).isEmpty()) {
+ PTSpell[] newSpellArray = new PTSpell[1];
+ newSpellArray[0] = new PTSpell();
+ return newSpellArray;
+ }
+ PTSpell[] levelSpells = new PTSpell[mSpells.get(level).size()];
+ return (PTSpell[]) ((ArrayList)mSpells.get(level)).toArray(levelSpells);
+ }*/
+
+ public PTSpell[] getSpells() {
+ PTSpell[] spells = new PTSpell[mSpells.size()];
+ return (PTSpell[]) mSpells.toArray(spells);
+ }
+
+
+ /*
+ public void setSpells(PTSpell[][] spells) {
+ mSpells = new PTSpell[NUM_SPELL_LEVELS][mLargestLevelSet.value];
+ for(int j = 0; j < NUM_SPELL_LEVELS; j++) {
+ for(int i = 0; i < spells[j].length; i++) {
+ mSpells[j][i] = spells[j][i];
+ }
+ mSpellCount[j] = spells[j].length;
+ }
+ }*/
+
+ public void deleteSpell(PTSpell spell) {
+ //mSpells.get(spell.getLevel()).remove(mSpells.get(spell.getLevel()).indexOf(spell));
+
+ mSpells.remove(mSpells.indexOf(spell));
+ }
+
+ public void deleteSpell(int index) {
+ mSpells.remove(index);
+ }
+
+ /**
+ *
+ * @param level
+ * @param index
+ * @return The specified spell
+ */
+ public PTSpell getSpell(int index) {
+ return (PTSpell) mSpells.get(index);
+ }
+
+ public void addSpell(PTSpell spell) {
+ if(spell == null)
+ return;
+
+ if(mSpells.size() == 0) {
+ mSpells.add(spell);
+ return;
+ }
+
+ for(int i = 0; i < this.getSpellCount(); i++) {
+ if(mSpells.get(i).getLevel() > spell.getLevel()) {
+ mSpells.add(i, spell);
+ return;
+ }
+ }
+ mSpells.add(spell);
+ }
+
+ public int getSpellCount() {
+ return mSpells.size();
+ }
+
+ public int getNumSpellLevels() {
+ return NUM_SPELL_LEVELS;
+ }
+
+ public boolean contains(PTSpell spell) {
+ if(mSpells.contains(spell))
+ return true;
+ return false;
+ }
+
+ public void setSpell(int mSpellSelectedForEdit, PTSpell spell) {
+ if(spell.getLevel() == mSpells.get(mSpellSelectedForEdit).getLevel()) {
+ mSpells.set(mSpellSelectedForEdit, spell);
+ } else {
+ // Make sure the spells stay ordered by level
+ mSpells.remove(mSpellSelectedForEdit);
+ this.addSpell(spell);
+ }
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTSpellBookAdapter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTSpellBookAdapter.java
new file mode 100644
index 0000000..ade7be4
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTSpellBookAdapter.java
@@ -0,0 +1,73 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+public class PTSpellBookAdapter extends ArrayAdapter{
+ Context mContext;
+ int mLayoutResourceId;
+ PTSpell[] mSpells = null;
+ String TAG = "PTSpellBookAdapter";
+
+ public PTSpellBookAdapter(Context context, int layoutResourceId,
+ PTSpell[] spells) {
+ super(context, layoutResourceId, spells);
+ Log.v(TAG, "Constructing"); //TODO:Debug log
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mSpells = spells;
+ Log.v(TAG, "Finished constructing"); //TODO:Debug log
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ /*if(convertView == null)
+ row = new View(parent.getContext());
+ else
+ row = convertView;*/
+ /*
+ if(row == null) {
+ row = ((LayoutInflater)((Activity) parent.getContext()).getLayoutInflater())
+ .inflate(mLayoutResourceId,null);
+ }*/
+
+ SpellItemHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new SpellItemHolder();
+
+ holder.level = (TextView)row.findViewById(R.id.spellLevel);
+ holder.name = (TextView)row.findViewById(R.id.spellName);
+ holder.prepared = (TextView)row.findViewById(R.id.spellPrepared);
+
+ row.setTag(holder);
+ }
+ else {
+ holder = (SpellItemHolder)row.getTag();
+ }
+
+ holder.level.setText(Integer.toString(mSpells[position].getLevel()));
+ holder.name.setText(mSpells[position].getName());
+ holder.prepared.setText(Integer.toString(mSpells[position].getPrepared()));
+
+ Log.v(TAG, "Finishing getView"); //TODO:Debug log
+ return row;
+ }
+
+ static class SpellItemHolder {
+ TextView prepared;
+ TextView name;
+ TextView level;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTWeaponAdapter.java b/src/com/lateensoft/pathfinder/toolkit/character/PTWeaponAdapter.java
new file mode 100644
index 0000000..9164273
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTWeaponAdapter.java
@@ -0,0 +1,79 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.items.PTWeapon;
+
+public class PTWeaponAdapter extends ArrayAdapter {
+ Context mContext;
+ int mLayoutResourceId;
+ PTWeapon[] mWeapons = null;
+ static final String TAG = "PTWeaponAdapter";
+
+ public PTWeaponAdapter(Context context, int layoutResourceId, PTWeapon[] weapons) {
+ super(context, layoutResourceId, weapons);
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mWeapons = weapons;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ WeaponHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new WeaponHolder();
+
+ holder.name = (TextView)row.findViewById(R.id.weaponName);
+ holder.weight = (TextView)row.findViewById(R.id.weaponWeight);
+ holder.totalAttackBonus = (TextView)row.findViewById(R.id.weaponAttack);
+ holder.damage = (TextView)row.findViewById(R.id.weaponDamage);
+ holder.range = (TextView)row.findViewById(R.id.weaponRange);
+ holder.specialProperties = (TextView)row.findViewById(R.id.weaponSpecial);
+ //holder.ammunition = (TextView)row.findViewById
+ holder.type = (TextView)row.findViewById(R.id.weaponType);
+ holder.size = (TextView)row.findViewById(R.id.weaponSize);
+ holder.critical = (TextView)row.findViewById(R.id.weaponCrit);
+
+ row.setTag(holder);
+ } else {
+ holder = (WeaponHolder)row.getTag();
+ }
+
+ holder.name.setText(mWeapons[position].getName());
+ holder.weight.setText(Integer.toString(mWeapons[position].getWeight()));
+ holder.totalAttackBonus.setText(Integer.toString(mWeapons[position].getTotalAttackBonus()));
+ holder.damage.setText(mWeapons[position].getDamage());
+ holder.range.setText(Integer.toString(mWeapons[position].getRange()));
+ holder.specialProperties.setText(mWeapons[position].getSpecialProperties());
+ holder.type.setText(mWeapons[position].getType());
+ holder.size.setText(mWeapons[position].getSize());
+ holder.critical.setText(mWeapons[position].getCritical());
+ //holder.name.setText(mWeapons[position].getName());
+
+ return row;
+ }
+
+ static class WeaponHolder {
+ TextView name;
+ TextView weight;
+ TextView totalAttackBonus;
+ TextView damage;
+ TextView range;
+ TextView specialProperties;
+ TextView ammunition;
+ TextView type;
+ TextView size;
+ TextView critical;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/character/PTWeaponsFragment.java b/src/com/lateensoft/pathfinder/toolkit/character/PTWeaponsFragment.java
new file mode 100644
index 0000000..9290cc0
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/character/PTWeaponsFragment.java
@@ -0,0 +1,238 @@
+package com.lateensoft.pathfinder.toolkit.character;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.items.PTArmor;
+import com.lateensoft.pathfinder.toolkit.items.PTWeapon;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View.OnClickListener;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+public class PTWeaponsFragment extends PTCharacterSheetFragment implements
+OnClickListener, OnItemClickListener, android.content.DialogInterface.OnClickListener{
+
+ static final String TAG = "PTWeaponFragment";
+ private static final int ATK_BONUS_OFFSET = 10;
+ private ListView mListView;
+ int mWeaponSelectedForEdit;
+ private Button mAddButton;
+
+ private EditText mDialogNameET;
+ private Spinner mDialogHighestAtkSpinner;
+ private Spinner mDialogAmmunitionSpinner;
+ private EditText mDialogDamageET;
+ private EditText mDialogCriticalET;
+ private Spinner mDialogTypeSpinner;
+ private Spinner mDialogRangeSpinner;
+ private Spinner mDialogSizeSpinner;
+ private EditText mDialogWeightET;
+ private EditText mDialogSpecialPropertiesET;
+
+
+
+ private ViewGroup mContainer;
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.v(TAG, "Starting onCreateView");
+
+ mContainer = container;
+
+ View fragmentView = inflater.inflate(R.layout.character_weapon_fragment,
+ container, false);
+
+ mAddButton = (Button) fragmentView.findViewById(R.id.buttonAddWeapon);
+ mAddButton.setOnClickListener(this);
+
+ mListView = new ListView(container.getContext());
+ mListView = (ListView) fragmentView.findViewById(R.id.listViewWeapons);
+ refreshWeaponsListView();
+
+ mListView.setOnItemClickListener(this);
+
+ Log.v(TAG, "Finishing onCreateView");
+ return fragmentView;
+ }
+
+ private void refreshWeaponsListView() {
+ PTWeaponAdapter adapter = new PTWeaponAdapter(mContainer.getContext(),
+ R.layout.character_weapon_row,
+ mCharacter.getInventory().getWeaponArray());
+
+ Log.v(TAG, "Called refreshWeaponsListView");
+
+ mListView.setAdapter(adapter);
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Log.v(TAG, "Item clicked: " + position);
+ mWeaponSelectedForEdit = position;
+ showWeaponDialog(mCharacter.getInventory().getWeapon(position));
+ }
+
+
+
+ public void onClick(View v) {
+ Log.v(TAG, "Add button clicked");
+ mWeaponSelectedForEdit = -1;
+ showWeaponDialog(null);
+ }
+
+ private void showWeaponDialog(PTWeapon weapon) {
+ if(weapon == null)
+ weapon = new PTWeapon();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View dialogView = inflater.inflate(R.layout.character_weapon_dialog, null);
+
+ mDialogNameET = (EditText) dialogView.findViewById(R.id.weaponDialogName);
+ mDialogHighestAtkSpinner = (Spinner) dialogView.findViewById(R.id.weaponDialogHighestAtk);
+ mDialogAmmunitionSpinner = (Spinner) dialogView.findViewById(R.id.weaponDialogAmmo);
+ mDialogDamageET = (EditText) dialogView.findViewById(R.id.weaponDialogDamage);
+ mDialogCriticalET = (EditText) dialogView.findViewById(R.id.weaponDialogCrit);
+ mDialogTypeSpinner = (Spinner) dialogView.findViewById(R.id.weaponDialogType);
+ mDialogRangeSpinner = (Spinner) dialogView.findViewById(R.id.weaponDialogRange);
+ mDialogSizeSpinner = (Spinner) dialogView.findViewById(R.id.weaponDialogSize);
+ mDialogWeightET = (EditText) dialogView.findViewById(R.id.weaponDialogWeight);
+ mDialogSpecialPropertiesET = (EditText) dialogView
+ .findViewById(R.id.weaponDialogSpecialProperties);
+
+ setupSpinner(mDialogHighestAtkSpinner, R.array.weapon_attack_bonus_options);
+ setupSpinner(mDialogAmmunitionSpinner, R.array.selectable_values_string);
+ setupSpinner(mDialogTypeSpinner, R.array.weapon_type_options);
+ setupSpinner(mDialogRangeSpinner, R.array.weapon_range_options);
+ setupSpinner(mDialogSizeSpinner, R.array.size_spinner_options);
+
+ if(mWeaponSelectedForEdit < 0) {
+ builder.setTitle(R.string.new_weapon_title);
+ mDialogHighestAtkSpinner.setSelection(ATK_BONUS_OFFSET);
+ } else {
+ builder.setTitle(weapon.getName()).setNeutralButton(R.string.delete_button_text,
+ this);
+ mDialogNameET.setText(weapon.getName());
+ mDialogHighestAtkSpinner.setSelection(weapon.getTotalAttackBonus() + ATK_BONUS_OFFSET);
+ mDialogAmmunitionSpinner.setSelection(weapon.getAmmunition());
+ mDialogDamageET.setText(weapon.getDamage());
+ mDialogCriticalET.setText(weapon.getCritical());
+ mDialogTypeSpinner.setSelection(weapon.getTypeInt(mContainer.getContext()));
+ mDialogRangeSpinner.setSelection(weapon.getRange()/5);
+ mDialogSizeSpinner.setSelection(weapon.getSizeInt());
+ mDialogWeightET.setText(Integer.toString(weapon.getWeight()));
+ mDialogSpecialPropertiesET.setText(weapon.getSpecialProperties());
+
+ }
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ PTWeapon weapon = getWeaponFromDialog();
+
+ switch (selection) {
+ case DialogInterface.BUTTON_POSITIVE:
+ Log.v(TAG, "Add.edit armor OK: " + mDialogNameET.getText());
+ if(mWeaponSelectedForEdit < 0) {
+ Log.v(TAG, "Adding a weapon");
+ if(weapon != null) {
+ mCharacter.getInventory().addWeapon(weapon);
+ refreshWeaponsListView();
+ }
+ } else {
+ Log.v(TAG, "Editing a weapon");
+
+ mCharacter.getInventory().setWeapon(weapon, mWeaponSelectedForEdit);
+ refreshWeaponsListView();
+ }
+
+ break;
+
+ case DialogInterface.BUTTON_NEUTRAL:
+ Log.v(TAG, "Deleting a weapon");
+ mCharacter.getInventory().deleteWeapon(mWeaponSelectedForEdit);
+ refreshWeaponsListView();
+ break;
+
+ case DialogInterface.BUTTON_NEGATIVE:
+ break;
+
+ default:
+ break;
+
+ }
+ }
+
+ private PTWeapon getWeaponFromDialog() {
+ String name = new String(mDialogNameET.getText().toString());
+ if(name == null || name.contentEquals("")) {
+ return null;
+ }
+
+ int attack = mDialogHighestAtkSpinner.getSelectedItemPosition() - ATK_BONUS_OFFSET;;
+ int weight;
+ try {
+ weight = Integer.parseInt(mDialogWeightET.getText().toString());
+ } catch (NumberFormatException e) {
+ weight = 1;
+ }
+
+ int range = mDialogRangeSpinner.getSelectedItemPosition()*5;
+ int ammo = mDialogAmmunitionSpinner.getSelectedItemPosition();
+ String damage = new String(mDialogDamageET.getText().toString());
+ String critical = new String(mDialogCriticalET.getText().toString());
+ String specialProperties = new String(mDialogSpecialPropertiesET.getText().toString());
+ String type = new String(getStringByResourceAndIndex(R.array.weapon_type_options,
+ mDialogTypeSpinner.getSelectedItemPosition()));
+ String size = new String(getStringByResourceAndIndex(R.array.size_spinner_options,
+ mDialogSizeSpinner.getSelectedItemPosition()));
+
+
+ PTWeapon weapon = new PTWeapon();
+ weapon.setName(name);
+ weapon.setTotalAttackBonus(attack);
+ weapon.setWeight(weight);
+ weapon.setRange(range);
+ weapon.setAmmunition(ammo);
+ weapon.setDamage(damage);
+ weapon.setCritical(critical);
+ weapon.setSpecialProperties(specialProperties);
+ weapon.setType(type);
+ weapon.setSize(size);
+
+ return weapon;
+ }
+
+ private void setupSpinner(Spinner spinner, int optionResourceId) {
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
+ optionResourceId, android.R.layout.simple_spinner_item);
+
+ adapter.setDropDownViewResource(R.layout.spinner_plain);
+ spinner.setAdapter(adapter);
+ }
+
+ private String getStringByResourceAndIndex(int resourceId, int position) {
+ Resources r = mContainer.getContext().getResources();
+ String[] resource = r.getStringArray(resourceId);
+ return resource[position];
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/datahelpers/PTDatabaseManager.java b/src/com/lateensoft/pathfinder/toolkit/datahelpers/PTDatabaseManager.java
new file mode 100644
index 0000000..7975ed4
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/datahelpers/PTDatabaseManager.java
@@ -0,0 +1,321 @@
+package com.lateensoft.pathfinder.toolkit.datahelpers;
+
+import com.google.gson.*;
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.character.PTCharacter;
+import com.lateensoft.pathfinder.toolkit.party.PTParty;
+import com.lateensoft.pathfinder.toolkit.stats.PTSkill;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+public class PTDatabaseManager extends SQLiteOpenHelper {
+ private final String TAG = "PTDatabaseManager";
+
+ static final String dbName = "pathfinderToolkitDB";
+ static final String characterTable = "Characters";
+ static final String colChtrID = "CharacterID";
+ static final String colChtrName = "CharacterName";
+ static final String colChtrGSON = "CharacterGSON";
+
+ static final String partyTable = "Parties";
+ static final String colPrtyID = "PartyID";
+ static final String colPrtyName = "PartyName";
+ static final String colPrtyGSON = "PartyGSON";
+
+ static int dbVersion = 1;
+
+ private Gson mGson;
+ private SQLiteDatabase mDatabase;
+
+ public PTDatabaseManager(Context appContext) {
+ super(appContext, dbName, null, dbVersion);
+ mGson = new Gson();
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+
+ Log.v(TAG, "Creating new database");
+ //Create character table
+ db.execSQL("CREATE TABLE "+characterTable+" ("+colChtrID+ " INTEGER PRIMARY KEY AUTOINCREMENT, "+
+ colChtrName+ " TEXT, " +colChtrGSON+ " TEXT)");
+
+ //Create party table
+ db.execSQL("CREATE TABLE "+partyTable+" ("+colPrtyID+ " INTEGER PRIMARY KEY AUTOINCREMENT, "+
+ colPrtyName+ " TEXT, " +colPrtyGSON+ " TEXT)");
+
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ //db.execSQL("DROP TABLE IF EXISTS "+characterTable);
+ //db.execSQL("DROP TABLE IF EXISTS "+partyTable);
+
+ //onCreate(db);
+ }
+
+ /**
+ * Intended to fix the database so it is compatible across all versions
+ * @param context
+ */
+ public void performUpdates(Context context){
+ int characterIDs[] = getCharacterIDs();
+
+ if (characterIDs.length > 0){
+ Log.v(TAG, "Updating character table to current version");
+ PTCharacter character;
+
+ Resources r = context.getResources();
+ int[] skillAbilityKeys = r.getIntArray(R.array.skill_ability_keys);
+ String[] skillAbilityShortStrings = r.getStringArray(R.array.abilities_short);
+
+ for(int characterIndex = 0; characterIndex < characterIDs.length; characterIndex++){
+ character = getCharacter(characterIDs[characterIndex]);
+
+ //Ensure that skills are up to date with string resources
+ for(int i = 0; i < skillAbilityKeys.length; i++) {
+ character.getSkillSet().getSkill(i).setKeyAbilityKey(skillAbilityKeys[i]);
+ character.getSkillSet().getSkill(i).setKeyAbility(skillAbilityShortStrings[skillAbilityKeys[i]]);
+ }
+
+ updateCharacter(character);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @param context
+ * @return a character newly added into the database
+ */
+ public PTCharacter addNewCharacter(String name, Context context){
+ PTCharacter newCharacter = new PTCharacter(name, context);
+ ContentValues cv=new ContentValues();
+ cv.put(colChtrName, newCharacter.getName());
+ cv.put(colChtrGSON, mGson.toJson(newCharacter));
+
+ open();
+ mDatabase.insert(characterTable, null, cv);
+
+ //Getting the character's id
+ Cursor cursor = mDatabase.query(characterTable, new String[]{colChtrID}, null ,
+ null, null, null, colChtrID);
+
+ cursor.moveToLast();
+ int characterID = cursor.getInt(cursor.getColumnIndex(colChtrID));
+ close();
+
+ newCharacter.mID = characterID;
+ updateCharacter(newCharacter);
+ Log.v(TAG, "New character added to database: " + characterID);
+
+ return newCharacter;
+ }
+
+ /**
+ * Updates the character's info in the database. Will only work if the character was created using PTDatabaseManager
+ * @param character
+ */
+ public void updateCharacter(PTCharacter character){
+ ContentValues editCon = new ContentValues();
+ editCon.put(colChtrName, character.getName());
+ editCon.put(colChtrGSON, mGson.toJson(character));
+
+ open();
+ mDatabase.update(characterTable, editCon, colChtrID+"="+character.mID, null);
+ close();
+ Log.v(TAG, "Character saved in database");
+ }
+
+ /**
+ *
+ * @param id
+ * @return the character with the id passed
+ */
+ public PTCharacter getCharacter(int id){
+ Log.v(TAG, "Retrieving character");
+ open();
+ Cursor cursor = mDatabase.query(characterTable, null, colChtrID+"="+id , null, null, null, null);
+
+ cursor.moveToFirst();
+ PTCharacter character = mGson.fromJson(cursor.getString(cursor.getColumnIndex(colChtrGSON)), PTCharacter.class);
+ close();
+ Log.v(TAG, "Character retrieved from database");
+ return character;
+ }
+
+ /**
+ *
+ * @return an array in int, filled with the IDs of all currently available characters in the database
+ */
+ public int[] getCharacterIDs(){
+ open();
+ Cursor cursor = mDatabase.query(characterTable, new String[]{colChtrID}, null, null, null, null, colChtrID);
+
+ int characterIDs[] = new int[cursor.getCount()];
+
+ cursor.moveToFirst();
+ while(!cursor.isAfterLast()){
+ characterIDs[cursor.getPosition()] = cursor.getInt(cursor.getColumnIndex(colChtrID));
+ cursor.moveToNext();
+ }
+ return characterIDs;
+ }
+
+ /**
+ *
+ * @return an array of strings with the names of all current characters, ordered by their IDs
+ */
+ public String[] getCharacterNames(){
+ open();
+ Cursor cursor = mDatabase.query(characterTable, new String[]{colChtrName}, null, null, null, null, colChtrID);
+
+ String characterNames[] = new String[cursor.getCount()];
+
+ cursor.moveToFirst();
+ while(!cursor.isAfterLast()){
+ characterNames[cursor.getPosition()] = cursor.getString(cursor.getColumnIndex(colChtrName));
+ cursor.moveToNext();
+ }
+
+ return characterNames;
+ }
+
+ /**
+ * deletes the character with the passed id
+ * @param id
+ */
+ public void deleteCharacter(int id){
+ open();
+ mDatabase.delete(characterTable, colChtrID+"="+id, null);
+ close();
+ Log.v(TAG, "Character deleted from database");
+ }
+
+ /**
+ *
+ * @param name
+ * @return a party newly added into the database
+ */
+ public PTParty addNewParty(String name){
+ PTParty newParty = new PTParty(name);
+ ContentValues cv=new ContentValues();
+ cv.put(colPrtyName, newParty.getName());
+ cv.put(colPrtyGSON, mGson.toJson(newParty));
+
+ open();
+ mDatabase.insert(partyTable, null, cv);
+
+ //Getting the party's id
+ Cursor cursor = mDatabase.query(partyTable, new String[]{colPrtyID}, null ,
+ null, null, null, colPrtyID);
+
+ cursor.moveToLast();
+ int partyID = cursor.getInt(cursor.getColumnIndex(colPrtyID));
+ close();
+
+ newParty.mID = partyID;
+ updateParty(newParty);
+ Log.v(TAG, "New party added to database: " + partyID);
+
+ return newParty;
+ }
+
+ /**
+ * Updates the party's info in the database. Will only work if the party was created using PTDatabaseManager
+ * @param party
+ */
+ public void updateParty(PTParty party){
+ ContentValues editCon = new ContentValues();
+ editCon.put(colPrtyName, party.getName());
+ editCon.put(colPrtyGSON, mGson.toJson(party));
+
+ open();
+ mDatabase.update(partyTable, editCon, colPrtyID+"="+party.mID, null);
+ close();
+ Log.v(TAG, "Party saved in database");
+ }
+
+ /**
+ *
+ * @param id
+ * @return the party with the id passed
+ */
+ public PTParty getParty(int id){
+ Log.v(TAG, "Retrieving party");
+ open();
+ Cursor cursor = mDatabase.query(partyTable, null, colPrtyID+"="+id , null, null, null, null);
+
+ cursor.moveToFirst();
+ PTParty party = mGson.fromJson(cursor.getString(cursor.getColumnIndex(colPrtyGSON)), PTParty.class);
+ close();
+ Log.v(TAG, "Party retrieved from database");
+ return party;
+ }
+
+ /**
+ *
+ * @return an array in int, filled with the IDs of all currently available partys in the database
+ */
+ public int[] getPartyIDs(){
+ open();
+ Cursor cursor = mDatabase.query(partyTable, new String[]{colPrtyID}, null, null, null, null, colPrtyID);
+
+ int partyIDs[] = new int[cursor.getCount()];
+
+ cursor.moveToFirst();
+ while(!cursor.isAfterLast()){
+ partyIDs[cursor.getPosition()] = cursor.getInt(cursor.getColumnIndex(colPrtyID));
+ cursor.moveToNext();
+ }
+ return partyIDs;
+ }
+
+ /**
+ *
+ * @return an array of strings with the names of all current partys, ordered by their IDs
+ */
+ public String[] getPartyNames(){
+ open();
+ Cursor cursor = mDatabase.query(partyTable, new String[]{colPrtyName}, null, null, null, null, colPrtyID);
+
+ String partyNames[] = new String[cursor.getCount()];
+
+ cursor.moveToFirst();
+ while(!cursor.isAfterLast()){
+ partyNames[cursor.getPosition()] = cursor.getString(cursor.getColumnIndex(colPrtyName));
+ cursor.moveToNext();
+ }
+
+ return partyNames;
+ }
+
+ /**
+ * deletes the party with the passed id
+ * @param id
+ */
+ public void deleteParty(int id){
+ open();
+ mDatabase.delete(partyTable, colPrtyID+"="+id, null);
+ close();
+ Log.v(TAG, "Party deleted from database");
+ }
+
+ public void open() throws SQLException {
+ //open database in reading/writing mode
+ mDatabase = this.getWritableDatabase();
+ }
+
+ public void close() {
+ if (mDatabase != null)
+ mDatabase.close();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/datahelpers/PTUserPrefsManager.java b/src/com/lateensoft/pathfinder/toolkit/datahelpers/PTUserPrefsManager.java
new file mode 100644
index 0000000..bf00329
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/datahelpers/PTUserPrefsManager.java
@@ -0,0 +1,212 @@
+package com.lateensoft.pathfinder.toolkit.datahelpers;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.lateensoft.pathfinder.toolkit.party.PTParty;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.util.Log;
+
+public class PTUserPrefsManager {
+ private final String TAG = "PTUserPrefsManager";
+
+ private final long SECONDS_BETWEEN_RATE_PROMPT = 604800L; //One week
+
+ private final String KEY_APP_SHARED_PREFS_NAME = "ptUserPrefs";
+ private final String KEY_SHARED_PREFS_LAST_RATE_TIME = "lastRateTime";
+ private final String KEY_SHARED_PREFS_LAST_RATE_VERSION = "lastRateVersion";
+ private final String KEY_SHARED_PREFS_LAST_USED_VERSION = "lastUsedVersion";
+ private final String KEY_SHARED_PREFS_SELECTED_CHARACTER = "selectedCharacter";
+ private final String KEY_SHARED_PREFS_LAST_TAB = "lastTab";
+ private final String KEY_SHARED_PREFS_SELECTED_PARTY = "selectedParty";
+ private final String KEY_SHARED_PREFS_ENCOUNTER_PARTY = "encounterParty";
+
+ SharedPreferences mSharedPreferences;
+ Editor mEditor;
+
+ /**
+ * Manages the shared preferences for the Pathfinder Toolkit application
+ * @param context
+ */
+ public PTUserPrefsManager(Context context){
+ Context appContext = context.getApplicationContext();
+ mSharedPreferences = context.getApplicationContext().getSharedPreferences(
+ KEY_APP_SHARED_PREFS_NAME, appContext.MODE_PRIVATE);
+ mEditor = mSharedPreferences.edit();
+ }
+
+ /**
+ * Saves the ID of the currently selected character to SharedPreferences
+ * @param characterID
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setSelectedCharacter(int characterID){
+ mEditor.putInt(KEY_SHARED_PREFS_SELECTED_CHARACTER, characterID);
+ Log.v(TAG, "Selected character set to "+characterID);
+ return mEditor.commit();
+ }
+
+ /**
+ * @return The ID of the currently selected character. Returns -1 if no character is selected
+ */
+ public int getSelectedCharacter(){
+ return mSharedPreferences.getInt(KEY_SHARED_PREFS_SELECTED_CHARACTER, -1);
+ }
+
+ /**
+ * Saves the last tab visited in character sheet to SharedPreferences
+ * @param tab
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setLastCharacterTab(int tab){
+ mEditor.putInt(KEY_SHARED_PREFS_LAST_TAB, tab);
+ Log.v(TAG, "Save last tab to "+tab);
+ return mEditor.commit();
+ }
+
+ /**
+ * @return The last tab visited in character sheet. Returns 0 if no value is set.
+ */
+ public int getLastCharacterTab(){
+ return mSharedPreferences.getInt(KEY_SHARED_PREFS_LAST_TAB, 0);
+ }
+
+ /**
+ * Saves the ID of the currently selected party to SharedPreferences
+ * @param characterID
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setSelectedParty(int partyID){
+ mEditor.putInt(KEY_SHARED_PREFS_SELECTED_PARTY, partyID);
+ Log.v(TAG, "Selected party set to "+partyID);
+ return mEditor.commit();
+ }
+
+ /**
+ * @return The ID of the currently selected party. Returns -1 if no character is selected
+ */
+ public int getSelectedParty(){
+ return mSharedPreferences.getInt(KEY_SHARED_PREFS_SELECTED_PARTY, -1);
+ }
+
+ /**
+ * Saves the current party in the encounter to shared prefs
+ * @param encounterParty
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setEncounterParty(PTParty encounterParty){
+ Gson gson = new Gson();
+ String partyJson = gson.toJson(encounterParty);
+ mEditor.putString(KEY_SHARED_PREFS_ENCOUNTER_PARTY, partyJson);
+ Log.v(TAG, "Saved current encounter party");
+ return mEditor.commit();
+ }
+
+ /**
+ *
+ * @return the current encounter party. returns null if none is saved.
+ */
+ public PTParty getEncounterParty(){
+ Gson gson = new Gson();
+ String partyJson = mSharedPreferences.getString(KEY_SHARED_PREFS_ENCOUNTER_PARTY, "");
+ PTParty encounterParty;
+ try{
+ encounterParty = gson.fromJson(partyJson, PTParty.class);
+ }catch(JsonSyntaxException e){
+ encounterParty = null;
+ }
+ return encounterParty;
+ }
+
+ /**
+ * Saves the unix time of the last time the user was asked to rate the app to SharedPreferences
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setRatePromptTime(){
+ long unixTime = System.currentTimeMillis() / 1000L;
+ mEditor.putLong(KEY_SHARED_PREFS_LAST_RATE_TIME, unixTime);
+ return mEditor.commit();
+ }
+
+ /**
+ * @return true if the app was rated more than one week ago
+ */
+ public boolean checkLastRateTime(){
+ long lastRateTime = mSharedPreferences.getLong(KEY_SHARED_PREFS_LAST_RATE_TIME, 0L);
+ long currentUnixTime = System.currentTimeMillis() / 1000L;
+ if( lastRateTime == 0L ){
+ setRatePromptTime();
+ return false;
+ }else
+ return (currentUnixTime - lastRateTime) > SECONDS_BETWEEN_RATE_PROMPT;
+ }
+
+ /**
+ * Sets the last rated version to the current version
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setLastRatedVersion(Context context){
+ PackageInfo pInfo;
+ try{
+ pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ mEditor.putInt(KEY_SHARED_PREFS_LAST_RATE_VERSION, pInfo.versionCode);
+ return mEditor.commit();
+ }catch (NameNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @return true if the last rated version is not the current one (version code)
+ */
+ public boolean checkLastRatedVersion(Context context){
+ int appCode = mSharedPreferences.getInt(KEY_SHARED_PREFS_LAST_RATE_VERSION, 0);
+ PackageInfo pInfo;
+ try{
+ pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return appCode != pInfo.versionCode;
+ }catch (NameNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * Sets the last used version to the current version
+ * @return true if the save was successful, false otherwise
+ */
+ public boolean setLastUsedVersion(Context context){
+ PackageInfo pInfo;
+ try{
+ pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ mEditor.putInt(KEY_SHARED_PREFS_LAST_USED_VERSION, pInfo.versionCode);
+ return mEditor.commit();
+ }catch (NameNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @return true if the last used version is not the current one (version code)
+ */
+ public boolean checkLastUsedVersion(Context context){
+ int appCode = mSharedPreferences.getInt(KEY_SHARED_PREFS_LAST_USED_VERSION, 0);
+ PackageInfo pInfo;
+ try{
+ pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return appCode != pInfo.versionCode;
+ }catch (NameNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/functional/PTDiceSet.java b/src/com/lateensoft/pathfinder/toolkit/functional/PTDiceSet.java
new file mode 100644
index 0000000..92b98b2
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/functional/PTDiceSet.java
@@ -0,0 +1,76 @@
+package com.lateensoft.pathfinder.toolkit.functional;
+
+import java.util.Random;
+
+public class PTDiceSet {
+
+ private Random mNumberGenerator;
+ final private int mDiceInSet[] = { 4, 6, 8, 10, 12, 20, 100 };
+ final private int TOTAL_DICE_IN_SET = 7;
+
+ public PTDiceSet() {
+ mNumberGenerator = new Random();
+ }
+
+ /**
+ * @param dieType
+ * @return an int between 1 and dieType (inclusive), if the dieType is a
+ * valid polyhedral die (4, 6, 8, 10, 12, 20, 100). Returns 0 if
+ * dieType is invalid.
+ */
+ public int singleRoll(int dieType) {
+ for (int i = 0; i < TOTAL_DICE_IN_SET; i++) {
+ if (dieType == mDiceInSet[i])
+ return mNumberGenerator.nextInt(dieType) + 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ * Performs an XdY type roll
+ *
+ * @param rolls
+ * @param dieType
+ * @return an int between 1 and rolls*dieType (inclusive), if the dieType is
+ * a valid polyhedral die (4, 6, 8, 10, 12, 20, 100). Returns 0 if
+ * dieType is invalid.
+ */
+ public int multiRoll(int rolls, int dieType) {
+ int rollTotal = 0;
+
+ for (int i = 0; i < TOTAL_DICE_IN_SET; i++) {
+ if (dieType == mDiceInSet[i]) {
+ for (int j = 0; j < rolls; j++)
+ rollTotal += (mNumberGenerator.nextInt(dieType) + 1);
+ return rollTotal;
+ }
+ }
+
+ return 0;
+ }
+
+
+ /**
+ * Performs an XdY type roll
+ *
+ * @param rolls
+ * @param dieType
+ * @return an int[] of size X containing all the roll results, if the dieType is
+ * a valid polyhedral die (4, 6, 8, 10, 12, 20, 100). Returns null if
+ * dieType is invalid.
+ */
+ public int[] multiRollWithResults(int rolls, int dieType){
+ int[] rollResults = new int[rolls];
+
+ for (int i = 0; i < TOTAL_DICE_IN_SET; i++) {
+ if (dieType == mDiceInSet[i]) {
+ for (int j = 0; j < rolls; j++)
+ rollResults[j] = (mNumberGenerator.nextInt(dieType) + 1);
+ return rollResults;
+ }
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/com/lateensoft/pathfinder/toolkit/items/PTArmor.java b/src/com/lateensoft/pathfinder/toolkit/items/PTArmor.java
new file mode 100644
index 0000000..6272140
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/items/PTArmor.java
@@ -0,0 +1,135 @@
+package com.lateensoft.pathfinder.toolkit.items;
+
+public class PTArmor extends PTItem {
+ boolean mWorn;
+ int mACBonus;
+ int mCheckPen;
+ int mMaxDex;
+ int mSpellFail;
+ int mSpeed;
+ String mSpecialProperties;
+ String mSize;
+
+ public PTArmor() {
+ super();
+ mWorn = true;
+ mACBonus = 0;
+ mCheckPen = 0;
+ mMaxDex = 10;
+ mSpellFail = 0;
+ mSpeed = 30;
+ mSpecialProperties = new String("");
+ mSize = "M";
+ }
+
+ public void setSize(String size) {
+ mSize = size;
+ }
+
+ public String getSize() {
+ return mSize;
+ }
+
+ public void setSpecialProperties(String properties) {
+ mSpecialProperties = properties;
+ }
+
+ public String getSpecialProperties() {
+ return mSpecialProperties;
+ }
+
+ /**
+ * @return the mWorn
+ */
+ public boolean isWorn() {
+ return mWorn;
+ }
+ /**
+ * @param mWorn the mWorn to set
+ */
+ public void setWorn(boolean mWorn) {
+ this.mWorn = mWorn;
+ }
+ /**
+ * @return the mACBonus
+ */
+ public int getACBonus() {
+ return mACBonus;
+ }
+ /**
+ * @param mACBonus the mACBonus to set
+ */
+ public void setACBonus(int mACBonus) {
+ this.mACBonus = mACBonus;
+ }
+ /**
+ * @return the mCheckPen
+ */
+ public int getCheckPen() {
+ return mCheckPen;
+ }
+ /**
+ * @param mCheckPen the mCheckPen to set
+ */
+ public void setCheckPen(int mCheckPen) {
+ this.mCheckPen = mCheckPen;
+ }
+ /**
+ * @return the mMaxDex
+ */
+ public int getMaxDex() {
+ return mMaxDex;
+ }
+ /**
+ * @param mMaxDex the mMaxDex to set
+ */
+ public void setMaxDex(int mMaxDex) {
+ this.mMaxDex = mMaxDex;
+ }
+ /**
+ * @return the mSpellFail
+ */
+ public int getSpellFail() {
+ return mSpellFail;
+ }
+ /**
+ * @param mSpellFail the mSpellFail to set
+ */
+ public void setSpellFail(int mSpellFail) {
+ this.mSpellFail = mSpellFail;
+ }
+ /**
+ * @return the mSpeed
+ */
+ public int getSpeed() {
+ return mSpeed;
+ }
+ /**
+ * @param mSpeed the mSpeed to set
+ */
+ public void setSpeed(int mSpeed) {
+ this.mSpeed = mSpeed;
+ }
+
+ public String getSpeedString() {
+ String speedString = new String();
+ speedString = Integer.toString(mSpeed) + " ft.";
+ return speedString;
+ }
+
+ public int getSizeInt() {
+ String[] sizeArray = {"S", "M", "L"};
+ for(int i = 0; i < sizeArray.length; i++) {
+ if(mSize.equals(sizeArray[i]))
+ return i;
+ }
+ return 1;
+ }
+
+ public void setSize(int size) {
+ String[] sizeArray = {"S", "M", "L"};
+ mSize = sizeArray[size];
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/items/PTItem.java b/src/com/lateensoft/pathfinder/toolkit/items/PTItem.java
new file mode 100644
index 0000000..6e9cfb7
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/items/PTItem.java
@@ -0,0 +1,65 @@
+package com.lateensoft.pathfinder.toolkit.items;
+
+public class PTItem {
+ String mName;
+ int mWeight;
+ int mQuantity;
+ boolean mIsContained; //set if in a container such as a bag of holding (will be used to set effective weight to 0)
+
+ public PTItem(String name, int weight, int quantity, boolean contained) {
+ mName = name;
+ mWeight = weight;
+ mQuantity = quantity;
+ mIsContained = contained;
+ }
+
+ /**
+ * Creates new instance of an Item. Defaults quantity to 1 and contained to false.
+ * @param name
+ * @param weight
+ */
+ public PTItem(String name, int weight) {
+ mName = name;
+ mWeight = weight;
+ mQuantity = 1;
+ mIsContained = false;
+ }
+
+ public PTItem() {
+ mName = "";
+ mWeight = 1;
+ mQuantity = 1;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public int getWeight() {
+ return mWeight;
+ }
+
+ public void setWeight(int weight) {
+ mWeight = weight;
+ }
+
+ public int getQuantity() {
+ return mQuantity;
+ }
+
+ public void setQuantity(int quantity) {
+ mQuantity = quantity;
+ }
+
+ public boolean isContained(){
+ return mIsContained;
+ }
+
+ public void setIsContained(boolean isContained){
+ mIsContained = isContained;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/items/PTWeapon.java b/src/com/lateensoft/pathfinder/toolkit/items/PTWeapon.java
new file mode 100644
index 0000000..8314560
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/items/PTWeapon.java
@@ -0,0 +1,167 @@
+package com.lateensoft.pathfinder.toolkit.items;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+public class PTWeapon extends PTItem {
+ int mTotalAttackBonus;
+ String mDamage;
+ String mCritical;
+ int mRange;
+ String mSpecialProperties;
+ int mAmmunition;
+ String mType;
+ String mSize;
+
+ public PTWeapon() {
+ super();
+ mTotalAttackBonus = 0;
+ mDamage = new String("");
+ mCritical = new String("x2");
+ mRange = 5;
+ mSpecialProperties = new String("");
+ mAmmunition = 0;
+ mType = new String("");
+ mSize = "M";
+ }
+
+ public PTWeapon(String name) {
+ this();
+ mName = name;
+ }
+
+ /**
+ * @return the mTotalAttackBonus
+ */
+ public int getTotalAttackBonus() {
+ return mTotalAttackBonus;
+ }
+
+ /**
+ * @param mTotalAttackBonus the mTotalAttackBonus to set
+ */
+ public void setTotalAttackBonus(int mTotalAttackBonus) {
+ this.mTotalAttackBonus = mTotalAttackBonus;
+ }
+
+ public int getSizeInt() {
+ String[] sizeArray = {"S", "M", "L"};
+ for(int i = 0; i < sizeArray.length; i++) {
+ if(mSize.equals(sizeArray[i]))
+ return i;
+ }
+ return 1;
+ }
+
+ /**
+ * @return the mDamage
+ */
+ public String getDamage() {
+ return mDamage;
+ }
+
+ /**
+ * @param mDamage the mDamage to set
+ */
+ public void setDamage(String mDamage) {
+ this.mDamage = mDamage;
+ }
+
+ /**
+ * @return the mCritical
+ */
+ public String getCritical() {
+ return mCritical;
+ }
+
+ /**
+ * @param mCritical the mCritical to set
+ */
+ public void setCritical(String mCritical) {
+ this.mCritical = mCritical;
+ }
+
+ /**
+ * @return the mRange
+ */
+ public int getRange() {
+ return mRange;
+ }
+
+ /**
+ * @param mRange the mRange to set
+ */
+ public void setRange(int mRange) {
+ this.mRange = mRange;
+ }
+
+ /**
+ * @return the mSpecialProperties
+ */
+ public String getSpecialProperties() {
+ return mSpecialProperties;
+ }
+
+ /**
+ * @param mSpecialProperties the mSpecialProperties to set
+ */
+ public void setSpecialProperties(String mSpecialProperties) {
+ this.mSpecialProperties = mSpecialProperties;
+ }
+
+ /**
+ * @return the mAmmunition
+ */
+ public int getAmmunition() {
+ return mAmmunition;
+ }
+
+ /**
+ * @param mAmmunition the mAmmunition to set
+ */
+ public void setAmmunition(int mAmmunition) {
+ this.mAmmunition = mAmmunition;
+ }
+
+ /**
+ * @return the mType
+ */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * @param mType the mType to set
+ */
+ public void setType(String mType) {
+ this.mType = mType;
+ }
+
+ /**
+ * @return the mSize
+ */
+ public String getSize() {
+ return mSize;
+ }
+
+ /**
+ * @param mSize the mSize to set
+ */
+ public void setSize(String mSize) {
+ this.mSize = mSize;
+ }
+
+ public int getTypeInt(Context context) {
+ Resources r = context.getResources();
+ String[] options = r.getStringArray(R.array.weapon_type_options);
+ for(int i = 0; i < options.length; i++) {
+ if(mType.equals(options[i]))
+ return i;
+ }
+ return 0;
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTBasePartyMemberEditorActivity.java b/src/com/lateensoft/pathfinder/toolkit/party/PTBasePartyMemberEditorActivity.java
new file mode 100644
index 0000000..a8d3dc8
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTBasePartyMemberEditorActivity.java
@@ -0,0 +1,181 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+import com.lateensoft.pathfinder.toolkit.PTSharedMenu;
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.EditText;
+import android.widget.ListView;
+
+public class PTBasePartyMemberEditorActivity extends Activity implements OnClickListener, OnItemClickListener{
+
+ private final String TAG = "PTBasePartyMemberEditorActivity";
+ private final int MENU_ITEM_DONE = 0;
+ private final int MENU_ITEM_DELETE_MEMBER = 1;
+ protected final int DIALOG_MODE_EDIT_MEMBER = 0;
+ protected final int DIALOG_MODE_DELETE_MEMBER = 1;
+
+ protected PTPartyMember mPartyMember = null;
+ protected int mPartyMemberIndex = 0;
+ protected PTParty mParty = null;
+
+ protected EditText mPartyMemberNameEditText;
+ private ListView mStatList;
+
+ protected int mDialogMode;
+ private int mStatSelectedForEdit;
+ private EditText mDialogStatValue;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ setContentView(R.layout.activity_party_member_editor);
+
+ //Defaults to prevent null pointers
+ mPartyMember = new PTPartyMember("");
+
+
+ mPartyMemberNameEditText = (EditText) findViewById(R.id.editTextPartyMemberName);
+ mPartyMemberNameEditText.setText(mPartyMember.getName());
+
+ mStatList = (ListView) findViewById(R.id.listViewPartyMemberStats);
+ PTPartyMemberStatAdapter adapter = new PTPartyMemberStatAdapter(this, R.layout.party_member_stat_row,
+ mPartyMember.getStatFields(this), mPartyMember.getStatsArray());
+ mStatList.setAdapter(adapter);
+ mStatList.setOnItemClickListener(this);
+
+ mDialogMode = DIALOG_MODE_EDIT_MEMBER;
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ if (PTSharedMenu.onOptionsItemSelected(item, this) == false) {
+ // handle local menu items here
+
+ switch (item.getItemId()) {
+ case android.R.id.home: // Tapped the back button on the action bar to return to previous screen
+ finish();
+ break;
+ case MENU_ITEM_DONE:
+ finish();
+ break;
+ case MENU_ITEM_DELETE_MEMBER:
+ //Delete party
+ mDialogMode = DIALOG_MODE_DELETE_MEMBER;
+ showMemberDeleteDialog();
+ break;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+
+ MenuItem partyListItem = menu.add(Menu.NONE,
+ MENU_ITEM_DONE, Menu.NONE,
+ R.string.menu_item_done);
+ partyListItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ MenuItem deletePartyItem = menu.add(Menu.NONE,
+ MENU_ITEM_DELETE_MEMBER, Menu.NONE,
+ R.string.menu_item_delete_member);
+ deletePartyItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+
+ PTSharedMenu.onCreateOptionsMenu(menu, getApplicationContext());
+ return true;
+ }
+
+ public void showStatEditDialog(int position){
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ //Set up dialog layout
+ LayoutInflater inflater = getLayoutInflater();
+
+ View dialogView = inflater.inflate(R.layout.party_member_stat_dialog, null);
+ mDialogStatValue = (EditText) dialogView.findViewById(R.id.dialogStatText);
+
+ builder.setTitle(mPartyMember.getStatFields(this)[position]);
+ mDialogStatValue.setText(Integer.toString(mPartyMember.getValueByIndex(position)));
+
+ builder.setView(dialogView)
+ .setPositiveButton(R.string.ok_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ private void showMemberDeleteDialog(){
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ //Set up dialog layout
+ builder.setTitle("Delete Party Member");
+ builder.setMessage(getString(R.string.delete_character_dialog_message_1)+mPartyMember.getName()+
+ getString(R.string.delete_character_dialog_message_2))
+ .setPositiveButton(R.string.delete_button_text, this)
+ .setNegativeButton(R.string.cancel_button_text, this);
+
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ mStatSelectedForEdit = position;
+ mDialogMode = DIALOG_MODE_EDIT_MEMBER;
+ mPartyMember.setName(mPartyMemberNameEditText.getText().toString()); //Ensures name is not overwritten
+ showStatEditDialog(position);
+
+ }
+
+ public void onClick(DialogInterface dialogInterface, int selection) {
+ switch (selection) {
+ //OK button tapped
+ case DialogInterface.BUTTON_POSITIVE:
+
+ if(mDialogMode == DIALOG_MODE_EDIT_MEMBER){
+ try{
+ mPartyMember.setStatByIndex(mStatSelectedForEdit, Integer.parseInt(mDialogStatValue.getText().toString()));
+ updateStatsViews();
+ }catch (NumberFormatException e){
+ //Do nothing
+ }
+ }
+ else if(mDialogMode == DIALOG_MODE_DELETE_MEMBER){
+ mParty.deletePartyMember(mPartyMemberIndex);
+ finish();
+ }
+ break;
+ //Cancel Button tapped
+ case DialogInterface.BUTTON_NEGATIVE:
+ mDialogMode = DIALOG_MODE_EDIT_MEMBER;
+ break;
+ default:
+ mDialogMode = DIALOG_MODE_EDIT_MEMBER;
+ break;
+ }
+ }
+
+ public void updateStatsViews(){
+ ((PTPartyMemberStatAdapter)mStatList.getAdapter()).updateValues(mPartyMember.getStatsArray());
+ mPartyMemberNameEditText.setText(mPartyMember.getName());
+ }
+
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTEncounterMemberEditorActivity.java b/src/com/lateensoft/pathfinder/toolkit/party/PTEncounterMemberEditorActivity.java
new file mode 100644
index 0000000..d23d4ca
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTEncounterMemberEditorActivity.java
@@ -0,0 +1,53 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTUserPrefsManager;
+
+/**
+ * requires an intent with extras: R.string.party_member_index_key (int)
+ * @author trevsiemens
+ *
+ */
+public class PTEncounterMemberEditorActivity extends PTBasePartyMemberEditorActivity{
+
+ private final String TAG = "PTEncounterMemberEditorActivity";
+
+ private PTUserPrefsManager mUserPrefManager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mUserPrefManager = new PTUserPrefsManager(this);
+ getDataFromExtras();
+ }
+
+ protected void getDataFromExtras(){
+ Bundle extras = getIntent().getExtras();
+ if(extras != null){
+ mParty = mUserPrefManager.getEncounterParty();
+ if(mParty == null)
+ finish();
+ mPartyMemberIndex = extras.getInt(getString(R.string.party_member_index_key));
+ mPartyMember = mParty.getPartyMember(mPartyMemberIndex);
+ updateStatsViews();
+ }
+ else finish();
+ }
+
+ @Override
+ protected void onPause() {
+ if(mParty != null){
+ if(mDialogMode != DIALOG_MODE_DELETE_MEMBER){
+ mPartyMember.setName(mPartyMemberNameEditText.getText().toString());
+ mPartyMemberIndex = mParty.setPartyMember(mPartyMemberIndex, mPartyMember);
+ }
+ mUserPrefManager.setEncounterParty(mParty);
+ }
+ super.onPause();
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTParty.java b/src/com/lateensoft/pathfinder/toolkit/party/PTParty.java
new file mode 100644
index 0000000..90839df
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTParty.java
@@ -0,0 +1,233 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+import java.util.ArrayList;
+
+import android.util.Log;
+
+public class PTParty {
+
+ private final String TAG = "PTParty";
+ private ArrayList mPartyMembers;
+ private String mPartyName;
+ public int mID; //Used in SQL
+
+ public PTParty(String name){
+ mPartyMembers = new ArrayList();
+
+ if(name != null)
+ mPartyName = name;
+ else mPartyName = "";
+
+ mID = 0;
+ }
+
+ /**
+ * Adds party member into the party. The party member is inserted into the list alphabetically.
+ * @param newPartyMember
+ * @return the index of the character in the list. -1 if the addition failed
+ */
+ public int addPartyMember(PTPartyMember newPartyMember){
+ if( newPartyMember != null ){
+
+ for(int i = 0; i < mPartyMembers.size(); i++){
+ //Places in alphabetical position
+ if(newPartyMember.getName().compareToIgnoreCase(getPartyMember(i).getName()) < 0 ){
+ mPartyMembers.add(i, newPartyMember);
+ return i;
+ }
+ }
+ //If party member is to go at the end of the list
+ mPartyMembers.add(newPartyMember);
+ return mPartyMembers.size() - 1;
+ }
+ else return -1;
+ }
+
+ /**
+ *
+ * @param index
+ * @return returns the party member at index, in an alphabetical list of all party members
+ */
+ public PTPartyMember getPartyMember(int index){
+ if(index >= 0 && index < mPartyMembers.size())
+ return mPartyMembers.get(index);
+ else return null;
+ }
+
+ /**
+ * Replaces the party member at i with the entered one.
+ * The list remains alphabetical, even if the entered party member's name is of different priority than the one previously at i.
+ * @param i
+ * @param partyMember
+ * @return the new index of the character in the list. -1 if the set failed
+ */
+ public int setPartyMember(int index, PTPartyMember partyMember){
+ if(index >= 0 && index < mPartyMembers.size() && partyMember != null){
+ mPartyMembers.remove(index);
+ return addPartyMember(partyMember);
+ }
+ else return -1;
+ }
+
+ /**
+ * deletes the party member at index
+ * @param index
+ */
+ public void deletePartyMember(int index){
+ if(index >= 0 && index < mPartyMembers.size())
+ mPartyMembers.remove(index);
+ }
+
+ /**
+ *
+ * @return an array of all the party members' names
+ */
+ public String[] getPartyMemberNames(){
+ String names[] = new String[mPartyMembers.size()];
+ for(int i = 0; i < mPartyMembers.size(); i++){
+ names[i] = mPartyMembers.get(i).getName();
+ }
+
+ return names;
+ }
+
+ public void setName(String name){
+ if(name != null)
+ mPartyName = name;
+ }
+
+ public String getName(){
+ return mPartyName;
+ }
+
+ /**
+ *
+ * @return an array of the names of party members, ordered from highest roll, to lowest.
+ * If there is a tie, sorts by default order
+ */
+ public String[] getNamesByRollValue(){
+ PTPartyMember[] orderedMembers = getPartyMembersByRollValue();
+ String[] names = new String[mPartyMembers.size()];
+
+ //Set each value in the array
+ for(int i = 0; i < mPartyMembers.size(); i++){
+ names[i] = orderedMembers[i].getName();
+ }
+ return names;
+ }
+
+ /**
+ *
+ * @return an array of the roll values of party members, ordered from highest roll, to lowest.
+ * If there is a tie, sorts by default order
+ */
+ public int[] getRollValuesByRollValue(){
+ PTPartyMember[] orderedMembers = getPartyMembersByRollValue();
+ int[] rollValues = new int[mPartyMembers.size()];
+
+ //Set each value in the array
+ for(int i = 0; i < mPartyMembers.size(); i++){
+ rollValues[i] = orderedMembers[i].getRolledValue();
+ }
+ return rollValues;
+ }
+
+
+ /**
+ *
+ * @param index
+ * @return the "actual" index of the party, based on its index in the list sorted by roll
+ */
+ public int getPartyMemberIndexByRollValueIndex(int index){
+ if(index < mPartyMembers.size()){
+ int[] indexes = getIndexesByRollValue();
+ return indexes[index];
+ }
+ else return -1;
+ }
+
+ /**
+ * @return an array of party members, ordered from highest roll, to lowest.
+ * If there is a tie, sorts by default order
+ */
+ private PTPartyMember[] getPartyMembersByRollValue(){
+ ArrayList tempMembers = cloneMemberList();
+ PTPartyMember[] sortedMembers = new PTPartyMember[mPartyMembers.size()];
+
+ int currentLargestRoll;
+ int indexWithLargestRoll;
+
+ //Set each value in the array
+ for(int currentNamesIndex = 0; currentNamesIndex < mPartyMembers.size(); currentNamesIndex++){
+ currentLargestRoll = Integer.MIN_VALUE;
+ indexWithLargestRoll = 0;
+
+ //Find the largest value still in arraylist
+ for(int i = 0; i < tempMembers.size(); i++){
+ if(tempMembers.get(i).getRolledValue() > currentLargestRoll){
+ indexWithLargestRoll = i;
+ currentLargestRoll = tempMembers.get(i).getRolledValue();
+ }
+ }
+ sortedMembers[currentNamesIndex] = new PTPartyMember(tempMembers.get(indexWithLargestRoll));
+ tempMembers.remove(indexWithLargestRoll);
+ }
+ return sortedMembers;
+ }
+
+ /**
+ * @return an array of the unsorted indexes of the party members, ordered as the characters are when sorted by roll
+ */
+ public int[] getIndexesByRollValue(){
+ ArrayList tempMembers = cloneMemberList();
+ ArrayList tempIndexes = new ArrayList();
+ int[] sortedIndexes = new int[mPartyMembers.size()];
+ for(int j = 0; j < mPartyMembers.size(); j++){
+ tempIndexes.add(Integer.valueOf(j));
+ }
+
+ int currentLargestRoll;
+ int indexWithLargestRoll;
+
+ //Set each value in the array
+ for(int currentNamesIndex = 0; currentNamesIndex < mPartyMembers.size(); currentNamesIndex++){
+ currentLargestRoll = Integer.MIN_VALUE;
+ indexWithLargestRoll = 0;
+
+ //Find the largest value still in arraylist
+ for(int i = 0; i < tempMembers.size(); i++){
+ if(tempMembers.get(i).getRolledValue() > currentLargestRoll){
+ indexWithLargestRoll = i;
+ currentLargestRoll = tempMembers.get(i).getRolledValue();
+ }
+ }
+ sortedIndexes[currentNamesIndex] = tempIndexes.get(indexWithLargestRoll).intValue();
+ tempMembers.remove(indexWithLargestRoll);
+ tempIndexes.remove(indexWithLargestRoll);
+ }
+ return sortedIndexes;
+ }
+
+ /**
+ *
+ * @return a deep copy of the member array list
+ */
+ private ArrayList cloneMemberList(){
+ int numberOfMembers = mPartyMembers.size();
+ ArrayList membersListClone = new ArrayList();
+
+ for(int i = 0; i < numberOfMembers; i++){
+ PTPartyMember tempMember = new PTPartyMember(mPartyMembers.get(i));
+ membersListClone.add(tempMember);
+ }
+ return membersListClone;
+ }
+
+ /**
+ *
+ * @return the number of party members in the party
+ */
+ public int size(){
+ return mPartyMembers.size();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMember.java b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMember.java
new file mode 100644
index 0000000..c381a82
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMember.java
@@ -0,0 +1,379 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+
+public class PTPartyMember {
+
+ private String mName;
+ private int mInitiative;
+ private int mAC;
+ private int mTouch;
+ private int mFlatFooted;
+ private int mSpellResist;
+ private int mDamageReduction;
+ private int mCMD;
+ private int mFortSave;
+ private int mReflexSave;
+ private int mWillSave;
+ private int mBluffSkillBonus;
+ private int mDisguiseSkillBonus;
+ private int mPerceptionSkillBonus;
+ private int mSenseMotiveSkillBonus;
+ private int mStealthSkillBonus;
+
+ private int mRolledValue;//Cheating!
+
+ public PTPartyMember(String name){
+ if(name != null)
+ mName = name;
+ else
+ mName = "";
+
+ mInitiative = 0;
+ mAC = 0;
+ mTouch = 0;
+ mFlatFooted = 0;
+ mSpellResist = 0;
+ mDamageReduction = 0;
+ mCMD = 0;
+ mFortSave = 0;
+ mReflexSave = 0;
+ mWillSave = 0;
+ mBluffSkillBonus = 0;
+ mDisguiseSkillBonus = 0;
+ mPerceptionSkillBonus = 0;
+ mSenseMotiveSkillBonus = 0;
+ mStealthSkillBonus = 0;
+
+ mRolledValue = 0; //Will be set in roller activities only
+ }
+
+ /**
+ * returns a deep copy of memberToCopy
+ */
+ public PTPartyMember(PTPartyMember memberToCopy){
+ mName = new String(memberToCopy.getName());
+ mInitiative = memberToCopy.getInitiative();
+ mAC = memberToCopy.getAC();
+ mTouch = memberToCopy.getTouch();
+ mFlatFooted = memberToCopy.getFlatFooted();
+ mSpellResist = memberToCopy.getSpellResist();
+ mDamageReduction = memberToCopy.getDamageReduction();
+ mCMD = memberToCopy.getCMD();
+ mFortSave = memberToCopy.getFortSave();
+ mReflexSave = memberToCopy.getReflexSave();
+ mWillSave = memberToCopy.getWillSave();
+ mBluffSkillBonus = memberToCopy.getBluffSkillBonus();
+ mDisguiseSkillBonus = memberToCopy.getDisguiseSkillBonus();
+ mPerceptionSkillBonus = memberToCopy.getPerceptionSkillBonus();
+ mSenseMotiveSkillBonus = memberToCopy.getSenseMotiveSkillBonus();
+ mStealthSkillBonus = memberToCopy.getStealthSkillBonus();
+ mRolledValue = memberToCopy.getRolledValue();
+ }
+
+
+ /**
+ *
+ * @return an array of the party member's stats, ordered as:
+ * 0:Initiative,
+ * 1:AC,
+ * 2:Touch,
+ * 3:Flat Footed,
+ * 4:Spell Resist,
+ * 5:Damage Reduction,
+ * 6:CMD,
+ * 7:Fort save
+ * 8:Reflex save
+ * 9:Will Save
+ * 10:Bluff,
+ * 11:Disguise,
+ * 12:Perception Skill Bonus,
+ * 13:Sense Motive,
+ * 14:Stealth
+ */
+ public int[] getStatsArray(){
+ int[] stats = {mInitiative, mAC, mTouch, mFlatFooted, mSpellResist, mDamageReduction, mCMD, mFortSave, mReflexSave, mWillSave,
+ mBluffSkillBonus, mDisguiseSkillBonus, mPerceptionSkillBonus, mSenseMotiveSkillBonus, mStealthSkillBonus};
+ return stats;
+ }
+
+ /**
+ * sets a stat by its assigned "index", ordered as:
+ * 0:Initiative
+ * 1:AC,
+ * 2:Touch,
+ * 3:Flat Footed,
+ * 4:Spell Resist,
+ * 5:Damage Reduction,
+ * 6:CMD,
+ * 7:Bluff,
+ * 8:Disguise,
+ * 9:Perception Skill Bonus,
+ * 10:Sense Motive,
+ * 11:Stealth
+ * @param index
+ * @param value
+ */
+ public void setStatByIndex(int index, int value){
+ switch(index){
+ case 0:
+ mInitiative = value;
+ break;
+ case 1:
+ mAC = value;
+ break;
+ case 2:
+ mTouch = value;
+ break;
+ case 3:
+ mFlatFooted = value;
+ break;
+ case 4:
+ mSpellResist = value;
+ break;
+ case 5:
+ mDamageReduction = value;
+ break;
+ case 6:
+ mCMD = value;
+ break;
+ case 7:
+ mFortSave = value;
+ break;
+ case 8:
+ mReflexSave = value;
+ break;
+ case 9:
+ mWillSave = value;
+ break;
+ case 10:
+ mBluffSkillBonus = value;
+ break;
+ case 11:
+ mDisguiseSkillBonus = value;
+ break;
+ case 12:
+ mPerceptionSkillBonus = value;
+ break;
+ case 13:
+ mSenseMotiveSkillBonus = value;
+ break;
+ case 14:
+ mStealthSkillBonus = value;
+ break;
+ }
+ }
+
+ /**
+ *
+ * @param index
+ * @return the value of the stat with "index", as follows:
+ * 0:Initiative
+ * 1:AC,
+ * 2:Touch,
+ * 3:Flat Footed,
+ * 4:Spell Resist,
+ * 5:Damage Reduction,
+ * 6:CMD,
+ * 7:Fort save
+ * 8:Reflex save
+ * 9:Will save
+ * 10:Bluff,
+ * 11:Disguise,
+ * 12:Perception Skill Bonus,
+ * 13:Sense Motive,
+ * 14:Stealth
+ *
+ */
+ public int getValueByIndex(int index){
+ switch(index){
+ case 0:
+ return mInitiative;
+ case 1:
+ return mAC;
+ case 2:
+ return mTouch;
+ case 3:
+ return mFlatFooted;
+ case 4:
+ return mSpellResist;
+ case 5:
+ return mDamageReduction;
+ case 6:
+ return mCMD;
+ case 7:
+ return mFortSave;
+ case 8:
+ return mReflexSave;
+ case 9:
+ return mWillSave;
+ case 10:
+ return mBluffSkillBonus;
+ case 11:
+ return mDisguiseSkillBonus;
+ case 12:
+ return mPerceptionSkillBonus;
+ case 13:
+ return mSenseMotiveSkillBonus;
+ case 14:
+ return mStealthSkillBonus;
+ default:
+ return 0;
+ }
+ }
+
+ public String[] getStatFields(Context context){
+ Resources r = context.getResources();
+ return r.getStringArray(R.array.party_member_stats);
+ }
+
+ public String getName() {
+ if(mName != null)
+ return mName;
+ else{
+ mName = new String("");
+ return mName;
+ }
+ }
+
+ public void setName(String name) {
+ if(name != null)
+ this.mName = name;
+ }
+
+ public int getInitiative() {
+ return mInitiative;
+ }
+
+ public void setInitiative(int initiative) {
+ this.mInitiative = initiative;
+ }
+
+ public int getAC() {
+ return mAC;
+ }
+
+ public void setAC(int AC) {
+ this.mAC = AC;
+ }
+
+ public int getTouch() {
+ return mTouch;
+ }
+
+ public void setTouch(int touch) {
+ this.mTouch = touch;
+ }
+
+ public int getFlatFooted() {
+ return mFlatFooted;
+ }
+
+ public void setFlatFooted(int flatFooted) {
+ this.mFlatFooted = flatFooted;
+ }
+
+ public int getSpellResist() {
+ return mSpellResist;
+ }
+
+ public void setSpellResist(int spellResist) {
+ this.mSpellResist = spellResist;
+ }
+
+ public int getDamageReduction() {
+ return mDamageReduction;
+ }
+
+ public void setDamageReduction(int damageReduction) {
+ this.mDamageReduction = damageReduction;
+ }
+
+ public int getCMD() {
+ return mCMD;
+ }
+
+ public void setCMD(int CMD) {
+ this.mCMD = CMD;
+ }
+
+ public int getFortSave() {
+ return mFortSave;
+ }
+
+ public void setFortSave(int FortSave) {
+ this.mFortSave = FortSave;
+ }
+
+ public int getReflexSave() {
+ return mReflexSave;
+ }
+
+ public void setFeflexSave(int reflexSave) {
+ this.mReflexSave = reflexSave;
+ }
+
+ public int getWillSave() {
+ return mWillSave;
+ }
+
+ public void setWillSave(int willSave) {
+ this.mWillSave = willSave;
+ }
+
+ public int getBluffSkillBonus() {
+ return mBluffSkillBonus;
+ }
+
+ public void setBluffSkillBonus(int bluffSkillBonus) {
+ this.mBluffSkillBonus = bluffSkillBonus;
+ }
+
+ public int getDisguiseSkillBonus() {
+ return mDisguiseSkillBonus;
+ }
+
+ public void setDisguiseSkillBonus(int disguiseSkillBonus) {
+ this.mDisguiseSkillBonus = disguiseSkillBonus;
+ }
+
+ public int getPerceptionSkillBonus() {
+ return mPerceptionSkillBonus;
+ }
+
+ public void setPerceptionSkillBonus(int perceptionSkillBonus) {
+ this.mPerceptionSkillBonus = perceptionSkillBonus;
+ }
+
+ public int getSenseMotiveSkillBonus() {
+ return mSenseMotiveSkillBonus;
+ }
+
+ public void setSenseMotiveSkillBonus(int senseMotiveSkillBonus) {
+ this.mSenseMotiveSkillBonus = senseMotiveSkillBonus;
+ }
+
+ public int getStealthSkillBonus() {
+ return mStealthSkillBonus;
+ }
+
+ public void setStealthSkillBonus(int stealthSkillBonus) {
+ this.mStealthSkillBonus = stealthSkillBonus;
+ }
+
+
+ public int getRolledValue() {
+ return mRolledValue;
+ }
+
+
+
+ public void setRolledValue(int rolledVal) {
+ this.mRolledValue = rolledVal;
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMemberEditorActivity.java b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMemberEditorActivity.java
new file mode 100644
index 0000000..3834482
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMemberEditorActivity.java
@@ -0,0 +1,55 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+
+import com.lateensoft.pathfinder.toolkit.R;
+import com.lateensoft.pathfinder.toolkit.datahelpers.PTDatabaseManager;
+
+
+import android.os.Bundle;
+import android.util.Log;
+
+
+/**
+ * requires an intent with extras: R.string.party_member_index_key (int) and R.string.party_id_key (int)
+ * @author trevsiemens
+ *
+ */
+public class PTPartyMemberEditorActivity extends PTBasePartyMemberEditorActivity{
+ private final String TAG = "PTPartyMemberEditorActivity";
+
+ private PTDatabaseManager mSQLManager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mSQLManager = new PTDatabaseManager(this.getApplicationContext());
+ getDataFromExtras();
+ }
+
+ protected void getDataFromExtras(){
+ Bundle extras = getIntent().getExtras();
+ if(extras != null){
+ mPartyMemberIndex = extras.getInt(getString(R.string.party_member_index_key));
+ int partyID = extras.getInt(getString(R.string.party_id_key));
+ mParty = mSQLManager.getParty(partyID);
+ mPartyMember = mParty.getPartyMember(mPartyMemberIndex);
+ updateStatsViews();
+ }
+ else finish();
+ }
+
+
+
+ @Override
+ protected void onPause() {
+ if(mParty != null){
+ if(mDialogMode != DIALOG_MODE_DELETE_MEMBER){
+ mPartyMember.setName(mPartyMemberNameEditText.getText().toString());
+ mPartyMemberIndex = mParty.setPartyMember(mPartyMemberIndex, mPartyMember);
+ }
+ mSQLManager.updateParty(mParty);
+ }
+ super.onPause();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMemberStatAdapter.java b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMemberStatAdapter.java
new file mode 100644
index 0000000..c6e1aa8
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyMemberStatAdapter.java
@@ -0,0 +1,65 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTPartyMemberStatAdapter extends ArrayAdapter{
+ Context mContext;
+ int mLayoutResourceId;
+ int[] mStatValues = null;
+ String[] mStatNames = null;
+ String TAG = "PTPartyMemberStatAdapter";
+
+ public PTPartyMemberStatAdapter(Context context, int layoutResourceId, String[] statNames, int[] statValues) {
+ super(context, layoutResourceId, statNames);
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mStatValues = statValues;
+ mStatNames = statNames;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ PartyMemberStatHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new PartyMemberStatHolder();
+
+ holder.label = (TextView)row.findViewById(R.id.partyMemberStatLabel);
+ holder.value = (TextView)row.findViewById(R.id.partyMemberStatValue);
+
+ row.setTag(holder);
+ }
+ else {
+ holder = (PartyMemberStatHolder)row.getTag();
+ }
+
+ Resources r = mContext.getResources();
+ holder.label.setText(r.getStringArray(R.array.party_member_stats)[position]);
+ holder.value.setText(Integer.toString(mStatValues[position]));
+
+ return row;
+ }
+
+ static class PartyMemberStatHolder {
+ TextView label;
+ TextView value;
+ }
+
+ public void updateValues(int[] newStatValues){
+ mStatValues = newStatValues;
+ notifyDataSetChanged();
+ }
+
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/party/PTPartyRollAdapter.java b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyRollAdapter.java
new file mode 100644
index 0000000..b97fb90
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/party/PTPartyRollAdapter.java
@@ -0,0 +1,87 @@
+package com.lateensoft.pathfinder.toolkit.party;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTPartyRollAdapter extends ArrayAdapter{
+ public static final int CRIT_FUMBLE = -1;
+ public static final int NO_CRIT = 0;
+ public static final int CRIT = 1;
+
+ Context mContext;
+ int mLayoutResourceId;
+ int[] mRollValues = null;
+ int[] mCritValues = null;
+ String[] mCharacterNames = null;
+ String TAG = "PTPartyMemberStatAdapter";
+
+ /**
+ *
+ * @param context
+ * @param layoutResourceId
+ * @param characterNames
+ * @param rollValues
+ * @param critValues CRUIT_FUMBLE, NO_CRIT, CRIT. if null, all considered NO_CRIT
+ */
+ public PTPartyRollAdapter(Context context, int layoutResourceId, String[] characterNames,
+ int[] rollValues, int[]critValues) {
+ super(context, layoutResourceId, characterNames);
+ mLayoutResourceId = layoutResourceId;
+ mContext = context;
+ mRollValues = rollValues;
+ mCharacterNames = characterNames;
+ mCritValues = critValues;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ CharacterRollHolder holder;
+
+ if(row == null) {
+ LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
+ row = inflater.inflate(mLayoutResourceId, parent, false);
+ holder = new CharacterRollHolder();
+
+ holder.name = (TextView)row.findViewById(R.id.textViewRollName);
+ holder.rollValue = (TextView)row.findViewById(R.id.textViewRollValue);
+
+ row.setTag(holder);
+ }
+ else {
+ holder = (CharacterRollHolder)row.getTag();
+ }
+
+ holder.name.setText(mCharacterNames[position]);
+ holder.rollValue.setText(Integer.toString(mRollValues[position]));
+
+ if(mCritValues != null){
+ if(mCritValues[position] == CRIT_FUMBLE){
+ holder.rollValue.setTextColor(Color.RED);
+ }
+ else if(mCritValues[position] == CRIT){
+ holder.rollValue.setTextColor(Color.GREEN);
+ }
+ }
+
+ return row;
+ }
+
+ static class CharacterRollHolder {
+ TextView name;
+ TextView rollValue;
+ }
+
+ public void updateRollValues(int[] newRollValues){
+ mRollValues = newRollValues;
+ notifyDataSetChanged();
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilityModSet.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilityModSet.java
new file mode 100644
index 0000000..764ca4a
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilityModSet.java
@@ -0,0 +1,78 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+
+public class PTAbilityModSet extends PTAbilitySet{
+ private static final String TAG = "PTAbilitySet";
+
+ public PTAbilityModSet() {
+ super();
+ }
+
+ public void setMod(String ability, int score) {
+ super.setScore(ability, score);
+ }
+
+ public int getMod(String ability) {
+ return super.getScore(ability);
+ }
+
+ public int[] getMods() {
+ return super.getScores();
+ }
+
+ public void setMods(int[] modifiers) {
+ if(modifiers.length != super.getLength())
+ return;
+
+ super.setScores(modifiers);
+ }
+
+ // Returns boolean of isHuman
+ public boolean setRacialMods(int index, Context context) {
+
+ Resources r = context.getResources();
+
+ switch (index) {
+ case 0:
+ super.setScores(r.getIntArray(R.array.HumanMods));
+ return true;
+
+ case 1:
+ super.setScores(r.getIntArray(R.array.DwarfMods));
+ return false;
+
+ case 2:
+ super.setScores(r.getIntArray(R.array.ElfMods));
+ return false;
+
+ case 3:
+ super.setScores(r.getIntArray(R.array.HalflingMods));
+ return false;
+
+ case 4:
+ super.setScores(r.getIntArray(R.array.GnomeMods));
+ return false;
+
+ case 5:
+ super.setScores(r.getIntArray(R.array.HalfElfMods));
+ return true;
+
+ default:
+ super.setScores(r.getIntArray(R.array.HumanMods));
+ return true;
+
+ }
+ }
+
+ public void setHumanRacialMods(int index, Context context) {
+ Resources r = context.getResources();
+ super.setScores(r.getIntArray(R.array.HumanMods));
+ setScore(index, 2);
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilityScore.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilityScore.java
new file mode 100644
index 0000000..8447ebb
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilityScore.java
@@ -0,0 +1,77 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+
+public class PTAbilityScore {
+ private String mAbility;
+ private int mScore;
+ private static final String TAG = "PTAbilityScore";
+
+ public PTAbilityScore(String ability, int score) {
+ mAbility = ability;
+ mScore = score;
+ }
+
+ public int getScore() {
+ return mScore;
+ }
+
+ public String getAbility() {
+ return mAbility;
+ }
+
+ public void setScore(int score) {
+ mScore = score;
+ }
+
+ public void setAbility(String ability) {
+ mAbility = ability;
+ }
+
+ public int getModifier() {
+ float temp = (float) ((mScore - 10)/2.0);
+ if (temp < 0) {
+ return (int) (temp - 0.5);
+ } else {
+ return (int) temp;
+ }
+ }
+
+ public void incScore() {
+ if ((mScore + 1) > 18) {
+ return;
+ } else {
+ mScore++;
+ return;
+ }
+ }
+
+ public void decScore() {
+ if ((mScore - 1) < 7) {
+ return;
+ } else {
+ mScore--;
+ return;
+ }
+ }
+
+ // Takes a raw ability score
+ // Returns the point cost
+ public int getAbilityPointCost() {
+ if (mScore <= -7) {
+ return -3;
+ } else if (mScore == 8) {
+ return -2;
+ } else if (mScore == 9) {
+ return -1;
+ } else if (mScore <= 13) {
+ return mScore - 10;
+ } else if (mScore <= 15) {
+ return (2 * (mScore - 14)) + 5;
+ } else if (mScore <= 17) {
+ return (3 * (mScore - 16)) + 10;
+ } else {
+ return 17;
+ }
+
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilitySet.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilitySet.java
new file mode 100644
index 0000000..f4eccb8
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilitySet.java
@@ -0,0 +1,88 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+
+
+public class PTAbilitySet {
+ private PTAbilityScore[] mAbilities;
+ static final String[] ABILITY_NAMES = {"Strength", "Dexterity", "Constitution",
+ "Intelligence", "Wisdom", "Charisma"};
+ static final int BASE_ABILITY_SCORE = 10;
+ private static final String TAG = "PTAbilitySet";
+
+ public PTAbilitySet() {
+ //Resources res = android.content.res.Resources.getSystem();
+ //String[] names = res.getStringArray(R.array.abilities);
+ //int base_ability = res.getInteger(R.integer.base_ability_score);
+ mAbilities = new PTAbilityScore[ABILITY_NAMES.length];
+
+ for(int i = 0; i < ABILITY_NAMES.length; i++) {
+ mAbilities[i] = new PTAbilityScore(ABILITY_NAMES[i], BASE_ABILITY_SCORE);
+ }
+ }
+
+ // Given a string ability name and a score, sets the
+ // ability score with the matching ability string
+ // to have the given score
+ public void setScore(String ability, int score) {
+ for(int i = 0; i < mAbilities.length; i++) {
+ if(ability.equals(mAbilities[i].getAbility())) {
+ mAbilities[i].setScore(score);
+ return;
+ }
+ }
+ }
+
+ public void setScore(int index, int score) {
+ mAbilities[index].setScore(score);
+ }
+
+ public void setScores(int[] scores) {
+ if(scores.length != mAbilities.length)
+ return;
+
+ for(int i = 0; i < mAbilities.length; i++) {
+ mAbilities[i].setScore(scores[i]);
+ }
+ }
+
+ // Returns the score for the corresponding ability
+ // or zero if such an ability does not exist in the set
+ public int getScore(String ability) {
+ for(int i = 0; i < mAbilities.length; i++) {
+ if(ability.equals(mAbilities[i].getAbility())) {
+ return mAbilities[i].getScore();
+ }
+ }
+ return 0;
+ }
+
+ // Returns an array of strings corresponding to the abilities
+ // in the set
+ public String[] getAbilities() {
+ String[] abilities = new String[mAbilities.length];
+ for(int i = 0; i < mAbilities.length; i++) {
+ abilities[i] = mAbilities[i].getAbility();
+ }
+ return abilities;
+ }
+
+ // Returns an array of scores corresponding to the abilities
+ // in the set
+ public int[] getScores() {
+ int[] scores = new int[mAbilities.length];
+ for(int i = 0; i < mAbilities.length; i++) {
+ scores[i] = mAbilities[i].getScore();
+ }
+ return scores;
+ }
+
+ public PTAbilityScore getAbilityScore(int index) {
+ if( index >=0 && index <= mAbilities.length)
+ return mAbilities[index];
+ return mAbilities[0];
+ }
+
+ public int getLength(){
+ return mAbilities.length;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilitySetCalc.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilitySetCalc.java
new file mode 100644
index 0000000..361a92a
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTAbilitySetCalc.java
@@ -0,0 +1,88 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+import android.util.Log;
+
+
+public class PTAbilitySetCalc extends PTAbilitySet {
+ private PTAbilityScore[] mAbilitiesPostMods;
+ private static final String TAG = "Ability set calc class";
+
+ public PTAbilitySetCalc() {
+ super();
+
+ //Resources res = android.content.res.Resources.getSystem();
+ //int base_ability = res.getInteger(R.integer.base_ability_score);
+ mAbilitiesPostMods = new PTAbilityScore[ABILITY_NAMES.length];
+
+ for(int i = 0; i < ABILITY_NAMES.length; i++) {
+ mAbilitiesPostMods[i] = new PTAbilityScore(ABILITY_NAMES[i], BASE_ABILITY_SCORE);
+ }
+ }
+
+ // Returns the point buy cost of the set
+ public int getPointBuyCost() {
+ int total = 0;
+ for(int i = 0; i < super.getLength(); i++) {
+ total += super.getAbilityScore(i).getAbilityPointCost();
+ }
+
+ return total;
+ }
+
+ // Increments the ability score with the corresponding
+ // ability string, if it is valid to do so
+ public void incAbilityScore(String ability) {
+ for(int i = 0; i < super.getLength(); i++) {
+ if(ability.equals(super.getAbilityScore(i).getAbility())) {
+ super.getAbilityScore(i).incScore();
+ return;
+ }
+ }
+ }
+
+ // Increments the ability score with the corresponding
+ // ability string, if it is valid to do so
+ public void decAbilityScore(String ability) {
+ for(int i = 0; i < super.getLength(); i++) {
+ if(ability.equals(super.getAbilityScore(i).getAbility())) {
+ super.getAbilityScore(i).decScore();
+ return;
+ }
+ }
+ }
+
+ public void applyMods(PTAbilityModSet modSet) {
+ int[] mods = modSet.getMods();
+ int[] baseAbilities = super.getScores();
+
+ if(mods.length != baseAbilities.length) {
+ return;
+ }
+
+ for(int i = 0; i < mAbilitiesPostMods.length; i++) {
+ mAbilitiesPostMods[i].setScore(mods[i] + baseAbilities[i]);
+ }
+ }
+
+ public int[] getScoresPostMods() {
+ int[] scores = new int[mAbilitiesPostMods.length];
+ for(int i = 0; i < mAbilitiesPostMods.length; i++) {
+ scores[i] = mAbilitiesPostMods[i].getScore();
+ }
+ return scores;
+ }
+
+ public int getScorePostMod(int index) {
+ return mAbilitiesPostMods[index].getScore();
+ }
+
+ public PTAbilityScore getAbilityScorePostMod(int index) {
+ return mAbilitiesPostMods[index];
+ }
+
+ public PTAbilitySet getAbilitySetPostMods() {
+ PTAbilitySet abilitySet = new PTAbilitySet();
+ abilitySet.setScores(this.getScoresPostMods());
+ return abilitySet;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTCombatStatSet.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTCombatStatSet.java
new file mode 100644
index 0000000..7edef51
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTCombatStatSet.java
@@ -0,0 +1,266 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+public class PTCombatStatSet {
+ private int mTotalHP;
+ private int mWounds;
+ private int mNonLethalDamage;
+ private int mDamageReduction;
+ private int mBaseSpeedFt;
+ //may need other for speed
+
+ private int mInitDexMod;
+ private int mInitMiscMod;
+
+ private int mACArmour;
+ private int mACShield;
+ private int mACDexMod;
+ private int mSizeMod;
+ private int mACNaturalArmour;
+ private int mDeflectionMod;
+ private int mACMiscMod;
+
+ private int mBABPrimary;
+ private String mBABSecondary;
+ private int mStrengthMod;
+ private int mCMDDexMod;
+
+ private int mSpellResist;
+
+ public PTCombatStatSet(){
+ mTotalHP = 0;
+ mWounds = 0;
+ mNonLethalDamage = 0;
+ mDamageReduction = 0;
+ mBaseSpeedFt = 0;
+
+ mInitDexMod = 0;
+ mInitMiscMod = 0;
+
+ mACArmour = 0;
+ mACShield = 0;
+ mACDexMod = 0;
+ mSizeMod = 0;
+ mACNaturalArmour = 0;
+ mDeflectionMod = 0;
+ mACMiscMod = 0;
+
+ mBABPrimary = 0;
+ mBABSecondary = "";
+ mStrengthMod = 0;
+ mACDexMod = 0;
+
+ mSpellResist = 0;
+ }
+
+
+ public void setTotalHP(int totalHP){
+ mTotalHP = totalHP;
+ }
+
+ public int getTotalHP(){
+ return mTotalHP;
+ }
+
+ public void setWounds(int wounds){
+ mWounds = wounds;
+ }
+
+ public int getWounds(){
+ return mWounds;
+ }
+
+ public void setNonLethalDamage(int nonlethalDamage){
+ mNonLethalDamage = nonlethalDamage;
+ }
+
+ public int getNonLethalDamage(){
+ return mNonLethalDamage;
+ }
+
+ public int getCurrentHP(){
+ return mTotalHP - mWounds - mNonLethalDamage;
+ }
+
+ public void setDamageReduction(int damageReduction){
+ mDamageReduction = damageReduction;
+ }
+
+ public int getDamageReduction(){
+ return mDamageReduction;
+ }
+
+ public void setBaseSpeed(int baseSpeedInFeet){
+ mBaseSpeedFt = baseSpeedInFeet;
+ }
+
+ public int getBaseSpeed(){
+ return mBaseSpeedFt;
+ }
+
+ public void setInitDexMod(int dexMod){
+ mInitDexMod = dexMod;
+ }
+
+ public int getInitDexMod(){
+ return mInitDexMod;
+ }
+
+ public void setInitiativeMiscMod(int initMiscMod){
+ mInitMiscMod = initMiscMod;
+ }
+
+ public int getInitiativeMiscMod(){
+ return mInitMiscMod;
+ }
+
+ public int getInitiativeMod(){
+ return mInitDexMod + mInitMiscMod;
+ }
+
+ public void setACArmourBonus(int armourBonus){
+ mACArmour = armourBonus;
+ }
+
+ public int getACArmourBonus(){
+ return mACArmour;
+ }
+
+ public void setACShieldBonus(int shieldBonus){
+ mACShield = shieldBonus;
+ }
+
+ public int getACShieldBonus(){
+ return mACShield;
+ }
+
+ public void setACDexMod(int dexMod){
+ mACDexMod = dexMod;
+ }
+
+ public int getACDexMod(){
+ return mACDexMod;
+ }
+
+ public void setSizeModifier(int sizeMod){
+ mSizeMod = sizeMod;
+ }
+
+ public int getSizeModifier(){
+ return mSizeMod;
+ }
+
+ public void setNaturalArmour(int naturalArmour){
+ mACNaturalArmour = naturalArmour;
+ }
+
+ public int getNaturalArmour(){
+ return mACNaturalArmour;
+ }
+
+ public void setDeflectionMod(int deflectionMod){
+ mDeflectionMod = deflectionMod;
+ }
+
+ public int getDeflectionMod(){
+ return mDeflectionMod;
+ }
+
+ public void setACMiscMod(int miscMod){
+ mACMiscMod = miscMod;
+ }
+
+ public int getACMiscMod(){
+ return mACMiscMod;
+ }
+
+ /**
+ *
+ * @return the net AC of the character. This is 10 + armour + shield + dexmod + sizemod + natural + defect + misc
+ */
+ public int getTotalAC(){
+ return 10 + mACArmour + mACShield + mACDexMod + mSizeMod + mACNaturalArmour + mDeflectionMod + mACMiscMod;
+ }
+
+ /**
+ *
+ * @return the touch AC of the character. This is 10 + dexmod + sizemod + defect + misc
+ */
+ public int getTouchAC(){
+ return 10 + mACDexMod + mSizeMod + mDeflectionMod + mACMiscMod;
+ }
+
+ /**
+ *
+ * @return the touch AC of the character. This is normal AC - dexmod
+ */
+ public int getFlatFootedAC(){
+ return getTotalAC() - mACDexMod;
+ }
+
+
+ /**
+ * Used to set the Base Attack Bonus for first attack. Sometimes referred to as "full" BAB
+ * @param BABPrimary
+ */
+ public void setBABPrimary(int BABPrimary){
+ mBABPrimary = BABPrimary;
+ }
+
+ public int getBABPrimary(){
+ return mBABPrimary;
+ }
+
+ /**
+ * Sets the representation of the Base Attack Bonus for attacks after the first.
+ * If a character has a BAB of x/y/z, this should be in the format of y/z
+ * @param BABSecondary
+ */
+ public void setBABSecondary(String BABSecondary){
+ if(BABSecondary != null)
+ mBABSecondary = BABSecondary;
+ }
+
+ public String getBABSecondary(){
+ return mBABSecondary;
+ }
+
+ public void setStrengthMod(int strengthMod){
+ mStrengthMod = strengthMod;
+ }
+
+ public int getStrengthMod(){
+ return mStrengthMod;
+ }
+
+ public void setCMDDexMod(int dexMod){
+ mCMDDexMod = dexMod;
+ }
+
+ public int getCMDDexMod(){
+ return mCMDDexMod;
+ }
+
+ public void setSpellResistance(int spellResist){
+ mSpellResist = spellResist;
+ }
+
+ public int getSpellResist(){
+ return mSpellResist;
+ }
+
+ /**
+ *
+ * @return CMB = BAB + Strength mod + size mod
+ */
+ public int getCombatManeuverBonus(){
+ return mBABPrimary + mStrengthMod + mSizeMod;
+ }
+
+ /**
+ *
+ * @return CMD = BAB + Strength mod + size mod + dex mod + 10
+ */
+ public int getCombatManeuverDefense(){
+ return getCombatManeuverBonus() + mCMDDexMod + 10;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTSave.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTSave.java
new file mode 100644
index 0000000..5e348a2
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTSave.java
@@ -0,0 +1,110 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+public class PTSave extends PTStat {
+ int mTotal;
+ int mAbilityMod;
+ int mMagicMod;
+ int mMiscMod;
+ int mTempMod;
+
+ public PTSave() {
+ super();
+ mAbilityMod = 0;
+ mMagicMod = 0;
+ mMiscMod = 0;
+ mTempMod = 0;
+ calculateTotal();
+ }
+
+ public PTSave(String name) {
+ super(name);
+ mAbilityMod = 0;
+ mMagicMod = 0;
+ mMiscMod = 0;
+ mTempMod = 0;
+ calculateTotal();
+ }
+
+ public PTSave(String name, int baseValue, int abilityMod, int magicMod,
+ int miscMod, int tempMod) {
+ super(name, baseValue);
+ mAbilityMod = abilityMod;
+ mMagicMod = magicMod;
+ mMiscMod = miscMod;
+ mTempMod = tempMod;
+ }
+
+ public PTSave(String name, int baseValue, int[] modArray) {
+ super(name, baseValue);
+
+ if(modArray.length >= 4) {
+ mAbilityMod = modArray[0];
+ mMagicMod = modArray[1];
+ mMiscMod = modArray[2];
+ mTempMod = modArray[3];
+ }
+ }
+
+ public PTSave(PTSave other) {
+ super(other);
+ mAbilityMod = other.getAbilityMod();
+ mMagicMod = other.getMagicMod();
+ mMiscMod = other.getMiscMod();
+ mTempMod = other.getTempMod();
+ calculateTotal();
+ }
+
+ public int getAbilityMod() {
+ return mAbilityMod;
+ }
+
+ public int getMagicMod() {
+ return mMagicMod;
+ }
+
+ public int getMiscMod() {
+ return mMiscMod;
+ }
+
+ public int getTempMod() {
+ return mTempMod;
+ }
+
+ public int getBase() {
+ return mBaseValue;
+ }
+
+ public int getTotal() {
+ calculateTotal();
+ return mTotal;
+ }
+
+ public void setAbilityMod(int abilityMod) {
+ mAbilityMod = abilityMod;
+ }
+
+ public void setBase(int base) {
+ mBaseValue = base;
+ }
+
+ public void setMagicMod(int magicMod) {
+ mMagicMod = magicMod;
+ }
+
+ public void setMiscMod(int miscMod) {
+ mMiscMod = miscMod;
+ }
+
+ public void setTempMod(int tempMod) {
+ mTempMod = tempMod;
+ }
+
+ private void calculateTotal() {
+ mTotal = 0;
+ mTotal += mBaseValue;
+ mTotal += mAbilityMod;
+ mTotal += mMagicMod;
+ mTotal += mMiscMod;
+ mTotal += mTempMod;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTSaveSet.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTSaveSet.java
new file mode 100644
index 0000000..41705d5
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTSaveSet.java
@@ -0,0 +1,35 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+public class PTSaveSet {
+ PTSave[] mSaves;
+
+ public PTSaveSet(Context context) {
+ Resources r = context.getResources();
+ String[] names = r.getStringArray(R.array.save_names);
+
+ mSaves = new PTSave[3];
+ for(int i = 0; i < mSaves.length; i++) {
+ mSaves[i] = new PTSave(names[i]);
+ }
+ }
+
+ public PTSave getSave(int index) {
+ return mSaves[index];
+ }
+
+ public void setAbilityMods(PTAbilitySet abilities, Context context) {
+ Resources r = context.getResources();
+
+ mSaves[r.getInteger(R.integer.key_fort_save)].setAbilityMod(
+ abilities.getAbilityScore(R.integer.key_constitution).getModifier());
+ mSaves[r.getInteger(R.integer.key_ref_save)].setAbilityMod(
+ abilities.getAbilityScore(R.integer.key_dexterity).getModifier());
+ mSaves[r.getInteger(R.integer.key_will_save)].setAbilityMod(
+ abilities.getAbilityScore(R.integer.key_wisdom).getModifier());
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTSkill.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTSkill.java
new file mode 100644
index 0000000..9e1d92f
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTSkill.java
@@ -0,0 +1,140 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+public class PTSkill {
+ String mName;
+ boolean mClassSkill;
+ String mKeyAbility;
+ int mAbilityMod;
+ int mRank;
+ int mMiscMod;
+ int mArmorCheckPenalty;
+ int mKeyAbilityKey;
+
+ public PTSkill() {
+ mName = "";
+ mClassSkill = false;
+ mKeyAbility = "";
+ mAbilityMod = 0;
+ mRank = 0;
+ mMiscMod = 0;
+ mArmorCheckPenalty = 0;
+ mKeyAbilityKey = 0;
+ }
+
+ public PTSkill(String name, int abilityKey, String abilityString) {
+ mName = name;
+ mClassSkill = false;
+ mAbilityMod = 0;
+ mRank = 0;
+ mMiscMod = 0;
+ mArmorCheckPenalty = 0;
+ mKeyAbilityKey = abilityKey;
+ mKeyAbility = abilityString;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return mName;
+ }
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ mName = name;
+ }
+ /**
+ * @return the classSkill
+ */
+ public boolean isClassSkill() {
+ return mClassSkill;
+ }
+ /**
+ * @param classSkill the classSkill to set
+ */
+ public void setClassSkill(boolean classSkill) {
+ mClassSkill = classSkill;
+ }
+ /**
+ * @return the keyAbility
+ */
+ public String getKeyAbility() {
+ return mKeyAbility;
+ }
+ /**
+ * @param keyAbility the keyAbility to set
+ */
+ public void setKeyAbility(String keyAbility) {
+ mKeyAbility = keyAbility;
+ }
+ /**
+ * @return the total skill Mod
+ */
+ public int getSkillMod() {
+ int skillMod = 0;
+ skillMod = skillMod + mAbilityMod + mRank + mMiscMod + mArmorCheckPenalty;
+
+ if(mClassSkill && mRank > 0)
+ skillMod += 3;
+
+ return skillMod;
+ }
+
+ /**
+ * @return the abilityMod
+ */
+ public int getAbilityMod() {
+ return mAbilityMod;
+ }
+ /**
+ * @param abilityMod the abilityMod to set
+ */
+ public void setAbilityMod(int abilityMod) {
+ mAbilityMod = abilityMod;
+ }
+ /**
+ * @return the rank
+ */
+ public int getRank() {
+ return mRank;
+ }
+ /**
+ * @param rank the rank to set
+ */
+ public void setRank(int rank) {
+ mRank = rank;
+ }
+ /**
+ * @return the miscMod
+ */
+ public int getMiscMod() {
+ return mMiscMod;
+ }
+ /**
+ * @param miscMod the miscMod to set
+ */
+ public void setMiscMod(int miscMod) {
+ mMiscMod = miscMod;
+ }
+ /**
+ * @return the armorCheckPenalty
+ */
+ public int getArmorCheckPenalty() {
+ return mArmorCheckPenalty;
+ }
+ /**
+ * @param armorCheckPenalty the armorCheckPenalty to set
+ */
+ public void setArmorCheckPenalty(int armorCheckPenalty) {
+ mArmorCheckPenalty = armorCheckPenalty;
+ }
+
+ public int getKeyAbilityKey() {
+ return mKeyAbilityKey;
+ }
+
+ public void setKeyAbilityKey(int keyAbilityKey) {
+ mKeyAbilityKey = keyAbilityKey;
+ }
+}
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTSkillSet.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTSkillSet.java
new file mode 100644
index 0000000..ccd54ff
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTSkillSet.java
@@ -0,0 +1,38 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.lateensoft.pathfinder.toolkit.R;
+
+public class PTSkillSet {
+ PTSkill[] mSkills;
+
+ public PTSkillSet(Context context) {
+ Resources r = context.getResources();
+ String[] skills = r.getStringArray(R.array.skills);
+ int[] skillAbilityKeys = r.getIntArray(R.array.skill_ability_keys);
+ String[] skillAbilityShortStrings = r.getStringArray(R.array.abilities_short);
+
+ mSkills = new PTSkill[skills.length];
+
+ for(int i = 0; i < skills.length; i++) {
+ mSkills[i] = new PTSkill(skills[i], skillAbilityKeys[i], skillAbilityShortStrings[skillAbilityKeys[i]]);
+ }
+ }
+
+ public PTSkill getSkill(int index) {
+ if( index >= 0 && index < mSkills.length )
+ return mSkills[index];
+ else
+ return null;
+ }
+
+ public PTSkill[] getSkills(){
+ return mSkills;
+ }
+
+ //can set/get through reff to skill
+}
+
+
diff --git a/src/com/lateensoft/pathfinder/toolkit/stats/PTStat.java b/src/com/lateensoft/pathfinder/toolkit/stats/PTStat.java
new file mode 100644
index 0000000..b7976fc
--- /dev/null
+++ b/src/com/lateensoft/pathfinder/toolkit/stats/PTStat.java
@@ -0,0 +1,42 @@
+package com.lateensoft.pathfinder.toolkit.stats;
+
+public class PTStat {
+ String mName;
+ int mBaseValue;
+
+ public PTStat() {
+ mName = "";
+ mBaseValue = 0;
+ }
+
+ public PTStat(String name) {
+ mName = name;
+ mBaseValue = 0;
+ }
+
+ public PTStat(String name, int baseValue) {
+ mName = name;
+ mBaseValue = baseValue;
+ }
+
+ public PTStat(PTStat other) {
+ mName = other.getName();
+ mBaseValue = other.getBaseValue();
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public int getBaseValue() {
+ return mBaseValue;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public void setBaseValue(int baseValue) {
+ mBaseValue = baseValue;
+ }
+}