diff --git a/core/src/main/assets/messages/journal/journal.properties b/core/src/main/assets/messages/journal/journal.properties
index 1d71405da..eb4732e6e 100644
--- a/core/src/main/assets/messages/journal/journal.properties
+++ b/core/src/main/assets/messages/journal/journal.properties
@@ -1,3 +1,11 @@
+journal.bestiary.regional.title=regional enemies
+journal.bestiary.bosses.title=regional bosses
+journal.bestiary.universal.title=universal enemies
+journal.bestiary.rare.title=rare enemies
+journal.bestiary.quest.title=quest enemies & bosses
+journal.bestiary.neutral.title=neutral characters
+journal.bestiary.ally.title=allies
+
journal.catalog.melee_weapons.title=melee weapons
journal.catalog.armor.title=armor
journal.catalog.enchantments.title=enchantments and curses
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/AllyBuff.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/AllyBuff.java
index 72f01fe71..dd8bc0b1e 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/AllyBuff.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/AllyBuff.java
@@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
+import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
//generic class for buffs which convert an enemy into an ally
@@ -60,6 +61,7 @@ public abstract class AllyBuff extends Buff{
Statistics.enemiesSlain++;
Badges.validateMonstersSlain();
Statistics.qualifiedForNoKilling = false;
+ Bestiary.trackKill(enemy.getClass());
AscensionChallenge.processEnemyKill(enemy);
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java
index 544674d35..dbc4b57b9 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java
@@ -72,6 +72,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Lucky;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts.Dart;
+import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -781,6 +782,7 @@ public abstract class Mob extends Char {
Statistics.enemiesSlain++;
Badges.validateMonstersSlain();
Statistics.qualifiedForNoKilling = false;
+ Bestiary.trackKill(getClass());
AscensionChallenge.processEnemyKill(this);
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NPC.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NPC.java
index 52bfb02b2..4f00b63c8 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NPC.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NPC.java
@@ -21,7 +21,9 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
+import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
public abstract class NPC extends Mob {
@@ -33,6 +35,15 @@ public abstract class NPC extends Mob {
state = PASSIVE;
}
+ @Override
+ protected boolean act() {
+ if (Dungeon.level.heroFOV[pos]){
+ Bestiary.setSeen(getClass());
+ }
+
+ return super.act();
+ }
+
@Override
public void beckon( int cell ) {
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Sheep.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Sheep.java
index 99823559d..7e1339f12 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Sheep.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Sheep.java
@@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
+import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.SheepSprite;
@@ -46,6 +47,9 @@ public class Sheep extends NPC {
@Override
protected boolean act() {
+ if (Dungeon.level.heroFOV[pos]){
+ Bestiary.setSeen(getClass());
+ }
if (initialized) {
HP = 0;
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Bestiary.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Bestiary.java
new file mode 100644
index 000000000..a6ad3d988
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Bestiary.java
@@ -0,0 +1,295 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2024 Evan Debenham
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.journal;
+
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk;
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.ShadowClone;
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.SmokeBomb;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Acidic;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Albino;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredBrute;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredStatue;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bandit;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bat;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bee;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Brute;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CausticSlime;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Crab;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalGuardian;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalMimic;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalSpire;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalWisp;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM200;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM201;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DemonSpawner;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DwarfKing;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.EbonyMimic;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.FetidRat;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Ghoul;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Gnoll;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollGeomancer;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollGuard;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollSapper;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GnollTrickster;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GoldenMimic;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Golem;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Goo;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GreatCrab;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Guard;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Monk;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Necromancer;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.PhantomPiranha;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Piranha;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Pylon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Rat;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.RipperDemon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.RotHeart;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.RotLasher;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Scorpio;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Senior;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Skeleton;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Slime;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Snake;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.SpectralNecromancer;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Spinner;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Statue;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Succubus;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Swarm;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Tengu;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Thief;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.TormentedSpirit;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Warlock;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.YogDzewa;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.YogFist;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.MirrorImage;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.PrismaticImage;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.RatKing;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
+import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker;
+import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
+import com.shatteredpixel.shatteredpixeldungeon.items.quest.CorpseDust;
+import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLivingEarth;
+import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
+import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SentryRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GuardianTrap;
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.watabou.utils.Bundle;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+public enum Bestiary {
+
+
+ REGIONAL,
+ BOSSES,
+ UNIVERSAL,
+ RARE,
+ QUEST,
+ NEUTRAL,
+ ALLY; //the journal tracks kills with allies, or quest completions, or shop purchases (eventually?)
+
+ //while this is all internally reported as kills, it's effectively 1 = seen for allies/NPCs
+ private LinkedHashMap, Integer> killCount = new LinkedHashMap<>();
+
+ //should only be used when initializing
+ private void addMobs( Class>... mobs ){
+ for (Class> mob : mobs){
+ killCount.put(mob, 0);
+ }
+ }
+
+ public Collection> mobs(){
+ return killCount.keySet();
+ }
+
+ public String title(){
+ return Messages.get(this, name() + ".title");
+ }
+
+ public int totalMobs(){
+ return killCount.size();
+ }
+
+ public int totalSeen(){
+ int seenTotal = 0;
+ for (int count : killCount.values()){
+ if (count > 0) seenTotal++;
+ }
+ return seenTotal;
+ }
+
+ static {
+
+ REGIONAL.addMobs(Rat.class, Snake.class, Gnoll.class, Swarm.class, Crab.class, Slime.class,
+ Skeleton.class, Thief.class, DM100.class, Guard.class, Necromancer.class,
+ Bat.class, Brute.class, Shaman.RedShaman.class, Shaman.BlueShaman.class, Shaman.PurpleShaman.class, Spinner.class, DM200.class,
+ Ghoul.class, Elemental.FireElemental.class, Elemental.FrostElemental.class, Elemental.ShockElemental.class, Warlock.class, Monk.class, Golem.class,
+ RipperDemon.class, DemonSpawner.class, Succubus.class, Eye.class, Scorpio.class);
+
+ BOSSES.addMobs(Goo.class,
+ Tengu.class,
+ Pylon.class, DM300.class,
+ DwarfKing.class,
+ YogDzewa.Larva.class, YogFist.BurningFist.class, YogFist.SoiledFist.class, YogFist.RottingFist.class, YogFist.RustedFist.class,YogFist.BrightFist.class, YogFist.DarkFist.class, YogDzewa.class);
+
+ UNIVERSAL.addMobs(Wraith.class, Piranha.class, Mimic.class, GoldenMimic.class, Statue.class, GuardianTrap.Guardian.class, SentryRoom.Sentry.class);
+
+ RARE.addMobs(Albino.class, CausticSlime.class,
+ Bandit.class, SpectralNecromancer.class,
+ ArmoredBrute.class, DM201.class,
+ Elemental.ChaosElemental.class, Senior.class,
+ Acidic.class,
+ TormentedSpirit.class, PhantomPiranha.class, CrystalMimic.class, EbonyMimic.class, ArmoredStatue.class);
+
+ QUEST.addMobs(FetidRat.class, GnollTrickster.class, GreatCrab.class,
+ Elemental.NewbornFireElemental.class, RotLasher.class, RotHeart.class,
+ CrystalWisp.class, CrystalGuardian.class, CrystalSpire.class, GnollGuard.class, GnollSapper.class, GnollGeomancer.class);
+
+ NEUTRAL.addMobs(Ghost.class, Shopkeeper.class, Wandmaker.class, Blacksmith.class, Imp.class, Sheep.class, RatKing.class, Bee.class);
+
+ ALLY.addMobs(MirrorImage.class, PrismaticImage.class,
+ DriedRose.GhostHero.class,
+ WandOfWarding.Ward.class, WandOfLivingEarth.EarthGuardian.class, WandOfRegrowth.Lotus.class,
+ ShadowClone.ShadowAlly.class, SmokeBomb.NinjaLog.class, SpiritHawk.HawkAlly.class);
+
+ }
+
+ public static int killCount(Class> mobClass) {
+ for (Bestiary cat : values()) {
+ if (cat.killCount.containsKey(mobClass)) {
+ return cat.killCount.get(mobClass);
+ }
+ }
+ return 0;
+ }
+
+ public static boolean isSeen(Class> mobClass){
+ return killCount(mobClass) > 0;
+ }
+
+ //some mobs have different internal classes when they are minions, so need to convert here
+ private static final HashMap, Class>> minionConversions = new HashMap<>();
+ static {
+ minionConversions.put(CorpseDust.DustWraith.class, Wraith.class);
+
+ minionConversions.put(Necromancer.NecroSkeleton.class, Skeleton.class);
+
+ minionConversions.put(DwarfKing.DKGhoul.class, Ghoul.class);
+ minionConversions.put(DwarfKing.DKWarlock.class, Warlock.class);
+ minionConversions.put(DwarfKing.DKMonk.class, Monk.class);
+ minionConversions.put(DwarfKing.DKGolem.class, Golem.class);
+
+ minionConversions.put(YogDzewa.YogRipper.class, RipperDemon.class);
+ minionConversions.put(YogDzewa.YogEye.class, Eye.class);
+ minionConversions.put(YogDzewa.YogScorpio.class, Scorpio.class);
+ }
+
+ public static boolean setSeen(Class> mobClass){
+ if (minionConversions.containsKey(mobClass)){
+ mobClass = minionConversions.get(mobClass);
+ }
+ for (Bestiary cat : values()) {
+ if (cat.killCount.containsKey(mobClass)) {
+ if (cat.killCount.get(mobClass) == 0){
+ cat.killCount.put(mobClass, 1);
+ Journal.saveNeeded = true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static void trackKill(Class> mobClass){
+ if (minionConversions.containsKey(mobClass)){
+ mobClass = minionConversions.get(mobClass);
+ }
+ for (Bestiary cat : values()) {
+ if (cat.killCount.containsKey(mobClass)) {
+ if (cat.killCount.get(mobClass) != Integer.MAX_VALUE){
+ cat.killCount.put(mobClass, cat.killCount.get(mobClass)+1);
+ Journal.saveNeeded = true;
+ }
+ }
+ }
+ }
+
+ private static final String BESTIARY_CLASSES = "bestiary_classes";
+ private static final String BESTIARY_KILLS = "bestiary_kills";
+
+ public static void store( Bundle bundle ){
+ Bundle bestiaryBundle = new Bundle();
+
+ ArrayList> classes = new ArrayList<>();
+ ArrayList kills = new ArrayList<>();
+
+ for (Bestiary cat : values()) {
+ for (Class> mob : cat.mobs()) {
+ if (cat.killCount.get(mob) > 0){
+ classes.add(mob);
+ kills.add(cat.killCount.get(mob));
+ }
+ }
+ }
+
+ int[] killsToStore = new int[kills.size()];
+ for (int i = 0; i < killsToStore.length; i++){
+ killsToStore[i] = kills.get(i);
+ }
+
+ bundle.put( BESTIARY_CLASSES, classes.toArray(new Class[0]) );
+ bundle.put( BESTIARY_KILLS, killsToStore );
+
+ }
+
+ public static void restore( Bundle bundle ){
+
+ if (bundle.contains(BESTIARY_CLASSES)){
+ Class>[] classes = bundle.getClassArray(BESTIARY_CLASSES);
+ int[] kills = bundle.getIntArray(BESTIARY_KILLS);
+
+ for (int i = 0; i < classes.length; i++){
+ for (Bestiary cat : values()){
+ if (cat.killCount.containsKey(classes[i])){
+ cat.killCount.put(classes[i], kills[i]);
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Catalog.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Catalog.java
index eafbcd23d..adef72281 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Catalog.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Catalog.java
@@ -121,6 +121,7 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
+//For items, but includes a few item-like effects, such as enchantments
public enum Catalog {
//EQUIPMENT
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Journal.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Journal.java
index 007617f92..4ecfe75ad 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Journal.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/journal/Journal.java
@@ -47,6 +47,7 @@ public class Journal {
}
Catalog.restore( bundle );
+ Bestiary.restore( bundle );
Document.restore( bundle );
loaded = true;
@@ -67,6 +68,7 @@ public class Journal {
Bundle bundle = new Bundle();
Catalog.store(bundle);
+ Bestiary.store(bundle);
Document.store(bundle);
try {
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java
index 6eb63201c..512ce78f8 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java
@@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHaste;
+import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
@@ -228,6 +229,10 @@ public class SentryRoom extends SpecialRoom {
@Override
protected boolean act() {
+ if (Dungeon.level.heroFOV[pos]){
+ Bestiary.setSeen(getClass());
+ }
+
if (fieldOfView == null || fieldOfView.length != Dungeon.level.length()){
fieldOfView = new boolean[Dungeon.level.length()];
}