v0.8.0: fixes/tweaks:

- fixed multiple bomb explosions killing characters many times
- fixed shops selling rarer thrown weapons instead of more common ones
- improved logic for shop bag selection. Now considers all bag-storable items and slightly favors velvet pouch
- fixed mimics spawning in treasury rooms on floor 1
- fixed poison dart traps not dealing updated damage in some cases
- items no longer spawn on top of enemies
- fixed blacksmith not accounting for curse infusion bonus
- fixed mimics attacking when time freeze is active
- fixed assassin prep attack not working on hidden mimics
- removed a bunch of unnecessary resistances and immunities from regular enemies
This commit is contained in:
Evan Debenham 2019-12-24 19:38:12 -05:00
parent 58d70e94d1
commit 4ef960e0f9
19 changed files with 74 additions and 105 deletions

View File

@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroAction;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Rat;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
@ -240,9 +241,8 @@ public class Preparation extends Buff implements ActionIndicator.Action {
//just attack them then!
if (Dungeon.hero.canAttack(enemy)){
if (Dungeon.hero.handle( cell )) {
Dungeon.hero.next();
}
Dungeon.hero.curAction = new HeroAction.Attack( enemy );
Dungeon.hero.next();
return;
}
@ -283,9 +283,8 @@ public class Preparation extends Buff implements ActionIndicator.Action {
CellEmitter.get( Dungeon.hero.pos ).burst( Speck.factory( Speck.WOOL ), 6 );
Sample.INSTANCE.play( Assets.SND_PUFF );
if (Dungeon.hero.handle( cell )) {
Dungeon.hero.next();
}
Dungeon.hero.curAction = new HeroAction.Attack( enemy );
Dungeon.hero.next();
}
}

View File

@ -199,9 +199,4 @@ public class Bee extends Mob {
return super.description();
}
}
{
immunities.add( Poison.class );
immunities.add( Amok.class );
}
}

View File

@ -113,10 +113,6 @@ public class Brute extends Mob {
hasRaged = bundle.getBoolean(HAS_RAGED);
}
{
immunities.add( Terror.class );
}
public static class BruteRage extends ShieldBuff {
{
@ -157,5 +153,8 @@ public class Brute extends Mob {
return Messages.get(this, "desc", shielding());
}
{
immunities.add(Terror.class);
}
}
}

View File

@ -240,7 +240,6 @@ public class Eye extends Mob {
{
resistances.add( WandOfDisintegration.class );
resistances.add( Grim.class );
}
{

View File

@ -211,9 +211,4 @@ public class Golem extends Mob {
}
}
{
immunities.add( Amok.class );
immunities.add( Terror.class );
immunities.add( Sleep.class );
}
}

View File

@ -33,10 +33,9 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.plants.Swiftthistle;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
@ -133,10 +132,19 @@ public class Mimic extends Mob {
return super.interact();
}
stopHiding();
doAttack(Dungeon.hero);
Dungeon.hero.busy();
Dungeon.hero.sprite.operate(pos);
return false;
if (Dungeon.hero.invisible <= 0
&& Dungeon.hero.buff(Swiftthistle.TimeBubble.class) == null
&& Dungeon.hero.buff(TimekeepersHourglass.timeFreeze.class) == null){
return doAttack(Dungeon.hero);
} else {
sprite.idle();
alignment = Alignment.ENEMY;
Dungeon.hero.spendAndNext(1f);
return true;
}
}
@Override
@ -286,8 +294,4 @@ public class Mimic extends Mob {
items.add(reward);
}
{
immunities.add( ScrollOfRetribution.class );
immunities.add( ScrollOfPsionicBlast.class );
}
}

View File

@ -122,11 +122,6 @@ public class Monk extends Mob {
}
}
{
immunities.add( Amok.class );
immunities.add( Terror.class );
}
private static String FOCUS_COOLDOWN = "focus_cooldown";
@Override

View File

