v0.9.4: Overhauled guidebook functionality

This commit is contained in:
Evan Debenham 2021-08-08 17:16:41 -04:00
parent 50a374aa43
commit d26e6b41dd
18 changed files with 235 additions and 90 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -557,6 +557,10 @@ items.journal.documentpage.desc=A lone page, probably torn from a book of some s
items.journal.alchemypage.name=torn alchemy book page
items.journal.alchemypage.desc=A torn page from a guidebook on alchemy.\n\nMost of the text is too small to read at a distance, but you can make out the title of the page:\n\n_"%s"_
items.journal.guidebook.name=tome of dungeon mastery
items.journal.guidebook.hint=Your guidebook has advice for you!
items.journal.guidebook.desc=An adventurer's guidebook, left here by someone who decided adventuring wasn't for them! This particular book is magical, and can prompt adventurers to read a page at the right moment.\n\nDespite that functionality, the book is most popular because of the big words "Don't Panic!" written in large friendly letters on the cover.
items.journal.guidepage.name=torn guidebook page
items.journal.guidepage.desc=A torn page from an adventuring guidebook.\n\nMost of the text is too small to read at a distance, but you can make out the title of the page:\n\n_"%s"_

View File

@ -1,24 +1,30 @@
journal.document.adventurers_guide.title=Adventurer's Guide
journal.document.adventurers_guide.title=Tome of Dungeon Mastery
journal.document.adventurers_guide.intro.title=Introduction
journal.document.adventurers_guide.intro.body=Greetings Adventurer!\n\nYou are reading the amazing Adventurer's Guide to Dungeoneering! This guidebook is full of tips and tricks to help budding adventurers survive and excel!\n\nWhile you can read this guide all at once, it is best used as a reference. Make sure to check it whenever you're struggling.\n\nKeep your wits about you, and remember:\nDON'T PANIC!
journal.document.adventurers_guide.identifying.title=Identifying Items
journal.document.adventurers_guide.identifying.body=Identifying items can be just as important as finding them!\n\nThe colors on potions and glyphs on scrolls are different in each dungeon, so you won't know what effect you'll get if they're unidentified.\n\nUnidentified equipment can be upgraded if you're lucky, or it might be cursed! Accidentally equipping a cursed item is bad, but usually isn't instant doom.\n\nScrolls of identify, upgrade, or remove curse are very useful if you want to reduce the risk of unidentified items.\n\n(You can find a list of all the items you've identified in the items tab of your journal)
journal.document.adventurers_guide.examining_and_searching.title=Examining and Searching
journal.document.adventurers_guide.examining_and_searching.body=Charging forward recklessly is a great way to get killed.\n\nThere's always time to slow down and examine things around you, which can help you figure out the best way to approach a situation. Rushing into enemies is almost never the best way to deal with them.\n\nDungeons are full of secret passages and traps which appear invisible at first glance. It's good to be willing to thoroughly search an area if you suspect something is hidden.\n\n(The magnifying glass button is used for examining and searching. Tap it once and then tap on something to examine, tap it twice to search the area around you)
journal.document.adventurers_guide.strength.title=Strength and Upgrades
journal.document.adventurers_guide.strength.body=There won't be any time to train with weapons and armor you find in the dungeon, so you'll need brute strength to use them effectively.\n\nPotions of Strength directly enhance your physical might and are the most effective way to meet the requirements of higher tier gear. \n\nScrolls of Upgrade are primarily for making equipment stronger, but also reduce weight. However each upgrade will be less effective at reducing weight than the last.\n\nIt's important to work towards heavier, high tier items, but don't completely ignore equipment you can use sooner as well.
journal.document.adventurers_guide.food.title=Dealing with Hunger
journal.document.adventurers_guide.food.body=Using food effectively is one of the best things you can do to improve your odds of survival.\n\nHunger ultimately affects your health: you will slowly heal when satiated and slowly lose health when starving. Losing health may sound bad, but as long as you don't die losing health has no direct penalty.\n\nIt's best to think of health and hunger as resources that need to be managed, not kept full at all times. For example, if you have full health, the health regen you get from being full will be wasted.\n\nIf you pace out when you eat based on how your health is doing, your food should last much longer.
journal.document.adventurers_guide.levelling.title=Gaining Experience
journal.document.adventurers_guide.levelling.body=As you defeat enemies your level of experience will increase. Your experience determines how accurate your attacks are, how easily you can dodge, and how much health you have.\n\nYour experience level makes a big difference in combat. It's best to have at least one level for each floor of the dungeon.\n\nIt can be tempting to rush through a dungeon, avoiding exploration and combat, but doing so will deprive you of both supplies and experience.\n\n(You can see information about your hero, including exp, on the status pane at the top of the game interface. Tap on your hero portrait to get even more info)
journal.document.adventurers_guide.intro.body=Greetings Adventurer, you are reading the Tome of Dungeon Mastery! This book is full of tips and tricks to help budding adventurers survive and excel!\n\nThis guide is best used as a reference, and will magically let you know when is the best time to read each page! Of course, you can still read it all at once if you prefer.\n\n(Whenever the journal icon at the top-right blinks, the guidebook has something to tell you! Some pages seem to be ripped out of the book though, perhaps you can find them in the dungeon?)
journal.document.adventurers_guide.examining.title=Examining
journal.document.adventurers_guide.examining.body=Rushing into enemies is almost never the best way to deal with them. It's important to take your time and study your opponents and surroundings so that you can learn how best to defeat them!\n\nExamining things also takes no time, so it's best to get in the habit of doing it to everything new you encounter.\n\n(You can examine something by tapping on the magnifying glass button, and then on the thing you want to examine. You can also examine buffs or debuffs by tapping on their icons.)
journal.document.adventurers_guide.surprise_attacks.title=Surprise Attacks
journal.document.adventurers_guide.surprise_attacks.body=One of the best ways to get the upper hand in combat is with surprise attacks.\n\nA surprise attack occurs whenever you attack an enemy while you are out of their sight, or right as you come into view. Even the most evasive of enemies can't dodge a surprise attack!\n\nOne of the most common parts of the environment you can use to surprise enemies is a door. An enemy will be open to a surprise attack right as they move through a closed door.\n\n(When you successfully land a surprise attack, a yellow exclamation mark will briefly appear ontop of the enemy you just struck)
journal.document.adventurers_guide.surprise_attacks.body=You're guaranteed to hit an enemy if you surprise them by attacking from outside of their view, or right as you enter their view. Even the most evasive of enemies can't dodge a surprise attack, which makes them very useful against enemies like wraiths and snakes.\n\nOne of the most common parts of the environment you can use to surprise enemies is a door, if an enemy chases you through one you can turn around as they enter and catch them by surprise!
journal.document.adventurers_guide.identifying.title=Identifying Items
journal.document.adventurers_guide.identifying.body=You won't know all of the properties of some items when you first find them.\n\nThe color of each potion and symbol of each scroll is different in each dungeon. Unidentified equipment can be upgraded or enchanted if you're lucky, or it might be cursed!\n\nScrolls of identify, upgrade, or remove curse are very useful if you want to reduce the risk of using unidentified items.\n\n(You can find a list of all the items you've identified in the items tab of your journal)
journal.document.adventurers_guide.food.title=Dealing with Hunger
journal.document.adventurers_guide.food.body=Rationing food effectively is one of the best things you can do to improve your odds of survival. It's best to think of health and hunger as resources that need to be managed, rather than being kept full at all times.\n\nStarving hurts, and being full slowly heals you. If you have full health though, the health regeneration you get from being full will be wasted.\n\nIf you pace out when you eat based on how your health is doing, your food should last much longer.
journal.document.adventurers_guide.dieing.title=Handling Defeat
journal.document.adventurers_guide.dieing.body=If a situation is looking grim, there's no shame in running away. Escaping to another part of the dungeon can give you some time to recover before trying again.\n\nUnfortunately, dungeoneering is a very dangerous profession and most adventurers will eventually meet their demise. While luck can definitely play a role, the best adventurers are the ones who use every little trick to improve their odds.\n\n(Don't be dissuaded if you are dying a lot. You shouldn't expect to get very far in your first few tries, this game is hard! Focus on learning the game and steadily improving, don't focus on winning right away.)
journal.document.adventurers_guide.dieing.body=Unfortunately, dungeoneering is a very dangerous profession and most adventurers will eventually meet their demise. While luck can definitely play a role, the best adventurers are the ones who use every little trick to improve their odds of success.\n\n(Don't be dissuaded if you are dying a lot. You shouldn't expect to get very far in your first few tries, this game is hard! Focus on learning the game and steadily improving, don't focus on winning right away.)
journal.document.adventurers_guide.searching.title=Searching
journal.document.adventurers_guide.searching.body=Dungeons are full of secret doorways and traps which appear invisible at first glance. Searching takes time, but is very useful if you suspect something is hidden.\n\nSearch near walls if you suspect a door is hidden, or around floors if you suspect a trap is hidden.\n\n(You can search all the tiles around you by double-tapping on the magnifying glass button. Anything that's hidden in these tiles will be revealed.)
journal.document.adventurers_guide.strength.title=Strength
journal.document.adventurers_guide.strength.body=There won't be any time to train with weapons and armor you find in the dungeon, so you'll need brute strength to use them effectively.\n\nPotions of Strength directly enhance your physical might and are the most effective way to meet the requirements of heavier, higher tier gear.\n\nIt's important to work towards heavier, high tier items, but don't completely ignore equipment you can use sooner as well. Once you're deep enough in the dungeon you'll need high tier gear to survive, but you have to survive long enough to equip it first!
journal.document.adventurers_guide.upgrades.title=Upgrades
journal.document.adventurers_guide.upgrades.body=The deeper you go into a dungeon, the more important it is that you're using magically enhanced gear.\n\nHigher tier weapons and armor gain more power from upgrades, but you'll also need the strength to use them properly. Wands, rings, and artifacts don't need strength, but have limited usages or don't help as directly in combat.\n\nMaking good choices about what you upgrade is one of the most important ways to set yourself up for success later in the dungeon. The most successful adventurers will end their dungeon runs with highly upgraded high tier gear.
journal.document.adventurers_guide.looting.title=Effective Looting
journal.document.adventurers_guide.looting.body=Specific rooms will often contain better loot than others. Some of these rooms will be behind locked doors, or will contain obstacles which must be navigated past.\n\nWhenever an obstacle like this blocks your progress, look for a solution nearby. Whether it's a key or something more crafty, there is usually a tool you can use on the same floor.\n\nPotions of strength and scrolls of upgrade are an excellent measure of how well you're exploring and looting. You will be able to find 3 scrolls of upgrade and 2 potions of strength per dungeon region.\n\n(You can see a list of important landmarks and unused keys in the notes tab of the journal window.)
journal.document.adventurers_guide.looting.body=Specific rooms will often contain better loot. Some of these rooms will be behind locked doors, or will contain obstacles which must be overcome.\n\nWhenever an obstacle blocks your progress, look for a solution nearby. Whether it's a key or something more crafty, you can usually find an item to help you on the same floor.\n\nPotions of strength and scrolls of upgrade are an excellent benchmark of how well you're exploring and looting. You will be able to find 2 potions of strength and 3 scrolls of upgrade in each five floor dungeon region.\n\n(You can see a list of important landmarks and unused keys in the notes tab of the journal window.)
journal.document.adventurers_guide.levelling.title=Gaining Experience
journal.document.adventurers_guide.levelling.body=Your experience level boosts your accuracy, evasion, health, and awards talent points. All of these can make a big difference in combat. It's best to have at least one level for each floor of the dungeon.\n\nIt can be tempting to rush through a dungeon, avoiding exploration and combat, but doing so will deprive you of both supplies and experience.\n\n(You can see information about your hero, including exp, on the status pane at the top of the game interface. Tap on your hero portrait to get even more info.)
journal.document.adventurers_guide.positioning.title=Positioning
journal.document.adventurers_guide.positioning.body=Effectively fighting enemies depends on good strategy as well as strong equipment. Bad situations like getting surrounded are often preventable with good positioning.\n\nFor instance, most dungeons have thin corridors, which are excellent at forcing enemies to fight you one at a time. These corridors often have doorways too, which can be used for surprise attacks!\n\nThere are lots of little ways to use environmental features like grass, water, or traps to your advantage as well.
journal.document.adventurers_guide.magic.title=Magical Attacks
journal.document.adventurers_guide.magic.body=Magical attacks cut right through armor and are extremely difficult to dodge.\n\nThis means that damage you deal with wands will be very reliable, but also makes magical enemies extremely dangerous.\n\nMagical attacks always have a caveat though. In the case of wands it's their limited charges, wands become almost useless if they aren't given time to recharge. Magic that enemies use will always have some form of weakness as well. \n\nWhen facing enemies that use magic it is extremely important to figure out how to evade their magic, rather than just eating the damage from it.
journal.document.adventurers_guide.magic.body=Magical attacks cut right through armor and are extremely difficult to dodge. This means that your wands will be very reliable, but also makes magical enemies extremely dangerous!\n\nMagical attacks always have a drawback though. In the case of wands it's their limited charges, but magic that enemies use will always have some form of weakness as well.\n\nWhen facing enemies that use magic it is extremely important to figure out how to evade their magic, rather than just eating the damage from it.
journal.document.alchemy_guide.title=Alchemy Guide
journal.document.alchemy_guide.potions.title=Creating Potions

View File

@ -41,7 +41,7 @@ public class ShatteredPixelDungeon extends Game {
public static final int v0_9_0b = 489;
public static final int v0_9_1d = 511;
public static final int v0_9_2b = 532;
public static final int v0_9_3 = 544;
public static final int v0_9_3c = 557; //557 on iOS, 554 on other platforms
public ShatteredPixelDungeon( PlatformSupport platform ) {
super( sceneClass == null ? WelcomeScene.class : sceneClass, platform );

View File

@ -26,7 +26,10 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HornOfPlenty;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Bundle;
@ -94,6 +97,11 @@ public class Hunger extends Buff implements Hero.Doom {
GLog.w( Messages.get(this, "onhungry") );
if (!Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_FOOD)){
GLog.p(Messages.get(Guidebook.class, "hint"));
GameScene.flashForDocument(Document.GUIDE_FOOD);
}
}
level = newLevel;

View File

@ -59,6 +59,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.N
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Endure;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Monk;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Snake;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
@ -82,6 +83,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.EtherealChains;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HornOfPlenty;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.GoldenKey;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
@ -105,6 +107,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Flail;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
@ -1252,6 +1255,13 @@ public class Hero extends Char {
} else if (distance(target) > distance(m)) {
target = m;
}
if (m instanceof Snake
&& !Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_EXAMINING)){
GLog.p(Messages.get(Guidebook.class, "hint"));
GameScene.flashForDocument(Document.GUIDE_EXAMINING);
//we set to read here to prevent this message popping up a bunch
Document.ADVENTURERS_GUIDE.readPage(Document.GUIDE_EXAMINING);
}
}
}
}

