v3.1.0: improved custom notes, work better with wands, rings, trinkets

This commit is contained in:
Evan Debenham
2025-04-20 17:02:33 -04:00
parent 07e3e1f724
commit 374df40408
7 changed files with 77 additions and 60 deletions

View File

@@ -2315,6 +2315,7 @@ items.item.ac_drop=DROP
items.item.ac_throw=THROW
items.item.rankings_desc=Killed by: %s
items.item.curse=curse
items.item.custom_note_type=This type of item has a custom note: "_%s_"
items.item.custom_note=This item has a custom note: "_%s_"
items.item.discover_hint=You can find this item randomly in the dungeon.

View File

@@ -41,8 +41,6 @@ public abstract class EquipableItem extends Item {
public static final String AC_EQUIP = "EQUIP";
public static final String AC_UNEQUIP = "UNEQUIP";
public int customNoteID = -1;
{
bones = true;
}
@@ -160,17 +158,4 @@ public abstract class EquipableItem extends Item {
public void activate( Char ch ){}
private static final String CUSTOM_NOTE_ID = "custom_note_id";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
if (customNoteID != -1) bundle.put(CUSTOM_NOTE_ID, customNoteID);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
if (bundle.contains(CUSTOM_NOTE_ID)) customNoteID = bundle.getInt(CUSTOM_NOTE_ID);
}
}

View File

