Update BetaX 0.6.0.1
|
@ -57,7 +57,7 @@ android {
|
|||
configurations { natives }
|
||||
|
||||
dependencies {
|
||||
implementation 'cat.ereza:customactivityoncrash:2.3.0'
|
||||
implementation 'com.github.RohitSurwase.UCE-Handler:uce_handler:1.4'
|
||||
implementation project(':core')
|
||||
|
||||
implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.badlogic.gdx.backends.android.AndroidApplication;
|
|||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
||||
import com.badlogic.gdx.backends.android.AndroidAudio;
|
||||
import com.badlogic.gdx.backends.android.AsynchronousAndroidAudio;
|
||||
import com.rohitss.uceh.UCEHandler;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.news.News;
|
||||
|
@ -84,6 +85,9 @@ public class AndroidGame extends AndroidApplication {
|
|||
// this is the default prefs filename given to an android app (.xml is automatically added to it)
|
||||
SPDSettings.set(instance.getPreferences("ShatteredPixelDungeon"));
|
||||
|
||||
UCEHandler.Builder builder = new UCEHandler.Builder(this);
|
||||
builder.build();
|
||||
|
||||
} else {
|
||||
instance = this;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ allprojects {
|
|||
repositories {
|
||||
maven{ url 'https://maven.aliyun.com/repository/google' }
|
||||
maven{ url 'https://maven.aliyun.com/repository/jcenter'}
|
||||
//maven { url 'https://jitpack.io' }
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
}
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 495 B |
Before Width: | Height: | Size: 404 B After Width: | Height: | Size: 827 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 621 B |
|
@ -1,4 +1,25 @@
|
|||
###MLPD
|
||||
actors.buffs.halomethaneburning.name=磷火缠身
|
||||
actors.buffs.halomethaneburning.heromsg=磷火像恶魔一样缠在了你的身上!
|
||||
actors.buffs.halomethaneburning.burnsup=%s被烧的渣都不剩了!
|
||||
actors.buffs.halomethaneburning.ondeath=你被磷火缠身燃烧的折磨至死…
|
||||
actors.buffs.halomethaneburning.rankings_desc=无法逃脱磷火缠身的痛苦
|
||||
actors.buffs.halomethaneburning.desc=没什么比被磷火缠身更痛苦了。 \n\n磷火会每回合都会造成伤害直到它被液体扑灭或者自行消散。磷火会在你进入水中时熄灭,打碎药瓶产生的磷火也具有同样的效果。 \n\n此外,磷火还会点燃所有接触到的可燃地形(以及可燃地形上的可燃物)。 \n\n剩余的燃烧效果时长:%s回合\n\nΠ相比于一般的火焰,磷火更加危险且更加致命Π
|
||||
actors.buffs.halofireimblue.name=磷火审判
|
||||
actors.buffs.halofireimblue.desc=你被灌注了磷火的力量!\n\n所有物理攻击都可以使敌人磷火缠身。与此同时你对磷火,火焰完全免疫。\n\n剩余磷火审判效果时长:%s回合
|
||||
|
||||
|
||||
actors.mobs.slimeprincess.name=史莱姆公主
|
||||
actors.mobs.slimeprincess.notice=站住!入侵者!
|
||||
actors.mobs.slimeprincess.defeated=你的行为会被世人铭记!
|
||||
actors.mobs.slimeprincess.!!!=!!!
|
||||
actors.mobs.slimeprincess.pumpup=史莱姆公主正在准备发射激光
|
||||
actors.mobs.slimeprincess.enraged=你为何要继续前进?
|
||||
actors.mobs.slimeprincess.gluuurp=让我看看你的能耐吧,凡人!
|
||||
|
||||
actors.mobs.slimeprincess.rankings_desc=成为史莱姆公主的傀儡
|
||||
actors.mobs.slimeprincess.desc=史莱姆公主,一个比Yog更强大的存在。她的力量诞生于300年前翼绫的手中,是翼绫曾经的宠物精灵。因为那场大火,翼绫从此了无音信。而她也来到了这个无人问津的古堡,在这里沉睡着,直到你的到来……吵醒了这个上古原始精灵……
|
||||
|
||||
custom.testmode.levelteleporter.name = 升降器
|
||||
custom.testmode.levelteleporter.desc = 测试专用的升降器,用于在楼层之间快速移动。注意,锁层状态下无法移动。
|
||||
custom.testmode.levelteleporter.ac_descend = 下一层
|
||||
|
@ -1381,9 +1402,17 @@ actors.mobs.npcs.sheep.def_verb=格挡
|
|||
actors.mobs.npcs.sheep.desc=这是一只魔法绵羊。为什么叫它魔法绵羊?因为你杀不死它。它只会站在那里直到它消失,它会做的事情只有边反刍边对你翻白眼。
|
||||
|
||||
actors.mobs.npcs.shopkeeper.name=商人
|
||||
actors.mobs.npcs.shopkeeper.thief=小偷,小偷!
|
||||
actors.mobs.npcs.shopkeeper.arise=抢劫者,我诅咒你!你被商人诅咒了,你着火了!你暂时看不见了……
|
||||
actors.mobs.npcs.shopkeeper.guards=来人,快来人!有人想在超市0元购!
|
||||
actors.mobs.npcs.shopkeeper.greetings=你好啊%s.欢迎来到我的商店!我会为你的行程提供必要的补给。价钱公道,童叟无欺。
|
||||
actors.mobs.npcs.shopkeeper.goodbye=欢迎下次再来!%s.
|
||||
actors.mobs.npcs.shopkeeper.thief=不知天高地厚无知之辈,你会为你的行为付出代价!!!
|
||||
actors.mobs.npcs.shopkeeper.sell=选择一件要出售的物品
|
||||
actors.mobs.npcs.shopkeeper.desc=这个矮胖的家伙看起来更适合在某些大城市里做买卖而不是这种地牢。这些商品的价格解释了为什么他会喜欢在这儿做生意。
|
||||
actors.mobs.npcs.shopkeeper.zcz=商人喊来了制裁者!
|
||||
actors.mobs.npcs.shopkeeper.eye=商人喊来了真眼者!
|
||||
actors.mobs.npcs.shopkeeper.dead=商人为敌人们购买了精英系统,选好东西,迅速离开本层!!!
|
||||
actors.mobs.npcs.shopkeeper.live=商人还为首领购买了精英系统,选好东西,迅速离开本层!!!
|
||||
|
||||
actors.mobs.npcs.wandmaker.name=老杖匠
|
||||
actors.mobs.npcs.wandmaker.intro_warrior=啊,能在这片压抑的地方遇见一位英雄可真是个惊喜!如果你愿意帮助我这个老人家脱离苦海的话,你可以帮忙做一个任务。
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#scenes.aboutscene.=
|
||||
windows.wndsettings$displaytab.splash_screen=启动时的瀑布界面
|
||||
windows.wndsettings$displaytab.disable=关闭
|
||||
windows.wndsettings$displaytab.full=开启
|
||||
windows.wndsettings$extendtab.splash_screen=启动界面
|
||||
windows.wndsettings$extendtab.disable=关闭
|
||||
windows.wndsettings$extendtab.full=开启
|
||||
|
||||
scenes.feedbackscene$1.title=确定退出游戏?
|
||||
scenes.feedbackscene$1.intro=你确定要退出游戏吗?
|
||||
|
@ -14,7 +14,7 @@ scenes.feedbackscene$1.feedback_link=回到游戏
|
|||
scenes.feedbackscene$1.join_link=加入魔绫开发总群
|
||||
|
||||
|
||||
scenes.changesscene.earlier=破碎更新动态
|
||||
scenes.changesscene.earlier=破碎更新日志
|
||||
scenes.changesscene.later=魔绫更新动态
|
||||
scenes.changesscene.shpd=破碎更新日志
|
||||
|
||||
|
@ -31,7 +31,7 @@ scenes.interlevelscene.dialog_1=合理_运用物品_,\n\n获取_最终胜利_
|
|||
scenes.interlevelscene.dialog_2=你知道吗?\n\n_左下角的放大镜_是一个好东西
|
||||
scenes.interlevelscene.dialog_3=常去看_更新记录_的好孩子,\n\n就不会因为_新改动_而茫然.
|
||||
scenes.interlevelscene.dialog_4=魔绫像素地牢-始于_2021年2月_,\n\n感谢引导者_REN_和Γ红龙Γ。
|
||||
scenes.interlevelscene.dialogi_5=有些时候_直面失败_,\n\n或许并不是什么坏事
|
||||
scenes.interlevelscene.dialog_5=有些时候_直面失败_,\n\n或许并不是什么坏事
|
||||
scenes.interlevelscene.dialog_6=_小心奸商!!!_\n\n他甚至不会卖给你_未诅咒的物品_!
|
||||
scenes.interlevelscene.dialog_7=Δ种子Δ是个好东西,\n\n_关键看你_会不会用
|
||||
scenes.interlevelscene.dialog_8=_死灵领主_是无敌的!\n\n你需要击败_骷髅王_!
|
||||
|
|
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 68 KiB |
|
@ -97,9 +97,10 @@ public class Assets {
|
|||
public static final String LOCKED = "interfaces/locked_badge.png";
|
||||
|
||||
public static final String CHROME = "interfaces/chrome.png";
|
||||
public static final String CHROME_DARK = "interfaces/chrome_normal.png";
|
||||
public static final String ICONS = "interfaces/icons.png";
|
||||
public static final String STATUS = "interfaces/status_pane.png";
|
||||
|
||||
public static final String TOOLBARDRAK = "interfaces/toolbar_normal.png";
|
||||
public static final String STATUS_DARK = "interfaces/status_pane_normal.png";
|
||||
|
||||
public static final String MENU = "interfaces/menu_pane.png";
|
||||
|
@ -112,7 +113,7 @@ public class Assets {
|
|||
|
||||
public static final String LOADING_SEWERS = "interfaces/loading_sewers.png";
|
||||
public static final String LOADING_PRISON = "interfaces/loading_prison.png";
|
||||
public static final String LOADING_CAVES = "interfaces/loading_caves.png";
|
||||
public static final String LOADING_COLD = "interfaces/loading_cold.png";
|
||||
public static final String LOADING_CITY = "interfaces/loading_city.png";
|
||||
public static final String LOADING_HALLS = "interfaces/loading_halls.png";
|
||||
|
||||
|
@ -121,7 +122,7 @@ public class Assets {
|
|||
|
||||
public static final String TALENT_ICONS = "interfaces/talent_icons.png";
|
||||
public static final String TALENT_BUTTON = "interfaces/talent_button.png";
|
||||
|
||||
public static final String TALENT_BUTTON_DARK = "interfaces/talent_button_dark.png";
|
||||
public static final String HERO_ICONS = "interfaces/hero_icons.png";
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,12 @@ public class Chrome {
|
|||
}
|
||||
|
||||
public static NinePatch get( Type type ) {
|
||||
String Asset = Assets.Interfaces.CHROME;
|
||||
String Asset;
|
||||
if (SPDSettings.ClassUI()) {
|
||||
Asset = Assets.Interfaces.CHROME_DARK;
|
||||
} else {
|
||||
Asset = Assets.Interfaces.CHROME;
|
||||
}
|
||||
switch (type) {
|
||||
case WINDOW:
|
||||
return new NinePatch( Asset, 0, 0, 20, 20, 6 );
|
||||
|
|
|
@ -501,6 +501,29 @@ public class Dungeon {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static boolean NxhyshopOnLevel() {
|
||||
return depth == 9 || depth == 18;
|
||||
}
|
||||
|
||||
public static boolean NyzshopOnLevel() {
|
||||
return depth == 12;
|
||||
}
|
||||
|
||||
//圣域保护
|
||||
public static boolean GodWaterLevel() {
|
||||
return depth == 1 ||depth == 2||depth == 3||depth == 4;
|
||||
}
|
||||
|
||||
//监狱保护
|
||||
public static boolean PrisonWaterLevel() {
|
||||
return depth == 6 ||depth == 7||depth == 8||depth == 9;
|
||||
}
|
||||
|
||||
//冰雪祝福
|
||||
public static boolean ColdWaterLevel() {
|
||||
return depth == 11 ||depth == 12||depth == 13||depth == 14;
|
||||
}
|
||||
|
||||
public static boolean shopOnLevel() {
|
||||
return depth == 6 || depth == 11 || depth == 16;
|
||||
}
|
||||
|
|
|
@ -396,10 +396,6 @@ public class SPDSettings extends GameSettings {
|
|||
return getBoolean(KEY_DARK, false);
|
||||
}
|
||||
|
||||
public static void ClassSkin(boolean value) {
|
||||
put( KEY_SKIN, value );
|
||||
}
|
||||
|
||||
public static boolean ClassSkin() {
|
||||
return getBoolean(KEY_SKIN, false);
|
||||
}
|
||||
|
@ -411,21 +407,4 @@ public class SPDSettings extends GameSettings {
|
|||
public static void ClassPage(boolean value) {
|
||||
put( KEY_PAGE, value );
|
||||
}
|
||||
|
||||
|
||||
public static boolean PCTestUI() {
|
||||
return getBoolean(KEY_PCUI, false);
|
||||
}
|
||||
|
||||
public static void PCTestUI(boolean value) {
|
||||
put( KEY_PCUI, value );
|
||||
}
|
||||
|
||||
public static boolean quickSwapper() {
|
||||
return getBoolean(KEY_SWAP, false);
|
||||
}
|
||||
|
||||
public static void quickSwapper(boolean value) {
|
||||
put( KEY_SWAP, value );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
|||
public class Bless extends FlavourBuff {
|
||||
|
||||
public static final float DURATION = 30f;
|
||||
|
||||
public static final float GODSPOERF = 6f;
|
||||
{
|
||||
type = buffType.POSITIVE;
|
||||
announced = true;
|
||||
|
|
|
@ -37,6 +37,11 @@ public class HaloFireImBlue extends Buff {
|
|||
announced = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String iconTextDisplay() {
|
||||
return Integer.toString((int)left);
|
||||
}
|
||||
|
||||
public static final float DURATION = 80f;
|
||||
|
||||
public static final float SURATION = 7f;
|
||||
|
|
|
@ -70,6 +70,11 @@ public class HalomethaneBurning extends Buff implements Hero.Doom {
|
|||
bundle.put( LEFT, left );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String iconTextDisplay() {
|
||||
return Integer.toString((int)left);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle( Bundle bundle ) {
|
||||
super.restoreFromBundle(bundle);
|
||||
|
|
|
@ -31,13 +31,17 @@ import com.watabou.noosa.Image;
|
|||
public class RoseShiled extends FlavourBuff {
|
||||
|
||||
public static final float DURATION = 70f;
|
||||
public static final float SURATION = 10f;
|
||||
public static final float XURATION = 3f;
|
||||
|
||||
{
|
||||
type = buffType.POSITIVE;
|
||||
announced = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String iconTextDisplay() {
|
||||
return Integer.toString((int)DURATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fx(boolean on) {
|
||||
if (on) target.sprite.add(CharSprite.State.ROSESHIELDED);
|
||||
|
|
|
@ -48,6 +48,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.DeadSoul;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Drowsy;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Foresight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FrostImbueEX;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HoldFast;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
|
||||
|
@ -56,6 +58,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MindVision;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Momentum;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Shadows;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
||||
|
@ -1816,6 +1819,34 @@ public class Hero extends Char {
|
|||
|
||||
super.move( step, travelling);
|
||||
|
||||
if (Dungeon.GodWaterLevel()&& Dungeon.level.water[pos]){
|
||||
Buff.affect(hero, Barkskin.class).set( 2 + hero.lvl/4, 10 );
|
||||
Buff.prolong(this, Bless.class, Bless.GODSPOERF);
|
||||
}
|
||||
|
||||
//监狱之水 祝福效果
|
||||
if (Dungeon.PrisonWaterLevel()&& Dungeon.level.water[pos]){
|
||||
Buff.affect(hero, Barkskin.class).set( 2 + hero.lvl/4, 10 );
|
||||
Buff.prolong(this, Bless.class,Bless.GODSPOERF);
|
||||
Buff.affect(this, Haste.class, Haste.DURATION/20);
|
||||
Buff.affect(this, Shadows.class, Shadows.DURATION/10f);
|
||||
} else if(Dungeon.PrisonWaterLevel()&& !Dungeon.level.water[pos])
|
||||
for (Buff buff : hero.buffs()) {
|
||||
if (buff instanceof Shadows||buff instanceof Haste ) {
|
||||
buff.detach();
|
||||
}
|
||||
}
|
||||
|
||||
//矿洞之水 祝福效果
|
||||
if (Dungeon.ColdWaterLevel()&& Dungeon.level.water[pos]){
|
||||
Buff.affect(this, FrostImbueEX.class, FrostImbueEX.DURATION*0.3f);
|
||||
} else if(Dungeon.ColdWaterLevel()&& !Dungeon.level.water[pos])
|
||||
for (Buff buff : hero.buffs()) {
|
||||
if (buff instanceof FrostImbueEX) {
|
||||
buff.detach();
|
||||
}
|
||||
}
|
||||
|
||||
if (!flying && travelling) {
|
||||
if (Dungeon.level.water[pos]) {
|
||||
Sample.INSTANCE.play( Assets.Sounds.WATER, 1, Random.Float( 0.8f, 1.25f ) );
|
||||
|
|
|
@ -46,7 +46,7 @@ public class Bestiary {
|
|||
case 1:
|
||||
//3x rat, 1x snake
|
||||
return new ArrayList<>(Arrays.asList(
|
||||
Rat.class, Rat.class,
|
||||
SlimePrincess.class, Rat.class,
|
||||
Rat.class, OGPDZSLS.class, Snake.class,
|
||||
Snake.class,Snake.class,Snake.class));
|
||||
case 2:
|
||||
|
|
|
@ -65,9 +65,9 @@ public class Eye extends Mob {
|
|||
properties.add(Property.DEMONIC);
|
||||
}
|
||||
|
||||
public static void spawnAround( int pos ) {
|
||||
public static void spawnAround() {
|
||||
for (int n : PathFinder.NEIGHBOURS4) {
|
||||
spawnAt( pos + n );
|
||||
spawnAt( Random.Int(Dungeon.level.length()) + n );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.quest.GooBlob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.GooSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.SlimePrincessSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class SlimePrincess extends Mob {
|
||||
|
||||
{
|
||||
HP = HT = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 1200 : 800;
|
||||
EXP = 10;
|
||||
defenseSkill = 8;
|
||||
spriteClass = SlimePrincessSprite.class;
|
||||
|
||||
properties.add(Property.BOSS);
|
||||
properties.add(Property.DEMONIC);
|
||||
properties.add(Property.ACIDIC);
|
||||
}
|
||||
|
||||
private int pumpedUp = 0;
|
||||
private int healInc = 1;
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
int min = 1;
|
||||
int max = (HP*2 <= HT) ? 12 : 8;
|
||||
if (pumpedUp > 0) {
|
||||
pumpedUp = 0;
|
||||
return Random.NormalIntRange( min*3, max*3 );
|
||||
} else {
|
||||
return Random.NormalIntRange( min, max );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
int attack = 10;
|
||||
if (HP*2 <= HT) attack = 15;
|
||||
if (pumpedUp > 0) attack *= 2;
|
||||
return attack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int defenseSkill(Char enemy) {
|
||||
return (int)(super.defenseSkill(enemy) * ((HP*2 <= HT)? 1.5 : 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act() {
|
||||
|
||||
if (Dungeon.level.water[pos] && HP < HT) {
|
||||
HP += healInc;
|
||||
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null) lock.removeTime(healInc*2);
|
||||
|
||||
if (Dungeon.level.heroFOV[pos] ){
|
||||
sprite.emitter().burst( Speck.factory( Speck.HEALING ), healInc );
|
||||
}
|
||||
if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES) && healInc < 3) {
|
||||
healInc++;
|
||||
}
|
||||
if (HP*2 > HT) {
|
||||
BossHealthBar.bleed(false);
|
||||
((GooSprite)sprite).spray(false);
|
||||
HP = Math.min(HP, HT);
|
||||
}
|
||||
} else {
|
||||
healInc = 1;
|
||||
}
|
||||
|
||||
if (state != SLEEPING){
|
||||
Dungeon.level.seal();
|
||||
}
|
||||
|
||||
return super.act();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
if (pumpedUp > 0){
|
||||
//we check both from and to in this case as projectile logic isn't always symmetrical.
|
||||
//this helps trim out BS edge-cases
|
||||
return Dungeon.level.distance(enemy.pos, pos) <= 2
|
||||
&& new Ballistica( pos, enemy.pos, Ballistica.PROJECTILE).collisionPos == enemy.pos
|
||||
&& new Ballistica( enemy.pos, pos, Ballistica.PROJECTILE).collisionPos == pos;
|
||||
} else {
|
||||
return super.canAttack(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackProc( Char enemy, int damage ) {
|
||||
damage = super.attackProc( enemy, damage );
|
||||
if (Random.Int( 3 ) == 0) {
|
||||
Buff.affect( enemy, Ooze.class ).set( Ooze.DURATION );
|
||||
enemy.sprite.burst( 0x000000, 5 );
|
||||
}
|
||||
|
||||
if (pumpedUp > 0) {
|
||||
Camera.main.shake( 3, 0.2f );
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSpriteState() {
|
||||
super.updateSpriteState();
|
||||
|
||||
if (pumpedUp > 0){
|
||||
((GooSprite)sprite).pumpUp( pumpedUp );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doAttack( Char enemy ) {
|
||||
if (pumpedUp == 1) {
|
||||
pumpedUp++;
|
||||
((GooSprite)sprite).pumpUp( pumpedUp );
|
||||
|
||||
spend( attackDelay() );
|
||||
|
||||
return true;
|
||||
} else if (pumpedUp >= 2 || Random.Int( (HP*2 <= HT) ? 2 : 5 ) > 0) {
|
||||
|
||||
boolean visible = Dungeon.level.heroFOV[pos];
|
||||
|
||||
if (visible) {
|
||||
if (pumpedUp >= 2) {
|
||||
((GooSprite) sprite).pumpAttack();
|
||||
} else {
|
||||
sprite.attack(enemy.pos);
|
||||
}
|
||||
} else {
|
||||
if (pumpedUp >= 2){
|
||||
((GooSprite)sprite).triggerEmitters();
|
||||
}
|
||||
attack( enemy );
|
||||
spend( attackDelay() );
|
||||
}
|
||||
|
||||
return !visible;
|
||||
|
||||
} else {
|
||||
|
||||
pumpedUp++;
|
||||
if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){
|
||||
pumpedUp++;
|
||||
}
|
||||
|
||||
((GooSprite)sprite).pumpUp( pumpedUp );
|
||||
|
||||
if (Dungeon.level.heroFOV[pos]) {
|
||||
sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "!!!") );
|
||||
GLog.n( Messages.get(this, "pumpup") );
|
||||
}
|
||||
|
||||
spend( attackDelay() );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attack( Char enemy, float dmgMulti, float dmgBonus, float accMulti ) {
|
||||
boolean result = super.attack( enemy, dmgMulti, dmgBonus, accMulti );
|
||||
pumpedUp = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getCloser( int target ) {
|
||||
if (pumpedUp != 0) {
|
||||
pumpedUp = 0;
|
||||
sprite.idle();
|
||||
}
|
||||
return super.getCloser( target );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int dmg, Object src) {
|
||||
if (!BossHealthBar.isAssigned()){
|
||||
BossHealthBar.assignBoss( this );
|
||||
Dungeon.level.seal();
|
||||
}
|
||||
boolean bleeding = (HP*2 <= HT);
|
||||
super.damage(dmg, src);
|
||||
if ((HP*2 <= HT) && !bleeding){
|
||||
BossHealthBar.bleed(true);
|
||||
sprite.showStatus(CharSprite.NEGATIVE, Messages.get(this, "enraged"));
|
||||
((GooSprite)sprite).spray(true);
|
||||
yell(Messages.get(this, "gluuurp"));
|
||||
}
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null) lock.addTime(dmg*2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die( Object cause ) {
|
||||
|
||||
super.die( cause );
|
||||
|
||||
Dungeon.level.unseal();
|
||||
|
||||
GameScene.bossSlain();
|
||||
Dungeon.level.drop( new SkeletonKey( Dungeon.depth ), pos ).sprite.drop();
|
||||
|
||||
//60% chance of 2 blobs, 30% chance of 3, 10% chance for 4. Average of 2.5
|
||||
int blobs = Random.chances(new float[]{0, 0, 6, 3, 1});
|
||||
for (int i = 0; i < blobs; i++){
|
||||
int ofs;
|
||||
do {
|
||||
ofs = PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||
} while (!Dungeon.level.passable[pos + ofs]);
|
||||
Dungeon.level.drop( new GooBlob(), pos + ofs ).sprite.drop( pos );
|
||||
}
|
||||
|
||||
Badges.validateBossSlain();
|
||||
|
||||
yell( Messages.get(this, "defeated") );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notice() {
|
||||
super.notice();
|
||||
if (!BossHealthBar.isAssigned()) {
|
||||
BossHealthBar.assignBoss(this);
|
||||
Dungeon.level.seal();
|
||||
yell(Messages.get(this, "notice"));
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof DriedRose.GhostHero){
|
||||
((DriedRose.GhostHero) ch).sayBoss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final String PUMPEDUP = "pumpedup";
|
||||
private final String HEALINC = "healinc";
|
||||
|
||||
@Override
|
||||
public void storeInBundle( Bundle bundle ) {
|
||||
|
||||
super.storeInBundle( bundle );
|
||||
|
||||
bundle.put( PUMPEDUP , pumpedUp );
|
||||
bundle.put( HEALINC, healInc );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle( Bundle bundle ) {
|
||||
|
||||
super.restoreFromBundle( bundle );
|
||||
|
||||
pumpedUp = bundle.getInt( PUMPEDUP );
|
||||
if (state != SLEEPING) BossHealthBar.assignBoss(this);
|
||||
if ((HP*2 <= HT)) BossHealthBar.bleed(true);
|
||||
|
||||
//if check is for pre-0.9.3 saves
|
||||
healInc = bundle.getInt(HEALINC);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1326,7 +1326,7 @@ public class DwarfMaster extends Boss {
|
|||
spend(TICK*15);
|
||||
}else if(wave == 3){
|
||||
yell(Messages.get(this, "wave_2"));
|
||||
new Eye().spawnAround(pos);
|
||||
new Eye().spawnAround();
|
||||
summonSubject(1, DwarfMaster.DKGhoul.class);
|
||||
summonSubject(2, DwarfMaster.DKWarlock.class);
|
||||
summonSubject(2, DwarfMaster.DKGhoul.class);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2022 Evan Debenham
|
||||
* Copyright (C) 2014-2021 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
|
||||
|
@ -21,74 +21,195 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
||||
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ChampionEnemy;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.MoloHR;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ShopGuard;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ShopGuardEye;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkeeperSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class Shopkeeper extends NPC {
|
||||
|
||||
{
|
||||
spriteClass = ShopkeeperSprite.class;
|
||||
|
||||
properties.add(Property.BOSS);
|
||||
properties.add(Property.IMMOVABLE);
|
||||
}
|
||||
public static boolean seenBefore = false;
|
||||
|
||||
@Override
|
||||
public boolean interact(Char c) {
|
||||
if (c != hero) {
|
||||
return true;
|
||||
}
|
||||
Game.runOnRenderThread(new Callback() {
|
||||
@Override
|
||||
public void call() {
|
||||
sell();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean act() {
|
||||
|
||||
if (Dungeon.level.heroFOV[pos]){
|
||||
Notes.add(Notes.Landmark.SHOP);
|
||||
if (!seenBefore && Dungeon.level.heroFOV[pos]) {
|
||||
yell(Messages.get(this, "greetings", Dungeon.hero.name()));
|
||||
seenBefore = true;
|
||||
//Buff.affect(this, ChampionEnemy.AntiMagic.class);
|
||||
//Buff.affect(this, ChampionEnemy.Halo.class);
|
||||
} else if(seenBefore && !Dungeon.level.heroFOV[pos]) {
|
||||
seenBefore = false;
|
||||
yell(Messages.get(this, "goodbye", Dungeon.hero.name()));
|
||||
}
|
||||
throwItem();
|
||||
|
||||
sprite.turnTo( pos, Dungeon.hero.pos );
|
||||
spend( TICK );
|
||||
return super.act();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage( int dmg, Object src ) {
|
||||
flee();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add( Buff buff ) {
|
||||
flee();
|
||||
public int defenseSkill( Char enemy ) {
|
||||
return INFINITE_EVASION;
|
||||
}
|
||||
|
||||
/*
|
||||
Buff.prolong(Dungeon.hero, Blindness.class, Blindness.DURATION * 4f);
|
||||
GameScene.flash(0x80FFFFFF);
|
||||
Buff.affect(hero, Burning.class).reignite(hero, 15f);
|
||||
Dungeon.level.seal();
|
||||
Mob moa = new MoloHR();
|
||||
moa.pos = pos;
|
||||
GameScene.add(moa);
|
||||
yell(Messages.get(this, "arise"));
|
||||
new ShopGuardEye().spawnAround(pos);
|
||||
new ShopGuard().spawnAround(pos);
|
||||
Buff.affect(moa, ChampionEnemy.Growing.class);
|
||||
Buff.affect(moa, ChampionEnemy.Projecting.class);
|
||||
Buff.affect(moa, ChampionEnemy.AntiMagic.class);
|
||||
Buff.affect(moa, ChampionEnemy.Giant.class);
|
||||
Buff.affect(moa, ChampionEnemy.Blessed.class);
|
||||
Buff.affect(moa, ChampionEnemy.Halo.class);
|
||||
for (Mob mob : Dungeon.level.mobs) {
|
||||
switch (Random.Int(7)) {
|
||||
case 0:
|
||||
default:
|
||||
Buff.affect(mob, ChampionEnemy.Blazing.class);
|
||||
break;
|
||||
case 1:
|
||||
Buff.affect(mob, ChampionEnemy.Projecting.class);
|
||||
break;
|
||||
case 2:
|
||||
Buff.affect(mob, ChampionEnemy.AntiMagic.class);
|
||||
break;
|
||||
case 3:
|
||||
Buff.affect(mob, ChampionEnemy.Giant.class);
|
||||
break;
|
||||
case 4:
|
||||
Buff.affect(mob, ChampionEnemy.Blessed.class);
|
||||
break;
|
||||
case 5:
|
||||
Buff.affect(mob, ChampionEnemy.Growing.class);
|
||||
break;
|
||||
case 6:
|
||||
Buff.affect(mob, ChampionEnemy.Halo.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
yell(Messages.get(this, "dead"));*/
|
||||
|
||||
public void flee() {
|
||||
destroy();
|
||||
|
||||
Notes.remove(Notes.Landmark.SHOP);
|
||||
|
||||
CellEmitter.get(pos).burst(ElmoParticle.FACTORY, 6);
|
||||
Sample.INSTANCE.play(Assets.Sounds.ALERT);
|
||||
Music.INSTANCE.play(Assets.RUN, true);
|
||||
hero.sprite.burst(15597568, 9);
|
||||
sprite.killAndErase();
|
||||
CellEmitter.get( pos ).burst( ElmoParticle.FACTORY, 6 );
|
||||
Buff.prolong(Dungeon.hero, Blindness.class, Blindness.DURATION * 4f);
|
||||
GameScene.flash(0x80FFFFFF);
|
||||
Buff.affect(hero, Burning.class).reignite(hero, 15f);
|
||||
Dungeon.level.seal();
|
||||
Mob moa = new MoloHR();
|
||||
moa.pos = pos;
|
||||
GameScene.add(moa);
|
||||
yell(Messages.get(this, "arise"));
|
||||
new ShopGuardEye().spawnAround(pos);
|
||||
new ShopGuard().spawnAround(pos);
|
||||
Buff.affect(moa, ChampionEnemy.Growing.class);
|
||||
Buff.affect(moa, ChampionEnemy.Projecting.class);
|
||||
Buff.affect(moa, ChampionEnemy.AntiMagic.class);
|
||||
Buff.affect(moa, ChampionEnemy.Giant.class);
|
||||
Buff.affect(moa, ChampionEnemy.Blessed.class);
|
||||
Buff.affect(moa, ChampionEnemy.Halo.class);
|
||||
for (Mob mob : Dungeon.level.mobs) {
|
||||
switch (Random.Int(7)) {
|
||||
case 0:
|
||||
default:
|
||||
Buff.affect(mob, ChampionEnemy.Blazing.class);
|
||||
break;
|
||||
case 1:
|
||||
Buff.affect(mob, ChampionEnemy.Projecting.class);
|
||||
break;
|
||||
case 2:
|
||||
Buff.affect(mob, ChampionEnemy.AntiMagic.class);
|
||||
break;
|
||||
case 3:
|
||||
Buff.affect(mob, ChampionEnemy.Giant.class);
|
||||
break;
|
||||
case 4:
|
||||
Buff.affect(mob, ChampionEnemy.Blessed.class);
|
||||
break;
|
||||
case 5:
|
||||
Buff.affect(mob, ChampionEnemy.Growing.class);
|
||||
break;
|
||||
case 6:
|
||||
Buff.affect(mob, ChampionEnemy.Halo.class);
|
||||
break;
|
||||
}
|
||||
|
||||
@Override
|
||||
}
|
||||
yell(Messages.get(this, "dead"));
|
||||
}
|
||||
private DriedRose.GhostHero ghost = null;
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
for (Heap heap: Dungeon.level.heaps.valueList()) {
|
||||
if (heap.type == Heap.Type.FOR_SALE) {
|
||||
CellEmitter.get( heap.pos ).burst( ElmoParticle.FACTORY, 4 );
|
||||
if (heap.size() == 1) {
|
||||
heap.destroy();
|
||||
} else {
|
||||
heap.items.remove(heap.size()-1);
|
||||
heap.type = Heap.Type.HEAP;
|
||||
}
|
||||
heap.type = Heap.Type.HEAP;//Allow them to be picked up
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,18 +255,4 @@ public class Shopkeeper extends NPC {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean interact(Char c) {
|
||||
if (c != Dungeon.hero) {
|
||||
return true;
|
||||
}
|
||||
Game.runOnRenderThread(new Callback() {
|
||||
@Override
|
||||
public void call() {
|
||||
sell();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2022 Evan Debenham
|
||||
* Copyright (C) 2014-2021 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
|
||||
|
@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportat
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTerror;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
|
||||
import com.watabou.utils.Reflection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -53,17 +54,20 @@ public abstract class ExoticScroll extends Scroll {
|
|||
regToExo.put(ScrollOfUpgrade.class, ScrollOfEnchantment.class);
|
||||
exoToReg.put(ScrollOfEnchantment.class, ScrollOfUpgrade.class);
|
||||
|
||||
regToExo.put(ScrollOfTerror.class, ScrollOfPetrification.class);
|
||||
exoToReg.put(ScrollOfPetrification.class, ScrollOfTerror.class);
|
||||
|
||||
regToExo.put(ScrollOfRemoveCurse.class, ScrollOfAntiMagic.class);
|
||||
exoToReg.put(ScrollOfAntiMagic.class, ScrollOfRemoveCurse.class);
|
||||
|
||||
regToExo.put(ScrollOfLullaby.class, ScrollOfSirensSong.class);
|
||||
exoToReg.put(ScrollOfSirensSong.class, ScrollOfLullaby.class);
|
||||
regToExo.put(ScrollOfLullaby.class, ScrollOfAffection.class);
|
||||
exoToReg.put(ScrollOfAffection.class, ScrollOfLullaby.class);
|
||||
|
||||
regToExo.put(ScrollOfRage.class, ScrollOfChallenge.class);
|
||||
exoToReg.put(ScrollOfChallenge.class, ScrollOfRage.class);
|
||||
regToExo.put(ScrollOfRage.class, ScrollOfConfusion.class);
|
||||
exoToReg.put(ScrollOfConfusion.class, ScrollOfRage.class);
|
||||
|
||||
regToExo.put(ScrollOfTerror.class, ScrollOfDread.class);
|
||||
exoToReg.put(ScrollOfDread.class, ScrollOfTerror.class);
|
||||
regToExo.put(ScrollOfTerror.class, ScrollOfPetrification.class);
|
||||
exoToReg.put(ScrollOfPetrification.class, ScrollOfTerror.class);
|
||||
|
||||
regToExo.put(ScrollOfRecharging.class, ScrollOfMysticalEnergy.class);
|
||||
exoToReg.put(ScrollOfMysticalEnergy.class, ScrollOfRecharging.class);
|
||||
|
@ -80,8 +84,8 @@ public abstract class ExoticScroll extends Scroll {
|
|||
regToExo.put(ScrollOfMirrorImage.class, ScrollOfPrismaticImage.class);
|
||||
exoToReg.put(ScrollOfPrismaticImage.class, ScrollOfMirrorImage.class);
|
||||
|
||||
regToExo.put(ScrollOfTransmutation.class, ScrollOfMetamorphosis.class);
|
||||
exoToReg.put(ScrollOfMetamorphosis.class, ScrollOfTransmutation.class);
|
||||
regToExo.put(ScrollOfTransmutation.class, ScrollOfPolymorph.class);
|
||||
exoToReg.put(ScrollOfPolymorph.class, ScrollOfTransmutation.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,43 +113,54 @@ public abstract class ExoticScroll extends Scroll {
|
|||
@Override
|
||||
//20 gold more than its none-exotic equivalent
|
||||
public int value() {
|
||||
return (Reflection.newInstance(exoToReg.get(getClass())).value() + 30) * quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
//6 more energy than its none-exotic equivalent
|
||||
public int energyVal() {
|
||||
return (Reflection.newInstance(exoToReg.get(getClass())).energyVal() + 6) * quantity;
|
||||
return (Reflection.newInstance(exoToReg.get(getClass())).value() + 20) * quantity;
|
||||
}
|
||||
|
||||
public static class ScrollToExotic extends Recipe {
|
||||
|
||||
@Override
|
||||
public boolean testIngredients(ArrayList<Item> ingredients) {
|
||||
if (ingredients.size() == 1 && regToExo.containsKey(ingredients.get(0).getClass())){
|
||||
return true;
|
||||
int r = 0;
|
||||
Scroll s = null;
|
||||
|
||||
for (Item i : ingredients){
|
||||
if (i instanceof Runestone){
|
||||
r++;
|
||||
} else if (regToExo.containsKey(i.getClass())) {
|
||||
s = (Scroll)i;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return s != null && r == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cost(ArrayList<Item> ingredients) {
|
||||
return 6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item brew(ArrayList<Item> ingredients) {
|
||||
Item result = null;
|
||||
|
||||
for (Item i : ingredients){
|
||||
i.quantity(i.quantity()-1);
|
||||
if (regToExo.containsKey(i.getClass())) {
|
||||
result = Reflection.newInstance(regToExo.get(i.getClass()));
|
||||
}
|
||||
|
||||
return Reflection.newInstance(regToExo.get(ingredients.get(0).getClass()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item sampleOutput(ArrayList<Item> ingredients) {
|
||||
return Reflection.newInstance(regToExo.get(ingredients.get(0).getClass()));
|
||||
for (Item i : ingredients){
|
||||
if (regToExo.containsKey(i.getClass())) {
|
||||
return Reflection.newInstance(regToExo.get(i.getClass()));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public class CaveTwoBossLevel extends Level {
|
|||
|
||||
@Override
|
||||
public String tilesTex() {
|
||||
return Assets.Environment.TILES_CAVES;
|
||||
return Assets.Environment.TILES_COLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -88,12 +88,12 @@ public class CavesBossLevel extends Level {
|
|||
|
||||
@Override
|
||||
public String tilesTex() {
|
||||
return Assets.Environment.TILES_CAVES;
|
||||
return Assets.Environment.TILES_COLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String waterTex() {
|
||||
return Assets.Environment.WATER_CAVES;
|
||||
return Assets.Environment.WATER_COLD;
|
||||
}
|
||||
|
||||
private static int WIDTH = 33;
|
||||
|
|
|
@ -110,12 +110,12 @@ public class CavesLevel extends RegularLevel {
|
|||
|
||||
@Override
|
||||
public String tilesTex() {
|
||||
return Assets.Environment.TILES_CAVES;
|
||||
return Assets.Environment.TILES_COLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String waterTex() {
|
||||
return Assets.Environment.WATER_CAVES;
|
||||
return Assets.Environment.WATER_COLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,11 +21,15 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.Challenges.ALLBOSS;
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Bones;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RandomBuff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GoldenMimic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||
|
@ -45,6 +49,8 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LoopBuilder;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.SecretRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.NxhyShopRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.NyzBombAndBooksRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.PitRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
|
||||
|
@ -115,9 +121,17 @@ public abstract class RegularLevel extends Level {
|
|||
initRooms.add(s);
|
||||
}
|
||||
|
||||
if (Dungeon.shopOnLevel())
|
||||
if (Dungeon.shopOnLevel() && (!Dungeon.isChallenged(ALLBOSS)))
|
||||
initRooms.add(new ShopRoom());
|
||||
|
||||
if (Dungeon.NxhyshopOnLevel() && (!Dungeon.isChallenged(ALLBOSS)))
|
||||
initRooms.add(new NxhyShopRoom());
|
||||
|
||||
if (Dungeon.NyzshopOnLevel() && (!Dungeon.isChallenged(ALLBOSS))) {
|
||||
Buff.affect(hero, RandomBuff.class).set( (3 + Random.Int(9)+hero.STR/6+hero.HP/30)/Random.Int(1,2)+5, 1 );
|
||||
initRooms.add(new NyzBombAndBooksRoom());
|
||||
}
|
||||
|
||||
//force max special rooms and add one more for large levels
|
||||
int specials = specialRooms(feeling == Feeling.LARGE);
|
||||
if (feeling == Feeling.LARGE){
|
||||
|
|
|
@ -135,7 +135,7 @@ public class ChangesScene extends PixelScene {
|
|||
@Override
|
||||
public void onClick() {
|
||||
NewChangesScene.changesSelected = 0;
|
||||
NewChangesScene.fromChangesScene = true;
|
||||
NewChangesScene.fromChangesScene = false;
|
||||
ShatteredPixelDungeon.switchNoFade(NewChangesScene.class);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2022 Evan Debenham
|
||||
* Copyright (C) 2014-2021 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
|
||||
|
@ -21,10 +21,9 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.scenes;
|
||||
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.Challenges.LIGHTBLACK;
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
|
@ -41,10 +40,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom
|
|||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.GameLog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StyledButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndError;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStory;
|
||||
|
@ -57,13 +53,14 @@ import com.watabou.noosa.NoosaScript;
|
|||
import com.watabou.noosa.NoosaScriptNoLighting;
|
||||
import com.watabou.noosa.SkinnedBlock;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class InterlevelScene extends PixelScene {
|
||||
|
||||
public static int lastRegion = -1;
|
||||
//slow fade on entering a new region
|
||||
private static final float SLOW_FADE = 1f; //.33 in, 1.33 steady, .33 out, 2 seconds total
|
||||
//norm fade when loading, falling, returning, or descending to a new floor
|
||||
|
@ -74,7 +71,7 @@ public class InterlevelScene extends PixelScene {
|
|||
private static float fadeTime;
|
||||
|
||||
public enum Mode {
|
||||
DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL, RESET, NONE
|
||||
DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL, RESET, NONE,KO,GOBACK
|
||||
}
|
||||
public static Mode mode;
|
||||
|
||||
|
@ -85,6 +82,18 @@ public class InterlevelScene extends PixelScene {
|
|||
|
||||
public static boolean fallIntoPit;
|
||||
|
||||
private static final int NUM_TIPS = 32;
|
||||
|
||||
private static ArrayList<Integer> tipset;
|
||||
private RenderedTextBlock tip;
|
||||
|
||||
private void newTipSet()
|
||||
{
|
||||
tipset = new ArrayList<>();
|
||||
for(int i = 1; i <= NUM_TIPS; i++)
|
||||
tipset.add(i);
|
||||
}
|
||||
|
||||
private enum Phase {
|
||||
FADE_IN, STATIC, FADE_OUT
|
||||
}
|
||||
|
@ -97,16 +106,21 @@ public class InterlevelScene extends PixelScene {
|
|||
private static Exception error = null;
|
||||
private float waitingTime;
|
||||
|
||||
public static int lastRegion = -1;
|
||||
|
||||
{
|
||||
inGameScene = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
super.create();
|
||||
|
||||
if(tipset == null || tipset.isEmpty())
|
||||
newTipSet();
|
||||
|
||||
int tip_i = tipset.remove(Random.Int(tipset.size()));
|
||||
|
||||
tip = PixelScene.renderTextBlock(Messages.get(this, "dialog_" + tip_i), 9);
|
||||
tip.maxWidth((int)Math.round(Camera.main.width * 0.8));
|
||||
tip.setPos((Camera.main.width - tip.width()) / 2, (Camera.main.height - tip.height()) / 2);
|
||||
align(tip);
|
||||
add(tip);
|
||||
|
||||
String loadingAsset;
|
||||
int loadingDepth;
|
||||
final float scrollSpeed;
|
||||
|
@ -149,27 +163,20 @@ public class InterlevelScene extends PixelScene {
|
|||
scrollSpeed = returnDepth > Dungeon.depth ? 15 : -15;
|
||||
break;
|
||||
}
|
||||
|
||||
//flush the texture cache whenever moving between regions, helps reduce memory load
|
||||
int region = (int)Math.ceil(loadingDepth / 5f);
|
||||
if (region != lastRegion){
|
||||
TextureCache.clear();
|
||||
lastRegion = region;
|
||||
}
|
||||
|
||||
if (lastRegion == 1) loadingAsset = Assets.Interfaces.LOADING_SEWERS;
|
||||
else if (lastRegion == 2) loadingAsset = Assets.Interfaces.LOADING_PRISON;
|
||||
else if (lastRegion == 3) loadingAsset = Assets.Interfaces.LOADING_CAVES;
|
||||
else if (lastRegion == 4) loadingAsset = Assets.Interfaces.LOADING_CITY;
|
||||
else if (lastRegion == 5) loadingAsset = Assets.Interfaces.LOADING_HALLS;
|
||||
if (loadingDepth == 1) loadingAsset = Assets.Interfaces.LOADING_COLD;
|
||||
else if (loadingDepth <= 5) loadingAsset = Assets.Interfaces.LOADING_COLD;
|
||||
else if (loadingDepth <= 10) loadingAsset = Assets.Interfaces.LOADING_PRISON;
|
||||
else if (loadingDepth <= 15) loadingAsset = Assets.Interfaces.LOADING_COLD;
|
||||
else if (loadingDepth <= 20) loadingAsset = Assets.Interfaces.LOADING_CITY;
|
||||
else if (loadingDepth <= 25) loadingAsset = Assets.Interfaces.LOADING_HALLS;
|
||||
else loadingAsset = Assets.Interfaces.SHADOW;
|
||||
|
||||
//slow down transition when displaying an install prompt
|
||||
if (Updates.isInstallable()){
|
||||
fadeTime += 0.5f; //adds 1 second total
|
||||
fadeTime += 0.9f; //adds 1 second total
|
||||
//speed up transition when debugging
|
||||
} else if (DeviceCompat.isDebug()){
|
||||
fadeTime = 0f;
|
||||
fadeTime = 0.7f;
|
||||
}
|
||||
|
||||
SkinnedBlock bg = new SkinnedBlock(Camera.main.width, Camera.main.height, loadingAsset ){
|
||||
|
@ -209,40 +216,21 @@ public class InterlevelScene extends PixelScene {
|
|||
im.scale.x = Camera.main.height/5f;
|
||||
im.scale.y = Camera.main.width;
|
||||
add(im);
|
||||
|
||||
String text = Messages.get(Mode.class, mode.name());
|
||||
|
||||
message = PixelScene.renderTextBlock( text, 9 );
|
||||
message.setPos(
|
||||
(Camera.main.width - message.width()) / 2,
|
||||
(Camera.main.height - message.height()) / 2
|
||||
);
|
||||
message = PixelScene.renderTextBlock(text, 9);
|
||||
message.x = (Camera.main.width - message.width()) / 2;
|
||||
message.y = (Camera.main.height - message.height()) / 4;
|
||||
align(message);
|
||||
add( message );
|
||||
add(message);
|
||||
|
||||
if (Updates.isInstallable()){
|
||||
StyledButton install = new StyledButton(Chrome.Type.GREY_BUTTON_TR, Messages.get(this, "install")){
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
float p = timeLeft / fadeTime;
|
||||
if (phase == Phase.FADE_IN) alpha(1 - p);
|
||||
else if (phase == Phase.FADE_OUT) alpha(p);
|
||||
else alpha(1);
|
||||
}
|
||||
if(tipset == null || tipset.isEmpty())
|
||||
newTipSet();
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
Updates.launchInstall();
|
||||
}
|
||||
};
|
||||
install.icon(Icons.get(Icons.CHANGES));
|
||||
install.textColor(Window.SHPX_COLOR);
|
||||
install.setSize(install.reqWidth()+5, 20);
|
||||
install.setPos((Camera.main.width - install.width())/2, (Camera.main.height - message.bottom())/3 + message.bottom());
|
||||
add(install);
|
||||
}
|
||||
tip = PixelScene.renderTextBlock(Messages.get(this, "dialog_" + tip_i), 7);
|
||||
tip.maxWidth((int)Math.round(Camera.main.width * 0.8));
|
||||
tip.setPos((Camera.main.width - tip.width()) / 2, (Camera.main.height - tip.height()) / 2);
|
||||
align(tip);
|
||||
add(tip);
|
||||
|
||||
phase = Phase.FADE_IN;
|
||||
timeLeft = fadeTime;
|
||||
|
@ -275,12 +263,20 @@ public class InterlevelScene extends PixelScene {
|
|||
case RETURN:
|
||||
returnTo();
|
||||
break;
|
||||
case GOBACK:
|
||||
returnPO();
|
||||
break;
|
||||
case FALL:
|
||||
fall();
|
||||
break;
|
||||
case RESET:
|
||||
reset();
|
||||
break;
|
||||
case KO:
|
||||
reset();
|
||||
returnTx();
|
||||
resurrect();
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
@ -430,10 +426,29 @@ public class InterlevelScene extends PixelScene {
|
|||
Dungeon.switchLevel( level, returnPos );
|
||||
}
|
||||
|
||||
private void returnPO() throws IOException {
|
||||
Mob.holdAllies( Dungeon.level );
|
||||
hero.STR = 10;
|
||||
hero.lvl = 1;
|
||||
InterlevelScene.returnDepth = Math.max(1, (Dungeon.depth - 1 - (Dungeon.depth-2)%5));
|
||||
InterlevelScene.returnPos = -1;
|
||||
Level level = Dungeon.loadLevel( GamesInProgress.curSlot );
|
||||
Dungeon.switchLevel( level, returnPos );
|
||||
}
|
||||
|
||||
private void returnTx() throws IOException {
|
||||
|
||||
Mob.holdAllies( Dungeon.level );
|
||||
|
||||
Dungeon.saveAll();
|
||||
Dungeon.depth = 0;
|
||||
Level level = Dungeon.loadLevel( GamesInProgress.curSlot );
|
||||
Dungeon.switchLevel( level, returnPos );
|
||||
}
|
||||
|
||||
private void restore() throws IOException {
|
||||
|
||||
Mob.clearHeldAllies();
|
||||
|
||||
GameLog.wipe();
|
||||
|
||||
Dungeon.loadGame( GamesInProgress.curSlot );
|
||||
|
@ -451,7 +466,6 @@ public class InterlevelScene extends PixelScene {
|
|||
Mob.holdAllies( Dungeon.level );
|
||||
|
||||
Level level;
|
||||
|
||||
if (Dungeon.level.locked) {
|
||||
ArrayList<Item> preservedItems = Dungeon.level.getItemsToPreserveFromSealedResurrect();
|
||||
|
||||
|
@ -460,12 +474,10 @@ public class InterlevelScene extends PixelScene {
|
|||
level = Dungeon.newLevel();
|
||||
Dungeon.hero.pos = level.randomRespawnCell(Dungeon.hero);
|
||||
|
||||
if(!Dungeon.isChallenged(LIGHTBLACK)) {
|
||||
for (Item i : preservedItems) {
|
||||
for (Item i : preservedItems){
|
||||
level.drop(i, level.randomRespawnCell(null));
|
||||
}
|
||||
level.drop(new LostBackpack(), level.randomRespawnCell(null));
|
||||
}
|
||||
|
||||
} else {
|
||||
level = Dungeon.level;
|
||||
|
@ -488,12 +500,8 @@ public class InterlevelScene extends PixelScene {
|
|||
level.map[Dungeon.hero.pos] = Terrain.GRASS;
|
||||
}
|
||||
Dungeon.hero.resurrect();
|
||||
|
||||
//非光与影死亡掉落遗物
|
||||
if(!Dungeon.isChallenged(LIGHTBLACK)) {
|
||||
level.drop(new LostBackpack(), invPos);
|
||||
}
|
||||
}
|
||||
|
||||
Dungeon.switchLevel( level, Dungeon.hero.pos );
|
||||
}
|
||||
|
@ -501,7 +509,7 @@ public class InterlevelScene extends PixelScene {
|
|||
private void reset() throws IOException {
|
||||
|
||||
Mob.holdAllies( Dungeon.level );
|
||||
|
||||
hero.HP += 20;
|
||||
SpecialRoom.resetPitRoom(Dungeon.depth+1);
|
||||
|
||||
Dungeon.depth--;
|
||||
|
|
|
@ -25,7 +25,7 @@ public class NewChangesScene extends PixelScene {
|
|||
|
||||
public static int changesSelected = 0;
|
||||
|
||||
public static boolean fromChangesScene = false;
|
||||
public static boolean fromChangesScene = true;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
@ -151,7 +151,7 @@ public class NewChangesScene extends PixelScene {
|
|||
};
|
||||
|
||||
if (changesSelected != 0) btnBeta.textColor( 0xBBBBBB );
|
||||
btnBeta.setRect(list.left()-4f, list.bottom(), 45, changesSelected == 0 ? 19 : 15);
|
||||
btnBeta.setRect(list.left()-4f, list.bottom(), 46, changesSelected == 0 ? 19 : 15);
|
||||
addToBack(btnBeta);
|
||||
|
||||
StyledButton btn0_8 = new StyledButton(Chrome.Type.TOAST, "0.5.X"){
|
||||
|
@ -165,7 +165,7 @@ public class NewChangesScene extends PixelScene {
|
|||
}
|
||||
};
|
||||
if (changesSelected != 1) btn0_8.textColor( 0xBBBBBB );
|
||||
btn0_8.setRect(btnBeta.right()+1, list.bottom(), 45, changesSelected == 1 ? 19 : 15);
|
||||
btn0_8.setRect(btnBeta.right()+1, list.bottom(), 47, changesSelected == 1 ? 19 : 15);
|
||||
addToBack(btn0_8);
|
||||
|
||||
StyledButton btn0_7 = new StyledButton(Chrome.Type.TOAST, "0.0-0.4"){
|
||||
|
@ -179,7 +179,7 @@ public class NewChangesScene extends PixelScene {
|
|||
}
|
||||
};
|
||||
if (changesSelected != 2) btn0_7.textColor( 0xBBBBBB );
|
||||
btn0_7.setRect(btn0_8.right() + 1, btn0_8.top(), 45, changesSelected == 2 ? 19 : 15);
|
||||
btn0_7.setRect(btn0_8.right() + 1, btn0_8.top(), 46, changesSelected == 2 ? 19 : 15);
|
||||
addToBack(btn0_7);
|
||||
|
||||
Archs archs = new Archs();
|
||||
|
|
|
@ -48,7 +48,7 @@ public class ThanksScene extends PixelScene {
|
|||
|
||||
CreditsBlock mispd = new CreditsBlock(true, Window.TITLE_COLOR,
|
||||
"Magic Ling Pixel Dungeon",
|
||||
Icons.STAIRS.get(),
|
||||
new Image("Ling.png", 0, 0, 16, 16),
|
||||
"_Start to 2021-2-12_\n\nDev:_JDSA Ling_"
|
||||
,
|
||||
null,
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
||||
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.Challenges.SBSG;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
|
@ -161,23 +159,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
|
|||
renderShadow = true;
|
||||
|
||||
//突变激素 粒子效果
|
||||
if ((Dungeon.isChallenged(SBSG) && (ch instanceof Mob))){
|
||||
switch (Random.Int(4)) {
|
||||
case 0:
|
||||
default:
|
||||
this.add(State.ILLUMINATED);
|
||||
break;
|
||||
case 1:
|
||||
this.add(State.CHILLED);
|
||||
break;
|
||||
case 2:
|
||||
this.add(State.ROSESHIELDED);
|
||||
break;
|
||||
case 3:
|
||||
this.add(State.MARKED);
|
||||
break;
|
||||
}
|
||||
} else if (ch != Dungeon.hero) {
|
||||
if (ch != Dungeon.hero) {
|
||||
if (health == null) {
|
||||
health = new CharHealthIndicator(ch);
|
||||
} else {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2022 Evan Debenham
|
||||
* Copyright (C) 2014-2021 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
|
||||
|
@ -21,10 +21,16 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.ui;
|
||||
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.ui.Window.CYELLOW;
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.ui.Window.R_COLOR;
|
||||
import static com.shatteredpixel.shatteredpixeldungeon.ui.Window.TITLE_COLOR;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BloodParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||
import com.watabou.noosa.BitmapText;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.watabou.noosa.ui.Component;
|
||||
|
@ -36,6 +42,7 @@ public class BossHealthBar extends Component {
|
|||
private Image rawShielding;
|
||||
private Image shieldedHP;
|
||||
private Image hp;
|
||||
private BitmapText hpText;
|
||||
|
||||
private static Mob boss;
|
||||
|
||||
|
@ -71,6 +78,10 @@ public class BossHealthBar extends Component {
|
|||
hp = new Image(asset, 15, 19, 47, 4);
|
||||
add(hp);
|
||||
|
||||
hpText = new BitmapText(PixelScene.pixelFont);
|
||||
hpText.alpha(0.6f);
|
||||
add(hpText);
|
||||
|
||||
skull = new Image(asset, 5, 18, 6, 6);
|
||||
add(skull);
|
||||
|
||||
|
@ -90,6 +101,13 @@ public class BossHealthBar extends Component {
|
|||
hp.x = shieldedHP.x = rawShielding.x = bar.x+15;
|
||||
hp.y = shieldedHP.y = rawShielding.y = bar.y+6;
|
||||
|
||||
hpText.scale.set(PixelScene.align(0.5f));
|
||||
hpText.x = hp.x + 1;
|
||||
hpText.y = hp.y + (hp.height - (hpText.baseLine()+hpText.scale.y))/2f;
|
||||
hpText.y -= 0.001f; //prefer to be slightly higher
|
||||
hpText.hardlight( 0x808080 );
|
||||
PixelScene.align(hpText);
|
||||
|
||||
skull.x = bar.x+5;
|
||||
skull.y = bar.y+5;
|
||||
}
|
||||
|
@ -97,6 +115,8 @@ public class BossHealthBar extends Component {
|
|||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
|
||||
if (boss != null){
|
||||
if (!boss.isAlive() || !Dungeon.level.mobs.contains(boss)){
|
||||
boss = null;
|
||||
|
@ -106,15 +126,32 @@ public class BossHealthBar extends Component {
|
|||
float health = boss.HP;
|
||||
float shield = boss.shielding();
|
||||
float max = boss.HT;
|
||||
|
||||
int maxHp = boss.HP;
|
||||
hp.scale.x = Math.max( 0, (health-shield)/max);
|
||||
shieldedHP.scale.x = health/max;
|
||||
rawShielding.scale.x = shield/max;
|
||||
|
||||
if (hp.scale.x < 0.25f) bleed( true );
|
||||
if (shield <= 0){
|
||||
hpText.text(health + "/" + max);
|
||||
}
|
||||
else {
|
||||
hpText.text(health + "+" + shield + "/" + max);
|
||||
}
|
||||
|
||||
//低于75%渲染成蓝色 低于35%渲染成红色
|
||||
//Boss血量文本显示
|
||||
//完全不符合更新为蓝色颜色
|
||||
if (hp.scale.x > 0.75f) {
|
||||
hpText.hardlight( TITLE_COLOR );
|
||||
} else if (hp.scale.x > 0.20f){
|
||||
hpText.hardlight( CYELLOW );
|
||||
} else {
|
||||
bleed(true);
|
||||
hpText.hardlight( R_COLOR );
|
||||
}
|
||||
|
||||
if (bleeding != blood.on){
|
||||
if (bleeding) skull.tint( 0xcc0000, 0.6f );
|
||||
if (bleeding) skull.tint( 0xcc0000, 0.5f );
|
||||
else skull.resetColor();
|
||||
blood.on = bleeding;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2022 Evan Debenham
|
||||
* Copyright (C) 2014-2021 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
|
||||
|
@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.BlackKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.GoldenKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
|
||||
|
@ -47,7 +48,7 @@ public class KeyDisplay extends Visual {
|
|||
private FloatBuffer quads;
|
||||
private Vertexbuffer buffer;
|
||||
|
||||
private SmartTexture tx = TextureCache.get(Assets.Interfaces.MENU_BTN);
|
||||
private SmartTexture tx = TextureCache.get(Assets.Interfaces.MENU);
|
||||
|
||||
private boolean dirty = true;
|
||||
private int[] keys;
|
||||
|
@ -61,6 +62,7 @@ public class KeyDisplay extends Visual {
|
|||
keyMap.put(CrystalKey.class, 2);
|
||||
keyMap.put(GoldenKey.class, 3);
|
||||
keyMap.put(IronKey.class, 4);
|
||||
keyMap.put(BlackKey.class, 5);
|
||||
}
|
||||
|
||||
private int totalKeys = 0;
|
||||
|
@ -214,11 +216,4 @@ public class KeyDisplay extends Visual {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
if (buffer != null)
|
||||
buffer.delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
|
@ -83,7 +84,11 @@ public class TalentButton extends Button {
|
|||
fill = new ColorBlock(0, 4, 0xFFFFFF44);
|
||||
add(fill);
|
||||
|
||||
if (SPDSettings.ClassUI()) {
|
||||
bg = new Image(Assets.Interfaces.TALENT_BUTTON_DARK);
|
||||
} else {
|
||||
bg = new Image(Assets.Interfaces.TALENT_BUTTON);
|
||||
}
|
||||
add(bg);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTerrainTilemap;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndKeyBindings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuickBag;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.input.GameAction;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Game;
|
||||
|
@ -335,6 +336,7 @@ public class Toolbar extends Component {
|
|||
if (instance != null) instance.layout();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
@ -403,6 +405,16 @@ public class Toolbar extends Component {
|
|||
add( base );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
if (SPDSettings.ClassUI()) {
|
||||
base.texture = TextureCache.get(Assets.Interfaces.TOOLBARDRAK);
|
||||
} else {
|
||||
base.texture = TextureCache.get(Assets.Interfaces.TOOLBAR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
super.layout();
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.ui.changelist.mlpd;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.changelist.ChangeButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.changelist.ChangeInfo;
|
||||
import com.watabou.noosa.Image;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -13,27 +17,40 @@ public class vM0_6_7_X_Changes {
|
|||
}
|
||||
|
||||
public static void add_v0_6_0_Changes( ArrayList<ChangeInfo> changeInfos ) {
|
||||
ChangeInfo changes = new ChangeInfo("敬请期待-MLPD最终更新(P1)", true, "");
|
||||
changes.hardlight(0x808080);
|
||||
ChangeInfo changes = new ChangeInfo("v0.6.0.0-BetaX", true, "");
|
||||
changes.hardlight(Window.TITLE_COLOR);
|
||||
changeInfos.add(changes);
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.SHPX), ("更新底层到破碎123版本"),
|
||||
("魔绫即将进行大更新到破碎123版本,敬请期待")));
|
||||
changes = new ChangeInfo("改动", false, null);
|
||||
changes.hardlight(Window.SKYBULE_COLOR);
|
||||
changeInfos.add(changes);
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.CHANGES), ("重大更新"),
|
||||
("魔绫现已更新底层到破碎123版本!")));
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.CHALLENGE_ON), ("新挑战和部分挑战改动"),
|
||||
("魔绫即将对部分挑战进行重新调整,同时追加全新挑战,敬请期待")));
|
||||
("部分挑战进行重新调整,同时追加全新挑战,欢迎前来探索\n\n注意:部分挑战尚未完成,请等待后续版本")));
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.LANGS), ("本地化模块升级"),
|
||||
("魔绫即将对本地化语言模块优化,使部分渣机性能更好")));
|
||||
("魔绫已经对本地化语言模块优化,使部分低配设备性能更好")));
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.DISPLAY), ("UI优化改动"),
|
||||
("魔绫即将对UI优化改动进行大规模调整,敬请期待")));
|
||||
("魔绫已经对UI优化改动进行大规模调整,欢迎前来体验")));
|
||||
|
||||
changes.addButton(new ChangeButton((new Image("Ling.png", 0, 0, 16, 16)), ("开发者的话"),
|
||||
("你好,这里是绫。如你所见,这是全新的魔绫像素地牢,她已经步入了破碎1.2" +
|
||||
".3的版本。\n\n至此,魔绫像素地牢以后将针对于此破碎底层进行更新。今后不会继续同步底层破碎版本。\n\n" +
|
||||
"同时,本次更新后,后续应该还有几个补丁版。很高兴一路以来有那么多的朋友,非常谢谢你们的支持。\n\n现在,旅途才刚刚开始,魔绫下半段,将会更加精彩。\n" +
|
||||
"在这之前,就让我们继续在上半段的魔绫里面探索前进吧。")));
|
||||
|
||||
changes = new ChangeInfo("调整", false, null);
|
||||
changes.hardlight(Window.GREEN_COLOR);
|
||||
changeInfos.add(changes);
|
||||
|
||||
changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.FIREFISHSWORD), ("尚方宝剑特效重写"),
|
||||
("优化了尚方宝剑特效,并最大程度上进行了处理")));
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.STAIRS), ("开发者的话"),
|
||||
("魔绫地牢已经更新了接近一年,接下来,第一部分即将完结。敬请期待第二部分的更新!")));
|
||||
|
||||
changes.addButton(new ChangeButton(Icons.get(Icons.NEWS), ("不止于此"),
|
||||
("更多第一部分最终版更新情报,请锁定魔绫总群!")));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,6 +138,14 @@ public class WndChallenges extends Window {
|
|||
cb.checked((checked & Challenges.MASKS[i]) != 0);
|
||||
cb.active = editable;
|
||||
|
||||
//暂时禁用
|
||||
if(Challenges.NAME_IDS[i].equals("light&black")||Challenges.NAME_IDS[i].equals("exsg")||Challenges.NAME_IDS[i].equals("boss")||Challenges.NAME_IDS[i].equals("aquaphobia")){
|
||||
cb.active = false;
|
||||
cb.checked(false);
|
||||
cb.alpha(0.5f);
|
||||
}
|
||||
|
||||
|
||||
if (i > 0) {
|
||||
pos += GAP;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ import java.util.Locale;
|
|||
public class WndSettings extends WndTabbed {
|
||||
|
||||
private static final int WIDTH_P = 122;
|
||||
private static final int WIDTH_L = 223;
|
||||
private static final int WIDTH_L = 240;
|
||||
|
||||
private static final int SLIDER_HEIGHT = 24;
|
||||
private static final int BTN_HEIGHT = 18;
|
||||
|
@ -211,7 +211,7 @@ public class WndSettings extends WndTabbed {
|
|||
ColorBlock sep2;
|
||||
OptionSlider optBrightness;
|
||||
OptionSlider optVisGrid;
|
||||
OptionSlider optSplashScreen;
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
title = PixelScene.renderTextBlock(Messages.get(this, "title"), 9);
|
||||
|
@ -323,20 +323,6 @@ public class WndSettings extends WndTabbed {
|
|||
optVisGrid.setSelectedValue(SPDSettings.visualGrid());
|
||||
add(optVisGrid);
|
||||
|
||||
optSplashScreen = new OptionSlider(Messages.get(this, "splash_screen"),
|
||||
Messages.get(this, "disable" ),
|
||||
Messages.get( this, "full" ),
|
||||
0, 1) {
|
||||
@Override
|
||||
protected void onChange() {
|
||||
if (getSelectedValue() != SPDSettings.splashScreen()) {
|
||||
SPDSettings.splashScreen(getSelectedValue());
|
||||
}
|
||||
}
|
||||
};
|
||||
optSplashScreen.setSelectedValue(SPDSettings.splashScreen());
|
||||
add(optSplashScreen);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -351,7 +337,11 @@ public class WndSettings extends WndTabbed {
|
|||
bottom = sep1.y + 1;
|
||||
|
||||
if (width > 200 && chkSaver != null) {
|
||||
if(DeviceCompat.isDesktop()){
|
||||
chkFullscreen.setRect(0, bottom + GAP, width/2-1, BTN_HEIGHT);
|
||||
} else {
|
||||
chkFullscreen.setRect(999, bottom + GAP, width/2-1, BTN_HEIGHT);
|
||||
}
|
||||
chkSaver.setRect(chkFullscreen.right()+ GAP, bottom + GAP, width/2-1, BTN_HEIGHT);
|
||||
bottom = chkFullscreen.bottom();
|
||||
} else {
|
||||
|
@ -381,11 +371,11 @@ public class WndSettings extends WndTabbed {
|
|||
if (width > 200){
|
||||
optBrightness.setRect(0, bottom + GAP, width/2-GAP/2, SLIDER_HEIGHT);
|
||||
optVisGrid.setRect(optBrightness.right() + GAP, optBrightness.top(), width/2-GAP/2, SLIDER_HEIGHT);
|
||||
optSplashScreen.setRect(optVisGrid.right() + GAP, optVisGrid.top(), width/2-GAP/2, SLIDER_HEIGHT);
|
||||
//optSplashScreen.setRect(optBrightness.left(), optBrightness.bottom(), width, SLIDER_HEIGHT);
|
||||
} else {
|
||||
optBrightness.setRect(0, bottom + GAP, width, SLIDER_HEIGHT);
|
||||
optVisGrid.setRect(0, optBrightness.bottom() + GAP, width, SLIDER_HEIGHT);
|
||||
optSplashScreen.setRect(0, optVisGrid.bottom() + GAP, width, SLIDER_HEIGHT);
|
||||
//optSplashScreen.setRect(0, optVisGrid.bottom() + GAP, width, SLIDER_HEIGHT);
|
||||
}
|
||||
|
||||
height = optVisGrid.bottom();
|
||||
|
@ -612,7 +602,7 @@ public class WndSettings extends WndTabbed {
|
|||
RenderedTextBlock title;
|
||||
ColorBlock sep1;
|
||||
CheckBox ClassUI;
|
||||
CheckBox ClassSkin;
|
||||
OptionSlider optSplashScreen;
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
|
@ -632,6 +622,20 @@ public class WndSettings extends WndTabbed {
|
|||
};
|
||||
ClassUI.checked(SPDSettings.ClassUI());
|
||||
add(ClassUI);
|
||||
|
||||
optSplashScreen = new OptionSlider(Messages.get(this, "splash_screen"),
|
||||
Messages.get(this, "disable" ),
|
||||
Messages.get( this, "full" ),
|
||||
0, 1) {
|
||||
@Override
|
||||
protected void onChange() {
|
||||
if (getSelectedValue() != SPDSettings.splashScreen()) {
|
||||
SPDSettings.splashScreen(getSelectedValue());
|
||||
}
|
||||
}
|
||||
};
|
||||
optSplashScreen.setSelectedValue(SPDSettings.splashScreen());
|
||||
add(optSplashScreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -646,10 +650,12 @@ public class WndSettings extends WndTabbed {
|
|||
bottom = sep1.y + 1;
|
||||
|
||||
if (width > 200){
|
||||
ClassUI.setRect(0, bottom, width/2-GAP/2, SLIDER_HEIGHT);
|
||||
ClassUI.setRect(0, bottom, width, SLIDER_HEIGHT);
|
||||
optSplashScreen.setRect(0, ClassUI.bottom() + GAP, width, SLIDER_HEIGHT);
|
||||
} else {
|
||||
//quickslots.setRect(0, bottom + GAP, width, SLIDER_HEIGHT);
|
||||
ClassUI.setRect(0, bottom + GAP, width, SLIDER_HEIGHT);
|
||||
optSplashScreen.setRect(0, ClassUI.bottom() + GAP, width, SLIDER_HEIGHT);
|
||||
//GameScene
|
||||
}
|
||||
|
||||
|
|