v1.3.0: finished new ascension route functionality

This commit is contained in:
Evan Debenham
2022-06-10 14:49:59 -04:00
parent 4b86d12ecf
commit 1d20a4ef18
21 changed files with 365 additions and 37 deletions

View File

@@ -67,6 +67,22 @@ actors.buffs.arcanearmor.desc=A thin shield is surrounding you, blocking some of
actors.buffs.artifactrecharge.name=Artifact Recharging
actors.buffs.artifactrecharge.desc=Energy is coursing through you, increasing the rate your equipped artifacts charge.\n\nEach artifact is affected a little differently, but they will all gain charge much faster than normal.\n\nTurns remaining: %s.
actors.buffs.ascensionchallenge.name=Amulet's Curse
actors.buffs.ascensionchallenge.desc=Somehow Yog-Dzewa is maintaining influence on this world through the amulet, and is trying to stop your ascent!\n\nYog's power is making the dungeon much more dangerous, increasing the number of enemies and making them stronger! This power will keep building if left unchecked, it can be weakened by defeating enemies that has been enhanced by Yog's power.
actors.buffs.ascensionchallenge.desc_clear=The dark energy radiating from the amulet has been weakened as much as possible for now.
actors.buffs.ascensionchallenge.desc_beckon=The amulet is currently _calling out to distant enemies,_ alerting them to your position.
actors.buffs.ascensionchallenge.desc_haste=The amulet is currently _hastening distant enemies,_ letting them reach you faster!
actors.buffs.ascensionchallenge.desc_slow=The amulet is currently _slowing you down,_ and negating speed boosting effects!
actors.buffs.ascensionchallenge.desc_damage=The energy from the amulet has gotten so strong that it's _directly harming you!_
actors.buffs.ascensionchallenge.beckon=The amulet begins calling out to distant enemies.
actors.buffs.ascensionchallenge.haste=The amulet begins hastening distant enemies!
actors.buffs.ascensionchallenge.slow=The amulet starts to feel like a lead weight in your inventory!
actors.buffs.ascensionchallenge.damage=The amulet begins radiating dark energy. It burns!
actors.buffs.ascensionchallenge.weaken=You can feel the amulet's curse weaken slightly.
actors.buffs.ascensionchallenge.break=You take a moment to catch your breath and feel your wounds begin to close!
actors.buffs.ascensionchallenge.almost=You feel Yog's grip on the amulet begin to weaken, you're almost there!
actors.buffs.ascensionchallenge.on_kill=The dark energy consumes you...
actors.buffs.barkskin.name=Barkskin
actors.buffs.barkskin.desc=Your skin is hardened, it feels rough and solid like bark.\n\nThe hardened skin increases your effective armor, allowing you to better defend against physical attack.\n\nYour armor is currently increased by: 0-%d.\nTurns until barkskin weakens: %s.
@@ -812,6 +828,7 @@ actors.mobs.npcs.imp.desc=Imps are lesser demons. They are notable for neither t
actors.mobs.npcs.impshopkeeper.name=ambitious imp
actors.mobs.npcs.impshopkeeper.greetings=Hello, %s!
actors.mobs.npcs.impshopkeeper.greetings_ascent=What did you do %s? Shop quickly, I've got to get out of here!
actors.mobs.npcs.impshopkeeper.thief=I thought I could trust you!
actors.mobs.npcs.impshopkeeper.desc=Imps are lesser demons. They are notable for neither their strength nor their magic talent. But they are quite smart and sociable, and many of imps prefer to live and do business among non-demons.

View File

