From 4d2c1ec1d05dea0dc1fe2265949f09f79d783524 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sun, 13 Aug 2023 11:21:17 -0400 Subject: [PATCH 01/23] adding pagination to shop to allow for more items --- mod/src/main/java/basemod/BaseMod.java | 20 + .../basemod/abstracts/CustomShopItem.java | 151 ++++++++ .../PostShopInitializeSubscriber.java | 5 + .../shop/ShopScreen/ShopItemGrid.java | 364 ++++++++++++++++++ 4 files changed, 540 insertions(+) create mode 100644 mod/src/main/java/basemod/abstracts/CustomShopItem.java create mode 100644 mod/src/main/java/basemod/interfaces/PostShopInitializeSubscriber.java create mode 100644 mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java diff --git a/mod/src/main/java/basemod/BaseMod.java b/mod/src/main/java/basemod/BaseMod.java index b58da8e6e..882dedc31 100644 --- a/mod/src/main/java/basemod/BaseMod.java +++ b/mod/src/main/java/basemod/BaseMod.java @@ -11,6 +11,7 @@ import basemod.patches.com.megacrit.cardcrawl.cards.AbstractCard.RenderDescriptionEnergy; import basemod.patches.com.megacrit.cardcrawl.helpers.TopPanel.TopPanelHelper; import basemod.patches.com.megacrit.cardcrawl.screens.select.GridCardSelectScreen.GridCardSelectScreenFields; +import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopItemGrid; import basemod.patches.com.megacrit.cardcrawl.unlock.UnlockTracker.CountModdedUnlockCards; import basemod.patches.imgui.ImGuiPatches; import basemod.patches.whatmod.WhatMod; @@ -120,6 +121,7 @@ public class BaseMod { private static ArrayList postDungeonInitializeSubscribers; private static ArrayList postEnergyRechargeSubscribers; private static ArrayList postInitializeSubscribers; + private static ArrayList postShopInitializeSubscribers; private static ArrayList preMonsterTurnSubscribers; private static ArrayList renderSubscribers; private static ArrayList preRenderSubscribers; @@ -461,6 +463,7 @@ private static void initializeSubscriptions() { postDungeonInitializeSubscribers = new ArrayList<>(); postEnergyRechargeSubscribers = new ArrayList<>(); postInitializeSubscribers = new ArrayList<>(); + postShopInitializeSubscribers = new ArrayList<>(); preMonsterTurnSubscribers = new ArrayList<>(); renderSubscribers = new ArrayList<>(); preRenderSubscribers = new ArrayList<>(); @@ -2302,6 +2305,17 @@ public static void publishPostInitialize() { unsubscribeLaterHelper(PostInitializeSubscriber.class); } + // publishPostShopInitialize - + public static void publishPostShopInitialize() { + logger.info("publishPostShopInitialize"); + + for (PostShopInitializeSubscriber sub : postShopInitializeSubscribers) { + sub.receivePostShopInitialize(); + } + + unsubscribeLaterHelper(PostShopInitializeSubscriber.class); + } + // publishPreMonsterTurn - false skips monster turn public static boolean publishPreMonsterTurn(AbstractMonster m) { logger.info("publishPreMonsterTurn"); @@ -2862,6 +2876,7 @@ public static void subscribe(ISubscriber sub) { subscribeIfInstance(postDungeonInitializeSubscribers, sub, PostDungeonInitializeSubscriber.class); subscribeIfInstance(postEnergyRechargeSubscribers, sub, PostEnergyRechargeSubscriber.class); subscribeIfInstance(postInitializeSubscribers, sub, PostInitializeSubscriber.class); + subscribeIfInstance(postShopInitializeSubscribers, sub, PostShopInitializeSubscriber.class); subscribeIfInstance(preMonsterTurnSubscribers, sub, PreMonsterTurnSubscriber.class); subscribeIfInstance(renderSubscribers, sub, RenderSubscriber.class); subscribeIfInstance(preRenderSubscribers, sub, PreRenderSubscriber.class); @@ -2925,6 +2940,8 @@ public static void subscribe(ISubscriber sub, Class addit postEnergyRechargeSubscribers.add((PostEnergyRechargeSubscriber) sub); } else if (additionClass.equals(PostInitializeSubscriber.class)) { postInitializeSubscribers.add((PostInitializeSubscriber) sub); + } else if (additionClass.equals(PostShopInitializeSubscriber.class)) { + postShopInitializeSubscribers.add((PostShopInitializeSubscriber) sub); } else if (additionClass.equals(PreMonsterTurnSubscriber.class)) { preMonsterTurnSubscribers.add((PreMonsterTurnSubscriber) sub); } else if (additionClass.equals(RenderSubscriber.class)) { @@ -3021,6 +3038,7 @@ public static void unsubscribe(ISubscriber sub) { unsubscribeIfInstance(postDungeonInitializeSubscribers, sub, PostDungeonInitializeSubscriber.class); unsubscribeIfInstance(postEnergyRechargeSubscribers, sub, PostEnergyRechargeSubscriber.class); unsubscribeIfInstance(postInitializeSubscribers, sub, PostInitializeSubscriber.class); + unsubscribeIfInstance(postShopInitializeSubscribers, sub, PostShopInitializeSubscriber.class); unsubscribeIfInstance(preMonsterTurnSubscribers, sub, PreMonsterTurnSubscriber.class); unsubscribeIfInstance(renderSubscribers, sub, RenderSubscriber.class); unsubscribeIfInstance(preRenderSubscribers, sub, PreRenderSubscriber.class); @@ -3083,6 +3101,8 @@ public static void unsubscribe(ISubscriber sub, Class rem postEnergyRechargeSubscribers.remove(sub); } else if (removalClass.equals(PostInitializeSubscriber.class)) { postInitializeSubscribers.remove(sub); + } else if (removalClass.equals(PostInitializeSubscriber.class)) { + postShopInitializeSubscribers.remove(sub); } else if (removalClass.equals(PreMonsterTurnSubscriber.class)) { preMonsterTurnSubscribers.remove(sub); } else if (removalClass.equals(RenderSubscriber.class)) { diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java new file mode 100644 index 000000000..835a552ec --- /dev/null +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -0,0 +1,151 @@ +package basemod.abstracts; + +import basemod.ReflectionHacks; +import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopItemGrid; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.megacrit.cardcrawl.core.Settings; +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; +import com.megacrit.cardcrawl.helpers.FontHelper; +import com.megacrit.cardcrawl.helpers.Hitbox; +import com.megacrit.cardcrawl.helpers.ImageMaster; +import com.megacrit.cardcrawl.helpers.TipHelper; +import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; +import com.megacrit.cardcrawl.helpers.input.InputHelper; +import com.megacrit.cardcrawl.shop.ShopScreen; +import com.megacrit.cardcrawl.shop.StorePotion; +import com.megacrit.cardcrawl.shop.StoreRelic; + +public class CustomShopItem { + + private ShopScreen screenRef; + private StoreRelic storeRelic; + private StorePotion storePotion; + + private String tipTitle = null; + private String tipBody = null; + + private Texture img; + private Hitbox hb; + private float x, y; + + public int price = 0; + public int slot = 0; + public int row; + + public boolean isPurchased = false; + + private static final float GOLD_IMG_WIDTH = ReflectionHacks.getPrivateStatic(StoreRelic.class, "GOLD_IMG_WIDTH"); + private static final float GOLD_OFFSET_X = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_GOLD_OFFSET_X"); + private static final float GOLD_OFFSET_Y = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_GOLD_OFFSET_Y"); + private static final float PRICE_OFFSET_X = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_X"); + private static final float PRICE_OFFSET_Y = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_Y"); + + public CustomShopItem(StoreRelic storeRelic) { + this.storeRelic = storeRelic; + this.slot = ReflectionHacks.getPrivate(storeRelic, StoreRelic.class, "slot"); + } + + public CustomShopItem(StorePotion storePotion) { + this.storePotion = storePotion; + this.slot = ReflectionHacks.getPrivate(storePotion, StorePotion.class, "slot"); + } + + public CustomShopItem(ShopScreen screenRef, Texture img, int price) { + this.screenRef = screenRef; + this.img = img; + this.price = price; + this.hb = new Hitbox(img.getWidth() * Settings.scale, img.getHeight() * Settings.scale); + } + + public CustomShopItem(ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { + this(screenRef, img, price); + this.tipTitle = tipTitle; + this.tipBody = tipBody; + } + + public void update(float rugY) { + if (storeRelic != null && storeRelic.relic != null) { + storeRelic.update(rugY); + return; + } else if (storePotion != null && storePotion.potion != null) { + storePotion.update(rugY); + return; + } else if (!this.isPurchased) { + this.x = 1000.0F * Settings.xScale + 150.0F * this.slot * Settings.xScale; + this.y = rugY + (this.row == 0 ? 400.0F : 200.0F) * Settings.yScale; + + this.hb.move(this.x, this.y); + this.hb.update(); + if (this.hb.hovered) { + this.screenRef.moveHand(this.x - 190.0F * Settings.scale, this.y - 70.0F * Settings.scale); + if (InputHelper.justClickedLeft) + this.hb.clickStarted = true; + } + if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { + if (AbstractDungeon.player.gold >= this.price) { + makePurchase(); + this.isPurchased = true; + this.hb.clicked = false; + } else { + this.screenRef.playCantBuySfx(); + this.screenRef.createSpeech(ShopScreen.getCantBuyMsg()); + } + } + } + } + + public void render(SpriteBatch sb) { + if (storeRelic != null && storeRelic.relic != null) + this.storeRelic.render(sb); + else if (storePotion != null && storePotion.potion != null) + this.storePotion.render(sb); + else if (!isPurchased) { + sb.setColor(Color.WHITE); + // assumes the size of a relic image + sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); + sb.draw(ImageMaster.UI_GOLD, x + GOLD_OFFSET_X, y + GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); + Color color = Color.WHITE; + if (this.price > AbstractDungeon.player.gold) + color = Color.SALMON; + FontHelper.renderFontLeftTopAligned(sb, FontHelper.tipHeaderFont, Integer.toString(this.price), x + PRICE_OFFSET_X, y + PRICE_OFFSET_Y, color); + if (this.hb.hovered && tipTitle != null && tipBody != null) + TipHelper.renderGenericTip( + InputHelper.mX + 50.0F * Settings.xScale, + InputHelper.mY + 50.0F * Settings.yScale, + tipTitle, + tipBody + ); + } + } + + public void hide() { + if (storeRelic != null && storeRelic.relic != null) { + this.storeRelic.hide(); + this.y = storeRelic.relic.currentY; + } + else if (storePotion != null && storePotion.potion != null) { + this.storePotion.hide(); + this.y = storePotion.potion.posY; + } + else { + this.y = Settings.HEIGHT + 200.0F * Settings.scale; + } + } + + protected void makePurchase() { + if (storeRelic != null && storeRelic.relic != null) { + this.storeRelic.purchaseRelic(); + } else if (storePotion != null && storePotion.potion != null) { + this.storePotion.purchasePotion(); + } else { + purchase(); + } + this.isPurchased = true; + ShopItemGrid.removeEmptyPages(); + } + + public void purchase() {} +} diff --git a/mod/src/main/java/basemod/interfaces/PostShopInitializeSubscriber.java b/mod/src/main/java/basemod/interfaces/PostShopInitializeSubscriber.java new file mode 100644 index 000000000..1004d39ff --- /dev/null +++ b/mod/src/main/java/basemod/interfaces/PostShopInitializeSubscriber.java @@ -0,0 +1,5 @@ +package basemod.interfaces; + +public interface PostShopInitializeSubscriber extends ISubscriber { + void receivePostShopInitialize(); +} diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java new file mode 100644 index 000000000..6c98a454d --- /dev/null +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java @@ -0,0 +1,364 @@ +package basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen; + +import basemod.BaseMod; +import basemod.ReflectionHacks; +import basemod.abstracts.CustomShopItem; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.evacipated.cardcrawl.modthespire.lib.LineFinder; +import com.evacipated.cardcrawl.modthespire.lib.Matcher; +import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; +import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; +import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; +import com.megacrit.cardcrawl.core.Settings; +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; +import com.megacrit.cardcrawl.helpers.FontHelper; +import com.megacrit.cardcrawl.helpers.Hitbox; +import com.megacrit.cardcrawl.helpers.ImageMaster; +import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; +import com.megacrit.cardcrawl.helpers.input.InputHelper; +import com.megacrit.cardcrawl.shop.ShopScreen; +import com.megacrit.cardcrawl.shop.StorePotion; +import com.megacrit.cardcrawl.shop.StoreRelic; +import java.util.ArrayList; +import java.util.LinkedList; + +import javassist.CannotCompileException; +import javassist.CtBehavior; +import javassist.expr.ExprEditor; +import javassist.expr.MethodCall; + +public class ShopItemGrid { + public static LinkedList pages = new LinkedList<>(); + public static ShopItemPage currentPage; + public static NavButton leftArrow; + public static NavButton rightArrow; + private static float pageIdxY; + + @SpirePatch2( + clz = ShopScreen.class, + method = "init" + ) + public static class InitPage { + @SpirePostfixPatch + public static void Postfix() { + BaseMod.publishPostShopInitialize(); + } + + @SpireInsertPatch( + locator = Locator.class + ) + public static void Insert(ArrayList ___relics, ArrayList ___potions) { + ShopItemPage page = new ShopItemPage(); + page.row1 = ShopItemRow.makeDefaultRelicRow(___relics, 0); + page.row2 = ShopItemRow.makeDefaultPotionRow(___potions, 1); + pages.clear(); + pages.addLast(page); + currentPage = page; + rightArrow = new NavButton(true); + leftArrow = new NavButton(false); + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.FieldAccessMatcher(ShopScreen.class, "purgeAvailable"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + @SpirePatch2( + clz = ShopScreen.class, + method = "open" + ) + public static class HideOnOpen { + @SpireInsertPatch( + locator = Locator.class + ) + public static void Insert() { + currentPage.hide(); + leftArrow.hide(); + rightArrow.hide(); + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.FieldAccessMatcher(ShopScreen.class, "rugY"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + @SpirePatch2( + clz = ShopScreen.class, + method = "update" + ) + public static class UpdateCurrentPage { + @SpireInstrumentPatch + public static ExprEditor Instrument() { + return new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("updateRelics") || m.getMethodName().equals("updatePotions")) + m.replace("{}"); + } + }; + } + + @SpireInsertPatch( + locator = Locator.class + ) + public static void Insert(float ___rugY) { + currentPage.update(___rugY); + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.MethodCallMatcher(ShopScreen.class, "updateRug"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + @SpirePatch2( + clz = ShopScreen.class, + method = "render" + ) + public static class RenderCurrentPage { + @SpireInstrumentPatch + public static ExprEditor Instrument() { + return new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("renderRelics") || m.getMethodName().equals("renderPotions")) + m.replace("{}"); + } + }; + } + + @SpireInsertPatch( + locator = Locator.class + ) + public static void Insert(SpriteBatch sb) { + currentPage.render(sb); + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.MethodCallMatcher(ShopScreen.class, "renderPurge"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + public static void addItem(CustomShopItem item) { + if (currentPage != null && currentPage.tryAddItem(item)) + return; + ShopItemPage newPage = new ShopItemPage(); + newPage.tryAddItem(item); + pages.addLast(newPage); + if (currentPage == null) + currentPage = newPage; + } + + public static void removeEmptyPages() { + ShopItemPage page = currentPage; + if (page.isEmpty()) { + int newIdx = pages.indexOf(page) - 1; + pages.remove(page); + currentPage = (newIdx == -1 ? null : pages.get(newIdx)); + } + } + + public static class ShopItemPage { + public ShopItemRow row1; + public ShopItemRow row2; + + public ShopItemPage() { + this.row1 = new ShopItemRow(0); + this.row2 = new ShopItemRow(1); + } + + public void hide() { + row1.hide(); + row2.hide(); + } + + public void update(float rugY) { + row1.update(rugY); + row2.update(rugY); + leftArrow.update(rugY); + rightArrow.update(rugY); + pageIdxY = rugY + 500.0F * Settings.yScale; + } + + public void render(SpriteBatch sb) { + row1.render(sb); + row2.render(sb); + leftArrow.render(sb); + rightArrow.render(sb); + if (pages.size() > 1) + FontHelper.renderFontCentered( + sb, + FontHelper.buttonLabelFont, + (pages.indexOf(currentPage) + 1) + "/" + pages.size(), + 1150.0F * Settings.xScale, + pageIdxY, + Color.WHITE + ); + } + + public boolean tryAddItem(CustomShopItem item) { + return row1.tryAddItem(item) || row2.tryAddItem(item); + } + + public boolean isEmpty() { + return row1.isEmpty() && row2.isEmpty(); + } + } + + public static class ShopItemRow { + public static final int MAX_ITEMS_PER_ROW = 3; + + public ArrayList items; + public int row; + + private boolean isDefaultRelics = false; + private boolean isDefaultPotions = false; + + public ShopItemRow(int row) { + this.items = new ArrayList<>(); + this.row = row; + } + + public static ShopItemRow makeDefaultRelicRow(ArrayList relics, int row) { + ShopItemRow itemRow = new ShopItemRow(row); + itemRow.items = new ArrayList<>(); + itemRow.row = row; + itemRow.isDefaultRelics = true; + for (StoreRelic relic : relics) { + itemRow.items.add(new CustomShopItem(relic)); + } + return itemRow; + } + + public static ShopItemRow makeDefaultPotionRow(ArrayList potions, int row) { + ShopItemRow itemRow = new ShopItemRow(row); + itemRow.items = new ArrayList<>(); + itemRow.row = row; + itemRow.isDefaultPotions = true; + for (StorePotion potion : potions) { + itemRow.items.add(new CustomShopItem(potion)); + } + return itemRow; + } + + public boolean tryAddItem(CustomShopItem item) { + if (items.size() < MAX_ITEMS_PER_ROW) { + item.row = this.row; + item.slot = items.size(); + items.add(item); + return true; + } + return false; + } + + public void update(float rugY) { + if (isDefaultRelics) { + ReflectionHacks.privateMethod(ShopScreen.class, "updateRelics").invoke(AbstractDungeon.shopScreen); + return; + } + if (isDefaultPotions) { + ReflectionHacks.privateMethod(ShopScreen.class, "updatePotions").invoke(AbstractDungeon.shopScreen); + return; + } + for (CustomShopItem item : items) { + item.update(rugY); + } + } + + public void render(SpriteBatch sb) { + if (isDefaultRelics && AbstractDungeon.shopScreen != null) { + ReflectionHacks.privateMethod(ShopScreen.class, "renderRelics", SpriteBatch.class).invoke(AbstractDungeon.shopScreen, sb); + return; + } + if (isDefaultPotions && AbstractDungeon.shopScreen != null) { + ReflectionHacks.privateMethod(ShopScreen.class, "renderPotions", SpriteBatch.class).invoke(AbstractDungeon.shopScreen, sb); + return; + } + if (AbstractDungeon.shopScreen != null) + for (CustomShopItem item : items) { + item.render(sb); + } + } + + public void hide() { + for (CustomShopItem item : items) { + item.hide(); + } + } + + public boolean isEmpty() { + BaseMod.logger.info("Checking if row is empty: " + items.size()); + BaseMod.logger.info("Checking if row is empty: " + items.stream().filter(item -> !item.isPurchased).count()); + return (items.stream().filter(item -> !item.isPurchased).count() == 0); + } + } + + public static class NavButton { + public static Texture texture = ImageMaster.POPUP_ARROW; + public Hitbox hb; + + private float x, y; + + public boolean forward = true; + + public NavButton(boolean forward) { + this.forward = forward; + this.hb = new Hitbox(64.0F * Settings.scale, 64.0F * Settings.scale); + } + + public void update(float rugY) { + this.x = (forward ? 1225.0F : 1075.0F) * Settings.xScale; + this.y = rugY + 500.0F * Settings.yScale; + this.hb.move(x, y); + this.hb.update(); + if (this.hb.hovered && InputHelper.justClickedLeft) + hb.clickStarted = true; + if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { + int curIdx = pages.indexOf(currentPage); + if (forward && curIdx < pages.size() - 1) + currentPage = pages.get(curIdx + 1); + else if (!forward && curIdx > 0) + currentPage = pages.get(curIdx - 1); + this.hb.clicked = false; + } + } + + public void render(SpriteBatch sb) { + sb.setColor(Color.WHITE); + int curIdx = pages.indexOf(currentPage); + if (!forward && curIdx > 0) { + TextureRegion region = new TextureRegion(texture); + sb.draw(region, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + hb.render(sb); + } + if (forward && curIdx < pages.size() - 1) { + TextureRegion flippedRegion = new TextureRegion(texture); + flippedRegion.flip(true, false); + sb.draw(flippedRegion, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + hb.render(sb); + } + } + + public void hide() { + this.hb.move(this.hb.x, Settings.HEIGHT + 200.0F * Settings.scale); + } + } +} From 646f1608488f653497895627eadc171fb2335987 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sun, 13 Aug 2023 20:20:30 -0400 Subject: [PATCH 02/23] applying relic discounts, only setting isPurchased when it's not a store relic or store potion --- .../java/basemod/abstracts/CustomShopItem.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 835a552ec..3e3733462 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -56,8 +56,8 @@ public CustomShopItem(StorePotion storePotion) { public CustomShopItem(ShopScreen screenRef, Texture img, int price) { this.screenRef = screenRef; this.img = img; - this.price = price; this.hb = new Hitbox(img.getWidth() * Settings.scale, img.getHeight() * Settings.scale); + applyDiscounts(price); } public CustomShopItem(ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { @@ -66,6 +66,12 @@ public CustomShopItem(ShopScreen screenRef, Texture img, int price, String tipTi this.tipBody = tipBody; } + public void applyDiscounts(int price) { + this.price = (int)(price + * (AbstractDungeon.player.hasRelic("The Courier") ? 0.8F : 1.0F) + * (AbstractDungeon.player.hasRelic("Membership Card") ? 0.5F : 1.0F)); + } + public void update(float rugY) { if (storeRelic != null && storeRelic.relic != null) { storeRelic.update(rugY); @@ -87,7 +93,6 @@ public void update(float rugY) { if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { if (AbstractDungeon.player.gold >= this.price) { makePurchase(); - this.isPurchased = true; this.hb.clicked = false; } else { this.screenRef.playCantBuySfx(); @@ -143,9 +148,10 @@ protected void makePurchase() { } else { purchase(); } - this.isPurchased = true; ShopItemGrid.removeEmptyPages(); } - public void purchase() {} + public void purchase() { + this.isPurchased = true; + } } From 79a3bab1b6f45352a7eca01f5154fa85c98fd3f8 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Mon, 14 Aug 2023 07:34:07 -0400 Subject: [PATCH 03/23] setting y position for store relic/potion so they can be in either row, fixing the addItem static method --- .../basemod/abstracts/CustomShopItem.java | 151 ++++++++++-------- .../shop/ShopScreen/ShopItemGrid.java | 142 ++++++++++++---- 2 files changed, 194 insertions(+), 99 deletions(-) diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 3e3733462..7095db91e 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -2,10 +2,10 @@ import basemod.ReflectionHacks; import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopItemGrid; - import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.megacrit.cardcrawl.core.CardCrawlGame; import com.megacrit.cardcrawl.core.Settings; import com.megacrit.cardcrawl.dungeons.AbstractDungeon; import com.megacrit.cardcrawl.helpers.FontHelper; @@ -21,8 +21,8 @@ public class CustomShopItem { private ShopScreen screenRef; - private StoreRelic storeRelic; - private StorePotion storePotion; + public StoreRelic storeRelic; + public StorePotion storePotion; private String tipTitle = null; private String tipBody = null; @@ -54,6 +54,7 @@ public CustomShopItem(StorePotion storePotion) { } public CustomShopItem(ShopScreen screenRef, Texture img, int price) { + this.slot = ShopItemGrid.getNextSlot(); this.screenRef = screenRef; this.img = img; this.hb = new Hitbox(img.getWidth() * Settings.scale, img.getHeight() * Settings.scale); @@ -73,85 +74,107 @@ public void applyDiscounts(int price) { } public void update(float rugY) { - if (storeRelic != null && storeRelic.relic != null) { - storeRelic.update(rugY); - return; - } else if (storePotion != null && storePotion.potion != null) { - storePotion.update(rugY); - return; - } else if (!this.isPurchased) { - this.x = 1000.0F * Settings.xScale + 150.0F * this.slot * Settings.xScale; - this.y = rugY + (this.row == 0 ? 400.0F : 200.0F) * Settings.yScale; - - this.hb.move(this.x, this.y); - this.hb.update(); - if (this.hb.hovered) { - this.screenRef.moveHand(this.x - 190.0F * Settings.scale, this.y - 70.0F * Settings.scale); - if (InputHelper.justClickedLeft) - this.hb.clickStarted = true; - } - if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { - if (AbstractDungeon.player.gold >= this.price) { - makePurchase(); + if (!this.isPurchased) { + if (storeRelic != null && storeRelic.relic != null) { + storeRelic.update(rugY); + this.isPurchased = storeRelic.isPurchased; + if (this.isPurchased) { + this.storeRelic.relic = null; + this.storeRelic = null; + } + } else if (storePotion != null && storePotion.potion != null) { + storePotion.update(rugY); + this.isPurchased = storePotion.isPurchased; + if (this.isPurchased) { + this.storePotion.potion = null; + this.storePotion = null; + } + } else { + this.x = 1000.0F * Settings.xScale + 150.0F * this.slot * Settings.xScale; + this.y = rugY + (this.row == 0 ? 400.0F : 200.0F) * Settings.yScale; + + this.hb.move(this.x, this.y); + this.hb.update(); + if (this.hb.hovered) { + this.screenRef.moveHand(this.x - 190.0F * Settings.scale, this.y - 70.0F * Settings.scale); + if (InputHelper.justClickedLeft) + this.hb.clickStarted = true; + } + if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { + attemptPurchase(); this.hb.clicked = false; - } else { - this.screenRef.playCantBuySfx(); - this.screenRef.createSpeech(ShopScreen.getCantBuyMsg()); } } + ShopItemGrid.removeEmptyPages(); } } public void render(SpriteBatch sb) { - if (storeRelic != null && storeRelic.relic != null) - this.storeRelic.render(sb); - else if (storePotion != null && storePotion.potion != null) - this.storePotion.render(sb); - else if (!isPurchased) { - sb.setColor(Color.WHITE); - // assumes the size of a relic image - sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); - sb.draw(ImageMaster.UI_GOLD, x + GOLD_OFFSET_X, y + GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); - Color color = Color.WHITE; - if (this.price > AbstractDungeon.player.gold) - color = Color.SALMON; - FontHelper.renderFontLeftTopAligned(sb, FontHelper.tipHeaderFont, Integer.toString(this.price), x + PRICE_OFFSET_X, y + PRICE_OFFSET_Y, color); - if (this.hb.hovered && tipTitle != null && tipBody != null) - TipHelper.renderGenericTip( - InputHelper.mX + 50.0F * Settings.xScale, - InputHelper.mY + 50.0F * Settings.yScale, - tipTitle, - tipBody - ); + if (!this.isPurchased) { + if (storeRelic != null && storeRelic.relic != null) + this.storeRelic.render(sb); + else if (storePotion != null && storePotion.potion != null) + this.storePotion.render(sb); + else { + sb.setColor(Color.WHITE); + // assumes the size of a relic image + sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); + sb.draw(ImageMaster.UI_GOLD, x + GOLD_OFFSET_X, y + GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); + Color color = Color.WHITE; + if (this.price > AbstractDungeon.player.gold) + color = Color.SALMON; + FontHelper.renderFontLeftTopAligned(sb, FontHelper.tipHeaderFont, Integer.toString(this.price), x + PRICE_OFFSET_X, y + PRICE_OFFSET_Y, color); + if (this.hb.hovered && tipTitle != null && tipBody != null) + TipHelper.renderGenericTip( + InputHelper.mX + 50.0F * Settings.xScale, + InputHelper.mY + 50.0F * Settings.yScale, + tipTitle, + tipBody + ); + } } } public void hide() { - if (storeRelic != null && storeRelic.relic != null) { - this.storeRelic.hide(); - this.y = storeRelic.relic.currentY; - } - else if (storePotion != null && storePotion.potion != null) { - this.storePotion.hide(); - this.y = storePotion.potion.posY; - } - else { - this.y = Settings.HEIGHT + 200.0F * Settings.scale; + if (!this.isPurchased) { + if (storeRelic != null && storeRelic.relic != null) { + this.storeRelic.hide(); + this.y = storeRelic.relic.currentY; + } + else if (storePotion != null && storePotion.potion != null) { + this.storePotion.hide(); + this.y = storePotion.potion.posY; + } + else { + this.y = Settings.HEIGHT + 200.0F * Settings.scale; + } } } - protected void makePurchase() { - if (storeRelic != null && storeRelic.relic != null) { - this.storeRelic.purchaseRelic(); - } else if (storePotion != null && storePotion.potion != null) { - this.storePotion.purchasePotion(); - } else { - purchase(); + protected void attemptPurchase() { + if (!this.isPurchased) { + if (storeRelic != null && storeRelic.relic != null) { + this.storeRelic.purchaseRelic(); + this.storeRelic.relic = null; + this.storeRelic = null; + this.isPurchased = true; + } else if (storePotion != null && storePotion.potion != null) { + this.storePotion.purchasePotion(); + this.storePotion.potion = null; + this.storePotion = null; + this.isPurchased = true; + } else if (AbstractDungeon.player.gold >= this.price){ + purchase(); + } else { + this.screenRef.playCantBuySfx(); + this.screenRef.createSpeech(ShopScreen.getCantBuyMsg()); + } } - ShopItemGrid.removeEmptyPages(); } public void purchase() { this.isPurchased = true; + AbstractDungeon.player.loseGold(this.price); + CardCrawlGame.sound.play("SHOP_PURCHASE", 0.1F); } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java index 6c98a454d..e67be61b9 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java @@ -9,9 +9,11 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.evacipated.cardcrawl.modthespire.lib.LineFinder; import com.evacipated.cardcrawl.modthespire.lib.Matcher; +import com.evacipated.cardcrawl.modthespire.lib.SpireField; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; import com.megacrit.cardcrawl.core.Settings; @@ -26,7 +28,6 @@ import com.megacrit.cardcrawl.shop.StoreRelic; import java.util.ArrayList; import java.util.LinkedList; - import javassist.CannotCompileException; import javassist.CtBehavior; import javassist.expr.ExprEditor; @@ -39,6 +40,16 @@ public class ShopItemGrid { public static NavButton rightArrow; private static float pageIdxY; + @SpirePatch2(clz = StoreRelic.class, method = SpirePatch.CLASS) + public static class RelicFields { + public static SpireField row = new SpireField<>(() -> 0); + } + + @SpirePatch2(clz = StorePotion.class, method = SpirePatch.CLASS) + public static class PotionFields { + public static SpireField row = new SpireField<>(() -> 0); + } + @SpirePatch2( clz = ShopScreen.class, method = "init" @@ -81,9 +92,11 @@ public static class HideOnOpen { locator = Locator.class ) public static void Insert() { - currentPage.hide(); - leftArrow.hide(); - rightArrow.hide(); + if (!currentPage.isEmpty()) { + currentPage.hide(); + leftArrow.hide(); + rightArrow.hide(); + } } private static class Locator extends SpireInsertLocator { @@ -126,6 +139,48 @@ public int[] Locate(CtBehavior ctb) throws Exception { } } + @SpirePatch2( + clz = StoreRelic.class, + method = "update" + ) + public static class SetRelicYBasedOnRow { + @SpireInsertPatch( + locator = Locator.class + ) + public static void Insert(StoreRelic __instance, float rugY) { + __instance.relic.currentY = rugY + (RelicFields.row.get(__instance) == 0 ? 400.0F : 200.0F) * Settings.yScale; + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + @SpirePatch2( + clz = StorePotion.class, + method = "update" + ) + public static class SetPotionYBasedOnRow { + @SpireInsertPatch( + locator = Locator.class + ) + public static void Insert(StorePotion __instance, float rugY) { + __instance.potion.posY = rugY + (PotionFields.row.get(__instance) == 0 ? 400.0F : 200.0F) * Settings.yScale; + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + @SpirePatch2( clz = ShopScreen.class, method = "render" @@ -158,22 +213,29 @@ public int[] Locate(CtBehavior ctb) throws Exception { } public static void addItem(CustomShopItem item) { - if (currentPage != null && currentPage.tryAddItem(item)) - return; - ShopItemPage newPage = new ShopItemPage(); - newPage.tryAddItem(item); - pages.addLast(newPage); - if (currentPage == null) - currentPage = newPage; + for (ShopItemPage page : pages) + if (page.tryAddItem(item)) + return; + ShopItemPage page = new ShopItemPage(); + page.tryAddItem(item); + pages.addLast(page); } public static void removeEmptyPages() { - ShopItemPage page = currentPage; - if (page.isEmpty()) { - int newIdx = pages.indexOf(page) - 1; - pages.remove(page); - currentPage = (newIdx == -1 ? null : pages.get(newIdx)); + pages.removeIf((page) -> page.isEmpty()); + currentPage = pages.contains(currentPage) + ? currentPage + : (pages.isEmpty() ? null : pages.getFirst()); + } + + public static int getNextSlot() { + int slot = -1; + for (ShopItemPage page : pages) { + slot = page.getNextSlot(); + if (slot != -1) + break; } + return slot == -1 ? 0 : slot; } public static class ShopItemPage { @@ -199,7 +261,8 @@ public void update(float rugY) { } public void render(SpriteBatch sb) { - row1.render(sb); + if (!row1.isEmpty()) + row1.render(sb); row2.render(sb); leftArrow.render(sb); rightArrow.render(sb); @@ -221,6 +284,13 @@ public boolean tryAddItem(CustomShopItem item) { public boolean isEmpty() { return row1.isEmpty() && row2.isEmpty(); } + + public int getNextSlot() { + int slot = row1.getNextSlot(); + if (slot != -1) + return slot; + return row2.getNextSlot(); + } } public static class ShopItemRow { @@ -239,23 +309,17 @@ public ShopItemRow(int row) { public static ShopItemRow makeDefaultRelicRow(ArrayList relics, int row) { ShopItemRow itemRow = new ShopItemRow(row); - itemRow.items = new ArrayList<>(); - itemRow.row = row; itemRow.isDefaultRelics = true; - for (StoreRelic relic : relics) { - itemRow.items.add(new CustomShopItem(relic)); - } + for (StoreRelic relic : relics) + itemRow.tryAddItem(new CustomShopItem(relic)); return itemRow; } public static ShopItemRow makeDefaultPotionRow(ArrayList potions, int row) { ShopItemRow itemRow = new ShopItemRow(row); - itemRow.items = new ArrayList<>(); - itemRow.row = row; itemRow.isDefaultPotions = true; - for (StorePotion potion : potions) { - itemRow.items.add(new CustomShopItem(potion)); - } + for (StorePotion potion : potions) + itemRow.tryAddItem(new CustomShopItem(potion)); return itemRow; } @@ -270,6 +334,14 @@ public boolean tryAddItem(CustomShopItem item) { } public void update(float rugY) { + items.forEach((item) -> { + if (!item.isPurchased) { + if (item.storePotion != null) + PotionFields.row.set(item.storePotion, this.row); + if (item.storeRelic != null) + RelicFields.row.set(item.storeRelic, this.row); + } + }); if (isDefaultRelics) { ReflectionHacks.privateMethod(ShopScreen.class, "updateRelics").invoke(AbstractDungeon.shopScreen); return; @@ -278,9 +350,8 @@ public void update(float rugY) { ReflectionHacks.privateMethod(ShopScreen.class, "updatePotions").invoke(AbstractDungeon.shopScreen); return; } - for (CustomShopItem item : items) { - item.update(rugY); - } + + items.forEach((item) -> item.update(rugY + (Settings.isFourByThree ? 50.0F : 0.0F))); } public void render(SpriteBatch sb) { @@ -293,9 +364,12 @@ public void render(SpriteBatch sb) { return; } if (AbstractDungeon.shopScreen != null) - for (CustomShopItem item : items) { + for (CustomShopItem item : items) item.render(sb); - } + } + + public int getNextSlot() { + return items.size() < MAX_ITEMS_PER_ROW ? items.size() : -1; } public void hide() { @@ -305,9 +379,7 @@ public void hide() { } public boolean isEmpty() { - BaseMod.logger.info("Checking if row is empty: " + items.size()); - BaseMod.logger.info("Checking if row is empty: " + items.stream().filter(item -> !item.isPurchased).count()); - return (items.stream().filter(item -> !item.isPurchased).count() == 0); + return items.isEmpty() || (items.stream().filter((item) -> !item.isPurchased).count() == 0); } } From bc4a03b74efc15d6ef11b0f17b7c67020f6e06dd Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Thu, 18 Jan 2024 22:40:33 -0500 Subject: [PATCH 04/23] cleaning up shop pagination --- mod/src/main/java/basemod/ShopGrid.java | 333 +++++++++++++ .../basemod/abstracts/CustomShopItem.java | 81 ++-- .../basemod/devcommands/ConsoleCommand.java | 2 + .../java/basemod/devcommands/shop/Shop.java | 29 ++ .../basemod/devcommands/shop/ShopAdd.java | 46 ++ .../basemod/devcommands/shop/ShopRemove.java | 20 + .../shop/ShopScreen/ShopGridPatch.java | 168 +++++++ .../shop/ShopScreen/ShopItemGrid.java | 436 ------------------ 8 files changed, 642 insertions(+), 473 deletions(-) create mode 100644 mod/src/main/java/basemod/ShopGrid.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/Shop.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopAdd.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopRemove.java create mode 100644 mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java delete mode 100644 mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java new file mode 100644 index 000000000..5e7259627 --- /dev/null +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -0,0 +1,333 @@ +package basemod; + +import java.util.ArrayList; +import java.util.LinkedList; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.megacrit.cardcrawl.core.Settings; +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; +import com.megacrit.cardcrawl.helpers.FontHelper; +import com.megacrit.cardcrawl.helpers.Hitbox; +import com.megacrit.cardcrawl.helpers.ImageMaster; +import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; +import com.megacrit.cardcrawl.helpers.input.InputHelper; +import basemod.abstracts.CustomShopItem; +import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches; +import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches; + +public class ShopGrid { + + public static int defaultPageRows = 3; + + public static int defaultPageCols = 3; + + public static float rightEdge = Settings.WIDTH * 0.74F; + + public static float leftEdge = Settings.WIDTH * 0.44F; + + public static float topEdge = Settings.HEIGHT * 0.44F; + + public static float bottomEdge = Settings.HEIGHT * 0.075F; + + // this list holds pages specifically added by modders + public static LinkedList customPages = new LinkedList<>(); + + // this list has the pages for the remaining items that were added and the initial shop items + public static LinkedList pages = new LinkedList<>(); + + public static Page currentPage; + + public static NavButton leftArrow; + + public static NavButton rightArrow; + + private static float pageIdxY; // the top of the page? + + public static void initialize() { + pages.add(currentPage = makeDefaultPage()); + rightArrow = new NavButton(true); + leftArrow = new NavButton(false); + } + + public static Page makeDefaultPage() { + int[] rowSizes = new int[defaultPageRows]; + for (int i = 0; i < rowSizes.length; i++) + rowSizes[i] = defaultPageCols; + return new Page(rowSizes); + } + + public static void addItem(CustomShopItem item) { + for (Page page : pages) + if (page.tryAddItem(item)) + return; + + Page page = makeDefaultPage(); + page.tryAddItem(item); + pages.add(page); + } + + public static float gridWidth() { + return leftEdge - rightEdge; + } + + public static float gridHeight() { + return topEdge - bottomEdge; + } + + public static void removeEmptyPages() { + Page previousPage = currentPage.getPreviousPage(); + pages.removeIf((page) -> page.isEmpty()); + customPages.removeIf((page) -> page.isEmpty()); + if (!pages.contains(currentPage) && !customPages.contains(currentPage)) + currentPage = previousPage; + } + + public static void hide() { + currentPage.hide(); + leftArrow.hide(); + rightArrow.hide(); + } + + // public static void show() { + // currentPage.show(); + // leftArrow.show(); + // rightArrow.show(); + // } + + public static class Page { + public ArrayList rows = new ArrayList(); + + public Page(int ... rowSizes) { + for (int i = 0; i < rowSizes.length; i++) { + int size = rowSizes[i]; + Row row = new Row(0, size); + row.owner = this; + rows.add(new Row(0, size)); + } + } + + public void hide() { + for (Row row : rows) + row.hide(); + } + + public void update(float rugY) { + for (Row row : rows) + row.update(rugY); + leftArrow.update(rugY); + rightArrow.update(rugY); + pageIdxY = rugY + 500.0F * Settings.yScale; // <-- is this wrong? + } + + public void render(SpriteBatch sb) { + for (Row row : rows) + if (!row.isEmpty()) + row.render(sb); + leftArrow.render(sb); + rightArrow.render(sb); + if (pages.size() > 1) { + FontHelper.renderFontCentered( + sb, + FontHelper.buttonLabelFont, + (pages.indexOf(currentPage) + 1) + "/" + pages.size(), + 1150.0F * Settings.xScale, + pageIdxY, + Color.WHITE + ); + } + } + + public boolean tryAddItem(CustomShopItem item) { + for (Row row : rows) { + if (!row.isFull()) { + row.tryAddItem(item); + return true; + } + } + return false; + } + + public boolean isFull() { + for (Row row : rows) + if (!row.isFull()) + return false; + return true; + } + + public boolean isEmpty() { + for (Row row : rows) + if (!row.isEmpty()) + return false; + return true; + } + + public Page getPreviousPage() { + if (pages.contains(this)) { + if (pages.getFirst() == this) { + if (customPages.isEmpty()) { + return pages.getLast(); + } + return customPages.getLast(); + } + return pages.get(pages.indexOf(this) - 1); + } else if (customPages.contains(this)) { + if (customPages.getFirst() == this) { + if (pages.isEmpty()) { + return customPages.getLast(); + } + return pages.getLast(); + } + return customPages.get(pages.indexOf(this) - 1); + } + return currentPage; + } + + public Page getNextPage() { + if (pages.contains(this)) { + if (pages.getLast() == this) { + if (customPages.isEmpty()) { + return pages.getFirst(); + } + return customPages.getFirst(); + } + return pages.get(pages.indexOf(this) + 1); + } else if (customPages.contains(this)) { + if (customPages.getLast() == this) { + if (pages.isEmpty()) { + return customPages.getFirst(); + } + return pages.getFirst(); + } + return customPages.get(pages.indexOf(this) + 1); + } + return currentPage; + } + } + + public static class Row { + + public Page owner; + + public ArrayList items; + + public int rowNumber; + + public int maxColumns; + + public Row(int rowNumber, int maxColumns) { + this.items = new ArrayList<>(); + this.maxColumns = maxColumns; + this.rowNumber = rowNumber; + } + + public float getX(int col) { + return leftEdge + (col + 1) / (maxColumns + 1) * gridWidth(); + } + + public float getY(int row, float rugY) { + return rugY + bottomEdge + (row + 1) / owner.rows.size() * gridHeight(); + } + + public boolean tryAddItem(CustomShopItem item) { + if (items.size() < maxColumns) { + item.row = rowNumber; + item.col = items.size(); + items.add(item); + return true; + } + return false; + } + + public void update(float rugY) { + for (CustomShopItem item : items) { + if (item.storePotion == null && item.storeRelic == null) { + item.update(rugY); + } else if (!item.isPurchased) { + if (item.storePotion != null) { + StorePotionPatches.row.set(item.storePotion, rowNumber); + StorePotionPatches.col.set(item.storePotion, items.indexOf(item)); + } + else if (item.storeRelic != null) { + StoreRelicPatches.row.set(item.storeRelic, rowNumber); + StoreRelicPatches.col.set(item.storeRelic, items.indexOf(item)); + } + } + } + } + + public void render(SpriteBatch sb) { + if (AbstractDungeon.shopScreen != null) + for (CustomShopItem item : items) + if (item.storePotion != null && item.storeRelic != null) + item.render(sb); + } + + public void hide() { + for (CustomShopItem item : items) { + item.hide(); + } + } + + public boolean isEmpty() { + return items.isEmpty() || (items.stream().filter((item) -> !item.isPurchased).count() == 0); + } + + public boolean isFull() { + return items.size() == maxColumns; + } + } + + public static class NavButton { + public static Texture texture = ImageMaster.POPUP_ARROW; + public Hitbox hb; + + private float x, y; + + public boolean forward = true; + + public NavButton(boolean forward) { + this.forward = forward; + this.hb = new Hitbox(64.0F * Settings.scale, 64.0F * Settings.scale); + } + + public void update(float rugY) { + this.x = (forward ? 1225.0F : 1075.0F) * Settings.xScale; + this.y = rugY + 500.0F * Settings.yScale; + this.hb.move(x, y); + this.hb.update(); + if (this.hb.hovered && InputHelper.justClickedLeft) + hb.clickStarted = true; + if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { + int curIdx = pages.indexOf(currentPage); + if (forward && curIdx < pages.size() - 1) + currentPage = pages.get(curIdx + 1); + else if (!forward && curIdx > 0) + currentPage = pages.get(curIdx - 1); + this.hb.clicked = false; + } + } + + public void render(SpriteBatch sb) { + sb.setColor(Color.WHITE); + int curIdx = pages.indexOf(currentPage); + if (!forward && curIdx > 0) { + TextureRegion region = new TextureRegion(texture); + sb.draw(region, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + hb.render(sb); + } + if (forward && curIdx < pages.size() - 1) { + TextureRegion flippedRegion = new TextureRegion(texture); + flippedRegion.flip(true, false); + sb.draw(flippedRegion, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + hb.render(sb); + } + } + + public void hide() { + this.hb.move(this.hb.x, Settings.HEIGHT + 200.0F * Settings.scale); + } + } +} diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 7095db91e..41464ebac 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -1,7 +1,9 @@ package basemod.abstracts; import basemod.ReflectionHacks; -import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopItemGrid; +import basemod.ShopGrid; +import java.util.ArrayList; + import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; @@ -14,6 +16,10 @@ import com.megacrit.cardcrawl.helpers.TipHelper; import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; import com.megacrit.cardcrawl.helpers.input.InputHelper; +import com.megacrit.cardcrawl.potions.AbstractPotion; +import com.megacrit.cardcrawl.relics.AbstractRelic; +import com.megacrit.cardcrawl.relics.Courier; +import com.megacrit.cardcrawl.relics.MembershipCard; import com.megacrit.cardcrawl.shop.ShopScreen; import com.megacrit.cardcrawl.shop.StorePotion; import com.megacrit.cardcrawl.shop.StoreRelic; @@ -21,6 +27,7 @@ public class CustomShopItem { private ShopScreen screenRef; + public ShopGrid.Row gridRow; public StoreRelic storeRelic; public StorePotion storePotion; @@ -32,8 +39,8 @@ public class CustomShopItem { private float x, y; public int price = 0; - public int slot = 0; - public int row; + public int row = 0; + public int col = 0; public boolean isPurchased = false; @@ -43,55 +50,69 @@ public class CustomShopItem { private static final float PRICE_OFFSET_X = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_X"); private static final float PRICE_OFFSET_Y = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_Y"); + public CustomShopItem(AbstractRelic relic) { + this.storeRelic = new StoreRelic(relic, 0, AbstractDungeon.shopScreen); + @SuppressWarnings("unchecked") + ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); + relics.add(this.storeRelic); + } + + public CustomShopItem(AbstractPotion potion) { + this.storePotion = new StorePotion(potion, 0, AbstractDungeon.shopScreen); + @SuppressWarnings("unchecked") + ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); + potions.add(this.storePotion); + } + public CustomShopItem(StoreRelic storeRelic) { this.storeRelic = storeRelic; - this.slot = ReflectionHacks.getPrivate(storeRelic, StoreRelic.class, "slot"); } public CustomShopItem(StorePotion storePotion) { this.storePotion = storePotion; - this.slot = ReflectionHacks.getPrivate(storePotion, StorePotion.class, "slot"); } - public CustomShopItem(ShopScreen screenRef, Texture img, int price) { - this.slot = ShopItemGrid.getNextSlot(); - this.screenRef = screenRef; - this.img = img; - this.hb = new Hitbox(img.getWidth() * Settings.scale, img.getHeight() * Settings.scale); - applyDiscounts(price); + public CustomShopItem(Texture img, int price, String tipTitle, String tipBody) { + this(AbstractDungeon.shopScreen, img, price, tipTitle, tipBody); } public CustomShopItem(ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { - this(screenRef, img, price); + this.screenRef = screenRef; this.tipTitle = tipTitle; this.tipBody = tipBody; + this.img = img; + this.hb = new Hitbox(img.getWidth() * Settings.scale, img.getHeight() * Settings.scale); + applyDiscounts(price); } public void applyDiscounts(int price) { - this.price = (int)(price - * (AbstractDungeon.player.hasRelic("The Courier") ? 0.8F : 1.0F) - * (AbstractDungeon.player.hasRelic("Membership Card") ? 0.5F : 1.0F)); + float mult = 1F; + for (AbstractRelic relic : AbstractDungeon.player.relics) + if (relic.relicId.equals(Courier.ID)) + mult *= 0.8F; + else if (relic.relicId.equals(MembershipCard.ID)) + mult *= 0.5F; + this.price = (int)(mult * price); } public void update(float rugY) { if (!this.isPurchased) { if (storeRelic != null && storeRelic.relic != null) { - storeRelic.update(rugY); this.isPurchased = storeRelic.isPurchased; if (this.isPurchased) { this.storeRelic.relic = null; this.storeRelic = null; } } else if (storePotion != null && storePotion.potion != null) { - storePotion.update(rugY); this.isPurchased = storePotion.isPurchased; if (this.isPurchased) { this.storePotion.potion = null; this.storePotion = null; } } else { - this.x = 1000.0F * Settings.xScale + 150.0F * this.slot * Settings.xScale; - this.y = rugY + (this.row == 0 ? 400.0F : 200.0F) * Settings.yScale; + + this.x = gridRow.getX(col); + this.y = gridRow.getY(row, rugY); this.hb.move(this.x, this.y); this.hb.update(); @@ -105,17 +126,13 @@ public void update(float rugY) { this.hb.clicked = false; } } - ShopItemGrid.removeEmptyPages(); + ShopGrid.removeEmptyPages(); } } public void render(SpriteBatch sb) { if (!this.isPurchased) { - if (storeRelic != null && storeRelic.relic != null) - this.storeRelic.render(sb); - else if (storePotion != null && storePotion.potion != null) - this.storePotion.render(sb); - else { + if (storeRelic == null && storePotion == null) { sb.setColor(Color.WHITE); // assumes the size of a relic image sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); @@ -152,18 +169,8 @@ else if (storePotion != null && storePotion.potion != null) { } protected void attemptPurchase() { - if (!this.isPurchased) { - if (storeRelic != null && storeRelic.relic != null) { - this.storeRelic.purchaseRelic(); - this.storeRelic.relic = null; - this.storeRelic = null; - this.isPurchased = true; - } else if (storePotion != null && storePotion.potion != null) { - this.storePotion.purchasePotion(); - this.storePotion.potion = null; - this.storePotion = null; - this.isPurchased = true; - } else if (AbstractDungeon.player.gold >= this.price){ + if (!this.isPurchased && this.storePotion == null && this.storeRelic == null) { + if (AbstractDungeon.player.gold >= this.price){ purchase(); } else { this.screenRef.playCantBuySfx(); diff --git a/mod/src/main/java/basemod/devcommands/ConsoleCommand.java b/mod/src/main/java/basemod/devcommands/ConsoleCommand.java index c43ecec95..26aa79782 100644 --- a/mod/src/main/java/basemod/devcommands/ConsoleCommand.java +++ b/mod/src/main/java/basemod/devcommands/ConsoleCommand.java @@ -22,6 +22,7 @@ import basemod.devcommands.potions.Potions; import basemod.devcommands.power.Power; import basemod.devcommands.relic.Relic; +import basemod.devcommands.shop.Shop; import basemod.devcommands.statics.SetStatic; import basemod.devcommands.unlock.Unlock; import basemod.DevConsole; @@ -151,6 +152,7 @@ public static void initialize() { addCommand("setstatic", SetStatic.class); addCommand("evalstatic", EvalStatic.class); addCommand("evalcode", EvalCode.class); + addCommand("shop", Shop.class); ActCommand.initialize(); } diff --git a/mod/src/main/java/basemod/devcommands/shop/Shop.java b/mod/src/main/java/basemod/devcommands/shop/Shop.java new file mode 100644 index 000000000..bc33ad856 --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/Shop.java @@ -0,0 +1,29 @@ +package basemod.devcommands.shop; + +import basemod.DevConsole; +import basemod.devcommands.ConsoleCommand; +import basemod.devcommands.relic.Relic; + +public class Shop extends ConsoleCommand { + public Shop() { + followup.put("add", ShopAdd.class); + followup.put("remove", ShopRemove.class); + } + + @Override + protected void execute(String[] tokens, int depth) { + cmdShopHelp(); + } + + @Override + public void errorMsg() { + Relic.cmdRelicHelp(); + } + + public static void cmdShopHelp() { + DevConsole.couldNotParse(); + DevConsole.log("options are:"); + DevConsole.log("* remove [row] [col]"); + DevConsole.log("* add [relic/potion] [id]"); + } +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java new file mode 100644 index 000000000..1c4d5f3b0 --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java @@ -0,0 +1,46 @@ +package basemod.devcommands.shop; + +import java.util.ArrayList; +import java.util.List; + +import com.megacrit.cardcrawl.characters.AbstractPlayer; +import com.megacrit.cardcrawl.helpers.PotionHelper; +import com.megacrit.cardcrawl.helpers.RelicLibrary; + +import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; +import basemod.devcommands.ConsoleCommand; + +public class ShopAdd extends ConsoleCommand { + public ShopAdd() { + requiresPlayer = true; + minExtraTokens = 2; + maxExtraTokens = 2; + simpleCheck = true; + } + + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + String item = tokens[1]; + if (item.equals("relic")) + return ConsoleCommand.getRelicOptions(); + + ArrayList result = new ArrayList<>(); + List allPotions = PotionHelper.getPotions(AbstractPlayer.PlayerClass.IRONCLAD, true); + for (String key : allPotions) { + result.add(key.replace(' ', '_')); + } + return result; + } + + @Override + protected void execute(String[] tokens, int depth) { + String item = tokens[1]; + String id = tokens[2]; + + if (item.equals("relic")) + ShopGrid.addItem(new CustomShopItem(RelicLibrary.getRelic(id))); + else if (item.equals("potion")) + ShopGrid.addItem(new CustomShopItem(PotionHelper.getPotion(id))); + } +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java new file mode 100644 index 000000000..71f0e5434 --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java @@ -0,0 +1,20 @@ +package basemod.devcommands.shop; + +import basemod.ShopGrid; +import basemod.devcommands.ConsoleCommand; + +public class ShopRemove extends ConsoleCommand { + public ShopRemove() { + requiresPlayer = true; + minExtraTokens = 2; + maxExtraTokens = 2; + simpleCheck = true; + } + + @Override + public void execute(String[] tokens, int depth) { + int row = Integer.parseInt(tokens[0]); + int col = Integer.parseInt(tokens[1]); + ShopGrid.currentPage.rows.get(row).items.remove(col); + } +} diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java new file mode 100644 index 000000000..20c632017 --- /dev/null +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -0,0 +1,168 @@ +package basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen; + +import java.util.ArrayList; + +import com.evacipated.cardcrawl.modthespire.lib.LineFinder; +import com.evacipated.cardcrawl.modthespire.lib.Matcher; +import com.evacipated.cardcrawl.modthespire.lib.SpireField; +import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; +import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; +import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; +import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch; +import com.megacrit.cardcrawl.helpers.Hitbox; +import com.megacrit.cardcrawl.shop.ShopScreen; +import com.megacrit.cardcrawl.shop.StorePotion; +import com.megacrit.cardcrawl.shop.StoreRelic; + +import basemod.BaseMod; +import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; +import javassist.CtBehavior; + +public class ShopGridPatch { + + @SpirePatch2(clz = ShopScreen.class, method = "init") + public static class ShopScreenInit { + + @SpirePostfixPatch + public static void PostShopInitializeHook() { + BaseMod.publishPostShopInitialize(); + } + + @SpireInsertPatch(locator = Locator.class) + public static void InitializeGrid () { + basemod.ShopGrid.initialize(); + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ct) throws Exception { + return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ShopScreen.class, "initRelics")); + } + } + } + + @SpirePatch2(clz = ShopScreen.class, method = "open") + public static class ShopScreenOpen { + + @SpirePostfixPatch + public static void HideGridOnOpen() { + if (!ShopGrid.currentPage.isEmpty()) { + ShopGrid.hide(); + } + } + } + + @SpirePatch2(clz = ShopScreen.class, method = "initRelics") + public static class AddGridRelics { + public static void Postfix(ArrayList ___relics) { + for (StoreRelic relic : ___relics) + ShopGrid.addItem(new CustomShopItem(relic)); + } + } + + @SpirePatch2(clz = ShopScreen.class, method = "initPotions") + public static class AddGridPotions { + public static void Postfix(ArrayList ___potions) { + for (StorePotion potion : ___potions) + ShopGrid.addItem(new CustomShopItem(potion)); + } + } + + @SpirePatch2(clz = ShopScreen.class, method = "updateRelics") + public static class UpdateGridRelics { + + @SpirePrefixPatch + public static void UpdateCurrentPage(float ___rugY) { + ShopGrid.currentPage.update(___rugY); + } + } + + @SpirePatch2(clz = StoreRelic.class, method = SpirePatch.CLASS) + public static class StoreRelicPatches { + + public static SpireField row = new SpireField<>(() -> 0); + public static SpireField col = new SpireField<>(() -> 0); + public static SpireField gridRow = new SpireField<>(() -> null); + + @SpirePatch2(clz = StoreRelic.class, method = "update") + public static class SetCoords { + + @SpireInsertPatch(locator = HBMoveLocator.class) + public static void Insert(StoreRelic __instance, float rugY) { + ShopGrid.Row gridRow = StoreRelicPatches.gridRow.get(__instance); + __instance.relic.currentY = gridRow.getY(row.get(__instance), rugY); + __instance.relic.currentX = gridRow.getX(col.get(__instance)); + } + + private static class HBMoveLocator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + @SpirePatch2(clz = StoreRelic.class, method = "purchaseRelic") + public static class UpdateGridRow { + public static void Postfix(StoreRelic __instance) { + if (__instance.isPurchased) { + ShopGrid.Row gridRow = StoreRelicPatches.gridRow.get(__instance); + for (CustomShopItem item : gridRow.items) { + if (item.storeRelic == __instance) { + item.storeRelic.relic = null; + item.storeRelic = null; + item.isPurchased = true; + } + } + } + } + } + } + + @SpirePatch2(clz = StorePotion.class, method = SpirePatch.CLASS) + public static class StorePotionPatches { + + public static SpireField row = new SpireField<>(() -> 0); + public static SpireField col = new SpireField<>(() -> 0); + public static SpireField gridRow = new SpireField<>(() -> null); + + @SpirePatch2(clz = StorePotion.class, method = "update") + public static class SetPotionYBasedOnRow { + + @SpireInsertPatch(locator = Locator.class) + public static void Insert(StorePotion __instance, float rugY) { + ShopGrid.Row gridRow = StorePotionPatches.gridRow.get(__instance); + __instance.potion.posY = gridRow.getY(row.get(__instance), rugY); + __instance.potion.posX = gridRow.getX(col.get(__instance)); + } + + private static class Locator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ctb) throws Exception { + Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); + return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); + } + } + } + + @SpirePatch2(clz = StorePotion.class, method = "purchasePotion") + public static class UpdateGridRow { + public static void Postfix(StorePotion __instance) { + if (__instance.isPurchased) { + ShopGrid.Row gridRow = StorePotionPatches.gridRow.get(__instance); + for (CustomShopItem item : gridRow.items) { + if (item.storePotion == __instance) { + item.storePotion.potion = null; + item.storePotion = null; + item.isPurchased = true; + } + } + } + } + } + } +} diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java deleted file mode 100644 index e67be61b9..000000000 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopItemGrid.java +++ /dev/null @@ -1,436 +0,0 @@ -package basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen; - -import basemod.BaseMod; -import basemod.ReflectionHacks; -import basemod.abstracts.CustomShopItem; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.evacipated.cardcrawl.modthespire.lib.LineFinder; -import com.evacipated.cardcrawl.modthespire.lib.Matcher; -import com.evacipated.cardcrawl.modthespire.lib.SpireField; -import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; -import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; -import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; -import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; -import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; -import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; -import com.megacrit.cardcrawl.core.Settings; -import com.megacrit.cardcrawl.dungeons.AbstractDungeon; -import com.megacrit.cardcrawl.helpers.FontHelper; -import com.megacrit.cardcrawl.helpers.Hitbox; -import com.megacrit.cardcrawl.helpers.ImageMaster; -import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; -import com.megacrit.cardcrawl.helpers.input.InputHelper; -import com.megacrit.cardcrawl.shop.ShopScreen; -import com.megacrit.cardcrawl.shop.StorePotion; -import com.megacrit.cardcrawl.shop.StoreRelic; -import java.util.ArrayList; -import java.util.LinkedList; -import javassist.CannotCompileException; -import javassist.CtBehavior; -import javassist.expr.ExprEditor; -import javassist.expr.MethodCall; - -public class ShopItemGrid { - public static LinkedList pages = new LinkedList<>(); - public static ShopItemPage currentPage; - public static NavButton leftArrow; - public static NavButton rightArrow; - private static float pageIdxY; - - @SpirePatch2(clz = StoreRelic.class, method = SpirePatch.CLASS) - public static class RelicFields { - public static SpireField row = new SpireField<>(() -> 0); - } - - @SpirePatch2(clz = StorePotion.class, method = SpirePatch.CLASS) - public static class PotionFields { - public static SpireField row = new SpireField<>(() -> 0); - } - - @SpirePatch2( - clz = ShopScreen.class, - method = "init" - ) - public static class InitPage { - @SpirePostfixPatch - public static void Postfix() { - BaseMod.publishPostShopInitialize(); - } - - @SpireInsertPatch( - locator = Locator.class - ) - public static void Insert(ArrayList ___relics, ArrayList ___potions) { - ShopItemPage page = new ShopItemPage(); - page.row1 = ShopItemRow.makeDefaultRelicRow(___relics, 0); - page.row2 = ShopItemRow.makeDefaultPotionRow(___potions, 1); - pages.clear(); - pages.addLast(page); - currentPage = page; - rightArrow = new NavButton(true); - leftArrow = new NavButton(false); - } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ctb) throws Exception { - Matcher finalMatcher = new Matcher.FieldAccessMatcher(ShopScreen.class, "purgeAvailable"); - return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); - } - } - } - - @SpirePatch2( - clz = ShopScreen.class, - method = "open" - ) - public static class HideOnOpen { - @SpireInsertPatch( - locator = Locator.class - ) - public static void Insert() { - if (!currentPage.isEmpty()) { - currentPage.hide(); - leftArrow.hide(); - rightArrow.hide(); - } - } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ctb) throws Exception { - Matcher finalMatcher = new Matcher.FieldAccessMatcher(ShopScreen.class, "rugY"); - return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); - } - } - } - - @SpirePatch2( - clz = ShopScreen.class, - method = "update" - ) - public static class UpdateCurrentPage { - @SpireInstrumentPatch - public static ExprEditor Instrument() { - return new ExprEditor() { - public void edit(MethodCall m) throws CannotCompileException { - if (m.getMethodName().equals("updateRelics") || m.getMethodName().equals("updatePotions")) - m.replace("{}"); - } - }; - } - - @SpireInsertPatch( - locator = Locator.class - ) - public static void Insert(float ___rugY) { - currentPage.update(___rugY); - } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ctb) throws Exception { - Matcher finalMatcher = new Matcher.MethodCallMatcher(ShopScreen.class, "updateRug"); - return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); - } - } - } - - @SpirePatch2( - clz = StoreRelic.class, - method = "update" - ) - public static class SetRelicYBasedOnRow { - @SpireInsertPatch( - locator = Locator.class - ) - public static void Insert(StoreRelic __instance, float rugY) { - __instance.relic.currentY = rugY + (RelicFields.row.get(__instance) == 0 ? 400.0F : 200.0F) * Settings.yScale; - } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ctb) throws Exception { - Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); - return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); - } - } - } - - @SpirePatch2( - clz = StorePotion.class, - method = "update" - ) - public static class SetPotionYBasedOnRow { - @SpireInsertPatch( - locator = Locator.class - ) - public static void Insert(StorePotion __instance, float rugY) { - __instance.potion.posY = rugY + (PotionFields.row.get(__instance) == 0 ? 400.0F : 200.0F) * Settings.yScale; - } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ctb) throws Exception { - Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); - return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); - } - } - } - - @SpirePatch2( - clz = ShopScreen.class, - method = "render" - ) - public static class RenderCurrentPage { - @SpireInstrumentPatch - public static ExprEditor Instrument() { - return new ExprEditor() { - public void edit(MethodCall m) throws CannotCompileException { - if (m.getMethodName().equals("renderRelics") || m.getMethodName().equals("renderPotions")) - m.replace("{}"); - } - }; - } - - @SpireInsertPatch( - locator = Locator.class - ) - public static void Insert(SpriteBatch sb) { - currentPage.render(sb); - } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ctb) throws Exception { - Matcher finalMatcher = new Matcher.MethodCallMatcher(ShopScreen.class, "renderPurge"); - return LineFinder.findInOrder(ctb, new ArrayList(), finalMatcher); - } - } - } - - public static void addItem(CustomShopItem item) { - for (ShopItemPage page : pages) - if (page.tryAddItem(item)) - return; - ShopItemPage page = new ShopItemPage(); - page.tryAddItem(item); - pages.addLast(page); - } - - public static void removeEmptyPages() { - pages.removeIf((page) -> page.isEmpty()); - currentPage = pages.contains(currentPage) - ? currentPage - : (pages.isEmpty() ? null : pages.getFirst()); - } - - public static int getNextSlot() { - int slot = -1; - for (ShopItemPage page : pages) { - slot = page.getNextSlot(); - if (slot != -1) - break; - } - return slot == -1 ? 0 : slot; - } - - public static class ShopItemPage { - public ShopItemRow row1; - public ShopItemRow row2; - - public ShopItemPage() { - this.row1 = new ShopItemRow(0); - this.row2 = new ShopItemRow(1); - } - - public void hide() { - row1.hide(); - row2.hide(); - } - - public void update(float rugY) { - row1.update(rugY); - row2.update(rugY); - leftArrow.update(rugY); - rightArrow.update(rugY); - pageIdxY = rugY + 500.0F * Settings.yScale; - } - - public void render(SpriteBatch sb) { - if (!row1.isEmpty()) - row1.render(sb); - row2.render(sb); - leftArrow.render(sb); - rightArrow.render(sb); - if (pages.size() > 1) - FontHelper.renderFontCentered( - sb, - FontHelper.buttonLabelFont, - (pages.indexOf(currentPage) + 1) + "/" + pages.size(), - 1150.0F * Settings.xScale, - pageIdxY, - Color.WHITE - ); - } - - public boolean tryAddItem(CustomShopItem item) { - return row1.tryAddItem(item) || row2.tryAddItem(item); - } - - public boolean isEmpty() { - return row1.isEmpty() && row2.isEmpty(); - } - - public int getNextSlot() { - int slot = row1.getNextSlot(); - if (slot != -1) - return slot; - return row2.getNextSlot(); - } - } - - public static class ShopItemRow { - public static final int MAX_ITEMS_PER_ROW = 3; - - public ArrayList items; - public int row; - - private boolean isDefaultRelics = false; - private boolean isDefaultPotions = false; - - public ShopItemRow(int row) { - this.items = new ArrayList<>(); - this.row = row; - } - - public static ShopItemRow makeDefaultRelicRow(ArrayList relics, int row) { - ShopItemRow itemRow = new ShopItemRow(row); - itemRow.isDefaultRelics = true; - for (StoreRelic relic : relics) - itemRow.tryAddItem(new CustomShopItem(relic)); - return itemRow; - } - - public static ShopItemRow makeDefaultPotionRow(ArrayList potions, int row) { - ShopItemRow itemRow = new ShopItemRow(row); - itemRow.isDefaultPotions = true; - for (StorePotion potion : potions) - itemRow.tryAddItem(new CustomShopItem(potion)); - return itemRow; - } - - public boolean tryAddItem(CustomShopItem item) { - if (items.size() < MAX_ITEMS_PER_ROW) { - item.row = this.row; - item.slot = items.size(); - items.add(item); - return true; - } - return false; - } - - public void update(float rugY) { - items.forEach((item) -> { - if (!item.isPurchased) { - if (item.storePotion != null) - PotionFields.row.set(item.storePotion, this.row); - if (item.storeRelic != null) - RelicFields.row.set(item.storeRelic, this.row); - } - }); - if (isDefaultRelics) { - ReflectionHacks.privateMethod(ShopScreen.class, "updateRelics").invoke(AbstractDungeon.shopScreen); - return; - } - if (isDefaultPotions) { - ReflectionHacks.privateMethod(ShopScreen.class, "updatePotions").invoke(AbstractDungeon.shopScreen); - return; - } - - items.forEach((item) -> item.update(rugY + (Settings.isFourByThree ? 50.0F : 0.0F))); - } - - public void render(SpriteBatch sb) { - if (isDefaultRelics && AbstractDungeon.shopScreen != null) { - ReflectionHacks.privateMethod(ShopScreen.class, "renderRelics", SpriteBatch.class).invoke(AbstractDungeon.shopScreen, sb); - return; - } - if (isDefaultPotions && AbstractDungeon.shopScreen != null) { - ReflectionHacks.privateMethod(ShopScreen.class, "renderPotions", SpriteBatch.class).invoke(AbstractDungeon.shopScreen, sb); - return; - } - if (AbstractDungeon.shopScreen != null) - for (CustomShopItem item : items) - item.render(sb); - } - - public int getNextSlot() { - return items.size() < MAX_ITEMS_PER_ROW ? items.size() : -1; - } - - public void hide() { - for (CustomShopItem item : items) { - item.hide(); - } - } - - public boolean isEmpty() { - return items.isEmpty() || (items.stream().filter((item) -> !item.isPurchased).count() == 0); - } - } - - public static class NavButton { - public static Texture texture = ImageMaster.POPUP_ARROW; - public Hitbox hb; - - private float x, y; - - public boolean forward = true; - - public NavButton(boolean forward) { - this.forward = forward; - this.hb = new Hitbox(64.0F * Settings.scale, 64.0F * Settings.scale); - } - - public void update(float rugY) { - this.x = (forward ? 1225.0F : 1075.0F) * Settings.xScale; - this.y = rugY + 500.0F * Settings.yScale; - this.hb.move(x, y); - this.hb.update(); - if (this.hb.hovered && InputHelper.justClickedLeft) - hb.clickStarted = true; - if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { - int curIdx = pages.indexOf(currentPage); - if (forward && curIdx < pages.size() - 1) - currentPage = pages.get(curIdx + 1); - else if (!forward && curIdx > 0) - currentPage = pages.get(curIdx - 1); - this.hb.clicked = false; - } - } - - public void render(SpriteBatch sb) { - sb.setColor(Color.WHITE); - int curIdx = pages.indexOf(currentPage); - if (!forward && curIdx > 0) { - TextureRegion region = new TextureRegion(texture); - sb.draw(region, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); - hb.render(sb); - } - if (forward && curIdx < pages.size() - 1) { - TextureRegion flippedRegion = new TextureRegion(texture); - flippedRegion.flip(true, false); - sb.draw(flippedRegion, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); - hb.render(sb); - } - } - - public void hide() { - this.hb.move(this.hb.x, Settings.HEIGHT + 200.0F * Settings.scale); - } - } -} From a466a17b9f19140f9bbd3a6087b36c7e340fec6c Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Fri, 19 Jan 2024 13:51:46 -0500 Subject: [PATCH 05/23] maybe fixed it, also added custom pages --- mod/src/main/java/basemod/ShopGrid.java | 68 +++++++++++------ .../basemod/abstracts/CustomShopItem.java | 60 ++++++--------- .../basemod/devcommands/shop/ShopAdd.java | 10 +-- .../shop/ShopScreen/ShopGridPatch.java | 73 ++++++++++++------- 4 files changed, 122 insertions(+), 89 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 5e7259627..32d7c9ef2 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -20,7 +20,9 @@ public class ShopGrid { - public static int defaultPageRows = 3; + public static final String DEFAULT_PAGE_ID = "basemod"; + + public static int defaultPageRows = 2; public static int defaultPageCols = 3; @@ -44,29 +46,45 @@ public class ShopGrid { public static NavButton rightArrow; - private static float pageIdxY; // the top of the page? + private static float pageY; public static void initialize() { - pages.add(currentPage = makeDefaultPage()); + pages.clear(); + currentPage = addDefaultPage(); rightArrow = new NavButton(true); leftArrow = new NavButton(false); } - public static Page makeDefaultPage() { + public static Page addDefaultPage() { int[] rowSizes = new int[defaultPageRows]; for (int i = 0; i < rowSizes.length; i++) rowSizes[i] = defaultPageCols; - return new Page(rowSizes); + Page page = new Page(rowSizes); + pages.addLast(page); + return page; + } + + public static Page addCustomPage(String modId, int ... rowSizes) { + Page page = new Page(modId, rowSizes); + customPages.addLast(page); + return page; } - public static void addItem(CustomShopItem item) { + public static boolean tryAddItem(CustomShopItem item) { for (Page page : pages) if (page.tryAddItem(item)) - return; + return true; - Page page = makeDefaultPage(); - page.tryAddItem(item); - pages.add(page); + Page page = addDefaultPage(); + pages.addLast(page); + return page.tryAddItem(item); + } + + public static boolean tryAddItemToCustomPage(String id, CustomShopItem item) { + for (Page customPage : customPages) + if (customPage.id.equals(id) && customPage.tryAddItem(item)) + return true; + return false; } public static float gridWidth() { @@ -98,17 +116,24 @@ public static void hide() { // } public static class Page { + + public String id = DEFAULT_PAGE_ID; + public ArrayList rows = new ArrayList(); public Page(int ... rowSizes) { for (int i = 0; i < rowSizes.length; i++) { int size = rowSizes[i]; - Row row = new Row(0, size); - row.owner = this; - rows.add(new Row(0, size)); + Row row = new Row(this, i, size); + rows.add(row); } } + public Page(String id, int ... rowSizes) { + this(rowSizes); + this.id = id; + } + public void hide() { for (Row row : rows) row.hide(); @@ -119,7 +144,7 @@ public void update(float rugY) { row.update(rugY); leftArrow.update(rugY); rightArrow.update(rugY); - pageIdxY = rugY + 500.0F * Settings.yScale; // <-- is this wrong? + pageY = rugY + 500.0F * Settings.yScale; } public void render(SpriteBatch sb) { @@ -134,7 +159,7 @@ public void render(SpriteBatch sb) { FontHelper.buttonLabelFont, (pages.indexOf(currentPage) + 1) + "/" + pages.size(), 1150.0F * Settings.xScale, - pageIdxY, + pageY, Color.WHITE ); } @@ -217,7 +242,8 @@ public static class Row { public int maxColumns; - public Row(int rowNumber, int maxColumns) { + public Row(Page owner, int rowNumber, int maxColumns) { + this.owner = owner; this.items = new ArrayList<>(); this.maxColumns = maxColumns; this.rowNumber = rowNumber; @@ -228,14 +254,14 @@ public float getX(int col) { } public float getY(int row, float rugY) { - return rugY + bottomEdge + (row + 1) / owner.rows.size() * gridHeight(); + return rugY + bottomEdge + (row + 1) / (owner.rows.size() + 1) * gridHeight(); } public boolean tryAddItem(CustomShopItem item) { if (items.size() < maxColumns) { item.row = rowNumber; - item.col = items.size(); items.add(item); + item.col = items.size() - 1; return true; } return false; @@ -247,12 +273,10 @@ public void update(float rugY) { item.update(rugY); } else if (!item.isPurchased) { if (item.storePotion != null) { - StorePotionPatches.row.set(item.storePotion, rowNumber); - StorePotionPatches.col.set(item.storePotion, items.indexOf(item)); + StorePotionPatches.gridRow.set(item.storePotion, this); } else if (item.storeRelic != null) { - StoreRelicPatches.row.set(item.storeRelic, rowNumber); - StoreRelicPatches.col.set(item.storeRelic, items.indexOf(item)); + StoreRelicPatches.gridRow.set(item.storeRelic, this); } } } diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 41464ebac..b6c3a84fe 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -26,7 +26,7 @@ public class CustomShopItem { - private ShopScreen screenRef; + public ShopScreen screenRef; public ShopGrid.Row gridRow; public StoreRelic storeRelic; public StorePotion storePotion; @@ -50,26 +50,28 @@ public class CustomShopItem { private static final float PRICE_OFFSET_X = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_X"); private static final float PRICE_OFFSET_Y = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_Y"); + public CustomShopItem() { /* not recommended */ } + public CustomShopItem(AbstractRelic relic) { - this.storeRelic = new StoreRelic(relic, 0, AbstractDungeon.shopScreen); - @SuppressWarnings("unchecked") - ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); - relics.add(this.storeRelic); + this(new StoreRelic(relic, 0, AbstractDungeon.shopScreen)); } public CustomShopItem(AbstractPotion potion) { - this.storePotion = new StorePotion(potion, 0, AbstractDungeon.shopScreen); - @SuppressWarnings("unchecked") - ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); - potions.add(this.storePotion); + this(new StorePotion(potion, 0, AbstractDungeon.shopScreen)); } public CustomShopItem(StoreRelic storeRelic) { this.storeRelic = storeRelic; + @SuppressWarnings("unchecked") + ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); + relics.add(this.storeRelic); } public CustomShopItem(StorePotion storePotion) { this.storePotion = storePotion; + @SuppressWarnings("unchecked") + ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); + potions.add(this.storePotion); } public CustomShopItem(Texture img, int price, String tipTitle, String tipBody) { @@ -97,34 +99,18 @@ else if (relic.relicId.equals(MembershipCard.ID)) public void update(float rugY) { if (!this.isPurchased) { - if (storeRelic != null && storeRelic.relic != null) { - this.isPurchased = storeRelic.isPurchased; - if (this.isPurchased) { - this.storeRelic.relic = null; - this.storeRelic = null; - } - } else if (storePotion != null && storePotion.potion != null) { - this.isPurchased = storePotion.isPurchased; - if (this.isPurchased) { - this.storePotion.potion = null; - this.storePotion = null; - } - } else { - - this.x = gridRow.getX(col); - this.y = gridRow.getY(row, rugY); - - this.hb.move(this.x, this.y); - this.hb.update(); - if (this.hb.hovered) { - this.screenRef.moveHand(this.x - 190.0F * Settings.scale, this.y - 70.0F * Settings.scale); - if (InputHelper.justClickedLeft) - this.hb.clickStarted = true; - } - if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { - attemptPurchase(); - this.hb.clicked = false; - } + this.x = gridRow.getX(col); + this.y = gridRow.getY(row, rugY); + this.hb.move(this.x, this.y); + this.hb.update(); + if (this.hb.hovered) { + this.screenRef.moveHand(this.x - 190.0F * Settings.scale, this.y - 70.0F * Settings.scale); + if (InputHelper.justClickedLeft) + this.hb.clickStarted = true; + } + if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { + attemptPurchase(); + this.hb.clicked = false; } ShopGrid.removeEmptyPages(); } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java index 1c4d5f3b0..09178a64e 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java @@ -17,14 +17,14 @@ public ShopAdd() { minExtraTokens = 2; maxExtraTokens = 2; simpleCheck = true; - } + } @Override public ArrayList extraOptions(String[] tokens, int depth) { String item = tokens[1]; if (item.equals("relic")) return ConsoleCommand.getRelicOptions(); - + ArrayList result = new ArrayList<>(); List allPotions = PotionHelper.getPotions(AbstractPlayer.PlayerClass.IRONCLAD, true); for (String key : allPotions) { @@ -37,10 +37,10 @@ public ArrayList extraOptions(String[] tokens, int depth) { protected void execute(String[] tokens, int depth) { String item = tokens[1]; String id = tokens[2]; - + if (item.equals("relic")) - ShopGrid.addItem(new CustomShopItem(RelicLibrary.getRelic(id))); + ShopGrid.tryAddItem(new CustomShopItem(RelicLibrary.getRelic(id))); else if (item.equals("potion")) - ShopGrid.addItem(new CustomShopItem(PotionHelper.getPotion(id))); + ShopGrid.tryAddItem(new CustomShopItem(PotionHelper.getPotion(id))); } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 20c632017..bf4d5f0b5 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -31,17 +31,10 @@ public static void PostShopInitializeHook() { BaseMod.publishPostShopInitialize(); } - @SpireInsertPatch(locator = Locator.class) + @SpirePrefixPatch public static void InitializeGrid () { basemod.ShopGrid.initialize(); } - - private static class Locator extends SpireInsertLocator { - @Override - public int[] Locate(CtBehavior ct) throws Exception { - return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ShopScreen.class, "initRelics")); - } - } } @SpirePatch2(clz = ShopScreen.class, method = "open") @@ -56,18 +49,40 @@ public static void HideGridOnOpen() { } @SpirePatch2(clz = ShopScreen.class, method = "initRelics") - public static class AddGridRelics { - public static void Postfix(ArrayList ___relics) { - for (StoreRelic relic : ___relics) - ShopGrid.addItem(new CustomShopItem(relic)); + public static class InitRelics { + + @SpirePostfixPatch + public static void AddGridRelics(ArrayList ___relics) { + for (StoreRelic relic : ___relics) { + CustomShopItem item = new CustomShopItem(); + item.storeRelic = relic; + ShopGrid.tryAddItem(item); + } } } @SpirePatch2(clz = ShopScreen.class, method = "initPotions") - public static class AddGridPotions { - public static void Postfix(ArrayList ___potions) { - for (StorePotion potion : ___potions) - ShopGrid.addItem(new CustomShopItem(potion)); + public static class PostInitPotions { + + @SpirePostfixPatch + public static void AddGridPotionsAndSetCoords(ArrayList ___potions) { + for (StorePotion potion : ___potions) { + CustomShopItem item = new CustomShopItem(); + item.storePotion = potion; + ShopGrid.tryAddItem(item); + } + + for (ShopGrid.Row row : ShopGrid.currentPage.rows) { + for (CustomShopItem item : row.items) { + if (item.storePotion != null) { + StorePotionPatches.row.set(item.storePotion, item.row); + StorePotionPatches.col.set(item.storePotion, item.col); + } else if (item.storeRelic != null) { + StoreRelicPatches.row.set(item.storeRelic, item.row); + StoreRelicPatches.col.set(item.storeRelic, item.col); + } + } + } } } @@ -92,9 +107,11 @@ public static class SetCoords { @SpireInsertPatch(locator = HBMoveLocator.class) public static void Insert(StoreRelic __instance, float rugY) { - ShopGrid.Row gridRow = StoreRelicPatches.gridRow.get(__instance); - __instance.relic.currentY = gridRow.getY(row.get(__instance), rugY); - __instance.relic.currentX = gridRow.getX(col.get(__instance)); + if (__instance.relic != null) { + ShopGrid.Row relicRow = gridRow.get(__instance); + __instance.relic.currentY = relicRow.getY(row.get(__instance), rugY); + __instance.relic.currentX = relicRow.getX(col.get(__instance)); + } } private static class HBMoveLocator extends SpireInsertLocator { @@ -116,8 +133,10 @@ public static void Postfix(StoreRelic __instance) { item.storeRelic.relic = null; item.storeRelic = null; item.isPurchased = true; + break; } } + ShopGrid.removeEmptyPages(); } } } @@ -131,13 +150,15 @@ public static class StorePotionPatches { public static SpireField gridRow = new SpireField<>(() -> null); @SpirePatch2(clz = StorePotion.class, method = "update") - public static class SetPotionYBasedOnRow { + public static class SetCoords { @SpireInsertPatch(locator = Locator.class) public static void Insert(StorePotion __instance, float rugY) { - ShopGrid.Row gridRow = StorePotionPatches.gridRow.get(__instance); - __instance.potion.posY = gridRow.getY(row.get(__instance), rugY); - __instance.potion.posX = gridRow.getX(col.get(__instance)); + if (__instance.potion != null) { + ShopGrid.Row potionRow = gridRow.get(__instance); + __instance.potion.posY = potionRow.getY(row.get(__instance), rugY); + __instance.potion.posX = potionRow.getX(col.get(__instance)); + } } private static class Locator extends SpireInsertLocator { @@ -153,14 +174,16 @@ public int[] Locate(CtBehavior ctb) throws Exception { public static class UpdateGridRow { public static void Postfix(StorePotion __instance) { if (__instance.isPurchased) { - ShopGrid.Row gridRow = StorePotionPatches.gridRow.get(__instance); - for (CustomShopItem item : gridRow.items) { + ShopGrid.Row potionRow = gridRow.get(__instance); + for (CustomShopItem item : potionRow.items) { if (item.storePotion == __instance) { item.storePotion.potion = null; item.storePotion = null; item.isPurchased = true; + break; } } + ShopGrid.removeEmptyPages(); } } } From 244005a8064dc550a069df19daeb9d3f7864465c Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Fri, 19 Jan 2024 14:12:18 -0500 Subject: [PATCH 06/23] bruh --- .../basemod/abstracts/CustomShopItem.java | 4 +- .../shop/ShopScreen/ShopGridPatch.java | 39 +++++++++++++------ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index b6c3a84fe..f1615aada 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -60,16 +60,16 @@ public CustomShopItem(AbstractPotion potion) { this(new StorePotion(potion, 0, AbstractDungeon.shopScreen)); } + @SuppressWarnings("unchecked") public CustomShopItem(StoreRelic storeRelic) { this.storeRelic = storeRelic; - @SuppressWarnings("unchecked") ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); relics.add(this.storeRelic); } + @SuppressWarnings("unchecked") public CustomShopItem(StorePotion storePotion) { this.storePotion = storePotion; - @SuppressWarnings("unchecked") ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); potions.add(this.storePotion); } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index bf4d5f0b5..30b57cab4 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -51,12 +51,18 @@ public static void HideGridOnOpen() { @SpirePatch2(clz = ShopScreen.class, method = "initRelics") public static class InitRelics { - @SpirePostfixPatch - public static void AddGridRelics(ArrayList ___relics) { - for (StoreRelic relic : ___relics) { - CustomShopItem item = new CustomShopItem(); - item.storeRelic = relic; - ShopGrid.tryAddItem(item); + @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) + public static void AddGridRelics(StoreRelic relic) { + CustomShopItem item = new CustomShopItem(); + item.storeRelic = relic; + ShopGrid.tryAddItem(item); + } + + private static class ArrayAddLocator extends SpireInsertLocator { + + @Override + public int[] Locate(CtBehavior ct) throws Exception { + return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ArrayList.class, "add")); } } } @@ -64,14 +70,23 @@ public static void AddGridRelics(ArrayList ___relics) { @SpirePatch2(clz = ShopScreen.class, method = "initPotions") public static class PostInitPotions { - @SpirePostfixPatch - public static void AddGridPotionsAndSetCoords(ArrayList ___potions) { - for (StorePotion potion : ___potions) { - CustomShopItem item = new CustomShopItem(); - item.storePotion = potion; - ShopGrid.tryAddItem(item); + @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" }) + public static void AddGridPotions(StorePotion potion) { + CustomShopItem item = new CustomShopItem(); + item.storePotion = potion; + ShopGrid.tryAddItem(item); + } + + private static class ArrayAddLocator extends SpireInsertLocator { + + @Override + public int[] Locate(CtBehavior ct) throws Exception { + return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ArrayList.class, "add")); } + } + @SpirePostfixPatch + public static void SetItemCoords() { for (ShopGrid.Row row : ShopGrid.currentPage.rows) { for (CustomShopItem item : row.items) { if (item.storePotion != null) { From 11eeacbcbe89cb584bbc7555e8cd0ac19e5fe204 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Fri, 19 Jan 2024 16:30:24 -0500 Subject: [PATCH 07/23] finally fixed spacing, now gotta do alignment --- mod/src/main/java/basemod/ShopGrid.java | 22 +-- .../shop/ShopScreen/ShopGridPatch.java | 183 +++++++++--------- 2 files changed, 93 insertions(+), 112 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 32d7c9ef2..23d804192 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -15,8 +15,6 @@ import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; import com.megacrit.cardcrawl.helpers.input.InputHelper; import basemod.abstracts.CustomShopItem; -import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches; -import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches; public class ShopGrid { @@ -109,6 +107,7 @@ public static void hide() { rightArrow.hide(); } + // dandy-TODO // public static void show() { // currentPage.show(); // leftArrow.show(); @@ -123,9 +122,7 @@ public static class Page { public Page(int ... rowSizes) { for (int i = 0; i < rowSizes.length; i++) { - int size = rowSizes[i]; - Row row = new Row(this, i, size); - rows.add(row); + rows.add(new Row(this, i, rowSizes[i])); } } @@ -250,18 +247,18 @@ public Row(Page owner, int rowNumber, int maxColumns) { } public float getX(int col) { - return leftEdge + (col + 1) / (maxColumns + 1) * gridWidth(); + return leftEdge + (col + 1F) / (maxColumns + 1F) * gridWidth(); } public float getY(int row, float rugY) { - return rugY + bottomEdge + (row + 1) / (owner.rows.size() + 1) * gridHeight(); + return rugY + bottomEdge + (row + 1F) / (owner.rows.size() + 1F) * gridHeight(); } public boolean tryAddItem(CustomShopItem item) { if (items.size() < maxColumns) { item.row = rowNumber; + item.col = items.size(); items.add(item); - item.col = items.size() - 1; return true; } return false; @@ -271,13 +268,6 @@ public void update(float rugY) { for (CustomShopItem item : items) { if (item.storePotion == null && item.storeRelic == null) { item.update(rugY); - } else if (!item.isPurchased) { - if (item.storePotion != null) { - StorePotionPatches.gridRow.set(item.storePotion, this); - } - else if (item.storeRelic != null) { - StoreRelicPatches.gridRow.set(item.storeRelic, this); - } } } } @@ -285,7 +275,7 @@ else if (item.storeRelic != null) { public void render(SpriteBatch sb) { if (AbstractDungeon.shopScreen != null) for (CustomShopItem item : items) - if (item.storePotion != null && item.storeRelic != null) + if (item.storePotion == null && item.storeRelic == null) item.render(sb); } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 30b57cab4..21360aa8e 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -4,13 +4,13 @@ import com.evacipated.cardcrawl.modthespire.lib.LineFinder; import com.evacipated.cardcrawl.modthespire.lib.Matcher; -import com.evacipated.cardcrawl.modthespire.lib.SpireField; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpireReturn; import com.megacrit.cardcrawl.helpers.Hitbox; import com.megacrit.cardcrawl.shop.ShopScreen; import com.megacrit.cardcrawl.shop.StorePotion; @@ -23,110 +23,100 @@ public class ShopGridPatch { - @SpirePatch2(clz = ShopScreen.class, method = "init") - public static class ShopScreenInit { + @SpirePatch2(clz = ShopScreen.class, method = SpirePatch.CLASS) + public static class ShopScreenPatches { - @SpirePostfixPatch - public static void PostShopInitializeHook() { - BaseMod.publishPostShopInitialize(); - } - - @SpirePrefixPatch - public static void InitializeGrid () { - basemod.ShopGrid.initialize(); - } - } + @SpirePatch2(clz = ShopScreen.class, method = "init") + public static class ShopScreenInit { - @SpirePatch2(clz = ShopScreen.class, method = "open") - public static class ShopScreenOpen { + @SpirePostfixPatch + public static void PostShopInitializeHook() { + BaseMod.publishPostShopInitialize(); + } - @SpirePostfixPatch - public static void HideGridOnOpen() { - if (!ShopGrid.currentPage.isEmpty()) { - ShopGrid.hide(); + @SpirePrefixPatch + public static void InitializeGrid(ShopScreen __instance) { + basemod.ShopGrid.initialize(); } } - } - @SpirePatch2(clz = ShopScreen.class, method = "initRelics") - public static class InitRelics { + @SpirePatch2(clz = ShopScreen.class, method = "open") + public static class ShopScreenOpen { - @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) - public static void AddGridRelics(StoreRelic relic) { - CustomShopItem item = new CustomShopItem(); - item.storeRelic = relic; - ShopGrid.tryAddItem(item); + @SpirePostfixPatch + public static void HideGridOnOpen() { + if (!ShopGrid.currentPage.isEmpty()) { + ShopGrid.hide(); + } + } } - private static class ArrayAddLocator extends SpireInsertLocator { + @SpirePatch2(clz = ShopScreen.class, method = "initRelics") + public static class InitRelics { - @Override - public int[] Locate(CtBehavior ct) throws Exception { - return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ArrayList.class, "add")); + @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) + public static void AddGridRelic(StoreRelic relic) { + CustomShopItem item = new CustomShopItem(); + item.storeRelic = relic; + BaseMod.logger.info(ShopGrid.tryAddItem(item)); } - } - } - @SpirePatch2(clz = ShopScreen.class, method = "initPotions") - public static class PostInitPotions { + private static class ArrayAddLocator extends SpireInsertLocator { - @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" }) - public static void AddGridPotions(StorePotion potion) { - CustomShopItem item = new CustomShopItem(); - item.storePotion = potion; - ShopGrid.tryAddItem(item); + @Override + public int[] Locate(CtBehavior ct) throws Exception { + return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ArrayList.class, "add")); + } + } } - private static class ArrayAddLocator extends SpireInsertLocator { + @SpirePatch2(clz = ShopScreen.class, method = "initPotions") + public static class PostInitPotions { - @Override - public int[] Locate(CtBehavior ct) throws Exception { - return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ArrayList.class, "add")); + @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" }) + public static void AddGridPotion(StorePotion potion) { + CustomShopItem item = new CustomShopItem(); + item.storePotion = potion; + BaseMod.logger.info(ShopGrid.tryAddItem(item)); } - } - @SpirePostfixPatch - public static void SetItemCoords() { - for (ShopGrid.Row row : ShopGrid.currentPage.rows) { - for (CustomShopItem item : row.items) { - if (item.storePotion != null) { - StorePotionPatches.row.set(item.storePotion, item.row); - StorePotionPatches.col.set(item.storePotion, item.col); - } else if (item.storeRelic != null) { - StoreRelicPatches.row.set(item.storeRelic, item.row); - StoreRelicPatches.col.set(item.storeRelic, item.col); - } + private static class ArrayAddLocator extends SpireInsertLocator { + + @Override + public int[] Locate(CtBehavior ct) throws Exception { + return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ArrayList.class, "add")); } } } - } - @SpirePatch2(clz = ShopScreen.class, method = "updateRelics") - public static class UpdateGridRelics { + @SpirePatch2(clz = ShopScreen.class, method = "updateRelics") + public static class UpdateGrid { - @SpirePrefixPatch - public static void UpdateCurrentPage(float ___rugY) { - ShopGrid.currentPage.update(___rugY); + @SpirePrefixPatch + public static void UpdateCurrentPage(float ___rugY) { + ShopGrid.currentPage.update(___rugY); + } } } - @SpirePatch2(clz = StoreRelic.class, method = SpirePatch.CLASS) public static class StoreRelicPatches { - public static SpireField row = new SpireField<>(() -> 0); - public static SpireField col = new SpireField<>(() -> 0); - public static SpireField gridRow = new SpireField<>(() -> null); - @SpirePatch2(clz = StoreRelic.class, method = "update") public static class SetCoords { @SpireInsertPatch(locator = HBMoveLocator.class) - public static void Insert(StoreRelic __instance, float rugY) { + public static SpireReturn Insert(StoreRelic __instance, float rugY) { + if (__instance.relic != null) { - ShopGrid.Row relicRow = gridRow.get(__instance); - __instance.relic.currentY = relicRow.getY(row.get(__instance), rugY); - __instance.relic.currentX = relicRow.getX(col.get(__instance)); + for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (CustomShopItem item : gridRow.items) + if (item.storeRelic == __instance) { + __instance.relic.currentY = gridRow.getY(item.row, rugY); + __instance.relic.currentX = gridRow.getX(item.col); + return SpireReturn.Continue(); + } } + return SpireReturn.Continue(); } private static class HBMoveLocator extends SpireInsertLocator { @@ -142,38 +132,39 @@ public int[] Locate(CtBehavior ctb) throws Exception { public static class UpdateGridRow { public static void Postfix(StoreRelic __instance) { if (__instance.isPurchased) { - ShopGrid.Row gridRow = StoreRelicPatches.gridRow.get(__instance); - for (CustomShopItem item : gridRow.items) { - if (item.storeRelic == __instance) { - item.storeRelic.relic = null; - item.storeRelic = null; - item.isPurchased = true; - break; + for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (CustomShopItem item : gridRow.items) { + if (item.storeRelic == __instance) { + item.storeRelic.relic = null; + item.storeRelic = null; + item.isPurchased = true; + break; + } } - } ShopGrid.removeEmptyPages(); } } } } - @SpirePatch2(clz = StorePotion.class, method = SpirePatch.CLASS) public static class StorePotionPatches { - public static SpireField row = new SpireField<>(() -> 0); - public static SpireField col = new SpireField<>(() -> 0); - public static SpireField gridRow = new SpireField<>(() -> null); - @SpirePatch2(clz = StorePotion.class, method = "update") public static class SetCoords { @SpireInsertPatch(locator = Locator.class) - public static void Insert(StorePotion __instance, float rugY) { + public static SpireReturn Insert(StorePotion __instance, float rugY) { if (__instance.potion != null) { - ShopGrid.Row potionRow = gridRow.get(__instance); - __instance.potion.posY = potionRow.getY(row.get(__instance), rugY); - __instance.potion.posX = potionRow.getX(col.get(__instance)); + for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (CustomShopItem item : gridRow.items) { + if (item.storePotion == __instance) { + __instance.potion.posY = gridRow.getY(item.row, rugY); + __instance.potion.posX = gridRow.getX(item.col); + return SpireReturn.Continue(); + } + } } + return SpireReturn.Continue(); } private static class Locator extends SpireInsertLocator { @@ -189,15 +180,15 @@ public int[] Locate(CtBehavior ctb) throws Exception { public static class UpdateGridRow { public static void Postfix(StorePotion __instance) { if (__instance.isPurchased) { - ShopGrid.Row potionRow = gridRow.get(__instance); - for (CustomShopItem item : potionRow.items) { - if (item.storePotion == __instance) { - item.storePotion.potion = null; - item.storePotion = null; - item.isPurchased = true; - break; + for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (CustomShopItem item : gridRow.items) { + if (item.storePotion == __instance) { + item.storePotion.potion = null; + item.storePotion = null; + item.isPurchased = true; + break; + } } - } ShopGrid.removeEmptyPages(); } } From 667afdf39a5cb7dc519fc272e439c65d6a6d2dec Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Fri, 19 Jan 2024 23:34:33 -0500 Subject: [PATCH 08/23] fleshed out commands, fixed alignment --- mod/src/main/java/basemod/ShopGrid.java | 59 +++++++- .../basemod/abstracts/CustomShopItem.java | 9 -- .../java/basemod/devcommands/shop/Shop.java | 8 +- .../basemod/devcommands/shop/ShopAdd.java | 129 ++++++++++++++++-- .../basemod/devcommands/shop/ShopRemove.java | 47 ++++++- .../shop/ShopScreen/ShopGridPatch.java | 10 +- 6 files changed, 226 insertions(+), 36 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 23d804192..868f37306 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -14,6 +14,10 @@ import com.megacrit.cardcrawl.helpers.ImageMaster; import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; import com.megacrit.cardcrawl.helpers.input.InputHelper; +import com.megacrit.cardcrawl.shop.ShopScreen; +import com.megacrit.cardcrawl.shop.StorePotion; +import com.megacrit.cardcrawl.shop.StoreRelic; + import basemod.abstracts.CustomShopItem; public class ShopGrid { @@ -44,6 +48,8 @@ public class ShopGrid { public static NavButton rightArrow; + private static Hitbox hb; + private static float pageY; public static void initialize() { @@ -51,6 +57,14 @@ public static void initialize() { currentPage = addDefaultPage(); rightArrow = new NavButton(true); leftArrow = new NavButton(false); + hb = new Hitbox(gridWidth(), gridHeight()); + hb.move(leftEdge, bottomEdge); + } + + public static Page addEmptyPage() { + Page page = new Page(); + pages.addLast(page); + return page; } public static Page addDefaultPage() { @@ -68,6 +82,28 @@ public static Page addCustomPage(String modId, int ... rowSizes) { return page; } + public static boolean removePage(Page page) { + if (pages.contains(page)) { + if (page == currentPage) + currentPage = page.getNextPage(); + pages.remove(page); + return true; + } else if (customPages.contains(page)) { + if (page == currentPage) + currentPage = page.getNextPage(); + customPages.remove(page); + return true; + } + return false; + } + + public static boolean removePage(String modId) { + for (Page page : customPages) + if (page.id.equals(modId)) + return removePage(page); + return false; + } + public static boolean tryAddItem(CustomShopItem item) { for (Page page : pages) if (page.tryAddItem(item)) @@ -86,7 +122,7 @@ public static boolean tryAddItemToCustomPage(String id, CustomShopItem item) { } public static float gridWidth() { - return leftEdge - rightEdge; + return rightEdge - leftEdge; } public static float gridHeight() { @@ -139,6 +175,7 @@ public void hide() { public void update(float rugY) { for (Row row : rows) row.update(rugY); + hb.update(); leftArrow.update(rugY); rightArrow.update(rugY); pageY = rugY + 500.0F * Settings.yScale; @@ -150,6 +187,7 @@ public void render(SpriteBatch sb) { row.render(sb); leftArrow.render(sb); rightArrow.render(sb); + hb.render(sb); if (pages.size() > 1) { FontHelper.renderFontCentered( sb, @@ -172,6 +210,16 @@ public boolean tryAddItem(CustomShopItem item) { return false; } + public Row addRow() { + return addRow(defaultPageCols); + } + + public Row addRow(int size) { + Row row = new Row(this, rows.size(), size); + rows.add(row); + return row; + } + public boolean isFull() { for (Row row : rows) if (!row.isFull()) @@ -254,11 +302,20 @@ public float getY(int row, float rugY) { return rugY + bottomEdge + (row + 1F) / (owner.rows.size() + 1F) * gridHeight(); } + @SuppressWarnings("unchecked") public boolean tryAddItem(CustomShopItem item) { if (items.size() < maxColumns) { item.row = rowNumber; item.col = items.size(); items.add(item); + if (item.storePotion != null) { + ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); + relics.add(item.storeRelic); + } + if (item.storePotion != null) { + ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); + potions.add(item.storePotion); + } return true; } return false; diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index f1615aada..3c1f1da27 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -2,7 +2,6 @@ import basemod.ReflectionHacks; import basemod.ShopGrid; -import java.util.ArrayList; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; @@ -50,8 +49,6 @@ public class CustomShopItem { private static final float PRICE_OFFSET_X = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_X"); private static final float PRICE_OFFSET_Y = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_PRICE_OFFSET_Y"); - public CustomShopItem() { /* not recommended */ } - public CustomShopItem(AbstractRelic relic) { this(new StoreRelic(relic, 0, AbstractDungeon.shopScreen)); } @@ -60,18 +57,12 @@ public CustomShopItem(AbstractPotion potion) { this(new StorePotion(potion, 0, AbstractDungeon.shopScreen)); } - @SuppressWarnings("unchecked") public CustomShopItem(StoreRelic storeRelic) { this.storeRelic = storeRelic; - ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); - relics.add(this.storeRelic); } - @SuppressWarnings("unchecked") public CustomShopItem(StorePotion storePotion) { this.storePotion = storePotion; - ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); - potions.add(this.storePotion); } public CustomShopItem(Texture img, int price, String tipTitle, String tipBody) { diff --git a/mod/src/main/java/basemod/devcommands/shop/Shop.java b/mod/src/main/java/basemod/devcommands/shop/Shop.java index bc33ad856..f433535bb 100644 --- a/mod/src/main/java/basemod/devcommands/shop/Shop.java +++ b/mod/src/main/java/basemod/devcommands/shop/Shop.java @@ -23,7 +23,11 @@ public void errorMsg() { public static void cmdShopHelp() { DevConsole.couldNotParse(); DevConsole.log("options are:"); - DevConsole.log("* remove [row] [col]"); - DevConsole.log("* add [relic/potion] [id]"); + DevConsole.log("* add page [row size] [row size] ..."); + DevConsole.log("* add potion [id]"); + DevConsole.log("* add relic [id]"); + DevConsole.log("* add row [id] [id] ..."); + DevConsole.log("* remove item [row] [col]"); + DevConsole.log("* remove page"); } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java index 09178a64e..fcb6313fa 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java @@ -1,12 +1,17 @@ package basemod.devcommands.shop; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import com.megacrit.cardcrawl.characters.AbstractPlayer; +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; import com.megacrit.cardcrawl.helpers.PotionHelper; import com.megacrit.cardcrawl.helpers.RelicLibrary; +import com.megacrit.cardcrawl.potions.AbstractPotion; +import com.megacrit.cardcrawl.relics.AbstractRelic; +import basemod.DevConsole; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; @@ -19,28 +24,122 @@ public ShopAdd() { simpleCheck = true; } + private static ArrayList allPotions() { + ArrayList results = new ArrayList<>(); + List allPotions = PotionHelper.getPotions(AbstractPlayer.PlayerClass.IRONCLAD, true); + for (String key : allPotions) { + results.add(key.replace(' ', '_')); + } + return results; + } + + private static CustomShopItem randomItem() { + if (AbstractDungeon.miscRng.randomBoolean()) + return new CustomShopItem(AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier())); + else + return new CustomShopItem(AbstractDungeon.returnRandomPotion()); + } + + private static CustomShopItem itemFromId(String id) { + Object obj = RelicLibrary.getRelic(id); + CustomShopItem item = null; + if (obj != null) + item = new CustomShopItem((AbstractRelic)obj); + else if ((obj = PotionHelper.getPotion(id)) != null) + item = new CustomShopItem((AbstractPotion)obj); + return item; + } + @Override public ArrayList extraOptions(String[] tokens, int depth) { - String item = tokens[1]; - if (item.equals("relic")) - return ConsoleCommand.getRelicOptions(); + if (tokens.length == 2) { + ArrayList choices = new ArrayList<>(); + choices.add("page"); + choices.add("potion"); + choices.add("relic"); + choices.add("row"); + return choices; + } - ArrayList result = new ArrayList<>(); - List allPotions = PotionHelper.getPotions(AbstractPlayer.PlayerClass.IRONCLAD, true); - for (String key : allPotions) { - result.add(key.replace(' ', '_')); + ArrayList results = new ArrayList<>(); + switch(tokens[2]) { + case "page": + results.add("3 3 3 ..."); + return results; + case "potion": + if (tokens.length > 3) + return results; + return allPotions(); + case "relic": + if (tokens.length > 3) + return results; + return ConsoleCommand.getRelicOptions(); + case "row": + results.addAll(allPotions()); + results.addAll(ConsoleCommand.getRelicOptions()); + results.sort(Comparator.comparing(String::toString)); + return results; + default: + return new ArrayList<>(); } - return result; } @Override protected void execute(String[] tokens, int depth) { - String item = tokens[1]; - String id = tokens[2]; - - if (item.equals("relic")) - ShopGrid.tryAddItem(new CustomShopItem(RelicLibrary.getRelic(id))); - else if (item.equals("potion")) - ShopGrid.tryAddItem(new CustomShopItem(PotionHelper.getPotion(id))); + switch(tokens[2]) { + case "page": + if (tokens.length == 3) { + ShopGrid.Page page = ShopGrid.addDefaultPage(); + while (page.tryAddItem(randomItem())); + ShopGrid.currentPage = page; + } else { + ShopGrid.Page page = ShopGrid.addEmptyPage(); + for (int i = 3; i < tokens.length; i++) + page.addRow(Integer.parseInt(tokens[i])); + while (page.tryAddItem(randomItem())); + ShopGrid.currentPage = page; + } + case "row": + if (tokens.length == 3) { + ShopGrid.Row row = ShopGrid.currentPage.addRow(); + while (row.tryAddItem(randomItem())); + } else { + ArrayList items = new ArrayList(); + for (int i = 3; i < tokens.length; i++) + items.add(itemFromId(tokens[i])); + ShopGrid.Row row = ShopGrid.currentPage.addRow(items.size()); + for (CustomShopItem item : items) + row.tryAddItem(item); + } + break; + case "relic": + if (tokens.length > 4) { + errorMsg(); + return; + } + AbstractRelic relic; + if (tokens.length < 4) + relic = AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier()); + else + relic = RelicLibrary.getRelic(tokens[3]); + if (!ShopGrid.tryAddItem(new CustomShopItem(relic))) + DevConsole.log("could not add " + relic.relicId + " to shop grid"); + break; + case "potion": + if (tokens.length > 4) { + errorMsg(); + return; + } + AbstractPotion potion; + if (tokens.length < 4) + potion = AbstractDungeon.returnRandomPotion(); + else + potion = PotionHelper.getPotion(tokens[3]); + if (!ShopGrid.tryAddItem(new CustomShopItem(potion))) + DevConsole.log("could not add " + potion.ID + " to shop grid"); + break; + default: + errorMsg(); + } } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java index 71f0e5434..0d8d08b43 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java @@ -1,9 +1,14 @@ package basemod.devcommands.shop; +import java.util.ArrayList; +import java.util.Iterator; + import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; public class ShopRemove extends ConsoleCommand { + public ShopRemove() { requiresPlayer = true; minExtraTokens = 2; @@ -11,10 +16,46 @@ public ShopRemove() { simpleCheck = true; } + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + if (tokens.length == 2) { + ArrayList choices = new ArrayList<>(); + choices.add("item"); + choices.add("page"); + } + + ArrayList results = new ArrayList<>(); + switch(tokens[2]) { + case "item": + if (tokens.length < 5) + results.add("col"); + if (tokens.length < 4) + results.add("row"); + return results; + } + return results; + } + @Override public void execute(String[] tokens, int depth) { - int row = Integer.parseInt(tokens[0]); - int col = Integer.parseInt(tokens[1]); - ShopGrid.currentPage.rows.get(row).items.remove(col); + switch(tokens[2]) { + case "item": + int row = Integer.parseInt(tokens[3]); + if (tokens.length == 4) { + Iterator it = ShopGrid.currentPage.rows.get(row).items.iterator(); + while (it.hasNext()) { + it.remove(); + } + } else if (tokens.length == 5) { + int col = Integer.parseInt(tokens[5]); + ShopGrid.currentPage.rows.get(row).items.remove(col); + } else { + errorMsg(); + } + break; + case "page": + ShopGrid.removePage(ShopGrid.currentPage); + break; + } } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 21360aa8e..c9ecb7377 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -56,9 +56,8 @@ public static class InitRelics { @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) public static void AddGridRelic(StoreRelic relic) { - CustomShopItem item = new CustomShopItem(); - item.storeRelic = relic; - BaseMod.logger.info(ShopGrid.tryAddItem(item)); + if (!ShopGrid.tryAddItem(new CustomShopItem(relic))) + BaseMod.logger.warn("not adding default shop relic because grid is full, is this intentional?"); } private static class ArrayAddLocator extends SpireInsertLocator { @@ -75,9 +74,8 @@ public static class PostInitPotions { @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" }) public static void AddGridPotion(StorePotion potion) { - CustomShopItem item = new CustomShopItem(); - item.storePotion = potion; - BaseMod.logger.info(ShopGrid.tryAddItem(item)); + if (!ShopGrid.tryAddItem(new CustomShopItem(potion))) + BaseMod.logger.warn("not adding default potion because grid is full, is this intentional?"); } private static class ArrayAddLocator extends SpireInsertLocator { From d8ff4de1c948f0db62e5dc2099c5e44a79061c86 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sat, 20 Jan 2024 13:35:25 -0500 Subject: [PATCH 09/23] added commands and some other stuff --- mod/src/main/java/basemod/ShopGrid.java | 26 +++-- .../java/basemod/devcommands/shop/Shop.java | 3 +- .../basemod/devcommands/shop/ShopAdd.java | 107 ++---------------- .../basemod/devcommands/shop/ShopAddPage.java | 42 +++++++ .../devcommands/shop/ShopAddPotion.java | 44 +++++++ .../devcommands/shop/ShopAddRelic.java | 44 +++++++ .../basemod/devcommands/shop/ShopAddRow.java | 47 ++++++++ .../basemod/devcommands/shop/ShopRemove.java | 50 +------- .../devcommands/shop/ShopRemoveItem.java | 53 +++++++++ .../devcommands/shop/ShopRemovePage.java | 24 ++++ .../shop/ShopScreen/ShopGridPatch.java | 2 +- 11 files changed, 289 insertions(+), 153 deletions(-) create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java create mode 100644 mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 868f37306..1735a4dd7 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -48,8 +48,6 @@ public class ShopGrid { public static NavButton rightArrow; - private static Hitbox hb; - private static float pageY; public static void initialize() { @@ -57,8 +55,6 @@ public static void initialize() { currentPage = addDefaultPage(); rightArrow = new NavButton(true); leftArrow = new NavButton(false); - hb = new Hitbox(gridWidth(), gridHeight()); - hb.move(leftEdge, bottomEdge); } public static Page addEmptyPage() { @@ -150,6 +146,18 @@ public static void hide() { // rightArrow.show(); // } + public static void update(float rugY) { + currentPage.update(rugY); + } + + public static void render(SpriteBatch sb) { + if (Settings.isDebug || Settings.isInfo) { + sb.setColor(Color.RED); + sb.draw(ImageMaster.DEBUG_HITBOX_IMG, leftEdge, bottomEdge, gridWidth(), gridHeight()); + } + currentPage.render(sb); + } + public static class Page { public String id = DEFAULT_PAGE_ID; @@ -175,7 +183,6 @@ public void hide() { public void update(float rugY) { for (Row row : rows) row.update(rugY); - hb.update(); leftArrow.update(rugY); rightArrow.update(rugY); pageY = rugY + 500.0F * Settings.yScale; @@ -187,7 +194,6 @@ public void render(SpriteBatch sb) { row.render(sb); leftArrow.render(sb); rightArrow.render(sb); - hb.render(sb); if (pages.size() > 1) { FontHelper.renderFontCentered( sb, @@ -308,13 +314,15 @@ public boolean tryAddItem(CustomShopItem item) { item.row = rowNumber; item.col = items.size(); items.add(item); - if (item.storePotion != null) { + if (item.storeRelic != null) { ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); - relics.add(item.storeRelic); + if (!relics.contains(item.storeRelic)) + relics.add(item.storeRelic); } if (item.storePotion != null) { ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); - potions.add(item.storePotion); + if (!potions.contains(item.storePotion)) + potions.add(item.storePotion); } return true; } diff --git a/mod/src/main/java/basemod/devcommands/shop/Shop.java b/mod/src/main/java/basemod/devcommands/shop/Shop.java index f433535bb..284cce05f 100644 --- a/mod/src/main/java/basemod/devcommands/shop/Shop.java +++ b/mod/src/main/java/basemod/devcommands/shop/Shop.java @@ -2,7 +2,6 @@ import basemod.DevConsole; import basemod.devcommands.ConsoleCommand; -import basemod.devcommands.relic.Relic; public class Shop extends ConsoleCommand { public Shop() { @@ -17,7 +16,7 @@ protected void execute(String[] tokens, int depth) { @Override public void errorMsg() { - Relic.cmdRelicHelp(); + cmdShopHelp(); } public static void cmdShopHelp() { diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java index fcb6313fa..c6171a615 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java @@ -1,7 +1,6 @@ package basemod.devcommands.shop; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import com.megacrit.cardcrawl.characters.AbstractPlayer; @@ -11,20 +10,19 @@ import com.megacrit.cardcrawl.potions.AbstractPotion; import com.megacrit.cardcrawl.relics.AbstractRelic; -import basemod.DevConsole; -import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; public class ShopAdd extends ConsoleCommand { + public ShopAdd() { - requiresPlayer = true; - minExtraTokens = 2; - maxExtraTokens = 2; - simpleCheck = true; + followup.put("page", ShopAddPage.class); + followup.put("potion", ShopAddPotion.class); + followup.put("relic", ShopAddRelic.class); + followup.put("row", ShopAddRow.class); } - private static ArrayList allPotions() { + public static ArrayList allPotions() { ArrayList results = new ArrayList<>(); List allPotions = PotionHelper.getPotions(AbstractPlayer.PlayerClass.IRONCLAD, true); for (String key : allPotions) { @@ -33,14 +31,14 @@ private static ArrayList allPotions() { return results; } - private static CustomShopItem randomItem() { + public static CustomShopItem randomItem() { if (AbstractDungeon.miscRng.randomBoolean()) return new CustomShopItem(AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier())); else return new CustomShopItem(AbstractDungeon.returnRandomPotion()); } - private static CustomShopItem itemFromId(String id) { + public static CustomShopItem itemFromId(String id) { Object obj = RelicLibrary.getRelic(id); CustomShopItem item = null; if (obj != null) @@ -51,95 +49,12 @@ else if ((obj = PotionHelper.getPotion(id)) != null) } @Override - public ArrayList extraOptions(String[] tokens, int depth) { - if (tokens.length == 2) { - ArrayList choices = new ArrayList<>(); - choices.add("page"); - choices.add("potion"); - choices.add("relic"); - choices.add("row"); - return choices; - } - - ArrayList results = new ArrayList<>(); - switch(tokens[2]) { - case "page": - results.add("3 3 3 ..."); - return results; - case "potion": - if (tokens.length > 3) - return results; - return allPotions(); - case "relic": - if (tokens.length > 3) - return results; - return ConsoleCommand.getRelicOptions(); - case "row": - results.addAll(allPotions()); - results.addAll(ConsoleCommand.getRelicOptions()); - results.sort(Comparator.comparing(String::toString)); - return results; - default: - return new ArrayList<>(); - } + public void errorMsg() { + Shop.cmdShopHelp(); } @Override protected void execute(String[] tokens, int depth) { - switch(tokens[2]) { - case "page": - if (tokens.length == 3) { - ShopGrid.Page page = ShopGrid.addDefaultPage(); - while (page.tryAddItem(randomItem())); - ShopGrid.currentPage = page; - } else { - ShopGrid.Page page = ShopGrid.addEmptyPage(); - for (int i = 3; i < tokens.length; i++) - page.addRow(Integer.parseInt(tokens[i])); - while (page.tryAddItem(randomItem())); - ShopGrid.currentPage = page; - } - case "row": - if (tokens.length == 3) { - ShopGrid.Row row = ShopGrid.currentPage.addRow(); - while (row.tryAddItem(randomItem())); - } else { - ArrayList items = new ArrayList(); - for (int i = 3; i < tokens.length; i++) - items.add(itemFromId(tokens[i])); - ShopGrid.Row row = ShopGrid.currentPage.addRow(items.size()); - for (CustomShopItem item : items) - row.tryAddItem(item); - } - break; - case "relic": - if (tokens.length > 4) { - errorMsg(); - return; - } - AbstractRelic relic; - if (tokens.length < 4) - relic = AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier()); - else - relic = RelicLibrary.getRelic(tokens[3]); - if (!ShopGrid.tryAddItem(new CustomShopItem(relic))) - DevConsole.log("could not add " + relic.relicId + " to shop grid"); - break; - case "potion": - if (tokens.length > 4) { - errorMsg(); - return; - } - AbstractPotion potion; - if (tokens.length < 4) - potion = AbstractDungeon.returnRandomPotion(); - else - potion = PotionHelper.getPotion(tokens[3]); - if (!ShopGrid.tryAddItem(new CustomShopItem(potion))) - DevConsole.log("could not add " + potion.ID + " to shop grid"); - break; - default: - errorMsg(); - } + Shop.cmdShopHelp(); } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java new file mode 100644 index 000000000..59d21818a --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java @@ -0,0 +1,42 @@ +package basemod.devcommands.shop; + +import java.util.ArrayList; + +import basemod.BaseMod; +import basemod.ShopGrid; +import basemod.devcommands.ConsoleCommand; + +public class ShopAddPage extends ConsoleCommand { + + public ShopAddPage() { + requiresPlayer = true; + minExtraTokens = 0; + maxExtraTokens = 9; + simpleCheck = true; + } + + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + ArrayList opts = new ArrayList(); + opts.add("3"); + return opts; + } + + @Override + protected void execute(String[] tokens, int depth) { + if (tokens.length == 3) { + BaseMod.logger.info("HERE"); + ShopGrid.Page page = ShopGrid.addDefaultPage(); + while (page.tryAddItem(ShopAdd.randomItem())); + ShopGrid.currentPage = page; + } else { + BaseMod.logger.info("HERE2"); + ShopGrid.Page page = ShopGrid.addEmptyPage(); + for (int i = 3; i < tokens.length; i++) + page.addRow(Integer.parseInt(tokens[i])); + while (page.tryAddItem(ShopAdd.randomItem())); + ShopGrid.currentPage = page; + } + } + +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java new file mode 100644 index 000000000..49687012c --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java @@ -0,0 +1,44 @@ +package basemod.devcommands.shop; + +import java.util.ArrayList; + +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; +import com.megacrit.cardcrawl.helpers.PotionHelper; +import com.megacrit.cardcrawl.potions.AbstractPotion; + +import basemod.DevConsole; +import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; +import basemod.devcommands.ConsoleCommand; + +public class ShopAddPotion extends ConsoleCommand { + + public ShopAddPotion() { + requiresPlayer = true; + minExtraTokens = 0; + minExtraTokens = 1; + simpleCheck = true; + } + + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + return ShopAdd.allPotions(); + } + + @Override + public void errorMsg() { + Shop.cmdShopHelp(); + } + + @Override + protected void execute(String[] tokens, int depth) { + AbstractPotion potion; + if (tokens.length < 4) + potion = AbstractDungeon.returnRandomPotion(); + else + potion = PotionHelper.getPotion(tokens[3]); + if (!ShopGrid.tryAddItem(new CustomShopItem(potion))) + DevConsole.log("could not add " + potion.ID + " to shop grid"); + } + +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java new file mode 100644 index 000000000..989f6eb35 --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java @@ -0,0 +1,44 @@ +package basemod.devcommands.shop; + +import java.util.ArrayList; + +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; +import com.megacrit.cardcrawl.helpers.RelicLibrary; +import com.megacrit.cardcrawl.relics.AbstractRelic; + +import basemod.DevConsole; +import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; +import basemod.devcommands.ConsoleCommand; + +public class ShopAddRelic extends ConsoleCommand { + + public ShopAddRelic() { + requiresPlayer = true; + minExtraTokens = 0; + minExtraTokens = 1; + simpleCheck = true; + } + + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + return ConsoleCommand.getRelicOptions(); + } + + @Override + public void errorMsg() { + Shop.cmdShopHelp(); + } + + @Override + protected void execute(String[] tokens, int depth) { + AbstractRelic relic; + if (tokens.length == 3) + relic = AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier()); + else + relic = RelicLibrary.getRelic(tokens[3]); + if (!ShopGrid.tryAddItem(new CustomShopItem(relic))) + DevConsole.log("could not add " + relic.relicId + " to shop grid"); + } + +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java new file mode 100644 index 000000000..39c5fbe6e --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java @@ -0,0 +1,47 @@ +package basemod.devcommands.shop; + +import java.util.ArrayList; +import java.util.Comparator; + +import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; +import basemod.devcommands.ConsoleCommand; + +public class ShopAddRow extends ConsoleCommand { + + public ShopAddRow() { + requiresPlayer = true; + minExtraTokens = 0; + minExtraTokens = 9; + simpleCheck = true; + } + + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + ArrayList opts = new ArrayList(); + opts.addAll(ShopAdd.allPotions()); + opts.addAll(ConsoleCommand.getRelicOptions()); + opts.sort(Comparator.comparing(String::toString)); + return opts; + } + + @Override + public void errorMsg() { + Shop.cmdShopHelp(); + } + + @Override + protected void execute(String[] tokens, int depth) { + if (tokens.length == 3) { + ShopGrid.Row row = ShopGrid.currentPage.addRow(); + while (row.tryAddItem(ShopAdd.randomItem())); + } else { + ArrayList items = new ArrayList(); + for (int i = 3; i < tokens.length; i++) + items.add(ShopAdd.itemFromId(tokens[i])); + ShopGrid.Row row = ShopGrid.currentPage.addRow(items.size()); + for (CustomShopItem item : items) + row.tryAddItem(item); + } + } +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java index 0d8d08b43..9753780e6 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemove.java @@ -1,61 +1,21 @@ package basemod.devcommands.shop; -import java.util.ArrayList; -import java.util.Iterator; - -import basemod.ShopGrid; -import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; public class ShopRemove extends ConsoleCommand { public ShopRemove() { - requiresPlayer = true; - minExtraTokens = 2; - maxExtraTokens = 2; - simpleCheck = true; + followup.put("item", ShopRemoveItem.class); + followup.put("page", ShopRemovePage.class); } @Override - public ArrayList extraOptions(String[] tokens, int depth) { - if (tokens.length == 2) { - ArrayList choices = new ArrayList<>(); - choices.add("item"); - choices.add("page"); - } - - ArrayList results = new ArrayList<>(); - switch(tokens[2]) { - case "item": - if (tokens.length < 5) - results.add("col"); - if (tokens.length < 4) - results.add("row"); - return results; - } - return results; + public void errorMsg() { + Shop.cmdShopHelp(); } @Override public void execute(String[] tokens, int depth) { - switch(tokens[2]) { - case "item": - int row = Integer.parseInt(tokens[3]); - if (tokens.length == 4) { - Iterator it = ShopGrid.currentPage.rows.get(row).items.iterator(); - while (it.hasNext()) { - it.remove(); - } - } else if (tokens.length == 5) { - int col = Integer.parseInt(tokens[5]); - ShopGrid.currentPage.rows.get(row).items.remove(col); - } else { - errorMsg(); - } - break; - case "page": - ShopGrid.removePage(ShopGrid.currentPage); - break; - } + Shop.cmdShopHelp(); } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java new file mode 100644 index 000000000..c37222e26 --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java @@ -0,0 +1,53 @@ +package basemod.devcommands.shop; + +import java.util.ArrayList; +import java.util.Iterator; + +import basemod.ShopGrid; +import basemod.abstracts.CustomShopItem; +import basemod.devcommands.ConsoleCommand; + +public class ShopRemoveItem extends ConsoleCommand { + + public ShopRemoveItem() { + requiresPlayer = true; + minExtraTokens = 1; + minExtraTokens = 2; + simpleCheck = true; + } + + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + ArrayList opts = new ArrayList<>(); + if (tokens.length == 3) { + for (int i = 0; i < ShopGrid.currentPage.rows.size(); i++) + opts.add(String.valueOf(i)); + } + else { + int row = Integer.parseInt(tokens[3]); + for (int i = 0; i < ShopGrid.currentPage.rows.get(row).maxColumns; i++) + opts.add(String.valueOf(i)); + } + return opts; + } + + @Override + public void errorMsg() { + Shop.cmdShopHelp(); + } + + @Override + protected void execute(String[] tokens, int depth) { + int row = Integer.parseInt(tokens[3]); + if (tokens.length == 4) { + Iterator it = ShopGrid.currentPage.rows.get(row).items.iterator(); + while (it.hasNext()) { + it.remove(); + } + } else { + int col = Integer.parseInt(tokens[5]); + ShopGrid.currentPage.rows.get(row).items.remove(col); + } + } + +} diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java new file mode 100644 index 000000000..897a86051 --- /dev/null +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java @@ -0,0 +1,24 @@ +package basemod.devcommands.shop; + +import basemod.ShopGrid; +import basemod.devcommands.ConsoleCommand; + +public class ShopRemovePage extends ConsoleCommand { + + public ShopRemovePage() { + requiresPlayer = true; + minExtraTokens = 0; + maxExtraTokens = 0; + simpleCheck = true; + } + + @Override + public void errorMsg() { + Shop.cmdShopHelp(); + } + + @Override + protected void execute(String[] tokens, int depth) { + ShopGrid.removePage(ShopGrid.currentPage); + } +} diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index c9ecb7377..9311db56e 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -92,7 +92,7 @@ public static class UpdateGrid { @SpirePrefixPatch public static void UpdateCurrentPage(float ___rugY) { - ShopGrid.currentPage.update(___rugY); + ShopGrid.update(___rugY); } } } From a0e724c0f5b2853cb5cbdc24ad2e69fbd8df422a Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sat, 20 Jan 2024 14:57:28 -0500 Subject: [PATCH 10/23] add debug box, add special case to use normal Y position when row = 2 --- mod/src/main/java/basemod/ShopGrid.java | 2 +- .../shop/ShopScreen/ShopGridPatch.java | 20 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 1735a4dd7..c7dad55c1 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -305,7 +305,7 @@ public float getX(int col) { } public float getY(int row, float rugY) { - return rugY + bottomEdge + (row + 1F) / (owner.rows.size() + 1F) * gridHeight(); + return rugY + (topEdge - ((row + 1F) / (owner.rows.size() + 1F) + gridHeight())) - (gridHeight() * 0.2F); } @SuppressWarnings("unchecked") diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 9311db56e..44c417043 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -2,6 +2,7 @@ import java.util.ArrayList; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.evacipated.cardcrawl.modthespire.lib.LineFinder; import com.evacipated.cardcrawl.modthespire.lib.Matcher; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; @@ -88,13 +89,22 @@ public int[] Locate(CtBehavior ct) throws Exception { } @SpirePatch2(clz = ShopScreen.class, method = "updateRelics") - public static class UpdateGrid { + public static class Update { @SpirePrefixPatch - public static void UpdateCurrentPage(float ___rugY) { + public static void UpdateGrid(float ___rugY) { ShopGrid.update(___rugY); } } + + @SpirePatch2(clz = ShopScreen.class, method = "render") + public static class Render { + + @SpirePostfixPatch + public static void RenderGrid(SpriteBatch sb) { + ShopGrid.render(sb); + } + } } public static class StoreRelicPatches { @@ -109,7 +119,8 @@ public static SpireReturn Insert(StoreRelic __instance, float rugY) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) if (item.storeRelic == __instance) { - __instance.relic.currentY = gridRow.getY(item.row, rugY); + if (gridRow.owner.rows.size() != 2) + __instance.relic.currentY = gridRow.getY(item.row, rugY); __instance.relic.currentX = gridRow.getX(item.col); return SpireReturn.Continue(); } @@ -156,7 +167,8 @@ public static SpireReturn Insert(StorePotion __instance, float rugY) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { - __instance.potion.posY = gridRow.getY(item.row, rugY); + if (gridRow.owner.rows.size() != 2) + __instance.potion.posY = gridRow.getY(item.row, rugY); __instance.potion.posX = gridRow.getX(item.col); return SpireReturn.Continue(); } From 1e0fd4a69076c65c0da4e83d50473102266bb756 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sat, 20 Jan 2024 16:28:16 -0500 Subject: [PATCH 11/23] fix some things, mainly the page stuff --- mod/src/main/java/basemod/BaseMod.java | 1 - mod/src/main/java/basemod/ShopGrid.java | 23 +++++++++++-- .../basemod/abstracts/CustomShopItem.java | 25 ++++++++++---- .../shop/ShopScreen/ShopGridPatch.java | 34 ++++++++++++++++--- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/mod/src/main/java/basemod/BaseMod.java b/mod/src/main/java/basemod/BaseMod.java index 47daafdbf..ec5979488 100644 --- a/mod/src/main/java/basemod/BaseMod.java +++ b/mod/src/main/java/basemod/BaseMod.java @@ -11,7 +11,6 @@ import basemod.patches.com.megacrit.cardcrawl.cards.AbstractCard.RenderDescriptionEnergy; import basemod.patches.com.megacrit.cardcrawl.helpers.TopPanel.TopPanelHelper; import basemod.patches.com.megacrit.cardcrawl.screens.select.GridCardSelectScreen.GridCardSelectScreenFields; -import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopItemGrid; import basemod.patches.com.megacrit.cardcrawl.unlock.UnlockTracker.CountModdedUnlockCards; import basemod.patches.imgui.ImGuiPatches; import basemod.patches.whatmod.WhatMod; diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index c7dad55c1..bd8e9ee0d 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -281,6 +281,25 @@ public Page getNextPage() { } return currentPage; } + + public boolean contains(String id) { + for (Row row : rows) + for (CustomShopItem item : row.items) { + if ((item.storePotion != null && item.storePotion.potion.ID.equals(id)) + || (item.storeRelic != null && item.storeRelic.relic.relicId.equals(id)) + || (item.id.equals(id))) + return true; + } + return false; + } + + public boolean contains (StoreRelic relic) { + return contains(relic.relic.relicId); + } + + public boolean contains(StorePotion potion) { + return contains(potion.potion.ID); + } } public static class Row { @@ -394,13 +413,13 @@ public void render(SpriteBatch sb) { int curIdx = pages.indexOf(currentPage); if (!forward && curIdx > 0) { TextureRegion region = new TextureRegion(texture); - sb.draw(region, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + sb.draw(region, x - 96.0F * Settings.scale, y - 96.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); hb.render(sb); } if (forward && curIdx < pages.size() - 1) { TextureRegion flippedRegion = new TextureRegion(texture); flippedRegion.flip(true, false); - sb.draw(flippedRegion, x - 64.0F * Settings.scale, y - 64.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + sb.draw(flippedRegion, x - 96.0F * Settings.scale, y - 96.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); hb.render(sb); } } diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 3c1f1da27..dc7815405 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -1,5 +1,6 @@ package basemod.abstracts; +import basemod.BaseMod; import basemod.ReflectionHacks; import basemod.ShopGrid; @@ -25,6 +26,8 @@ public class CustomShopItem { + public String id; + public ShopScreen screenRef; public ShopGrid.Row gridRow; public StoreRelic storeRelic; @@ -58,18 +61,28 @@ public CustomShopItem(AbstractPotion potion) { } public CustomShopItem(StoreRelic storeRelic) { - this.storeRelic = storeRelic; + if (storeRelic.relic != null) { + this.storeRelic = storeRelic; + this.id = ShopGrid.DEFAULT_PAGE_ID + ":" + storeRelic.relic.relicId; + } else { + BaseMod.logger.error("StoreRelic cannot have a null relic"); + } } public CustomShopItem(StorePotion storePotion) { - this.storePotion = storePotion; + if (storePotion.potion != null) { + this.storePotion = storePotion; + this.id = ShopGrid.DEFAULT_PAGE_ID + ":" + storePotion.potion.ID; + } else { + BaseMod.logger.error("StorePotion cannot have a null potion"); + } } - public CustomShopItem(Texture img, int price, String tipTitle, String tipBody) { - this(AbstractDungeon.shopScreen, img, price, tipTitle, tipBody); + public CustomShopItem(String modId, Texture img, int price, String tipTitle, String tipBody) { + this(modId, AbstractDungeon.shopScreen, img, price, tipTitle, tipBody); } - public CustomShopItem(ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { + public CustomShopItem(String modId, ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { this.screenRef = screenRef; this.tipTitle = tipTitle; this.tipBody = tipBody; @@ -109,7 +122,7 @@ public void update(float rugY) { public void render(SpriteBatch sb) { if (!this.isPurchased) { - if (storeRelic == null && storePotion == null) { + if (storeRelic == null && storePotion == null && ShopGrid.currentPage.contains(id)) { sb.setColor(Color.WHITE); // assumes the size of a relic image sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 44c417043..d7d0ce7a3 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -154,15 +154,27 @@ public static void Postfix(StoreRelic __instance) { } } } + + @SpirePatch2(clz = StoreRelic.class, method = "render") + public static class Render { + + @SpirePrefixPatch + public static SpireReturn CheckIfRelicInCurrentPage(StoreRelic __instance, SpriteBatch sb) { + if (__instance.relic != null && !ShopGrid.currentPage.contains(__instance)) { + return SpireReturn.Return(); + } + return SpireReturn.Continue(); + } + } } public static class StorePotionPatches { @SpirePatch2(clz = StorePotion.class, method = "update") - public static class SetCoords { + public static class Update { - @SpireInsertPatch(locator = Locator.class) - public static SpireReturn Insert(StorePotion __instance, float rugY) { + @SpireInsertPatch(locator = HBMoveLocator.class) + public static SpireReturn SetCoords(StorePotion __instance, float rugY) { if (__instance.potion != null) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) { @@ -177,7 +189,7 @@ public static SpireReturn Insert(StorePotion __instance, float rugY) { return SpireReturn.Continue(); } - private static class Locator extends SpireInsertLocator { + private static class HBMoveLocator extends SpireInsertLocator { @Override public int[] Locate(CtBehavior ctb) throws Exception { Matcher finalMatcher = new Matcher.MethodCallMatcher(Hitbox.class, "move"); @@ -187,7 +199,7 @@ public int[] Locate(CtBehavior ctb) throws Exception { } @SpirePatch2(clz = StorePotion.class, method = "purchasePotion") - public static class UpdateGridRow { + public static class PurchasePotion { public static void Postfix(StorePotion __instance) { if (__instance.isPurchased) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) @@ -203,5 +215,17 @@ public static void Postfix(StorePotion __instance) { } } } + + @SpirePatch2(clz = StorePotion.class, method = "render") + public static class Render { + + @SpirePrefixPatch + public static SpireReturn CheckIfPotionInCurrentPage(StorePotion __instance, SpriteBatch sb) { + if (__instance.potion != null && !ShopGrid.currentPage.contains(__instance)) { + return SpireReturn.Return(); + } + return SpireReturn.Continue(); + } + } } } From 385f67fbce54f9739749fdc47179280806d97c58 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sat, 20 Jan 2024 17:04:03 -0500 Subject: [PATCH 12/23] fix default spacing issue --- .../cardcrawl/shop/ShopScreen/ShopGridPatch.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index d7d0ce7a3..58a0f40fe 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -7,11 +7,13 @@ import com.evacipated.cardcrawl.modthespire.lib.Matcher; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch; import com.evacipated.cardcrawl.modthespire.lib.SpireReturn; +import com.megacrit.cardcrawl.core.Settings; import com.megacrit.cardcrawl.helpers.Hitbox; import com.megacrit.cardcrawl.shop.ShopScreen; import com.megacrit.cardcrawl.shop.StorePotion; @@ -20,7 +22,10 @@ import basemod.BaseMod; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; +import javassist.CannotCompileException; import javassist.CtBehavior; +import javassist.expr.ExprEditor; +import javassist.expr.FieldAccess; public class ShopGridPatch { @@ -119,8 +124,11 @@ public static SpireReturn Insert(StoreRelic __instance, float rugY) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) if (item.storeRelic == __instance) { - if (gridRow.owner.rows.size() != 2) + if (gridRow.owner.rows.size() != 2) { __instance.relic.currentY = gridRow.getY(item.row, rugY); + } else { + __instance.relic.currentY = rugY + (item.row == 0 ? 200F : 400F) * Settings.xScale; + } __instance.relic.currentX = gridRow.getX(item.col); return SpireReturn.Continue(); } @@ -179,8 +187,11 @@ public static SpireReturn SetCoords(StorePotion __instance, float rugY) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { - if (gridRow.owner.rows.size() != 2) + if (gridRow.owner.rows.size() != 2) { __instance.potion.posY = gridRow.getY(item.row, rugY); + } else { + __instance.potion.posY = rugY + (item.row == 0 ? 200F : 400F) * Settings.xScale; + } __instance.potion.posX = gridRow.getX(item.col); return SpireReturn.Continue(); } From 13a86bd662972096328435d81ee1c8a4eff0e245 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sat, 20 Jan 2024 17:37:09 -0500 Subject: [PATCH 13/23] whelp --- mod/src/main/java/basemod/ShopGrid.java | 4 ++-- mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index bd8e9ee0d..3b33ef00a 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -150,10 +150,10 @@ public static void update(float rugY) { currentPage.update(rugY); } - public static void render(SpriteBatch sb) { + public static void render(SpriteBatch sb, float rugY) { if (Settings.isDebug || Settings.isInfo) { sb.setColor(Color.RED); - sb.draw(ImageMaster.DEBUG_HITBOX_IMG, leftEdge, bottomEdge, gridWidth(), gridHeight()); + sb.draw(ImageMaster.DEBUG_HITBOX_IMG, leftEdge, rugY + bottomEdge, gridWidth(), gridHeight()); } currentPage.render(sb); } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java index 59d21818a..be776164d 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java @@ -32,7 +32,7 @@ protected void execute(String[] tokens, int depth) { } else { BaseMod.logger.info("HERE2"); ShopGrid.Page page = ShopGrid.addEmptyPage(); - for (int i = 3; i < tokens.length; i++) + for (int i = 2; i < tokens.length; i++) page.addRow(Integer.parseInt(tokens[i])); while (page.tryAddItem(ShopAdd.randomItem())); ShopGrid.currentPage = page; From 1face0d296547a020001f7d78b99f06a7b59e2f3 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sun, 21 Jan 2024 12:26:25 -0500 Subject: [PATCH 14/23] fixing bugs in commands and patches --- mod/src/main/java/basemod/ShopGrid.java | 23 +++++++------ .../basemod/devcommands/shop/ShopAddPage.java | 14 ++++---- .../devcommands/shop/ShopRemoveItem.java | 32 ++++++++++++------- .../devcommands/shop/ShopRemovePage.java | 4 ++- .../shop/ShopScreen/ShopGridPatch.java | 32 ++++++++++++------- 5 files changed, 63 insertions(+), 42 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 3b33ef00a..febb22e64 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -79,17 +79,15 @@ public static Page addCustomPage(String modId, int ... rowSizes) { } public static boolean removePage(Page page) { - if (pages.contains(page)) { - if (page == currentPage) - currentPage = page.getNextPage(); - pages.remove(page); - return true; - } else if (customPages.contains(page)) { - if (page == currentPage) - currentPage = page.getNextPage(); - customPages.remove(page); - return true; + if (page == currentPage) { + currentPage = page.getNextPage(); + if (currentPage == page) + currentPage = null; } + if (pages.contains(page)) + return pages.remove(page); + else if (customPages.contains(page)) + return customPages.remove(page); return false; } @@ -126,6 +124,7 @@ public static float gridHeight() { } public static void removeEmptyPages() { + BaseMod.logger.info("HERE"); Page previousPage = currentPage.getPreviousPage(); pages.removeIf((page) -> page.isEmpty()); customPages.removeIf((page) -> page.isEmpty()); @@ -199,7 +198,7 @@ public void render(SpriteBatch sb) { sb, FontHelper.buttonLabelFont, (pages.indexOf(currentPage) + 1) + "/" + pages.size(), - 1150.0F * Settings.xScale, + 1130F * Settings.xScale, pageY, Color.WHITE ); @@ -392,7 +391,7 @@ public NavButton(boolean forward) { } public void update(float rugY) { - this.x = (forward ? 1225.0F : 1075.0F) * Settings.xScale; + this.x = (forward ? 1205.0F : 1055.0F) * Settings.xScale; this.y = rugY + 500.0F * Settings.yScale; this.hb.move(x, y); this.hb.update(); diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java index be776164d..246eac1dd 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java @@ -2,7 +2,6 @@ import java.util.ArrayList; -import basemod.BaseMod; import basemod.ShopGrid; import basemod.devcommands.ConsoleCommand; @@ -25,17 +24,20 @@ public ArrayList extraOptions(String[] tokens, int depth) { @Override protected void execute(String[] tokens, int depth) { if (tokens.length == 3) { - BaseMod.logger.info("HERE"); ShopGrid.Page page = ShopGrid.addDefaultPage(); while (page.tryAddItem(ShopAdd.randomItem())); ShopGrid.currentPage = page; } else { - BaseMod.logger.info("HERE2"); ShopGrid.Page page = ShopGrid.addEmptyPage(); - for (int i = 2; i < tokens.length; i++) + try { + for (int i = 3; i < tokens.length; i++) page.addRow(Integer.parseInt(tokens[i])); - while (page.tryAddItem(ShopAdd.randomItem())); - ShopGrid.currentPage = page; + while (page.tryAddItem(ShopAdd.randomItem())); + ShopGrid.currentPage = page; + } catch (NumberFormatException nfe) { + nfe.printStackTrace(); + Shop.cmdShopHelp(); + } } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java index c37222e26..67fb85085 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java @@ -24,9 +24,14 @@ public ArrayList extraOptions(String[] tokens, int depth) { opts.add(String.valueOf(i)); } else { - int row = Integer.parseInt(tokens[3]); - for (int i = 0; i < ShopGrid.currentPage.rows.get(row).maxColumns; i++) - opts.add(String.valueOf(i)); + try { + int row = Integer.parseInt(tokens[3]); + for (int i = 0; i < ShopGrid.currentPage.rows.get(row).maxColumns; i++) + opts.add(String.valueOf(i)); + } catch (NumberFormatException nfe) { + nfe.printStackTrace(); + Shop.cmdShopHelp(); + } } return opts; } @@ -38,15 +43,20 @@ public void errorMsg() { @Override protected void execute(String[] tokens, int depth) { - int row = Integer.parseInt(tokens[3]); - if (tokens.length == 4) { - Iterator it = ShopGrid.currentPage.rows.get(row).items.iterator(); - while (it.hasNext()) { - it.remove(); + try { + int row = Integer.parseInt(tokens[3]); + if (tokens.length == 4) { + Iterator it = ShopGrid.currentPage.rows.get(row).items.iterator(); + while (it.hasNext()) { + it.remove(); + } + } else { + int col = Integer.parseInt(tokens[4]); + ShopGrid.currentPage.rows.get(row).items.remove(col); } - } else { - int col = Integer.parseInt(tokens[5]); - ShopGrid.currentPage.rows.get(row).items.remove(col); + } catch(NumberFormatException nfe) { + nfe.printStackTrace(); + Shop.cmdShopHelp(); } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java index 897a86051..122ef8c6a 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java @@ -1,5 +1,6 @@ package basemod.devcommands.shop; +import basemod.DevConsole; import basemod.ShopGrid; import basemod.devcommands.ConsoleCommand; @@ -19,6 +20,7 @@ public void errorMsg() { @Override protected void execute(String[] tokens, int depth) { - ShopGrid.removePage(ShopGrid.currentPage); + if (!ShopGrid.removePage(ShopGrid.currentPage)) + DevConsole.log("could not remove page"); } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 58a0f40fe..95a893180 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -7,7 +7,6 @@ import com.evacipated.cardcrawl.modthespire.lib.Matcher; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; -import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; @@ -22,10 +21,7 @@ import basemod.BaseMod; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; -import javassist.CannotCompileException; import javassist.CtBehavior; -import javassist.expr.ExprEditor; -import javassist.expr.FieldAccess; public class ShopGridPatch { @@ -105,9 +101,16 @@ public static void UpdateGrid(float ___rugY) { @SpirePatch2(clz = ShopScreen.class, method = "render") public static class Render { - @SpirePostfixPatch - public static void RenderGrid(SpriteBatch sb) { - ShopGrid.render(sb); + @SpireInsertPatch(locator = RenderRelicsLocator.class) + public static void RenderGrid(SpriteBatch sb, float ___rugY) { + ShopGrid.render(sb, ___rugY); + } + + private static class RenderRelicsLocator extends SpireInsertLocator { + @Override + public int[] Locate(CtBehavior ct) throws Exception { + return LineFinder.findInOrder(ct, new Matcher.MethodCallMatcher(ShopScreen.class, "renderRelics")); + } } } } @@ -120,7 +123,7 @@ public static class SetCoords { @SpireInsertPatch(locator = HBMoveLocator.class) public static SpireReturn Insert(StoreRelic __instance, float rugY) { - if (__instance.relic != null) { + if (__instance.relic != null) { // dandy-TODO: for compatibility, add check to see if relic/potion was added to grid, otherwise continue for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) if (item.storeRelic == __instance) { @@ -132,6 +135,7 @@ public static SpireReturn Insert(StoreRelic __instance, float rugY) { __instance.relic.currentX = gridRow.getX(item.col); return SpireReturn.Continue(); } + return SpireReturn.Return(); } return SpireReturn.Continue(); } @@ -146,8 +150,9 @@ public int[] Locate(CtBehavior ctb) throws Exception { } @SpirePatch2(clz = StoreRelic.class, method = "purchaseRelic") - public static class UpdateGridRow { - public static void Postfix(StoreRelic __instance) { + public static class PurchaseRelic { + @SpirePostfixPatch + public static void RemoveRelic(StoreRelic __instance) { if (__instance.isPurchased) { for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) { @@ -155,7 +160,9 @@ public static void Postfix(StoreRelic __instance) { item.storeRelic.relic = null; item.storeRelic = null; item.isPurchased = true; - break; + + ShopGrid.removeEmptyPages(); + return; } } ShopGrid.removeEmptyPages(); @@ -183,7 +190,7 @@ public static class Update { @SpireInsertPatch(locator = HBMoveLocator.class) public static SpireReturn SetCoords(StorePotion __instance, float rugY) { - if (__instance.potion != null) { + if (__instance.potion != null) { // dandy-TODO: for compatibility, add check to see if relic/potion was added to grid, otherwise continue for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { @@ -196,6 +203,7 @@ public static SpireReturn SetCoords(StorePotion __instance, float rugY) { return SpireReturn.Continue(); } } + return SpireReturn.Return(); } return SpireReturn.Continue(); } From a6d0bb397582069d8cfab4680c60426b2c327f58 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sun, 21 Jan 2024 14:23:38 -0500 Subject: [PATCH 15/23] making more resilient --- mod/src/main/java/basemod/ShopGrid.java | 120 ++++++++++++------ .../basemod/abstracts/CustomShopItem.java | 14 +- .../java/basemod/devcommands/shop/Shop.java | 2 +- .../basemod/devcommands/shop/ShopAddPage.java | 4 +- .../basemod/devcommands/shop/ShopAddRow.java | 25 ++-- .../devcommands/shop/ShopRemoveItem.java | 12 +- .../devcommands/shop/ShopRemovePage.java | 25 +++- .../shop/ShopScreen/ShopGridPatch.java | 24 ++-- 8 files changed, 150 insertions(+), 76 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index febb22e64..40f0abebd 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -24,6 +24,8 @@ public class ShopGrid { public static final String DEFAULT_PAGE_ID = "basemod"; + private static int pageIdCounter = 0; + public static int defaultPageRows = 2; public static int defaultPageCols = 3; @@ -42,7 +44,10 @@ public class ShopGrid { // this list has the pages for the remaining items that were added and the initial shop items public static LinkedList pages = new LinkedList<>(); - public static Page currentPage; + // used for when the shop grid is empty + public static final Page EMPTY_SHOP_PAGE = new Page(); + + private static Page currentPage; public static NavButton leftArrow; @@ -57,6 +62,19 @@ public static void initialize() { leftArrow = new NavButton(false); } + public static Page getCurrentPage() { + if (currentPage == null || (pages.isEmpty() && customPages.isEmpty())) + return EMPTY_SHOP_PAGE; + return currentPage; + } + + public static void setCurrentPage(Page page) { + if (page == null) + currentPage = EMPTY_SHOP_PAGE; + else + currentPage = page; + } + public static Page addEmptyPage() { Page page = new Page(); pages.addLast(page); @@ -72,6 +90,12 @@ public static Page addDefaultPage() { return page; } + public static Page addPage(int ... rowSizes) { + Page page = new Page(rowSizes); + pages.addLast(page); + return page; + } + public static Page addCustomPage(String modId, int ... rowSizes) { Page page = new Page(modId, rowSizes); customPages.addLast(page); @@ -82,7 +106,7 @@ public static boolean removePage(Page page) { if (page == currentPage) { currentPage = page.getNextPage(); if (currentPage == page) - currentPage = null; + currentPage = addEmptyPage(); } if (pages.contains(page)) return pages.remove(page); @@ -91,9 +115,19 @@ else if (customPages.contains(page)) return false; } - public static boolean removePage(String modId) { + public static boolean removePage(int idx) { + Page page = pages.get(idx); + if (page != null) + return removePage(page); + return false; + } + + public static boolean removePage(String pageId) { + for (Page page : pages) + if (page.id.equals(pageId)) + return removePage(page); for (Page page : customPages) - if (page.id.equals(modId)) + if (page.id.equals(pageId)) return removePage(page); return false; } @@ -124,29 +158,27 @@ public static float gridHeight() { } public static void removeEmptyPages() { - BaseMod.logger.info("HERE"); - Page previousPage = currentPage.getPreviousPage(); + Page previousPage = null; + if (currentPage != null) + previousPage = currentPage.getPreviousPage(); pages.removeIf((page) -> page.isEmpty()); customPages.removeIf((page) -> page.isEmpty()); if (!pages.contains(currentPage) && !customPages.contains(currentPage)) currentPage = previousPage; + else if (currentPage == previousPage) + currentPage = EMPTY_SHOP_PAGE; } public static void hide() { - currentPage.hide(); + if (currentPage != null) + currentPage.hide(); leftArrow.hide(); rightArrow.hide(); } - // dandy-TODO - // public static void show() { - // currentPage.show(); - // leftArrow.show(); - // rightArrow.show(); - // } - public static void update(float rugY) { - currentPage.update(rugY); + if (currentPage != null) + currentPage.update(rugY); } public static void render(SpriteBatch sb, float rugY) { @@ -154,12 +186,25 @@ public static void render(SpriteBatch sb, float rugY) { sb.setColor(Color.RED); sb.draw(ImageMaster.DEBUG_HITBOX_IMG, leftEdge, rugY + bottomEdge, gridWidth(), gridHeight()); } - currentPage.render(sb); + if (currentPage != null) + currentPage.render(sb); + } + + public static boolean isEmpty() { + if (getCurrentPage() == EMPTY_SHOP_PAGE) + return true; + for (Page page : pages) + if (!page.isEmpty()) + return false; + for (Page page : customPages) + if (!page.isEmpty()) + return false; + return true; } public static class Page { - public String id = DEFAULT_PAGE_ID; + public String id; public ArrayList rows = new ArrayList(); @@ -167,10 +212,13 @@ public Page(int ... rowSizes) { for (int i = 0; i < rowSizes.length; i++) { rows.add(new Row(this, i, rowSizes[i])); } + this.id = DEFAULT_PAGE_ID + ++pageIdCounter; } public Page(String id, int ... rowSizes) { - this(rowSizes); + for (int i = 0; i < rowSizes.length; i++) { + rows.add(new Row(this, i, rowSizes[i])); + } this.id = id; } @@ -281,23 +329,27 @@ public Page getNextPage() { return currentPage; } - public boolean contains(String id) { + public boolean contains(CustomShopItem item) { for (Row row : rows) - for (CustomShopItem item : row.items) { - if ((item.storePotion != null && item.storePotion.potion.ID.equals(id)) - || (item.storeRelic != null && item.storeRelic.relic.relicId.equals(id)) - || (item.id.equals(id))) - return true; - } + if (row.items.contains(item)) + return true; return false; } public boolean contains (StoreRelic relic) { - return contains(relic.relic.relicId); + for (Row row : rows) + for (CustomShopItem item : row.items) + if (relic == item.storeRelic) + return true; + return false; } public boolean contains(StorePotion potion) { - return contains(potion.potion.ID); + for (Row row : rows) + for (CustomShopItem item : row.items) + if (potion == item.storePotion) + return true; + return false; } } @@ -323,7 +375,7 @@ public float getX(int col) { } public float getY(int row, float rugY) { - return rugY + (topEdge - ((row + 1F) / (owner.rows.size() + 1F) + gridHeight())) - (gridHeight() * 0.2F); + return rugY + (topEdge - ((row + 1F) / (owner.rows.size() + 1F) * gridHeight())); } @SuppressWarnings("unchecked") @@ -408,19 +460,15 @@ else if (!forward && curIdx > 0) } public void render(SpriteBatch sb) { - sb.setColor(Color.WHITE); int curIdx = pages.indexOf(currentPage); - if (!forward && curIdx > 0) { + if (((!forward && curIdx > 0) || (forward && curIdx < pages.size() - 1))) { + sb.setColor(Color.WHITE); TextureRegion region = new TextureRegion(texture); + if (forward) + region.flip(true, false); sb.draw(region, x - 96.0F * Settings.scale, y - 96.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); hb.render(sb); } - if (forward && curIdx < pages.size() - 1) { - TextureRegion flippedRegion = new TextureRegion(texture); - flippedRegion.flip(true, false); - sb.draw(flippedRegion, x - 96.0F * Settings.scale, y - 96.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); - hb.render(sb); - } } public void hide() { diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index dc7815405..c30b1f0a8 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -26,8 +26,6 @@ public class CustomShopItem { - public String id; - public ShopScreen screenRef; public ShopGrid.Row gridRow; public StoreRelic storeRelic; @@ -63,7 +61,6 @@ public CustomShopItem(AbstractPotion potion) { public CustomShopItem(StoreRelic storeRelic) { if (storeRelic.relic != null) { this.storeRelic = storeRelic; - this.id = ShopGrid.DEFAULT_PAGE_ID + ":" + storeRelic.relic.relicId; } else { BaseMod.logger.error("StoreRelic cannot have a null relic"); } @@ -72,7 +69,6 @@ public CustomShopItem(StoreRelic storeRelic) { public CustomShopItem(StorePotion storePotion) { if (storePotion.potion != null) { this.storePotion = storePotion; - this.id = ShopGrid.DEFAULT_PAGE_ID + ":" + storePotion.potion.ID; } else { BaseMod.logger.error("StorePotion cannot have a null potion"); } @@ -122,7 +118,7 @@ public void update(float rugY) { public void render(SpriteBatch sb) { if (!this.isPurchased) { - if (storeRelic == null && storePotion == null && ShopGrid.currentPage.contains(id)) { + if (storeRelic == null && storePotion == null) { sb.setColor(Color.WHITE); // assumes the size of a relic image sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); @@ -147,12 +143,10 @@ public void hide() { if (storeRelic != null && storeRelic.relic != null) { this.storeRelic.hide(); this.y = storeRelic.relic.currentY; - } - else if (storePotion != null && storePotion.potion != null) { + } else if (storePotion != null && storePotion.potion != null) { this.storePotion.hide(); this.y = storePotion.potion.posY; - } - else { + } else { this.y = Settings.HEIGHT + 200.0F * Settings.scale; } } @@ -160,7 +154,7 @@ else if (storePotion != null && storePotion.potion != null) { protected void attemptPurchase() { if (!this.isPurchased && this.storePotion == null && this.storeRelic == null) { - if (AbstractDungeon.player.gold >= this.price){ + if (AbstractDungeon.player.gold >= this.price) { purchase(); } else { this.screenRef.playCantBuySfx(); diff --git a/mod/src/main/java/basemod/devcommands/shop/Shop.java b/mod/src/main/java/basemod/devcommands/shop/Shop.java index 284cce05f..58213200d 100644 --- a/mod/src/main/java/basemod/devcommands/shop/Shop.java +++ b/mod/src/main/java/basemod/devcommands/shop/Shop.java @@ -27,6 +27,6 @@ public static void cmdShopHelp() { DevConsole.log("* add relic [id]"); DevConsole.log("* add row [id] [id] ..."); DevConsole.log("* remove item [row] [col]"); - DevConsole.log("* remove page"); + DevConsole.log("* remove page [id]"); } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java index 246eac1dd..ac391d4e6 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java @@ -26,14 +26,14 @@ protected void execute(String[] tokens, int depth) { if (tokens.length == 3) { ShopGrid.Page page = ShopGrid.addDefaultPage(); while (page.tryAddItem(ShopAdd.randomItem())); - ShopGrid.currentPage = page; + ShopGrid.setCurrentPage(page); } else { ShopGrid.Page page = ShopGrid.addEmptyPage(); try { for (int i = 3; i < tokens.length; i++) page.addRow(Integer.parseInt(tokens[i])); while (page.tryAddItem(ShopAdd.randomItem())); - ShopGrid.currentPage = page; + ShopGrid.setCurrentPage(page); } catch (NumberFormatException nfe) { nfe.printStackTrace(); Shop.cmdShopHelp(); diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java index 39c5fbe6e..21db0e906 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Comparator; +import basemod.DevConsole; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; @@ -33,15 +34,23 @@ public void errorMsg() { @Override protected void execute(String[] tokens, int depth) { if (tokens.length == 3) { - ShopGrid.Row row = ShopGrid.currentPage.addRow(); - while (row.tryAddItem(ShopAdd.randomItem())); + if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { + ShopGrid.Row row = ShopGrid.getCurrentPage().addRow(); + while (row.tryAddItem(ShopAdd.randomItem())); + } else { + DevConsole.log("no page to add a row to"); + } } else { - ArrayList items = new ArrayList(); - for (int i = 3; i < tokens.length; i++) - items.add(ShopAdd.itemFromId(tokens[i])); - ShopGrid.Row row = ShopGrid.currentPage.addRow(items.size()); - for (CustomShopItem item : items) - row.tryAddItem(item); + if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { + ArrayList items = new ArrayList(); + for (int i = 3; i < tokens.length; i++) + items.add(ShopAdd.itemFromId(tokens[i])); + ShopGrid.Row row = ShopGrid.getCurrentPage().addRow(items.size()); + for (CustomShopItem item : items) + row.tryAddItem(item); + } else { + DevConsole.log("no page to add a row to"); + } } } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java index 67fb85085..0acf9b7f8 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java @@ -20,13 +20,15 @@ public ShopRemoveItem() { public ArrayList extraOptions(String[] tokens, int depth) { ArrayList opts = new ArrayList<>(); if (tokens.length == 3) { - for (int i = 0; i < ShopGrid.currentPage.rows.size(); i++) - opts.add(String.valueOf(i)); + if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { + for (int i = 0; i < ShopGrid.getCurrentPage().rows.size(); i++) + opts.add(String.valueOf(i)); + } } else { try { int row = Integer.parseInt(tokens[3]); - for (int i = 0; i < ShopGrid.currentPage.rows.get(row).maxColumns; i++) + for (int i = 0; i < ShopGrid.getCurrentPage().rows.get(row).maxColumns; i++) opts.add(String.valueOf(i)); } catch (NumberFormatException nfe) { nfe.printStackTrace(); @@ -46,13 +48,13 @@ protected void execute(String[] tokens, int depth) { try { int row = Integer.parseInt(tokens[3]); if (tokens.length == 4) { - Iterator it = ShopGrid.currentPage.rows.get(row).items.iterator(); + Iterator it = ShopGrid.getCurrentPage().rows.get(row).items.iterator(); while (it.hasNext()) { it.remove(); } } else { int col = Integer.parseInt(tokens[4]); - ShopGrid.currentPage.rows.get(row).items.remove(col); + ShopGrid.getCurrentPage().rows.get(row).items.remove(col); } } catch(NumberFormatException nfe) { nfe.printStackTrace(); diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java index 122ef8c6a..806e63b85 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java @@ -1,5 +1,8 @@ package basemod.devcommands.shop; +import java.util.ArrayList; +import java.util.Comparator; + import basemod.DevConsole; import basemod.ShopGrid; import basemod.devcommands.ConsoleCommand; @@ -9,10 +12,21 @@ public class ShopRemovePage extends ConsoleCommand { public ShopRemovePage() { requiresPlayer = true; minExtraTokens = 0; - maxExtraTokens = 0; + maxExtraTokens = 1; simpleCheck = true; } + @Override + public ArrayList extraOptions(String[] tokens, int depth) { + ArrayList opts = new ArrayList<>(); + for (ShopGrid.Page page : ShopGrid.pages) + opts.add(page.id); + for (ShopGrid.Page page : ShopGrid.customPages) + opts.add(page.id); + opts.sort(Comparator.comparing(String::toString)); + return opts; + } + @Override public void errorMsg() { Shop.cmdShopHelp(); @@ -20,7 +34,12 @@ public void errorMsg() { @Override protected void execute(String[] tokens, int depth) { - if (!ShopGrid.removePage(ShopGrid.currentPage)) - DevConsole.log("could not remove page"); + if (tokens.length == 3) { + if (!ShopGrid.removePage(ShopGrid.getCurrentPage())) + DevConsole.log("could not remove current page"); + } else { + if (!ShopGrid.removePage(tokens[3])) + DevConsole.log("could not remove page with id " + tokens[3]); + } } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 95a893180..c84bd4e08 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -47,7 +47,7 @@ public static class ShopScreenOpen { @SpirePostfixPatch public static void HideGridOnOpen() { - if (!ShopGrid.currentPage.isEmpty()) { + if (!ShopGrid.getCurrentPage().isEmpty()) { ShopGrid.hide(); } } @@ -124,13 +124,13 @@ public static class SetCoords { public static SpireReturn Insert(StoreRelic __instance, float rugY) { if (__instance.relic != null) { // dandy-TODO: for compatibility, add check to see if relic/potion was added to grid, otherwise continue - for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) if (item.storeRelic == __instance) { - if (gridRow.owner.rows.size() != 2) { + if (gridRow.owner.rows.size() > 2) { __instance.relic.currentY = gridRow.getY(item.row, rugY); } else { - __instance.relic.currentY = rugY + (item.row == 0 ? 200F : 400F) * Settings.xScale; + __instance.relic.currentY = rugY + (item.row == 0 ? 400F : 200F) * Settings.xScale; } __instance.relic.currentX = gridRow.getX(item.col); return SpireReturn.Continue(); @@ -154,7 +154,7 @@ public static class PurchaseRelic { @SpirePostfixPatch public static void RemoveRelic(StoreRelic __instance) { if (__instance.isPurchased) { - for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storeRelic == __instance) { item.storeRelic.relic = null; @@ -175,7 +175,7 @@ public static class Render { @SpirePrefixPatch public static SpireReturn CheckIfRelicInCurrentPage(StoreRelic __instance, SpriteBatch sb) { - if (__instance.relic != null && !ShopGrid.currentPage.contains(__instance)) { + if (__instance.relic != null && !ShopGrid.getCurrentPage().contains(__instance)) { return SpireReturn.Return(); } return SpireReturn.Continue(); @@ -191,13 +191,13 @@ public static class Update { @SpireInsertPatch(locator = HBMoveLocator.class) public static SpireReturn SetCoords(StorePotion __instance, float rugY) { if (__instance.potion != null) { // dandy-TODO: for compatibility, add check to see if relic/potion was added to grid, otherwise continue - for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { - if (gridRow.owner.rows.size() != 2) { + if (gridRow.owner.rows.size() > 2) { __instance.potion.posY = gridRow.getY(item.row, rugY); } else { - __instance.potion.posY = rugY + (item.row == 0 ? 200F : 400F) * Settings.xScale; + __instance.potion.posY = rugY + (item.row == 0 ? 400F : 200F) * Settings.xScale; } __instance.potion.posX = gridRow.getX(item.col); return SpireReturn.Continue(); @@ -221,12 +221,14 @@ public int[] Locate(CtBehavior ctb) throws Exception { public static class PurchasePotion { public static void Postfix(StorePotion __instance) { if (__instance.isPurchased) { - for (ShopGrid.Row gridRow : ShopGrid.currentPage.rows) + for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { item.storePotion.potion = null; item.storePotion = null; item.isPurchased = true; + + ShopGrid.removeEmptyPages(); break; } } @@ -240,7 +242,7 @@ public static class Render { @SpirePrefixPatch public static SpireReturn CheckIfPotionInCurrentPage(StorePotion __instance, SpriteBatch sb) { - if (__instance.potion != null && !ShopGrid.currentPage.contains(__instance)) { + if (__instance.potion != null && !ShopGrid.getCurrentPage().contains(__instance)) { return SpireReturn.Return(); } return SpireReturn.Continue(); From 99c3497cddc44649a99bcdbc03421876e7b8eb3d Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sun, 21 Jan 2024 17:08:47 -0500 Subject: [PATCH 16/23] modify text and gold rendering so it looks better --- mod/src/main/java/basemod/ShopGrid.java | 31 +++- .../basemod/abstracts/CustomShopItem.java | 2 + .../shop/ShopScreen/ShopGridPatch.java | 164 ++++++++++++++++++ 3 files changed, 190 insertions(+), 7 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 40f0abebd..d4bbbef0e 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -22,7 +22,7 @@ public class ShopGrid { - public static final String DEFAULT_PAGE_ID = "basemod"; + public static final String DEFAULT_PAGE_ID = "basemod:"; private static int pageIdCounter = 0; @@ -34,7 +34,7 @@ public class ShopGrid { public static float leftEdge = Settings.WIDTH * 0.44F; - public static float topEdge = Settings.HEIGHT * 0.44F; + public static float topEdge = Settings.HEIGHT * 0.48F; public static float bottomEdge = Settings.HEIGHT * 0.075F; @@ -44,7 +44,7 @@ public class ShopGrid { // this list has the pages for the remaining items that were added and the initial shop items public static LinkedList pages = new LinkedList<>(); - // used for when the shop grid is empty + // used for when the shop grid is empty, will always have id of basemod:1 and cannot be removed public static final Page EMPTY_SHOP_PAGE = new Page(); private static Page currentPage; @@ -60,6 +60,7 @@ public static void initialize() { currentPage = addDefaultPage(); rightArrow = new NavButton(true); leftArrow = new NavButton(false); + pageIdCounter = 0; } public static Page getCurrentPage() { @@ -106,7 +107,7 @@ public static boolean removePage(Page page) { if (page == currentPage) { currentPage = page.getNextPage(); if (currentPage == page) - currentPage = addEmptyPage(); + currentPage = EMPTY_SHOP_PAGE; } if (pages.contains(page)) return pages.remove(page); @@ -138,14 +139,13 @@ public static boolean tryAddItem(CustomShopItem item) { return true; Page page = addDefaultPage(); - pages.addLast(page); return page.tryAddItem(item); } public static boolean tryAddItemToCustomPage(String id, CustomShopItem item) { for (Page customPage : customPages) - if (customPage.id.equals(id) && customPage.tryAddItem(item)) - return true; + if (customPage.id.equals(id)) + return customPage.tryAddItem(item); return false; } @@ -351,6 +351,22 @@ public boolean contains(StorePotion potion) { return true; return false; } + + public CustomShopItem getItem(StorePotion potion) { + for (Row row : rows) + for (CustomShopItem item : row.items) + if (potion == item.storePotion) + return item; + return null; + } + + public CustomShopItem getItem(StoreRelic relic) { + for (Row row : rows) + for (CustomShopItem item : row.items) + if (relic == item.storeRelic) + return item; + return null; + } } public static class Row { @@ -383,6 +399,7 @@ public boolean tryAddItem(CustomShopItem item) { if (items.size() < maxColumns) { item.row = rowNumber; item.col = items.size(); + item.gridRow = this; items.add(item); if (item.storeRelic != null) { ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index c30b1f0a8..072915879 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -26,6 +26,8 @@ public class CustomShopItem { + public String customShopId; + public ShopScreen screenRef; public ShopGrid.Row gridRow; public StoreRelic storeRelic; diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index c84bd4e08..ce29f7522 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -7,6 +7,7 @@ import com.evacipated.cardcrawl.modthespire.lib.Matcher; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; +import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch; import com.evacipated.cardcrawl.modthespire.lib.SpirePatch2; import com.evacipated.cardcrawl.modthespire.lib.SpirePostfixPatch; @@ -21,7 +22,10 @@ import basemod.BaseMod; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; +import javassist.CannotCompileException; import javassist.CtBehavior; +import javassist.expr.ExprEditor; +import javassist.expr.MethodCall; public class ShopGridPatch { @@ -180,6 +184,86 @@ public static SpireReturn CheckIfRelicInCurrentPage(StoreRelic __instance, } return SpireReturn.Continue(); } + + public static boolean canRender(StoreRelic instance) { + if (ShopGrid.getCurrentPage().contains(instance) + && ((ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 5) + || ShopGrid.getCurrentPage().rows.size() > 4)) + return false; + return true; + } + + public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { + if (!canRender(instance)) { + if (instance.relic.hb.hovered) { + // render the cost above the tooltips + } + return false; + } + return true; + } + + public static float goldY(StoreRelic instance, float yOffset) { + if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + return instance.relic.currentY - 75F * Settings.yScale; + return instance.relic.currentY + yOffset; + } + + @SpireInstrumentPatch + public static ExprEditor ChangeGoldPosition() { + return new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("draw")) { + m.replace("" + + "{" + + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.canRenderGold($0, this))" + + "sb.draw($1, $2, basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.goldY(this, RELIC_GOLD_OFFSET_Y), $4, $5);" + + "}" + ); + } + } + }; + } + + public static boolean canRenderText(SpriteBatch sb, StoreRelic instance) { + if (!canRender(instance)) { + if (instance.relic.hb.hovered) { + // render the text above the tooltips + } + return false; + } + return true; + } + + public static float textX(StoreRelic instance, float xOffset) { + if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 4) + return instance.relic.currentX + 3F * Settings.scale; + return instance.relic.currentX + xOffset; + } + + public static float textY(StoreRelic instance, float yOffset) { + if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + return instance.relic.currentY - 40F * Settings.scale; + return instance.relic.currentY + yOffset; + } + + @SpireInstrumentPatch + public static ExprEditor ChangeTextPosition() { + return new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("renderFontLeftTopAligned")) { + m.replace("" + + "{" + + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.canRenderText($1, this))" + + "com.megacrit.cardcrawl.helpers.FontHelper.renderFontLeftTopAligned($1, $2, $3, " + + "basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.textX(this, RELIC_PRICE_OFFSET_X), " + + "basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.textY(this, RELIC_PRICE_OFFSET_Y), $6);" + + "}" + ); + } + } + }; + } } } @@ -247,6 +331,86 @@ public static SpireReturn CheckIfPotionInCurrentPage(StorePotion __instanc } return SpireReturn.Continue(); } + + public static boolean canRender(StorePotion instance) { + if (ShopGrid.getCurrentPage().contains(instance) + && ((ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 5) + || ShopGrid.getCurrentPage().rows.size() > 4)) + return false; + return true; + } + + public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { + if (!canRender(instance)) { + if (instance.potion.hb.hovered) { + // render the cost above the tooltips + } + return false; + } + return true; + } + + public static float goldY(StorePotion instance, float yOffset) { + if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + return instance.potion.posY - 75F * Settings.yScale; + return instance.potion.posY + yOffset; + } + + @SpireInstrumentPatch + public static ExprEditor ChangeGoldPosition() { + return new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("draw")) { + m.replace("" + + "{" + + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.canRenderGold($0, this))" + + "sb.draw($1, $2, basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.goldY(this, RELIC_GOLD_OFFSET_Y), $4, $5);" + + "}" + ); + } + } + }; + } + + public static boolean canRenderText(SpriteBatch sb, StorePotion instance) { + if (!canRender(instance)) { + if (instance.potion.hb.hovered) { + // render the text above the tooltips + } + return false; + } + return true; + } + + public static float textX(StorePotion instance, float xOffset) { + if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 4) + return instance.potion.posX + 3F * Settings.scale; + return instance.potion.posX + xOffset; + } + + public static float textY(StorePotion instance, float yOffset) { + if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + return instance.potion.posY - 40F * Settings.scale; + return instance.potion.posY + yOffset; + } + + @SpireInstrumentPatch + public static ExprEditor ChangeTextPosition() { + return new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("renderFontLeftTopAligned")) { + m.replace("" + + "{" + + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.canRenderText($1, this))" + + "com.megacrit.cardcrawl.helpers.FontHelper.renderFontLeftTopAligned($1, $2, $3, " + + "basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.textX(this, RELIC_PRICE_OFFSET_X), " + + "basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.textY(this, RELIC_PRICE_OFFSET_Y), $6);" + + "}" + ); + } + } + }; + } } } } From 4b4262578a13e281cc350c6f0ec373383694942f Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sun, 21 Jan 2024 21:47:04 -0500 Subject: [PATCH 17/23] add price tag when grid is dense, fixed pricing --- mod/src/main/java/basemod/ShopGrid.java | 21 +++-- .../basemod/abstracts/CustomShopItem.java | 7 +- .../shop/ShopScreen/ShopGridPatch.java | 93 +++++++++++++++---- 3 files changed, 95 insertions(+), 26 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index d4bbbef0e..cccc2349c 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -44,7 +44,7 @@ public class ShopGrid { // this list has the pages for the remaining items that were added and the initial shop items public static LinkedList pages = new LinkedList<>(); - // used for when the shop grid is empty, will always have id of basemod:1 and cannot be removed + // used for when the shop grid is empty, will always have id of basemod:0 and cannot be removed public static final Page EMPTY_SHOP_PAGE = new Page(); private static Page currentPage; @@ -57,10 +57,10 @@ public class ShopGrid { public static void initialize() { pages.clear(); + pageIdCounter = 0; currentPage = addDefaultPage(); rightArrow = new NavButton(true); leftArrow = new NavButton(false); - pageIdCounter = 0; } public static Page getCurrentPage() { @@ -212,7 +212,7 @@ public Page(int ... rowSizes) { for (int i = 0; i < rowSizes.length; i++) { rows.add(new Row(this, i, rowSizes[i])); } - this.id = DEFAULT_PAGE_ID + ++pageIdCounter; + this.id = DEFAULT_PAGE_ID + pageIdCounter++; } public Page(String id, int ... rowSizes) { @@ -232,7 +232,7 @@ public void update(float rugY) { row.update(rugY); leftArrow.update(rugY); rightArrow.update(rugY); - pageY = rugY + 500.0F * Settings.yScale; + pageY = rugY + 510.0F * Settings.yScale; } public void render(SpriteBatch sb) { @@ -402,11 +402,18 @@ public boolean tryAddItem(CustomShopItem item) { item.gridRow = this; items.add(item); if (item.storeRelic != null) { + if (item.applyDiscounts) { + item.applyDiscounts(item.storeRelic.price); + item.storeRelic.price = item.price; + } ArrayList relics = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "relics"); if (!relics.contains(item.storeRelic)) relics.add(item.storeRelic); - } - if (item.storePotion != null) { + } else if (item.storePotion != null) { + if (item.applyDiscounts) { + item.applyDiscounts(item.storePotion.price); + item.storePotion.price = item.price; + } ArrayList potions = (ArrayList)ReflectionHacks.getPrivate(AbstractDungeon.shopScreen, ShopScreen.class, "potions"); if (!potions.contains(item.storePotion)) potions.add(item.storePotion); @@ -483,7 +490,7 @@ public void render(SpriteBatch sb) { TextureRegion region = new TextureRegion(texture); if (forward) region.flip(true, false); - sb.draw(region, x - 96.0F * Settings.scale, y - 96.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + sb.draw(region, x - 96.0F * Settings.scale, y - 86.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); hb.render(sb); } } diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 072915879..a479547c8 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -46,6 +46,8 @@ public class CustomShopItem { public boolean isPurchased = false; + public boolean applyDiscounts = true; + private static final float GOLD_IMG_WIDTH = ReflectionHacks.getPrivateStatic(StoreRelic.class, "GOLD_IMG_WIDTH"); private static final float GOLD_OFFSET_X = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_GOLD_OFFSET_X"); private static final float GOLD_OFFSET_Y = ReflectionHacks.getPrivateStatic(StoreRelic.class, "RELIC_GOLD_OFFSET_Y"); @@ -63,6 +65,7 @@ public CustomShopItem(AbstractPotion potion) { public CustomShopItem(StoreRelic storeRelic) { if (storeRelic.relic != null) { this.storeRelic = storeRelic; + this.price = storeRelic.price; } else { BaseMod.logger.error("StoreRelic cannot have a null relic"); } @@ -71,6 +74,7 @@ public CustomShopItem(StoreRelic storeRelic) { public CustomShopItem(StorePotion storePotion) { if (storePotion.potion != null) { this.storePotion = storePotion; + this.price = storePotion.price; } else { BaseMod.logger.error("StorePotion cannot have a null potion"); } @@ -91,11 +95,12 @@ public CustomShopItem(String modId, ShopScreen screenRef, Texture img, int price public void applyDiscounts(int price) { float mult = 1F; - for (AbstractRelic relic : AbstractDungeon.player.relics) + for (AbstractRelic relic : AbstractDungeon.player.relics) { if (relic.relicId.equals(Courier.ID)) mult *= 0.8F; else if (relic.relicId.equals(MembershipCard.ID)) mult *= 0.5F; + } this.price = (int)(mult * price); } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index ce29f7522..24d703bcc 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -2,6 +2,7 @@ import java.util.ArrayList; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.evacipated.cardcrawl.modthespire.lib.LineFinder; import com.evacipated.cardcrawl.modthespire.lib.Matcher; @@ -14,12 +15,16 @@ import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch; import com.evacipated.cardcrawl.modthespire.lib.SpireReturn; import com.megacrit.cardcrawl.core.Settings; +import com.megacrit.cardcrawl.helpers.FontHelper; import com.megacrit.cardcrawl.helpers.Hitbox; +import com.megacrit.cardcrawl.helpers.ImageMaster; +import com.megacrit.cardcrawl.helpers.TipHelper; import com.megacrit.cardcrawl.shop.ShopScreen; import com.megacrit.cardcrawl.shop.StorePotion; import com.megacrit.cardcrawl.shop.StoreRelic; import basemod.BaseMod; +import basemod.ReflectionHacks; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; import javassist.CannotCompileException; @@ -29,6 +34,49 @@ public class ShopGridPatch { + private static final float GOLD_IMG_WIDTH = ImageMaster.UI_GOLD.getWidth() * Settings.scale; + + private static final float SHADOW_DIST_X = 4F * Settings.scale; + + private static final float SHADOW_DIST_Y = 4F * Settings.scale; + + private static final float BOX_W = 100F * Settings.scale; + + private static final float OFFSET_X = -50F * Settings.scale; + + private static final float OFFSET_Y = -78F * Settings.scale; + + private static final float TEXT_OFFSET_X = -16F * Settings.scale; + + private static final float TEXT_OFFSET_Y = 16F * Settings.scale; + + private static final float RELIC_GOLD_OFFSET_X = -57F * Settings.scale; + + private static final float RELIC_GOLD_OFFSET_Y = -102F * Settings.scale; + + private static boolean hoveringItem = false; + + private static float x; + + private static float y; + + private static int price; + + public static void renderPrice(SpriteBatch sb) { + final float BOX_EDGE_H = ReflectionHacks.getPrivateStatic(TipHelper.class, "BOX_EDGE_H"); + final float TIP_DESC_LINE_SPACING = ReflectionHacks.getPrivateStatic(TipHelper.class, "TIP_DESC_LINE_SPACING"); + final Color BASE_COLOR = ReflectionHacks.getPrivateStatic(TipHelper.class, "BASE_COLOR"); + float h = FontHelper.getHeight(FontHelper.tipBodyFont, Integer.toString(price), 1F); + sb.setColor(Settings.TOP_PANEL_SHADOW_COLOR); + sb.draw(ImageMaster.KEYWORD_TOP, x + OFFSET_X + SHADOW_DIST_X, y + OFFSET_Y - SHADOW_DIST_Y, BOX_W, BOX_EDGE_H); + sb.draw(ImageMaster.KEYWORD_BOT, x + OFFSET_X + SHADOW_DIST_X, y + OFFSET_Y - h - SHADOW_DIST_Y, BOX_W, BOX_EDGE_H + Math.min(h, 0F)); + sb.setColor(Color.WHITE); + sb.draw(ImageMaster.KEYWORD_TOP, x + OFFSET_X, y + OFFSET_Y, BOX_W, BOX_EDGE_H); + sb.draw(ImageMaster.KEYWORD_BOT, x + OFFSET_X, y + OFFSET_Y - h, BOX_W, BOX_EDGE_H); + sb.draw(ImageMaster.UI_GOLD, x + RELIC_GOLD_OFFSET_X, y + RELIC_GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); + FontHelper.renderSmartText(sb, FontHelper.tipBodyFont, Integer.toString(price), x + TEXT_OFFSET_X + OFFSET_X + GOLD_IMG_WIDTH, y + TEXT_OFFSET_Y + OFFSET_Y, BOX_W, TIP_DESC_LINE_SPACING, BASE_COLOR); + } + @SpirePatch2(clz = ShopScreen.class, method = SpirePatch.CLASS) public static class ShopScreenPatches { @@ -62,7 +110,9 @@ public static class InitRelics { @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) public static void AddGridRelic(StoreRelic relic) { - if (!ShopGrid.tryAddItem(new CustomShopItem(relic))) + CustomShopItem item = new CustomShopItem(relic); + item.applyDiscounts = false; + if (!ShopGrid.tryAddItem(item)) BaseMod.logger.warn("not adding default shop relic because grid is full, is this intentional?"); } @@ -80,7 +130,9 @@ public static class PostInitPotions { @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" }) public static void AddGridPotion(StorePotion potion) { - if (!ShopGrid.tryAddItem(new CustomShopItem(potion))) + CustomShopItem item = new CustomShopItem(potion); + item.applyDiscounts = false; + if (!ShopGrid.tryAddItem(item)) BaseMod.logger.warn("not adding default potion because grid is full, is this intentional?"); } @@ -105,6 +157,17 @@ public static void UpdateGrid(float ___rugY) { @SpirePatch2(clz = ShopScreen.class, method = "render") public static class Render { + @SpirePrefixPatch + public static void ResetHoveringItem() { + hoveringItem = false; + } + + @SpirePostfixPatch + public static void RenderItemPrice(SpriteBatch sb) { + if (hoveringItem) + renderPrice(sb); + } + @SpireInsertPatch(locator = RenderRelicsLocator.class) public static void RenderGrid(SpriteBatch sb, float ___rugY) { ShopGrid.render(sb, ___rugY); @@ -196,7 +259,10 @@ public static boolean canRender(StoreRelic instance) { public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { if (!canRender(instance)) { if (instance.relic.hb.hovered) { - // render the cost above the tooltips + hoveringItem = true; + x = instance.relic.currentX; + y = instance.relic.currentY; + price = instance.price; } return false; } @@ -226,13 +292,7 @@ public void edit(MethodCall m) throws CannotCompileException { } public static boolean canRenderText(SpriteBatch sb, StoreRelic instance) { - if (!canRender(instance)) { - if (instance.relic.hb.hovered) { - // render the text above the tooltips - } - return false; - } - return true; + return canRender(instance); } public static float textX(StoreRelic instance, float xOffset) { @@ -343,7 +403,10 @@ public static boolean canRender(StorePotion instance) { public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { if (!canRender(instance)) { if (instance.potion.hb.hovered) { - // render the cost above the tooltips + hoveringItem = true; + x = instance.potion.posX; + y = instance.potion.posY; + price = instance.price; } return false; } @@ -373,13 +436,7 @@ public void edit(MethodCall m) throws CannotCompileException { } public static boolean canRenderText(SpriteBatch sb, StorePotion instance) { - if (!canRender(instance)) { - if (instance.potion.hb.hovered) { - // render the text above the tooltips - } - return false; - } - return true; + return canRender(instance); } public static float textX(StorePotion instance, float xOffset) { From c0dd53b00af83a3dc04900e19553ae8b6d7845b0 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Mon, 22 Jan 2024 02:21:38 -0500 Subject: [PATCH 18/23] fix up commands, disable patches for incompatible potions/relics --- mod/src/main/java/basemod/ShopGrid.java | 4 +- .../basemod/abstracts/CustomShopItem.java | 3 ++ .../java/basemod/devcommands/shop/Shop.java | 2 +- .../basemod/devcommands/shop/ShopAdd.java | 2 +- .../basemod/devcommands/shop/ShopAddPage.java | 3 +- .../devcommands/shop/ShopAddPotion.java | 2 +- .../devcommands/shop/ShopAddRelic.java | 6 +-- .../basemod/devcommands/shop/ShopAddRow.java | 35 ++++++---------- .../devcommands/shop/ShopRemoveItem.java | 11 +++-- .../devcommands/shop/ShopRemovePage.java | 1 + .../shop/ShopScreen/ShopGridPatch.java | 42 +++++++++++-------- 11 files changed, 59 insertions(+), 52 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index cccc2349c..4c5212c44 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -57,7 +57,7 @@ public class ShopGrid { public static void initialize() { pages.clear(); - pageIdCounter = 0; + pageIdCounter = 1; currentPage = addDefaultPage(); rightArrow = new NavButton(true); leftArrow = new NavButton(false); @@ -104,6 +104,8 @@ public static Page addCustomPage(String modId, int ... rowSizes) { } public static boolean removePage(Page page) { + if (page == EMPTY_SHOP_PAGE) + return false; if (page == currentPage) { currentPage = page.getNextPage(); if (currentPage == page) diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index a479547c8..847014740 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -3,6 +3,7 @@ import basemod.BaseMod; import basemod.ReflectionHacks; import basemod.ShopGrid; +import basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; @@ -64,6 +65,7 @@ public CustomShopItem(AbstractPotion potion) { public CustomShopItem(StoreRelic storeRelic) { if (storeRelic.relic != null) { + ShopGridPatch.StoreRelicPatches.compatibleWithGrid.set(storeRelic, true); this.storeRelic = storeRelic; this.price = storeRelic.price; } else { @@ -73,6 +75,7 @@ public CustomShopItem(StoreRelic storeRelic) { public CustomShopItem(StorePotion storePotion) { if (storePotion.potion != null) { + ShopGridPatch.StorePotionPatches.compatibleWithGrid.set(storePotion, true); this.storePotion = storePotion; this.price = storePotion.price; } else { diff --git a/mod/src/main/java/basemod/devcommands/shop/Shop.java b/mod/src/main/java/basemod/devcommands/shop/Shop.java index 58213200d..0dcd39a19 100644 --- a/mod/src/main/java/basemod/devcommands/shop/Shop.java +++ b/mod/src/main/java/basemod/devcommands/shop/Shop.java @@ -25,7 +25,7 @@ public static void cmdShopHelp() { DevConsole.log("* add page [row size] [row size] ..."); DevConsole.log("* add potion [id]"); DevConsole.log("* add relic [id]"); - DevConsole.log("* add row [id] [id] ..."); + DevConsole.log("* add row [size]"); DevConsole.log("* remove item [row] [col]"); DevConsole.log("* remove page [id]"); } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java index c6171a615..1dc54405d 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAdd.java @@ -33,7 +33,7 @@ public static ArrayList allPotions() { public static CustomShopItem randomItem() { if (AbstractDungeon.miscRng.randomBoolean()) - return new CustomShopItem(AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier())); + return new CustomShopItem(AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier()).makeCopy()); else return new CustomShopItem(AbstractDungeon.returnRandomPotion()); } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java index ac391d4e6..2186c46c4 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPage.java @@ -17,7 +17,8 @@ public ShopAddPage() { @Override public ArrayList extraOptions(String[] tokens, int depth) { ArrayList opts = new ArrayList(); - opts.add("3"); + for (int i = 1; i < 10; i++) + opts.add(Integer.toString(i)); return opts; } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java index 49687012c..7f9bcbc3c 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddPotion.java @@ -16,7 +16,7 @@ public class ShopAddPotion extends ConsoleCommand { public ShopAddPotion() { requiresPlayer = true; minExtraTokens = 0; - minExtraTokens = 1; + maxExtraTokens = 1; simpleCheck = true; } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java index 989f6eb35..df2f9da5c 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddRelic.java @@ -16,7 +16,7 @@ public class ShopAddRelic extends ConsoleCommand { public ShopAddRelic() { requiresPlayer = true; minExtraTokens = 0; - minExtraTokens = 1; + maxExtraTokens = 1; simpleCheck = true; } @@ -34,9 +34,9 @@ public void errorMsg() { protected void execute(String[] tokens, int depth) { AbstractRelic relic; if (tokens.length == 3) - relic = AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier()); + relic = AbstractDungeon.returnRandomRelic(AbstractDungeon.returnRandomRelicTier()).makeCopy(); else - relic = RelicLibrary.getRelic(tokens[3]); + relic = RelicLibrary.getRelic(tokens[3]).makeCopy(); if (!ShopGrid.tryAddItem(new CustomShopItem(relic))) DevConsole.log("could not add " + relic.relicId + " to shop grid"); } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java b/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java index 21db0e906..6bed382e3 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopAddRow.java @@ -1,28 +1,24 @@ package basemod.devcommands.shop; import java.util.ArrayList; -import java.util.Comparator; - import basemod.DevConsole; import basemod.ShopGrid; -import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; public class ShopAddRow extends ConsoleCommand { public ShopAddRow() { requiresPlayer = true; - minExtraTokens = 0; - minExtraTokens = 9; + minExtraTokens = 1; + maxExtraTokens = 1; simpleCheck = true; } @Override public ArrayList extraOptions(String[] tokens, int depth) { ArrayList opts = new ArrayList(); - opts.addAll(ShopAdd.allPotions()); - opts.addAll(ConsoleCommand.getRelicOptions()); - opts.sort(Comparator.comparing(String::toString)); + for (int i = 0; i < 10; i++) + opts.add(Integer.toString(i)); return opts; } @@ -33,24 +29,17 @@ public void errorMsg() { @Override protected void execute(String[] tokens, int depth) { - if (tokens.length == 3) { - if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { - ShopGrid.Row row = ShopGrid.getCurrentPage().addRow(); + if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { + try { + int size = Integer.parseInt(tokens[3]); + ShopGrid.Row row = ShopGrid.getCurrentPage().addRow(size); while (row.tryAddItem(ShopAdd.randomItem())); - } else { - DevConsole.log("no page to add a row to"); + } catch (NumberFormatException nfe) { + nfe.printStackTrace(); + Shop.cmdShopHelp(); } } else { - if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { - ArrayList items = new ArrayList(); - for (int i = 3; i < tokens.length; i++) - items.add(ShopAdd.itemFromId(tokens[i])); - ShopGrid.Row row = ShopGrid.getCurrentPage().addRow(items.size()); - for (CustomShopItem item : items) - row.tryAddItem(item); - } else { - DevConsole.log("no page to add a row to"); - } + DevConsole.log("no page to add a row to"); } } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java index 0acf9b7f8..6d8695590 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemoveItem.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Iterator; +import basemod.DevConsole; import basemod.ShopGrid; import basemod.abstracts.CustomShopItem; import basemod.devcommands.ConsoleCommand; @@ -12,14 +13,14 @@ public class ShopRemoveItem extends ConsoleCommand { public ShopRemoveItem() { requiresPlayer = true; minExtraTokens = 1; - minExtraTokens = 2; + maxExtraTokens = 2; simpleCheck = true; } @Override public ArrayList extraOptions(String[] tokens, int depth) { ArrayList opts = new ArrayList<>(); - if (tokens.length == 3) { + if (tokens.length <= 4) { if (ShopGrid.getCurrentPage() != ShopGrid.EMPTY_SHOP_PAGE) { for (int i = 0; i < ShopGrid.getCurrentPage().rows.size(); i++) opts.add(String.valueOf(i)); @@ -32,7 +33,6 @@ public ArrayList extraOptions(String[] tokens, int depth) { opts.add(String.valueOf(i)); } catch (NumberFormatException nfe) { nfe.printStackTrace(); - Shop.cmdShopHelp(); } } return opts; @@ -50,15 +50,20 @@ protected void execute(String[] tokens, int depth) { if (tokens.length == 4) { Iterator it = ShopGrid.getCurrentPage().rows.get(row).items.iterator(); while (it.hasNext()) { + it.next(); it.remove(); } } else { int col = Integer.parseInt(tokens[4]); ShopGrid.getCurrentPage().rows.get(row).items.remove(col); } + ShopGrid.removeEmptyPages(); } catch(NumberFormatException nfe) { nfe.printStackTrace(); Shop.cmdShopHelp(); + } catch (IndexOutOfBoundsException iobe) { + iobe.printStackTrace(); + DevConsole.log("row could not be found"); } } diff --git a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java index 806e63b85..ccb08454c 100644 --- a/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java +++ b/mod/src/main/java/basemod/devcommands/shop/ShopRemovePage.java @@ -41,5 +41,6 @@ protected void execute(String[] tokens, int depth) { if (!ShopGrid.removePage(tokens[3])) DevConsole.log("could not remove page with id " + tokens[3]); } + ShopGrid.removeEmptyPages(); } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 24d703bcc..1a747461c 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.evacipated.cardcrawl.modthespire.lib.LineFinder; import com.evacipated.cardcrawl.modthespire.lib.Matcher; +import com.evacipated.cardcrawl.modthespire.lib.SpireField; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertLocator; import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch; import com.evacipated.cardcrawl.modthespire.lib.SpireInstrumentPatch; @@ -182,15 +183,17 @@ public int[] Locate(CtBehavior ct) throws Exception { } } + @SpirePatch2(clz = StoreRelic.class, method = SpirePatch.CLASS) public static class StoreRelicPatches { + public static SpireField compatibleWithGrid = new SpireField<>(() -> false); + @SpirePatch2(clz = StoreRelic.class, method = "update") public static class SetCoords { @SpireInsertPatch(locator = HBMoveLocator.class) public static SpireReturn Insert(StoreRelic __instance, float rugY) { - - if (__instance.relic != null) { // dandy-TODO: for compatibility, add check to see if relic/potion was added to grid, otherwise continue + if (__instance.relic != null && compatibleWithGrid.get(__instance)) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) if (item.storeRelic == __instance) { @@ -220,7 +223,7 @@ public int[] Locate(CtBehavior ctb) throws Exception { public static class PurchaseRelic { @SpirePostfixPatch public static void RemoveRelic(StoreRelic __instance) { - if (__instance.isPurchased) { + if (__instance.isPurchased && compatibleWithGrid.get(__instance)) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storeRelic == __instance) { @@ -242,14 +245,14 @@ public static class Render { @SpirePrefixPatch public static SpireReturn CheckIfRelicInCurrentPage(StoreRelic __instance, SpriteBatch sb) { - if (__instance.relic != null && !ShopGrid.getCurrentPage().contains(__instance)) { + if (__instance.relic != null && compatibleWithGrid.get(__instance) && !ShopGrid.getCurrentPage().contains(__instance)) { return SpireReturn.Return(); } return SpireReturn.Continue(); } public static boolean canRender(StoreRelic instance) { - if (ShopGrid.getCurrentPage().contains(instance) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ((ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 5) || ShopGrid.getCurrentPage().rows.size() > 4)) return false; @@ -257,7 +260,7 @@ public static boolean canRender(StoreRelic instance) { } public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { - if (!canRender(instance)) { + if (compatibleWithGrid.get(instance) && !canRender(instance)) { if (instance.relic.hb.hovered) { hoveringItem = true; x = instance.relic.currentX; @@ -270,7 +273,7 @@ public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { } public static float goldY(StoreRelic instance, float yOffset) { - if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) return instance.relic.currentY - 75F * Settings.yScale; return instance.relic.currentY + yOffset; } @@ -296,13 +299,13 @@ public static boolean canRenderText(SpriteBatch sb, StoreRelic instance) { } public static float textX(StoreRelic instance, float xOffset) { - if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 4) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 4) return instance.relic.currentX + 3F * Settings.scale; return instance.relic.currentX + xOffset; } public static float textY(StoreRelic instance, float yOffset) { - if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) return instance.relic.currentY - 40F * Settings.scale; return instance.relic.currentY + yOffset; } @@ -327,14 +330,17 @@ public void edit(MethodCall m) throws CannotCompileException { } } + @SpirePatch2(clz = StorePotion.class, method = SpirePatch.CLASS) public static class StorePotionPatches { + public static SpireField compatibleWithGrid = new SpireField<>(() -> false); + @SpirePatch2(clz = StorePotion.class, method = "update") public static class Update { @SpireInsertPatch(locator = HBMoveLocator.class) public static SpireReturn SetCoords(StorePotion __instance, float rugY) { - if (__instance.potion != null) { // dandy-TODO: for compatibility, add check to see if relic/potion was added to grid, otherwise continue + if (__instance.potion != null && compatibleWithGrid.get(__instance)) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { @@ -364,7 +370,7 @@ public int[] Locate(CtBehavior ctb) throws Exception { @SpirePatch2(clz = StorePotion.class, method = "purchasePotion") public static class PurchasePotion { public static void Postfix(StorePotion __instance) { - if (__instance.isPurchased) { + if (__instance.isPurchased && compatibleWithGrid.get(__instance)) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { @@ -386,14 +392,14 @@ public static class Render { @SpirePrefixPatch public static SpireReturn CheckIfPotionInCurrentPage(StorePotion __instance, SpriteBatch sb) { - if (__instance.potion != null && !ShopGrid.getCurrentPage().contains(__instance)) { + if (__instance.potion != null && compatibleWithGrid.get(__instance) && !ShopGrid.getCurrentPage().contains(__instance)) { return SpireReturn.Return(); } return SpireReturn.Continue(); } public static boolean canRender(StorePotion instance) { - if (ShopGrid.getCurrentPage().contains(instance) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ((ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 5) || ShopGrid.getCurrentPage().rows.size() > 4)) return false; @@ -401,7 +407,7 @@ public static boolean canRender(StorePotion instance) { } public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { - if (!canRender(instance)) { + if (compatibleWithGrid.get(instance) && !canRender(instance)) { if (instance.potion.hb.hovered) { hoveringItem = true; x = instance.potion.posX; @@ -414,7 +420,7 @@ public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { } public static float goldY(StorePotion instance, float yOffset) { - if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) return instance.potion.posY - 75F * Settings.yScale; return instance.potion.posY + yOffset; } @@ -436,17 +442,17 @@ public void edit(MethodCall m) throws CannotCompileException { } public static boolean canRenderText(SpriteBatch sb, StorePotion instance) { - return canRender(instance); + return compatibleWithGrid.get(instance) && canRender(instance); } public static float textX(StorePotion instance, float xOffset) { - if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 4) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().getItem(instance).gridRow.maxColumns > 4) return instance.potion.posX + 3F * Settings.scale; return instance.potion.posX + xOffset; } public static float textY(StorePotion instance, float yOffset) { - if (ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) return instance.potion.posY - 40F * Settings.scale; return instance.potion.posY + yOffset; } From bb47f35c24e4e75840aa55ba3d6438635a4f0c39 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Mon, 22 Jan 2024 02:52:04 -0500 Subject: [PATCH 19/23] fix compatiblity issue, fix page removal issue --- mod/src/main/java/basemod/ShopGrid.java | 2 +- .../megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 4c5212c44..984ff1384 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -167,7 +167,7 @@ public static void removeEmptyPages() { customPages.removeIf((page) -> page.isEmpty()); if (!pages.contains(currentPage) && !customPages.contains(currentPage)) currentPage = previousPage; - else if (currentPage == previousPage) + else if (currentPage == previousPage && pages.size() == 0 && customPages.size() == 0) currentPage = EMPTY_SHOP_PAGE; } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 1a747461c..22b65871f 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -260,7 +260,7 @@ public static boolean canRender(StoreRelic instance) { } public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { - if (compatibleWithGrid.get(instance) && !canRender(instance)) { + if (!canRender(instance)) { if (instance.relic.hb.hovered) { hoveringItem = true; x = instance.relic.currentX; @@ -407,7 +407,7 @@ public static boolean canRender(StorePotion instance) { } public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { - if (compatibleWithGrid.get(instance) && !canRender(instance)) { + if (!canRender(instance)) { if (instance.potion.hb.hovered) { hoveringItem = true; x = instance.potion.posX; @@ -442,7 +442,7 @@ public void edit(MethodCall m) throws CannotCompileException { } public static boolean canRenderText(SpriteBatch sb, StorePotion instance) { - return compatibleWithGrid.get(instance) && canRender(instance); + return canRender(instance); } public static float textX(StorePotion instance, float xOffset) { From 8b894da300825c4b264faa63aef76771cfae7cab Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Mon, 22 Jan 2024 05:03:50 -0500 Subject: [PATCH 20/23] fix weird edge case --- mod/src/main/java/basemod/ShopGrid.java | 2 +- .../basemod/abstracts/CustomShopItem.java | 22 ++++++++++++------- .../shop/ShopScreen/ShopGridPatch.java | 15 ++++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 984ff1384..9e3be715f 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -447,7 +447,7 @@ public void hide() { } public boolean isEmpty() { - return items.isEmpty() || (items.stream().filter((item) -> !item.isPurchased).count() == 0); + return items.isEmpty() || (items.stream().filter((item) -> !item.isPurchased && item.isValid()).count() == 0); } public boolean isFull() { diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index 847014740..c1fcbc6d2 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -29,17 +29,17 @@ public class CustomShopItem { public String customShopId; - public ShopScreen screenRef; + public ShopScreen screenRef = null; public ShopGrid.Row gridRow; - public StoreRelic storeRelic; - public StorePotion storePotion; + public StoreRelic storeRelic = null; + public StorePotion storePotion = null; - private String tipTitle = null; - private String tipBody = null; + public String tipTitle = null; + public String tipBody = null; - private Texture img; - private Hitbox hb; - private float x, y; + public Texture img = null; + public Hitbox hb; + public float x, y; public int price = 0; public int row = 0; @@ -178,4 +178,10 @@ public void purchase() { AbstractDungeon.player.loseGold(this.price); CardCrawlGame.sound.play("SHOP_PURCHASE", 0.1F); } + + public boolean isValid() { + return (storePotion != null && storePotion.potion != null) + || (storeRelic != null && storeRelic.relic != null) + || (screenRef != null && tipTitle != null && tipBody != null && img != null); + } } diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 22b65871f..b04b38f1b 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -88,11 +88,6 @@ public static class ShopScreenInit { public static void PostShopInitializeHook() { BaseMod.publishPostShopInitialize(); } - - @SpirePrefixPatch - public static void InitializeGrid(ShopScreen __instance) { - basemod.ShopGrid.initialize(); - } } @SpirePatch2(clz = ShopScreen.class, method = "open") @@ -109,6 +104,11 @@ public static void HideGridOnOpen() { @SpirePatch2(clz = ShopScreen.class, method = "initRelics") public static class InitRelics { + @SpirePrefixPatch + public static void InitializeGrid() { + basemod.ShopGrid.initialize(); + } + @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) public static void AddGridRelic(StoreRelic relic) { CustomShopItem item = new CustomShopItem(relic); @@ -129,6 +129,11 @@ public int[] Locate(CtBehavior ct) throws Exception { @SpirePatch2(clz = ShopScreen.class, method = "initPotions") public static class PostInitPotions { + @SpirePostfixPatch + public static void ClearEmptyPagesAfterInit() { + ShopGrid.removeEmptyPages(); + } + @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" }) public static void AddGridPotion(StorePotion potion) { CustomShopItem item = new CustomShopItem(potion); From 4ab7954d48566676934a51f3d38bc78deb1fe6c3 Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Sat, 3 Feb 2024 18:21:36 -0500 Subject: [PATCH 21/23] polishing up custom shop item, nav button --- mod/src/main/java/basemod/BaseMod.java | 13 +++- mod/src/main/java/basemod/ShopGrid.java | 75 +++++++++++++------ .../basemod/abstracts/CustomShopItem.java | 56 ++++++++++---- .../PostGridInitializeSubscriber.java | 5 ++ .../shop/ShopScreen/ShopGridPatch.java | 38 +++++----- 5 files changed, 129 insertions(+), 58 deletions(-) create mode 100644 mod/src/main/java/basemod/interfaces/PostGridInitializeSubscriber.java diff --git a/mod/src/main/java/basemod/BaseMod.java b/mod/src/main/java/basemod/BaseMod.java index ec5979488..aab581c96 100644 --- a/mod/src/main/java/basemod/BaseMod.java +++ b/mod/src/main/java/basemod/BaseMod.java @@ -120,6 +120,7 @@ public class BaseMod { private static ArrayList postDungeonInitializeSubscribers; private static ArrayList postEnergyRechargeSubscribers; private static ArrayList postInitializeSubscribers; + private static ArrayList postGridInitializeSubscribers; private static ArrayList postShopInitializeSubscribers; private static ArrayList preMonsterTurnSubscribers; private static ArrayList renderSubscribers; @@ -462,6 +463,7 @@ private static void initializeSubscriptions() { postDungeonInitializeSubscribers = new ArrayList<>(); postEnergyRechargeSubscribers = new ArrayList<>(); postInitializeSubscribers = new ArrayList<>(); + postGridInitializeSubscribers = new ArrayList<>(); postShopInitializeSubscribers = new ArrayList<>(); preMonsterTurnSubscribers = new ArrayList<>(); renderSubscribers = new ArrayList<>(); @@ -2310,6 +2312,16 @@ public static void publishPostInitialize() { unsubscribeLaterHelper(PostInitializeSubscriber.class); } + // publishPostGridInitialize - + public static void publishPostGridInitialize() { + logger.info("publishPostGridInitialize"); + + for (PostGridInitializeSubscriber sub : postGridInitializeSubscribers) { + sub.receivePostGridInitialize(); + } + unsubscribeLaterHelper(PostGridInitializeSubscriber.class); + } + // publishPostShopInitialize - public static void publishPostShopInitialize() { logger.info("publishPostShopInitialize"); @@ -2317,7 +2329,6 @@ public static void publishPostShopInitialize() { for (PostShopInitializeSubscriber sub : postShopInitializeSubscribers) { sub.receivePostShopInitialize(); } - unsubscribeLaterHelper(PostShopInitializeSubscriber.class); } diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 9e3be715f..272add6a7 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -36,7 +36,7 @@ public class ShopGrid { public static float topEdge = Settings.HEIGHT * 0.48F; - public static float bottomEdge = Settings.HEIGHT * 0.075F; + public static float bottomEdge = Settings.HEIGHT * 0.035F; // this list holds pages specifically added by modders public static LinkedList customPages = new LinkedList<>(); @@ -57,6 +57,7 @@ public class ShopGrid { public static void initialize() { pages.clear(); + customPages.clear(); pageIdCounter = 1; currentPage = addDefaultPage(); rightArrow = new NavButton(true); @@ -118,13 +119,6 @@ else if (customPages.contains(page)) return false; } - public static boolean removePage(int idx) { - Page page = pages.get(idx); - if (page != null) - return removePage(page); - return false; - } - public static boolean removePage(String pageId) { for (Page page : pages) if (page.id.equals(pageId)) @@ -172,7 +166,7 @@ else if (currentPage == previousPage && pages.size() == 0 && customPages.size() } public static void hide() { - if (currentPage != null) + if (currentPage != null && currentPage != EMPTY_SHOP_PAGE) currentPage.hide(); leftArrow.hide(); rightArrow.hide(); @@ -243,11 +237,17 @@ public void render(SpriteBatch sb) { row.render(sb); leftArrow.render(sb); rightArrow.render(sb); - if (pages.size() > 1) { + if (pages.size() + customPages.size() > 1) { + int currPageIdx = 1; + if (pages.contains(currentPage)) + currPageIdx += pages.indexOf(currentPage); + else if (customPages.contains(currentPage)) + currPageIdx += pages.size() + customPages.indexOf(currentPage); + FontHelper.renderFontCentered( sb, FontHelper.buttonLabelFont, - (pages.indexOf(currentPage) + 1) + "/" + pages.size(), + currPageIdx + "/" + (pages.size() + customPages.size()), 1130F * Settings.xScale, pageY, Color.WHITE @@ -265,7 +265,7 @@ public boolean tryAddItem(CustomShopItem item) { return false; } - public Row addRow() { + public Row addDefaultRow() { return addRow(defaultPageCols); } @@ -275,6 +275,14 @@ public Row addRow(int size) { return row; } + public Row insertRow(int idx, int size) { + Row row = new Row(this, idx, size); + rows.add(idx, row); + for (int i = idx + 1; i < rows.size(); i++) + rows.get(i).rowNumber++; + return row; + } + public boolean isFull() { for (Row row : rows) if (!row.isFull()) @@ -393,7 +401,15 @@ public float getX(int col) { } public float getY(int row, float rugY) { - return rugY + (topEdge - ((row + 1F) / (owner.rows.size() + 1F) * gridHeight())); + float y = rugY; + if (this.owner.rows.size() > 2) { + y += (topEdge - ((row + 1F) / (owner.rows.size() + 1F) * gridHeight())); + } else if (row == 0) { + y += 400F * Settings.xScale; + } else { + y += 200F * Settings.xScale; + } + return y; } @SuppressWarnings("unchecked") @@ -460,6 +476,7 @@ public static class NavButton { public Hitbox hb; private float x, y; + private float scale; public boolean forward = true; @@ -473,26 +490,40 @@ public void update(float rugY) { this.y = rugY + 500.0F * Settings.yScale; this.hb.move(x, y); this.hb.update(); - if (this.hb.hovered && InputHelper.justClickedLeft) - hb.clickStarted = true; + if (this.hb.hovered) { + this.scale = Settings.scale / 2F * 1.1F; + if (InputHelper.justClickedLeft) { + hb.clickStarted = true; + } + } else { + this.scale = Settings.scale / 2F; + } if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { - int curIdx = pages.indexOf(currentPage); - if (forward && curIdx < pages.size() - 1) - currentPage = pages.get(curIdx + 1); + int curIdx = -1; + if (pages.contains(currentPage)) + curIdx = pages.indexOf(currentPage); + else if (customPages.contains(currentPage)) + curIdx = pages.size() + customPages.indexOf(currentPage); + if (forward && curIdx < (pages.size() + customPages.size() - 1)) + currentPage = currentPage.getNextPage(); else if (!forward && curIdx > 0) - currentPage = pages.get(curIdx - 1); + currentPage = currentPage.getPreviousPage(); this.hb.clicked = false; } } public void render(SpriteBatch sb) { - int curIdx = pages.indexOf(currentPage); - if (((!forward && curIdx > 0) || (forward && curIdx < pages.size() - 1))) { + int curIdx = -1; + if (pages.contains(currentPage)) + curIdx = pages.indexOf(currentPage); + else if (customPages.contains(currentPage)) + curIdx = pages.size() + customPages.indexOf(currentPage); + if (((!forward && curIdx > 0) || (forward && (curIdx < pages.size() + customPages.size() - 1)))) { sb.setColor(Color.WHITE); TextureRegion region = new TextureRegion(texture); if (forward) region.flip(true, false); - sb.draw(region, x - 96.0F * Settings.scale, y - 86.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, Settings.scale / 2, Settings.scale / 2, 0.0F); + sb.draw(region, x - 96.0F * Settings.scale, y - 86.0F * Settings.scale, 128.0F, 128.0F, 128.0F, 128.0F, scale, scale, 0.0F); hb.render(sb); } } diff --git a/mod/src/main/java/basemod/abstracts/CustomShopItem.java b/mod/src/main/java/basemod/abstracts/CustomShopItem.java index c1fcbc6d2..b701d7bc9 100644 --- a/mod/src/main/java/basemod/abstracts/CustomShopItem.java +++ b/mod/src/main/java/basemod/abstracts/CustomShopItem.java @@ -14,6 +14,7 @@ import com.megacrit.cardcrawl.helpers.FontHelper; import com.megacrit.cardcrawl.helpers.Hitbox; import com.megacrit.cardcrawl.helpers.ImageMaster; +import com.megacrit.cardcrawl.helpers.MathHelper; import com.megacrit.cardcrawl.helpers.TipHelper; import com.megacrit.cardcrawl.helpers.controller.CInputActionSet; import com.megacrit.cardcrawl.helpers.input.InputHelper; @@ -27,7 +28,7 @@ public class CustomShopItem { - public String customShopId; + public String id; public ShopScreen screenRef = null; public ShopGrid.Row gridRow; @@ -40,6 +41,7 @@ public class CustomShopItem { public Texture img = null; public Hitbox hb; public float x, y; + public float scale; public int price = 0; public int row = 0; @@ -87,12 +89,13 @@ public CustomShopItem(String modId, Texture img, int price, String tipTitle, Str this(modId, AbstractDungeon.shopScreen, img, price, tipTitle, tipBody); } - public CustomShopItem(String modId, ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { + public CustomShopItem(String id, ShopScreen screenRef, Texture img, int price, String tipTitle, String tipBody) { + this.id = id; this.screenRef = screenRef; this.tipTitle = tipTitle; this.tipBody = tipBody; this.img = img; - this.hb = new Hitbox(img.getWidth() * Settings.scale, img.getHeight() * Settings.scale); + this.hb = new Hitbox(72F * Settings.scale, 72F * Settings.scale); applyDiscounts(price); } @@ -117,6 +120,9 @@ public void update(float rugY) { this.screenRef.moveHand(this.x - 190.0F * Settings.scale, this.y - 70.0F * Settings.scale); if (InputHelper.justClickedLeft) this.hb.clickStarted = true; + this.scale = Settings.scale * 1.25F; + } else { + this.scale = MathHelper.scaleLerpSnap(this.scale, Settings.scale); } if (this.hb.clicked || (this.hb.hovered && CInputActionSet.select.isJustPressed())) { attemptPurchase(); @@ -130,20 +136,38 @@ public void render(SpriteBatch sb) { if (!this.isPurchased) { if (storeRelic == null && storePotion == null) { sb.setColor(Color.WHITE); + hb.render(sb); // assumes the size of a relic image - sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, Settings.scale, Settings.scale, 0.0F, 0, 0, 128, 128, false, false); - sb.draw(ImageMaster.UI_GOLD, x + GOLD_OFFSET_X, y + GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); - Color color = Color.WHITE; - if (this.price > AbstractDungeon.player.gold) - color = Color.SALMON; - FontHelper.renderFontLeftTopAligned(sb, FontHelper.tipHeaderFont, Integer.toString(this.price), x + PRICE_OFFSET_X, y + PRICE_OFFSET_Y, color); - if (this.hb.hovered && tipTitle != null && tipBody != null) - TipHelper.renderGenericTip( - InputHelper.mX + 50.0F * Settings.xScale, - InputHelper.mY + 50.0F * Settings.yScale, - tipTitle, - tipBody - ); + sb.draw(img, x - 64.0F, y - 64.0F, 64.0F, 64.0F, 128.0F, 128.0F, scale, scale, 0.0F, 0, 0, 128, 128, false, false); + if (gridRow != null && gridRow.maxColumns <= 5 && gridRow.owner.rows.size() <= 4) { + float goldY = y; + if (gridRow.owner.rows.size() > 3) + goldY += 26F * Settings.scale; + float textX = x; + if (gridRow.maxColumns > 4) + textX -= 10 * Settings.scale; + float textY = y; + if (gridRow.owner.rows.size() > 3) + textY += 22F * Settings.scale; + + sb.draw(ImageMaster.UI_GOLD, x + GOLD_OFFSET_X, goldY + GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); + Color color = Color.WHITE; + if (this.price > AbstractDungeon.player.gold) + color = Color.SALMON; + FontHelper.renderFontLeftTopAligned(sb, FontHelper.tipHeaderFont, Integer.toString(this.price), textX + PRICE_OFFSET_X, textY + PRICE_OFFSET_Y, color); + if (this.hb.hovered && tipTitle != null && tipBody != null) + TipHelper.renderGenericTip( + InputHelper.mX + 50.0F * Settings.xScale, + InputHelper.mY + 50.0F * Settings.xScale, + tipTitle, + tipBody + ); + } else if (hb.hovered) { + ShopGridPatch.x = x; + ShopGridPatch.y = y; + ShopGridPatch.price = price; + ShopGridPatch.hoveringItem = true; + } } } } diff --git a/mod/src/main/java/basemod/interfaces/PostGridInitializeSubscriber.java b/mod/src/main/java/basemod/interfaces/PostGridInitializeSubscriber.java new file mode 100644 index 000000000..74d8a75e5 --- /dev/null +++ b/mod/src/main/java/basemod/interfaces/PostGridInitializeSubscriber.java @@ -0,0 +1,5 @@ +package basemod.interfaces; + +public interface PostGridInitializeSubscriber extends ISubscriber { + void receivePostGridInitialize(); +} diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index b04b38f1b..5484d3f49 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -16,6 +16,7 @@ import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch; import com.evacipated.cardcrawl.modthespire.lib.SpireReturn; import com.megacrit.cardcrawl.core.Settings; +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; import com.megacrit.cardcrawl.helpers.FontHelper; import com.megacrit.cardcrawl.helpers.Hitbox; import com.megacrit.cardcrawl.helpers.ImageMaster; @@ -55,18 +56,18 @@ public class ShopGridPatch { private static final float RELIC_GOLD_OFFSET_Y = -102F * Settings.scale; - private static boolean hoveringItem = false; + public static boolean hoveringItem = false; - private static float x; + public static float x; - private static float y; + public static float y; - private static int price; + public static int price; public static void renderPrice(SpriteBatch sb) { final float BOX_EDGE_H = ReflectionHacks.getPrivateStatic(TipHelper.class, "BOX_EDGE_H"); final float TIP_DESC_LINE_SPACING = ReflectionHacks.getPrivateStatic(TipHelper.class, "TIP_DESC_LINE_SPACING"); - final Color BASE_COLOR = ReflectionHacks.getPrivateStatic(TipHelper.class, "BASE_COLOR"); + Color color = ReflectionHacks.getPrivateStatic(TipHelper.class, "BASE_COLOR"); float h = FontHelper.getHeight(FontHelper.tipBodyFont, Integer.toString(price), 1F); sb.setColor(Settings.TOP_PANEL_SHADOW_COLOR); sb.draw(ImageMaster.KEYWORD_TOP, x + OFFSET_X + SHADOW_DIST_X, y + OFFSET_Y - SHADOW_DIST_Y, BOX_W, BOX_EDGE_H); @@ -75,7 +76,9 @@ public static void renderPrice(SpriteBatch sb) { sb.draw(ImageMaster.KEYWORD_TOP, x + OFFSET_X, y + OFFSET_Y, BOX_W, BOX_EDGE_H); sb.draw(ImageMaster.KEYWORD_BOT, x + OFFSET_X, y + OFFSET_Y - h, BOX_W, BOX_EDGE_H); sb.draw(ImageMaster.UI_GOLD, x + RELIC_GOLD_OFFSET_X, y + RELIC_GOLD_OFFSET_Y, GOLD_IMG_WIDTH, GOLD_IMG_WIDTH); - FontHelper.renderSmartText(sb, FontHelper.tipBodyFont, Integer.toString(price), x + TEXT_OFFSET_X + OFFSET_X + GOLD_IMG_WIDTH, y + TEXT_OFFSET_Y + OFFSET_Y, BOX_W, TIP_DESC_LINE_SPACING, BASE_COLOR); + if (price > AbstractDungeon.player.gold) + color = Color.SALMON; + FontHelper.renderSmartText(sb, FontHelper.tipBodyFont, Integer.toString(price), x + TEXT_OFFSET_X + OFFSET_X + GOLD_IMG_WIDTH, y + TEXT_OFFSET_Y + OFFSET_Y, BOX_W, TIP_DESC_LINE_SPACING, color); } @SpirePatch2(clz = ShopScreen.class, method = SpirePatch.CLASS) @@ -107,6 +110,7 @@ public static class InitRelics { @SpirePrefixPatch public static void InitializeGrid() { basemod.ShopGrid.initialize(); + BaseMod.publishPostGridInitialize(); } @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "relic" }) @@ -202,11 +206,7 @@ public static SpireReturn Insert(StoreRelic __instance, float rugY) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) if (item.storeRelic == __instance) { - if (gridRow.owner.rows.size() > 2) { - __instance.relic.currentY = gridRow.getY(item.row, rugY); - } else { - __instance.relic.currentY = rugY + (item.row == 0 ? 400F : 200F) * Settings.xScale; - } + __instance.relic.currentY = gridRow.getY(item.row, rugY); __instance.relic.currentX = gridRow.getX(item.col); return SpireReturn.Continue(); } @@ -264,7 +264,7 @@ public static boolean canRender(StoreRelic instance) { return true; } - public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { + public static boolean canRenderGold(StoreRelic instance) { if (!canRender(instance)) { if (instance.relic.hb.hovered) { hoveringItem = true; @@ -278,7 +278,7 @@ public static boolean canRenderGold(SpriteBatch sb, StoreRelic instance) { } public static float goldY(StoreRelic instance, float yOffset) { - if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 3) return instance.relic.currentY - 75F * Settings.yScale; return instance.relic.currentY + yOffset; } @@ -290,7 +290,7 @@ public void edit(MethodCall m) throws CannotCompileException { if (m.getMethodName().equals("draw")) { m.replace("" + "{" - + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.canRenderGold($0, this))" + + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.canRenderGold(this))" + "sb.draw($1, $2, basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StoreRelicPatches.Render.goldY(this, RELIC_GOLD_OFFSET_Y), $4, $5);" + "}" ); @@ -310,7 +310,7 @@ public static float textX(StoreRelic instance, float xOffset) { } public static float textY(StoreRelic instance, float yOffset) { - if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 3) return instance.relic.currentY - 40F * Settings.scale; return instance.relic.currentY + yOffset; } @@ -411,7 +411,7 @@ public static boolean canRender(StorePotion instance) { return true; } - public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { + public static boolean canRenderGold(StorePotion instance) { if (!canRender(instance)) { if (instance.potion.hb.hovered) { hoveringItem = true; @@ -425,7 +425,7 @@ public static boolean canRenderGold(SpriteBatch sb, StorePotion instance) { } public static float goldY(StorePotion instance, float yOffset) { - if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 3) return instance.potion.posY - 75F * Settings.yScale; return instance.potion.posY + yOffset; } @@ -437,7 +437,7 @@ public void edit(MethodCall m) throws CannotCompileException { if (m.getMethodName().equals("draw")) { m.replace("" + "{" - + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.canRenderGold($0, this))" + + "if (basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.canRenderGold(this))" + "sb.draw($1, $2, basemod.patches.com.megacrit.cardcrawl.shop.ShopScreen.ShopGridPatch.StorePotionPatches.Render.goldY(this, RELIC_GOLD_OFFSET_Y), $4, $5);" + "}" ); @@ -457,7 +457,7 @@ public static float textX(StorePotion instance, float xOffset) { } public static float textY(StorePotion instance, float yOffset) { - if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 2) + if (compatibleWithGrid.get(instance) && ShopGrid.getCurrentPage().contains(instance) && ShopGrid.getCurrentPage().rows.size() > 3) return instance.potion.posY - 40F * Settings.scale; return instance.potion.posY + yOffset; } From ee6b6784116a1099a1174917c2324c99d3d6fb8f Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Fri, 9 Feb 2024 11:16:15 -0500 Subject: [PATCH 22/23] dont set potion & storePotion to null --- .../megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 5484d3f49..683b5696c 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -232,10 +232,7 @@ public static void RemoveRelic(StoreRelic __instance) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storeRelic == __instance) { - item.storeRelic.relic = null; - item.storeRelic = null; item.isPurchased = true; - ShopGrid.removeEmptyPages(); return; } @@ -379,10 +376,7 @@ public static void Postfix(StorePotion __instance) { for (ShopGrid.Row gridRow : ShopGrid.getCurrentPage().rows) for (CustomShopItem item : gridRow.items) { if (item.storePotion == __instance) { - item.storePotion.potion = null; - item.storePotion = null; item.isPurchased = true; - ShopGrid.removeEmptyPages(); break; } From 12e6246560952f85faec866b408d9d4ba9425b6b Mon Sep 17 00:00:00 2001 From: Dan Donley Date: Fri, 9 Feb 2024 11:51:39 -0500 Subject: [PATCH 23/23] tweaks to make it compatible with SpicyShops --- mod/src/main/java/basemod/ShopGrid.java | 12 +++++++++++- .../cardcrawl/shop/ShopScreen/ShopGridPatch.java | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mod/src/main/java/basemod/ShopGrid.java b/mod/src/main/java/basemod/ShopGrid.java index 272add6a7..603cba09d 100644 --- a/mod/src/main/java/basemod/ShopGrid.java +++ b/mod/src/main/java/basemod/ShopGrid.java @@ -26,6 +26,9 @@ public class ShopGrid { private static int pageIdCounter = 0; + // temporary dimensions to help support SpicyShops + public static int[] initialPageDimensions = { 3, 3, 4 }; + public static int defaultPageRows = 2; public static int defaultPageCols = 3; @@ -59,7 +62,10 @@ public static void initialize() { pages.clear(); customPages.clear(); pageIdCounter = 1; - currentPage = addDefaultPage(); + // currentPage = addDefaultPage(); + Page initialPage = new Page(initialPageDimensions); + pages.addLast(initialPage); + currentPage = initialPage; rightArrow = new NavButton(true); leftArrow = new NavButton(false); } @@ -165,6 +171,10 @@ else if (currentPage == previousPage && pages.size() == 0 && customPages.size() currentPage = EMPTY_SHOP_PAGE; } + public static void removeEmptyRows() { + currentPage.rows.removeIf((row) -> row.isEmpty()); + } + public static void hide() { if (currentPage != null && currentPage != EMPTY_SHOP_PAGE) currentPage.hide(); diff --git a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java index 683b5696c..f764bd7d1 100644 --- a/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java +++ b/mod/src/main/java/basemod/patches/com/megacrit/cardcrawl/shop/ShopScreen/ShopGridPatch.java @@ -136,6 +136,7 @@ public static class PostInitPotions { @SpirePostfixPatch public static void ClearEmptyPagesAfterInit() { ShopGrid.removeEmptyPages(); + ShopGrid.removeEmptyRows(); } @SpireInsertPatch(locator = ArrayAddLocator.class, localvars = { "potion" })