@ -148,7 +148,6 @@ public class Piranha extends Mob {
{
immunities.add( Burning.class );
immunities.add( Vertigo.class );
}
//if there is not a path to the enemy, piranhas act as if they can't see them

View File

@ -164,7 +164,6 @@ public class Succubus extends Mob {
}
{
immunities.add( Sleep.class );
immunities.add( Charm.class );
}
}

View File

@ -150,8 +150,4 @@ public class Warlock extends Mob implements Callback {
return loot;
}
{
resistances.add( Grim.class );
}
}

View File

@ -124,8 +124,4 @@ public class Wraith extends Mob {
}
}
{
immunities.add( Grim.class );
immunities.add( Terror.class );
}
}

View File

@ -33,6 +33,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.DarkGold;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
@ -227,7 +229,12 @@ public class Blacksmith extends NPC {
if (first instanceof MissileWeapon && first.quantity() > 1){
first = first.split(1);
}
first.level(first.level()+1); //prevents on-upgrade effects like enchant/glyph removal
int level = first.level();
//adjust for curse infusion
if (first instanceof Weapon && ((Weapon) first).curseInfusionBonus) level--;
if (first instanceof Armor && ((Armor) first).curseInfusionBonus) level--;
if (first instanceof Wand && ((Wand) first).curseInfusionBonus) level--;
first.level(level+1); //prevents on-upgrade effects like enchant/glyph removal
if (first instanceof MissileWeapon && !Dungeon.hero.belongings.contains(first)) {
if (!first.collect()){
Dungeon.level.drop( first, Dungeon.hero.pos );

View File

@ -192,11 +192,6 @@ public class Ghost extends NPC {
return false;
}
{
immunities.add( Paralysis.class );
immunities.add( Roots.class );
}
public static class Quest {
private static boolean spawned;

View File

@ -172,6 +172,12 @@ public class Bomb extends Item {
}
for (Char ch : affected){
//if they have already been killed by another bomb
if(!ch.isAlive()){
continue;
}
int dmg = Random.NormalIntRange(5 + Dungeon.depth, 10 + Dungeon.depth*2);
//those not at the center of the blast take less damage

View File

@ -450,7 +450,8 @@ public abstract class RegularLevel extends Level {
int pos = pointToCell(room.random());
if (passable[pos]
&& pos != exit
&& heaps.get(pos) == null) {
&& heaps.get(pos) == null
&& Actor.findChar(pos) == null) {
Trap t = traps.get(pos);

View File

@ -45,15 +45,11 @@ import com.shatteredpixel.shatteredpixeldungeon.items.bags.ScrollHolder;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.VelvetPouch;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAugmentation;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BattleAxe;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.HandAxe;
@ -62,11 +58,10 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Mace;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Shortsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Sword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WarHammer;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Bolas;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.FishingSpear;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Javelin;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Shuriken;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Kunai;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingClub;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingHammer;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingSpear;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Tomahawk;
@ -80,6 +75,7 @@ import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
import java.util.HashMap;
public class ShopRoom extends SpecialRoom {
@ -172,7 +168,7 @@ public class ShopRoom extends SpecialRoom {
itemsToSpawn.add( (Random.Int( 2 ) == 0 ? new Shortsword().identify() : new HandAxe()).identify() );
itemsToSpawn.add( Random.Int( 2 ) == 0 ?
new FishingSpear().quantity(2) :
new Shuriken().quantity(2));
new ThrowingClub().quantity(2));
itemsToSpawn.add( new LeatherArmor().identify() );
break;
@ -180,7 +176,7 @@ public class ShopRoom extends SpecialRoom {
itemsToSpawn.add( (Random.Int( 2 ) == 0 ? new Sword().identify() : new Mace()).identify() );
itemsToSpawn.add( Random.Int( 2 ) == 0 ?
new ThrowingSpear().quantity(2) :
new Bolas().quantity(2));
new Kunai().quantity(2));
itemsToSpawn.add( new MailArmor().identify() );
break;
@ -298,48 +294,36 @@ public class ShopRoom extends SpecialRoom {
protected static Bag ChooseBag(Belongings pack){
//0=pouch, 1=holder, 2=bandolier, 3=holster
int[] bagItems = new int[4];
//generate a hashmap of all valid bags.
HashMap<Bag, Integer> bags = new HashMap<>();
if (!Dungeon.LimitedDrops.VELVET_POUCH.dropped()) bags.put(new VelvetPouch(), 1);
if (!Dungeon.LimitedDrops.SCROLL_HOLDER.dropped()) bags.put(new ScrollHolder(), 0);
if (!Dungeon.LimitedDrops.POTION_BANDOLIER.dropped()) bags.put(new PotionBandolier(), 0);
if (!Dungeon.LimitedDrops.MAGICAL_HOLSTER.dropped()) bags.put(new MagicalHolster(), 0);
if (bags.isEmpty()) return null;
//count up items in the main bag
for (Item item : pack.backpack.items) {
if (item instanceof Plant.Seed || item instanceof Runestone) bagItems[0]++;
if (item instanceof Scroll) bagItems[1]++;
if (item instanceof Potion) bagItems[2]++;
if (item instanceof Wand || item instanceof MissileWeapon) bagItems[3]++;
}
//disqualify bags that have already been dropped
if (Dungeon.LimitedDrops.VELVET_POUCH.dropped()) bagItems[0] = -1;
if (Dungeon.LimitedDrops.SCROLL_HOLDER.dropped()) bagItems[1] = -1;
if (Dungeon.LimitedDrops.POTION_BANDOLIER.dropped()) bagItems[2] = -1;
if (Dungeon.LimitedDrops.MAGICAL_HOLSTER.dropped()) bagItems[3] = -1;
//find the best bag to drop. This does give a preference to later bags, if counts are equal
int bestBagIdx = 0;
for (int i = 1; i <= 3; i++){
if (bagItems[bestBagIdx] <= bagItems[i]){
bestBagIdx = i;
for (Bag bag : bags.keySet()){
if (bag.grab(item)){
bags.put(bag, bags.get(bag)+1);
}
}
}
//drop it, or return nothing if no bag works
if (bagItems[bestBagIdx] == -1) return null;
switch (bestBagIdx){
case 0: default:
Dungeon.LimitedDrops.VELVET_POUCH.drop();
return new VelvetPouch();
case 1:
Dungeon.LimitedDrops.SCROLL_HOLDER.drop();
return new ScrollHolder();
case 2:
Dungeon.LimitedDrops.POTION_BANDOLIER.drop();
return new PotionBandolier();
case 3:
Dungeon.LimitedDrops.MAGICAL_HOLSTER.drop();
return new MagicalHolster();
//find which bag will result in most inventory savings, drop that.
Bag bestBag = null;
for (Bag bag : bags.keySet()){
if (bestBag == null){
bestBag = bag;
} else if (bags.get(bag) > bags.get(bestBag)){
bestBag = bag;
}
}
return bestBag;
}
}

View File

@ -48,7 +48,7 @@ public class TreasuryRoom extends SpecialRoom {
do {
pos = level.pointToCell(random());
} while (level.map[pos] != Terrain.EMPTY || level.heaps.get( pos ) != null);
if (heapType == Heap.Type.CHEST && Random.Int(5 ) == 0){
if (heapType == Heap.Type.CHEST && Dungeon.depth > 1 && Random.Int( 5 ) == 0){
level.mobs.add(Mimic.spawnAt(pos, new Gold().random()));
} else {
level.drop( new Gold().random(), pos ).type = heapType;

View File

@ -105,7 +105,7 @@ public class PoisonDartTrap extends Trap {
}
});
} else {
finalTarget.damage(Random.NormalIntRange(1, 4) - finalTarget.drRoll(), trap);
finalTarget.damage(Random.NormalIntRange(4, 8) - finalTarget.drRoll(), trap);
Buff.affect( finalTarget, Poison.class ).set( poisonAmount() );
}
}

View File

@ -90,7 +90,7 @@ public class WornDartTrap extends Trap {
}
});
} else {
finalTarget.damage(Random.NormalIntRange(1, 4) - finalTarget.drRoll(), trap);
finalTarget.damage(Random.NormalIntRange(4, 8) - finalTarget.drRoll(), trap);
}
}
}