From 53acf6cfc6a5fa72be76203a0d0a765db60cb830 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 11 Oct 2024 14:31:49 -0400 Subject: [PATCH] v3.0.0: implemented barebones cleric with basically no functionality --- .../assets/messages/actors/actors.properties | 6 ++++ .../shatteredpixeldungeon/Badges.java | 8 +++++ .../actors/hero/HeroClass.java | 31 ++++++++++++++++++- .../actors/hero/Talent.java | 11 +++++++ .../actors/mobs/npcs/Blacksmith.java | 2 +- .../actors/mobs/npcs/Wandmaker.java | 3 ++ .../items/armor/ClassArmor.java | 3 ++ .../items/remains/RemainsItem.java | 2 ++ .../scenes/HeroSelectScene.java | 4 +++ .../shatteredpixeldungeon/ui/Icons.java | 2 ++ .../windows/WndHeroInfo.java | 9 ++++++ 11 files changed, 79 insertions(+), 2 deletions(-) diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 5ee6d1f7c..bbff0162f 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -577,6 +577,11 @@ actors.hero.heroclass.duelist_desc_short=The Duelist is a weapons master who can actors.hero.heroclass.duelist_desc=The Duelist starts with a _unique rapier_ with a special ability that recharges over time.\n\nEvery weapon in the game has a _different special ability_ that the Duelist can use.\n\nThe Duelist also starts with _two throwing spikes_, cloth armor, a waterskin, and a velvet pouch.\n\nThe Duelist automatically identifies:\n_-_ Scrolls of Identify\n_-_ Potions of Strength\n_-_ Scrolls of Mirror Image actors.hero.heroclass.duelist_unlock=To unlock the Duelist _equip a tier 2 or higher weapon with no strength penalty._ +actors.hero.heroclass.cleric=cleric +actors.hero.heroclass.cleric_desc_short=The Cleric is a divine spellcaster who uses their unique _holy tome_ to channel divine magic. They can learn and upgrade spells_ via talents. +actors.hero.heroclass.cleric_desc=The Cleric starts with a _unique holy tome_, which they can use to cast various spells.\n\nMost of the Cleric's talents are focused around learning or upgrading spells.\n\nThe Cleric also starts with _a cudgel_, cloth armor, a waterskin, and a velvet pouch.\n\nThe Cleric automatically identifies:\n_-_ Scrolls of Identify\n_-_ Potions of Purity\n_-_ Scrolls of Remove Curse +actors.hero.heroclass.cleric_unlock=TODO + actors.hero.herosubclass.berserker=berserker actors.hero.herosubclass.berserker_short_desc=The _Berserker_ builds rage as he takes damage. Rage increases his damage and can be activated at 100% for bonus shielding. actors.hero.herosubclass.berserker_desc=The Berserker gains rage as he takes physical damage, including damage that gets blocked by his armor! Rage steadily fades away over time, but fades more slowly if he is at low HP.\n\nThe Berserker deals up to +50% damage at 100% rage. At 100% rage he can also go berserk, gaining 2-6x his seal's maximum shielding depending on his missing health and keeping his rage at 100% as long as he has shielding left. However, the Berserker needs time to recover after he goes berserk. @@ -1095,6 +1100,7 @@ actors.mobs.npcs.wandmaker.intro_rogue=Oh Goodness, you startled me! I haven't m actors.mobs.npcs.wandmaker.intro_mage=Oh, hello %s! I heard there was some ruckus regarding you and the wizards institute? Oh never mind, I never liked those stick-in-the-muds anyway. If you're willing, I may have a task for you. actors.mobs.npcs.wandmaker.intro_huntress=Oh, hello miss! A friendly face is a pleasant surprise down here isn't it? In fact, I swear I've seen your face before, but I can't put my finger on it... Oh never mind, if you're here for adventure, I may have a task for you. actors.mobs.npcs.wandmaker.intro_duelist=Oh, hello miss! What a pleasant surprise to meet a hero in such a depressing place! If you're up to helping an old man out, I may have a task for you. +actors.mobs.npcs.wandmaker.intro_cleric=Oh, hello your highness! What a pleasant surprise to meet you in such a depressing place! I hate to impose, but I may have a task for you. actors.mobs.npcs.wandmaker.intro_1=\n\nI came here to find a rare ingredient for a wand, but I've gotten myself lost, and my magical shield is weakening. I'll need to leave soon, but can't bear to go without getting what I came for. actors.mobs.npcs.wandmaker.intro_dust=I'm looking for some _corpse dust._ It's a special kind of cursed bone meal that usually shows up in places like this. There should be a barricaded room around here somewhere, I'm sure some dust will turn up there. Do be careful though, the curse the dust carries is quite potent, _get back to me as fast as you can_ and I'll cleanse it for you. actors.mobs.npcs.wandmaker.intro_ember=I'm looking for some _fresh embers_ from a newborn fire elemental. Elementals usually pop up when a summoning ritual isn't controlled, so just find some candles and a ritual site and I'm sure you can get one to pop up. You'll want to _avoid boxing yourself in_ while fighting it though, or you could _keep some sort of freezing item handy._ Newborn Elementals are pretty powerful and chaotic, but they can't stand the cold. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java index da85fcfbc..bc754f51c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java @@ -67,6 +67,7 @@ public class Badges { MASTERY_ROGUE, MASTERY_HUNTRESS, MASTERY_DUELIST, + MASTERY_CLERIC, FOUND_RATMOGRIFY, //bronze @@ -125,6 +126,7 @@ public class Badges { BOSS_SLAIN_1_ROGUE, BOSS_SLAIN_1_HUNTRESS, BOSS_SLAIN_1_DUELIST, + BOSS_SLAIN_1_CLERIC, BOSS_SLAIN_1_ALL_CLASSES ( 54, BadgeType.GLOBAL ), RESEARCHER_2 ( 55, BadgeType.JOURNAL ), GAMES_PLAYED_2 ( 56, BadgeType.GLOBAL ), @@ -176,6 +178,7 @@ public class Badges { VICTORY_ROGUE, VICTORY_HUNTRESS, VICTORY_DUELIST, + VICTORY_CLERIC, VICTORY_ALL_CLASSES ( 101, BadgeType.GLOBAL ), DEATH_FROM_ALL ( 102, BadgeType.GLOBAL ), BOSS_SLAIN_3_GLADIATOR, @@ -786,6 +789,7 @@ public class Badges { firstBossClassBadges.put(HeroClass.ROGUE, Badge.BOSS_SLAIN_1_ROGUE); firstBossClassBadges.put(HeroClass.HUNTRESS, Badge.BOSS_SLAIN_1_HUNTRESS); firstBossClassBadges.put(HeroClass.DUELIST, Badge.BOSS_SLAIN_1_DUELIST); + firstBossClassBadges.put(HeroClass.CLERIC, Badge.BOSS_SLAIN_1_CLERIC); } private static LinkedHashMap victoryClassBadges = new LinkedHashMap<>(); @@ -795,6 +799,7 @@ public class Badges { victoryClassBadges.put(HeroClass.ROGUE, Badge.VICTORY_ROGUE); victoryClassBadges.put(HeroClass.HUNTRESS, Badge.VICTORY_HUNTRESS); victoryClassBadges.put(HeroClass.DUELIST, Badge.VICTORY_DUELIST); + victoryClassBadges.put(HeroClass.CLERIC, Badge.VICTORY_CLERIC); } private static LinkedHashMap thirdBossSubclassBadges = new LinkedHashMap<>(); @@ -928,6 +933,9 @@ public class Badges { case DUELIST: badge = Badge.MASTERY_DUELIST; break; + case CLERIC: + badge = Badge.MASTERY_CLERIC; + break; } unlock(badge); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java index 92bb5515f..fac472052 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java @@ -54,12 +54,14 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfInvisibility; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMindVision; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfLullaby; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMirrorImage; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRage; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfMagicMissile; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow; @@ -81,7 +83,8 @@ public enum HeroClass { MAGE( HeroSubClass.BATTLEMAGE, HeroSubClass.WARLOCK ), ROGUE( HeroSubClass.ASSASSIN, HeroSubClass.FREERUNNER ), HUNTRESS( HeroSubClass.SNIPER, HeroSubClass.WARDEN ), - DUELIST( HeroSubClass.CHAMPION, HeroSubClass.MONK ); + DUELIST( HeroSubClass.CHAMPION, HeroSubClass.MONK ), + CLERIC( HeroSubClass.GLADIATOR, HeroSubClass.WARDEN ); //TODO cleric subclasses private HeroSubClass[] subClasses; @@ -128,6 +131,10 @@ public enum HeroClass { case DUELIST: initDuelist( hero ); break; + + case CLERIC: + initCleric( hero ); + break; } if (SPDSettings.quickslotWaterskin()) { @@ -153,6 +160,8 @@ public enum HeroClass { return Badges.Badge.MASTERY_HUNTRESS; case DUELIST: return Badges.Badge.MASTERY_DUELIST; + case CLERIC: + return Badges.Badge.MASTERY_CLERIC; } return null; } @@ -230,6 +239,18 @@ public enum HeroClass { new ScrollOfMirrorImage().identify(); } + private static void initCleric( Hero hero ) { + + //TODO Cudgel + (hero.belongings.weapon = new Dagger()).identify(); + hero.belongings.weapon.activate(hero); + + //TODO Spellbook + + new PotionOfPurity().identify(); + new ScrollOfRemoveCurse().identify(); + } + public String title() { return Messages.get(HeroClass.class, name()); } @@ -258,6 +279,8 @@ public enum HeroClass { return new ArmorAbility[]{new SpectralBlades(), new NaturesPower(), new SpiritHawk()}; case DUELIST: return new ArmorAbility[]{new Challenge(), new ElementalStrike(), new Feint()}; + case CLERIC: //TODO CLERIC armor abilities + return new ArmorAbility[]{new HeroicLeap(), new Shockwave(), new Endure()}; } } @@ -273,6 +296,8 @@ public enum HeroClass { return Assets.Sprites.HUNTRESS; case DUELIST: return Assets.Sprites.DUELIST; + case CLERIC: //TODO CLERIC cleric sprites + return Assets.Sprites.HUNTRESS; } } @@ -288,6 +313,8 @@ public enum HeroClass { return Assets.Splashes.HUNTRESS; case DUELIST: return Assets.Splashes.DUELIST; + case CLERIC: //TODO CLERIC cleric splash + return Assets.Splashes.HUNTRESS; } } @@ -306,6 +333,8 @@ public enum HeroClass { return Badges.isUnlocked(Badges.Badge.UNLOCK_HUNTRESS); case DUELIST: return Badges.isUnlocked(Badges.Badge.UNLOCK_DUELIST); + case CLERIC: + return true; //TODO CLERIC cleric unlock badge } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java index fe6582778..b1223c7c0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java @@ -414,6 +414,8 @@ public enum Talent { return 122; case DUELIST: return 154; + case CLERIC: + return 26; //TODO CLERIC talent sprite here } } else { return icon; @@ -851,6 +853,9 @@ public enum Talent { case DUELIST: Collections.addAll(tierTalents, STRENGTHENING_MEAL, ADVENTURERS_INTUITION, PATIENT_STRIKE, AGGRESSIVE_BARRIER); break; + case CLERIC: //TODO CLERIC T1 + Collections.addAll(tierTalents, HEARTY_MEAL, VETERANS_INTUITION, PROVOKED_ANGER, IRON_WILL); + break; } for (Talent talent : tierTalents){ if (replacements.containsKey(talent)){ @@ -877,6 +882,9 @@ public enum Talent { case DUELIST: Collections.addAll(tierTalents, FOCUSED_MEAL, LIQUID_AGILITY, WEAPON_RECHARGING, LETHAL_HASTE, SWIFT_EQUIP); break; + case CLERIC: //TODO CLERIC T2 + Collections.addAll(tierTalents, IRON_STOMACH, LIQUID_WILLPOWER, RUNIC_TRANSFERENCE, LETHAL_MOMENTUM, IMPROVISED_PROJECTILES); + break; } for (Talent talent : tierTalents){ if (replacements.containsKey(talent)){ @@ -903,6 +911,9 @@ public enum Talent { case DUELIST: Collections.addAll(tierTalents, PRECISE_ASSAULT, DEADLY_FOLLOWUP); break; + case CLERIC: //TODO CLERIC T3 + Collections.addAll(tierTalents, HOLD_FAST, STRONGMAN); + break; } for (Talent talent : tierTalents){ if (replacements.containsKey(talent)){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java index 0291374dc..af1923dca 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java @@ -100,7 +100,7 @@ public class Blacksmith extends NPC { case ROGUE: msg1 += Messages.get(Blacksmith.this, "intro_quest_rogue"); break; case HUNTRESS: msg1 += Messages.get(Blacksmith.this, "intro_quest_huntress"); break; case DUELIST: msg1 += Messages.get(Blacksmith.this, "intro_quest_duelist"); break; - //case CLERIC: msg1 += Messages.get(Blacksmith.this, "intro_quest_cleric"); break; + case CLERIC: msg1 += Messages.get(Blacksmith.this, "intro_quest_cleric"); break; } msg1 += "\n\n" + Messages.get(Blacksmith.this, "intro_quest_start"); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java index 596bd6abc..7d9c03572 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java @@ -172,6 +172,9 @@ public class Wandmaker extends NPC { case DUELIST: msg1 += Messages.get(this, "intro_duelist"); break; + case CLERIC: + msg1 += Messages.get(this, "intro_cleric"); + break; } msg1 += Messages.get(this, "intro_1"); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/ClassArmor.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/ClassArmor.java index f2456e97d..ae94393fe 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/ClassArmor.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/ClassArmor.java @@ -114,6 +114,9 @@ abstract public class ClassArmor extends Armor { case DUELIST: classArmor = new DuelistArmor(); break; + case CLERIC: //TODO CLERIC class armor + classArmor = new WarriorArmor(); + break; } classArmor.level(armor.trueLevel()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/RemainsItem.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/RemainsItem.java index 55c4c251e..5352a7935 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/RemainsItem.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/RemainsItem.java @@ -90,6 +90,8 @@ public abstract class RemainsItem extends Item { return new BowFragment(); case DUELIST: return new BrokenHilt(); + case CLERIC: //TODO CLERIC remains item + return new SealShard(); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/HeroSelectScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/HeroSelectScene.java index eb1611961..635260a27 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/HeroSelectScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/HeroSelectScene.java @@ -175,6 +175,10 @@ public class HeroSelectScene extends PixelScene { add(infoButton); for (HeroClass cl : HeroClass.values()){ + //TODO CLERIC skip this when not in debug for now + if (cl == HeroClass.CLERIC && !DeviceCompat.isDebug()){ + continue; + } HeroBtn button = new HeroBtn(cl); add(button); heroBtns.add(button); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java index 9bab37fa6..2e41e49be 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java @@ -460,6 +460,8 @@ public enum Icons { return new ItemSprite(ItemSpriteSheet.SPIRIT_BOW); case DUELIST: return new ItemSprite(ItemSpriteSheet.RAPIER); + case CLERIC: //TODO CLERIC class sprite + return new ItemSprite(ItemSpriteSheet.MASTERY); default: return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndHeroInfo.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndHeroInfo.java index 2de2cda98..afe7097e4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndHeroInfo.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndHeroInfo.java @@ -73,6 +73,9 @@ public class WndHeroInfo extends WndTabbed { case DUELIST: tabIcon = new ItemSprite(ItemSpriteSheet.RAPIER, null); break; + case CLERIC: //TODO CLERIC + tabIcon = new ItemSprite(ItemSpriteSheet.MASTERY, null); + break; } int finalHeight = MIN_HEIGHT; @@ -198,6 +201,12 @@ public class WndHeroInfo extends WndTabbed { new ItemSprite(ItemSpriteSheet.THROWING_SPIKE), new ItemSprite(ItemSpriteSheet.SCROLL_ISAZ)}; break; + case CLERIC: //TODO CLERIC + icons = new Image[]{ new ItemSprite(ItemSpriteSheet.MASTERY), + Icons.TALENT.get(), + new ItemSprite(ItemSpriteSheet.MACE), + new ItemSprite(ItemSpriteSheet.SCROLL_ISAZ)}; + break; } for (Image im : icons) { add(im);