diff --git a/AndorsTrail/res/layout/heroinfo_stats.xml b/AndorsTrail/res/layout/heroinfo_stats.xml
index 5a53ab869..760b16f1b 100644
--- a/AndorsTrail/res/layout/heroinfo_stats.xml
+++ b/AndorsTrail/res/layout/heroinfo_stats.xml
@@ -130,6 +130,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml
index 26902acb9..441f5048e 100644
--- a/AndorsTrail/res/values/strings.xml
+++ b/AndorsTrail/res/values/strings.xml
@@ -651,5 +651,17 @@ Every skill level increases the attack chance of weapons with %1$d %% of their o
This is a development version of Andor\'s Trail. Savegames produced by this version are incompatible with the release version.
This is a prerelease version of Andor\'s Trail. Savegames produced by this version might not be compatible with the release version.
+ Game statistics
+ Number of completed quests
+ Times fallen unconscious
+ Gold spent in shops
+ Number of Bonemeal potions used
+ Number of items used
+ Number of places visited
+ Most commonly used item
+ Number of monsters killed
+ Most powerful monster killed
+ Most commonly killed monsters
+ %1$s (%2$d)
diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java
index fa0ba4d62..2c4038429 100644
--- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java
+++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java
@@ -1,6 +1,7 @@
package com.gpl.rpg.AndorsTrail.activity.fragment;
import android.content.Intent;
+import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
@@ -9,11 +10,13 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableLayout;
+import android.widget.TableRow;
import android.widget.TextView;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.Dialogs;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
+import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
@@ -30,7 +33,8 @@ public final class HeroinfoActivity_Stats extends Fragment {
private WorldContext world;
private Player player;
-
+
+ private View view;
private Button levelUpButton;
private TextView heroinfo_ap;
private TextView heroinfo_reequip_cost;
@@ -59,7 +63,8 @@ public final class HeroinfoActivity_Stats extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.heroinfo_stats, container, false);
-
+ view = v;
+
TextView tv = (TextView) v.findViewById(R.id.heroinfo_title);
tv.setText(player.getName());
world.tileManager.setImageViewTile(getResources(), tv, player);
@@ -121,6 +126,8 @@ public final class HeroinfoActivity_Stats extends Fragment {
}
private void updateTraits() {
+ final Resources res = getResources();
+
heroinfo_level.setText(Integer.toString(player.getLevel()));
heroinfo_totalexperience.setText(Integer.toString(player.getTotalExperience()));
heroinfo_ap.setText(player.getMaxAP() + "/" + player.getCurrentAP());
@@ -158,5 +165,33 @@ public final class HeroinfoActivity_Stats extends Fragment {
if (effects_hit.isEmpty()) effects_hit = null;
if (effects_kill.isEmpty()) effects_kill = null;
actorinfo_onhiteffects.update(null, null, effects_hit, effects_kill, false);
+
+
+ updateStatsTableRow(world.model.statistics.getNumberOfCompletedQuests(world), R.id.heroinfo_gamestats_quests, R.id.heroinfo_gamestats_quests_row);
+ updateStatsTableRow(world.model.statistics.getNumberOfVisitedMaps(world), R.id.heroinfo_gamestats_visited_maps, R.id.heroinfo_gamestats_visited_maps_row);
+ updateStatsTableRow(world.model.statistics.getDeaths(), R.id.heroinfo_gamestats_deaths, R.id.heroinfo_gamestats_deaths_row);
+ updateStatsTableRow(world.model.statistics.getSpentGold(), R.id.heroinfo_gamestats_spent_gold, R.id.heroinfo_gamestats_spent_gold_row);
+ updateStatsTableRow(world.model.statistics.getNumberOfUsedItems(), R.id.heroinfo_gamestats_num_used_items, R.id.heroinfo_gamestats_num_used_items_row);
+ updateStatsTableRow(world.model.statistics.getNumberOfUsedBonemealPotions(), R.id.heroinfo_gamestats_bonemeals, R.id.heroinfo_gamestats_bonemeals_row);
+ updateStatsTableRow(world.model.statistics.getNumberOfKilledMonsters(), R.id.heroinfo_gamestats_num_killed_monsters, R.id.heroinfo_gamestats_num_killed_monsters_row);
+ updateStatsTableRow(world.model.statistics.getMostCommonlyUsedItem(world, res), R.id.heroinfo_gamestats_fav_item, R.id.heroinfo_gamestats_fav_item_row);
+ updateStatsTableRow(world.model.statistics.getMostPowerfulKilledMonster(world), R.id.heroinfo_gamestats_top_boss, R.id.heroinfo_gamestats_top_boss_row);
+ updateStatsTableRow(world.model.statistics.getTop5MostCommonlyKilledMonsters(world, res), R.id.heroinfo_gamestats_fav_monsters, R.id.heroinfo_gamestats_fav_monsters_row);
}
+
+ private void updateStatsTableRow(int value, int textView, int tableRow) {
+ String s = (value > 0) ? Integer.toString(value) : null;
+ updateStatsTableRow(s, textView, tableRow);
+ }
+
+ private void updateStatsTableRow(String value, int textView, int tableRow) {
+ TextView tv = (TextView) view.findViewById(textView);
+ TableRow tr = (TableRow) view.findViewById(tableRow);
+ if (value != null) {
+ tv.setText(value);
+ tr.setVisibility(View.VISIBLE);
+ } else {
+ tr.setVisibility(View.GONE);
+ }
+ }
}
diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/GameStatistics.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/GameStatistics.java
index 7ad675247..fc791d4a4 100644
--- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/GameStatistics.java
+++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/GameStatistics.java
@@ -1,22 +1,25 @@
package com.gpl.rpg.AndorsTrail.model;
+import android.content.res.Resources;
+import com.gpl.rpg.AndorsTrail.R;
+import com.gpl.rpg.AndorsTrail.context.WorldContext;
+import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
+import com.gpl.rpg.AndorsTrail.model.item.ItemType;
+import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
+import com.gpl.rpg.AndorsTrail.model.quest.Quest;
+
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Set;
+import java.util.*;
import java.util.Map.Entry;
-import com.gpl.rpg.AndorsTrail.context.WorldContext;
-import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
-import com.gpl.rpg.AndorsTrail.model.item.ItemType;
-
public final class GameStatistics {
private int deaths = 0;
private final HashMap killedMonsters = new HashMap();
private final HashMap usedItems = new HashMap();
- private int spentGold = 0;
-
+ private int spentGold = 0;
+
public GameStatistics() { }
public void addMonsterKill(String monsterTypeID) {
if (!killedMonsters.containsKey(monsterTypeID)) killedMonsters.put(monsterTypeID, 1);
@@ -33,8 +36,95 @@ public final class GameStatistics {
if (!usedItems.containsKey(n)) usedItems.put(n, 1);
else usedItems.put(n, usedItems.get(n) + 1);
}
-
-
+
+ public int getDeaths() {
+ return deaths;
+ }
+
+ public int getSpentGold() {
+ return spentGold;
+ }
+
+ public String getTop5MostCommonlyKilledMonsters(WorldContext world, Resources res) {
+ if (killedMonsters.isEmpty()) return null;
+ List> entries = new ArrayList>(killedMonsters.entrySet());
+ Collections.sort(entries, descendingValueComparator);
+ StringBuilder sb = new StringBuilder(100);
+ int i = 0;
+ for (Entry e : entries) {
+ if (i++ >= 5) break;
+ MonsterType t = world.monsterTypes.getMonsterType(e.getKey());
+ if (t == null) continue;
+ sb.append(res.getString(R.string.heroinfo_gamestats_name_and_qty, t.name, e.getValue())).append("\n");
+ }
+ return sb.toString();
+ }
+
+ public String getMostPowerfulKilledMonster(WorldContext world) {
+ if (killedMonsters.isEmpty()) return null;
+ HashMap expPerMonsterType = new HashMap(killedMonsters.size());
+ for (String monsterTypeID : killedMonsters.keySet()) {
+ MonsterType t = world.monsterTypes.getMonsterType(monsterTypeID);
+ expPerMonsterType.put(monsterTypeID, t != null ? t.exp : 0);
+ }
+ String monsterTypeID = Collections.min(expPerMonsterType.entrySet(), descendingValueComparator).getKey();
+ MonsterType t = world.monsterTypes.getMonsterType(monsterTypeID);
+ return t != null ? t.name : null;
+ }
+
+ public String getMostCommonlyUsedItem(WorldContext world, Resources res) {
+ if (usedItems.isEmpty()) return null;
+ Entry e = Collections.min(usedItems.entrySet(), descendingValueComparator);
+ String itemTypeID = e.getKey();
+ ItemType t = world.itemTypes.getItemType(itemTypeID);
+ if (t == null) return null;
+ return res.getString(R.string.heroinfo_gamestats_name_and_qty, t.getName(world.model.player), e.getValue());
+ }
+
+ public int getNumberOfUsedBonemealPotions() {
+ int result = 0;
+ Integer v;
+ if ((v = usedItems.get("bonemeal_potion")) != null) result += v;
+ if ((v = usedItems.get("pot_bm_lodar")) != null) result += v;
+ return result;
+ }
+
+ public int getNumberOfCompletedQuests(WorldContext world) {
+ int result = 0;
+ for (Quest q : world.quests.getAllQuests()) {
+ if (q.isCompleted(world.model.player)) ++result;
+ }
+ return result;
+ }
+
+ public int getNumberOfVisitedMaps(WorldContext world) {
+ int result = 0;
+ for (PredefinedMap m : world.maps.getAllMaps()) {
+ if (m.visited) ++result;
+ }
+ return result;
+ }
+
+ public int getNumberOfUsedItems() {
+ int result = 0;
+ for (int v : usedItems.values()) result += v;
+ return result;
+ }
+
+ public int getNumberOfKilledMonsters() {
+ int result = 0;
+ for (int v : killedMonsters.values()) result += v;
+ return result;
+ }
+
+ private static final Comparator> descendingValueComparator = new Comparator>() {
+ @Override
+ public int compare(Entry a, Entry b) {
+ return b.getValue().compareTo(a.getValue());
+ }
+ };
+
+
// ====== PARCELABLE ===================================================================
public GameStatistics(DataInputStream src, WorldContext world, int fileversion) throws IOException {