v3.3.0: added a randomize button to hero select

This commit is contained in:
Evan Debenham
2025-11-05 12:50:48 -05:00
parent f8bd2233b9
commit 45ecb30dbe
6 changed files with 142 additions and 1 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -73,6 +73,12 @@ scenes.heroselectscene.custom_seed_nowin=The game uses a seed code for dungeon g
scenes.heroselectscene.custom_seed_set=Set
scenes.heroselectscene.custom_seed_clear=Clear
scenes.heroselectscene.challenges_nowin=Challenges are optional modifiers that make the game more difficult. Some challenges make the dungeon more dangerous, others reduce the power of your abilities or items.\n\n_You must win at least one game before you are able to enable challenges._
scenes.heroselectscene.randomize=Randomize
scenes.heroselectscene.randomize_hero=Randomize Hero
scenes.heroselectscene.randomize_chals=Randomize Challenges
scenes.heroselectscene.randomize_chals_title=Challenges
scenes.heroselectscene.randomize_confirm=Confirm
scenes.heroselectscene.randomize_cancel=Cancel
scenes.interlevelscene$mode.descend=Descending
scenes.interlevelscene$mode.ascend=Ascending

View File

@@ -38,6 +38,7 @@ public class Challenges {
public static final int STRONGER_BOSSES = 256;
public static final int MAX_VALUE = 511;
public static final int MAX_CHALS = 9;
public static final String[] NAME_IDS = {
"champion_enemies",
@@ -56,9 +57,13 @@ public class Challenges {
};
public static int activeChallenges(){
return activeChallenges(Dungeon.challenges);
}
public static int activeChallenges(int mask){
int chCount = 0;
for (int ch : Challenges.MASKS){
if ((Dungeon.challenges & ch) != 0) chCount++;
if ((mask & ch) != 0) chCount++;
}
return chCount;
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.scenes;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress;
@@ -32,9 +33,12 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.journal.Journal;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.CheckBox;
import com.shatteredpixel.shatteredpixeldungeon.ui.ExitButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
import com.shatteredpixel.shatteredpixeldungeon.ui.OptionSlider;
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
import com.shatteredpixel.shatteredpixeldungeon.ui.StyledButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
@@ -62,6 +66,7 @@ import com.watabou.utils.DeviceCompat;
import com.watabou.utils.GameMath;
import com.watabou.utils.PlatformSupport;
import com.watabou.utils.PointF;
import com.watabou.utils.Random;
import com.watabou.utils.RectF;
import java.text.SimpleDateFormat;
@@ -810,6 +815,35 @@ public class HeroSelectScene extends PixelScene {
add(challengeButton);
buttons.add(challengeButton);
int unlockedCount = 0;
for (HeroClass cls : HeroClass.values()){
if (cls.isUnlocked()) unlockedCount++;
}
if (unlockedCount >= 2) {
StyledButton randomButton = new StyledButton(Chrome.Type.BLANK, Messages.get(HeroSelectScene.class, "randomize"), 6) {
@Override
protected void onClick() {
if (Badges.isUnlocked(Badges.Badge.VICTORY) || DeviceCompat.isDebug()){
ShatteredPixelDungeon.scene().addToFront(new WndRandomize());
//add window
} else {
HeroClass randomCls;
do {
randomCls = Random.oneOf(HeroClass.values());
} while (!randomCls.isUnlocked());
setSelectedHero(randomCls);
}
}
};
randomButton.leftJustify = true;
randomButton.icon(Icons.SHUFFLE.get());
buttons.add(randomButton);
add(randomButton);
}
for (int i = 1; i < buttons.size(); i++){
ColorBlock spc = new ColorBlock(1, 1, 0xFF000000);
add(spc);
@@ -817,6 +851,90 @@ public class HeroSelectScene extends PixelScene {
}
}
private class WndRandomize extends Window {
CheckBox chkHero;
CheckBox chkChals;
OptionSlider optChals;
public WndRandomize(){
super();
chkHero = new CheckBox(Messages.get(HeroSelectScene.class, "randomize_hero"));
chkHero.setRect(0, 0, 120, 16);
chkHero.checked(true);
add(chkHero);
chkChals = new CheckBox(Messages.get(HeroSelectScene.class, "randomize_chals")){
@Override
public void checked(boolean value) {
super.checked(value);
optChals.enable(value);
}
};
chkChals.setRect(0, 20, 120, 16);
add(chkChals);
int max = Challenges.MAX_CHALS;
optChals = new OptionSlider(Messages.get(HeroSelectScene.class, "randomize_chals_title"), "0", Integer.toString(max), 0, max) {
@Override
protected void onChange() {
//do nothing immediately
}
};
optChals.enable(false);
optChals.setSelectedValue(Challenges.activeChallenges(SPDSettings.challenges()));
optChals.setRect(0, 38, 120, 22);
add(optChals);
RedButton btnCancel = new RedButton(Messages.get(HeroSelectScene.class, "randomize_cancel")){
@Override
protected void onClick() {
super.onClick();
hide();
}
};
btnCancel.setRect(61, 64, 60, 16);
add(btnCancel);
RedButton btnConfirm = new RedButton(Messages.get(HeroSelectScene.class, "randomize_confirm")){
@Override
protected void onClick() {
super.onClick();
hide();
if (chkHero.checked()){
HeroClass randomCls;
do {
randomCls = Random.oneOf(HeroClass.values());
} while (!randomCls.isUnlocked());
setSelectedHero(randomCls);
}
if (chkChals.checked()){
int chals = optChals.getSelectedValue();
ArrayList<Integer> chalMasks = new ArrayList<>();
for (int i = 0; i < Challenges.MAX_CHALS; i++){
chalMasks.add((int)Math.pow(2, i));
}
Random.shuffle(chalMasks);
int mask = 0;
for (int i = 0; i < chals; i++){
mask += chalMasks.remove(0);
}
SPDSettings.challenges(mask);
ShatteredPixelDungeon.scene().addToFront(new WndChallenges(mask, false));
}
}
};
btnConfirm.setRect(0, 64, 60, 16);
add(btnConfirm);
resize(120, (int)btnConfirm.bottom());
}
}
@Override
protected void layout() {
super.layout();

View File

@@ -62,6 +62,7 @@ public enum Icons {
RIGHTARROW,
CALENDAR,
CHEVRON,
SHUFFLE,
//misc larger icons, mainly used for buttons, tabs, and journal, spacing for 16x16
TARGET,
@@ -224,6 +225,9 @@ public enum Icons {
case CHEVRON:
icon.frame( icon.texture.uvRectBySize( 240, 16, 13, 10 ) );
break;
case SHUFFLE:
icon.frame(icon.texture.uvRectBySize( 240, 32, 16, 15 ) );
break;
case TARGET:
icon.frame( icon.texture.uvRectBySize( 0, 32, 16, 16 ) );

View File

@@ -87,6 +87,14 @@ public abstract class OptionSlider extends Component {
PixelScene.align(sliderNode);
}
public void enable( boolean value ) {
active = value;
title.alpha( value ? 1.0f : 0.3f );
minTxt.alpha( value ? 1.0f : 0.3f );
maxTxt.alpha( value ? 1.0f : 0.3f );
sliderNode.alpha( value ? 1.0f : 0.3f );
}
@Override
protected void createChildren() {
super.createChildren();