v0.6.2: overhauled alchemy system
This commit is contained in:
+12
-45
@@ -24,58 +24,25 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.blobs;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
|
||||||
import com.watabou.utils.Bundle;
|
|
||||||
|
|
||||||
public class Alchemy extends Blob {
|
public class Alchemy extends Blob {
|
||||||
|
|
||||||
protected int pos;
|
protected int pos;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void restoreFromBundle( Bundle bundle ) {
|
|
||||||
super.restoreFromBundle( bundle );
|
|
||||||
|
|
||||||
if (volume > 0)
|
|
||||||
for (int i=0; i < cur.length; i++) {
|
|
||||||
if (cur[i] > 0) {
|
|
||||||
pos = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void evolve() {
|
protected void evolve() {
|
||||||
volume = off[pos] = cur[pos];
|
int cell;
|
||||||
area.union(pos%Dungeon.level.width(), pos/Dungeon.level.width());
|
for (int i=area.top-1; i <= area.bottom; i++) {
|
||||||
|
for (int j = area.left-1; j <= area.right; j++) {
|
||||||
if (Dungeon.visible[pos]) {
|
cell = j + i* Dungeon.level.width();
|
||||||
Notes.add( Notes.Landmark.ALCHEMY );
|
if (Dungeon.level.insideMap(cell)) {
|
||||||
}
|
off[cell] = cur[cell];
|
||||||
}
|
volume += off[cell];
|
||||||
|
if (off[cell] > 0 && Dungeon.visible[cell]){
|
||||||
@Override
|
Notes.add( Notes.Landmark.ALCHEMY );
|
||||||
public void seed( Level level, int cell, int amount ) {
|
}
|
||||||
super.seed(level, cell, amount);
|
}
|
||||||
|
|
||||||
cur[pos] = 0;
|
|
||||||
pos = cell;
|
|
||||||
volume = cur[pos] = amount;
|
|
||||||
|
|
||||||
area.setEmpty();
|
|
||||||
area.union(cell%level.width(), cell/level.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void transmute( int cell ) {
|
|
||||||
Heap heap = Dungeon.level.heaps.get( cell );
|
|
||||||
if (heap != null) {
|
|
||||||
|
|
||||||
Item result = heap.transmute();
|
|
||||||
if (result != null) {
|
|
||||||
Dungeon.level.drop( result, cell ).sprite.drop( cell );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,6 +50,6 @@ public class Alchemy extends Blob {
|
|||||||
@Override
|
@Override
|
||||||
public void use( BlobEmitter emitter ) {
|
public void use( BlobEmitter emitter ) {
|
||||||
super.use( emitter );
|
super.use( emitter );
|
||||||
emitter.start( Speck.factory( Speck.BUBBLE ), 0.4f, 0 );
|
emitter.start( Speck.factory( Speck.BUBBLE ), 0.33f, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWea
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.AlchemyPot;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Earthroot;
|
import com.shatteredpixel.shatteredpixeldungeon.plants.Earthroot;
|
||||||
@@ -110,6 +109,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndAlchemy;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndMessage;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
||||||
@@ -544,9 +544,9 @@ public class Hero extends Char {
|
|||||||
return actAttack( (HeroAction.Attack)curAction );
|
return actAttack( (HeroAction.Attack)curAction );
|
||||||
|
|
||||||
} else
|
} else
|
||||||
if (curAction instanceof HeroAction.Cook) {
|
if (curAction instanceof HeroAction.Alchemy) {
|
||||||
|
|
||||||
return actCook( (HeroAction.Cook)curAction );
|
return actAlchemy( (HeroAction.Alchemy)curAction );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -643,12 +643,12 @@ public class Hero extends Char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean actCook( HeroAction.Cook action ) {
|
private boolean actAlchemy( HeroAction.Alchemy action ) {
|
||||||
int dst = action.dst;
|
int dst = action.dst;
|
||||||
if (Dungeon.visible[dst]) {
|
if (Dungeon.level.distance(dst, pos) <= 1) {
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
AlchemyPot.operate( this, dst );
|
GameScene.show(new WndAlchemy());
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else if (getCloser( dst )) {
|
} else if (getCloser( dst )) {
|
||||||
@@ -1132,7 +1132,7 @@ public class Hero extends Char {
|
|||||||
|
|
||||||
if (Dungeon.level.map[cell] == Terrain.ALCHEMY && cell != pos) {
|
if (Dungeon.level.map[cell] == Terrain.ALCHEMY && cell != pos) {
|
||||||
|
|
||||||
curAction = new HeroAction.Cook( cell );
|
curAction = new HeroAction.Alchemy( cell );
|
||||||
|
|
||||||
} else if (Level.fieldOfView[cell] && (ch = Actor.findChar( cell )) instanceof Mob) {
|
} else if (Level.fieldOfView[cell] && (ch = Actor.findChar( cell )) instanceof Mob) {
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -77,8 +77,8 @@ public class HeroAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Cook extends HeroAction {
|
public static class Alchemy extends HeroAction {
|
||||||
public Cook( int pot ) {
|
public Alchemy( int pot ) {
|
||||||
this.dst = pot;
|
this.dst = pot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,7 @@
|
|||||||
package com.shatteredpixel.shatteredpixeldungeon.items;
|
package com.shatteredpixel.shatteredpixeldungeon.items;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost;
|
||||||
@@ -35,21 +32,16 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Splash;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.AlchemistsToolkit;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.ChargrilledMeat;
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.ChargrilledMeat;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.FrozenCarpaccio;
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.FrozenCarpaccio;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.journal.DocumentPage;
|
import com.shatteredpixel.shatteredpixeldungeon.items.journal.DocumentPage;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMight;
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMight;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
||||||
@@ -58,7 +50,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicalInf
|
|||||||
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.wands.Wand;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant.Seed;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
import com.watabou.noosa.audio.Sample;
|
import com.watabou.noosa.audio.Sample;
|
||||||
@@ -360,105 +351,6 @@ public class Heap implements Bundlable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item transmute() {
|
|
||||||
|
|
||||||
CellEmitter.get( pos ).burst( Speck.factory( Speck.BUBBLE ), 3 );
|
|
||||||
Splash.at( pos, 0xFFFFFF, 3 );
|
|
||||||
|
|
||||||
float chances[] = new float[items.size()];
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (items.size() == 2 && items.get(0) instanceof Seed && items.get(1) instanceof Blandfruit ) {
|
|
||||||
|
|
||||||
Sample.INSTANCE.play( Assets.SND_PUFF );
|
|
||||||
CellEmitter.center( pos ).burst( Speck.factory( Speck.EVOKE ), 3 );
|
|
||||||
|
|
||||||
Blandfruit result = new Blandfruit();
|
|
||||||
result.cook((Seed)items.get(0));
|
|
||||||
|
|
||||||
destroy();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (Item item : items) {
|
|
||||||
if (item instanceof Seed) {
|
|
||||||
count += item.quantity;
|
|
||||||
chances[index++] = item.quantity;
|
|
||||||
} else{
|
|
||||||
count = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//alchemists toolkit gives a chance to cook a potion in two or even one seeds
|
|
||||||
AlchemistsToolkit.alchemy alchemy = Dungeon.hero.buff(AlchemistsToolkit.alchemy.class);
|
|
||||||
int bonus = alchemy != null ? alchemy.itemLevel() : -1;
|
|
||||||
|
|
||||||
if (bonus != -1 ? alchemy.tryCook(count) : count >= SEEDS_TO_POTION) {
|
|
||||||
|
|
||||||
CellEmitter.get( pos ).burst( Speck.factory( Speck.WOOL ), 6 );
|
|
||||||
Sample.INSTANCE.play( Assets.SND_PUFF );
|
|
||||||
|
|
||||||
Item potion;
|
|
||||||
|
|
||||||
if (Random.Int( count + bonus ) == 0) {
|
|
||||||
|
|
||||||
CellEmitter.center( pos ).burst( Speck.factory( Speck.EVOKE ), 3 );
|
|
||||||
|
|
||||||
destroy();
|
|
||||||
|
|
||||||
Statistics.potionsCooked++;
|
|
||||||
Badges.validatePotionsCooked();
|
|
||||||
|
|
||||||
potion = Generator.random( Generator.Category.POTION );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Seed proto = (Seed)items.get( Random.chances( chances ) );
|
|
||||||
Class<? extends Item> itemClass = proto.alchemyClass;
|
|
||||||
|
|
||||||
destroy();
|
|
||||||
|
|
||||||
Statistics.potionsCooked++;
|
|
||||||
Badges.validatePotionsCooked();
|
|
||||||
|
|
||||||
if (itemClass == null) {
|
|
||||||
potion = Generator.random( Generator.Category.POTION );
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
potion = itemClass.newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
ShatteredPixelDungeon.reportException(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//not a buff per-se, meant to cancel out higher potion accuracy when ppl are farming for potions of exp.
|
|
||||||
if (bonus > 0)
|
|
||||||
if (Random.Int(1000/bonus) == 0)
|
|
||||||
return new PotionOfExperience();
|
|
||||||
|
|
||||||
while (potion instanceof PotionOfHealing
|
|
||||||
&& Random.Int(10) < Dungeon.LimitedDrops.COOKING_HP.count) {
|
|
||||||
potion = Generator.random(Generator.Category.POTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (potion instanceof PotionOfHealing) {
|
|
||||||
Dungeon.LimitedDrops.COOKING_HP.count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return potion;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void burnFX( int pos ) {
|
public static void burnFX( int pos ) {
|
||||||
CellEmitter.get( pos ).burst( ElmoParticle.FACTORY, 6 );
|
CellEmitter.get( pos ).burst( ElmoParticle.FACTORY, 6 );
|
||||||
Sample.INSTANCE.play( Assets.SND_BURNING );
|
Sample.INSTANCE.play( Assets.SND_BURNING );
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
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.blobs.Alchemy;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.WellWater;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.WellWater;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness;
|
||||||
@@ -792,12 +791,6 @@ public abstract class Level implements Bundlable {
|
|||||||
WellWater.affectCell( cell );
|
WellWater.affectCell( cell );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Terrain.ALCHEMY:
|
|
||||||
if (ch == null) {
|
|
||||||
Alchemy.transmute( cell );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Terrain.DOOR:
|
case Terrain.DOOR:
|
||||||
Door.enter( cell );
|
Door.enter( cell );
|
||||||
break;
|
break;
|
||||||
|
|||||||
-87
@@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Pixel Dungeon
|
|
||||||
* Copyright (C) 2012-2015 Oleg Dolya
|
|
||||||
*
|
|
||||||
* Shattered Pixel Dungeon
|
|
||||||
* Copyright (C) 2014-2017 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.levels.features;
|
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class AlchemyPot {
|
|
||||||
|
|
||||||
public static Hero hero;
|
|
||||||
public static int pos;
|
|
||||||
|
|
||||||
public static boolean foundFruit;
|
|
||||||
public static Item curItem = null;
|
|
||||||
|
|
||||||
public static void operate( Hero hero, int pos ) {
|
|
||||||
|
|
||||||
AlchemyPot.hero = hero;
|
|
||||||
AlchemyPot.pos = pos;
|
|
||||||
|
|
||||||
Iterator<Item> items = hero.belongings.iterator();
|
|
||||||
foundFruit = false;
|
|
||||||
Heap heap = Dungeon.level.heaps.get( pos );
|
|
||||||
|
|
||||||
if (heap == null)
|
|
||||||
while (items.hasNext() && !foundFruit){
|
|
||||||
curItem = items.next();
|
|
||||||
if (curItem instanceof Blandfruit && ((Blandfruit) curItem).potionAttrib == null){
|
|
||||||
GameScene.show(
|
|
||||||
new WndOptions(Messages.get(AlchemyPot.class, "pot"),
|
|
||||||
Messages.get(AlchemyPot.class, "options"),
|
|
||||||
Messages.get(AlchemyPot.class, "fruit"),
|
|
||||||
Messages.get(AlchemyPot.class, "potion")) {
|
|
||||||
@Override
|
|
||||||
protected void onSelect(int index) {
|
|
||||||
if (index == 0) {
|
|
||||||
curItem.cast( AlchemyPot.hero, AlchemyPot.pos );
|
|
||||||
} else
|
|
||||||
GameScene.selectItem(itemSelector, WndBag.Mode.SEED, Messages.get(AlchemyPot.class, "select_seed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
foundFruit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundFruit)
|
|
||||||
GameScene.selectItem(itemSelector, WndBag.Mode.SEED, Messages.get(AlchemyPot.class, "select_seed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final WndBag.Listener itemSelector = new WndBag.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onSelect( Item item ) {
|
|
||||||
if (item != null) {
|
|
||||||
item.cast( hero, pos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
+1
-1
@@ -55,7 +55,7 @@ public class LaboratoryRoom extends SpecialRoom {
|
|||||||
Painter.set( level, pot, Terrain.ALCHEMY );
|
Painter.set( level, pot, Terrain.ALCHEMY );
|
||||||
|
|
||||||
Alchemy alchemy = new Alchemy();
|
Alchemy alchemy = new Alchemy();
|
||||||
alchemy.seed( level, pot.x + level.width() * pot.y, 1 );
|
alchemy.seed( level, pot.x + level.width() * pot.y, Random.IntRange(25, 50) );
|
||||||
level.blobs.put( Alchemy.class, alchemy );
|
level.blobs.put( Alchemy.class, alchemy );
|
||||||
|
|
||||||
int n = Random.IntRange( 2, 3 );
|
int n = Random.IntRange( 2, 3 );
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* Pixel Dungeon
|
||||||
|
* Copyright (C) 2012-2015 Oleg Dolya
|
||||||
|
*
|
||||||
|
* Shattered Pixel Dungeon
|
||||||
|
* Copyright (C) 2014-2017 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.windows;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.ItemSlot;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextMultiline;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||||
|
import com.watabou.noosa.ColorBlock;
|
||||||
|
import com.watabou.noosa.Image;
|
||||||
|
import com.watabou.noosa.audio.Sample;
|
||||||
|
import com.watabou.noosa.particles.Emitter;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class WndAlchemy extends Window {
|
||||||
|
|
||||||
|
private WndBlacksmith.ItemButton[] inputs = new WndBlacksmith.ItemButton[3];
|
||||||
|
private ItemSlot output;
|
||||||
|
|
||||||
|
private Emitter smokeEmitter;
|
||||||
|
private Emitter bubbleEmitter;
|
||||||
|
|
||||||
|
private RedButton btnCombine;
|
||||||
|
|
||||||
|
private static final int WIDTH_P = 116;
|
||||||
|
private static final int WIDTH_L = 160;
|
||||||
|
|
||||||
|
private static final int BTN_SIZE = 28;
|
||||||
|
|
||||||
|
public WndAlchemy(){
|
||||||
|
|
||||||
|
int w = WIDTH_P;
|
||||||
|
|
||||||
|
int h = 0;
|
||||||
|
|
||||||
|
IconTitle titlebar = new IconTitle();
|
||||||
|
titlebar.icon(DungeonTerrainTilemap.tile(0, Terrain.ALCHEMY));
|
||||||
|
titlebar.label( Messages.get(this, "title") );
|
||||||
|
titlebar.setRect( 0, 0, w, 0 );
|
||||||
|
add( titlebar );
|
||||||
|
|
||||||
|
h += titlebar.height() + 2;
|
||||||
|
|
||||||
|
RenderedTextMultiline desc = PixelScene.renderMultiline(6);
|
||||||
|
desc.text( Messages.get(this, "text") );
|
||||||
|
desc.setPos(0, h);
|
||||||
|
desc.maxWidth(w);
|
||||||
|
add(desc);
|
||||||
|
|
||||||
|
h += desc.height() + 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < inputs.length; i++) {
|
||||||
|
inputs[i] = new WndBlacksmith.ItemButton(){
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
super.onClick();
|
||||||
|
if (item != null){
|
||||||
|
if (!item.collect()){
|
||||||
|
Dungeon.level.drop(item, Dungeon.hero.pos);
|
||||||
|
}
|
||||||
|
item = null;
|
||||||
|
slot.item(new WndBag.Placeholder(ItemSpriteSheet.SOMETHING));
|
||||||
|
}
|
||||||
|
GameScene.selectItem( itemSelector, WndBag.Mode.ALCHEMY, Messages.get(WndAlchemy.class, "select") );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
inputs[i].setRect(15, h, BTN_SIZE, BTN_SIZE);
|
||||||
|
add(inputs[i]);
|
||||||
|
h += BTN_SIZE + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image arrow = Icons.get(Icons.RESUME);
|
||||||
|
arrow.hardlight(0, 0, 0);
|
||||||
|
arrow.x = (w - arrow.width)/2f;
|
||||||
|
arrow.y = inputs[1].top() + (inputs[1].height() - arrow.height)/2f;
|
||||||
|
PixelScene.align(arrow);
|
||||||
|
add(arrow);
|
||||||
|
|
||||||
|
output = new ItemSlot(){
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
super.onClick();
|
||||||
|
if (visible && item.trueName() != null){
|
||||||
|
GameScene.show(new WndInfoItem(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
output.setRect(w - BTN_SIZE - 15, inputs[1].top(), BTN_SIZE, BTN_SIZE);
|
||||||
|
|
||||||
|
ColorBlock outputBG = new ColorBlock(output.width(), output.height(), 0x9991938C);
|
||||||
|
outputBG.x = output.left();
|
||||||
|
outputBG.y = output.top();
|
||||||
|
add(outputBG);
|
||||||
|
|
||||||
|
add(output);
|
||||||
|
output.visible = false;
|
||||||
|
|
||||||
|
bubbleEmitter = new Emitter();
|
||||||
|
smokeEmitter = new Emitter();
|
||||||
|
bubbleEmitter.pos(outputBG.x + (BTN_SIZE-16)/2f, outputBG.y + (BTN_SIZE-16)/2f, 16, 16);
|
||||||
|
smokeEmitter.pos(bubbleEmitter.x, bubbleEmitter.y, bubbleEmitter.width, bubbleEmitter.height);
|
||||||
|
bubbleEmitter.autoKill = false;
|
||||||
|
smokeEmitter.autoKill = false;
|
||||||
|
add(bubbleEmitter);
|
||||||
|
add(smokeEmitter);
|
||||||
|
|
||||||
|
h += 4;
|
||||||
|
|
||||||
|
float btnWidth = (w-14)/2f;
|
||||||
|
|
||||||
|
btnCombine = new RedButton(Messages.get(this, "combine")){
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
super.onClick();
|
||||||
|
combine();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
btnCombine.setRect(5, h, btnWidth, 18);
|
||||||
|
PixelScene.align(btnCombine);
|
||||||
|
btnCombine.enable(false);
|
||||||
|
add(btnCombine);
|
||||||
|
|
||||||
|
RedButton btnCancel = new RedButton(Messages.get(this, "cancel")){
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
super.onClick();
|
||||||
|
onBackPressed();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
btnCancel.setRect(w - 5 - btnWidth, h, btnWidth, 18);
|
||||||
|
PixelScene.align(btnCancel);
|
||||||
|
add(btnCancel);
|
||||||
|
|
||||||
|
h += btnCancel.height();
|
||||||
|
|
||||||
|
resize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected WndBag.Listener itemSelector = new WndBag.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onSelect( Item item ) {
|
||||||
|
if (item != null) {
|
||||||
|
for (int i = 0; i < inputs.length; i++) {
|
||||||
|
if (inputs[i].item == null){
|
||||||
|
inputs[i].item(item.detach(Dungeon.hero.belongings.backpack));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private<T extends Item> ArrayList<T> filterInput(Class<? extends T> itemClass){
|
||||||
|
ArrayList<T> filtered = new ArrayList<>();
|
||||||
|
for (int i = 0; i < inputs.length; i++){
|
||||||
|
Item item = inputs[i].item;
|
||||||
|
if (item != null && itemClass.isInstance(item)){
|
||||||
|
filtered.add((T)item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateState(){
|
||||||
|
//potion creation
|
||||||
|
if (filterInput(Plant.Seed.class).size() == 3){
|
||||||
|
output.item(new WndBag.Placeholder(ItemSpriteSheet.POTION_HOLDER));
|
||||||
|
output.visible = true;
|
||||||
|
btnCombine.enable(true);
|
||||||
|
|
||||||
|
//blandfruit cooking
|
||||||
|
} else if (filterInput(Blandfruit.class).size() == 1 && filterInput(Plant.Seed.class).size() == 1){
|
||||||
|
output.item(new WndBag.Placeholder(ItemSpriteSheet.SOMETHING));
|
||||||
|
output.visible = true;
|
||||||
|
btnCombine.enable(true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
btnCombine.enable(false);
|
||||||
|
output.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void combine(){
|
||||||
|
ArrayList<Plant.Seed> seeds = filterInput(Plant.Seed.class);
|
||||||
|
ArrayList<Blandfruit> fruits = filterInput(Blandfruit.class);
|
||||||
|
|
||||||
|
Item result = null;
|
||||||
|
|
||||||
|
//potion creation
|
||||||
|
if (seeds.size() == 3){
|
||||||
|
|
||||||
|
if (Random.Int( 3 ) == 0) {
|
||||||
|
|
||||||
|
result = Generator.random( Generator.Category.POTION );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Class<? extends Item> itemClass = Random.element(seeds).alchemyClass;
|
||||||
|
try {
|
||||||
|
result = itemClass.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
ShatteredPixelDungeon.reportException(e);
|
||||||
|
result = Generator.random( Generator.Category.POTION );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (result instanceof PotionOfHealing
|
||||||
|
&& Random.Int(10) < Dungeon.LimitedDrops.COOKING_HP.count) {
|
||||||
|
result = Generator.random(Generator.Category.POTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result instanceof PotionOfHealing) {
|
||||||
|
Dungeon.LimitedDrops.COOKING_HP.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statistics.potionsCooked++;
|
||||||
|
Badges.validatePotionsCooked();
|
||||||
|
|
||||||
|
//blandfruit cooking
|
||||||
|
} else if (fruits.size() == 1 && seeds.size() == 1) {
|
||||||
|
result = fruits.get(0);
|
||||||
|
((Blandfruit)result).cook(seeds.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != null){
|
||||||
|
bubbleEmitter.start(Speck.factory( Speck.BUBBLE ), 0.2f, 10 );
|
||||||
|
smokeEmitter.burst(Speck.factory( Speck.WOOL ), 10 );
|
||||||
|
Sample.INSTANCE.play( Assets.SND_PUFF );
|
||||||
|
|
||||||
|
output.item(result);
|
||||||
|
if (!result.collect()){
|
||||||
|
Dungeon.level.drop(result, Dungeon.hero.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < inputs.length; i++){
|
||||||
|
inputs[i].slot.item(new WndBag.Placeholder(ItemSpriteSheet.SOMETHING));
|
||||||
|
inputs[i].item = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
btnCombine.enable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
for (int i = 0; i < inputs.length; i++) {
|
||||||
|
if (inputs[i].item != null){
|
||||||
|
if (!inputs[i].item.collect()){
|
||||||
|
Dungeon.level.drop(inputs[i].item, Dungeon.hero.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.bags.PotionBandolier;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.ScrollHolder;
|
import com.shatteredpixel.shatteredpixeldungeon.items.bags.ScrollHolder;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.SeedPouch;
|
import com.shatteredpixel.shatteredpixeldungeon.items.bags.SeedPouch;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.WandHolster;
|
import com.shatteredpixel.shatteredpixeldungeon.items.bags.WandHolster;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.Food;
|
import com.shatteredpixel.shatteredpixeldungeon.items.food.Food;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
|
||||||
@@ -45,6 +46,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Boomerang;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.Boomerang;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.plants.BlandfruitBush;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant.Seed;
|
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant.Seed;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||||
@@ -77,7 +79,8 @@ public class WndBag extends WndTabbed {
|
|||||||
FOOD,
|
FOOD,
|
||||||
POTION,
|
POTION,
|
||||||
SCROLL,
|
SCROLL,
|
||||||
EQUIPMENT
|
EQUIPMENT,
|
||||||
|
ALCHEMY
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final int COLS_P = 4;
|
protected static final int COLS_P = 4;
|
||||||
@@ -400,6 +403,7 @@ public class WndBag extends WndTabbed {
|
|||||||
mode == Mode.POTION && (item instanceof Potion) ||
|
mode == Mode.POTION && (item instanceof Potion) ||
|
||||||
mode == Mode.SCROLL && (item instanceof Scroll) ||
|
mode == Mode.SCROLL && (item instanceof Scroll) ||
|
||||||
mode == Mode.EQUIPMENT && (item instanceof EquipableItem) ||
|
mode == Mode.EQUIPMENT && (item instanceof EquipableItem) ||
|
||||||
|
mode == Mode.ALCHEMY && ((item instanceof Seed && !(item instanceof BlandfruitBush.Seed)) || (item instanceof Blandfruit && ((Blandfruit) item).potionAttrib == null)) ||
|
||||||
mode == Mode.ALL
|
mode == Mode.ALL
|
||||||
);
|
);
|
||||||
//extra logic for cursed weapons or armor
|
//extra logic for cursed weapons or armor
|
||||||
|
|||||||
+6
@@ -1,3 +1,9 @@
|
|||||||
|
windows.wndalchemy.title=Alchemy
|
||||||
|
windows.wndalchemy.text=Combine three seeds to create a potion!
|
||||||
|
windows.wndalchemy.combine=Combine
|
||||||
|
windows.wndalchemy.cancel=Cancel
|
||||||
|
windows.wndalchemy.select=Select an item
|
||||||
|
|
||||||
windows.wndblacksmith.prompt=Ok, a deal is a deal, here's what I can do for you: I can reforge 2 items and turn them into one of a better quality.
|
windows.wndblacksmith.prompt=Ok, a deal is a deal, here's what I can do for you: I can reforge 2 items and turn them into one of a better quality.
|
||||||
windows.wndblacksmith.select=Reforge an item
|
windows.wndblacksmith.select=Reforge an item
|
||||||
windows.wndblacksmith.reforge=Reforge them
|
windows.wndblacksmith.reforge=Reforge them
|
||||||
|
|||||||
Reference in New Issue
Block a user