v1.3.0: added new badges, and made a few more tweaks to existing ones

This commit is contained in:
Evan Debenham
2022-05-05 17:18:49 -04:00
parent 74ef6f50ce
commit 5b05e453da
35 changed files with 424 additions and 129 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -56,12 +56,18 @@ badges$badge.death_from_gas.title=Suffocated
badges$badge.death_from_gas.desc=Die from toxic gas
badges$badge.death_from_hunger.title=Starved
badges$badge.death_from_hunger.desc=Die from hunger
badges$badge.death_from_glyph.title=Deferred Death
badges$badge.death_from_glyph.desc=Die from deferred damage
badges$badge.death_from_falling.title=Pancaked
badges$badge.death_from_falling.desc=Die from falling down
badges$badge.yasd.title=Yet Another Sad Death
badges$badge.yasd.desc=Die to fire, poison, toxic gas, hunger, deferred damage, and falling
badges$badge.death_from_enemy_magic.title=Zapped
badges$badge.death_from_enemy_magic.desc=Die to an enemy's magical attack
badges$badge.death_from_friendly_magic.title=Friendly Fire
badges$badge.death_from_friendly_magic.desc=Die to your own magical item
badges$badge.death_from_sacrifice.title=A Worthy Sacrifice
badges$badge.death_from_sacrifice.desc=Die while next to sacrifical fire
badges$badge.death_from_grim_trap.title=Deadly Misstep
badges$badge.death_from_grim_trap.desc=Die to a grim trap
badges$badge.death_from_all.title=Yet Another Sad Death
badges$badge.death_from_all.desc=Unlock all of the 'cause of death' badges
badges$badge.boss_slain_1.title=Slime janitor
badges$badge.boss_slain_1.desc=Defeat the boss at the end of the sewers
badges$badge.boss_slain_2.title=Prison Warden
@@ -71,9 +77,9 @@ badges$badge.boss_slain_3.desc=Defeat the boss at the end of the caves
badges$badge.boss_slain_4.title=King Conqueror
badges$badge.boss_slain_4.desc=Defeat the boss at the end of the city
badges$badge.boss_slain_1_all_classes.title=Jack of Many Trades
badges$badge.boss_slain_1_all_classes.desc=Defeat the first boss with the Warrior, Mage, Rogue & Huntress
badges$badge.boss_slain_1_all_classes.desc=Defeat the first boss with every hero class
badges$badge.boss_slain_3_all_subclasses.title=Jack of All Trades
badges$badge.boss_slain_3_all_subclasses.desc=Defeat the third boss with the Gladiator, Berserker, Warlock, Battlemage, Freerunner, Assassin, Sniper & Warden
badges$badge.boss_slain_3_all_subclasses.desc=Defeat the third boss with every hero subclass
badges$badge.strength_attained_1.title=Novice Bodybuilder
badges$badge.strength_attained_1.desc=Reach 12 points of strength
badges$badge.strength_attained_2.title=Adept Bodybuilder
@@ -126,6 +132,16 @@ badges$badge.grim_weapon.title=Grim Reaper
badges$badge.grim_weapon.desc=Defeat an enemy with a Grim weapon
badges$badge.piranhas.title=Unconventional Angler
badges$badge.piranhas.desc=Kill 6 piranhas in one game
badges$badge.boss_challenge_1.title=Spotless Victory
badges$badge.boss_challenge_1.desc=Defeat the sewers boss without letting it use its charge attack or heal in water
badges$badge.boss_challenge_2.title=Gotcha!
badges$badge.boss_challenge_2.desc=Defeat the prison boss without getting hit by any traps or hazards
badges$badge.boss_challenge_3.title=Outmaneuvered
badges$badge.boss_challenge_3.desc=Defeat the caves boss without getting attacked or damaged while it is supercharged
badges$badge.boss_challenge_4.title=No Weapons in His Presence
badges$badge.boss_challenge_4.desc=Defeat the city boss without ever directly attacking him with weapons or wands
badges$badge.boss_challenge_5.title=Doom Slayer
badges$badge.boss_challenge_5.desc=Defeat the final boss with all demon spawners alive and the badder bosses challenge enabled
badges$badge.games_played_1.title=Novice Dungeoneer
badges$badge.games_played_1.desc=Play 10 games or win 1 game
badges$badge.games_played_2.title=Adept Dungeoneer
@@ -133,9 +149,19 @@ badges$badge.games_played_2.desc=Play 25 games or win 3 games
badges$badge.games_played_3.title=Expert Dungeoneer
badges$badge.games_played_3.desc=Play 50 games or win 5 games
badges$badge.games_played_4.title=Master Dungeoneer
badges$badge.games_played_4.desc=Play 100 games or win 10 games
badges$badge.games_played_4.desc=Play 200 games or win 10 games
badges$badge.games_played_5.title=Grandmaster Dungeoneer
badges$badge.games_played_5.desc=Play 250 games or win 25 games
badges$badge.games_played_5.desc=Play 1000 games or win 25 games
badges$badge.high_score_1.title=Novice Score Chaser
badges$badge.high_score_1.desc=End a run with a score of 5000 or higher
badges$badge.high_score_2.title=Adept Score Chaser
badges$badge.high_score_2.desc=End a run with a score of 25,000 or higher
badges$badge.high_score_3.title=Expert Score Chaser
badges$badge.high_score_3.desc=End a run with a score of 100,000 or higher
badges$badge.high_score_4.title=Master Score Chaser
badges$badge.high_score_4.desc=End a run with a score of 250,000 or higher
badges$badge.high_score_5.title=Grandmaster Score Chaser
badges$badge.high_score_5.desc=End a run with a score of 1,000,000 or higher
badges$badge.happy_end.title=Happy Ending
badges$badge.happy_end.desc=Take the Amulet of Yendor to the surface
badges$badge.champion_1.title=Bronze Champion

