From f6054cc8967532f208c9003d5fe6841d13acd80f Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 23 Nov 2023 14:04:34 -0500 Subject: [PATCH] v2.3.0: remains changes: - remains now include an extra item based on the class of the hero who died, these either appear on their own instead of gold drops, or in addition to a regular remains drop - capped the quantity scaling of consumable items left by remains at 3 - fixed extremely rare cases of remains affecting small parts of levelgen --- .../assets/messages/items/items.properties | 15 +++ core/src/main/assets/sprites/items.png | Bin 21048 -> 21233 bytes .../shatteredpixeldungeon/Bones.java | 106 ++++++++++-------- .../items/remains/BowFragment.java | 78 +++++++++++++ .../items/remains/BrokenHilt.java | 42 +++++++ .../items/remains/BrokenStaff.java | 43 +++++++ .../items/remains/CloakScrap.java | 48 ++++++++ .../items/remains/RemainsItem.java | 89 +++++++++++++++ .../items/remains/SealShard.java | 43 +++++++ .../levels/CavesBossLevel.java | 20 ++-- .../levels/CityBossLevel.java | 20 ++-- .../levels/DeadEndLevel.java | 15 ++- .../levels/HallsBossLevel.java | 20 ++-- .../levels/LastShopLevel.java | 20 ++-- .../levels/MiningLevel.java | 20 ++-- .../levels/PrisonBossLevel.java | 17 ++- .../levels/RegularLevel.java | 10 +- .../levels/SewerBossLevel.java | 20 ++-- .../sprites/ItemSpriteSheet.java | 20 +++- 19 files changed, 537 insertions(+), 109 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BowFragment.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenHilt.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenStaff.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/CloakScrap.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/RemainsItem.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/SealShard.java diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 983feb4f8..f992ae6d6 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -858,6 +858,21 @@ items.quest.ratskull.desc=A surprisingly large rat skull. It would make a great +###remains +items.remains.remainsitem.ac_use=USE +items.remains.bowfragment.name=bow fragment +items.remains.bowfragment.desc=This broken fragment of wood was once part of a lost huntress' spirit bow. You can still feel a little nature energy left in the fragment, you can use the fragment to grow some high grass around you. Doing this will destroy the fragment however. +items.remains.brokenhilt.name=broken hilt +items.remains.brokenhilt.desc=This broken hilt looks like it came from a defeated Duelist's weapon. You can still feel a little martial power left in the hilt, you can use it to get a little bonus damage on your next two melee attacks. Doing this will destroy the hilt however. +items.remains.brokenstaff.name=broken staff +items.remains.brokenstaff.desc=This Mage's staff has been broken in half after its owner met their demise. You can still feel some magical energy left in the staff, you can use it to give your wands a little boost. Doing this will destroy the staff however. +items.remains.cloakscrap.name=scrap of fabric +items.remains.cloakscrap.desc=This scrap of translucent fabric looks like it came from a late Rogue's cloak of shadows. You can still feel a little mystical energy left in it, you can use it to give your artifacts a little boost. Doing this will destroy the fabric however +items.remains.sealshard.name=seal shard +items.remains.sealshard.desc=This tiny shard of red wax looks like it came from the seal of a fallen Warrior. You can still feel a bit of willpower clinging to the seal, you can use it to give yourself a bit of shielding. Doing this will destroy the seal shard however. + + + ###rings items.rings.ring.diamond=diamond ring items.rings.ring.opal=opal ring diff --git a/core/src/main/assets/sprites/items.png b/core/src/main/assets/sprites/items.png index 40de034d6e81e43e5786758447f37975cf69840f..2a763756f4e05b3a2367688ac7be7155d3b0e025 100644 GIT binary patch delta 20337 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 Ipjg^}0b%JalmGw# diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Bones.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Bones.java index 7f2406b58..db563edc1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Bones.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Bones.java @@ -22,10 +22,12 @@ package com.shatteredpixel.shatteredpixeldungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.Gold; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact; +import com.shatteredpixel.shatteredpixeldungeon.items.remains.RemainsItem; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.watabou.utils.Bundle; import com.watabou.utils.FileUtils; @@ -43,11 +45,14 @@ public class Bones { private static final String LEVEL = "level"; private static final String BRANCH = "branch"; private static final String ITEM = "item"; + private static final String HERO_CLASS = "hero_class"; private static int depth = -1; private static int branch = -1; + private static Item item; - + private static HeroClass heroClass; + public static void leave() { //remains will usually drop on the floor the hero died on @@ -67,6 +72,7 @@ public class Bones { Bundle bundle = new Bundle(); bundle.put( LEVEL, depth ); bundle.put( ITEM, item ); + bundle.put( HERO_CLASS, heroClass ); try { FileUtils.bundleToFile( BONES_FILE, bundle ); @@ -78,14 +84,10 @@ public class Bones { private static Item pickItem(Hero hero){ Item item = null; - //seeded runs always leave gold + //seeded runs don't leave items //This is to prevent using specific seeds to transport items to regular runs if (!Dungeon.customSeedText.isEmpty()){ - if (Dungeon.gold > 100) { - return new Gold( Random.NormalIntRange( 50, Dungeon.gold/2 ) ); - } else { - return new Gold( 50 ); - } + return null; } if (Random.Int(3) != 0) { @@ -125,28 +127,29 @@ public class Bones { ArrayList items = new ArrayList<>(); while (iterator.hasNext()){ curItem = iterator.next(); - if (curItem.bones) + if (curItem.bones) { items.add(curItem); + } } + //if there are few items, there is an increasingly high chance of leaving nothing if (Random.Int(3) < items.size()) { item = Random.element(items); if (item.stackable){ item.quantity(Random.NormalIntRange(1, (item.quantity() + 1) / 2)); + if (item.quantity() > 3){ + item.quantity(3); + } } } else { - if (Dungeon.gold > 100) { - item = new Gold( Random.NormalIntRange( 50, Dungeon.gold/2 ) ); - } else { - item = new Gold( 50 ); - } + item = null; } } return item; } - public static Item get() { + public static ArrayList get() { //daily runs do not interact with remains if (Dungeon.daily){ return null; @@ -160,7 +163,16 @@ public class Bones { depth = bundle.getInt( LEVEL ); branch = bundle.getInt( BRANCH ); if (depth > 0) { - item = (Item) bundle.get(ITEM); + if (bundle.contains(ITEM)) { + item = (Item) bundle.get(ITEM); + } else { + item = null; + } + if (bundle.contains(HERO_CLASS)){ + heroClass = bundle.getEnum(HERO_CLASS, HeroClass.class); + } else { + heroClass = null; + } } return get(); @@ -181,13 +193,9 @@ public class Bones { } depth = 0; - //challenged or seeded runs will always find 10 gold + //challenged or seeded runs don't get items from prior runs if (Dungeon.challenges != 0 || !Dungeon.customSeedText.isEmpty()){ - item = new Gold(10); - } - - if (item == null) { - item = new Gold(50); + item = null; } //Enforces artifact uniqueness @@ -197,37 +205,47 @@ public class Bones { //generates a new artifact of the same type, always +0 Artifact artifact = Reflection.newInstance(((Artifact)item).getClass()); - if (artifact == null){ - return new Gold(item.value()); + if (artifact != null){ + artifact.cursed = true; + artifact.cursedKnown = true; } - artifact.cursed = true; - artifact.cursedKnown = true; - - return artifact; + item = artifact; } else { - return new Gold(item.value()); + item = new Gold(item.value()); } } - - if (item.isUpgradable() && !(item instanceof MissileWeapon)) { - item.cursed = true; - item.cursedKnown = true; - } - - if (item.isUpgradable()) { - //caps at +3 - if (item.level() > 3) { - item.degrade( item.level() - 3 ); + + if (item != null) { + if (item.isUpgradable() && !(item instanceof MissileWeapon)) { + item.cursed = true; + item.cursedKnown = true; } - //thrown weapons are always IDed, otherwise set unknown - item.levelKnown = item instanceof MissileWeapon; + + if (item.isUpgradable()) { + //caps at +3 + if (item.level() > 3) { + item.degrade(item.level() - 3); + } + //thrown weapons are always IDed, otherwise set unknown + item.levelKnown = item instanceof MissileWeapon; + } + + item.reset(); } - - item.reset(); - - return item; + + ArrayList result = new ArrayList<>(); + + if (heroClass != null) { + result.add(RemainsItem.get(heroClass)); + } + + if (item != null) { + result.add(item); + } + + return result.isEmpty() ? null : result; } else { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BowFragment.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BowFragment.java new file mode 100644 index 000000000..b21ca9618 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BowFragment.java @@ -0,0 +1,78 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.remains; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.PathFinder; +import com.watabou.utils.Random; + +import java.util.ArrayList; + +public class BowFragment extends RemainsItem { + + { + image = ItemSpriteSheet.BOW_FRAGMENT; + } + + @Override + protected void doEffect(Hero hero) { + ArrayList grassCells = new ArrayList<>(); + for (int i : PathFinder.NEIGHBOURS9){ + grassCells.add(hero.pos+i); + } + Random.shuffle(grassCells); + for (int grassCell : grassCells){ + if (Dungeon.level.map[grassCell] == Terrain.EMPTY || + Dungeon.level.map[grassCell] == Terrain.EMBERS || + Dungeon.level.map[grassCell] == Terrain.EMPTY_DECO){ + Level.set(grassCell, Terrain.GRASS); + GameScene.updateMap(grassCell); + } + CellEmitter.get(grassCell).burst(LeafParticle.LEVEL_SPECIFIC, 4); + } + // 5 cells total + int totalGrassCells = 5; + while (grassCells.size() > totalGrassCells){ + grassCells.remove(0); + } + for (int grassCell : grassCells){ + int t = Dungeon.level.map[grassCell]; + if ((t == Terrain.EMPTY || t == Terrain.EMPTY_DECO || t == Terrain.EMBERS + || t == Terrain.GRASS || t == Terrain.FURROWED_GRASS) + && Dungeon.level.plants.get(grassCell) == null){ + Level.set(grassCell, Terrain.HIGH_GRASS); + GameScene.updateMap(grassCell); + } + } + Dungeon.observe(); + Sample.INSTANCE.play(Assets.Sounds.PLANT); + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenHilt.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenHilt.java new file mode 100644 index 000000000..af74495de --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenHilt.java @@ -0,0 +1,42 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.remains; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.PhysicalEmpower; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.noosa.audio.Sample; + +public class BrokenHilt extends RemainsItem { + + { + image = ItemSpriteSheet.BROKEN_HILT; + } + + @Override + protected void doEffect(Hero hero) { + Buff.affect( hero, PhysicalEmpower.class).set(Math.max(2, hero.lvl/3), 2); + Sample.INSTANCE.play(Assets.Sounds.UNLOCK); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenStaff.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenStaff.java new file mode 100644 index 000000000..ab3c708c3 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/BrokenStaff.java @@ -0,0 +1,43 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.remains; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.noosa.audio.Sample; + +public class BrokenStaff extends RemainsItem { + + { + image = ItemSpriteSheet.BROKEN_STAFF; + } + + @Override + protected void doEffect(Hero hero) { + hero.belongings.charge(1f); + ScrollOfRecharging.charge(hero); + Sample.INSTANCE.play( Assets.Sounds.CHARGEUP ); + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/CloakScrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/CloakScrap.java new file mode 100644 index 000000000..364d40875 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/CloakScrap.java @@ -0,0 +1,48 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.remains; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.noosa.audio.Sample; + +public class CloakScrap extends RemainsItem { + + { + image = ItemSpriteSheet.CLOAK_SCRAP; + } + + @Override + protected void doEffect(Hero hero) { + for (Buff b : hero.buffs()){ + if (b instanceof Artifact.ArtifactBuff){ + if (!((Artifact.ArtifactBuff) b).isCursed()) ((Artifact.ArtifactBuff) b).charge(hero, 4); + } + } + ScrollOfRecharging.charge(hero); + Sample.INSTANCE.play( Assets.Sounds.CHARGEUP ); + } +} 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 new file mode 100644 index 000000000..4962c38ec --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/RemainsItem.java @@ -0,0 +1,89 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.remains; + +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; + +import java.util.ArrayList; + +public abstract class RemainsItem extends Item { + + { + bones = false; + + defaultAction = AC_USE; + } + + public static final String AC_USE = "USE"; + + @Override + public ArrayList actions(Hero hero) { + ArrayList actions = super.actions(hero); + actions.add(AC_USE); + return actions; + } + + @Override + public void execute(Hero hero, String action) { + super.execute(hero, action); + + if (action.equals(AC_USE)){ + hero.sprite.operate(hero.pos); + + doEffect(hero); + + hero.spendAndNext(Actor.TICK); + detach(hero.belongings.backpack); + } + } + + protected abstract void doEffect(Hero hero); + + @Override + public boolean isIdentified() { + return true; + } + + @Override + public int value() { + return 50; + } + + public static RemainsItem get(HeroClass cls){ + switch (cls){ + case WARRIOR: default: + return new SealShard(); + case MAGE: + return new BrokenStaff(); + case ROGUE: + return new CloakScrap(); + case HUNTRESS: + return new BowFragment(); + case DUELIST: + return new BrokenHilt(); + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/SealShard.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/SealShard.java new file mode 100644 index 000000000..782d9d1ca --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/remains/SealShard.java @@ -0,0 +1,43 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2023 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.items.remains; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.noosa.audio.Sample; + +public class SealShard extends RemainsItem { + + { + image = ItemSpriteSheet.SEAL_SHARD; + } + + @Override + protected void doEffect(Hero hero) { + Buff.affect(hero, Barrier.class).incShield(hero.HT/10); + Sample.INSTANCE.play(Assets.Sounds.UNLOCK); + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesBossLevel.java index aaea586a5..905c5548e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesBossLevel.java @@ -212,14 +212,18 @@ public class CavesBossLevel extends Level { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - int pos; - do { - pos = randomRespawnCell(null); - } while (pos == entrance()); - drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int pos; + do { + pos = randomRespawnCell(null); + } while (pos == entrance()); + for (Item i : bonesItems) { + drop(i, pos).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityBossLevel.java index 957fde74a..ffa6f779b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityBossLevel.java @@ -260,14 +260,18 @@ public class CityBossLevel extends Level { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - int pos; - do { - pos = randomRespawnCell(null); - } while (pos == entrance()); - drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int pos; + do { + pos = randomRespawnCell(null); + } while (pos == entrance()); + for (Item i : bonesItems) { + drop(i, pos).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java index e2befe488..ce43fb274 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java @@ -30,6 +30,9 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition; +import com.watabou.utils.Random; + +import java.util.ArrayList; public class DeadEndLevel extends Level { @@ -102,10 +105,14 @@ public class DeadEndLevel extends Level { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - drop( item, entrance()-width() ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + for (Item i : bonesItems) { + drop(i, entrance()-width()).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsBossLevel.java index 461f54e24..b74a9d7fa 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsBossLevel.java @@ -198,14 +198,18 @@ public class HallsBossLevel extends Level { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - int pos; - do { - pos = randomRespawnCell(null); - } while (pos == entrance()); - drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int pos; + do { + pos = randomRespawnCell(null); + } while (pos == entrance()); + for (Item i : bonesItems) { + drop(i, pos).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java index bcd0f8ede..045d082a5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java @@ -118,14 +118,18 @@ public class LastShopLevel extends RegularLevel { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - int pos; - do { - pos = pointToCell(roomEntrance.random()); - } while (pos == entrance()); - drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int pos; + do { + pos = pointToCell(roomEntrance.random()); + } while (pos == entrance()); + for (Item i : bonesItems) { + drop(i, pos).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java index 3af258cf2..5b67886e0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/MiningLevel.java @@ -164,15 +164,19 @@ public class MiningLevel extends CavesLevel { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - int cell = randomDropCell(); - if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { - map[cell] = Terrain.GRASS; - losBlocking[cell] = false; + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int cell = randomDropCell(); + if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { + map[cell] = Terrain.GRASS; + losBlocking[cell] = false; + } + for (Item i : bonesItems) { + drop(i, cell).setHauntedIfCursed().type = Heap.Type.REMAINS; + } } - drop( item, cell ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.popGenerator(); int cell = randomDropCell(); if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java index 3e6f6712f..1b8c5a73b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java @@ -565,10 +565,19 @@ public class PrisonBossLevel extends Level { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - drop( item, randomRespawnCell( null ) ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int pos; + do { + pos = randomRespawnCell(null); + } while (pos == entrance()); + for (Item i : bonesItems) { + drop(i, pos).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); + drop(new IronKey(10), randomPrisonCellPos()); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java index b919fae24..992377d6d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -437,14 +437,16 @@ public abstract class RegularLevel extends Level { Random.popGenerator(); Random.pushGenerator( Random.Long() ); - Item item = Bones.get(); - if (item != null) { + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { int cell = randomDropCell(); if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { map[cell] = Terrain.GRASS; losBlocking[cell] = false; } - drop( item, cell ).setHauntedIfCursed().type = Heap.Type.REMAINS; + for (Item i : bonesItems) { + drop(i, cell).setHauntedIfCursed().type = Heap.Type.REMAINS; + } } Random.popGenerator(); @@ -457,7 +459,7 @@ public abstract class RegularLevel extends Level { for (int i=1; i <= petalsNeeded; i++) { //the player may miss a single petal and still max their rose. if (rose.droppedPetals < 11) { - item = new DriedRose.Petal(); + Item item = new DriedRose.Petal(); int cell = randomDropCell(); drop( item, cell ).type = Heap.Type.HEAP; if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java index 32fb02eff..c380660cd 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java @@ -139,14 +139,18 @@ public class SewerBossLevel extends SewerLevel { @Override protected void createItems() { - Item item = Bones.get(); - if (item != null) { - int pos; - do { - pos = pointToCell(roomEntrance.random()); - } while (pos == entrance() || solid[pos]); - drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS; - } + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + int pos; + do { + pos = pointToCell(roomEntrance.random()); + } while (pos == entrance() || solid[pos]); + for (Item i : bonesItems) { + drop(i, pos).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java index 375214df7..e1ea96d0c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java @@ -125,7 +125,7 @@ public class ItemSpriteSheet { assignItemRect(EBONY_CHEST, 16, 14); } - private static final int MISC_CONSUMABLE = xy(1, 4); //16 slots + private static final int MISC_CONSUMABLE = xy(1, 4); //32 slots public static final int ANKH = MISC_CONSUMABLE +0; public static final int STYLUS = MISC_CONSUMABLE +1; public static final int SEAL = MISC_CONSUMABLE +2; @@ -142,6 +142,12 @@ public class ItemSpriteSheet { public static final int AMULET = MISC_CONSUMABLE +13; public static final int MASTERY = MISC_CONSUMABLE +14; public static final int KIT = MISC_CONSUMABLE +15; + public static final int SEAL_SHARD = MISC_CONSUMABLE +16; + public static final int BROKEN_STAFF = MISC_CONSUMABLE +17; + public static final int CLOAK_SCRAP = MISC_CONSUMABLE +18; + public static final int BOW_FRAGMENT = MISC_CONSUMABLE +19; + public static final int BROKEN_HILT = MISC_CONSUMABLE +20; + static{ assignItemRect(ANKH, 10, 16); assignItemRect(STYLUS, 12, 13); @@ -161,9 +167,16 @@ public class ItemSpriteSheet { assignItemRect(AMULET, 16, 16); assignItemRect(MASTERY, 13, 16); assignItemRect(KIT, 16, 15); + + //TODO improve these placeholder images + assignItemRect(SEAL_SHARD, 6, 9); + assignItemRect(BROKEN_STAFF, 15, 11); + assignItemRect(CLOAK_SCRAP, 5, 9); + assignItemRect(BOW_FRAGMENT, 12, 7); + assignItemRect(BROKEN_HILT, 6, 7); } - private static final int BOMBS = xy(1, 5); //16 slots + private static final int BOMBS = xy(1, 6); //16 slots public static final int BOMB = BOMBS+0; public static final int DBL_BOMB = BOMBS+1; public static final int FIRE_BOMB = BOMBS+2; @@ -192,9 +205,6 @@ public class ItemSpriteSheet { assignItemRect(SHRAPNEL_BOMB, 10, 13); } - - //16 free slots - private static final int WEP_TIER1 = xy(1, 7); //8 slots public static final int WORN_SHORTSWORD = WEP_TIER1+0; public static final int CUDGEL = WEP_TIER1+1;