View File

@ -24,7 +24,10 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.SnakeSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Random;
@ -59,8 +62,9 @@ public class Snake extends Mob {
@Override
public String defenseVerb() {
dodges++;
if (dodges >= 3 && !Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_1)){
GLog.h(Messages.get(this, "hint"));
if (dodges >= 2 && !Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_SURPRISE_ATKS)){
GLog.p(Messages.get(Guidebook.class, "hint"));
GameScene.flashForDocument(Document.GUIDE_SURPRISE_ATKS);
dodges = 0;
}
return super.defenseVerb();

View File

@ -27,12 +27,17 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import java.util.ArrayList;
import javax.print.Doc;
public abstract class EquipableItem extends Item {
public static final String AC_EQUIP = "EQUIP";
@ -49,6 +54,19 @@ public abstract class EquipableItem extends Item {
return actions;
}
@Override
public boolean doPickUp(Hero hero) {
if (super.doPickUp(hero)){
if (!isIdentified() && !Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_IDING)){
GLog.p(Messages.get(Guidebook.class, "hint"));
GameScene.flashForDocument(Document.GUIDE_IDING);
}
return true;
} else {
return false;
}
}
@Override
public void execute( Hero hero, String action ) {

View File

@ -37,10 +37,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.food.ChargrilledMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.food.FrozenCarpaccio;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.DocumentPage;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
@ -418,6 +420,9 @@ public class Heap implements Bundlable {
|| ((DocumentPage) item).document().pageFound(((DocumentPage) item).page()))){
items.remove(item);
}
if (item instanceof Guidebook && Document.ADVENTURERS_GUIDE.pageRead(0)){
items.remove(item);
}
}
haunted = bundle.getBoolean( HAUNTED );

