v2.5.0: made a bunch of code tweaks so catalogs can appear out of game

This commit is contained in:
Evan Debenham
2024-06-19 15:48:07 -04:00
parent d69530831d
commit b6f7e7462c
25 changed files with 132 additions and 71 deletions

View File

@@ -149,8 +149,13 @@ public class SpiritHawk extends ArmorAbility {
defenseSkill = 60;
flying = true;
viewDistance = (int)GameMath.gate(6, 6+Dungeon.hero.pointsInTalent(Talent.EAGLE_EYE), 8);
baseSpeed = 2f + Dungeon.hero.pointsInTalent(Talent.SWIFT_SPIRIT)/2f;
if (Dungeon.hero != null) {
viewDistance = (int) GameMath.gate(6, 6 + Dungeon.hero.pointsInTalent(Talent.EAGLE_EYE), 8);
baseSpeed = 2f + Dungeon.hero.pointsInTalent(Talent.SWIFT_SPIRIT) / 2f;
} else {
viewDistance = 6;
baseSpeed = 2f;
}
attacksAutomatically = false;
immunities.addAll(new BlobImmunity().immunities());

View File

@@ -171,7 +171,9 @@ public class SmokeBomb extends ArmorAbility {
alignment = Alignment.ALLY;
HP = HT = 20*Dungeon.hero.pointsInTalent(Talent.BODY_REPLACEMENT);
HT = 20;
if (Dungeon.hero != null) HT *= Dungeon.hero.pointsInTalent(Talent.BODY_REPLACEMENT);
HP = HT;
}
@Override

View File

@@ -161,7 +161,7 @@ public class RatKing extends NPC {
@Override
public String description() {
if (Dungeon.hero.armorAbility instanceof Ratmogrify){
if (Dungeon.hero != null && Dungeon.hero.armorAbility instanceof Ratmogrify){
return Messages.get(this, "desc_crown");
} else if (Holiday.getCurrentHoliday() == Holiday.APRIL_FOOLS){
return Messages.get(this, "desc_birthday");

View File

@@ -134,7 +134,7 @@ public class Amulet extends Item {
public String desc() {
String desc = super.desc();
if (Dungeon.hero.buff(AscensionChallenge.class) == null){
if (Dungeon.hero == null || Dungeon.hero.buff(AscensionChallenge.class) == null){
desc += "\n\n" + Messages.get(this, "desc_origins");
} else {
desc += "\n\n" + Messages.get(this, "desc_ascent");

View File

@@ -373,7 +373,7 @@ public class Item implements Bundlable {
//note that not all item properties should care about buffs/debuffs! (e.g. str requirement)
public int buffedLvl(){
//only the hero can be affected by Degradation
if (Dungeon.hero.buff( Degrade.class ) != null
if (Dungeon.hero != null && Dungeon.hero.buff( Degrade.class ) != null
&& (isEquipped( Dungeon.hero ) || Dungeon.hero.belongings.contains( this ))) {
return Degrade.reduceLevel(level());
} else {

View File

@@ -181,9 +181,9 @@ public abstract class KindofMisc extends EquipableItem {
@Override
public boolean isEquipped( Hero hero ) {
return hero.belongings.artifact() == this
return hero != null && (hero.belongings.artifact() == this
|| hero.belongings.misc() == this
|| hero.belongings.ring() == this;
|| hero.belongings.ring() == this);
}
}

View File

@@ -504,13 +504,13 @@ public class Armor extends EquipableItem {
info += "\n\n" + Messages.get(Armor.class, "curr_absorb", tier, DRMin(), DRMax(), STRReq());
if (STRReq() > Dungeon.hero.STR()) {
if (Dungeon.hero != null && STRReq() > Dungeon.hero.STR()) {
info += " " + Messages.get(Armor.class, "too_heavy");
}
} else {
info += "\n\n" + Messages.get(Armor.class, "avg_absorb", tier, DRMin(0), DRMax(0), STRReq(0));
if (STRReq(0) > Dungeon.hero.STR()) {
if (Dungeon.hero != null && STRReq(0) > Dungeon.hero.STR()) {
info += " " + Messages.get(Armor.class, "probably_too_heavy");
}
}

View File

@@ -297,7 +297,7 @@ abstract public class ClassArmor extends Armor {
public String desc() {
String desc = super.desc();
if (Dungeon.hero.belongings.contains(this)) {
if (Dungeon.hero != null && Dungeon.hero.belongings.contains(this)) {
ArmorAbility ability = Dungeon.hero.armorAbility;
if (ability != null) {
desc += "\n\n" + ability.shortDesc();

View File

@@ -393,7 +393,7 @@ public class Potion extends Item {
}
public static boolean allKnown() {
return handler.known().size() == Generator.Category.POTION.classes.length;
return handler != null && handler.known().size() == Generator.Category.POTION.classes.length;
}
protected int splashColor(){

View File

@@ -64,7 +64,7 @@ public class ElixirOfMight extends Elixir {
}
public String desc() {
return Messages.get(this, "desc", HTBoost.boost(Dungeon.hero.HT));
return Messages.get(this, "desc", HTBoost.boost(Dungeon.hero != null ? Dungeon.hero.HT : 20));
}
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {

View File

@@ -242,7 +242,7 @@ public class Ring extends KindofMisc {
}
public static boolean allKnown() {
return handler.known().size() == Generator.Category.RING.classes.length;
return handler != null && handler.known().size() == Generator.Category.RING.classes.length;
}
@Override

View File

@@ -117,7 +117,7 @@ public class RingOfForce extends Ring {
@Override
public String statsInfo() {
float tier = tier(Dungeon.hero.STR());
float tier = tier(Dungeon.hero != null ? Dungeon.hero.STR() : 10);
if (isIdentified()) {
int level = soloBuffedBonus();
String info = Messages.get(this, "stats", min(level, tier), max(level, tier), level);
@@ -200,7 +200,7 @@ public class RingOfForce extends Ring {
public String info() {
String info = super.info();
if (Dungeon.hero.heroClass == HeroClass.DUELIST
if (Dungeon.hero != null && Dungeon.hero.heroClass == HeroClass.DUELIST
&& (anonymous || isIdentified() || isEquipped(Dungeon.hero))){
//0 if unidentified, solo level if unequipped, combined level if equipped
int level = isIdentified() ? (isEquipped(Dungeon.hero) ? getBuffedBonus(Dungeon.hero, Force.class) : soloBuffedBonus()) : 0;

View File

@@ -256,7 +256,7 @@ public abstract class Scroll extends Item {
}
public static boolean allKnown() {
return handler.known().size() == Generator.Category.SCROLL.classes.length;
return handler != null && handler.known().size() == Generator.Category.SCROLL.classes.length;
}
@Override

View File

@@ -265,7 +265,7 @@ public abstract class Wand extends Item {
desc += "\n\n" + Messages.get(Wand.class, "not_cursed");
}
if (Dungeon.hero.subClass == HeroSubClass.BATTLEMAGE){
if (Dungeon.hero != null && Dungeon.hero.subClass == HeroSubClass.BATTLEMAGE){
desc += "\n\n" + Messages.get(this, "bmage_desc");
}

View File

@@ -189,7 +189,7 @@ public class WandOfTransfusion extends DamageWand {
@Override
public String statsDesc() {
int selfDMG = Math.round(Dungeon.hero.HT*0.05f);
int selfDMG = Dungeon.hero != null ? Math.round(Dungeon.hero.HT*0.05f): 1;
if (levelKnown)
return Messages.get(this, "stats_desc", selfDMG, selfDMG + 3*buffedLvl(), 5+buffedLvl(), min(), max());
else

View File

@@ -269,7 +269,7 @@ public class MeleeWeapon extends Weapon {
private static boolean evaluatingTwinUpgrades = false;
@Override
public int buffedLvl() {
if (!evaluatingTwinUpgrades && isEquipped(Dungeon.hero) && Dungeon.hero.hasTalent(Talent.TWIN_UPGRADES)){
if (!evaluatingTwinUpgrades && Dungeon.hero != null && isEquipped(Dungeon.hero) && Dungeon.hero.hasTalent(Talent.TWIN_UPGRADES)){
KindOfWeapon other = null;
if (Dungeon.hero.belongings.weapon() != this) other = Dungeon.hero.belongings.weapon();
if (Dungeon.hero.belongings.secondWep() != this) other = Dungeon.hero.belongings.secondWep();
@@ -333,14 +333,16 @@ public class MeleeWeapon extends Weapon {
if (levelKnown) {
info += "\n\n" + Messages.get(MeleeWeapon.class, "stats_known", tier, augment.damageFactor(min()), augment.damageFactor(max()), STRReq());
if (STRReq() > Dungeon.hero.STR()) {
info += " " + Messages.get(Weapon.class, "too_heavy");
} else if (Dungeon.hero.STR() > STRReq()){
info += " " + Messages.get(Weapon.class, "excess_str", Dungeon.hero.STR() - STRReq());
if (Dungeon.hero != null) {
if (STRReq() > Dungeon.hero.STR()) {
info += " " + Messages.get(Weapon.class, "too_heavy");
} else if (Dungeon.hero.STR() > STRReq()) {
info += " " + Messages.get(Weapon.class, "excess_str", Dungeon.hero.STR() - STRReq());
}
}
} else {
info += "\n\n" + Messages.get(MeleeWeapon.class, "stats_unknown", tier, min(0), max(0), STRReq(0));
if (STRReq(0) > Dungeon.hero.STR()) {
if (Dungeon.hero != null && STRReq(0) > Dungeon.hero.STR()) {
info += " " + Messages.get(MeleeWeapon.class, "probably_too_heavy");
}
}
@@ -379,7 +381,7 @@ public class MeleeWeapon extends Weapon {
}
//the mage's staff has no ability as it can only be gained by the mage
if (Dungeon.hero.heroClass == HeroClass.DUELIST && !(this instanceof MagesStaff)){
if (Dungeon.hero != null && Dungeon.hero.heroClass == HeroClass.DUELIST && !(this instanceof MagesStaff)){
info += "\n\n" + abilityInfo();
}

View File

@@ -75,7 +75,11 @@ abstract public class MissileWeapon extends Weapon {
@Override
public int min() {
return Math.max(0, min( buffedLvl() + RingOfSharpshooting.levelDamageBonus(Dungeon.hero) ));
if (Dungeon.hero != null){
return Math.max(0, min(buffedLvl() + RingOfSharpshooting.levelDamageBonus(Dungeon.hero)));
} else {
return Math.max(0 , min( buffedLvl() ));
}
}
@Override
@@ -86,7 +90,11 @@ abstract public class MissileWeapon extends Weapon {
@Override
public int max() {
return Math.max(0, max( buffedLvl() + RingOfSharpshooting.levelDamageBonus(Dungeon.hero) ));
if (Dungeon.hero != null){
return Math.max(0, max( buffedLvl() + RingOfSharpshooting.levelDamageBonus(Dungeon.hero) ));
} else {
return Math.max(0 , max( buffedLvl() ));
}
}
@Override
@@ -326,14 +334,14 @@ abstract public class MissileWeapon extends Weapon {
float usages = baseUses * (float)(Math.pow(3, level()));
//+50%/75% durability
if (Dungeon.hero.hasTalent(Talent.DURABLE_PROJECTILES)){
if (Dungeon.hero != null && Dungeon.hero.hasTalent(Talent.DURABLE_PROJECTILES)){
usages *= 1.25f + (0.25f*Dungeon.hero.pointsInTalent(Talent.DURABLE_PROJECTILES));
}
if (holster) {
usages *= MagicalHolster.HOLSTER_DURABILITY_FACTOR;
}
usages *= RingOfSharpshooting.durabilityMultiplier( Dungeon.hero );
if (Dungeon.hero != null) usages *= RingOfSharpshooting.durabilityMultiplier( Dungeon.hero );
//at 100 uses, items just last forever.
if (usages >= 100f) return 0;
@@ -451,10 +459,12 @@ abstract public class MissileWeapon extends Weapon {
Math.round(augment.damageFactor(max())),
STRReq());
if (STRReq() > Dungeon.hero.STR()) {
info += " " + Messages.get(Weapon.class, "too_heavy");
} else if (Dungeon.hero.STR() > STRReq()){
info += " " + Messages.get(Weapon.class, "excess_str", Dungeon.hero.STR() - STRReq());
if (Dungeon.hero != null) {
if (STRReq() > Dungeon.hero.STR()) {
info += " " + Messages.get(Weapon.class, "too_heavy");
} else if (Dungeon.hero.STR() > STRReq()) {
info += " " + Messages.get(Weapon.class, "excess_str", Dungeon.hero.STR() - STRReq());
}
}
if (enchantment != null && (cursedKnown || !enchantment.curse())){

View File

@@ -100,6 +100,7 @@ public class Dart extends MissileWeapon {
protected static Crossbow bow;
private void updateCrossbow(){
if (Dungeon.hero == null) return;
if (Dungeon.hero.belongings.weapon() instanceof Crossbow){
bow = (Crossbow) Dungeon.hero.belongings.weapon();
} else if (Dungeon.hero.belongings.secondWep() instanceof Crossbow) {

View File

@@ -154,32 +154,34 @@ public abstract class TippedDart extends Dart {
@Override
public float durabilityPerUse() {
float use = super.durabilityPerUse(false);
use /= (1 + Dungeon.hero.pointsInTalent(Talent.DURABLE_TIPS));
//checks both destination and source position
float lotusPreserve = 0f;
if (targetPos != -1){
for (Char ch : Actor.chars()){
if (ch instanceof WandOfRegrowth.Lotus){
if (Dungeon.hero != null) {
use /= (1 + Dungeon.hero.pointsInTalent(Talent.DURABLE_TIPS));
//checks both destination and source position
float lotusPreserve = 0f;
if (targetPos != -1) {
for (Char ch : Actor.chars()) {
if (ch instanceof WandOfRegrowth.Lotus) {
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) ch;
if (l.inRange(targetPos)) {
lotusPreserve = Math.max(lotusPreserve, l.seedPreservation());
}
}
}
targetPos = -1;
}
int p = curUser == null ? Dungeon.hero.pos : curUser.pos;
for (Char ch : Actor.chars()) {
if (ch instanceof WandOfRegrowth.Lotus) {
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) ch;
if (l.inRange(targetPos)){
if (l.inRange(p)) {
lotusPreserve = Math.max(lotusPreserve, l.seedPreservation());
}
}
}
targetPos = -1;
use *= (1f - lotusPreserve);
}
int p = curUser == null ? Dungeon.hero.pos : curUser.pos;
for (Char ch : Actor.chars()){
if (ch instanceof WandOfRegrowth.Lotus){
WandOfRegrowth.Lotus l = (WandOfRegrowth.Lotus) ch;
if (l.inRange(p)){
lotusPreserve = Math.max(lotusPreserve, l.seedPreservation());
}
}
}
use *= (1f - lotusPreserve);
float usages = Math.round(MAX_DURABILITY/use);

View File

@@ -121,7 +121,7 @@ public abstract class Plant implements Bundlable {
public String desc() {
String desc = Messages.get(this, "desc");
if (Dungeon.hero.subClass == HeroSubClass.WARDEN){
if (Dungeon.hero != null && Dungeon.hero.subClass == HeroSubClass.WARDEN){
desc += "\n\n" + Messages.get(this, "warden_desc");
}
return desc;
@@ -219,7 +219,7 @@ public abstract class Plant implements Bundlable {
@Override
public String desc() {
String desc = Messages.get(plantClass, "desc");
if (Dungeon.hero.subClass == HeroSubClass.WARDEN){
if (Dungeon.hero != null && Dungeon.hero.subClass == HeroSubClass.WARDEN){
desc += "\n\n" + Messages.get(plantClass, "warden_desc");
}
return desc;

View File

@@ -73,9 +73,11 @@ public class GooSprite extends MobSprite {
play(idle);
spray = centerEmitter();
spray.autoKill = false;
spray.pour( GooParticle.FACTORY, 0.04f );
spray.on = false;
if (spray != null) {
spray.autoKill = false;
spray.pour(GooParticle.FACTORY, 0.04f);
spray.on = false;
}
}
@Override

View File

@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.MirrorImage;
import com.watabou.noosa.TextureFilm;
import com.watabou.utils.PointF;
@@ -35,7 +36,7 @@ public class MirrorSprite extends MobSprite {
public MirrorSprite() {
super();
texture( Dungeon.hero.heroClass.spritesheet() );
texture( Dungeon.hero != null ? Dungeon.hero.heroClass.spritesheet() : HeroClass.WARRIOR.spritesheet() );
updateArmor( 0 );
idle();
}

View File

@@ -46,7 +46,9 @@ public class TerrainFeaturesTilemap extends DungeonTilemap {
this.plants = plants;
this.traps = traps;
map( Dungeon.level.map, Dungeon.level.width() );
if (Dungeon.level != null) {
map(Dungeon.level.map, Dungeon.level.width());
}
instance = this;
}
@@ -81,6 +83,8 @@ public class TerrainFeaturesTilemap extends DungeonTilemap {
}
public static Image getTrapVisual( Trap trap ){
if (instance == null) instance = new TerrainFeaturesTilemap(null, null);
RectF uv = instance.tileset.get((trap.active ? trap.color : Trap.BLACK) + (trap.shape * 16));
if (uv == null) return null;
@@ -90,6 +94,8 @@ public class TerrainFeaturesTilemap extends DungeonTilemap {
}
public static Image getPlantVisual( Plant plant ){
if (instance == null) instance = new TerrainFeaturesTilemap(null, null);
RectF uv = instance.tileset.get(plant.image + 7*16);
if (uv == null) return null;

View File

@@ -115,12 +115,15 @@ public class QuickRecipe extends Component {
ShatteredPixelDungeon.scene().addToFront(new WndInfoItem(in));
}
};
ArrayList<Item> similar = Dungeon.hero.belongings.getAllSimilar(in);
int quantity = 0;
for (Item sim : similar) {
//if we are looking for a specific item, it must be IDed
if (sim.getClass() != in.getClass() || sim.isIdentified()) quantity += sim.quantity();
if (Dungeon.hero != null) {
ArrayList<Item> similar = Dungeon.hero.belongings.getAllSimilar(in);
for (Item sim : similar) {
//if we are looking for a specific item, it must be IDed
if (sim.getClass() != in.getClass() || sim.isIdentified())
quantity += sim.quantity();
}
}
if (quantity < in.quantity()) {

View File

@@ -37,6 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
@@ -655,7 +656,12 @@ public class WndJournal extends WndTabbed {
desc = Messages.get(CatalogTab.class, "not_seen_item");
} else {
title = Messages.titleCase(item.trueName());
desc = item instanceof ClassArmor ? item.desc() : item.info();
//some items don't include direct stats, generally when they're not applicable
if (item instanceof ClassArmor || item instanceof SpiritBow){
desc += item.desc();
} else {
desc += item.info();
}
if (Catalog.useCount(itemClass) > 1) {
if (item.isUpgradable()) {
@@ -715,7 +721,11 @@ public class WndJournal extends WndTabbed {
if (inside(x, y)) {
Image sprite = new ItemSprite();
sprite.copy(icon);
GameScene.show(new WndJournalItem(sprite, finalTitle, finalDesc));
if (ShatteredPixelDungeon.scene() instanceof GameScene){
GameScene.show(new WndJournalItem(sprite, finalTitle, finalDesc));
} else {
ShatteredPixelDungeon.scene().addToFront(new WndJournalItem(sprite, finalTitle, finalDesc));
}
return true;
} else {
return false;
@@ -834,10 +844,17 @@ public class WndJournal extends WndTabbed {
@Override
public boolean onClick(float x, float y) {
if (inside(x, y)) {
Image image;
if (seen && finalMob != null){
GameScene.show(new WndJournalItem(finalMob.sprite(), finalTitle, finalDesc));
image = finalMob.sprite();
} else {
GameScene.show(new WndJournalItem(new Image(icon), finalTitle, finalDesc));
image = new Image(icon);
}
if (ShatteredPixelDungeon.scene() instanceof GameScene){
GameScene.show(new WndJournalItem(image, finalTitle, finalDesc));
} else {
ShatteredPixelDungeon.scene().addToFront(new WndJournalItem(image, finalTitle, finalDesc));
}
return true;
@@ -871,11 +888,21 @@ public class WndJournal extends WndTabbed {
if (inside(x, y)) {
Image sprite = new Image(icon);
if (seen) {
GameScene.show(new WndStory(sprite, doc.pageTitle(page), doc.pageBody(page)));
if (ShatteredPixelDungeon.scene() instanceof GameScene){
GameScene.show(new WndStory(sprite, doc.pageTitle(page), doc.pageBody(page)));
} else {
ShatteredPixelDungeon.scene().addToFront(new WndStory(sprite, doc.pageTitle(page), doc.pageBody(page)));
}
doc.readPage(page);
hardLightBG(1, 1, 1);
} else {
GameScene.show(new WndJournalItem(sprite, "???", Messages.get(CatalogTab.class, "not_seen_lore")));
if (ShatteredPixelDungeon.scene() instanceof GameScene){
GameScene.show(new WndJournalItem(sprite, "???", Messages.get(CatalogTab.class, "not_seen_lore")));
} else {
ShatteredPixelDungeon.scene().addToFront(new WndJournalItem(sprite, "???", Messages.get(CatalogTab.class, "not_seen_lore")));
}
}
return true;
} else {