v0.7.1: added hero unlock requirements and 3 badges for hero unlocking
This commit is contained in:
parent
650f10983e
commit
06458bfb20
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.2 KiB |
|
@ -120,6 +120,9 @@ public class Badges {
|
|||
MASTERY_MAGE,
|
||||
MASTERY_ROGUE,
|
||||
MASTERY_HUNTRESS,
|
||||
UNLOCK_MAGE( 65 ),
|
||||
UNLOCK_ROGUE( 66 ),
|
||||
UNLOCK_HUNTRESS( 67 ),
|
||||
ITEM_LEVEL_1( 48 ),
|
||||
ITEM_LEVEL_2( 49 ),
|
||||
ITEM_LEVEL_3( 50 ),
|
||||
|
@ -688,6 +691,24 @@ public class Badges {
|
|||
}
|
||||
}
|
||||
|
||||
public static void validateMageUnlock(){
|
||||
if (Statistics.upgradesUsed >= 2 && !global.contains(Badge.UNLOCK_MAGE)){
|
||||
displayBadge( Badge.UNLOCK_MAGE );
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateRogueUnlock(){
|
||||
if (Statistics.sneakAttacks >= 20 && !global.contains(Badge.UNLOCK_ROGUE)){
|
||||
displayBadge( Badge.UNLOCK_ROGUE );
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateHuntressUnlock(){
|
||||
if (Statistics.thrownAssists >= 20 && !global.contains(Badge.UNLOCK_HUNTRESS)){
|
||||
displayBadge( Badge.UNLOCK_HUNTRESS );
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateMasteryCombo( int n ) {
|
||||
if (!local.contains( Badge.MASTERY_COMBO ) && n == 10) {
|
||||
Badge badge = Badge.MASTERY_COMBO;
|
||||
|
@ -826,6 +847,13 @@ public class Badges {
|
|||
saveNeeded = true;
|
||||
}
|
||||
|
||||
public static void addGlobal( Badge badge ){
|
||||
if (!global.contains(badge)){
|
||||
global.add( badge );
|
||||
saveNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Badge> filtered( boolean global ) {
|
||||
|
||||
HashSet<Badge> filtered = new HashSet<Badge>( global ? Badges.global : Badges.local );
|
||||
|
|
|
@ -48,7 +48,7 @@ public class ShatteredPixelDungeon extends Game {
|
|||
public static final int v0_6_4a = 252;
|
||||
public static final int v0_6_5c = 264;
|
||||
|
||||
public static final int v0_7_0 = 303;
|
||||
public static final int v0_7_0c = 311;
|
||||
|
||||
public ShatteredPixelDungeon() {
|
||||
super( WelcomeScene.class );
|
||||
|
|
|
@ -33,6 +33,11 @@ public class Statistics {
|
|||
public static int piranhasKilled;
|
||||
public static int ankhsUsed;
|
||||
|
||||
//used for hero unlock badges
|
||||
public static int upgradesUsed;
|
||||
public static int sneakAttacks;
|
||||
public static int thrownAssists;
|
||||
|
||||
public static float duration;
|
||||
|
||||
public static boolean qualifiedForNoKilling = false;
|
||||
|
@ -50,6 +55,10 @@ public class Statistics {
|
|||
piranhasKilled = 0;
|
||||
ankhsUsed = 0;
|
||||
|
||||
upgradesUsed = 0;
|
||||
sneakAttacks = 0;
|
||||
thrownAssists = 0;
|
||||
|
||||
duration = 0;
|
||||
|
||||
qualifiedForNoKilling = false;
|
||||
|
@ -65,7 +74,13 @@ public class Statistics {
|
|||
private static final String ALCHEMY = "potionsCooked";
|
||||
private static final String PIRANHAS = "priranhas";
|
||||
private static final String ANKHS = "ankhsUsed";
|
||||
|
||||
private static final String UPGRADES = "upgradesUsed";
|
||||
private static final String SNEAKS = "sneakAttacks";
|
||||
private static final String THROWN = "thrownAssists";
|
||||
|
||||
private static final String DURATION = "duration";
|
||||
|
||||
private static final String AMULET = "amuletObtained";
|
||||
|
||||
public static void storeInBundle( Bundle bundle ) {
|
||||
|
@ -76,7 +91,13 @@ public class Statistics {
|
|||
bundle.put( ALCHEMY, potionsCooked );
|
||||
bundle.put( PIRANHAS, piranhasKilled );
|
||||
bundle.put( ANKHS, ankhsUsed );
|
||||
|
||||
bundle.put( UPGRADES, upgradesUsed );
|
||||
bundle.put( SNEAKS, sneakAttacks );
|
||||
bundle.put( THROWN, thrownAssists );
|
||||
|
||||
bundle.put( DURATION, duration );
|
||||
|
||||
bundle.put( AMULET, amuletObtained );
|
||||
}
|
||||
|
||||
|
@ -88,7 +109,13 @@ public class Statistics {
|
|||
potionsCooked = bundle.getInt( ALCHEMY );
|
||||
piranhasKilled = bundle.getInt( PIRANHAS );
|
||||
ankhsUsed = bundle.getInt( ANKHS );
|
||||
|
||||
upgradesUsed = bundle.getInt( UPGRADES );
|
||||
sneakAttacks = bundle.getInt( SNEAKS );
|
||||
thrownAssists = bundle.getInt( THROWN );
|
||||
|
||||
duration = bundle.getFloat( DURATION );
|
||||
|
||||
amuletObtained = bundle.getBoolean( AMULET );
|
||||
}
|
||||
|
||||
|
|
|
@ -202,9 +202,8 @@ public enum HeroClass {
|
|||
}
|
||||
|
||||
public String spritesheet() {
|
||||
|
||||
switch (this) {
|
||||
case WARRIOR:
|
||||
case WARRIOR: default:
|
||||
return Assets.WARRIOR;
|
||||
case MAGE:
|
||||
return Assets.MAGE;
|
||||
|
@ -213,14 +212,11 @@ public enum HeroClass {
|
|||
case HUNTRESS:
|
||||
return Assets.HUNTRESS;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String[] perks() {
|
||||
|
||||
switch (this) {
|
||||
case WARRIOR:
|
||||
case WARRIOR: default:
|
||||
return new String[]{
|
||||
Messages.get(HeroClass.class, "warrior_perk1"),
|
||||
Messages.get(HeroClass.class, "warrior_perk2"),
|
||||
|
@ -253,8 +249,32 @@ public enum HeroClass {
|
|||
Messages.get(HeroClass.class, "huntress_perk5"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
public boolean isUnlocked(){
|
||||
switch (this){
|
||||
case WARRIOR: default:
|
||||
return true;
|
||||
case MAGE:
|
||||
return Badges.isUnlocked(Badges.Badge.UNLOCK_MAGE);
|
||||
case ROGUE:
|
||||
return Badges.isUnlocked(Badges.Badge.UNLOCK_ROGUE);
|
||||
case HUNTRESS:
|
||||
return Badges.isUnlocked(Badges.Badge.UNLOCK_HUNTRESS);
|
||||
}
|
||||
}
|
||||
|
||||
public String unlockMsg() {
|
||||
switch (this){
|
||||
case WARRIOR: default:
|
||||
return "";
|
||||
case MAGE:
|
||||
return Messages.get(HeroClass.class, "mage_unlock");
|
||||
case ROGUE:
|
||||
return Messages.get(HeroClass.class, "rogue_unlock");
|
||||
case HUNTRESS:
|
||||
return Messages.get(HeroClass.class, "huntress_unlock");
|
||||
}
|
||||
}
|
||||
|
||||
private static final String CLASS = "class";
|
||||
|
|
|
@ -50,6 +50,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourg
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
|
@ -503,10 +504,19 @@ public abstract class Mob extends Char {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean hitWithRanged = false;
|
||||
|
||||
@Override
|
||||
public int defenseProc( Char enemy, int damage ) {
|
||||
|
||||
if (enemy instanceof Hero && ((Hero) enemy).belongings.weapon instanceof MissileWeapon){
|
||||
hitWithRanged = true;
|
||||
}
|
||||
|
||||
if ((!enemySeen || enemy.invisible > 0)
|
||||
&& enemy == Dungeon.hero && Dungeon.hero.canSurpriseAttack()) {
|
||||
Statistics.sneakAttacks++;
|
||||
Badges.validateRogueUnlock();
|
||||
if (enemy.buff(Preparation.class) != null) {
|
||||
Wound.hit(this);
|
||||
} else {
|
||||
|
@ -582,6 +592,11 @@ public abstract class Mob extends Char {
|
|||
@Override
|
||||
public void die( Object cause ) {
|
||||
|
||||
if (hitWithRanged){
|
||||
Statistics.thrownAssists++;
|
||||
Badges.validateHuntressUnlock();
|
||||
}
|
||||
|
||||
if (cause == Chasm.class){
|
||||
//50% chance to round up, 50% to round down
|
||||
if (EXP % 2 == 1) EXP += Random.Int(2);
|
||||
|
|
|
@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.scrolls;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
|
||||
|
@ -97,6 +98,8 @@ public class ScrollOfUpgrade extends InventoryScroll {
|
|||
}
|
||||
|
||||
Badges.validateItemLevelAquired( item );
|
||||
Statistics.upgradesUsed++;
|
||||
Badges.validateMageUnlock();
|
||||
}
|
||||
|
||||
public static void upgrade( Hero hero ) {
|
||||
|
|
|
@ -75,7 +75,7 @@ public class BadgesScene extends PixelScene {
|
|||
|
||||
List<Badges.Badge> badges = Badges.filtered( true );
|
||||
|
||||
int blankBadges = 33;
|
||||
int blankBadges = 36;
|
||||
blankBadges -= badges.size();
|
||||
if (badges.contains(Badges.Badge.ALL_ITEMS_IDENTIFIED)) blankBadges -= 6;
|
||||
if (badges.contains(Badges.Badge.YASD)) blankBadges -= 5;
|
||||
|
|
|
@ -45,7 +45,7 @@ import com.watabou.utils.FileUtils;
|
|||
|
||||
public class WelcomeScene extends PixelScene {
|
||||
|
||||
private static int LATEST_UPDATE = ShatteredPixelDungeon.v0_7_0;
|
||||
private static int LATEST_UPDATE = ShatteredPixelDungeon.v0_7_0c;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
@ -171,7 +171,18 @@ public class WelcomeScene extends PixelScene {
|
|||
}
|
||||
}
|
||||
|
||||
if (previousVersion < ShatteredPixelDungeon.v0_7_0){
|
||||
//give classes to people with saves that have previously unlocked them
|
||||
if (previousVersion <= ShatteredPixelDungeon.v0_7_0c){
|
||||
Badges.loadGlobal();
|
||||
Badges.addGlobal(Badges.Badge.UNLOCK_MAGE);
|
||||
Badges.addGlobal(Badges.Badge.UNLOCK_ROGUE);
|
||||
if (Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_3)){
|
||||
Badges.addGlobal(Badges.Badge.UNLOCK_HUNTRESS);
|
||||
}
|
||||
Badges.saveGlobal();
|
||||
}
|
||||
|
||||
if (previousVersion <= ShatteredPixelDungeon.v0_6_5c){
|
||||
Journal.loadGlobal();
|
||||
Document.ALCHEMY_GUIDE.addPage("Potions");
|
||||
Document.ALCHEMY_GUIDE.addPage("Stones");
|
||||
|
|
|
@ -192,8 +192,8 @@ public class WndStartGame extends Window {
|
|||
public void update() {
|
||||
super.update();
|
||||
if (cl != GamesInProgress.selectedClass){
|
||||
if (cl == HeroClass.HUNTRESS && !Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_3)){
|
||||
hero.brightness( 0f );
|
||||
if (!cl.isUnlocked()){
|
||||
hero.brightness(0.3f);
|
||||
} else {
|
||||
hero.brightness(0.6f);
|
||||
}
|
||||
|
@ -206,9 +206,9 @@ public class WndStartGame extends Window {
|
|||
protected void onClick() {
|
||||
super.onClick();
|
||||
|
||||
if( cl == HeroClass.HUNTRESS && !Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_3)){
|
||||
if( !cl.isUnlocked() ){
|
||||
ShatteredPixelDungeon.scene().add(
|
||||
new WndMessage(Messages.get(WndStartGame.class, "huntress_unlock")));
|
||||
new WndMessage(cl.unlockMsg()));
|
||||
} else {
|
||||
GamesInProgress.selectedClass = cl;
|
||||
}
|
||||
|
|
|
@ -300,18 +300,21 @@ actors.hero.heroclass.warrior_desc_misc=The Warrior regains a small amount of HP
|
|||
actors.hero.heroclass.warrior_desc_subclasses=A subclass can be chosen after defeating the second boss. The Warrior has two subclasses:
|
||||
|
||||
actors.hero.heroclass.mage=mage
|
||||
actors.hero.heroclass.mage_unlock=The Mage is an expert with wands, and carries a _unique magical staff._\n\nTo unlock him _use two scrolls of upgrade in one run.
|
||||
actors.hero.heroclass.mage_desc_item=The Mage starts with a _unique staff,_ which can be imbued with the properties of a wand.\n\nThe staff recharges significantly faster than a wand, and has 1 more maximum charge.\n\nThe staff starts out imbued with magic missile.
|
||||
actors.hero.heroclass.mage_desc_loadout=The Mage starts with his staff as his melee weapon. The staff deals less melee damage than other starter weapons.\n\nThe Mage can use the magic in his staff to attack at range.\n\nThe Mage starts with a _scroll holder,_ which can store various scrolls and protect them from fire.
|
||||
actors.hero.heroclass.mage_desc_misc=The Mage partially identifies wands the moment he uses them.\n\nThe Mage regains a small amount of wand and staff charge whenever he eats food.\n\nThe Mage automatically identifies:\n- Scrolls of Identify\n- Potions of Liquid Flame\n- Scrolls of Upgrade
|
||||
actors.hero.heroclass.mage_desc_subclasses=A subclass can be chosen after defeating the second boss. The Mage has two subclasses:
|
||||
|
||||
actors.hero.heroclass.rogue=rogue
|
||||
actors.hero.heroclass.rogue_unlock=The Rogue can control the flow of battle and strike from invisibility using his _unique cloak of shadows._\n\nTo unlock him _perform 20 sneak attacks in one run._
|
||||
actors.hero.heroclass.rogue_desc_item=The Rogue starts with a unique artifact: the _Cloak of Shadows,_ which he can use to become invisible at will.\n\nLike all artifacts, the cloak cannot be directly upgraded. Instead it becomes more powerful as it is used.
|
||||
actors.hero.heroclass.rogue_desc_loadout=The Rogue starts with a _dagger,_ which deals more damage when surprising enemies.\n\nThe Rogue starts with _three throwing knives,_ which offer some ranged damage and deal more damage to surprised enemies.\n\nThe Rogue starts with a _velvet pouch,_ which can store small items like seeds and runestones.
|
||||
actors.hero.heroclass.rogue_desc_misc=The Rogue detects secrets and traps from a greater distance.\n\nThe Rogue is able to find more secrets hidden in the dungeon.\n\nThe Rogue automatically identifies:\n- Scrolls of Identify\n- Potions of Invisibility\n- Scrolls of Magic Mapping
|
||||
actors.hero.heroclass.rogue_desc_subclasses=A subclass can be chosen after defeating the second boss. The Rogue has two subclasses:
|
||||
|
||||
actors.hero.heroclass.huntress=huntress
|
||||
actors.hero.heroclass.huntress_unlock=The Huntress is a master of thrown weapons, and has a _unique magical bow_ with infinite arrows.\n\nTo unlock her _defeat 20 enemies with the help of missile weapons in one run._
|
||||
actors.hero.heroclass.huntress_desc_item=The Huntress starts with a _unique spirit bow,_ which can fire an infinite number of conjured arrows.\n\nThe bow steadily grows stronger as the huntress levels up, and can be augmented and enchanted.
|
||||
actors.hero.heroclass.huntress_desc_loadout=The Huntress starts with _knuckledusters,_ which attack much faster than other starter weapons.\n\nThe Huntress starts with her bow as a ranged option.\n\nThe Huntress starts with a _velvet pouch,_ which can store small items like seeds and runestones.
|
||||
actors.hero.heroclass.huntress_desc_misc=The Huntress can travel through tall grass without trampling it.\n\nThe Huntress gains bonus damage from excess strength on thrown weapons.\n\nThe Huntress can use thrown weapons for longer before they break.\n\nThe Huntress senses nearby enemies even if they are hidden behind obstacles.\n\nThe Huntress automatically identifies:\n- Scrolls of Identify\n- Potions of Mind Vision\n- Scrolls of Lullaby
|
||||
|
|
|
@ -65,6 +65,9 @@ badges$badge.happy_end=Happy end
|
|||
badges$badge.champion_1=Won with a Challenge
|
||||
badges$badge.champion_2=Won with 3 Challenges
|
||||
badges$badge.champion_3=Won with 6 Challenges
|
||||
badges$badge.unlock_mage=Unlocked the Mage
|
||||
badges$badge.unlock_rogue=Unlocked the Rogue
|
||||
badges$badge.unlock_huntress=Unlocked the Huntress
|
||||
|
||||
challenges.no_food=On diet
|
||||
challenges.no_food_desc=Food is scarce, so make every bite count!\n\n- Regular rations and pasties are replaced with small rations\n- Mystery meat and blandfruit are removed\n- Horn of Plenty is removed
|
||||
|
|
Loading…
Reference in New Issue
Block a user