View File

@@ -21,6 +21,8 @@
package com.shatteredpixel.shatteredpixeldungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.MagicalHolster;
@@ -41,6 +43,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
public class Badges {
@@ -72,6 +75,7 @@ public class Badges {
DEATH_FROM_HUNGER ( 17 ),
DEATH_FROM_FALLING ( 18 ),
GAMES_PLAYED_1 ( 19, true ),
HIGH_SCORE_1 ( 20 ),
//silver
NO_MONSTERS_SLAIN ( 32 ),
@@ -93,13 +97,16 @@ public class Badges {
BOSS_SLAIN_3 ( 48 ),
ALL_POTIONS_IDENTIFIED ( 49 ),
ALL_SCROLLS_IDENTIFIED ( 50 ),
DEATH_FROM_GLYPH ( 51 ),
DEATH_FROM_ENEMY_MAGIC( 51 ),
DEATH_FROM_FRIENDLY_MAGIC ( 52 ),
DEATH_FROM_SACRIFICE ( 53 ),
BOSS_SLAIN_1_WARRIOR,
BOSS_SLAIN_1_MAGE,
BOSS_SLAIN_1_ROGUE,
BOSS_SLAIN_1_HUNTRESS,
BOSS_SLAIN_1_ALL_CLASSES ( 52, true ),
GAMES_PLAYED_2 ( 53, true ),
BOSS_SLAIN_1_ALL_CLASSES ( 54, true ),
GAMES_PLAYED_2 ( 55, true ),
HIGH_SCORE_2 ( 56 ),
//gold
PIRANHAS ( 64 ),
@@ -123,8 +130,12 @@ public class Badges {
BOSS_SLAIN_4 ( 78 ),
ALL_RINGS_IDENTIFIED ( 79 ),
ALL_ARTIFACTS_IDENTIFIED ( 80 ),
VICTORY ( 81 ),
GAMES_PLAYED_3 ( 82, true ),
DEATH_FROM_GRIM_TRAP ( 81 ),
VICTORY ( 82 ),
BOSS_CHALLENGE_1 ( 83 ),
BOSS_CHALLENGE_2 ( 84 ),
GAMES_PLAYED_3 ( 85, true ),
HIGH_SCORE_3 ( 86 ),
//platinum
ITEM_LEVEL_5 ( 96 ),
@@ -139,7 +150,7 @@ public class Badges {
VICTORY_ROGUE,
VICTORY_HUNTRESS,
VICTORY_ALL_CLASSES ( 103, true ),
YASD ( 104, true ),
DEATH_FROM_ALL ( 104, true ),
BOSS_SLAIN_3_GLADIATOR,
BOSS_SLAIN_3_BERSERKER,
BOSS_SLAIN_3_WARLOCK,
@@ -149,13 +160,18 @@ public class Badges {
BOSS_SLAIN_3_SNIPER,
BOSS_SLAIN_3_WARDEN,
BOSS_SLAIN_3_ALL_SUBCLASSES ( 105, true ),
GAMES_PLAYED_4 ( 106, true ),
CHAMPION_1 ( 107 ),
BOSS_CHALLENGE_3 ( 106 ),
BOSS_CHALLENGE_4 ( 107 ),
GAMES_PLAYED_4 ( 108, true ),
HIGH_SCORE_4 ( 109 ),
CHAMPION_1 ( 110 ),
//diamond
GAMES_PLAYED_5 ( 112, true ),
CHAMPION_2 ( 113 ),
CHAMPION_3 ( 114 );
BOSS_CHALLENGE_5 ( 120 ),
GAMES_PLAYED_5 ( 121, true ),
HIGH_SCORE_5 ( 122 ),
CHAMPION_2 ( 123 ),
CHAMPION_3 ( 124 );
public boolean meta;
@@ -198,7 +214,9 @@ public class Badges {
private static final HashSet<String> removedBadges = new HashSet<>();
static{
//no recently removed badges
//v1.3.0 (These were removed and re-added internally as new unlock reqs were added)
removedBadges.add("YASD");
removedBadges.add("DEATH_FROM_GLYPH");
}
private static final HashMap<String, String> renamedBadges = new HashMap<>();
@@ -559,7 +577,7 @@ public class Badges {
local.add( badge );
displayBadge( badge );
validateYASD();
validateDeathFromAll();
}
public static void validateDeathFromPoison() {
@@ -567,7 +585,7 @@ public class Badges {
local.add( badge );
displayBadge( badge );
validateYASD();
validateDeathFromAll();
}
public static void validateDeathFromGas() {
@@ -575,7 +593,7 @@ public class Badges {
local.add( badge );
displayBadge( badge );
validateYASD();
validateDeathFromAll();
}
public static void validateDeathFromHunger() {
@@ -583,39 +601,86 @@ public class Badges {
local.add( badge );
displayBadge( badge );
validateYASD();
validateDeathFromAll();
}
public static void validateDeathFromGlyph() {
Badge badge = Badge.DEATH_FROM_GLYPH;
local.add( badge );
displayBadge( badge );
validateYASD();
}
public static void validateDeathFromFalling() {
Badge badge = Badge.DEATH_FROM_FALLING;
local.add( badge );
displayBadge( badge );
validateYASD();
validateDeathFromAll();
}
public static void validateDeathFromEnemyMagic() {
Badge badge = Badge.DEATH_FROM_ENEMY_MAGIC;
local.add( badge );
displayBadge( badge );
validateDeathFromAll();
}
private static void validateYASD() {
public static void validateDeathFromFriendlyMagic() {
Badge badge = Badge.DEATH_FROM_FRIENDLY_MAGIC;
local.add( badge );
displayBadge( badge );
validateDeathFromAll();
}
public static void validateDeathFromSacrifice() {
Badge badge = Badge.DEATH_FROM_SACRIFICE;
local.add( badge );
displayBadge( badge );
validateDeathFromAll();
}
public static void validateDeathFromGrimTrap() {
Badge badge = Badge.DEATH_FROM_GRIM_TRAP;
local.add( badge );
displayBadge( badge );
validateDeathFromAll();
}
private static void validateDeathFromAll() {
if (isUnlocked( Badge.DEATH_FROM_FIRE ) &&
isUnlocked( Badge.DEATH_FROM_POISON ) &&
isUnlocked( Badge.DEATH_FROM_GAS ) &&
isUnlocked( Badge.DEATH_FROM_HUNGER) &&
isUnlocked( Badge.DEATH_FROM_GLYPH) &&
isUnlocked( Badge.DEATH_FROM_FALLING)) {
isUnlocked( Badge.DEATH_FROM_FALLING) &&
isUnlocked( Badge.DEATH_FROM_ENEMY_MAGIC) &&
isUnlocked( Badge.DEATH_FROM_FRIENDLY_MAGIC) &&
isUnlocked( Badge.DEATH_FROM_SACRIFICE) &&
isUnlocked( Badge.DEATH_FROM_GRIM_TRAP)) {
Badge badge = Badge.YASD;
Badge badge = Badge.DEATH_FROM_ALL;
if (!isUnlocked( badge )) {
displayBadge( badge );
}
}
}
private static LinkedHashMap<HeroClass, Badge> firstBossClassBadges = new LinkedHashMap<>();
static {
firstBossClassBadges.put(HeroClass.WARRIOR, Badge.BOSS_SLAIN_1_WARRIOR);
firstBossClassBadges.put(HeroClass.MAGE, Badge.BOSS_SLAIN_1_MAGE);
firstBossClassBadges.put(HeroClass.ROGUE, Badge.BOSS_SLAIN_1_ROGUE);
firstBossClassBadges.put(HeroClass.HUNTRESS, Badge.BOSS_SLAIN_1_HUNTRESS);
}
private static LinkedHashMap<HeroSubClass, Badge> thirdBossSubclassBadges = new LinkedHashMap<>();
static {
thirdBossSubclassBadges.put(HeroSubClass.BERSERKER, Badge.BOSS_SLAIN_3_BERSERKER);
thirdBossSubclassBadges.put(HeroSubClass.GLADIATOR, Badge.BOSS_SLAIN_3_GLADIATOR);
thirdBossSubclassBadges.put(HeroSubClass.BATTLEMAGE, Badge.BOSS_SLAIN_3_BATTLEMAGE);
thirdBossSubclassBadges.put(HeroSubClass.WARLOCK, Badge.BOSS_SLAIN_3_WARLOCK);
thirdBossSubclassBadges.put(HeroSubClass.ASSASSIN, Badge.BOSS_SLAIN_3_ASSASSIN);
thirdBossSubclassBadges.put(HeroSubClass.FREERUNNER, Badge.BOSS_SLAIN_3_FREERUNNER);
thirdBossSubclassBadges.put(HeroSubClass.SNIPER, Badge.BOSS_SLAIN_3_SNIPER);
thirdBossSubclassBadges.put(HeroSubClass.WARDEN, Badge.BOSS_SLAIN_3_WARDEN);
}
public static void validateBossSlain() {
Badge badge = null;
@@ -639,75 +704,40 @@ public class Badges {
displayBadge( badge );
if (badge == Badge.BOSS_SLAIN_1) {
switch (Dungeon.hero.heroClass) {
case WARRIOR:
badge = Badge.BOSS_SLAIN_1_WARRIOR;
break;
case MAGE:
badge = Badge.BOSS_SLAIN_1_MAGE;
break;
case ROGUE:
badge = Badge.BOSS_SLAIN_1_ROGUE;
break;
case HUNTRESS:
badge = Badge.BOSS_SLAIN_1_HUNTRESS;
break;
}
badge = firstBossClassBadges.get(Dungeon.hero.heroClass);
if (badge == null) return;
local.add( badge );
unlock(badge);
if (isUnlocked( Badge.BOSS_SLAIN_1_WARRIOR ) &&
isUnlocked( Badge.BOSS_SLAIN_1_MAGE ) &&
isUnlocked( Badge.BOSS_SLAIN_1_ROGUE ) &&
isUnlocked( Badge.BOSS_SLAIN_1_HUNTRESS)) {
boolean allUnlocked = true;
for (Badge b : firstBossClassBadges.values()){
if (!isUnlocked(b)){
allUnlocked = false;
break;
}
}
if (allUnlocked) {
badge = Badge.BOSS_SLAIN_1_ALL_CLASSES;
if (!isUnlocked( badge )) {
displayBadge( badge );
}
}
} else
if (badge == Badge.BOSS_SLAIN_3) {
switch (Dungeon.hero.subClass) {
case GLADIATOR:
badge = Badge.BOSS_SLAIN_3_GLADIATOR;
break;
case BERSERKER:
badge = Badge.BOSS_SLAIN_3_BERSERKER;
break;
case WARLOCK:
badge = Badge.BOSS_SLAIN_3_WARLOCK;
break;
case BATTLEMAGE:
badge = Badge.BOSS_SLAIN_3_BATTLEMAGE;
break;
case FREERUNNER:
badge = Badge.BOSS_SLAIN_3_FREERUNNER;
break;
case ASSASSIN:
badge = Badge.BOSS_SLAIN_3_ASSASSIN;
break;
case SNIPER:
badge = Badge.BOSS_SLAIN_3_SNIPER;
break;
case WARDEN:
badge = Badge.BOSS_SLAIN_3_WARDEN;
break;
default:
return;
}
} else if (badge == Badge.BOSS_SLAIN_3) {
badge = thirdBossSubclassBadges.get(Dungeon.hero.subClass);
if (badge == null) return;
local.add( badge );
unlock(badge);
if (isUnlocked( Badge.BOSS_SLAIN_3_GLADIATOR ) &&
isUnlocked( Badge.BOSS_SLAIN_3_BERSERKER ) &&
isUnlocked( Badge.BOSS_SLAIN_3_WARLOCK ) &&
isUnlocked( Badge.BOSS_SLAIN_3_BATTLEMAGE ) &&
isUnlocked( Badge.BOSS_SLAIN_3_FREERUNNER ) &&
isUnlocked( Badge.BOSS_SLAIN_3_ASSASSIN ) &&
isUnlocked( Badge.BOSS_SLAIN_3_SNIPER ) &&
isUnlocked( Badge.BOSS_SLAIN_3_WARDEN )) {
boolean allUnlocked = true;
for (Badge b : thirdBossSubclassBadges.values()){
if (!isUnlocked(b)){
allUnlocked = false;
break;
}
}
if (allUnlocked) {
badge = Badge.BOSS_SLAIN_3_ALL_SUBCLASSES;
if (!isUnlocked( badge )) {
displayBadge( badge );
@@ -716,6 +746,32 @@ public class Badges {
}
}
}
public static void validateBossChallengeCompleted(){
Badge badge = null;
switch (Dungeon.depth) {
case 5:
badge = Badge.BOSS_CHALLENGE_1;
break;
case 10:
badge = Badge.BOSS_CHALLENGE_2;
break;
case 15:
badge = Badge.BOSS_CHALLENGE_3;
break;
case 20:
badge = Badge.BOSS_CHALLENGE_4;
break;
case 25:
badge = Badge.BOSS_CHALLENGE_5;
break;
}
if (badge != null) {
local.add(badge);
displayBadge(badge);
}
}
public static void validateMastery() {
@@ -827,15 +883,42 @@ public class Badges {
if (Rankings.INSTANCE.totalNumber >= 50 || Rankings.INSTANCE.wonNumber >= 5) {
badge = Badge.GAMES_PLAYED_3;
}
if (Rankings.INSTANCE.totalNumber >= 100 || Rankings.INSTANCE.wonNumber >= 10) {
if (Rankings.INSTANCE.totalNumber >= 200 || Rankings.INSTANCE.wonNumber >= 10) {
badge = Badge.GAMES_PLAYED_4;
}
if (Rankings.INSTANCE.totalNumber >= 250 || Rankings.INSTANCE.wonNumber >= 25) {
if (Rankings.INSTANCE.totalNumber >= 1000 || Rankings.INSTANCE.wonNumber >= 25) {
badge = Badge.GAMES_PLAYED_5;
}
displayBadge( badge );
}
//TODO this is calibrated for scoring changes I plan to make
public static void validateHighScore( int score ){
Badge badge = null;
if (score >= 5000) {
badge = Badge.HIGH_SCORE_1;
local.add( badge );
}
if (score >= 25_000) {
badge = Badge.HIGH_SCORE_2;
local.add( badge );
}
if (score >= 100_000) {
badge = Badge.HIGH_SCORE_3;
local.add( badge );
}
if (score >= 250_000) {
badge = Badge.HIGH_SCORE_4;
local.add( badge );
}
if (score >= 1_000_000) {
badge = Badge.HIGH_SCORE_5;
local.add( badge );
}
displayBadge( badge );
}
//necessary in order to display the happy end badge in the surface scene
public static void silentValidateHappyEnd() {
@@ -929,6 +1012,7 @@ public class Badges {
}
//only show the highest unlocked and the lowest locked
private static final Badge[][] tierBadgeReplacements = new Badge[][]{
{Badge.MONSTERS_SLAIN_1, Badge.MONSTERS_SLAIN_2, Badge.MONSTERS_SLAIN_3, Badge.MONSTERS_SLAIN_4, Badge.MONSTERS_SLAIN_5},
{Badge.GOLD_COLLECTED_1, Badge.GOLD_COLLECTED_2, Badge.GOLD_COLLECTED_3, Badge.GOLD_COLLECTED_4, Badge.GOLD_COLLECTED_5},
@@ -938,17 +1022,31 @@ public class Badges {
{Badge.FOOD_EATEN_1, Badge.FOOD_EATEN_2, Badge.FOOD_EATEN_3, Badge.FOOD_EATEN_4, Badge.FOOD_EATEN_5},
{Badge.ITEMS_CRAFTED_1, Badge.ITEMS_CRAFTED_2, Badge.ITEMS_CRAFTED_3, Badge.ITEMS_CRAFTED_4, Badge.ITEMS_CRAFTED_5},
{Badge.BOSS_SLAIN_1, Badge.BOSS_SLAIN_2, Badge.BOSS_SLAIN_3, Badge.BOSS_SLAIN_4},
{Badge.HIGH_SCORE_1, Badge.HIGH_SCORE_2, Badge.HIGH_SCORE_3, Badge.HIGH_SCORE_4, Badge.HIGH_SCORE_5},
{Badge.GAMES_PLAYED_1, Badge.GAMES_PLAYED_2, Badge.GAMES_PLAYED_3, Badge.GAMES_PLAYED_4, Badge.GAMES_PLAYED_5},
{Badge.CHAMPION_1, Badge.CHAMPION_2, Badge.CHAMPION_3}
};
private static final Badge[][] metaBadgeReplacements = new Badge[][]{
{Badge.DEATH_FROM_FIRE, Badge.YASD},
{Badge.DEATH_FROM_GAS, Badge.YASD},
{Badge.DEATH_FROM_HUNGER, Badge.YASD},
{Badge.DEATH_FROM_POISON, Badge.YASD},
{Badge.DEATH_FROM_GLYPH, Badge.YASD},
{Badge.DEATH_FROM_FALLING, Badge.YASD },
//don't show the later badge if the earlier one isn't unlocked
private static final Badge[][] prerequisiteBadges = new Badge[][]{
{Badge.BOSS_SLAIN_1, Badge.BOSS_CHALLENGE_1},
{Badge.BOSS_SLAIN_2, Badge.BOSS_CHALLENGE_2},
{Badge.BOSS_SLAIN_3, Badge.BOSS_CHALLENGE_3},
{Badge.BOSS_SLAIN_4, Badge.BOSS_CHALLENGE_4},
{Badge.VICTORY, Badge.BOSS_CHALLENGE_5},
};
//If the summary badge is unlocked, don't show the component badges
private static final Badge[][] summaryBadgeReplacements = new Badge[][]{
{Badge.DEATH_FROM_FIRE, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_GAS, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_HUNGER, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_POISON, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_FALLING, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_ENEMY_MAGIC, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_FRIENDLY_MAGIC, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_SACRIFICE, Badge.DEATH_FROM_ALL},
{Badge.DEATH_FROM_GRIM_TRAP, Badge.DEATH_FROM_ALL},
{Badge.ALL_WEAPONS_IDENTIFIED, Badge.ALL_ITEMS_IDENTIFIED},
{Badge.ALL_ARMOR_IDENTIFIED, Badge.ALL_ITEMS_IDENTIFIED},
@@ -965,7 +1063,7 @@ public class Badges {
leaveBest( badges, tierReplace );
}
for (Badge[] metaReplace : metaBadgeReplacements){
for (Badge[] metaReplace : summaryBadgeReplacements){
leaveBest( badges, metaReplace );
}
@@ -983,7 +1081,11 @@ public class Badges {
}
}
public static List<Badge> filterHigherIncrementalBadges(List<Badges.Badge> badges ) {
public static List<Badge> filterBadgesWithoutPrerequisites(List<Badges.Badge> badges ) {
for (Badge[] prereqReplace : prerequisiteBadges){
leaveWorst( badges, prereqReplace );
}
for (Badge[] tierReplace : tierBadgeReplacements){
leaveWorst( badges, tierReplace );
@@ -1011,7 +1113,7 @@ public class Badges {
addLower( badges, tierReplace );
}
for (Badge[] metaReplace : metaBadgeReplacements){
for (Badge[] metaReplace : summaryBadgeReplacements){
addLower( badges, metaReplace );
}
@@ -1028,4 +1130,34 @@ public class Badges {
}
}
}
//used for badges with completion progress that would otherwise be hard to track
public static String showCompletionProgress( Badge badge ){
if (isUnlocked(badge)) return null;
String result = "\n";
if (badge == Badge.BOSS_SLAIN_1_ALL_CLASSES){
for (HeroClass cls : HeroClass.values()){
result += "\n";
if (isUnlocked(firstBossClassBadges.get(cls))) result += "_" + Messages.titleCase(cls.title()) + "_";
else result += Messages.titleCase(cls.title());
}
return result;
} else if (badge == Badge.BOSS_SLAIN_3_ALL_SUBCLASSES){
for (HeroSubClass cls : HeroSubClass.values()){
if (cls == HeroSubClass.NONE) continue;
result += "\n";
if (isUnlocked(thirdBossSubclassBadges.get(cls))) result += "_" + Messages.titleCase(cls.title()) + "_";
else result += Messages.titleCase(cls.title()) ;
}
return result;
}
return null;
}
}

View File

@@ -324,6 +324,7 @@ public class Dungeon {
level.create();
Statistics.qualifiedForNoKilling = !bossLevel();
Statistics.qualifiedForBossChallengeBadge = bossLevel();
return level;
}

View File

@@ -75,6 +75,8 @@ public enum Rankings {
rec.herolevel = Dungeon.hero.lvl;
rec.depth = Dungeon.depth;
rec.score = score( win );
Badges.validateHighScore( rec.score );
INSTANCE.saveGameData(rec);

View File

@@ -44,6 +44,7 @@ public class Statistics {
public static boolean qualifiedForNoKilling = false;
public static boolean completedWithNoKilling = false;
public static boolean qualifiedForBossChallengeBadge = false;
public static boolean amuletObtained = false;
@@ -66,6 +67,7 @@ public class Statistics {
duration = 0;
qualifiedForNoKilling = false;
qualifiedForBossChallengeBadge = false;
amuletObtained = false;
@@ -88,6 +90,7 @@ public class Statistics {
private static final String DURATION = "duration";
private static final String NO_KILLING_QUALIFIED = "qualifiedForNoKilling";
private static final String BOSS_CHALLENGE_QUALIFIED= "qualifiedForBossChallengeBadge";
private static final String AMULET = "amuletObtained";
@@ -109,6 +112,8 @@ public class Statistics {
bundle.put( DURATION, duration );
bundle.put(NO_KILLING_QUALIFIED, qualifiedForNoKilling);
bundle.put(BOSS_CHALLENGE_QUALIFIED, qualifiedForBossChallengeBadge);
bundle.put( AMULET, amuletObtained );
}
@@ -131,6 +136,8 @@ public class Statistics {
duration = bundle.getFloat( DURATION );
qualifiedForNoKilling = bundle.getBoolean( NO_KILLING_QUALIFIED );
qualifiedForBossChallengeBadge = bundle.getBoolean( BOSS_CHALLENGE_QUALIFIED );
amuletObtained = bundle.getBoolean( AMULET );
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.blobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -157,6 +158,7 @@ public class SacrificialFire extends Blob {
exp *= Random.IntRange( 2, 3 );
} else if (ch instanceof Hero) {
exp = 1_000_000; //always enough to activate the reward, if you can somehow get it
Badges.validateDeathFromSacrifice();
}
if (exp > 0) {

View File

@@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
@@ -102,6 +103,7 @@ public class DM100 extends Mob implements Callback {
Camera.main.shake( 2, 0.3f );
if (!enemy.isAlive()) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "zap_kill") );
}

View File

@@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
@@ -298,6 +299,14 @@ public class DM300 extends Mob {
return super.act();
}
@Override
public boolean attack(Char enemy, float dmgMulti, float dmgBonus, float accMulti) {
if (enemy == Dungeon.hero && supercharged){
Statistics.qualifiedForBossChallengeBadge = false;
}
return super.attack(enemy, dmgMulti, dmgBonus, accMulti);
}
@Override
protected Char chooseEnemy() {
Char enemy = super.chooseEnemy();
@@ -533,6 +542,9 @@ public class DM300 extends Mob {
}
Badges.validateBossSlain();
if (Statistics.qualifiedForBossChallengeBadge){
Badges.validateBossChallengeCompleted();
}
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
if (beacon != null) {

View File

@@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier;
@@ -47,6 +48,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Viscosity;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLightning;
import com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -435,6 +438,11 @@ public class DwarfKing extends Mob {
@Override
public void damage(int dmg, Object src) {
//lightning and corrosion have their own custom logic
if (src == Dungeon.hero || (src instanceof Wand && !(src instanceof WandOfLightning))){
Statistics.qualifiedForBossChallengeBadge = false;
}
if (isInvulnerable(src.getClass())){
super.damage(dmg, src);
return;
@@ -513,6 +521,9 @@ public class DwarfKing extends Mob {
}
Badges.validateBossSlain();
if (Statistics.qualifiedForBossChallengeBadge){
Badges.validateBossChallengeCompleted();
}
Dungeon.level.unseal();

View File

@@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -184,6 +185,7 @@ public class Eye extends Mob {
}
if (!ch.isAlive() && ch == Dungeon.hero) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "deathgaze_kill") );
}

View File

@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
@@ -67,6 +68,7 @@ public class Goo extends Mob {
int max = (HP*2 <= HT) ? 12 : 8;
if (pumpedUp > 0) {
pumpedUp = 0;
Statistics.qualifiedForBossChallengeBadge = false;
return Random.NormalIntRange( min*3, max*3 );
} else {
return Random.NormalIntRange( min, max );
@@ -96,6 +98,7 @@ public class Goo extends Mob {
if (Dungeon.level.water[pos] && HP < HT) {
HP += healInc;
Statistics.qualifiedForBossChallengeBadge = false;
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
if (lock != null) lock.removeTime(healInc*2);
@@ -211,7 +214,10 @@ public class Goo extends Mob {
@Override
public boolean attack( Char enemy, float dmgMulti, float dmgBonus, float accMulti ) {
boolean result = super.attack( enemy, dmgMulti, dmgBonus, accMulti );
pumpedUp = 0;
if (pumpedUp > 0) {
pumpedUp = 0;
Statistics.qualifiedForBossChallengeBadge = false;
}
return result;
}
@@ -263,6 +269,9 @@ public class Goo extends Mob {
}
Badges.validateBossSlain();
if (Statistics.qualifiedForBossChallengeBadge){
Badges.validateBossChallengeCompleted();
}
yell( Messages.get(this, "defeated") );
}

View File

@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
@@ -124,9 +125,12 @@ public class Pylon extends Mob {
ch.sprite.flash();
ch.damage(Random.NormalIntRange(10, 20), new Electricity());
if (ch == Dungeon.hero && !ch.isAlive()){
Dungeon.fail(DM300.class);
GLog.n( Messages.get(Electricity.class, "ondeath") );
if (ch == Dungeon.hero) {
Statistics.qualifiedForBossChallengeBadge = false;
if (!ch.isAlive()) {
Dungeon.fail(DM300.class);
GLog.n(Messages.get(Electricity.class, "ondeath"));
}
}
}
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
@@ -119,6 +120,7 @@ public abstract class Shaman extends Mob {
enemy.damage( dmg, new EarthenBolt() );
if (!enemy.isAlive() && enemy == Dungeon.hero) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "bolt_kill") );
}

View File

@@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
@@ -209,6 +210,9 @@ public class Tengu extends Mob {
super.die( cause );
Badges.validateBossSlain();
if (Statistics.qualifiedForBossChallengeBadge){
Badges.validateBossChallengeCompleted();
}
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
if (beacon != null) {
@@ -612,8 +616,12 @@ public class Tengu extends Mob {
ch.damage(dmg, Bomb.class);
}
if (ch == Dungeon.hero && !ch.isAlive()) {
Dungeon.fail(Tengu.class);
if (ch == Dungeon.hero){
Statistics.qualifiedForBossChallengeBadge = false;
if (!ch.isAlive()) {
Dungeon.fail(Tengu.class);
}
}
}
@@ -840,6 +848,9 @@ public class Tengu extends Mob {
if (ch != null && !ch.isImmune(Fire.class) && !(ch instanceof Tengu)) {
Buff.affect( ch, Burning.class ).reignite( ch );
}
if (ch == Dungeon.hero){
Statistics.qualifiedForBossChallengeBadge = false;
}
if (Dungeon.level.flamable[cell]){
Dungeon.level.destroy( cell );
@@ -1021,9 +1032,12 @@ public class Tengu extends Mob {
if (ch != null && !(ch instanceof Tengu)){
ch.damage(2 + Dungeon.depth, new Electricity());
if (ch == Dungeon.hero && !ch.isAlive()) {
Dungeon.fail(Tengu.class);
GLog.n( Messages.get(Electricity.class, "ondeath") );
if (ch == Dungeon.hero){
Statistics.qualifiedForBossChallengeBadge = false;
if (!ch.isAlive()) {
Dungeon.fail(Tengu.class);
GLog.n(Messages.get(Electricity.class, "ondeath"));
}
}
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
@@ -112,6 +113,7 @@ public class Warlock extends Mob implements Callback {
enemy.damage( dmg, new DarkBolt() );
if (enemy == Dungeon.hero && !enemy.isAlive()) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "bolt_kill") );
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
@@ -225,6 +226,7 @@ public class YogDzewa extends Mob {
CellEmitter.center(pos).burst(PurpleParticle.BURST, Random.IntRange(1, 2));
}
if (!ch.isAlive() && ch == Dungeon.hero) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail(getClass());
GLog.n(Messages.get(Char.class, "kill", name()));
}
@@ -463,6 +465,13 @@ public class YogDzewa extends Mob {
updateVisibility(Dungeon.level);
GameScene.bossSlain();
if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES) && Statistics.spawnersAlive == 4){
Badges.validateBossChallengeCompleted();
} else {
Statistics.qualifiedForBossChallengeBadge = false;
}
Dungeon.level.unseal();
super.die( cause );

View File

@@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -473,6 +474,7 @@ public abstract class YogFist extends Mob {
Buff.prolong( enemy, Blindness.class, Blindness.DURATION/2f );
if (!enemy.isAlive() && enemy == Dungeon.hero) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(Char.class, "kill", name()) );
}
@@ -540,6 +542,7 @@ public abstract class YogFist extends Mob {
}
if (!enemy.isAlive() && enemy == Dungeon.hero) {
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(Char.class, "kill", name()) );
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.effects;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.watabou.noosa.Game;
@@ -134,8 +135,7 @@ public class BadgeBanner extends Image {
//we also hardcode any special cases
static {
//combo master
highlightPositions.put(66, new Point(3, 7));
highlightPositions.put(Badges.Badge.MASTERY_COMBO.image, new Point(3, 7));
}
//adds a shine to an appropriate pixel on a badge

View File

@@ -146,7 +146,7 @@ public class Viscosity extends Glyph {
target.damage( damageThisTick, this );
if (target == Dungeon.hero && !target.isAlive()) {
Badges.validateDeathFromGlyph();
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "ondeath") );

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.artifacts;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
@@ -116,6 +117,7 @@ public class ChaliceOfBlood extends Artifact {
hero.damage(damage, this);
if (!hero.isAlive()) {
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "ondeath") );
} else {

View File

@@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -84,6 +85,7 @@ public class ArcaneBomb extends Bomb {
float multiplier = 1f - (.16667f*Dungeon.level.distance(cell, ch.pos));
ch.damage(Math.round(damage*multiplier), this);
if (ch == Dungeon.hero && !ch.isAlive()){
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail(Bomb.class);
}
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
@@ -64,6 +65,7 @@ public class ScrollOfPsionicBlast extends ExoticScroll {
Dungeon.observe();
readAnimation();
} else {
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "ondeath") );
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
@@ -223,9 +224,11 @@ public class CursedWand {
Sample.INSTANCE.play(Assets.Sounds.CURSED);
if (!toDamage.isAlive()) {
if (origin != null) {
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( origin.getClass() );
GLog.n( Messages.get( CursedWand.class, "ondeath", origin.name() ) );
} else {
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( toHeal.getClass() );
}
}

View File

@@ -23,12 +23,14 @@ package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.CorrosiveGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DwarfKing;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
@@ -64,6 +66,10 @@ public class WandOfCorrosion extends Wand {
Char ch = Actor.findChar(bolt.collisionPos + i);
if (ch != null) {
wandProc(ch, chargesPerCast());
if (i == 0 && ch instanceof DwarfKing){
Statistics.qualifiedForBossChallengeBadge = false;
}
}
}

View File

@@ -22,9 +22,12 @@
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DwarfKing;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
@@ -87,6 +90,7 @@ public class WandOfLightning extends DamageWand {
}
if (!curUser.isAlive()) {
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( getClass() );
GLog.n(Messages.get(this, "ondeath"));
}
@@ -133,6 +137,10 @@ public class WandOfLightning extends DamageWand {
Char ch = Actor.findChar( cell );
if (ch != null) {
if (ch instanceof DwarfKing){
Statistics.qualifiedForBossChallengeBadge = false;
}
affected.add( ch );
arcs.add( new Lightning.Arc(curUser.sprite.center(), ch.sprite.center()));
arc(ch);

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -131,6 +132,7 @@ public class WandOfTransfusion extends Wand {
curUser.damage(damage, this);
if (!curUser.isAlive()){
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "ondeath") );
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -328,6 +329,7 @@ public class WandOfWarding extends Wand {
}
if (!enemy.isAlive() && enemy == Dungeon.hero) {
Badges.validateDeathFromFriendlyMagic();
Dungeon.fail( getClass() );
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;

View File

@@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Bones;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
@@ -44,6 +45,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.PylonSprite;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTilemap;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
@@ -794,9 +796,15 @@ public class CavesBossLevel extends Level {
ch.damage( Random.NormalIntRange(6, 12), Electricity.class);
ch.sprite.flash();
if (ch == Dungeon.hero && !ch.isAlive()) {
Dungeon.fail(DM300.class);
GLog.n( Messages.get(Electricity.class, "ondeath") );
if (ch == Dungeon.hero){
if (energySourceSprite != null && energySourceSprite instanceof PylonSprite){
//took damage while DM-300 was supercharged
Statistics.qualifiedForBossChallengeBadge = false;
}
if ( !ch.isAlive()) {
Dungeon.fail(DM300.class);
GLog.n(Messages.get(Electricity.class, "ondeath"));
}
}
}
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
@@ -275,8 +276,9 @@ public class SentryRoom extends SpecialRoom {
public void onZapComplete(){
Dungeon.hero.damage(Random.NormalIntRange(2+Dungeon.depth/2, 4+Dungeon.depth), new Eye.DeathGaze());
if (!Dungeon.hero.isAlive()){
GLog.n( Messages.capitalize(Messages.get(Char.class, "kill", name())) );
Badges.validateDeathFromEnemyMagic();
Dungeon.fail( getClass() );
GLog.n( Messages.capitalize(Messages.get(Char.class, "kill", name())) );
}
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.traps;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -99,6 +100,7 @@ public class GrimTrap extends Trap {
if (finalTarget == Dungeon.hero) {
Sample.INSTANCE.play(Assets.Sounds.CURSED);
if (!finalTarget.isAlive()) {
Badges.validateDeathFromGrimTrap();
Dungeon.fail( GrimTrap.class );
GLog.n( Messages.get(GrimTrap.class, "ondeath") );
}

View File

@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
@@ -94,8 +95,12 @@ public class PoisonDartTrap extends Trap {
public void call() {
int dmg = Random.NormalIntRange(4, 8) - finalTarget.drRoll();
finalTarget.damage(dmg, trap);
if (finalTarget == Dungeon.hero && !finalTarget.isAlive()){
Dungeon.fail( trap.getClass() );
if (finalTarget == Dungeon.hero){
//for the poison dart traps in the Tengu fight
Statistics.qualifiedForBossChallengeBadge = false;
if (!finalTarget.isAlive()) {
Dungeon.fail(trap.getClass());
}
}
Buff.affect( finalTarget, Poison.class ).set( poisonAmount() );
Sample.INSTANCE.play(Assets.Sounds.HIT, 1, 1, Random.Float(0.8f, 1.25f));

View File

@@ -61,7 +61,7 @@ public class BadgesGrid extends Component {
lockedBadges.add(badge);
}
}
Badges.filterHigherIncrementalBadges(lockedBadges);
Badges.filterBadgesWithoutPrerequisites(lockedBadges);
for (Badges.Badge badge : lockedBadges) {
BadgeButton button = new BadgeButton( badge, false );

View File

@@ -49,10 +49,20 @@ public class WndBadge extends Window {
if (!unlocked) title.hardlight( 0x888822 );
add(title);
RenderedTextBlock info = PixelScene.renderTextBlock( badge.desc(), 6 );
String desc = badge.desc();
String unlock = Badges.showCompletionProgress(badge);
if (unlock != null){
desc += unlock;
}
RenderedTextBlock info = PixelScene.renderTextBlock( desc, 6 );
info.maxWidth(MAX_WIDTH - MARGIN * 2);
info.align(RenderedTextBlock.CENTER_ALIGN);
if (!unlocked) info.hardlight( 0x888888 );
if (!unlocked) {
info.hardlight( 0x888888 );
info.setHightlighting( true, 0x888822 );
}
add(info);
float w = Math.max( icon.width(), Math.max(title.width(), info.width()) ) + MARGIN * 2;