v2.4.0: mostly implemented the wondrous resin trinket

This commit is contained in:
Evan Debenham
2024-05-07 15:59:51 -04:00
parent ef2fec4c8c
commit f278a60929
7 changed files with 115 additions and 14 deletions

View File

@@ -1324,6 +1324,9 @@ items.trinkets.thirteenleafclover.desc=Somehow stewing in the alchemy pot has ca
items.trinkets.trapmechanism.name=trap mechanism
items.trinkets.trapmechanism.desc=The core mechanism of one of the dungeon's pitfall traps, carefully carved out of the floor so it can be carried. It seems to be magically tied to the dungeon itself, making terrain more hazardous for you and the dungeon's inhabitants.\n\nAt its current level this trinket will make _%d%%_ of regular floors become filled with either traps or chasms instead.
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 post has seemed to stabilize it somewhat, and its now affecting your wands.\n\nAt its current level this trinket will cause cursed wand effects to be forced positive _%1$s%%_ of the time, and will cause uncursed wands to fire an additional cursed zap _%2$s%%_ of the time.\n\nThis trinket costs a relatively large amount of energy to upgrade.
items.trinkets.trinketcatalyst.name=magical catalyst
items.trinkets.trinketcatalyst.window_text=The water begins to glow as you add the catalyst. There are a few nearby items you could imbue with energy to turn into a magical trinket.
items.trinkets.trinketcatalyst.desc=This ball of magical golden dust glimmers in the darkness of the dungeon. This catalyst can be used at an alchemy pot with a little alchemical energy to produce a unique trinket item.\n\nTrinkets provide various different effects that slightly alter the dungeon or its inhabitants. Trinkets can be upgraded with more energy to make their effect more powerful, or dropped to forego the effect entirely.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -117,6 +117,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.ThirteenLeafClove
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.TrapMechanism;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.Trinket;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.TrinketCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.WondrousResin;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfCorrosion;
@@ -566,9 +567,10 @@ public class Generator {
MossyClump.class,
DimensionalSundial.class,
ThirteenLeafClover.class,
TrapMechanism.class
TrapMechanism.class,
WondrousResin.class
};
TRINKET.defaultProbs = new float[]{ 1, 1, 1, 1, 1, 1, 1, 1, 1 };
TRINKET.defaultProbs = new float[]{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
TRINKET.probs = TRINKET.defaultProbs.clone();
for (Category cat : Category.values()){

View File

@@ -0,0 +1,73 @@
/*
* 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.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
public class WondrousResin extends Trinket {
{
image = ItemSpriteSheet.WONDROUS_RESIN;
}
@Override
protected int upgradeEnergyCost() {
//5 -> 10(15) -> 15(30) -> 20(50)
return 10+5*level();
}
@Override
public String desc() {
return Messages.get(this, "desc",
Messages.decimalFormat("#.##", 100*positiveCurseEffectChance(buffedLvl())),
Messages.decimalFormat("#.##", 100*extraCurseEffectChance(buffedLvl())));
}
//TODO currently this trims most rare/v.rare wand effects entirely. Need to improve variety there
// certain effects might also be extremely good with no negatives
public static float positiveCurseEffectChance(){
return positiveCurseEffectChance( trinketLevel(WondrousResin.class) );
}
public static float positiveCurseEffectChance(int level ){
if (level >= 0){
return 0.25f + 0.25f * level;
} else {
return 0;
}
}
public static float extraCurseEffectChance(){
return extraCurseEffectChance( trinketLevel(WondrousResin.class) );
}
public static float extraCurseEffectChance( int level ){
if (level >= 0){
return 0.125f + 0.125f * level;
} else {
return 0;
}
}
}

View File

@@ -54,6 +54,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.WondrousResin;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap;
@@ -123,6 +124,7 @@ public class CursedWand {
}
private static boolean commonEffect(final Item origin, final Char user, final int targetPos){
boolean positiveOnly = Random.Float() < WondrousResin.positiveCurseEffectChance();
switch(Random.Int(4)){
//anti-entropy
@@ -130,9 +132,9 @@ public class CursedWand {
Char target = Actor.findChar(targetPos);
if (Random.Int(2) == 0) {
if (target != null) Buff.affect(target, Burning.class).reignite(target);
Buff.affect(user, Frost.class, Frost.DURATION);
if (!positiveOnly) Buff.affect(user, Frost.class, Frost.DURATION);
} else {
Buff.affect(user, Burning.class).reignite(user);
if (!positiveOnly)Buff.affect(user, Burning.class).reignite(user);
if (target != null) Buff.affect(target, Frost.class, Frost.DURATION);
}
tryForWandProc(target, origin);
@@ -146,7 +148,7 @@ public class CursedWand {
//random teleportation
case 2:
if(Random.Int(2) == 0) {
if(!positiveOnly && Random.Int(2) == 0) {
if (user != null && !user.properties().contains(Char.Property.IMMOVABLE)) {
ScrollOfTeleportation.teleportChar(user);
} else {
@@ -183,6 +185,7 @@ public class CursedWand {
}
private static boolean uncommonEffect(final Item origin, final Char user, final int targetPos){
boolean positiveOnly = Random.Float() < WondrousResin.positiveCurseEffectChance();
switch(Random.Int(4)){
//Random plant
@@ -208,7 +211,7 @@ public class CursedWand {
int damage = Dungeon.scalingDepth() * 2;
Char toHeal, toDamage;
if (Random.Int(2) == 0){
if (positiveOnly || Random.Int(2) == 0){
toHeal = user;
toDamage = target;
} else {
@@ -251,7 +254,7 @@ public class CursedWand {
//shock and recharge
case 3:
new ShockingTrap().set( user.pos ).activate();
if (!positiveOnly) new ShockingTrap().set( user.pos ).activate();
Buff.prolong(user, Recharging.class, Recharging.DURATION);
ScrollOfRecharging.charge(user);
SpellSprite.show(user, SpellSprite.CHARGE);
@@ -261,7 +264,8 @@ public class CursedWand {
}
private static boolean rareEffect(final Item origin, final Char user, final int targetPos){
switch(Random.Int(4)){
boolean positiveOnly = Random.Float() < WondrousResin.positiveCurseEffectChance();
switch(positiveOnly ? 0 : Random.Int(4)){
//sheep transformation
case 0: default:
@@ -325,20 +329,24 @@ public class CursedWand {
}
private static boolean veryRareEffect(final Item origin, final Char user, final int targetPos){
switch(Random.Int(4)){
boolean positiveOnly = Random.Float() < WondrousResin.positiveCurseEffectChance();
switch( positiveOnly ? 0 : Random.Int(4) ){
//great forest fire!
case 0: default:
for (int i = 0; i < Dungeon.level.length(); i++){
GameScene.add( Blob.seed(i, 15, Regrowth.class));
}
do {
GameScene.add(Blob.seed(Dungeon.level.randomDestination(null), 10, Fire.class));
} while (Random.Int(5) != 0);
new Flare(8, 32).color(0xFFFF66, true).show(user.sprite, 2f);
Sample.INSTANCE.play(Assets.Sounds.TELEPORT);
GLog.p(Messages.get(CursedWand.class, "grass"));
GLog.w(Messages.get(CursedWand.class, "fire"));
if (!positiveOnly) {
GLog.w(Messages.get(CursedWand.class, "fire"));
do {
GameScene.add(Blob.seed(Dungeon.level.randomDestination(null), 10, Fire.class));
} while (Random.Int(5) != 0);
}
return true;
//golden mimic

View File

@@ -48,6 +48,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.MagicalHolster;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging;
import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.WondrousResin;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -683,9 +684,21 @@ public abstract class Wand extends Item {
curWand.fx(shot, new Callback() {
public void call() {
curWand.onZap(shot);
curWand.wandUsed();
if (Random.Float() < WondrousResin.extraCurseEffectChance()){
CursedWand.cursedZap(curWand,
curUser,
new Ballistica(curUser.pos, target, Ballistica.MAGIC_BOLT), new Callback() {
@Override
public void call() {
curWand.wandUsed();
}
});
} else {
curWand.wandUsed();
}
}
});
}
curWand.cursedKnown = true;

View File

@@ -481,6 +481,7 @@ public class ItemSpriteSheet {
public static final int CLOVER = TRINKETS+6;
public static final int TRAP_MECHANISM = TRINKETS+7;
public static final int MIMIC_TOOTH = TRINKETS+8;
public static final int WONDROUS_RESIN = TRINKETS+9;
static{
assignItemRect(RAT_SKULL, 16, 11);
assignItemRect(PARCHMENT_SCRAP, 10, 14);
@@ -491,6 +492,7 @@ public class ItemSpriteSheet {
assignItemRect(CLOVER, 11, 15);
assignItemRect(TRAP_MECHANISM, 13, 15);
assignItemRect(MIMIC_TOOTH, 8, 15);
assignItemRect(WONDROUS_RESIN, 12, 11);
}
private static final int SCROLLS = xy(1, 19); //16 slots