@@ -96,6 +96,8 @@ public class Item implements Bundlable {
// whether an item can be included in heroes remains
public boolean bones = false;
public int customNoteID = -1;
public static final Comparator<Item> itemComparator = new Comparator<Item>() {
@Override
@@ -512,15 +514,16 @@ public class Item implements Bundlable {
public String info() {
if (Dungeon.hero != null) {
Notes.CustomRecord note;
if (this instanceof EquipableItem) {
note = Notes.findCustomRecord(((EquipableItem) this).customNoteID);
} else {
note = Notes.findCustomRecord(getClass());
}
if (note != null){
Notes.CustomRecord note = Notes.findCustomRecord(customNoteID);
if (note != null) {
//we swap underscore(0x5F) with low macron(0x2CD) here to avoid highlighting in the item window
return Messages.get(this, "custom_note", note.title().replace('_', 'ˍ')) + "\n\n" + desc();
} else {
note = Notes.findCustomRecord(getClass());
if (note != null) {
//we swap underscore(0x5F) with low macron(0x2CD) here to avoid highlighting in the item window
return Messages.get(this, "custom_note_type", note.title().replace('_', 'ˍ')) + "\n\n" + desc();
}
}
}
@@ -578,6 +581,7 @@ public class Item implements Bundlable {
private static final String CURSED_KNOWN = "cursedKnown";
private static final String QUICKSLOT = "quickslotpos";
private static final String KEPT_LOST = "kept_lost";
private static final String CUSTOM_NOTE_ID = "custom_note_id";
@Override
public void storeInBundle( Bundle bundle ) {
@@ -590,6 +594,7 @@ public class Item implements Bundlable {
bundle.put( QUICKSLOT, Dungeon.quickslot.getSlot(this) );
}
bundle.put( KEPT_LOST, keptThoughLostInvent );
if (customNoteID != -1) bundle.put(CUSTOM_NOTE_ID, customNoteID);
}
@Override
@@ -615,6 +620,7 @@ public class Item implements Bundlable {
}
keptThoughLostInvent = bundle.getBoolean( KEPT_LOST );
if (bundle.contains(CUSTOM_NOTE_ID)) customNoteID = bundle.getInt(CUSTOM_NOTE_ID);
}
public int targetingPos( Hero user, int dst ){

View File

@@ -37,7 +37,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.ItemStatusHandler;
import com.shatteredpixel.shatteredpixeldungeon.items.KindofMisc;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.ShardOfOblivion;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
@@ -187,15 +186,6 @@ public class Ring extends KindofMisc {
if (anonymous && (handler == null || !handler.isKnown( this ))){
desc = desc();
//otherwise, check for item type note, rings can have either but not both
} else if (Notes.findCustomRecord(customNoteID) == null) {
Notes.CustomRecord note = Notes.findCustomRecord(getClass());
if (note != null){
//we swap underscore(0x5F) with low macron(0x2CD) here to avoid highlighting in the item window
desc = Messages.get(this, "custom_note", note.title().replace('_', 'ˍ')) + "\n\n" + super.info();
} else {
desc = super.info();
}
} else {
desc = super.info();
}

View File

@@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.ImpShopkeeper;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.RatKing;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker;
import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.LostBackpack;
@@ -374,7 +375,8 @@ public class Notes {
public enum CustomType {
TEXT,
DEPTH,
ITEM,
ITEM_TYPE,
SPECIFIC_ITEM,
}
public static class CustomRecord extends Record {
@@ -402,8 +404,15 @@ public class Notes {
body = desc;
}
public CustomRecord(Class itemCls, String title, String desc) {
type = CustomType.ITEM_TYPE;
itemClass = itemCls;
this.title = title;
body = desc;
}
public CustomRecord(Item item, String title, String desc) {
type = CustomType.ITEM;
type = CustomType.SPECIFIC_ITEM;
itemClass = item.getClass();
this.title = title;
body = desc;
@@ -435,7 +444,8 @@ public class Notes {
return Icons.SCROLL_COLOR.get();
case DEPTH:
return Icons.STAIRS.get();
case ITEM:
case ITEM_TYPE:
case SPECIFIC_ITEM:
Item i = (Item) Reflection.newInstance(itemClass);
return new ItemSprite(i);
}
@@ -450,7 +460,8 @@ public class Notes {
BitmapText text = new BitmapText(Integer.toString(depth()), PixelScene.pixelFont);
text.measure();
return text;
case ITEM:
case ITEM_TYPE:
case SPECIFIC_ITEM:
Item item = (Item) Reflection.newInstance(itemClass);
if (item.isIdentified() && item.icon != -1) {
Image secondIcon = new Image(Assets.Sprites.ITEM_ICONS);
@@ -507,10 +518,26 @@ public class Notes {
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
type = bundle.getEnum(TYPE, CustomType.class);
try {
type = bundle.getEnum(TYPE, CustomType.class);
} catch (Exception e){
//prior to v3.1 specific item notes and item type notes were the same
type = null;
}
ID = bundle.getInt(ID_NUMBER);
if (bundle.contains(ITEM_CLASS)) itemClass = bundle.getClass(ITEM_CLASS);
if (bundle.contains(ITEM_CLASS)) {
itemClass = bundle.getClass(ITEM_CLASS);
if (type == null){
//prior to v3.1 specific item notes and item type notes were the same
//we assume notes are for a specific item if they're for an equipment
if (EquipableItem.class.isAssignableFrom(itemClass)){
type = CustomType.SPECIFIC_ITEM;
} else {
type = CustomType.ITEM_TYPE;
}
}
}
title = bundle.getString(TITLE);
body = bundle.getString(BODY);
@@ -648,7 +675,9 @@ public class Notes {
public static CustomRecord findCustomRecord( Class itemClass ){
for (Record rec : records){
if (rec instanceof CustomRecord && ((CustomRecord) rec).itemClass == itemClass) {
if (rec instanceof CustomRecord
&& ((CustomRecord) rec).type == CustomType.ITEM_TYPE
&& ((CustomRecord) rec).itemClass == itemClass) {
return (CustomRecord) rec;
}
}

View File

@@ -28,6 +28,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.Trinket;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@@ -171,8 +173,8 @@ public class CustomNoteButton extends IconButton {
if (item instanceof Ring && Notes.findCustomRecord(item.getClass()) != null){
return false;
}
return ((EquipableItem) item).customNoteID == -1
|| Notes.findCustomRecord(((EquipableItem) item).customNoteID) == null;
return item.customNoteID == -1
|| Notes.findCustomRecord(item.customNoteID) == null;
} else {
return Notes.findCustomRecord(item.getClass()) == null;
}
@@ -181,10 +183,14 @@ public class CustomNoteButton extends IconButton {
@Override
public void onSelect( Item item ) {
if (item != null){
Notes.CustomRecord custom = new Notes.CustomRecord(item, "", "");
custom.assignID();
if (item instanceof EquipableItem){
((EquipableItem) item).customNoteID = custom.ID();
Notes.CustomRecord custom;
if (item instanceof EquipableItem || item instanceof Wand || item instanceof Trinket) {
custom = new Notes.CustomRecord(item, "", "");
custom.assignID();
item.customNoteID = custom.ID();
} else {
custom = new Notes.CustomRecord(item.getClass(), "", "");
custom.assignID();
}
addNote(null, custom,
@@ -219,7 +225,7 @@ public class CustomNoteButton extends IconButton {
ItemButton itemButton = new ItemButton(){
@Override
protected void onClick() {
addNote(WndItemtypeSelect.this, new Notes.CustomRecord(item, "", ""),
addNote(WndItemtypeSelect.this, new Notes.CustomRecord(item.getClass(), "", ""),
Messages.get(CustomNoteButton.class, "new_type"),
Messages.get(CustomNoteButton.class, "new_item_title", Messages.titleCase(item.name())));
}

View File

@@ -21,16 +21,13 @@
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.Trinket;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.SupporterScene;
import com.shatteredpixel.shatteredpixeldungeon.services.payment.Payment;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTextInput;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTitledMessage;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndUseItem;
@@ -55,24 +52,27 @@ public class ItemJournalButton extends IconButton {
private void customNote(){
Notes.CustomRecord note = null;
if (item instanceof EquipableItem){
note = Notes.findCustomRecord(((EquipableItem) item).customNoteID);
}
if (note == null) {
if (item instanceof EquipableItem || item instanceof Wand || item instanceof Trinket){
note = Notes.findCustomRecord(item.customNoteID);
} else {
note = Notes.findCustomRecord(item.getClass());
}
//TODO custom note functionality for rings doesn't really work atm, need to let them have equip-specific notes
if (note == null){
if (Notes.getRecords(Notes.CustomRecord.class).size() >= Notes.customRecordLimit()){
GameScene.show(new WndTitledMessage(Icons.INFO.get(),
Messages.get(CustomNoteButton.class, "limit_title"),
Messages.get(CustomNoteButton.class, "limit_text")));
} else {
note = new Notes.CustomRecord(item, "", "");
note.assignID();
if (item instanceof EquipableItem){
((EquipableItem) item).customNoteID = note.ID();
if (item instanceof EquipableItem || item instanceof Wand || item instanceof Trinket) {
note = new Notes.CustomRecord(item, "", "");
note.assignID();
item.customNoteID = note.ID();
} else {
note = new Notes.CustomRecord(item.getClass(), "", "");
note.assignID();
}
addNote(parentWnd, note, Messages.get(CustomNoteButton.class, "new_inv"),
Messages.get(CustomNoteButton.class, "new_item_title", Messages.titleCase(item.name())));
}