View File

@ -0,0 +1,66 @@
package com.shatteredpixel.shatteredpixeldungeon.items.journal;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndJournal;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStory;
import com.watabou.noosa.Game;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
public class Guidebook extends Item {
{
image = ItemSpriteSheet.MASTERY;
}
@Override
public final boolean doPickUp(Hero hero) {
GameScene.pickUpJournal(this, hero.pos);
String page = Document.GUIDE_INTRO;
Game.runOnRenderThread(new Callback() {
@Override
public void call() {
GameScene.show(new WndStory(WndJournal.GuideTab.iconForPage(page),
Document.ADVENTURERS_GUIDE.pageTitle(page),
Document.ADVENTURERS_GUIDE.pageBody(page)){
float elapsed = 0;
@Override
public void update() {
elapsed += Game.elapsed;
super.update();
}
@Override
public void hide() {
//prevents accidentally closing
if (elapsed >= 1) {
super.hide();
}
}
});
}
});
Document.ADVENTURERS_GUIDE.readPage(Document.GUIDE_INTRO);
Sample.INSTANCE.play( Assets.Sounds.ITEM );
hero.spendAndNext( TIME_TO_PICK_UP );
return true;
}
@Override
public boolean isUpgradable() {
return false;
}
@Override
public boolean isIdentified() {
return true;
}
}