@@ -1705,8 +1705,13 @@ items.weapon.weapon$enchantment.enchant=enchantment
###misc items
items.amulet.name=amulet of yendor
items.amulet.ac_end=END THE GAME
items.amulet.rankings_desc=Obtained the Amulet of Yendor
items.amulet.desc=The Amulet of Yendor is the most powerful artifact known to human or dwarf kind. Its shimmering crystals contain incredible and wondrous power.\n\nThe origins of the amulet are unknown. History says that the King of Dwarves boasted that he had discovered the artifact shortly before the Dwarven civilization cut off all contact. How did he find it? How did Yog-Dzewa take it from him? Questions for another time perhaps, all that matters now is the amulet is yours!
items.amulet.desc=The Amulet of Yendor is the most powerful artifact known to human or dwarf kind. Its shimmering crystals contain incredible and wondrous power.
items.amulet.desc_origins=The origins of the amulet are unknown. History says that the King of Dwarves boasted that he had discovered the artifact shortly before the Dwarven civilization cut off all contact. How did he find it? How did Yog-Dzewa take it from him? Questions for another time perhaps, all that matters now is the amulet is yours!
items.amulet.desc_ascent=The origins of the amulet are unknown, but clearly it has been heavily influenced by Yog-Dzewa's power. The dungeon seems to be bending to Yog's will as you move through it, making enemies much more plentiful and powerful! You're also no longer able to activate or discard the amulet, almost as if it is cursed.
items.amulet.ascent_title=Ascension
items.amulet.ascent_desc=You begin to feel Yog-Dzewa's great and terrible power radiating from the amulet. Ascending back through the dungeon as a mortal might be more difficult than you thought!\n\nIf you continue ascending with the amulet the dungeon will become more dangerous, teleports between floors will be disabled, and you will only be able to win the game by ascending through the dungeon!\n\nYou can leave the amulet here for now if you want to ascend without starting this challenge, or activate the amulet before ascending to end the game normally.
items.amulet.ascent_yes=Continue!
items.amulet.ascent_no=Stop for Now
items.ankh.name=ankh
items.ankh.ac_bless=BLESS

View File

@@ -197,3 +197,5 @@ challenges.stronger_bosses=Badder bosses
challenges.stronger_bosses_desc=Bosses are much tougher with this challenge!\n\n_Goo:_ +20% health\n_-_ Healing in water ramps up, to 3/turn\n_-_ Pumps up in 1 turn instead of 2\n_Tengu:_ +25% health\n_-_ Phase 1: traps are much deadlier\n_-_ Phase 2: abilities are more frequent\n_DM-300:_ +33% health\n_-_ Pylons are tougher and 3 activate\n_-_ Abilities are more powerful and frequent\n_-_ DM-300 is faster when supercharged\n_-_ Exposed wires are twice as common\n_Dwarf King:_ +50% health\n_-_ Minions are stronger in all phases\n_-_ Phase 1: faster abilities and summons\n_-_ Phase 2: 2 more minions per round\n_-_ Phase 3: 2x health, faster summons\n_Yog-Dzewa:_\n_-_ Two fists are summoned at a time!\n_-_ +60% laser damage\n_-_ Stronger minions
rankings$record.something=Killed by Something
rankings$record.won=Obtained the Amulet of Yendor
rankings$record.ascended=Ascended with the Amulet!

View File

@@ -7,7 +7,7 @@ scenes.alchemyscene.energy=Energy:
scenes.amuletscene.exit=Let's call it a day
scenes.amuletscene.stay=I'm not done yet
scenes.amuletscene.text=You finally hold it in your hands, the Amulet of Yendor! With the power of this amulet nothing will be able to stand in your way! You have conquered the dungeon and succeeded in your quest!\n\nOr, perhaps you're not ready yet? You can also decide to just hold onto the amulet, and stay a mere mortal a little longer...
scenes.amuletscene.text=You finally hold it in your hands, the Amulet of Yendor! With the power of this amulet nothing will be able to stand in your way! You have conquered the dungeon and succeeded in your quest!\n\nOr, perhaps you're not ready yet? You can also decide to just hold onto the amulet, stay a mere mortal a little longer, and perhaps leave the dungeon the old fashioned way...
scenes.badgesscene.title=Your Badges

View File

@@ -161,6 +161,7 @@ windows.wndranking$statstab.score=Score
windows.wndranking$statstab.str=Strength
windows.wndranking$statstab.duration=Game Duration
windows.wndranking$statstab.depth=Maximum Depth
windows.wndranking$statstab.ascent=Highest Ascent
windows.wndranking$statstab.seed=Dungeon Seed
windows.wndranking$statstab.enemies=Mobs Killed
windows.wndranking$statstab.gold=Gold Collected

View File

