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

View File

@ -199,9 +199,4 @@ public class Bee extends Mob {
return super.description(); 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); hasRaged = bundle.getBoolean(HAS_RAGED);
} }
{
immunities.add( Terror.class );
}
public static class BruteRage extends ShieldBuff { public static class BruteRage extends ShieldBuff {
{ {
@ -156,6 +152,9 @@ public class Brute extends Mob {
public String desc () { public String desc () {
return Messages.get(this, "desc", shielding()); 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( WandOfDisintegration.class );
resistances.add( Grim.class );
} }
{ {

View File

@ -210,10 +210,5 @@ 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.Gold;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; 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.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
@ -133,10 +132,19 @@ public class Mimic extends Mob {
return super.interact(); return super.interact();
} }
stopHiding(); stopHiding();
doAttack(Dungeon.hero);
Dungeon.hero.busy(); Dungeon.hero.busy();
Dungeon.hero.sprite.operate(pos); 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 @Override
@ -285,9 +293,5 @@ public class Mimic extends Mob {
} while (reward == null || Challenges.isItemBlocked(reward)); } while (reward == null || Challenges.isItemBlocked(reward));
items.add(reward); 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"; private static String FOCUS_COOLDOWN = "focus_cooldown";
@Override @Override

View File

@ -148,7 +148,6 @@ public class Piranha extends Mob {
{ {
immunities.add( Burning.class ); 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 //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 ); immunities.add( Charm.class );
} }
} }

View File

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

View File

@ -123,9 +123,5 @@ public class Wraith extends Mob {
return null; return null;
} }
} }
{
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.DarkGold;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe; import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade; 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.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes; import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
@ -227,7 +229,12 @@ public class Blacksmith extends NPC {
if (first instanceof MissileWeapon && first.quantity() > 1){ if (first instanceof MissileWeapon && first.quantity() > 1){
first = first.split(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 instanceof MissileWeapon && !Dungeon.hero.belongings.contains(first)) {
if (!first.collect()){ if (!first.collect()){
Dungeon.level.drop( first, Dungeon.hero.pos ); Dungeon.level.drop( first, Dungeon.hero.pos );

View File

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

View File

@ -172,6 +172,12 @@ public class Bomb extends Item {
} }
for (Char ch : affected){ 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); int dmg = Random.NormalIntRange(5 + Dungeon.depth, 10 + Dungeon.depth*2);
//those not at the center of the blast take less damage //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()); int pos = pointToCell(room.random());
if (passable[pos] if (passable[pos]
&& pos != exit && pos != exit
&& heaps.get(pos) == null) { && heaps.get(pos) == null
&& Actor.findChar(pos) == null) {
Trap t = traps.get(pos); 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.bags.VelvetPouch;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb; import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation; 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.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse; 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.stones.StoneOfAugmentation;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BattleAxe; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BattleAxe;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatsword; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.HandAxe; 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.Shortsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Sword; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Sword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WarHammer; 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.FishingSpear;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Javelin; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Javelin;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Kunai;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Shuriken; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingClub;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingHammer; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingHammer;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingSpear; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.ThrowingSpear;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Tomahawk; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Tomahawk;
@ -80,6 +75,7 @@ import com.watabou.utils.Point;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
public class ShopRoom extends SpecialRoom { 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 Shortsword().identify() : new HandAxe()).identify() );
itemsToSpawn.add( Random.Int( 2 ) == 0 ? itemsToSpawn.add( Random.Int( 2 ) == 0 ?
new FishingSpear().quantity(2) : new FishingSpear().quantity(2) :
new Shuriken().quantity(2)); new ThrowingClub().quantity(2));
itemsToSpawn.add( new LeatherArmor().identify() ); itemsToSpawn.add( new LeatherArmor().identify() );
break; 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 Sword().identify() : new Mace()).identify() );
itemsToSpawn.add( Random.Int( 2 ) == 0 ? itemsToSpawn.add( Random.Int( 2 ) == 0 ?
new ThrowingSpear().quantity(2) : new ThrowingSpear().quantity(2) :
new Bolas().quantity(2)); new Kunai().quantity(2));
itemsToSpawn.add( new MailArmor().identify() ); itemsToSpawn.add( new MailArmor().identify() );
break; break;
@ -297,49 +293,37 @@ public class ShopRoom extends SpecialRoom {
} }
protected static Bag ChooseBag(Belongings pack){ protected static Bag ChooseBag(Belongings pack){
//0=pouch, 1=holder, 2=bandolier, 3=holster //generate a hashmap of all valid bags.
int[] bagItems = new int[4]; 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 //count up items in the main bag
for (Item item : pack.backpack.items) { for (Item item : pack.backpack.items) {
if (item instanceof Plant.Seed || item instanceof Runestone) bagItems[0]++; for (Bag bag : bags.keySet()){
if (item instanceof Scroll) bagItems[1]++; if (bag.grab(item)){
if (item instanceof Potion) bagItems[2]++; bags.put(bag, bags.get(bag)+1);
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;
} }
} }
//drop it, or return nothing if no bag works //find which bag will result in most inventory savings, drop that.
if (bagItems[bestBagIdx] == -1) return null; Bag bestBag = null;
switch (bestBagIdx){ for (Bag bag : bags.keySet()){
case 0: default: if (bestBag == null){
Dungeon.LimitedDrops.VELVET_POUCH.drop(); bestBag = bag;
return new VelvetPouch(); } else if (bags.get(bag) > bags.get(bestBag)){
case 1: bestBag = bag;
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();
} }
return bestBag;
} }
} }

View File

@ -48,7 +48,7 @@ public class TreasuryRoom extends SpecialRoom {
do { do {
pos = level.pointToCell(random()); pos = level.pointToCell(random());
} while (level.map[pos] != Terrain.EMPTY || level.heaps.get( pos ) != null); } 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())); level.mobs.add(Mimic.spawnAt(pos, new Gold().random()));
} else { } else {
level.drop( new Gold().random(), pos ).type = heapType; level.drop( new Gold().random(), pos ).type = heapType;

View File

@ -105,7 +105,7 @@ public class PoisonDartTrap extends Trap {
} }
}); });
} else { } 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() ); Buff.affect( finalTarget, Poison.class ).set( poisonAmount() );
} }
} }

View File

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