View File

@ -125,34 +125,45 @@ public enum Document {
return pageBody( pagesStates.keySet().toArray(new String[0])[pageIdx] );
}
public static final String GUIDE_INTRO_PAGE = "Intro";
public static final String GUIDE_SEARCH_PAGE = "Examining_and_Searching";
public static final String GUIDE_INTRO = "Intro";
public static final String GUIDE_EXAMINING = "Examining";
public static final String GUIDE_SURPRISE_ATKS = "Surprise_Attacks";
public static final String GUIDE_IDING = "Identifying";
public static final String GUIDE_FOOD = "Food";
public static final String GUIDE_DIEING = "Dieing";
public static final String GUIDE_SEARCHING = "Searching";
//pages and default states
static {
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_INTRO_PAGE, DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Identifying", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_SEARCH_PAGE, DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Strength", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Food", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Levelling", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Surprise_Attacks", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Dieing", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Looting", DeviceCompat.isDebug() ? 2 : 0);
ADVENTURERS_GUIDE.pagesStates.put("Magic", DeviceCompat.isDebug() ? 2 : 0);
boolean debug = DeviceCompat.isDebug();
//hero starts with these
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_INTRO, debug ? READ : FOUND);
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_EXAMINING, debug ? READ : FOUND);
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_SURPRISE_ATKS, debug ? READ : FOUND);
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_IDING, debug ? READ : FOUND);
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_FOOD, debug ? READ : FOUND);
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_DIEING, debug ? READ : FOUND);
//given in sewers
ADVENTURERS_GUIDE.pagesStates.put(GUIDE_SEARCHING, debug ? READ : NOT_FOUND);
ADVENTURERS_GUIDE.pagesStates.put("Strength", debug ? READ : NOT_FOUND);
ADVENTURERS_GUIDE.pagesStates.put("Upgrades", debug ? READ : NOT_FOUND);
ADVENTURERS_GUIDE.pagesStates.put("Looting", debug ? READ : NOT_FOUND);
ADVENTURERS_GUIDE.pagesStates.put("Levelling", debug ? READ : NOT_FOUND);
ADVENTURERS_GUIDE.pagesStates.put("Positioning", debug ? READ : NOT_FOUND);
ADVENTURERS_GUIDE.pagesStates.put("Magic", debug ? READ : NOT_FOUND);
//sewers
ALCHEMY_GUIDE.pagesStates.put("Potions", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Stones", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Energy_Food", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Bombs", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Weapons", DeviceCompat.isDebug() ? 2 : 0);
//prison
ALCHEMY_GUIDE.pagesStates.put("Exotic_Potions", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Exotic_Scrolls", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Catalysts", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Brews_Elixirs", DeviceCompat.isDebug() ? 2 : 0);
ALCHEMY_GUIDE.pagesStates.put("Spells", DeviceCompat.isDebug() ? 2 : 0);
//given in sewers
ALCHEMY_GUIDE.pagesStates.put("Potions", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Stones", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Energy_Food", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Bombs", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Weapons", debug ? READ : NOT_FOUND);
//given in prison
ALCHEMY_GUIDE.pagesStates.put("Exotic_Potions", debug? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Exotic_Scrolls", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Catalysts", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Brews_Elixirs", debug ? READ : NOT_FOUND);
ALCHEMY_GUIDE.pagesStates.put("Spells", debug ? READ : NOT_FOUND);
}
private static final String DOCUMENTS = "documents";

View File

@ -444,12 +444,11 @@ public abstract class RegularLevel extends Level {
}
}
//a total of 8 pages drop randomly, 2 pages are specially dropped
missingPages.remove(Document.GUIDE_INTRO_PAGE);
missingPages.remove(Document.GUIDE_SEARCH_PAGE);
//a total of 6 pages drop randomly, the rest are specially dropped or are given at the start
missingPages.remove(Document.GUIDE_SEARCHING);
//chance to find a page scales with pages missing and depth
float dropChance = (missingPages.size() + Dungeon.depth - 1) / (float)(allPages.size() - 2);
//chance to find a page is 0/25/50/75/100% for floors 1/2/3/4/5+
float dropChance = 0.25f*(Dungeon.depth-1);
if (!missingPages.isEmpty() && Random.Float() < dropChance){
GuidePage p = new GuidePage();
p.page(missingPages.get(0));

View File

@ -216,7 +216,7 @@ public abstract class RegularPainter extends Painter {
//entrance doors on floor 2 are hidden if the player hasn't picked up 2nd guidebook page
if (Dungeon.depth == 2
&& !Document.ADVENTURERS_GUIDE.pageFound(Document.GUIDE_SEARCH_PAGE)
&& !Document.ADVENTURERS_GUIDE.pageFound(Document.GUIDE_SEARCHING)
&& r instanceof EntranceRoom){
d.type = Room.Door.Type.HIDDEN;
}

View File

@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.GuidePage;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
@ -66,20 +67,18 @@ public class EntranceRoom extends StandardRoom {
Random.pushGenerator();
//places the first guidebook page on floor 1
if (Dungeon.depth == 1 && !Document.ADVENTURERS_GUIDE.pageFound(Document.GUIDE_INTRO_PAGE)){
if (Dungeon.depth == 1 && !Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_INTRO)){
int pos;
do {
//can't be on bottom row of tiles
pos = level.pointToCell(new Point( Random.IntRange( left + 1, right - 1 ),
Random.IntRange( top + 1, bottom - 2 )));
} while (pos == level.entrance || level.findMob(level.entrance) != null);
GuidePage p = new GuidePage();
p.page(Document.GUIDE_INTRO_PAGE);
level.drop( p, pos );
level.drop( new Guidebook(), pos );
}
//places the third guidebook page on floor 2
if (Dungeon.depth == 2 && !Document.ADVENTURERS_GUIDE.pageFound(Document.GUIDE_SEARCH_PAGE)){
if (Dungeon.depth == 2 && !Document.ADVENTURERS_GUIDE.pageFound(Document.GUIDE_SEARCHING)){
int pos;
do {
//can't be on bottom row of tiles
@ -87,7 +86,7 @@ public class EntranceRoom extends StandardRoom {
Random.IntRange( top + 1, bottom - 2 )));
} while (pos == level.entrance || level.findMob(level.entrance) != null);
GuidePage p = new GuidePage();
p.page(Document.GUIDE_SEARCH_PAGE);
p.page(Document.GUIDE_SEARCHING);
level.drop( p, pos );
}

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.Rankings;
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
@ -35,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ChampionEnemy;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DemonSpawner;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Snake;
import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites;
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.CircleArc;
@ -47,8 +49,10 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Honeypot;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.items.journal.Guidebook;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.journal.Journal;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
@ -534,6 +538,11 @@ public class GameScene extends PixelScene {
}
if (Rankings.INSTANCE.totalNumber > 0 && !Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_DIEING)){
GLog.p(Messages.get(Guidebook.class, "hint"));
GameScene.flashForDocument(Document.GUIDE_DIEING);
}
fadeIn();
//assume the hero died with an ankh
@ -1169,6 +1178,10 @@ public class GameScene extends PixelScene {
GameScene.show( new WndHero() );
} else if ( o instanceof Mob ){
GameScene.show(new WndInfoMob((Mob) o));
if (o instanceof Snake && !Document.ADVENTURERS_GUIDE.pageRead(Document.GUIDE_SURPRISE_ATKS)){
GLog.p(Messages.get(Guidebook.class, "hint"));
GameScene.flashForDocument(Document.GUIDE_SURPRISE_ATKS);
}
} else if ( o instanceof Heap ){
GameScene.show(new WndInfoItem((Heap)o));
} else if ( o instanceof Plant ){

View File

@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites;
import com.shatteredpixel.shatteredpixeldungeon.effects.Fireball;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
@ -46,7 +47,6 @@ import com.watabou.noosa.audio.Music;
import com.watabou.utils.FileUtils;
import java.util.ArrayList;
import java.util.Locale;
public class WelcomeScene extends PixelScene {
@ -189,13 +189,11 @@ public class WelcomeScene extends PixelScene {
//update rankings, to update any data which may be outdated
if (previousVersion < LATEST_UPDATE){
int highestChalInRankings = 0;
try {
Rankings.INSTANCE.load();
for (Rankings.Record rec : Rankings.INSTANCE.records.toArray(new Rankings.Record[0])){
try {
Rankings.INSTANCE.loadGameData(rec);
if (rec.win) highestChalInRankings = Math.max(highestChalInRankings, Challenges.activeChallenges());
Rankings.INSTANCE.saveGameData(rec);
} catch (Exception e) {
//if we encounter a fatal per-record error, then clear that record
@ -210,23 +208,16 @@ public class WelcomeScene extends PixelScene {
ShatteredPixelDungeon.reportException(e);
}
//fixes a bug from v0.9.0- where champion badges would rarely not save
if (highestChalInRankings > 0){
Badges.loadGlobal();
if (highestChalInRankings >= 1) Badges.addGlobal(Badges.Badge.CHAMPION_1);
if (highestChalInRankings >= 3) Badges.addGlobal(Badges.Badge.CHAMPION_2);
if (highestChalInRankings >= 6) Badges.addGlobal(Badges.Badge.CHAMPION_3);
Badges.saveGlobal();
}
}
//resetting language preference back to native for finnish speakers if they were on english
//This is because Finnish was unmaintained for quite a while
if ( previousVersion <= 500
&& Languages.matchLocale(Locale.getDefault()) == Languages.FINNISH
&& Messages.lang() == Languages.ENGLISH) {
SPDSettings.language(Languages.FINNISH);
Messages.setup(Languages.FINNISH);
//if the player has beaten Goo, automatically give all guidebook pages
if (previousVersion <= ShatteredPixelDungeon.v0_9_3c){
Badges.loadGlobal();
if (Badges.isUnlocked(Badges.Badge.BOSS_SLAIN_1)){
for (String page : Document.ADVENTURERS_GUIDE.pageNames()){
Document.ADVENTURERS_GUIDE.readPage(page);
}
}
}
SPDSettings.version(ShatteredPixelDungeon.versionCode);

View File

@ -43,6 +43,7 @@ public enum Icons {
DATA,
AUDIO,
TALENT,
MAGNIFY,
//ingame UI icons
SKULL,
@ -138,6 +139,9 @@ public enum Icons {
case TALENT:
icon.frame( icon.texture.uvRect( 80, 16, 93, 29 ) );
break;
case MAGNIFY:
icon.frame( icon.texture.uvRect( 96, 16, 110, 30 ) );
break;
case SKULL:
icon.frame( icon.texture.uvRect( 0, 32, 8, 40 ) );
break;

View File

@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
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.scrolls.ScrollOfIdentify;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
@ -283,7 +284,7 @@ public class WndJournal extends WndTabbed {
GameScene.show( new WndStory( iconForPage(page),
Document.ADVENTURERS_GUIDE.pageTitle(page),
Document.ADVENTURERS_GUIDE.pageBody(page) ));
Document.ALCHEMY_GUIDE.readPage(page);
Document.ADVENTURERS_GUIDE.readPage(page);
return true;
} else {
return false;
@ -298,26 +299,32 @@ public class WndJournal extends WndTabbed {
return new ItemSprite( ItemSpriteSheet.GUIDE_PAGE );
}
switch (page){
case Document.GUIDE_INTRO_PAGE: default:
case Document.GUIDE_INTRO: default:
return new ItemSprite(ItemSpriteSheet.MASTERY);
case "Identifying":
return new ItemSprite( ItemSpriteSheet.SCROLL_ISAZ );
case Document.GUIDE_SEARCH_PAGE:
return new ItemSprite( ItemSpriteSheet.LOCKED_CHEST );
case "Strength":
return new ItemSprite( ItemSpriteSheet.ARMOR_SCALE );
case "Food":
return new ItemSprite( ItemSpriteSheet.PASTY );
case "Levelling":
return new ItemSprite( ItemSpriteSheet.POTION_MAGENTA );
case "Examining":
return Icons.get(Icons.MAGNIFY);
case "Surprise_Attacks":
return new ItemSprite( ItemSpriteSheet.ASSASSINS_BLADE );
case "Identifying":
return new ItemSprite( new ScrollOfIdentify() );
case "Food":
return new ItemSprite( ItemSpriteSheet.PASTY );
case "Dieing":
return new ItemSprite( ItemSpriteSheet.ANKH );
return new ItemSprite( ItemSpriteSheet.TOMB );
case Document.GUIDE_SEARCHING:
return Icons.get(Icons.MAGNIFY);
case "Strength":
return new ItemSprite( ItemSpriteSheet.GREATAXE );
case "Upgrades":
return new ItemSprite( ItemSpriteSheet.RING_EMERALD );
case "Looting":
return new ItemSprite( ItemSpriteSheet.CRYSTAL_KEY );
case "Levelling":
return Icons.get(Icons.TALENT);
case "Positioning":
return new ItemSprite( ItemSpriteSheet.SPIRIT_BOW );
case "Magic":
return new ItemSprite( ItemSpriteSheet.WAND_LIGHTNING );
return new ItemSprite( ItemSpriteSheet.WAND_FIREBOLT );
}
}