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 {