@@ -431,6 +431,10 @@ public class Dungeon {
hero.curAction = hero.lastAction = null;
if (hero.buff(AscensionChallenge.class) != null){
hero.buff(AscensionChallenge.class).onLevelSwitch();
}
observe();
try {
saveAll();

View File

@@ -75,7 +75,13 @@ public enum Rankings {
rec.heroClass = Dungeon.hero.heroClass;
rec.armorTier = Dungeon.hero.tier();
rec.herolevel = Dungeon.hero.lvl;
rec.depth = Dungeon.depth;
if (Statistics.highestAscent == 0){
rec.depth = Statistics.deepestFloor;
rec.ascending = false;
} else {
rec.depth = Statistics.highestAscent;
rec.ascending = true;
}
rec.score = calculateScore();
Badges.validateHighScore( rec.score );
@@ -346,6 +352,7 @@ public enum Rankings {
private static final String TIER = "tier";
private static final String LEVEL = "level";
private static final String DEPTH = "depth";
private static final String ASCEND = "ascending";
private static final String DATA = "gameData";
private static final String ID = "gameID";
@@ -356,7 +363,8 @@ public enum Rankings {
public int armorTier;
public int herolevel;
public int depth;
public boolean ascending;
public Bundle gameData;
public String gameID;
@@ -364,7 +372,13 @@ public enum Rankings {
public int score;
public String desc(){
if (cause == null) {
if (win){
if (ascending){
return Messages.get(this, "ascended");
} else {
return Messages.get(this, "won");
}
} else if (cause == null) {
return Messages.get(this, "something");
} else {
String result = Messages.get(cause, "rankings_desc", (Messages.get(cause, "name")));
@@ -390,15 +404,15 @@ public enum Rankings {
heroClass = bundle.getEnum( CLASS, HeroClass.class );
armorTier = bundle.getInt( TIER );
herolevel = bundle.getInt( LEVEL );
depth = bundle.getInt( DEPTH );
ascending = bundle.getBoolean( ASCEND );
if (bundle.contains(DATA)) gameData = bundle.getBundle(DATA);
if (bundle.contains(ID)) gameID = bundle.getString(ID);
if (gameID == null) gameID = UUID.randomUUID().toString();
depth = bundle.getInt( DEPTH );
herolevel = bundle.getInt( LEVEL );
}
@Override
@@ -413,7 +427,8 @@ public enum Rankings {
bundle.put( TIER, armorTier );
bundle.put( LEVEL, herolevel );
bundle.put( DEPTH, depth );
bundle.put( ASCEND, ascending );
if (gameData != null) bundle.put( DATA, gameData );
bundle.put( ID, gameID );
}

View File

@@ -28,6 +28,7 @@ public class Statistics {
public static int goldCollected;
public static int deepestFloor;
public static int highestAscent;
public static int enemiesSlain;
public static int foodEaten;
public static int itemsCrafted;
@@ -70,6 +71,7 @@ public class Statistics {
goldCollected = 0;
deepestFloor = 0;
highestAscent = 0;
enemiesSlain = 0;
foodEaten = 0;
itemsCrafted = 0;
@@ -108,6 +110,7 @@ public class Statistics {
private static final String GOLD = "score";
private static final String DEEPEST = "maxDepth";
private static final String HIGHEST = "maxAscent";
private static final String SLAIN = "enemiesSlain";
private static final String FOOD = "foodEaten";
private static final String ALCHEMY = "potionsCooked";
@@ -145,6 +148,7 @@ public class Statistics {
public static void storeInBundle( Bundle bundle ) {
bundle.put( GOLD, goldCollected );
bundle.put( DEEPEST, deepestFloor );
bundle.put( HIGHEST, highestAscent );
bundle.put( SLAIN, enemiesSlain );
bundle.put( FOOD, foodEaten );
bundle.put( ALCHEMY, itemsCrafted );
@@ -187,6 +191,7 @@ public class Statistics {
public static void restoreFromBundle( Bundle bundle ) {
goldCollected = bundle.getInt( GOLD );
deepestFloor = bundle.getInt( DEEPEST );
highestAscent = bundle.getInt( HIGHEST );
enemiesSlain = bundle.getInt( SLAIN );
foodEaten = bundle.getInt( FOOD );
itemsCrafted = bundle.getInt( ALCHEMY );

View File

@@ -63,6 +63,7 @@ public abstract class AllyBuff extends Buff{
} else {
hero.earnExp(0, enemy.getClass());
}
if (droppingLoot) AscensionChallenge.processEnemyKill(enemy);
}
}

View File

@@ -21,19 +21,22 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.Ratmogrify;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.*;
import com.shatteredpixel.shatteredpixeldungeon.items.Amulet;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Image;
import com.watabou.utils.Bundle;
import java.util.HashMap;
public class AscensionChallenge extends Buff{
{
revivePersists = true;
}
public class AscensionChallenge extends Buff {
private static HashMap<Class<?extends Mob>, Float> modifiers = new HashMap<>();
static {
@@ -73,6 +76,10 @@ public class AscensionChallenge extends Buff{
return 1;
}
if (ch instanceof Ratmogrify.TransmogRat){
ch = ((Ratmogrify.TransmogRat) ch).getOriginal();
}
for (Class<?extends Mob> cls : modifiers.keySet()){
if (ch.getClass().isAssignableFrom(cls)){
return modifiers.get(cls);
@@ -82,16 +89,83 @@ public class AscensionChallenge extends Buff{
return 1;
}
//mobs get constantly beckoned to the hero at 2.5+ stacks
public static void beckonEnemies(){
if (Dungeon.hero.buff(AscensionChallenge.class) != null
&& Dungeon.hero.buff(AscensionChallenge.class).stacks >= 2.5f){
for (Mob m : Dungeon.level.mobs){
if (m.alignment == Char.Alignment.ENEMY) m.beckon(Dungeon.hero.pos);
}
}
}
//mobs move at 2x speed when not hunting/fleeing at 5 stacks or higher
public static float enemySpeedModifier(Mob m){
if (Dungeon.hero.buff(AscensionChallenge.class) != null
&& m.alignment == Char.Alignment.ENEMY
&& Dungeon.hero.buff(AscensionChallenge.class).stacks >= 5f
&& m.state != m.HUNTING && m.state != m.FLEEING){
return 2;
}
return 1;
}
//hero speed is halved and capped at 1x at 7.5+ stacks
public static float modifyHeroSpeed(float speed){
if (Dungeon.hero.buff(AscensionChallenge.class) != null
&& Dungeon.hero.buff(AscensionChallenge.class).stacks >= 7.5f){
return Math.min(speed/2f, 1f);
}
return speed;
}
public static void processEnemyKill(Char enemy){
AscensionChallenge chal = Dungeon.hero.buff(AscensionChallenge.class);
if (chal == null) return;
if (enemy instanceof Ratmogrify.TransmogRat){
enemy = ((Ratmogrify.TransmogRat) enemy).getOriginal();
}
//only enemies that are boosted count
boolean found = false;
for (Class<?extends Mob> cls : modifiers.keySet()){
if (enemy.getClass().isAssignableFrom(cls)){
found = true;
break;
}
}
if (!found) return;
float oldStacks = chal.stacks;
if (enemy instanceof Ghoul || enemy instanceof RipperDemon){
chal.stacks -= 0.5f;
} else {
chal.stacks -= 1;
}
chal.stacks = Math.max(0, chal.stacks);
if (chal.stacks < 10f && (int)(chal.stacks/2.5) != (int)(oldStacks/2.5f)){
GLog.p(Messages.get(AscensionChallenge.class, "weaken"));
}
BuffIndicator.refreshHero();
}
//used for internal calculations like corruption, not actual exp gain
public static int AscensionExp(Mob m){
if (Dungeon.hero.buff(AscensionChallenge.class) == null){
return m.EXP;
}
if (m instanceof Ratmogrify.TransmogRat){
m = ((Ratmogrify.TransmogRat) m).getOriginal();
}
if (m instanceof RipperDemon){
return 10; //reduced due to their numbers
} else if (m instanceof Ghoul){
return 7; //half of 14
return 7; //half of 13, rounded up
} else {
for (Class<?extends Mob> cls : modifiers.keySet()){
if (m.getClass().isAssignableFrom(cls)){
@@ -102,6 +176,77 @@ public class AscensionChallenge extends Buff{
return m.EXP;
}
{
revivePersists = true;
}
private float stacks = 0;
private float damageInc = 0;
public void onLevelSwitch(){
if (Dungeon.depth < Statistics.highestAscent){
Statistics.highestAscent = Dungeon.depth;
if (Dungeon.bossLevel()){
Dungeon.hero.buff(Hunger.class).satisfy(Hunger.STARVING);
Buff.affect(Dungeon.hero, Healing.class).setHeal(Dungeon.hero.HT, 0, 20);
toSay = Messages.get(this, "break");
} else {
stacks += 2.5f;
if (Dungeon.depth == 1){
toSay = Messages.get(this, "almost");
} else if (stacks >= 10f){
toSay = Messages.get(this, "damage");
} else if (stacks >= 7.5f){
toSay = Messages.get(this, "slow");
} else if (stacks >= 5f){
toSay = Messages.get(this, "haste");
} else if (stacks >= 2.5f){
toSay = Messages.get(this, "beckon");
}
}
}
}
private String toSay;
public void saySwitch(){
if (toSay != null){
if (Dungeon.bossLevel() || Dungeon.depth == 1){
GLog.p(toSay);
} else {
GLog.n(toSay);
}
toSay = null;
}
}
@Override
public boolean act() {
beckonEnemies();
//hero starts progressively taking damage over time at 10+ stacks
if (stacks >= 10 && !Dungeon.bossLevel()){
damageInc += (stacks-5)/5f;
if (damageInc >= 1){
target.damage((int)damageInc, this);
damageInc -= (int)damageInc;
if (target == Dungeon.hero && !target.isAlive()){
Badges.validateDeathFromFriendlyMagic();
GLog.n(Messages.get(this, "on_kill"));
Dungeon.fail(Amulet.class);
}
}
} else {
damageInc = 0;
}
spend(TICK);
return true;
}
@Override
public int icon() {
return BuffIndicator.AMULET;
@@ -109,8 +254,58 @@ public class AscensionChallenge extends Buff{
@Override
public void tintIcon(Image icon) {
icon.hardlight(1, 1, 0);
if (stacks < 2.5f){
icon.hardlight(0.5f, 1, 0);
} else if (stacks < 5) {
icon.hardlight(1, 1, 0);
} else if (stacks < 7.5f){
icon.hardlight(1, 0.67f, 0);
} else if (stacks < 10){
icon.hardlight(1, 0.33f, 0);
} else {
icon.hardlight(1, 0, 0);
}
}
@Override
public String toString() {
return Messages.get(this, "name");
}
@Override
public String desc() {
String desc = Messages.get(this, "desc");
desc += "\n";
if (stacks < 2.5f){
desc += "\n" + Messages.get(this, "desc_clear");
} else {
if (stacks >= 2.5f) desc += "\n" + Messages.get(this, "desc_beckon");
if (stacks >= 5.0f) desc += "\n" + Messages.get(this, "desc_haste");
if (stacks >= 7.5f) desc += "\n" + Messages.get(this, "desc_slow");
if (stacks >= 10.0f) desc += "\n" + Messages.get(this, "desc_damage");
}
return desc;
}
public static final String STACKS = "enemy_stacks";
public static final String DAMAGE = "damage_inc";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(STACKS, stacks);
bundle.put(DAMAGE, damageInc);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
stacks = bundle.getFloat(STACKS);
damageInc = bundle.getFloat(DAMAGE);
}
}

View File

@@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AdrenalineSurge;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AnkhInvulnerability;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AscensionChallenge;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barkskin;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Berserk;
@@ -130,6 +131,8 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.SurfaceScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
@@ -137,6 +140,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndHero;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
import com.watabou.noosa.Camera;
@@ -566,6 +570,8 @@ public class Hero extends Char {
if (natStrength != null){
speed *= (2f + 0.25f*pointsInTalent(Talent.GROWING_POWER));
}
speed = AscensionChallenge.modifyHeroSpeed(speed);
return speed;
@@ -1028,6 +1034,34 @@ public class Hero extends Char {
Game.switchScene( SurfaceScene.class );
}
} else if (transition.type == LevelTransition.Type.REGULAR_ENTRANCE
&& Dungeon.depth == 25
//ascension challenge only works on runs started on v1.3+
&& Dungeon.initialVersion > ShatteredPixelDungeon.v1_2_3
&& belongings.getItem(Amulet.class) != null
&& buff(AscensionChallenge.class) == null) {
Game.runOnRenderThread(new Callback() {
@Override
public void call() {
GameScene.show( new WndOptions( new ItemSprite(ItemSpriteSheet.AMULET),
Messages.get(Amulet.class, "ascent_title"),
Messages.get(Amulet.class, "ascent_desc"),
Messages.get(Amulet.class, "ascent_yes"),
Messages.get(Amulet.class, "ascent_no")){
@Override
protected void onSelect(int index) {
if (index == 0){
Buff.affect(Hero.this, AscensionChallenge.class);
Statistics.highestAscent = 25;
actTransition(action);
}
}
} );
}
});
ready();
} else {
curAction = null;

View File

@@ -190,6 +190,10 @@ public class Ratmogrify extends ArmorAbility {
}
public Mob getOriginal(){
return original;
}
private float timeLeft = 6f;
@Override

View File

@@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Adrenaline;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AllyBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AscensionChallenge;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ChampionEnemy;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
@@ -643,6 +644,11 @@ public abstract class Mob extends Char {
return damage;
}
@Override
public float speed() {
return super.speed() * AscensionChallenge.enemySpeedModifier(this);
}
public final boolean surprisedBy( Char enemy ){
return surprisedBy( enemy, true);
}
@@ -691,6 +697,8 @@ public abstract class Mob extends Char {
Statistics.enemiesSlain++;
Badges.validateMonstersSlain();
Statistics.qualifiedForNoKilling = false;
AscensionChallenge.processEnemyKill(this);
int exp = Dungeon.hero.lvl <= maxLvl ? EXP : 0;
if (exp > 0) {

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AscensionChallenge;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
@@ -41,7 +42,11 @@ public class ImpShopkeeper extends Shopkeeper {
protected boolean act() {
if (!seenBefore && Dungeon.level.heroFOV[pos]) {
yell( Messages.get(this, "greetings", Dungeon.hero.name() ) );
if (Dungeon.hero.buff(AscensionChallenge.class) == null) {
yell(Messages.get(this, "greetings", Dungeon.hero.name()));
} else {
yell(Messages.get(this, "greetings_ascent", Dungeon.hero.name()));
}
seenBefore = true;
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AscensionChallenge;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
@@ -54,7 +55,7 @@ public class Shopkeeper extends NPC {
Notes.add(Notes.Landmark.SHOP);
}
if (Dungeon.depth < 20 && Dungeon.hero.buff(AscensionChallenge.class) != null){
if (Statistics.highestAscent < 20 && Dungeon.hero.buff(AscensionChallenge.class) != null){
flee();
return true;
}

View File

@@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AscensionChallenge;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.AmuletScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.Game;
@@ -124,4 +125,16 @@ public class Amulet extends Item {
return false;
}
@Override
public String desc() {
String desc = super.desc();
if (Dungeon.hero.buff(AscensionChallenge.class) == null){
desc += "\n\n" + Messages.get(this, "desc_origins");
} else {
desc += "\n\n" + Messages.get(this, "desc_ascent");
}
return desc;
}
}

View File

@@ -582,13 +582,13 @@ public abstract class Level implements Bundlable {
}
public int mobCount(){
int count = 0;
float count = 0;
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])){
if (mob.alignment == Char.Alignment.ENEMY && !mob.properties().contains(Char.Property.MINIBOSS)) {
count += mob.spawningWeight();
}
}
return count;
return Math.round(count);
}
public Mob findMob( int pos ){
@@ -647,10 +647,12 @@ public abstract class Level implements Bundlable {
public float respawnCooldown(){
if (Statistics.amuletObtained){
if (Dungeon.level.mobCount() <= 2){
return TIME_TO_RESPAWN / 10f;
if (Dungeon.depth == 1){
//very fast spawns on floor 1! 0/2/4/6/8/10, etc.
return Dungeon.level.mobCount() * (TIME_TO_RESPAWN / 25f);
} else {
return TIME_TO_RESPAWN / 2f;
//respawn time is 0/6/13/19/25/25, etc.
return Math.round(Math.min(Dungeon.level.mobCount() * (TIME_TO_RESPAWN / 8f), TIME_TO_RESPAWN / 2f));
}
} else if (Dungeon.level.feeling == Feeling.DARK){
return 2*TIME_TO_RESPAWN/3f;
@@ -667,9 +669,6 @@ public abstract class Level implements Bundlable {
mob.pos = Dungeon.level.randomRespawnCell( mob );
if (Dungeon.hero.isAlive() && mob.pos != -1 && PathFinder.distance[mob.pos] >= disLimit) {
GameScene.add( mob );
if (Statistics.amuletObtained) {
mob.beckon( Dungeon.hero.pos );
}
if (!mob.buffs(ChampionEnemy.class).isEmpty()){
GLog.w(Messages.get(ChampionEnemy.class, "warn"));
}

View File

@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels;
import com.shatteredpixel.shatteredpixeldungeon.Bones;
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;
@@ -186,7 +187,10 @@ public abstract class RegularLevel extends Level {
@Override
public int mobLimit() {
if (Dungeon.depth <= 1) return 0;
if (Dungeon.depth <= 1){
if (!Statistics.amuletObtained) return 0;
else return 10;
}
int mobs = 3 + Dungeon.depth % 5 + Random.Int(3);
if (feeling == Feeling.LARGE){

View File

@@ -34,6 +34,7 @@ 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.buffs.AscensionChallenge;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ChampionEnemy;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
@@ -285,9 +286,6 @@ public class GameScene extends PixelScene {
for (Mob mob : Dungeon.level.mobs) {
addMobSprite( mob );
if (Statistics.amuletObtained) {
mob.beckon( Dungeon.hero.pos );
}
}
raisedTerrain = new RaisedTerrainTilemap();
@@ -564,6 +562,10 @@ public class GameScene extends PixelScene {
}
}
if (Dungeon.hero.buff(AscensionChallenge.class) != null){
Dungeon.hero.buff(AscensionChallenge.class).saySwitch();
}
InterlevelScene.mode = InterlevelScene.Mode.NONE;

View File

@@ -210,6 +210,11 @@ public class RankingsScene extends PixelScene {
add(depth);
}
if (rec.ascending){
shield.view( ItemSpriteSheet.AMULET, null );
shield.hardlight(0.4f, 0.4f, 0.7f);
}
}
if (rec.herolevel != 0){

View File

@@ -132,12 +132,16 @@ public class WndRanking extends WndTabbed {
Icons[] icons =
{Icons.RANKINGS, Icons.TALENT, Icons.BACKPACK_LRG, Icons.BADGES, Icons.CHALLENGE_ON};
Group[] pages =
{new StatsTab(), new TalentsTab(), new ItemsTab(), new BadgesTab(), new ChallengesTab()};
{new StatsTab(), new TalentsTab(), new ItemsTab(), new BadgesTab(), null};
if (Dungeon.challenges != 0) pages[4] = new ChallengesTab();
for (int i=0; i < pages.length; i++) {
if (i == 4 && Dungeon.challenges == 0) break;
if (pages[i] == null) {
break;
}
add( pages[i] );
Tab tab = new RankingTab( icons[i], pages[i] );
@@ -183,7 +187,7 @@ public class WndRanking extends WndTabbed {
title.setRect( 0, 0, WIDTH, 0 );
add( title );
float pos = title.bottom() + GAP + 2;
float pos = title.bottom() + GAP + 1;
NumberFormat num = NumberFormat.getInstance(Locale.US);
pos = statSlot( this, Messages.get(this, "score"), num.format( Statistics.totalScore ), pos );
@@ -205,7 +209,11 @@ public class WndRanking extends WndTabbed {
else if (strBonus < 0) pos = statSlot(this, Messages.get(this, "str"), Dungeon.hero.STR + " - " + -strBonus, pos );
else pos = statSlot(this, Messages.get(this, "str"), Integer.toString(Dungeon.hero.STR), pos);
pos = statSlot( this, Messages.get(this, "duration"), num.format( (int)Statistics.duration ), pos );
pos = statSlot( this, Messages.get(this, "depth"), num.format( Statistics.deepestFloor ), pos );
if (Statistics.highestAscent == 0) {
pos = statSlot(this, Messages.get(this, "depth"), num.format(Statistics.deepestFloor), pos);
} else {
pos = statSlot(this, Messages.get(this, "ascent"), num.format(Statistics.highestAscent), pos);
}
if (Dungeon.seed != -1) {
pos = statSlot(this, Messages.get(this, "seed"), DungeonSeed.convertToCode(Dungeon.seed), pos);
} else {