v2.5.0: added a new trinket: vial of blood

This commit is contained in:
Evan Debenham
2024-07-17 14:45:11 -04:00
parent c84e4852ee
commit ab7bcf027a
7 changed files with 149 additions and 13 deletions

View File

@@ -509,7 +509,7 @@ items.bombs.shockbomb.name=shock bomb
items.bombs.shockbomb.desc=This bomb has been modified to unleash bolts of electricity when it explodes. Anything nearby will be damaged and stunned based on how close it was to the bomb.
items.bombs.regrowthbomb.name=regrowth bomb
items.bombs.regrowthbomb.desc=This customized bomb will splash life-giving liquid all around it instead of exploding. The area caught in the blast will rapidly sprout grass and plants. Yourself and any allies caught in the blast will be healed.
items.bombs.regrowthbomb.desc=This customized bomb will splash life-giving liquid all around it instead of exploding. The area caught in the blast will rapidly sprout grass and plants. Yourself and any allies caught in the blast will be healed as if they had drank a potion of healing.
items.bombs.shrapnelbomb.name=shrapnel bomb
items.bombs.shrapnelbomb.desc=This bomb has been modified with scraps of DM-300's metal, which will fragment and fly everywhere when it explodes, damaging anything in a huge range around the bomb. You had better hide behind something when using it...
@@ -769,7 +769,7 @@ items.potions.elixirs.elixiroffeatherfall$featherbuff.name=feather fall
items.potions.elixirs.elixiroffeatherfall$featherbuff.desc=You are under the effects of a feather fall elixir, allowing you to fall into a chasm without taking damage! This effect will expire when it is used, or after a bit of time passes.\n\nTurns remaining: %s.
items.potions.elixirs.elixirofhoneyedhealing.name=elixir of honeyed healing
items.potions.elixirs.elixirofhoneyedhealing.desc=This elixir combines healing with the sweetness of honey. When drank, it will satisfy a small amount of hunger, but it can also be thrown to heal an ally.\n\nCreatures with an affinity for honey might be pacified if this item is used on them.
items.potions.elixirs.elixirofhoneyedhealing.desc=This elixir combines healing with the sweetness of honey. When drank, it will apply the same effect as a potion of healing and satisfy a small amount of hunger, but it can also be thrown to heal an ally.\n\nCreatures with an affinity for honey might be pacified if this item is used on them.
items.potions.elixirs.elixiroficytouch.name=elixir of icy touch
items.potions.elixirs.elixiroficytouch.desc=When consumed, this elixir will allow the drinker to sap the heat from enemies they attack. This effect will make the drinker immune to the cold, and allow them to chill enemies with physical attacks.
@@ -1371,6 +1371,11 @@ items.trinkets.trapmechanism.desc=The core mechanism of one of the dungeon's pit
items.trinkets.trapmechanism.typical_stats_desc=Typically this trinket will make _%d%%_ of regular floors become filled with either traps or chasms instead.\n\nThis trinket costs relatively little energy to upgrade.
items.trinkets.trapmechanism.stats_desc=At its current level this trinket will make _%d%%_ of regular floors become filled with either traps or chasms instead.\n\nThis trinket costs relatively little energy to upgrade.
items.trinkets.vialofblood.name=vial of blood
items.trinkets.vialofblood.desc=This thin vial contains the blood of some denizen of the dungeon, it moves slowly as you rotate the vial. It seems to be magically enhancing stronger healing effects, but also delaying them.
items.trinkets.vialofblood.typical_stats_desc=Typically this trinket will increase the overall health you gain from drinking potions of healing, waterskins, or wells of health by _%1$s%%_. However, these healing effects will also occur more slowly, regenerating a maximum of _%2$s_ HP per turn this scales with hero level).
items.trinkets.vialofblood.stats_desc=At its current level this trinket will increase the overall health you gain from drinking potions of healing, waterskins, or wells of health by _%1$s%%_. However, these healing effects will also occur more slowly, regenerating a maximum of _%2$s_ HP per turn (this scales with hero level).
items.trinkets.wondrousresin.name=wondrous resin
items.trinkets.wondrousresin.desc=This shimmering blue resin appears to have the distilled essence of a cursed wand's magic. The magic from the alchemy pot has seemed to stabilize it somewhat, and it's now affecting your wands.
items.trinkets.wondrousresin.typical_stats_desc=Typically this trinket will force cursed wand effects to become neutral or positive _%1$s%%_ of the time, and will cause uncursed wands to fire an additional neutral or positive cursed zap _%2$s%%_ of the time.\n\nThis trinket costs a moderately large amount of energy to upgrade.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -23,6 +23,8 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.blobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Healing;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
@@ -36,6 +38,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.Waterskin;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.VialOfBlood;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes.Landmark;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
@@ -55,9 +58,15 @@ public class WaterOfHealth extends WellWater {
hero.belongings.uncurseEquipped();
hero.buff( Hunger.class ).satisfy( Hunger.STARVING );
hero.HP = hero.HT;
hero.sprite.emitter().start( Speck.factory( Speck.HEALING ), 0.4f, 4 );
hero.sprite.showStatusWithIcon(CharSprite.POSITIVE, Integer.toString(hero.HT), FloatingText.HEALING);
if (VialOfBlood.delayBurstHealing()){
Healing healing = Buff.affect(hero, Healing.class);
healing.setHeal(hero.HT, 0, VialOfBlood.maxHealPerTurn());
healing.applyVialEffect();
} else {
hero.HP = hero.HT;
hero.sprite.emitter().start(Speck.factory(Speck.HEALING), 0.4f, 4);
hero.sprite.showStatusWithIcon(CharSprite.POSITIVE, Integer.toString(hero.HT), FloatingText.HEALING);
}
CellEmitter.get( hero.pos ).start( ShaftParticle.FACTORY, 0.2f, 3 );

View File

@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.VialOfBlood;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
@@ -35,6 +36,8 @@ public class Healing extends Buff {
private float percentHealPerTick;
private int flatHealPerTick;
private boolean healingLimited = false;
{
//unlike other buffs, this one acts after the hero and takes priority against other effects
@@ -53,10 +56,9 @@ public class Healing extends Buff {
if (target.HP == target.HT && target instanceof Hero) {
((Hero) target).resting = false;
}
target.sprite.showStatusWithIcon(CharSprite.POSITIVE, Integer.toString(healingThisTick()), FloatingText.HEALING);
}
target.sprite.showStatusWithIcon(CharSprite.POSITIVE, Integer.toString(healingThisTick()), FloatingText.HEALING);
healingLeft -= healingThisTick();
if (healingLeft <= 0){
@@ -72,9 +74,13 @@ public class Healing extends Buff {
}
private int healingThisTick(){
return (int)GameMath.gate(1,
int heal = (int)GameMath.gate(1,
Math.round(healingLeft * percentHealPerTick) + flatHealPerTick,
healingLeft);
if (healingLimited && heal > VialOfBlood.maxHealPerTurn()){
heal = VialOfBlood.maxHealPerTurn();
}
return heal;
}
public void setHeal(int amount, float percentPerTick, int flatPerTick){
@@ -83,6 +89,13 @@ public class Healing extends Buff {
percentHealPerTick = Math.max(percentHealPerTick, percentPerTick);
flatHealPerTick = Math.max(flatHealPerTick, flatPerTick);
}
public void applyVialEffect(){
healingLimited = VialOfBlood.delayBurstHealing();
if (healingLimited){
healingLeft = Math.round(healingLeft*VialOfBlood.totalHealMultiplier());
}
}
public void increaseHeal( int amount ){
healingLeft += amount;
@@ -97,6 +110,8 @@ public class Healing extends Buff {
private static final String LEFT = "left";
private static final String PERCENT = "percent";
private static final String FLAT = "flat";
private static final String HEALING_LIMITED = "healing_limited";
@Override
public void storeInBundle(Bundle bundle) {
@@ -104,6 +119,7 @@ public class Healing extends Buff {
bundle.put(LEFT, healingLeft);
bundle.put(PERCENT, percentHealPerTick);
bundle.put(FLAT, flatHealPerTick);
bundle.put(HEALING_LIMITED, healingLimited);
}
@Override
@@ -112,6 +128,7 @@ public class Healing extends Buff {
healingLeft = bundle.getInt(LEFT);
percentHealPerTick = bundle.getFloat(PERCENT);
flatHealPerTick = bundle.getInt(FLAT);
healingLimited = bundle.getBoolean(HEALING_LIMITED);
}
@Override

View File

@@ -25,9 +25,11 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Healing;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.VialOfBlood;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -89,12 +91,20 @@ public class Dewdrop extends Item {
shield = Math.min(shield, maxShield-curShield);
}
if (effect > 0 || shield > 0) {
hero.HP += effect;
if (shield > 0) Buff.affect(hero, Barrier.class).incShield(shield);
if (effect > 0){
hero.sprite.showStatusWithIcon( CharSprite.POSITIVE, Integer.toString(effect), FloatingText.HEALING);
if (effect > 0 && quantity > 1 && VialOfBlood.delayBurstHealing()){
Healing healing = Buff.affect(hero, Healing.class);
healing.setHeal(effect, 0, VialOfBlood.maxHealPerTurn());
healing.applyVialEffect();
} else {
hero.HP += effect;
if (effect > 0){
hero.sprite.showStatusWithIcon( CharSprite.POSITIVE, Integer.toString(effect), FloatingText.HEALING);
}
}
if (shield > 0) {
Buff.affect(hero, Barrier.class).incShield(shield);
hero.sprite.showStatusWithIcon( CharSprite.POSITIVE, Integer.toString(shield), FloatingText.SHIELDING );
}

View File

@@ -60,7 +60,9 @@ public class PotionOfHealing extends Potion {
pharmacophobiaProc(Dungeon.hero);
} else {
//starts out healing 30 hp, equalizes with hero health total at level 11
Buff.affect(ch, Healing.class).setHeal((int) (0.8f * ch.HT + 14), 0.25f, 0);
Healing healing = Buff.affect(ch, Healing.class);
healing.setHeal((int) (0.8f * ch.HT + 14), 0.25f, 0);
healing.applyVialEffect();
if (ch == Dungeon.hero){
GLog.p( Messages.get(PotionOfHealing.class, "heal") );
}

View File

@@ -0,0 +1,93 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2024 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.trinkets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
public class VialOfBlood extends Trinket {
{
image = ItemSpriteSheet.ARTIFACT_HOURGLASS;
}
@Override
protected int upgradeEnergyCost() {
//5 -> 8(13) -> 10(23) -> 12(35)
return 6+2*level();
}
@Override
public String statsDesc() {
if (isIdentified()){
return Messages.get(this,
"stats_desc",
Messages.decimalFormat("#.##", 100*(totalHealMultiplier(buffedLvl())-1f)),
Integer.toString(maxHealPerTurn(buffedLvl())));
} else {
return Messages.get(this,
"typical_stats_desc",
Messages.decimalFormat("#.##", 100*(totalHealMultiplier(buffedLvl())-1f)),
Integer.toString(maxHealPerTurn(buffedLvl())));
}
}
public static boolean delayBurstHealing(){
return trinketLevel(VialOfBlood.class) != -1;
}
public static float totalHealMultiplier(){
return totalHealMultiplier(trinketLevel(VialOfBlood.class));
}
public static float totalHealMultiplier(int level){
if (level == -1){
return 1;
} else {
return 1f + 0.125f*(level+1);
}
}
public static int maxHealPerTurn(){
return maxHealPerTurn(trinketLevel(VialOfBlood.class));
}
public static int maxHealPerTurn(int level){
int maxHP = Dungeon.hero == null ? 20 : Dungeon.hero.HT;
if (level == -1){
return maxHP;
} else {
switch (level){
case 0: default:
return 4 + Math.round(0.15f*maxHP);
case 1:
return 3 + Math.round(0.10f*maxHP);
case 2:
return 2 + Math.round(0.07f*maxHP);
case 3:
return 1 + Math.round(0.05f*maxHP);
}
}
}
}