From 7b7748c891facbfb0b06578565954c6606af485b Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 17 Dec 2019 17:16:54 -0800 Subject: [PATCH 1/2] December 2019 Updates and Bugfixes ModTheSpire.json, pom.xml: Incremented minor version number since this is a bugfix release. Additionally, added a compoonent version numbers section to make updating external library version numbers easier and a Steam.path value so location of mod components can easily be changed. SneckoMod.java: updates com.megacrit.cardcrawl.helpers.CardHelper.getColor now takes 3 int parameters instead of 3 doubles; this call has been adjusted accordingly. SneckoCharacter.java: updates AbstractCharacter has been updated, so SneckoCharacter required certain changes; it needed to implement getPortraitImageName(). There is no longer a damageFlash member in the AbstractPlayer or CustomPlayer class, so lines referencing it in the render function of SneckoCharacter have been commented out pending replacement or removal. I'm not sure what it used to do, and it seems to work fine without them, so if anyone knows more feel free to get in touch. MasterEyePower.java, ReduceCostRelic.java, ReduceMostExpensiveCardAction.java: bugfixing cost reducers modifyCostForTurn is no longer a supported method for the AbstractCard class and the atStartOfTurnPostDraw() method of cards are called after draw actions have been put on the action manager stack, but not before those draw actions have been processed. Because of this, MasterEyePower and ReduceCostRelic now add a new ReduceMostExpensiveCardAction to the bottom of the action manager in their atStartOfTurnPostDraw() methods, which uses modifyCostForCombat(-1) on a randomly selected card in hand with max cost. This modification of cost for combat is more consistent with overall snecko mechanics. SnekproofRandomizeHandCostPatch.java, SnekproofConfusionPatch.java: Fixing Snekproof mechanic Sneckproof cards are set up to un-randomize cost via logic in their a triggerWhenDrawn() method which is currently called before ConfusionPower.onCardDraw(card) randomizes costs; this rendered the snekproof mechanic non-functional. I have added SnekproofConfusionPatch to return early in ConfusionPower.onCardDraw(card) if card has the SNEKPROOF tag, preventing confusion from randomizing these cards at all. Additionally, RandomizeHandCostAction (called with the new beta branch snecko potion) is patched to not randomize the cost of cards with the snekproof tag. AbstractSneckoCard.java: Major Bugfix Issue: When unknown cards generated a card which was previously generated by an unknown card and then exhausted, it would be almost (or entirely) invisible, apparently reflecting the final frame of the exhaust animation. Additionally, when multiple unknown cards in the deck generated the same card, those cards were actually the _same_card_, in that they only existed once in your hand if you drew both and two number keys would play them, which led to some crazy UI bugs in both hand and draw/discard pile display. Exhausting invisible cards "fixed" their rendering in exhaust pile; Save and quit->continue run didn't fix either of these problems, fully exiting the game fixed invisible cards but not duplicate cards. Explanation: Cards generated by Unknown Cards are all pointing to same instance of that card, which is returned by CardLibrary.cards.get(tmp.get(AbstractDungeon.cardRng.random(0, tmp.size() - 1))). They have the same UUID, exhausted cards were still exhausted causing invisibility bug, and duplicate cards were literally the same card at 2 places in your draw pile, causing all manner of havoc. --- pom.xml | 58 ++++++++++------- src/main/java/sneckomod/SneckoMod.java | 2 +- .../ReduceMostExpensiveCardAction.java | 39 ++++++++++++ .../sneckomod/cards/AbstractSneckoCard.java | 2 +- .../sneckomod/characters/SneckoCharacter.java | 23 ++++--- .../patches/SnekproofConfusionPatch.java | 25 ++++++++ .../SnekproofRandomizeHandCostPatch.java | 62 +++++++++++++++++++ .../java/sneckomod/powers/MasterEyePower.java | 18 +----- .../sneckomod/relics/ReduceCostRelic.java | 17 +---- src/main/resources/ModTheSpire.json | 8 +-- 10 files changed, 187 insertions(+), 67 deletions(-) create mode 100644 src/main/java/sneckomod/actions/ReduceMostExpensiveCardAction.java create mode 100644 src/main/java/sneckomod/patches/SnekproofConfusionPatch.java create mode 100644 src/main/java/sneckomod/patches/SnekproofRandomizeHandCostPatch.java diff --git a/pom.xml b/pom.xml index 4691d73..d3a5f66 100644 --- a/pom.xml +++ b/pom.xml @@ -3,75 +3,92 @@ sneckomod sneckomod - v0.0.19 + v0.0.20 jar Snecko Mod A new silly character for Slay the Spire: The Snek + + + 1.8 + 1.8 + 12-17-2019 + 5.16.0-beta.3 + 3.14.1 + 1.17.1 + 1.4.5 + 0.24.0 + 1.5.3 + 0.20.0 + 0.10.11 + + D:\Program Files (x86)\Steam\steamapps + + com.megacrit.cardcrawl slaythespire - 051 + ${SlayTheSpire.version} system - ${basedir}/../lib/desktop-1.0.jar + ${Steam.path}/common/SlayTheSpire/desktop-1.0.jar basemod basemod - 5.4.0 + ${basemod.version} system - ${basedir}/../lib/BaseMod.jar + ${Steam.path}/workshop/content/646570/1605833019/BaseMod.jar com.evacipated.cardcrawl ModTheSpire - 3.6.3 + ${ModTheSpire.version} system - ${basedir}/../lib/ModTheSpire.jar + ${Steam.path}/workshop/content/646570/1605060445/ModTheSpire.jar com.evacipated.cardcrawl stslib - 1.9.0 + ${stslib.version} system - ${basedir}/../lib/STSLib.jar + ${Steam.path}/workshop/content/646570/1609158507/StSLib.jar yohane yohane - 1.9.0 + ${yohane.version} system - ${basedir}/../lib/Yohane.jar + ${Steam.path}/workshop/content/646570/1612593526/Yohane.jar hubris hubris - 0.19.1 + ${hubris.version} system - ${basedir}/../lib/Hubris.jar + ${Steam.path}/workshop/content/646570/1609159603/Hubris.jar replaythespire replaythespire - 1.3.15 + ${replaythespire.version} system - ${basedir}/../lib/ReplayTheSpireMod.jar + ${Steam.path}/workshop/content/646570/1610173938/ReplayTheSpireMod.jar infinitespire infinitespire - 0.12.0 + ${infintespire.version} system - ${basedir}/../lib/InfiniteSpire.jar + ${Steam.path}/workshop/content/646570/1610128058/InfiniteSpire.jar chronomuncher chronomuncher - 0.12.0 + ${chronomuncher.version} system - ${basedir}/../lib/TheDisciple.jar + ${Steam.path}/workshop/content/646570/1609846039/TheDisciple.jar @@ -97,8 +114,7 @@ - - + diff --git a/src/main/java/sneckomod/SneckoMod.java b/src/main/java/sneckomod/SneckoMod.java index f72c399..b108084 100644 --- a/src/main/java/sneckomod/SneckoMod.java +++ b/src/main/java/sneckomod/SneckoMod.java @@ -37,7 +37,7 @@ @com.evacipated.cardcrawl.modthespire.lib.SpireInitializer public class SneckoMod implements basemod.interfaces.PostBattleSubscriber, basemod.interfaces.OnStartBattleSubscriber, basemod.interfaces.PostInitializeSubscriber, basemod.interfaces.EditCharactersSubscriber, basemod.interfaces.EditRelicsSubscriber, basemod.interfaces.EditCardsSubscriber, basemod.interfaces.EditKeywordsSubscriber, basemod.interfaces.EditStringsSubscriber { - private static final com.badlogic.gdx.graphics.Color SNECKO_COLOR = com.megacrit.cardcrawl.helpers.CardHelper.getColor(220.0F, 55.0F, 220.0F); + private static final com.badlogic.gdx.graphics.Color SNECKO_COLOR = com.megacrit.cardcrawl.helpers.CardHelper.getColor(220, 55, 220); private static final String SneckoMOD_ASSETS_FOLDER = "SneckoImages"; diff --git a/src/main/java/sneckomod/actions/ReduceMostExpensiveCardAction.java b/src/main/java/sneckomod/actions/ReduceMostExpensiveCardAction.java new file mode 100644 index 0000000..4ee4aac --- /dev/null +++ b/src/main/java/sneckomod/actions/ReduceMostExpensiveCardAction.java @@ -0,0 +1,39 @@ +package sneckomod.actions; + +import com.badlogic.gdx.graphics.Color; +import com.megacrit.cardcrawl.actions.AbstractGameAction; +import com.megacrit.cardcrawl.cards.AbstractCard; +import com.megacrit.cardcrawl.dungeons.AbstractDungeon; +import sneckomod.SneckoMod; +import java.util.ArrayList; +import java.util.Collections; + +public class ReduceMostExpensiveCardAction extends AbstractGameAction { + public ReduceMostExpensiveCardAction() { + } + public void update() { + ArrayList mostExpensive = new ArrayList(); + int mostExpensiveCost = -1; + SneckoMod.logger.info("AbstractDungeon.player.hand.group.size() = " + AbstractDungeon.player.hand.group.size()); + for (AbstractCard c : AbstractDungeon.player.hand.group) { + SneckoMod.logger.info("Card" +c.name +"has cost"+c.cost); + if (c.cost > mostExpensiveCost) { + mostExpensive.clear(); + mostExpensive.add(c) ; + mostExpensiveCost = c.cost; + } else if (c.cost == mostExpensiveCost) { + mostExpensive.add(c); + } + } + if (mostExpensive.size() == 0) { + SneckoMod.logger.info("Tried to reduce most expensive cost with no cards in hand."); + } else { + Collections.shuffle(mostExpensive, AbstractDungeon.cardRandomRng.random); + AbstractCard mostExpensiveCard = mostExpensive.get(0); + mostExpensiveCard.modifyCostForCombat(-1); + mostExpensiveCard.isCostModified = true; + mostExpensiveCard.superFlash(Color.PURPLE.cpy()); + } + tickDuration(); + } +} diff --git a/src/main/java/sneckomod/cards/AbstractSneckoCard.java b/src/main/java/sneckomod/cards/AbstractSneckoCard.java index 0c6875c..eb496b2 100644 --- a/src/main/java/sneckomod/cards/AbstractSneckoCard.java +++ b/src/main/java/sneckomod/cards/AbstractSneckoCard.java @@ -102,7 +102,7 @@ public void replaceUnknown(boolean toHand) { SneckoMod.logger.info("Attempting to create new Unknown: " + this.name); AbstractCard cUnknown; if (tmp.size() > 0) { - cUnknown = CardLibrary.cards.get(tmp.get(AbstractDungeon.cardRng.random(0, tmp.size() - 1))); + cUnknown = CardLibrary.cards.get(tmp.get(AbstractDungeon.cardRng.random(0, tmp.size() - 1))).makeStatEquivalentCopy(); } else { cUnknown = new com.megacrit.cardcrawl.cards.colorless.Madness(); diff --git a/src/main/java/sneckomod/characters/SneckoCharacter.java b/src/main/java/sneckomod/characters/SneckoCharacter.java index 1ab12b1..5b2f544 100644 --- a/src/main/java/sneckomod/characters/SneckoCharacter.java +++ b/src/main/java/sneckomod/characters/SneckoCharacter.java @@ -235,9 +235,9 @@ public void render(SpriteBatch sb) { } if (!(AbstractDungeon.getCurrRoom() instanceof RestRoom)) { - if (this.damageFlash) { - ShaderHelper.setShader(sb, ShaderHelper.Shader.WHITE_SILHOUETTE); - } +// if (this.damageFlash) { +// ShaderHelper.setShader(sb, ShaderHelper.Shader.WHITE_SILHOUETTE); +// } Boolean renderCorpse = (Boolean)ReflectionHacks.getPrivate(this,AbstractPlayer.class,"renderCorpse"); @@ -248,13 +248,13 @@ public void render(SpriteBatch sb) { sb.draw(this.img, this.drawX - (float)this.img.getWidth() * Settings.scale / 2.0F + this.animX, this.drawY, (float)this.img.getWidth() * Settings.scale, (float)this.img.getHeight() * Settings.scale, 0, 0, this.img.getWidth(), this.img.getHeight(), this.flipHorizontal, this.flipVertical); } - if (this.damageFlash) { - ShaderHelper.setShader(sb, ShaderHelper.Shader.DEFAULT); - --this.damageFlashFrames; - if (this.damageFlashFrames == 0) { - this.damageFlash = false; - } - } +// if (this.damageFlash) { +// ShaderHelper.setShader(sb, ShaderHelper.Shader.DEFAULT); +// --this.damageFlashFrames; +// if (this.damageFlashFrames == 0) { +// this.damageFlash = false; +// } +// } this.hb.render(sb); this.healthHb.render(sb); @@ -276,6 +276,9 @@ public void render(SpriteBatch sb) { } + @Override + public String getPortraitImageName(){return "That Sneaky Snake";} + private static final com.megacrit.cardcrawl.localization.CharacterStrings charStrings = CardCrawlGame.languagePack.getCharacterString("Snecko"); public static final String NAME = charStrings.NAMES[0]; public static final String DESCRIPTION = charStrings.TEXT[0]; diff --git a/src/main/java/sneckomod/patches/SnekproofConfusionPatch.java b/src/main/java/sneckomod/patches/SnekproofConfusionPatch.java new file mode 100644 index 0000000..155d02b --- /dev/null +++ b/src/main/java/sneckomod/patches/SnekproofConfusionPatch.java @@ -0,0 +1,25 @@ +package sneckomod.patches; + +import com.evacipated.cardcrawl.modthespire.lib.*; +import com.megacrit.cardcrawl.cards.AbstractCard; +import com.megacrit.cardcrawl.powers.ConfusionPower; +import static sneckomod.SneckoMod.SNEKPROOF; + + +public class SnekproofConfusionPatch { + //Patches ConfusionPower to not randomize costs on Snekproof cards + @SpirePatch( + clz=ConfusionPower.class, + method = "onCardDraw" + ) + public static class ConfusionPower_onCardDraw { + @SpirePrefixPatch + public static SpireReturn prefix(ConfusionPower __this, AbstractCard card) { + + if (card.hasTag(SNEKPROOF)) { + return SpireReturn.Return(null); + } + return SpireReturn.Continue(); + } + } +} \ No newline at end of file diff --git a/src/main/java/sneckomod/patches/SnekproofRandomizeHandCostPatch.java b/src/main/java/sneckomod/patches/SnekproofRandomizeHandCostPatch.java new file mode 100644 index 0000000..34e9fb5 --- /dev/null +++ b/src/main/java/sneckomod/patches/SnekproofRandomizeHandCostPatch.java @@ -0,0 +1,62 @@ +package sneckomod.patches; + +import com.evacipated.cardcrawl.modthespire.lib.*; +import com.evacipated.cardcrawl.modthespire.patcher.PatchingException; +import com.megacrit.cardcrawl.cards.AbstractCard; +import com.megacrit.cardcrawl.actions.unique.RandomizeHandCostAction; +import com.megacrit.cardcrawl.random.Random; +import javassist.CannotCompileException; +import javassist.CtBehavior; +import sneckomod.SneckoMod; + +import java.util.ArrayList; + +import static sneckomod.SneckoMod.SNEKPROOF; + +public class SnekproofRandomizeHandCostPatch { + //Patches the RandomizeHandCostAction to not randomize costs on Snekproof cards + @SpirePatch( + clz= RandomizeHandCostAction.class, + method = "update" + ) + public static class DoNotRandomizeSnekproofCosts { + + @SpireInsertPatch( + locator = Locator.class, + localvars = {"card","newCost"} + ) + //This method will be inserted after the RandomizeHandAction gets a newCost from the AbstractDungeon.cardRandomRng.random(3) + public static void Insert (RandomizeHandCostAction __this, AbstractCard card, @ByRef int[] newCost) {// + if (card.hasTag(SNEKPROOF)) { + SneckoMod.logger.info("Not randomizing cost of " + card.name + "since it has snekproof."); + newCost[0]=card.cost; + } + } + + // ModTheSpire searches for a nested class that extends SpireInsertLocator + // This class will be the Locator for the @SpireInsertPatch + // When a Locator is not specified, ModTheSpire uses the default behavior for the @SpireInsertPatch + private static class Locator extends SpireInsertLocator { + // This is the abstract method from SpireInsertLocator that will be used to find the line + // numbers you want this patch inserted at + public int[] Locate(CtBehavior ctMethodToPatch) throws CannotCompileException, PatchingException { + // finalMatcher is the line that we want to insert our patch before - + // in this example we are using a `MethodCallMatcher` which is a type + // of matcher that matches a method call based on the type of the calling + // object and the name of the method being called. Here you can see that + // we're expecting the `end` method to be called on a `SpireBatch` + Matcher finalMatcher = new Matcher.MethodCallMatcher(Random.class, "random"); + + // the `new ArrayList()` specifies the prerequisites before the line can be matched - + // the LineFinder will search for all the prerequisites in order before it will match the finalMatcher - + // since we didn't specify any prerequisites here, the LineFinder will simply find the first expression + // that matches the finalMatcher. + int[] result = LineFinder.findInOrder(ctMethodToPatch, new ArrayList(), finalMatcher); + //we actually want the immediate next line, after the value has been assigned to newCost + result[0]++; + return result; + } + } + + } +} diff --git a/src/main/java/sneckomod/powers/MasterEyePower.java b/src/main/java/sneckomod/powers/MasterEyePower.java index b66afae..31d9280 100644 --- a/src/main/java/sneckomod/powers/MasterEyePower.java +++ b/src/main/java/sneckomod/powers/MasterEyePower.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import sneckomod.SneckoMod; + import sneckomod.actions.ReduceMostExpensiveCardAction; public class MasterEyePower extends AbstractPower { @@ -66,22 +67,9 @@ public void updateDescription() public void atStartOfTurnPostDraw() { + SneckoMod.logger.info("Beginning atStartOfTurnPostDraw for MasterEye"); super.atStartOfTurnPostDraw(); - - AbstractCard mostExpensive = null; - int mostExpensiveCost = -1; - - for (AbstractCard c : AbstractDungeon.player.hand.group) { - if (c.cost > mostExpensiveCost) { - mostExpensive = c; - } - } - - if (mostExpensive != null) { - mostExpensive.modifyCostForTurn(-1); - mostExpensive.isCostModified = true; - mostExpensive.superFlash(Color.PURPLE.cpy()); - } + addToBot(new ReduceMostExpensiveCardAction()); } } diff --git a/src/main/java/sneckomod/relics/ReduceCostRelic.java b/src/main/java/sneckomod/relics/ReduceCostRelic.java index ddd5c95..2a5a280 100644 --- a/src/main/java/sneckomod/relics/ReduceCostRelic.java +++ b/src/main/java/sneckomod/relics/ReduceCostRelic.java @@ -9,6 +9,7 @@ import com.megacrit.cardcrawl.relics.AbstractRelic; import com.megacrit.cardcrawl.relics.AbstractRelic.RelicTier; import sneckomod.SneckoMod; + import sneckomod.actions.ReduceMostExpensiveCardAction; import sneckomod.characters.SneckoCharacter; public class ReduceCostRelic extends CustomRelic @@ -33,21 +34,7 @@ public String getUpdatedDescription() public void atTurnStartPostDraw() { super.atTurnStartPostDraw(); - AbstractCard mostExpensive = null; - int mostExpensiveCost = -1; - - for (AbstractCard c : AbstractDungeon.player.hand.group) { - if (c.cost > mostExpensiveCost) { - mostExpensive = c; - } - } - - if (mostExpensive != null) { - flash(); - mostExpensive.modifyCostForTurn(-1); - mostExpensive.isCostModified = true; - mostExpensive.superFlash(Color.PURPLE.cpy()); - } + addToBot(new ReduceMostExpensiveCardAction()); } public boolean canSpawn() { diff --git a/src/main/resources/ModTheSpire.json b/src/main/resources/ModTheSpire.json index 148168f..d986876 100644 --- a/src/main/resources/ModTheSpire.json +++ b/src/main/resources/ModTheSpire.json @@ -2,10 +2,10 @@ "modid": "SneckoMod", "name": "Snecko Mod", "author_list": ["Michael Mayhem"], - "description": "Adds a new silly playable Snecko character: The Perplexed. ", - "version": "0.0.19", - "sts_version": "01-03-2019", - "mts_version": "3.6.3", + "description": "Adds a new silly playable Snecko character: The Snek. ", + "version": "0.0.20", + "sts_version": "12-17-2019", + "mts_version": "3.14.1", "dependencies": ["basemod", "stslib"], "update_json": "https://api.github.com/repos/mikemayhemdev/Snecko_Mod/releases/latest" } From 48e294b4287118fb8c8877129fe89a951533269f Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 17 Dec 2019 17:21:28 -0800 Subject: [PATCH 2/2] fleshing out gitignore using a more robust standard gitignore for maven-based java projects --- .gitignore | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b83d222..131be1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,79 @@ -/target/ +*.class + +# IntelliJ +.idea/ +out/ +*.iml + +# Eclipse +.classpath +.project +.settings/ + +# maven build target +target/ + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Spriter files +*.autosave.scml \ No newline at end of file