v0.7.0: rough implementation of some exotic potions/scrolls

This commit is contained in:
Evan Debenham 2018-07-14 18:49:35 -04:00
parent e3ec860e18
commit c95c5e93ad
22 changed files with 899 additions and 28 deletions

View File

@ -49,6 +49,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Preparation;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Slow;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Speed;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Stamina;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
@ -281,6 +282,7 @@ public abstract class Char extends Actor {
public float speed() {
float speed = baseSpeed;
if ( buff( Cripple.class ) != null ) speed /= 2f;
if ( buff( Stamina.class ) != null) speed *= 1.5f;
if ( buff( Adrenaline.class ) != null) speed *= 2f;
if ( buff( Haste.class ) != null) speed *= 3f;
return speed;

View File

@ -33,6 +33,7 @@ import com.watabou.utils.Bundle;
public class CorrosiveGas extends Blob {
//FIXME should have strength per-cell
private int strength = 0;
@Override
@ -57,9 +58,11 @@ public class CorrosiveGas extends Blob {
}
}
public void setStrength(int str){
if (str > strength)
public CorrosiveGas setStrength(int str){
if (str > strength) {
strength = str;
}
return this;
}
private static final String STRENGTH = "strength";

View File

@ -0,0 +1,26 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 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.actors.buffs;
//TODO
public class Stamina extends FlavourBuff {
}

View File

@ -76,6 +76,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMight;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfAdrenalineSurge;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfForce;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror;
@ -199,6 +200,11 @@ public class Hero extends Char {
STR += RingOfMight.strengthBonus( this );
PotionOfAdrenalineSurge.strBoost buff = buff(PotionOfAdrenalineSurge.strBoost.class);
if (buff != null){
STR += buff.boost();
}
return (buff(Weakness.class) != null) ? STR - 2 : STR;
}

View File

@ -529,10 +529,22 @@ public class Armor extends EquipableItem {
Obfuscation.class, Swiftness.class, Viscosity.class, Potential.class,
Brimstone.class, Stone.class, Entanglement.class, Repulsion.class, Camouflage.class, Flow.class,
Affection.class, AntiMagic.class, Thorns.class };
private static final float[] chances= new float[]{
10, 10, 10, 10,
5, 5, 5, 5, 5, 5,
2, 2, 2 };
private static final Class<?>[] common = new Class<?>[]{
Obfuscation.class, Swiftness.class, Viscosity.class, Potential.class };
private static final Class<?>[] uncommon = new Class<?>[]{
Brimstone.class, Stone.class, Entanglement.class,
Repulsion.class, Camouflage.class, Flow.class };
private static final Class<?>[] rare = new Class<?>[]{
Affection.class, AntiMagic.class, Thorns.class };
private static final float[] typeChances = new float[]{
40, //10 each
30, // 5 each
6 // 2 each
};
private static final Class<?>[] curses = new Class<?>[]{
AntiEntropy.class, Corrosion.class, Displacement.class, Metabolism.class,
@ -572,8 +584,40 @@ public class Armor extends EquipableItem {
@SuppressWarnings("unchecked")
public static Glyph random() {
switch(Random.chances(typeChances)){
case 0: default:
return randomCommon();
case 1:
return randomUncommon();
case 2:
return randomRare();
}
}
@SuppressWarnings("unchecked")
public static Glyph randomCommon(){
try {
return ((Class<Glyph>)glyphs[ Random.chances( chances ) ]).newInstance();
return ((Class<Glyph>)Random.oneOf(common)).newInstance();
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
return null;
}
}
@SuppressWarnings("unchecked")
public static Glyph randomUncommon(){
try {
return ((Class<Glyph>)Random.oneOf(uncommon)).newInstance();
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
return null;
}
}
@SuppressWarnings("unchecked")
public static Glyph randomRare(){
try {
return ((Class<Glyph>)Random.oneOf(rare)).newInstance();
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
return null;

View File

@ -41,6 +41,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.ItemStatusHandler;
import com.shatteredpixel.shatteredpixeldungeon.items.Recipe;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.ExoticPotion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfCorrosiveGas;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfSnapFreeze;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@ -121,6 +123,10 @@ public class Potion extends Item {
mustThrowPots.add(PotionOfLiquidFlame.class);
mustThrowPots.add(PotionOfParalyticGas.class);
mustThrowPots.add(PotionOfFrost.class);
//exotic
mustThrowPots.add(PotionOfCorrosiveGas.class);
mustThrowPots.add(PotionOfSnapFreeze.class);
}
private static final HashSet<Class<?extends Potion>> canThrowPots = new HashSet<>();
@ -313,8 +319,10 @@ public class Potion extends Item {
updateQuickslot();
Potion p = Dungeon.hero.belongings.getItem(getClass());
if (p != null) p.setAction();
p = Dungeon.hero.belongings.getItem(ExoticPotion.regToExo.get(getClass()));
if (p != null) p.setAction();
if (ExoticPotion.regToExo.get(getClass()) != null) {
p = Dungeon.hero.belongings.getItem(ExoticPotion.regToExo.get(getClass()));
if (p != null) p.setAction();
}
}
if (Dungeon.hero.isAlive()) {

View File

@ -26,7 +26,12 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.Recipe;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHaste;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import java.util.ArrayList;
@ -41,8 +46,23 @@ public class ExoticPotion extends Potion {
public static final HashMap<Class<?extends Potion>, Class<?extends ExoticPotion>> regToExo = new HashMap<>();
public static final HashMap<Class<?extends ExoticPotion>, Class<?extends Potion>> exoToReg = new HashMap<>();
static{
regToExo.put(PotionOfHealing.class, PotionOfSheilding.class);
exoToReg.put(PotionOfSheilding.class, PotionOfHealing.class);
regToExo.put(PotionOfHealing.class, PotionOfShielding.class);
exoToReg.put(PotionOfShielding.class, PotionOfHealing.class);
regToExo.put(PotionOfToxicGas.class, PotionOfCorrosiveGas.class);
exoToReg.put(PotionOfCorrosiveGas.class, PotionOfToxicGas.class);
regToExo.put(PotionOfStrength.class, PotionOfAdrenalineSurge.class);
exoToReg.put(PotionOfAdrenalineSurge.class, PotionOfStrength.class);
regToExo.put(PotionOfFrost.class, PotionOfSnapFreeze.class);
exoToReg.put(PotionOfSnapFreeze.class, PotionOfFrost.class);
regToExo.put(PotionOfHaste.class, PotionOfStamina.class);
exoToReg.put(PotionOfStamina.class, PotionOfHaste.class);
regToExo.put(PotionOfLiquidFlame.class, PotionOfDragonsBreath.class);
exoToReg.put(PotionOfDragonsBreath.class, PotionOfLiquidFlame.class);
}
@Override

View File

@ -0,0 +1,78 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
public class PotionOfAdrenalineSurge extends ExoticPotion {
@Override
public void apply(Hero hero) {
setKnown();
Buff.affect(hero, strBoost.class).reset();
}
public static class strBoost extends Buff {
int boost;
private static final float INTERVAL = TICK * 500f;
public void reset(){
boost = 2;
spend(INTERVAL - cooldown());
}
public int boost(){
return boost;
}
@Override
public boolean act() {
boost --;
if (boost > 0){
spend( INTERVAL );
} else {
detach();
}
return true;
}
//TODO visuals
@Override
public int icon() {
return BuffIndicator.MOMENTUM;
}
@Override
public String toString() {
return "surge";
}
@Override
public String desc() {
return "cur boost: +" + boost + "\n\nleft: " + dispTurns(cooldown());
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.CorrosiveGas;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.noosa.audio.Sample;
public class PotionOfCorrosiveGas extends ExoticPotion {
@Override
public void shatter( int cell ) {
if (Dungeon.level.heroFOV[cell]) {
setKnown();
splash( cell );
Sample.INSTANCE.play( Assets.SND_SHATTER );
}
GameScene.add( Blob.seed( cell, 100, CorrosiveGas.class ).setStrength( 1 + Dungeon.depth/5));
}
}

View File

@ -0,0 +1,185 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
import com.watabou.utils.PathFinder;
import java.util.HashSet;
public class PotionOfDragonsBreath extends ExoticPotion {
//a lot of this is copy-paste from wand of fireblast
//the actual affected cells
private HashSet<Integer> affectedCells;
//the cells to trace fire shots to, for visual effects.
private HashSet<Integer> visualCells;
private int direction = 0;
@Override
//need to override drink so that time isn't spent right away
protected void drink(final Hero hero) {
detach( hero.belongings.backpack );
setKnown();
//hero.spend( TIME_TO_DRINK );
//hero.busy();
//apply( hero );
GameScene.selectCell(targeter);
}
private CellSelector.Listener targeter = new CellSelector.Listener() {
@Override
public void onSelect(final Integer cell) {
if (cell == null){
return;
} else {
Sample.INSTANCE.play( Assets.SND_DRINK );
curUser.sprite.operate(curUser.pos, new Callback() {
@Override
public void call() {
curUser.spend(1f);
curUser.sprite.idle();
curUser.sprite.zap(cell);
final Ballistica bolt
= new Ballistica(curUser.pos, cell, Ballistica.MAGIC_BOLT);
affectedCells = new HashSet<>();
visualCells = new HashSet<>();
int maxDist = 6;
int dist = Math.min(bolt.dist, maxDist);
for (int i = 0; i < PathFinder.CIRCLE8.length; i++) {
if (bolt.sourcePos + PathFinder.CIRCLE8[i] == bolt.path.get(1)) {
direction = i;
break;
}
}
float strength = maxDist;
for (int c : bolt.subPath(1, dist)) {
strength--; //as we start at dist 1, not 0.
affectedCells.add(c);
if (strength > 1) {
spreadFlames(c + PathFinder.CIRCLE8[left(direction)], strength - 1);
spreadFlames(c + PathFinder.CIRCLE8[direction], strength - 1);
spreadFlames(c + PathFinder.CIRCLE8[right(direction)], strength - 1);
} else {
visualCells.add(c);
}
}
//going to call this one manually
visualCells.remove(bolt.path.get(dist));
for (int c : visualCells) {
//this way we only get the cells at the tip, much better performance.
((MagicMissile) curUser.sprite.parent.recycle(MagicMissile.class)).reset(
MagicMissile.FIRE_CONE,
curUser.sprite,
c,
null
);
}
MagicMissile.boltFromChar(curUser.sprite.parent,
MagicMissile.FIRE_CONE,
curUser.sprite,
bolt.path.get(dist / 2),
new Callback() {
@Override
public void call() {
for (int cell : affectedCells){
//ignore caster cell
if (cell == bolt.sourcePos){
continue;
}
GameScene.add( Blob.seed( cell, 5, Fire.class ) );
Char ch = Actor.findChar( cell );
if (ch != null) {
Buff.affect( ch, Burning.class ).reignite( ch );
Buff.affect(ch, Cripple.class, 5f); break;
}
}
}
});
}
});
}
}
@Override
public String prompt() {
return "test";
}
};
//burn... BURNNNNN!.....
private void spreadFlames(int cell, float strength){
if (strength >= 0 && (Dungeon.level.passable[cell] || Dungeon.level.flamable[cell])){
affectedCells.add(cell);
if (strength >= 1.5f) {
visualCells.remove(cell);
spreadFlames(cell + PathFinder.CIRCLE8[left(direction)], strength - 1.5f);
spreadFlames(cell + PathFinder.CIRCLE8[direction], strength - 1.5f);
spreadFlames(cell + PathFinder.CIRCLE8[right(direction)], strength - 1.5f);
} else {
visualCells.add(cell);
}
} else if (!Dungeon.level.passable[cell])
visualCells.add(cell);
}
private int left(int direction){
return direction == 0 ? 7 : direction-1;
}
private int right(int direction){
return direction == 7 ? 0 : direction+1;
}
}

View File

@ -21,5 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic;
public class PotionOfSheilding extends ExoticPotion {
public class PotionOfShielding extends ExoticPotion {
//TODO
}

View File

@ -0,0 +1,63 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Freezing;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder;
public class PotionOfSnapFreeze extends ExoticPotion {
@Override
public void shatter(int cell) {
if (Dungeon.level.heroFOV[cell]) {
setKnown();
splash( cell );
Sample.INSTANCE.play( Assets.SND_SHATTER );
}
Fire fire = (Fire)Dungeon.level.blobs.get( Fire.class );
for (int offset : PathFinder.NEIGHBOURS9){
if (!Dungeon.level.solid[cell+offset]) {
Freezing.affect( cell + offset, fire );
Char ch = Actor.findChar( cell + offset);
if (ch != null){
//TODO balancing on this
Buff.affect(ch, Roots.class, 10f);
}
}
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Stamina;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
public class PotionOfStamina extends ExoticPotion {
@Override
public void apply(Hero hero) {
setKnown();
Buff.affect(hero, Stamina.class, 100f);
}
}

View File

@ -139,7 +139,7 @@ public class Ring extends KindofMisc {
return handler != null && handler.isKnown( this );
}
protected void setKnown() {
public void setKnown() {
if (!isKnown()) {
handler.know( this );
}

View File

@ -59,7 +59,7 @@ public abstract class Scroll extends Item {
protected static final float TIME_TO_READ = 1f;
protected int initials;
protected Integer initials;
private static final Class<?>[] scrolls = {
ScrollOfIdentify.class,

View File

@ -26,6 +26,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.Recipe;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTerror;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
import java.util.ArrayList;
@ -39,6 +41,13 @@ public abstract class ExoticScroll extends Scroll {
static{
regToExo.put(ScrollOfIdentify.class, ScrollOfForesight.class);
exoToReg.put(ScrollOfForesight.class, ScrollOfIdentify.class);
regToExo.put(ScrollOfUpgrade.class, ScrollOfEnchantment.class);
exoToReg.put(ScrollOfEnchantment.class, ScrollOfUpgrade.class);
regToExo.put(ScrollOfTerror.class, ScrollOfPetrification.class);
exoToReg.put(ScrollOfPetrification.class, ScrollOfTerror.class);
}
@Override

View File

@ -0,0 +1,54 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene;
import com.watabou.noosa.Game;
public class ScrollOfDistortion extends ExoticScroll {
@Override
public void doRead() {
//FIXME this doesn't handle various edge-cases. especially as it can trigger in boss rooms!
InterlevelScene.returnDepth = Dungeon.depth;
Belongings belongings = Dungeon.hero.belongings;
for (Notes.Record rec : Notes.getRecords()){
if (rec.depth() == Dungeon.depth){
Notes.remove(rec);
}
}
for (Item i : belongings){
if (i instanceof LloydsBeacon && ((LloydsBeacon) i).returnDepth == Dungeon.depth)
((LloydsBeacon) i).returnDepth = -1;
}
InterlevelScene.mode = InterlevelScene.Mode.RESET;
Game.switchScene(InterlevelScene.class);
}
}

View File

@ -0,0 +1,100 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic;
import com.shatteredpixel.shatteredpixeldungeon.effects.Enchanting;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
public class ScrollOfEnchantment extends ExoticScroll {
@Override
public void doRead() {
setKnown();
GameScene.selectItem( itemSelector, WndBag.Mode.ENCHANTABLE, "TODO" );
}
protected static WndBag.Listener itemSelector = new WndBag.Listener() {
@Override
public void onSelect(final Item item) {
if (item instanceof Weapon){
final Weapon.Enchantment enchants[] = new Weapon.Enchantment[3];
enchants[0] = Weapon.Enchantment.randomCommon();
enchants[1] = Weapon.Enchantment.randomUncommon();
do {
enchants[2] = Weapon.Enchantment.random();
} while (enchants[2].getClass() == enchants[0].getClass() ||
enchants[1].getClass() == enchants[0].getClass());
GameScene.show(new WndOptions("title", "body",
enchants[0].name(),
enchants[1].name(),
enchants[2].name(),
"cancel"){
@Override
protected void onSelect(int index) {
if (index < 3) {
((Weapon) item).enchant(enchants[index]);
//TODO text
Enchanting.show(curUser, item);
}
}
});
} else {
final Armor.Glyph glyphs[] = new Armor.Glyph[3];
glyphs[0] = Armor.Glyph.randomCommon();
glyphs[1] = Armor.Glyph.randomUncommon();
do {
glyphs[2] = Armor.Glyph.random();
} while (glyphs[2].getClass() == glyphs[0].getClass() ||
glyphs[1].getClass() == glyphs[0].getClass());
GameScene.show(new WndOptions("title", "body",
glyphs[0].name(),
glyphs[1].name(),
glyphs[2].name(),
"cancel"){
@Override
protected void onSelect(int index) {
if (index < 3) {
((Armor) item).inscribe(glyphs[index]);
//TODO text
Enchanting.show(curUser, item);
}
}
});
}
}
};
}

View File

@ -21,9 +21,102 @@
package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.effects.Identification;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
import java.util.HashSet;
public class ScrollOfForesight extends ExoticScroll {
@Override
public void doRead() {
curUser.sprite.parent.add( new Identification( curUser.sprite.center().offset( 0, -16 ) ) );
readAnimation();
setKnown();
Sample.INSTANCE.play( Assets.SND_READ );
Invisibility.dispel();
HashSet<Class<? extends Potion>> potions = Potion.getUnknown();
HashSet<Class<? extends Scroll>> scrolls = Scroll.getUnknown();
HashSet<Class<? extends Ring>> rings = Ring.getUnknown();
int total = potions.size() + scrolls.size() + rings.size();
if (total == 0){
GLog.n("Nothing left to Identify!");
return;
}
/*
//items which the player holds have lower priority
HashSet<Class <? extends Potion>> heldPotions = new HashSet<>();
HashSet<Class <? extends Scroll>> heldScrolls = new HashSet<>();
HashSet<Class <? extends Ring>> heldRings = new HashSet<>();
for (Class <? extends Potion> p : potions){
if (curUser.belongings.getItem(p) != null){
heldPotions.add(p);
}
}
potions.removeAll(heldPotions);
for (Class <? extends Scroll> s : scrolls){
if (curUser.belongings.getItem(s) != null){
heldScrolls.add(s);
}
}
scrolls.removeAll(heldScrolls);
for (Class <? extends Ring> r : rings){
if (curUser.belongings.getItem(r) != null){
heldRings.add(r);
}
}
rings.removeAll(heldRings);*/
int left = 4;
while (left > 0 && total > 0) {
try {
switch (Random.Int(3)) {
case 0:
default:
if (potions.isEmpty()) continue;
Potion p = Random.element(potions).newInstance();
p.setKnown();
GLog.i(p.name() + " identified!");
potions.remove(p.getClass());
break;
case 1:
if (scrolls.isEmpty()) continue;
Scroll s = Random.element(scrolls).newInstance();
s.setKnown();
GLog.i(s.name() + " identified!");
scrolls.remove(s.getClass());
break;
case 2:
if (rings.isEmpty()) continue;
Ring r = Random.element(rings).newInstance();
r.setKnown();
GLog.i(r.name() + " identified!");
rings.remove(r.getClass());
break;
}
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
}
left --;
total --;
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2018 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
import com.watabou.noosa.audio.Sample;
public class ScrollOfPetrification extends ExoticScroll {
@Override
public void doRead() {
new Flare( 5, 32 ).color( 0xFF0000, true ).show( curUser.sprite, 2f );
Sample.INSTANCE.play( Assets.SND_READ );
Invisibility.dispel();
for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) {
if (Dungeon.level.heroFOV[mob.pos]) {
Buff.affect( mob, Paralysis.class, Paralysis.DURATION );
}
}
setKnown();
readAnimation();
}
}

View File

@ -266,20 +266,28 @@ abstract public class Weapon extends KindOfWeapon {
public static abstract class Enchantment implements Bundlable {
private static final Class<?>[] enchants = new Class<?>[]{
Blazing.class, Venomous.class, Vorpal.class, Shocking.class,
Chilling.class, Eldritch.class, Lucky.class, Projecting.class, Unstable.class, Dazzling.class,
Grim.class, Stunning.class, Vampiric.class,};
private static final float[] chances= new float[]{
10, 10, 10, 10,
5, 5, 5, 5, 5, 5,
2, 2, 2 };
private static final Class<?>[] common = new Class<?>[]{
Blazing.class, Venomous.class, Vorpal.class, Shocking.class};
private static final Class<?>[] uncommon = new Class<?>[]{
Chilling.class, Eldritch.class, Lucky.class,
Projecting.class, Unstable.class, Dazzling.class};
private static final Class<?>[] rare = new Class<?>[]{
Grim.class, Stunning.class, Vampiric.class};
private static final float[] typeChances = new float[]{
40, //10 each
30, // 5 each
6 // 2 each
};
private static final Class<?>[] curses = new Class<?>[]{
Annoying.class, Displacing.class, Exhausting.class, Fragile.class,
Sacrificial.class, Wayward.class, Elastic.class, Friendly.class
};
public abstract int proc( Weapon weapon, Char attacker, Char defender, int damage );
public String name() {
@ -313,8 +321,40 @@ abstract public class Weapon extends KindOfWeapon {
@SuppressWarnings("unchecked")
public static Enchantment random() {
switch(Random.chances(typeChances)){
case 0: default:
return randomCommon();
case 1:
return randomUncommon();
case 2:
return randomRare();
}
}
@SuppressWarnings("unchecked")
public static Enchantment randomCommon() {
try {
return ((Class<Enchantment>)enchants[ Random.chances( chances ) ]).newInstance();
return ((Class<Enchantment>)Random.oneOf(common)).newInstance();
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
return null;
}
}
@SuppressWarnings("unchecked")
public static Enchantment randomUncommon() {
try {
return ((Class<Enchantment>)Random.oneOf(uncommon)).newInstance();
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
return null;
}
}
@SuppressWarnings("unchecked")
public static Enchantment randomRare() {
try {
return ((Class<Enchantment>)Random.oneOf(rare)).newInstance();
} catch (Exception e) {
ShatteredPixelDungeon.reportException(e);
return null;

View File

@ -222,6 +222,12 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
play( operate );
}
public void operate( int cell, Callback callback ) {
animCallback = callback;
turnTo( ch.pos, cell );
play( operate );
}
public void zap( int cell ) {
turnTo( ch.pos, cell );
play( zap );