diff --git a/.gitignore b/.gitignore index efecd5748..cbdd88943 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ *.apk *.smali +*.hprof + # Files for the Dalvik VM *.dex diff --git a/SPD-classes/src/main/java/com/watabou/noosa/ui/Component.java b/SPD-classes/src/main/java/com/watabou/noosa/ui/Component.java index 4b26b7685..8381fe109 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/ui/Component.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/ui/Component.java @@ -42,6 +42,8 @@ public class Component extends Group { return this; } + public final Component setX( float x ) { return setPos(x, y); } + public final Component setY( float y ) { return setPos(x, y); } public Component setSize( float width, float height ) { this.width = width; @@ -51,14 +53,13 @@ public class Component extends Group { return this; } + public final Component setHeight( float height ) { return setSize(width, height); } + public final Component setWidth( float width ) { return setSize(width, height); } + public Component setRect( float x, float y, float width, float height ) { this.x = x; this.y = y; - this.width = width; - this.height = height; - layout(); - - return this; + return setSize(width, height); } public boolean inside( float x, float y ) { @@ -106,4 +107,4 @@ public class Component extends Group { protected void layout() { } -} +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 77ec22b24..0d651c746 100644 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,8 @@ allprojects { appName = 'Magic Ling Pixel Dungeon' appPackageName = 'com.ansdomagiclingpixeldungeon.ling' - appVersionCode =901000 - appVersionName = '0.6.4.0-Beta1' + appVersionCode =901200 + appVersionName = '0.6.4.0-Beta3' appJavaCompatibility = JavaVersion.VERSION_11 diff --git a/core/src/main/assets/environment/tiles_ancient.png b/core/src/main/assets/environment/tiles_ancient.png index 42db7a6d8..8977b16b9 100644 Binary files a/core/src/main/assets/environment/tiles_ancient.png and b/core/src/main/assets/environment/tiles_ancient.png differ diff --git a/core/src/main/assets/interfaces/happymode.png b/core/src/main/assets/interfaces/happymode.png index fa985ca5d..5b9f98858 100644 Binary files a/core/src/main/assets/interfaces/happymode.png and b/core/src/main/assets/interfaces/happymode.png differ diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 41c43762a..278078c4c 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -6,6 +6,28 @@ actors.mobs.bosses.sakafishboss.notice=sakasaka……saka?腻……系…… actors.mobs.bosses.sakafishboss.attack=吧嗒吧嗒—呜呜……好怀念上面的风景和底栖生物 actors.mobs.bosses.sakafishboss.leap=萨卡班甲鱼正在蓄力泥头车冲撞!哦——创似——李——!!! actors.mobs.bosses.sakafishboss.king=泰山压顶!biu—— +actors.mobs.bosses.sakafishboss.interesting=让你瞧瞧远古顶级掠食者的姿态! +actors.mobs.bosses.sakafishboss.angry=可恶的人类!你们为什么要毁掉我们的家园?!可恶可恶可恶可恶,陪我的同胞一起下地狱吧! +actors.mobs.bosses.sakafishboss.defeated=呜呜呜……我……我……我……,仍然无法回到大海…… +actors.mobs.bosses.sakafishboss.dictcar_kill=%s被萨卡班创飞,离开了人间…… +actors.mobs.bosses.sakafishboss.deathgaze_kill=%s被萨卡班的死亡凝视吓死了…… +actors.mobs.bosses.sakafishboss.rankings_desc=成为了萨卡班甲鱼的食物…… + + +actors.mobs.bosses.dictfish.name=板足鲎 +actors.mobs.bosses.dictfish.desc=底栖顶级捕食者,他的巨鳌和巨颚可以碾碎你的铠甲。\n\n与_房角石_是共生互助,因此死后房角石会狂暴,获得的特殊攻击带有冲击,可以击退敌人造成大量伤害。 +actors.mobs.bosses.dictfish.notice=板足鲎:大哥! +actors.mobs.bosses.dictfish.death=大哥,接下来就交给你了! +actors.mobs.bosses.dictfish.angry=板足鲎:大哥!该死的人类!我要你们付出代价! +actors.mobs.bosses.dictfish.rankings_desc=成为了萨卡班甲鱼的食物…… + +actors.mobs.bosses.roomstone.name=房角石 +actors.mobs.bosses.roomstone.desc=远古顶级掠食者,他的喙和甲壳可以轻易刺穿你的身材。\n\n与_板足鲎_是共生互助,因此死后板足鲎会狂暴,获得35回合激素涌动和暂时无敌10回合,并且每次攻击必定造成易伤,离开水面后速度大幅度提升。 +actors.mobs.bosses.roomstone.notice=板足鲎:二弟! +actors.mobs.bosses.roomstone.allget=我们兄弟齐心!力断其金!为了我们的家园! +actors.mobs.bosses.roomstone.angry=房角石:二弟!该死的人类!我要把你们碾成肉酱! +actors.mobs.bosses.roomstone.leap=房角石:人类,用你的血来祭奠我们的家园吧! +actors.mobs.bosses.roomstone.rankings_desc=成为了萨卡班甲鱼的食物…… actors.mobs.npcs.nxhy.talk=交谈 actors.mobs.npcs.nxhy.buyback=回忆很爽快的退还了相应的商品。 @@ -161,7 +183,7 @@ actors.buffs.magicgirldebuff.magicgirlsaysoftdied.name=魔女的低语-软弱 actors.buffs.magicgirldebuff.magicgirlsaysoftdied.desc=软弱不是你的缺点,恐惧才是!\n\n本大层所有被护甲减免过的物理伤害增加25% actors.buffs.magicgirldebuff.magicgirlsaymoneymore.name=魔女的低语-贪婪 -actors.buffs.magicgirldebuff.magicgirlsaymoneymore.desc=贪婪的欲望是人类的本质\n\n本大层商店的价格除十字架和食物和治疗药水打1折,其他全部1.5倍价格。 +actors.buffs.magicgirldebuff.magicgirlsaymoneymore.desc=贪婪的欲望是人类的本质\n\n本大层商店的价格除十字架和食物和治疗药水涨价到2.5倍,其他全部打半折价格。 actors.buffs.magicgirldebuff.magicgirlsaytimelast.name=魔女的低语-流逝 actors.buffs.magicgirldebuff.magicgirlsaytimelast.desc=流逝的是时间,不变的是地牢的模样。\n\n本大层每隔一段时间英雄获得随机火焰,中毒,流血其中之一。 @@ -321,6 +343,25 @@ text.textchallenges.seed_custom_title = 种子 text.textchallenges.hint = text.textchallenges.delete_seed_input = 清除 + + +custom.testmode.mobplacer.elite_name0=]烈焰] +custom.testmode.mobplacer.elite_name1=}敌法} +custom.testmode.mobplacer.elite_name2=_天佑_ +custom.testmode.mobplacer.elite_name3=]巨型] +custom.testmode.mobplacer.elite_name4={成长{ +custom.testmode.mobplacer.elite_name5=]索敌] +custom.testmode.mobplacer.elite_name6=_鬼磷_ +custom.testmode.mobplacer.elite_name7=|苦痛| +custom.testmode.mobplacer.elite_name8={炼狱{ + +custom.testmode.mobplacer.elite_name9=失败体 +custom.testmode.mobplacer.elite_name10=爆炸体 +custom.testmode.mobplacer.elite_name11=完全体 +custom.testmode.mobplacer.elite_name12=危险体 +custom.testmode.mobplacer.elite_name13=烟雾体 +custom.testmode.mobplacer.elite_name14=酸液体 + actors.mobs.bloodbat$bloodbatrecharge.name=血影充能 actors.mobs.bloodbat$bloodbatrecharge.desc=小血影正在充能,等待下一次和主人并肩作战的时候!\n\n剩余充能时长:%s回合. diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 5ed08e9c8..ee9e8fc9e 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -2,6 +2,14 @@ items.weapon.melee.sdbsword.name=钻石大剑 items.weapon.melee.sdbsword.desc=钻石制成的奇特大剑,现在它已经给予了足够多的能量,它回到了巅峰时刻\n剑身残留着钻石宝箱王的魔力,因此对其他魔力有着莫名的亲和性。相比于其他武器,这把武器会随着等级的提升增加更多伤害。\n这把武器攻击速度极慢,但精准极高。\n该武器已经重回巅峰,可以发射剑气。(该武器尚未完成,切勿使用) +items.quest.sakafishsketon.name=萨卡班甲鱼骨 +items.quest.sakafishsketon.desc=这个可怜的生物因为常年在此,身躯已经残破不堪。它似乎只是想回到地面看一眼而已……,这件物品对于商人似乎有很高的吸引力。 +items.quest.sakafishsketon.ac_interlevel_tp=回到地牢 + +items.food.sakameat.name=萨卡班甲鱼里脊 +items.food.sakameat.desc=哦……好吧,看了这个远古生物还是能吃的。 +items.food.sakameat.oks=你吃了萨卡班甲鱼里脊,你感觉到了一股祝福的清流涌入了你的身体! + items.wands.wandofanmy.name=共生法杖 items.wands.wandofanmy.desc=这把法杖是由神秘的能量驱使的,它们会在能量充足的时候,使地牢的怪物臣服于你(Boss除外)。\n\n该法杖无法自动升级,无法丢弃,且在神秘能量消散时一同消散…… items.wands.wandofanmy.stats_desc=这根法杖能射出心灵控制波,\n没有任何伤害,但可以立刻控制一个怪物成为盟友。 @@ -416,6 +424,13 @@ items.weapon.melee.runicblade.desc=这把武器据说曾经是300年前贤者使 items.weapon.melee.locksword.name=归溯钥剑 items.weapon.melee.locksword.desc=来自神秘国度的一把失落神剑,形态像是巨大化的钥匙。据说这把剑能够通过战斗的积累而改变外貌,或许还能在一些特别的地方开启东西,不知道是否真实。该武器无法升级,但可以在战斗中渐渐变强。\n\n武器的战斗经验: items.weapon.melee.locksword.stats_desc=这把武器会在攻击时不断积累经验,到达一定阶段时会变化造型,并赋予或加强紊乱附魔的效果与增加固定伤害值。 +items.weapon.melee.locksword.ac_interlevel_tp=远古遗迹 +items.weapon.melee.locksword.go_interlevel=探索之外 +items.weapon.melee.locksword.go_desc=归溯钥剑上面似乎有几个符号,你可以选择其中一个。\n\n你现在选择了A符号,在你脑海中映射出了一个远古遗迹,真的要前往吗?\n\n你随时都可以出发,但倘若归溯钥剑还没有能量的话,在你到达之后,归溯钥剑会变得无用。 +items.weapon.melee.locksword.okay=前去探索 +items.weapon.melee.locksword.cancel=还是算了 + + items.weapon.melee.boomsword.name=炸弹匕首 items.weapon.melee.boomsword.desc=这种神奇的魔法匕首被将炸弹结合...\n\n我有一把匕首,我有一颗炸弹,啊~\n_"炸弹匕首"_ @@ -2170,7 +2185,7 @@ items.weapon.weapon.identify=你对手中的武器已经足够熟悉并将其完 items.weapon.weapon.too_heavy=因为你的力量不足,该武器会降低你的攻速和精准,并让你无法偷袭。 items.weapon.weapon.excess_str=你的额外力量让你在使用这件武器时最多能够造成_%d点额外伤害_。 items.weapon.weapon.incompatible=不同属性的魔法相冲突,消除了武器上的附魔! -items.weapon.weapon.cursed_worn=由于这件武器被诅咒,你无f法将其放下。 +items.weapon.weapon.cursed_worn=由于这件武器被诅咒,你无法将其放下。 items.weapon.weapon.cursed=你能感觉到这件武器里潜伏着一股充满恶意的魔力。 items.weapon.weapon.not_cursed=这件武器没有被诅咒。 items.weapon.weapon.faster=这件武器强化了_攻速_。 diff --git a/core/src/main/assets/messages/scenes/scenes.properties b/core/src/main/assets/messages/scenes/scenes.properties index f482e6368..73a137e42 100644 --- a/core/src/main/assets/messages/scenes/scenes.properties +++ b/core/src/main/assets/messages/scenes/scenes.properties @@ -17,6 +17,8 @@ scenes.heroselectscene$4$1.title0=挑战模式 windows.wndchallenges.title0=挑战-Page1 windows.wndchallenges.title9=挑战-Page2 +scenes.gamescene.ancity=你现在的当前位置:远古遗迹-阴暗水潭 +scenes.gamescene.ancityboss=你现在的当前位置:远古遗迹-阴暗水潭 scenes.gamescene.snowcynon=你现在的当前位置:雪凛峡谷 scenes.gamescene.descend=你降入了地牢的第%d层。 scenes.titlescene.spawnerror=楼层生成错误!!! diff --git a/core/src/main/assets/messages/ui/ui.properties b/core/src/main/assets/messages/ui/ui.properties index 4fd64d8ca..56fed8421 100644 --- a/core/src/main/assets/messages/ui/ui.properties +++ b/core/src/main/assets/messages/ui/ui.properties @@ -550,4 +550,6 @@ ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x80=1.修复灯火值不扣减的错 ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x81=1.优化灯火体验\n其他错误修复。 +ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x82=1.修复商店抢劫的一些错误\n2.修复部分崩溃错误\n3.修复Beta2古神无限循环的错误 + //ui.changelist.mlpd.vm0_5_x_changes.xxx// \ No newline at end of file diff --git a/core/src/main/assets/messages/windows/windows.properties b/core/src/main/assets/messages/windows/windows.properties index 9feb11e95..cc5922f7f 100644 --- a/core/src/main/assets/messages/windows/windows.properties +++ b/core/src/main/assets/messages/windows/windows.properties @@ -8,7 +8,7 @@ windows.wndkingshop.nomoney=看起来你并不是很有钱……,我这人不给 windows.wndkeybindings.update=检查更新 scenes.gamenewsscene.title=正在检查更新 -scenes.gamenewsscene.update=请稍后,我们正在向服务器请求你的版本数据。\n\n若长时间未检查到版本,你可在倒计时结束后通过下方按钮继续游玩该版本 +scenes.gamenewsscene.update=请稍后,我们正在向服务器请求你的版本数据。若长时间未检查到版本,你可在倒计时结束后通过下方按钮继续游玩该版本 scenes.gamenewsscene.continue=继续游玩 @@ -55,6 +55,8 @@ windows.wndstory.good=灯火光彩夺目,提灯中的信仰诞生出一种纯 windows.wndstory.start=灯火冒险正式开始!你获得了一次免费的增益Roll! windows.wndstory.letxz=灯火冒险欢迎您,已赠送你免费的增益Roll! +windows.wndstory.letsplay=深度调查模式已经开启,在该模式下挑战徽章不可获得,祝你游戏愉快! + windows.wndhero$statstab.lanterfire=灯火 windows.wndhero$statstab.icehp=寒冷 @@ -482,8 +484,8 @@ windows.wndwandmaker.ember=哦,我注意到你已经获得了余烬!希望 windows.wndwandmaker.berry=哦,我注意到你已经获得了莓果!希望那株植物没有对你造成太多困扰。就像我承诺的,你可以选择我制作的一把高品质法杖。 windows.wndwandmaker.farewell=祝你在试炼中好运,%s! - windows.wndstory.bossrushstart=当你再一次回到了地牢时,你发觉气氛变得有些不寻常。\n\n入口似乎产生了异变,而衪和奈亚正在焦急等待着谁。 +#windows.wndstory.bossrushstart=依靠钥匙剑的力量,我们打开了一道传送门。一道白光过后,我们来到了一个陌生的地方。\n\n这里是一个长年没有光照的阴暗水潭,周围似乎没有生命的气息,但是这里却有着一股强大的力量,究竟是什么东西在这里栖息? windows.wndstory.nomobs=在衪的要求下,你再次进入地牢。映入眼帘的并不是熟悉的森林,而是一片冰天雪地。\n\n这里感受不到任何生命的气息,但是不远处堆放着的补给品,证明不久前有人来过这里。 windows.wndstory.calaboss=冰雪止步于再次出现的林木。\n\n熟悉的感觉再次涌上心头,你明白这茂密的树木代表着什么。不远处散发着醉人香气的鲜红果实也证明了你的猜测。 windows.wndstory.sewsboss=一个黑乎乎的家伙出现在你的面前,如果没有猜错,这应该是存在于其他地牢的奇特生物——粘咕。\n\n粘咕似乎比以前更加危险,请谨慎行事。 @@ -500,12 +502,15 @@ windows.wndstory.zotboss=万千地牢的邪恶力量汇聚一起,造就了这 windows.wndstory.dmzero=你所经历的一切不过是地牢曾经记忆的投影。打乱的时间被揉成一团,重新展开成这条弯弯曲曲的线。这只打乱时间的手,出现在你的面前。 windows.wndstory.end=时间在此停滞。\n\n在这个极度扭曲的空间中,DM-ZERO,被未知生物侵占后的极具威胁的机器,伫立在你的前方。\n\n那是一座铁城,镇压着无法流淌的时间。 -windows.wndgameinprogress.dlc=娱乐 +windows.wndgameinprogress.dlc=调查 -windows.wnddlc.title=娱乐模式 +windows.wnddlc.title=深度调查 conducts.null=什么都不选择 conducts.bossrush=首领对决 -conducts.bossrush_desc=被你击败过多次的首领们熟识了英雄的技能,并掌握了一定的对策。它们盘踞在地牢中,等待复仇的时机。\n-你不知道这次又会有怎样的危机需要应对。\n-但你感觉到这次的冒险绝对与其他时期有所不同。\n-娱乐模式仅可选择一种模式游玩。 +conducts.bossrush_desc=被你击败过多次的首领们熟识了英雄的技能,并掌握了一定的对策。它们盘踞在地牢中,等待复仇的时机。\n-你不知道这次又会有怎样的危机需要应对。\n-但你感觉到这次的冒险绝对与其他时期有所不同。\n\n-_深度调查模式仅可选择一种模式游玩。且无法计入多挑徽章中。_ + +conducts.moneyletgo=黄金时代 +conducts.moneyletgo_desc=地牢终于赶上了淘金热的时代,在这个金钱的时代,地牢中几乎所有东西都被明码标价。商人们因此赚的盆满钵满,所以他们打算商店打5折。\n然而,金钱的背后是利益的驱使,她已知晓地牢的现状,现在怪物都会可能额外掉落金币,随着地牢的深入,该项能力越来越弱。\n\n-_深度调查模式仅可选择一种模式游玩。且无法计入多挑徽章中。_ windows.wnddlcx.title=难度选择-Beta difficulty.null=默认难度(一般) diff --git a/core/src/main/assets/sprites/boss/IceSlowGirl.png b/core/src/main/assets/sprites/boss/IceSlowGirl.png new file mode 100644 index 000000000..a857038c8 Binary files /dev/null and b/core/src/main/assets/sprites/boss/IceSlowGirl.png differ diff --git a/core/src/main/assets/sprites/boss/RoomStone.png b/core/src/main/assets/sprites/boss/RoomStone.png index dcba17722..106f6abc6 100644 Binary files a/core/src/main/assets/sprites/boss/RoomStone.png and b/core/src/main/assets/sprites/boss/RoomStone.png differ diff --git a/core/src/main/assets/sprites/boss/SeaVastGirl.png b/core/src/main/assets/sprites/boss/SeaVastGirl.png index 00991bca0..c53c9e8fa 100644 Binary files a/core/src/main/assets/sprites/boss/SeaVastGirl.png and b/core/src/main/assets/sprites/boss/SeaVastGirl.png differ diff --git a/core/src/main/assets/sprites/items/items.png b/core/src/main/assets/sprites/items/items.png index 97c6ee61b..acd95710f 100644 Binary files a/core/src/main/assets/sprites/items/items.png and b/core/src/main/assets/sprites/items/items.png differ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java index 96b9b47bf..f9e43c431 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java @@ -319,6 +319,8 @@ public class Assets { public static final String ROOMSTONE = "sprites/boss/RoomStone.png"; public static final String VSGR = "sprites/boss/SeaVastGirl.png"; + public static final String SXGR = "sprites/boss/IceSlowGirl.png"; + public static final String SKFS = "sprites/boss/SakaFishBoss.png"; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/BGMPlayer.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/BGMPlayer.java index 3bf86a1cf..0dd3cc2ac 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/BGMPlayer.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/BGMPlayer.java @@ -34,7 +34,7 @@ public class BGMPlayer { if (d == -1) { playBGM(Assets.SNOWCYON, true); }else if (d == 0||d==27) { - playBGM(Assets.SKBJY, true); + playBGM(Assets.SNOWCYON, true); } else if (d > 0 && d <= 5) { playBGM(Assets.BGM_1, true); } else if (d > 5 && d <= 10) { @@ -163,6 +163,8 @@ public class BGMPlayer { playBGM(Assets.BGM_BOSSE, true); } else if (Dungeon.bossLevel() && t == -15) { playBGM(Assets.BGM_FRBOSS, true); + } else if (Dungeon.bossLevel() && t == -31) { + playBGM(Assets.SKBJY, true); } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java index 466387fe5..fd86d88e8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java @@ -765,7 +765,7 @@ public class Badges { private static void validateAMZ() { if (global.contains( Badge.KILL_APPLE ) &&global.contains( Badge.KILL_DM720 ) && - global.contains( Badge.KILL_MG) && global.contains( Badge.FIREGIRL) && global.contains( Badge.DRAWF_HEAD)) { + global.contains( Badge.KILL_MG) && global.contains( Badge.FIREGIRL) && global.contains( Badge.DRAWF_HEAD) && global.contains( Badge.SAKA_DIED)) { Badge badge = Badge.SPICEALBOSS; displayBadge( badge ); @@ -945,6 +945,14 @@ public class Badges { } } + public void Test(){ + + } + + public int Tests(){ + return 4; + } + public static void validateVictory() { Badge badge = Badge.VICTORY; @@ -1030,6 +1038,15 @@ public class Badges { validateAMZ(); } + public static void KILLSAKA() { + displayBadge( Badge.SAKA_DIED); + validateAMZ(); + } + + public static void REHOMESKY() { + displayBadge( Badge.RESET_DAY ); + } + public static void STORM() { displayBadge( Badge.STORM); } @@ -1091,22 +1108,22 @@ public class Badges { public static void validateChampion( int challenges ) { if (challenges == 0) return; Badge badge = null; - if (challenges >= 1 && !(Dungeon.isChallenged(PRO))) { + if (challenges >= 1 && !(Dungeon.isChallenged(PRO)) || !Statistics.happyMode) { badge = Badge.CHAMPION_1X; } - if (challenges >= 3 && !(Dungeon.isChallenged(PRO))){ + if (challenges >= 3 && !(Dungeon.isChallenged(PRO))|| !Statistics.happyMode){ addGlobal(badge); badge = Badge.CHAMPION_2X; } - if (challenges >= 6 && !(Dungeon.isChallenged(PRO))){ + if (challenges >= 6 && !(Dungeon.isChallenged(PRO))|| !Statistics.happyMode){ addGlobal(badge); badge = Badge.CHAMPION_3X; } - if (challenges >= 8 && !(Dungeon.isChallenged(PRO))){ + if (challenges >= 8 && !(Dungeon.isChallenged(PRO))||!Statistics.happyMode){ addGlobal(badge); badge = Badge.CHAMPION_4X; } - if (challenges >= 10 && !(Dungeon.isChallenged(PRO))){ + if (challenges >= 10 && !(Dungeon.isChallenged(PRO))||!Statistics.happyMode){ addGlobal(badge); badge = Badge.CHAMPION_5X; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Conducts.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Conducts.java index 3ef248416..c70d933e4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Conducts.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Conducts.java @@ -10,7 +10,8 @@ import java.util.Arrays; public class Conducts { public enum Conduct { NULL, - BOSSRUSH(1.2f); + BOSSRUSH(1.2f), + MONEYLETGO(1.5f); public float scoreMod; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index 5705513fe..64f288cfe 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -58,6 +58,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagicTorch; import com.shatteredpixel.shatteredpixeldungeon.journal.Notes; +import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel; +import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.DeadEndLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.LinkLevel; @@ -126,16 +128,36 @@ public class Dungeon { Dungeon.level = null; Actor.clear(); - depth = -20; + depth = -30; if (depth > Statistics.realdeepestFloor) { Statistics.realdeepestFloor = depth;} Level level; - level = new ShopBossLevel(); + level = new AncientMysteryCityLevel(); level.create(); + Statistics.qualifiedForNoKilling = !bossLevel(); + return level; + } + + //远古领袖 + public static Level AncityBossWaterLevel(){ + + + Dungeon.level = null; + Actor.clear(); + + depth = -31; + + if (depth > Statistics.realdeepestFloor) { + Statistics.realdeepestFloor = depth;} + + Level level; + level = new AncientMysteryCityBossLevel(); + + level.create(); Statistics.qualifiedForNoKilling = !bossLevel(); return level; @@ -491,7 +513,7 @@ public class Dungeon { } public static boolean bossLevel( int depth ) { - return depth == 5 || depth == 10 || depth == 15 || depth == 20 || depth == 25|| depth == -15; + return depth == 5 || depth == 10 || depth == 15 || depth == 20 || depth == 25|| depth == -15| depth == -31; } public static void switchLevel( final Level level, int pos ) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java index 6ce02ebce..dbf249387 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java @@ -29,6 +29,10 @@ public class Statistics { //统计分数 public static int progressScore; + public static boolean happyMode = false; + + //萨卡班甲鱼二阶段 + public static int sakaBackStage; public static int readBooks; public static int treasureScore; public static SparseArray floorsExplored = new SparseArray<>(); @@ -118,13 +122,16 @@ public class Statistics { public static boolean TryUsedAnmy= false; public static void reset() { - - boss_enhance = 0; ChaicBlood = 0; readBooks = 0; HealingIsDied = 0; + happyMode = false; + + //萨卡班甲鱼二阶段 + sakaBackStage = 0; + goldCollected = 0; deepestFloor = -1; enemiesSlain = 0; @@ -159,8 +166,10 @@ public class Statistics { lanterfireactive = false; bugsyncfixed = false; + crivusfruitslevel2 = false; TPDoorDieds = false; + TryUsedAnmy = false; second_elapsed = 0f; @@ -184,6 +193,7 @@ public class Statistics { } private static final String GOLD = "score"; + private static final String HAPPY = "happy"; private static final String DEEPEST = "maxDepth"; private static final String SLAIN = "enemiesSlain"; private static final String FOOD = "foodEaten"; @@ -265,6 +275,8 @@ public class Statistics { private static final String READBOOKS = "readbooks"; + private static final String SAKATWO = "sakatwo"; + public static void storeInBundle( Bundle bundle ) { @@ -282,6 +294,9 @@ public class Statistics { bundle.put( READBOOKS, readBooks); bundle.put( EXPL_SCORE, exploreScore ); + + bundle.put( HAPPY, happyMode ); + bundle.put( BOSS_SCORES, bossScores ); bundle.put( TOT_BOSS, totalBossScore ); bundle.put( QUEST_SCORES,questScores ); @@ -343,6 +358,8 @@ public class Statistics { bundle.put( ENBR, endingbald ); + bundle.put( SAKATWO, sakaBackStage ); + //SPD bundle.put("real_time_passed", second_elapsed); bundle.put("real_seconds_passed", real_seconds); @@ -358,6 +375,8 @@ public class Statistics { readBooks = bundle.getInt( READBOOKS ); + sakaBackStage = bundle.getInt( SAKATWO ); + //分数 progressScore = bundle.getInt( PROG_SCORE ); heldItemValue = bundle.getInt( ITEM_VAL ); @@ -382,7 +401,7 @@ public class Statistics { highestAscent = bundle.getInt( HIGHEST ); gameWon = bundle.getBoolean( WON ); ascended = bundle.getBoolean( ASCENDED ); - + happyMode = bundle.getBoolean(HAPPY); dimandchestmazeCollected = bundle.getInt(DDK); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java index 496be1df9..1273b04c0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java @@ -33,7 +33,9 @@ import com.watabou.utils.SparseArray; import java.util.HashSet; public abstract class Actor implements Bundlable { - + public static synchronized Class getCurrentActorClass(){ + return current == null ? null:current.getClass(); + } public static final float TICK = 1f; protected Bundle upgrades; protected Bundle crafted; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Boss.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Boss.java index 423c12838..6f8d76e38 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Boss.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Boss.java @@ -8,7 +8,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim; import com.watabou.utils.Random; public class Boss extends Mob { - protected static float baseMin; //最小伤害 protected static float baseMax; //最大伤害 protected static float baseAcc; //命中率 diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Cost.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Cost.java index 89e30f06c..498391739 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Cost.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Cost.java @@ -6,8 +6,6 @@ import com.watabou.utils.Bundle; public class Cost extends Buff { - - { type = buffType.POSITIVE; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java index 47c22882a..a2c27d679 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java @@ -171,7 +171,7 @@ public class Belongings implements Iterable { if (bundle.contains( ARMOR )){ Armor armor = ((Armor)bundle.get( ARMOR )); if (armor instanceof ClassArmor){ - info.armorTier = 6; + info.armorTier = 7; } else { info.armorTier = armor.tier; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index e1ab2f940..39eb82d76 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -27,6 +27,7 @@ import static com.shatteredpixel.shatteredpixeldungeon.Challenges.PRO; import static com.shatteredpixel.shatteredpixeldungeon.Difficulty.DifficultyConduct.HARD; import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero; import static com.shatteredpixel.shatteredpixeldungeon.SPDSettings.HelpSettings; +import static com.shatteredpixel.shatteredpixeldungeon.Statistics.happyMode; import static com.shatteredpixel.shatteredpixeldungeon.Statistics.lanterfireactive; import static com.shatteredpixel.shatteredpixeldungeon.Statistics.tipsgodungeon; import static com.shatteredpixel.shatteredpixeldungeon.levels.Level.set; @@ -145,6 +146,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMight; import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfDivineInspiration; import com.shatteredpixel.shatteredpixeldungeon.items.quest.MIME; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.SakaFishSketon; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfForce; @@ -955,7 +957,7 @@ public class Hero extends Char { } ///测试坐标用 - GLog.w(String.valueOf(hero.pos)); +// GLog.w(String.valueOf(hero.pos)); //携带该物品时,玩家血量低于一半后自动隐身一段回合。 //actMove实现 @@ -971,7 +973,13 @@ public class Hero extends Char { if ((Dungeon.challenges & ch) != 0) chCount++; } - //icehp++; + + // 深度调查 + if ((Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) || Dungeon.isDLC(Conducts.Conduct.MONEYLETGO)) && !happyMode) { + happyMode = true; + GLog.n(Messages.get(WndStory.class, "letsplay")); + } + if(chCount >= 3 && !lanterfireactive && !Dungeon.isChallenged(PRO) || Dungeon.isChallenged(DHXD) && !lanterfireactive){ //TODO 灯火前行 @@ -1312,6 +1320,10 @@ public class Hero extends Char { if (Dungeon.depth == 0) { + if (belongings.getItem(SakaFishSketon.class) != null) { + Badges.REHOMESKY(); + } + if (belongings.getItem(Amulet.class) == null) { Game.runOnRenderThread(new Callback() { @Override @@ -1960,7 +1972,6 @@ public class Hero extends Char { for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])){ if (mob instanceof BlackSoul) { Buff.affect( mob, Dread.class ); - Buff.prolong(mob, AnkhInvulnerability.class, 200f); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java index 9a883764b..ca5ca051e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java @@ -65,6 +65,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.bags.KingBag; import com.shatteredpixel.shatteredpixeldungeon.items.bags.VelvetPouch; import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.BrokenBooks; import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.DimandBook; +import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.IceCityBooks; import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.TestBooks; import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.YellowSunBooks; import com.shatteredpixel.shatteredpixeldungeon.items.food.Food; @@ -205,7 +206,8 @@ public enum HeroClass { new KingBag().quantity(1).identify().collect(); new PotionOfLiquidFlameX().quantity(100).identify().collect(); new YellowSunBooks().quantity(1).identify().collect(); - new BrokenBooks().quantity(44).identify().collect(); + new BrokenBooks().quantity(12).identify().collect(); + new IceCityBooks().quantity(12).identify().collect(); new ScrollOfFlameCursed().quantity(44).identify().collect(); new LeatherArmor().quantity(1).identify().collect(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java index ff4bce87d..993edca9d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java @@ -102,9 +102,8 @@ public class Bestiary { DM100.class, BlackHost.class)); case 2: return new ArrayList<>(Arrays.asList( - Elemental.random(), - Monk.class,FireGhost.class, - Warlock.class,Random.NormalFloat(1,6)>=3 ? BruteBot.class : Warlock.class)); + Monk.class, + Warlock.class)); case 3: return new ArrayList<>(Arrays.asList( Elemental.random(), @@ -135,19 +134,15 @@ public class Bestiary { case 2: return new ArrayList<>(Arrays.asList( Succubus.class, - Eye.class,ShieldHuntsman.class,Scorpio.class,Monk.class, + Scorpio.class,Monk.class, Golem.class)); case 3: return new ArrayList<>(Arrays.asList( - Succubus.class, Succubus.class, Succubus.class, - Succubus.class, Succubus.class, - Eye.class,ShieldHuntsman.class,Albino.class,Monk.class, + Fire_Scorpio.class,Albino.class,Monk.class, Golem.class)); case 4: return new ArrayList<>(Arrays.asList( - Succubus.class, - Succubus.class, - Eye.class,ShieldHuntsman.class, + ShieldHuntsman.class, Monk.class, Golem.class)); case 5: diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java index a0cddb8ff..f2738bec0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java @@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.BGMPlayer; import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.Challenges; +import com.shatteredpixel.shatteredpixeldungeon.Conducts; import com.shatteredpixel.shatteredpixeldungeon.Difficulty; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; @@ -869,6 +870,13 @@ public abstract class Mob extends Char { EXP /= 2; } + //黄金时代所有怪物都可能会掉落金币 + if(Dungeon.isDLC(Conducts.Conduct.MONEYLETGO) && Dungeon.hero.lvl <= maxLvl && alignment == Alignment.ENEMY){ + if(Random.Int(100) == 50-Dungeon.depth/5){ + Dungeon.level.drop( ( new Gold().random() ), pos ).sprite.drop(); + } + } + if (alignment == Alignment.ENEMY){ rollToDropLoot(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/SlimeKing.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/SlimeKing.java index 9a1202ef7..b6ce006fb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/SlimeKing.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/SlimeKing.java @@ -61,8 +61,7 @@ public class SlimeKing extends Mob { private boolean PartCold = false; - private static final String partcold = "partcold"; - private static final String chainsused = "chainsused"; + @Override @@ -94,6 +93,10 @@ public class SlimeKing extends Mob { return super.defenseProc(enemy, damage); } + + private static final String partcold = "partcold"; + private static final String chainsused = "chainsused"; + @Override public void storeInBundle(Bundle bundle) { super.storeInBundle(bundle); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java index 41c94336a..228c21f5e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java @@ -1,33 +1,6 @@ -/* - * Pixel Dungeon - * Copyright (C) 2012-2015 Oleg Dolya - * - * Shattered Pixel Dungeon - * Copyright (C) 2014-2022 Evan Debenham - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; -import static com.shatteredpixel.shatteredpixeldungeon.Challenges.AQUAPHOBIA; -import static com.shatteredpixel.shatteredpixeldungeon.Challenges.EXSG; -import static com.shatteredpixel.shatteredpixeldungeon.Challenges.RLPT; -import static com.shatteredpixel.shatteredpixeldungeon.Challenges.SBSG; - import com.shatteredpixel.shatteredpixeldungeon.Assets; -import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.Challenges; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; @@ -37,34 +10,43 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Dread; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep; +import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; +import com.shatteredpixel.shatteredpixeldungeon.effects.TargetedCell; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.PurpleParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +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.LarvaSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.YogSprite; +import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.Game; import com.watabou.noosa.audio.Music; import com.watabou.utils.Bundle; import com.watabou.utils.Callback; +import com.watabou.utils.GameMath; import com.watabou.utils.PathFinder; import com.watabou.utils.Random; import com.watabou.utils.Reflection; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; public class YogDzewa extends Mob { @@ -108,21 +90,22 @@ public class YogDzewa extends Mob { private ArrayList fistSummons = new ArrayList<>(); private ArrayList challengeSummons = new ArrayList<>(); { - Random.pushGenerator(Dungeon.seedCurDepth()); - fistSummons.add(Random.Int(2) == 0 ? YogFist.BurningFist.class : YogFist.SoiledFist.class); - fistSummons.add(Random.Int(2) == 0 ? YogFist.RottingFist.class : YogFist.RustedFist.class); - fistSummons.add(Random.Int(2) == 0 ? YogFist.BrightFist.class : YogFist.DarkFist.class); - Random.shuffle(fistSummons); - //randomly place challenge summons so that two fists of a pair can never spawn together - if (Random.Int(2) == 0){ - challengeSummons.add(getPairedFist(fistSummons.get(1))); - challengeSummons.add(getPairedFist(fistSummons.get(2))); - challengeSummons.add(getPairedFist(fistSummons.get(0))); - } else { - challengeSummons.add(getPairedFist(fistSummons.get(2))); - challengeSummons.add(getPairedFist(fistSummons.get(0))); - challengeSummons.add(getPairedFist(fistSummons.get(1))); - } + //offset seed slightly to avoid output patterns + Random.pushGenerator(Dungeon.seedCurDepth()+1); + fistSummons.add(Random.Int(2) == 0 ? YogFist.BurningFist.class : YogFist.SoiledFist.class); + fistSummons.add(Random.Int(2) == 0 ? YogFist.RottingFist.class : YogFist.RustedFist.class); + fistSummons.add(Random.Int(2) == 0 ? YogFist.BrightFist.class : YogFist.DarkFist.class); + Random.shuffle(fistSummons); + //randomly place challenge summons so that two fists of a pair can never spawn together + if (Random.Int(2) == 0){ + challengeSummons.add(getPairedFist(fistSummons.get(1))); + challengeSummons.add(getPairedFist(fistSummons.get(2))); + challengeSummons.add(getPairedFist(fistSummons.get(0))); + } else { + challengeSummons.add(getPairedFist(fistSummons.get(2))); + challengeSummons.add(getPairedFist(fistSummons.get(0))); + challengeSummons.add(getPairedFist(fistSummons.get(1))); + } Random.popGenerator(); } @@ -132,15 +115,14 @@ public class YogDzewa extends Mob { for (int i = 0; i < 6; i++){ if (i >= 4){ regularSummons.add(YogRipper.class); - } - if (i >= Statistics.spawnersAlive){ + } else if (i >= Statistics.spawnersAlive){ regularSummons.add(Larva.class); } else { regularSummons.add( i % 2 == 0 ? YogEye.class : YogScorpio.class); } } } else { - for (int i = 0; i < 6; i++){ + for (int i = 0; i < 4; i++){ if (i >= Statistics.spawnersAlive){ regularSummons.add(Larva.class); } else { @@ -153,6 +135,11 @@ public class YogDzewa extends Mob { private ArrayList targetedCells = new ArrayList<>(); + @Override + public int attackSkill(Char target) { + return INFINITE_ACCURACY; + } + @Override protected boolean act() { //char logic @@ -163,6 +150,9 @@ public class YogDzewa extends Mob { throwItems(); + sprite.hideAlert(); + sprite.hideLost(); + //mob logic enemy = chooseEnemy(); @@ -182,6 +172,7 @@ public class YogDzewa extends Mob { yell(Messages.get(this, "hope")); summonCooldown = -15; //summon a burst of minions! phase = 5; + BossHealthBar.bleed(true); } if (phase == 0){ @@ -189,7 +180,100 @@ public class YogDzewa extends Mob { return true; } else { + boolean terrainAffected = false; + HashSet affected = new HashSet<>(); + //delay fire on a rooted hero + if (!Dungeon.hero.rooted) { + for (int i : targetedCells) { + Ballistica b = new Ballistica(pos, i, Ballistica.WONT_STOP); + //shoot beams + sprite.parent.add(new Beam.DeathRay(sprite.center(), DungeonTilemap.raisedTileCenterToWorld(b.collisionPos))); + for (int p : b.path) { + Char ch = Actor.findChar(p); + if (ch != null && (ch.alignment != alignment || ch instanceof Bee)) { + affected.add(ch); + } + if (Dungeon.level.flamable[p]) { + Dungeon.level.destroy(p); + GameScene.updateMap(p); + terrainAffected = true; + } + } + } + if (terrainAffected) { + Dungeon.observe(); + } + Invisibility.dispel(this); + for (Char ch : affected) { + if (ch == Dungeon.hero) { + Statistics.bossScores[4] -= 500; + } + + if (hit( this, ch, true )) { + if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)) { + ch.damage(Random.NormalIntRange(30, 50), new Eye.DeathGaze()); + } else { + ch.damage(Random.NormalIntRange(20, 30), new Eye.DeathGaze()); + } + if (Dungeon.level.heroFOV[pos]) { + ch.sprite.flash(); + CellEmitter.center(pos).burst(PurpleParticle.BURST, Random.IntRange(1, 2)); + } + } else { + ch.sprite.showStatus( CharSprite.NEUTRAL, ch.defenseVerb() ); + } + } + targetedCells.clear(); + } + + if (abilityCooldown <= 0){ + + int beams = 1 + (HT - HP)/400; + HashSet affectedCells = new HashSet<>(); + for (int i = 0; i < beams; i++){ + + int targetPos = Dungeon.hero.pos; + if (i != 0){ + do { + targetPos = Dungeon.hero.pos + PathFinder.NEIGHBOURS8[Random.Int(8)]; + } while (Dungeon.level.trueDistance(pos, Dungeon.hero.pos) + > Dungeon.level.trueDistance(pos, targetPos)); + } + targetedCells.add(targetPos); + Ballistica b = new Ballistica(pos, targetPos, Ballistica.WONT_STOP); + affectedCells.addAll(b.path); + } + + //remove one beam if multiple shots would cause every cell next to the hero to be targeted + boolean allAdjTargeted = true; + for (int i : PathFinder.NEIGHBOURS9){ + if (!affectedCells.contains(Dungeon.hero.pos + i) && Dungeon.level.passable[Dungeon.hero.pos + i]){ + allAdjTargeted = false; + break; + } + } + if (allAdjTargeted){ + targetedCells.remove(targetedCells.size()-1); + } + for (int i : targetedCells){ + Ballistica b = new Ballistica(pos, i, Ballistica.WONT_STOP); + for (int p : b.path){ + sprite.parent.add(new TargetedCell(p, 0xFF0000)); + affectedCells.add(p); + } + } + + //don't want to overly punish players with slow move or attack speed + spend(GameMath.gate(TICK, Dungeon.hero.cooldown(), 3*TICK)); + Dungeon.hero.interrupt(); + + abilityCooldown += Random.NormalFloat(MIN_ABILITY_CD, MAX_ABILITY_CD); + abilityCooldown -= (phase - 1); + + } else { + spend(TICK); + } while (summonCooldown <= 0){ @@ -206,11 +290,26 @@ public class YogDzewa extends Mob { } } + //if no other valid spawn spots exist, try to kill an adjacent sheep to spawn anyway + if (spawnPos == -1){ + for (int i : PathFinder.NEIGHBOURS8){ + if (Actor.findChar(pos+i) instanceof Sheep){ + if (spawnPos == -1 || Dungeon.level.trueDistance(Dungeon.hero.pos, spawnPos) > Dungeon.level.trueDistance(Dungeon.hero.pos, pos+i)){ + spawnPos = pos + i; + } + } + } + if (spawnPos != -1){ + Actor.findChar(spawnPos).die(null); + } + } + if (spawnPos != -1) { summon.pos = spawnPos; GameScene.add( summon ); Actor.addDelayed( new Pushing( summon, pos, summon.pos ), -1 ); summon.beckon(Dungeon.hero.pos); + Dungeon.level.occupyCell(summon); summonCooldown += Random.NormalFloat(MIN_SUMMON_CD, MAX_SUMMON_CD); summonCooldown -= (phase - 1); @@ -245,7 +344,7 @@ public class YogDzewa extends Mob { @Override public boolean isInvulnerable(Class effect) { - return phase == 0 || findFist() != null; + return phase == 0 || findFist() != null || super.isInvulnerable(effect); } @Override @@ -292,7 +391,10 @@ public class YogDzewa extends Mob { } LockedFloor lock = Dungeon.hero.buff(LockedFloor.class); - if (lock != null) lock.addTime(dmgTaken); + if (lock != null){ + if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)) lock.addTime(dmgTaken/3f); + else lock.addTime(dmgTaken/2f); + } } @@ -309,18 +411,23 @@ public class YogDzewa extends Mob { int targetPos = Dungeon.level.exit + Dungeon.level.width(); if (!Dungeon.isChallenged(Challenges.STRONGER_BOSSES) - && Actor.findChar(targetPos) == null){ + && (Actor.findChar(targetPos) == null || Actor.findChar(targetPos) instanceof Sheep)){ fist.pos = targetPos; - } else if (Actor.findChar(targetPos-1) == null){ + } else if (Actor.findChar(targetPos-1) == null || Actor.findChar(targetPos-1) instanceof Sheep){ fist.pos = targetPos-1; - } else if (Actor.findChar(targetPos+1) == null){ + } else if (Actor.findChar(targetPos+1) == null || Actor.findChar(targetPos+1) instanceof Sheep){ fist.pos = targetPos+1; - } else if (Actor.findChar(targetPos) == null){ + } else if (Actor.findChar(targetPos) == null || Actor.findChar(targetPos) instanceof Sheep){ fist.pos = targetPos; } + if (Actor.findChar(fist.pos) instanceof Sheep){ + Actor.findChar(fist.pos).die(null); + } + GameScene.add(fist, 4); Actor.addDelayed( new Pushing( fist, Dungeon.level.exit, fist.pos ), -1 ); + Dungeon.level.occupyCell(fist); } public void updateVisibility( Level level ){ @@ -355,7 +462,7 @@ public class YogDzewa extends Mob { public void aggro(Char ch) { for (Mob mob : (Iterable)Dungeon.level.mobs.clone()) { if (Dungeon.level.distance(pos, mob.pos) <= 4 && - (mob instanceof Larva || mob instanceof RipperDemon)) { + (mob instanceof Larva || mob instanceof YogRipper || mob instanceof YogEye || mob instanceof YogScorpio)) { mob.aggro(ch); } } @@ -366,35 +473,20 @@ public class YogDzewa extends Mob { public void die( Object cause ) { for (Mob mob : (Iterable)Dungeon.level.mobs.clone()) { - if (mob instanceof Larva || mob instanceof RipperDemon) { + if (mob instanceof Larva || mob instanceof YogRipper || mob instanceof YogEye || mob instanceof YogScorpio) { mob.die( cause ); } } - if(Dungeon.isChallenged(RLPT)){ - Badges.GOODRLPT(); - } - - if(Dungeon.isChallenged(AQUAPHOBIA)){ - Badges.CLEARWATER(); - } - - if(Dungeon.isChallenged(SBSG)){ - Badges.BIGX(); - } - - if(Dungeon.isChallenged(EXSG)){ - Badges.EXSG(); - } - - - updateVisibility(Dungeon.level); GameScene.bossSlain(); + + Statistics.bossScores[4] += 5000 + 1250*Statistics.spawnersAlive; + Dungeon.level.unseal(); super.die( cause ); - Statistics.bossScores[4] += 10000 + 1250*Statistics.spawnersAlive; + yell( Messages.get(this, "defeated") ); } @@ -478,18 +570,18 @@ public class YogDzewa extends Mob { public void restoreFromBundle(Bundle bundle) { super.restoreFromBundle(bundle); phase = bundle.getInt(PHASE); - if (phase != 0) BossHealthBar.assignBoss(this); + if (phase != 0) { + BossHealthBar.assignBoss(this); + if (phase == 5) BossHealthBar.bleed(true); + } abilityCooldown = bundle.getFloat(ABILITY_CD); summonCooldown = bundle.getFloat(SUMMON_CD); fistSummons.clear(); Collections.addAll(fistSummons, bundle.getClassArray(FIST_SUMMONS)); - //pre-0.9.3 saves - if (bundle.contains(CHALLENGE_SUMMONS)) { - challengeSummons.clear(); - Collections.addAll(challengeSummons, bundle.getClassArray(CHALLENGE_SUMMONS)); - } + challengeSummons.clear(); + Collections.addAll(challengeSummons, bundle.getClassArray(CHALLENGE_SUMMONS)); regularSummons.clear(); Collections.addAll(regularSummons, bundle.getClassArray(REGULAR_SUMMONS)); @@ -525,13 +617,17 @@ public class YogDzewa extends Mob { @Override public int drRoll() { - return Random.NormalIntRange(0, 4); + return super.drRoll() + Random.NormalIntRange(0, 4); } } //used so death to yog's ripper demons have their own rankings description - public static class YogRipper extends RipperDemon {} + public static class YogRipper extends RipperDemon { + { + maxLvl = -2; + } + } public static class YogEye extends Eye { { maxLvl = -2; @@ -542,6 +638,4 @@ public class YogDzewa extends Mob { maxLvl = -2; } } - - -} +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/CrivusFruits.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/CrivusFruits.java index 49f157947..519223cfd 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/CrivusFruits.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/CrivusFruits.java @@ -136,6 +136,14 @@ public class CrivusFruits extends Mob { @Override protected boolean act() { + + alerted = false; + super.act(); + + if (alignment == Alignment.NEUTRAL){ + return true; + } + //毒雾扩散 if(!crivusfruitslevel2){ GameScene.add(Blob.seed(pos, HP<65 ? 50 : 30, DiedBlobs.class)); @@ -200,6 +208,7 @@ public class CrivusFruits extends Mob { //三阶段 if(HP==36){ + alignment = Alignment.ENEMY; GameScene.flash(0x80009c9c); HP=HT=35; if(Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DMZERO.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DMZERO.java index 9cebeb267..b2eea127b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DMZERO.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DMZERO.java @@ -728,7 +728,6 @@ public class DMZERO extends Mob cell = i + j*Dungeon.level.width(); if (cur[cell] > 0 && (ch = Actor.findChar( cell )) != null) { if (!ch.isImmune(this.getClass())) { - ch.damage(damage, this); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DictFish.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DictFish.java new file mode 100644 index 000000000..76829b825 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DictFish.java @@ -0,0 +1,92 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.Statistics; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vulnerable; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim; +import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.sprites.DictFishSprites; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.utils.Random; + +public class DictFish extends Mob { + + { + spriteClass = DictFishSprites.class; + + HP = HT = 100; + defenseSkill = 4; + + EXP = 2; + maxLvl = -8; + baseSpeed = 0.5f; + properties.add(Property.BOSS); //添加BOSS属性 + immunities.add(Grim.class); //添加Grim类 + immunities.add(ScrollOfPsionicBlast.class); //添加ScrollOfPsionicBlast类 + immunities.add(ScrollOfRetribution.class); //添加ScrollOfRetribution类 + immunities.add(Corruption.class); + } + + @Override + protected boolean act() { + + if (Statistics.sakaBackStage >= 2) { + ((AncientMysteryCityBossLevel) Dungeon.level).progress(); + } + return super.act(); + } + + @Override + public void damage(int dmg, Object src) { + LockedFloor lock = Dungeon.hero.buff(LockedFloor.class); + if (lock != null) lock.addTime(dmg*0.4f); + super.damage(dmg, src); + } + + @Override + public int attackProc( Char enemy, int damage ) { + damage = super.attackProc( enemy, damage ); + + if (Random.Int(10)==4 || Statistics.sakaBackStage >= 1) { + Buff.affect(enemy, Vulnerable.class, 6f); + } else { + Buff.affect( enemy, Cripple.class, 4f); + } + return damage; + } + + @Override + public void die( Object cause ) { + Statistics.sakaBackStage++; + GLog.n(Messages.get( RoomStone.class, "angry" )); + if (Statistics.sakaBackStage >= 2) { + ((AncientMysteryCityBossLevel) Dungeon.level).progress(); + } + super.die( cause ); + } + + @Override + public int damageRoll() { + return Random.NormalIntRange( 10, 20 ); + } + + @Override + public int attackSkill( Char target ) { + return 10; + } + + @Override + public int drRoll() { + return 8; + } +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/RoomStone.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/RoomStone.java new file mode 100644 index 000000000..a5f8bc08e --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/RoomStone.java @@ -0,0 +1,358 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses; + +import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.Statistics; +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.Adrenaline; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bleeding; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RoseShiled; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; +import com.shatteredpixel.shatteredpixeldungeon.effects.TargetedCell; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim; +import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel; +import com.shatteredpixel.shatteredpixeldungeon.levels.CaveTwoBossLevel; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.RoomStoneSprites; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Bundle; +import com.watabou.utils.Callback; +import com.watabou.utils.GameMath; +import com.watabou.utils.PathFinder; +import com.watabou.utils.Random; + +public class RoomStone extends Mob { + + { + spriteClass = RoomStoneSprites.class; + + HP = HT = 100; + defenseSkill = 16; + + EXP = 9; //for corrupting + maxLvl = -2; + + HUNTING = new Hunting(); + + baseSpeed = 1.5f; + + properties.add(Property.BOSS); //添加BOSS属性 + immunities.add(Grim.class); //添加Grim类 + immunities.add(ScrollOfPsionicBlast.class); //添加ScrollOfPsionicBlast类 + immunities.add(ScrollOfRetribution.class); //添加ScrollOfRetribution类 + immunities.add(Corruption.class); + } + + @Override + public void damage(int dmg, Object src) { + LockedFloor lock = Dungeon.hero.buff(LockedFloor.class); + if (lock != null) lock.addTime(dmg*0.8f); + super.damage(dmg, src); + } + + @Override + public int damageRoll() { + return Random.NormalIntRange( 5, 12 ); + } + + @Override + public int attackSkill( Char target ) { + return 5; + } + + @Override + public int drRoll() { + return 3; + } + + private static final String LAST_ENEMY_POS = "last_enemy_pos"; + private static final String LEAP_POS = "leap_pos"; + private static final String LEAP_CD = "leap_cd"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(LAST_ENEMY_POS, lastEnemyPos); + bundle.put(LEAP_POS, leapPos); + bundle.put(LEAP_CD, leapCooldown); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + lastEnemyPos = bundle.getInt(LAST_ENEMY_POS); + leapPos = bundle.getInt(LEAP_POS); + leapCooldown = bundle.getFloat(LEAP_CD); + } + + private int lastEnemyPos = -1; + + @Override + protected boolean act() { + + if(Statistics.sakaBackStage >= 2){ + ((AncientMysteryCityBossLevel)Dungeon.level).progress(); + } + + AiState lastState = state; + boolean result = super.act(); + if (paralysed <= 0) leapCooldown --; + + //if state changed from wandering to hunting, we haven't acted yet, don't update. + if (!(lastState == WANDERING && state == HUNTING)) { + if (enemy != null) { + lastEnemyPos = enemy.pos; + } else { + lastEnemyPos = hero.pos; + } + } + + return result; + } + + private int leapPos = -1; + private float leapCooldown = 0; + + @Override + public void die( Object cause ) { + Statistics.sakaBackStage++; + GLog.n(Messages.get( DictFish.class, "angry" )); + if (Statistics.sakaBackStage >= 2) { + ((AncientMysteryCityBossLevel) Dungeon.level).progress(); + } + + for (Mob boss : Dungeon.level.mobs.toArray(new Mob[0])) { + if (boss instanceof DictFish) { + Buff.affect(boss, Adrenaline.class, 35f); + Buff.affect(boss, RoseShiled.class, 10f); + } + } + super.die( cause ); + } + + public class Hunting extends Mob.Hunting { + + + public void dropRocks( Char target ) { + + hero.interrupt(); + final int rockCenter; + if (Dungeon.level.adjacent(pos, target.pos)){ + int oppositeAdjacent = target.pos + (target.pos - pos); + Ballistica trajectory = new Ballistica(target.pos, oppositeAdjacent, Ballistica.MAGIC_BOLT); + WandOfBlastWave.throwChar(target, trajectory, 20, false, false, getClass()); + if (target == hero){ + hero.interrupt(); + } + rockCenter = trajectory.path.get(Math.min(trajectory.dist, 200)); + } else { + rockCenter = target.pos; + } + + Actor a = new Actor() { + + { + actPriority = HERO_PRIO+1; + } + private static final float TIME_TO_ZAP = 1f; + + @Override + protected boolean act() { + + //pick an adjacent cell to the hero as a safe cell. This cell is less likely to be in a wall or containing hazards + int safeCell; + do { + safeCell = rockCenter + PathFinder.NEIGHBOURS8[Random.Int(8)]; + } while (safeCell == pos + || (Dungeon.level.solid[safeCell] && Random.Int(2) == 0) + || (Blob.volumeAt(safeCell, CaveTwoBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0)); + + int start = rockCenter - Dungeon.level.width() * 3 - 3; + int pos; + for (int y = 0; y < 7; y++) { + pos = start + Dungeon.level.width() * y; + for (int x = 0; x < 7; x++) { + if (!Dungeon.level.insideMap(pos)) { + pos++; + continue; + } + //add rock cell to pos, if it is not solid, and isn't the safecell + if (!Dungeon.level.solid[pos] && pos != safeCell && Random.Int(Dungeon.level.distance(rockCenter, pos)) == 0) { + //don't want to overly punish players with slow move or attack speed + GameScene.add(Blob.seed(pos, 4, Fire.class)); + } + pos++; + } + } + Actor.remove(this); + return true; + } + }; + Actor.addDelayed(a, Math.min(target.cooldown(), 3*TICK)); + + } + + @Override + public boolean act( boolean enemyInFOV, boolean justAlerted ) { + + if (leapPos != -1){ + + leapCooldown = Random.NormalIntRange(2, 4); + Ballistica b = new Ballistica(pos, leapPos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID); + + //check if leap pos is not obstructed by terrain + if (rooted || b.collisionPos != leapPos){ + leapPos = -1; + return true; + } + + final Char leapVictim = Actor.findChar(leapPos); + final int endPos; + + //ensure there is somewhere to land after leaping + if (leapVictim != null){ + int bouncepos = -1; + for (int i : PathFinder.NEIGHBOURS8){ + if ((bouncepos == -1 || Dungeon.level.trueDistance(pos, leapPos+i) < Dungeon.level.trueDistance(pos, bouncepos)) + && Actor.findChar(leapPos+i) == null && Dungeon.level.passable[leapPos+i]){ + bouncepos = leapPos+i; + } + } + if (bouncepos == -1) { + leapPos = -1; + return true; + } else { + endPos = bouncepos; + } + } else { + endPos = leapPos; + } + + //do leap + sprite.visible = Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[leapPos] || Dungeon.level.heroFOV[endPos]; + Ballistica route = new Ballistica(leapPos, target, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID); + int cell = route.collisionPos; + + //can't occupy the same cell as another char, so move back one. + int backTrace = route.dist-1; + while (Actor.findChar( cell ) != null && cell != leapPos) { + cell = route.path.get(backTrace); + backTrace--; + } + sprite.jump(pos, leapPos, new Callback() { + @Override + public void call() { + + if (leapVictim != null && alignment != leapVictim.alignment){ + Buff.affect(leapVictim, Bleeding.class).set(0.75f*damageRoll()); + leapVictim.sprite.flash(); + dropRocks(enemy); + Sample.INSTANCE.play(Assets.Sounds.HIT); + } + + if (endPos != leapPos){ + Actor.addDelayed(new Pushing(RoomStone.this, leapPos, endPos), -1); + } + + pos = endPos; + leapPos = -1; + sprite.idle(); + Dungeon.level.occupyCell(RoomStone.this); + next(); + } + }); + return false; + } + + enemySeen = enemyInFOV; + if (enemyInFOV && !isCharmedBy( enemy ) && canAttack( enemy )) { + + return doAttack( enemy ); + + } else { + + if (enemyInFOV) { + target = enemy.pos; + } else if (enemy == null) { + state = WANDERING; + target = Dungeon.level.randomDestination( RoomStone.this ); + return true; + } + + + if (leapCooldown <= 0 && enemyInFOV && !rooted + && Dungeon.level.distance(pos, enemy.pos) >= 3 && Statistics.sakaBackStage>=1) { + + int targetPos = enemy.pos; + if (lastEnemyPos != enemy.pos) { + int closestIdx = 0; + for (int i = 1; i < PathFinder.CIRCLE8.length; i++) { + if (Dungeon.level.trueDistance(lastEnemyPos, enemy.pos + PathFinder.CIRCLE8[i]) + < Dungeon.level.trueDistance(lastEnemyPos, enemy.pos + PathFinder.CIRCLE8[closestIdx])) { + closestIdx = i; + } + } + targetPos = enemy.pos + PathFinder.CIRCLE8[(closestIdx + 4) % 8]; + } + + Ballistica b = new Ballistica(pos, targetPos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID); + //try aiming directly at hero if aiming near them doesn't work + if (b.collisionPos != targetPos && targetPos != enemy.pos) { + targetPos = enemy.pos; + b = new Ballistica(pos, targetPos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID); + } + if (b.collisionPos == targetPos) { + //get ready to leap + leapPos = targetPos; + //don't want to overly punish players with slow move or attack speed + spend(GameMath.gate(TICK, enemy.cooldown(), 3 * TICK)); + if (Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[leapPos]) { + GLog.w(Messages.get(RoomStone.this, "leap")); + sprite.parent.addToBack(new TargetedCell(leapPos, 0xFF0000)); + ((RoomStoneSprites) sprite).leapPrep(leapPos); + hero.interrupt(); + } + return true; + } + } + + + + + int oldPos = pos; + if (target != -1 && getCloser( target )) { + + spend( 1 / speed() ); + return moveSprite( oldPos, pos ); + + } else { + spend( TICK ); + if (!enemyInFOV) { + sprite.showLost(); + state = WANDERING; + target = Dungeon.level.randomDestination( RoomStone.this ); + } + return true; + } + } + } + + } + +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java index 3873f2844..dc09556a0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java @@ -10,9 +10,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Boss; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.HalomethaneFire; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bleeding; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM720; @@ -21,9 +20,12 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; import com.shatteredpixel.shatteredpixeldungeon.effects.TargetedCell; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.RainbowParticle; -import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey; -import com.shatteredpixel.shatteredpixeldungeon.items.quest.GooBlob; +import com.shatteredpixel.shatteredpixeldungeon.items.food.SakaMeat; +import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.WaterSoul; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.SakaFishSketon; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave; +import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.CaveTwoBossLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; @@ -43,6 +45,7 @@ import com.watabou.utils.GameMath; import com.watabou.utils.PathFinder; import com.watabou.utils.Random; +/**萨卡班甲鱼 Boss 难度:3.5级 */ public class SakaFishBoss extends Boss { private int leapPos = -1; private float leapCooldown = 0; @@ -68,6 +71,8 @@ public class SakaFishBoss extends Boss { HT=480; properties.add(Property.ICY); + properties.add(Property.ELECTRIC); + properties.add(Property.FIERY); viewDistance = 30; } @@ -80,6 +85,11 @@ public class SakaFishBoss extends Boss { return; } + if (dmg >= 25){ + //takes 5/6/7/8/9/10 dmg at 5/7/10/14/19/25 incoming dmg + dmg = 14 + (int)(Math.sqrt(8*(dmg - 4) + 1) - 1)/2; + } + int hpBracket = HT / 8; int beforeHitHP = HP; @@ -96,15 +106,22 @@ public class SakaFishBoss extends Boss { lock.addTime(dmg*3f); } + AncientMysteryCityBossLevel.State level = ((AncientMysteryCityBossLevel)Dungeon.level).pro(); //phase 1 of the fight is over - if (HP <= HT/2){ + if (HP <= HT/2 && level==AncientMysteryCityBossLevel.State.TWO_BOSS){ HP = (HT/2); yell(Messages.get(this, "interesting")); -// ((PrisonBossLevel)Dungeon.level).progress(); + ((AncientMysteryCityBossLevel)Dungeon.level).progress(); BossHealthBar.bleed(true); } } + @Override + public boolean isInvulnerable(Class effect) { + AncientMysteryCityBossLevel.State level = ((AncientMysteryCityBossLevel)Dungeon.level).pro(); + return level==AncientMysteryCityBossLevel.State.END_BOSS; + } + @Override protected boolean canAttack( Char enemy ) { @@ -149,7 +166,8 @@ public class SakaFishBoss extends Boss { @Override public int drRoll() { - return Random.NormalIntRange(0, 2); + AncientMysteryCityBossLevel.State level = ((AncientMysteryCityBossLevel)Dungeon.level).pro(); + return level == AncientMysteryCityBossLevel.State.FALL_BOSS ? 5 : 15; } @@ -157,6 +175,15 @@ public class SakaFishBoss extends Boss { ((SakaFishBossSprites) sprite).activate(); } + @Override + protected boolean getCloser( int target ) { + if (state == HUNTING) { + return enemySeen && getFurther( target ); + } else { + return super.getCloser( target ); + } + } + @Override protected boolean act() { AiState lastState = state; @@ -187,96 +214,75 @@ public class SakaFishBoss extends Boss { @Override protected boolean doAttack( Char enemy ) { - + AncientMysteryCityBossLevel.State level = ((AncientMysteryCityBossLevel)Dungeon.level).pro(); if (beamCooldown > 0) { return super.doAttack(enemy); } else if (!beamCharged){ ((SakaFishBossSprites)sprite).charge( enemy.pos ); - spend( attackDelay()*2f ); + + spend( level == AncientMysteryCityBossLevel.State.FALL_BOSS ? attackDelay() : attackDelay()*2f ); beamCharged = true; return true; } else if(HP*2>=HT) { - spend( attackDelay()*3f ); + spend( level == AncientMysteryCityBossLevel.State.FALL_BOSS ? attackDelay() : attackDelay()*3f ); beam = new Ballistica(pos, beamTarget, Ballistica.STOP_SOLID); if (Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[beam.collisionPos] ) { sprite.zap( beam.collisionPos ); return false; } else { - sprite.operate(this.pos); + sprite.idle(); deathGaze(); - return true; } } else { + spend( level == AncientMysteryCityBossLevel.State.FALL_BOSS ? attackDelay() : attackDelay()*3f ); - return true; + beam = new Ballistica(pos, beamTarget, Ballistica.STOP_SOLID); + if (Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[beam.collisionPos] ) { + sprite.zap( beam.collisionPos ); + return false; + } else { + sprite.idle(); + deathGaze(); + 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 ); - if(Dungeon.depth!=28){ + Dungeon.level.unseal(); GetBossLoot(); GameScene.bossSlain(); - Dungeon.level.drop( new SkeletonKey( Dungeon.depth ), pos ).sprite.drop(); + Dungeon.level.drop( new CrystalKey( 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 meets = Random.chances(new float[]{0, 0, 6, 3, 1}); + for (int i = 0; i < meets; 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 ); + Dungeon.level.drop( new SakaMeat(), pos + ofs ).sprite.drop( pos ); } - Badges.validateBossSlain(); + Dungeon.level.drop( new WaterSoul(), pos-1 ).sprite.drop(); + Dungeon.level.drop( new SakaFishSketon(), pos ).sprite.drop(); + Dungeon.level.drop( new WaterSoul(), pos+1 ).sprite.drop(); + + Badges.KILLSAKA(); yell( Messages.get(this, "defeated") ); - } + } @@ -304,6 +310,9 @@ public class SakaFishBoss extends Boss { private static final String BEAM_COOLDOWN = "beamCooldown"; private static final String BEAM_CHARGED = "beamCharged"; + //二阶段 + private static final String TO_ATTACK = "toattack"; + @Override public void storeInBundle( Bundle bundle ) { @@ -338,7 +347,6 @@ public class SakaFishBoss extends Boss { lastEnemyPos = bundle.getInt(LAST_ENEMY_POS); leapPos = bundle.getInt(LEAP_POS); leapCooldown = bundle.getFloat(LEAP_CD); - } public void dropRocks( Char target ) { @@ -357,8 +365,6 @@ public class SakaFishBoss extends Boss { rockCenter = target.pos; } - //we handle this through an actor as it gives us fine-grainted control over when the blog acts vs. when the hero acts - //FIXME this is really messy to just get some fine-grained control. would be nice to build this into blob functionality, or just not use blobs for this at all Actor a = new Actor() { { @@ -444,39 +450,21 @@ public class SakaFishBoss extends Boss { sprite.dirtcar(pos, leapPos, new Callback() { @Override public void call() { - + AncientMysteryCityBossLevel.State level = ((AncientMysteryCityBossLevel)Dungeon.level).pro(); if (leapVictim != null && alignment != leapVictim.alignment){ - Buff.affect(leapVictim, Bleeding.class).set(0.75f*damageRoll()); - dropRocks(enemy); + enemy.damage( Random.NormalIntRange( 20, 40 ), this ); + if(level == AncientMysteryCityBossLevel.State.FALL_BOSS){ + //三阶段 魔法风暴 + FishStorm(sprite.ch); + } Sample.INSTANCE.play(Assets.Sounds.ROCKS); leapVictim.sprite.flash(); Sample.INSTANCE.play(Assets.Sounds.HIT); } - if (endPos != leapPos){ - Actor.addDelayed(new Pushing(SakaFishBoss.this, leapPos, endPos), -1); - } - - pos = endPos; - leapPos = -1; - sprite.operate(pos); - Dungeon.level.occupyCell(SakaFishBoss.this); - next(); - } - }); - sprite.visible = Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[leapPos] || Dungeon.level.heroFOV[endPos]; - sprite.dirtcar(pos, leapPos, new Callback() { - @Override - public void call() { - - if (leapVictim != null && alignment != leapVictim.alignment){ - Buff.affect(leapVictim, Bleeding.class).set(0.75f*damageRoll()); - //TODO 魔法风暴 - FishStorm(enemy); - enemy.damage( Random.NormalIntRange( 10, 20 ), this ); - Sample.INSTANCE.play(Assets.Sounds.ROCKS); - leapVictim.sprite.flash(); - Sample.INSTANCE.play(Assets.Sounds.HIT); + if (!enemy.isAlive() && enemy == hero) { + Dungeon.fail( getClass() ); + GLog.n( Messages.get(SakaFishBoss.class, "dictcar_kill"),Dungeon.hero.name() ); } if (endPos != leapPos){ @@ -569,7 +557,7 @@ public class SakaFishBoss extends Boss { public void deathGaze(){ if (!beamCharged || beamCooldown > 0 || beam == null) return; - + AncientMysteryCityBossLevel.State level = ((AncientMysteryCityBossLevel)Dungeon.level).pro(); beamCharged = false; beamCooldown = Random.IntRange(4, 6); @@ -592,6 +580,9 @@ public class SakaFishBoss extends Boss { if (hit( this, ch, true )) { ch.damage( Random.NormalIntRange( 20, 40 ), new DeathGaze() ); + if(level == AncientMysteryCityBossLevel.State.FALL_BOSS){ + dropRocks(enemy); + } if (Dungeon.level.heroFOV[pos]) { ch.sprite.flash(); @@ -600,7 +591,7 @@ public class SakaFishBoss extends Boss { if (!ch.isAlive() && ch == hero) { Dungeon.fail( getClass() ); - GLog.n( Messages.get(this, "deathgaze_kill") ); + GLog.n( Messages.get(this, "deathgaze_kill"),Dungeon.hero.name() ); } } else { ch.sprite.showStatus( CharSprite.NEUTRAL, ch.defenseVerb() ); @@ -615,28 +606,30 @@ public class SakaFishBoss extends Boss { beamTarget = -1; } + + + //萨卡班甲鱼魔法风暴 public void FishStorm(Char ch){ Ballistica aim; aim = new Ballistica(ch.pos, ch.pos - 1, Ballistica.WONT_STOP); int projectileProps = Ballistica.STOP_SOLID | Ballistica.STOP_TARGET; - int aoeSize = 4; + int aoeSize = 8; ConeAOE aoe = new ConeAOE(aim, aoeSize, 360, projectileProps); for (Ballistica ray : aoe.outerRays){ ((MagicMissile)ch.sprite.parent.recycle( MagicMissile.class )).reset( - MagicMissile.FROST, + MagicMissile.HALOFIRE, ch.sprite, ray.path.get(ray.dist), null ); - if( ray.collisionPos == hero.pos){ - Buff.prolong(enemy, Frost.class, Frost.DURATION); - } else { - GameScene.add(Blob.seed(ray.path.get(ray.dist),5, HalomethaneFire.class)); + if( Dungeon.level.water[ray.path.get(ray.dist)] && Random.Int(10) == 2){ + GameScene.add(Blob.seed(ray.path.get(ray.dist), 30, HalomethaneFire.class)); Level.set(ray.path.get(ray.dist), Terrain.EMPTY); GameScene.updateMap( ray.path.get(ray.dist) ); + } else { + Buff.prolong(enemy, Cripple.class, Cripple.DURATION); } - } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/v.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/v.java deleted file mode 100644 index d9e0bef08..000000000 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/v.java +++ /dev/null @@ -1,476 +0,0 @@ -//package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses; -// -//import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero; -// -//import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -//import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; -//import com.shatteredpixel.shatteredpixeldungeon.actors.Char; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Adrenaline; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ChaosTime; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FireImbue; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MaxGuard; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SoulMark; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; -//import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; -//import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; -//import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; -//import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; -//import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; -//import com.shatteredpixel.shatteredpixeldungeon.effects.TargetedCell; -//import com.shatteredpixel.shatteredpixeldungeon.effects.particles.PurpleParticle; -//import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; -//import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; -//import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; -//import com.shatteredpixel.shatteredpixeldungeon.sprites.PillarSprite; -//import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; -//import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; -//import com.watabou.utils.Bundle; -//import com.watabou.utils.GameMath; -//import com.watabou.utils.PathFinder; -//import com.watabou.utils.Random; -// -//import java.util.ArrayList; -//import java.util.HashSet; -// -//public abstract class SeptiumPillar extends Mob { -// -// private boolean firstactive = false; -// private boolean secondactive = false; -// private boolean thirdactive = false; -// -// { -// HP = HT = 100; -// -// viewDistance = 99; -// -// //for doomed resistance -// EXP = 25; -// maxLvl = -2; -// baseSpeed = 0; -// -// state = PASSIVE; -// alignment = Alignment.NEUTRAL; -// -// properties.add(Property.BOSS); -// properties.add(Property.KISEKI); -// properties.add(Property.IMMOVABLE); -// properties.add(Property.INORGANIC); -// immunities.add( Terror.class ); -// immunities.add( Amok.class ); -// immunities.add( Charm.class ); -// immunities.add( Sleep.class ); -// immunities.add( Vertigo.class ); -// immunities.add( Paralysis.class ); -// immunities.add( SoulMark.class ); -// immunities.add( Weakness.class ); -// immunities.add( Blindness.class ); -// } -// -// @Override -// protected boolean act() -// -// { -// if (alignment == Alignment.NEUTRAL){ -// next(); -// } -// else -// { -// onZapComplete(); -// state = PASSIVE; -// } -// return super.act(); -// } -// -// @Override -// public void notice() { -// //do nothing -// } -// -// -// -// @Override -// public void add(Buff buff) { -// //immune to all buffs/debuffs when inactive -// if (alignment != Alignment.NEUTRAL) { -// super.add(buff); -// } -// } -// -// private static final String ALIGNMENT = "alignment"; -// -// @Override -// public void storeInBundle(Bundle bundle) { -// super.storeInBundle(bundle); -// bundle.put(ALIGNMENT, alignment); -// -// } -// -// @Override -// public void restoreFromBundle(Bundle bundle) { -// super.restoreFromBundle(bundle); -// alignment = bundle.getEnum(ALIGNMENT, Alignment.class); -// -// } -// -// @Override -// public boolean interact(Char c) { -// return true; -// } -// -// protected abstract void zap(); -// -// -// -// public void onZapComplete(){ -// zap(); -// next(); -// } -// -// -// -// public void activate(){ -// alignment = Alignment.ENEMY; -// ((PillarSprite) sprite).activate(); -// } -// -// @Override -// public String description() { -// return Messages.get(SeptiumPillar.class, "desc") + "\n\n" + Messages.get(this, "desc"); -// } -// -// { -// immunities.add( Terror.class ); -// immunities.add( Amok.class ); -// immunities.add( Charm.class ); -// immunities.add( Sleep.class ); -// immunities.add( Vertigo.class ); -// immunities.add( Paralysis.class ); -// immunities.add( SoulMark.class ); -// immunities.add( Weakness.class ); -// immunities.add( Blindness.class ); -// } -// -// public static class FlamePillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Flame.class; -// } -// -// @Override -// protected boolean act() { -// { -// state = PASSIVE; -// } -// return super.act(); -// } -// -// @Override -// protected void zap() { -// for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) { -// if(!mob.properties().contains(Property.KISEKI)) { -// Buff.affect(mob, FireImbue.class).set( 10f); -// } -// next(); -// } -// GLog.w(Messages.get( this, "message") ); -// spend(15f); -// } -// -// } -// -// public static class GroundPillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Ground.class; -// } -// -// @Override -// protected boolean act() { -// { -// state = PASSIVE; -// } -// return super.act(); -// } -// -// -// @Override -// protected void zap() { -// for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) { -// if(!mob.properties().contains(Property.KISEKI)) { -// Buff.affect(mob, MaxGuard.class); -// } -// next(); -// } -// GLog.w(Messages.get( this, "message") ); -// spend(15f); -// }; -// -// -// -// -// -// } -// -// public static class WaterPillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Water.class; -// -// } -// -// @Override -// protected boolean act() { -// { -// state = PASSIVE; -// } -// return super.act(); -// } -// -// @Override -// protected void zap() { -// for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) { -// if(!mob.properties().contains(Property.KISEKI)) { -// if (mob.HP < mob.HT/3){ -// -// mob.HP = mob.HP+20; -// -// } -// -// -// } -// -// } -// GLog.w(Messages.get( this, "message") ); -// spend(15f); -// }; -// -// -// -// } -// -// public static class WindPillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Wind.class; -// -// } -// -// @Override -// protected boolean act() { -// { -// state = PASSIVE; -// } -// return super.act(); -// } -// -// @Override -// protected void zap() { -// for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) { -// if(!mob.properties().contains(Property.KISEKI)) { -// Buff.affect(mob, Adrenaline.class,3f); -// } -// next(); -// } -// GLog.w(Messages.get( this, "message") ); -// spend(15f); -// } -// } -// -// public static class ChronosPillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Chronos.class; -// -// } -// -// @Override -// protected boolean act() { -// { -// state = PASSIVE; -// } -// return super.act(); -// } -// -// @Override -// protected void zap() { -// -// spend(15f); -// Buff.affect( hero, ChaosTime.class, 15f); -// GLog.w(Messages.get( this, "message") ); -// -// } -// -// -// } -// -// -// public static class HeavenPillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Heaven.class; -// } -// -// private ArrayList targetedCells = new ArrayList<>(); -// -// private float abilityCooldown; -// private static final int MIN_ABILITY_CD = 10; -// private static final int MAX_ABILITY_CD = 15; -// -// // 添加一个计数器,用来记录回合数 -// private int turnCount = 0; -// -// @Override -// protected boolean act() { -// boolean terrainAffected = false; -// HashSet affected = new HashSet<>(); -// //delay fire on a rooted hero -// if (!hero.rooted && alignment == Alignment.ENEMY && firstActive) { -// for (int i : targetedCells) { -// Ballistica b = new Ballistica(pos, i, Ballistica.WONT_STOP); -// //shoot beams -// sprite.parent.add(new Beam.DeathRay(sprite.center(), DungeonTilemap.raisedTileCenterToWorld(b.collisionPos))); -// for (int p : b.path) { -// Char ch = Actor.findChar(p); -// if (ch != null && (ch.alignment != alignment || ch instanceof Bee)) { -// affected.add(ch); -// } -// if (Dungeon.level.flamable[p]) { -// Dungeon.level.destroy(p); -// GameScene.updateMap(p); -// terrainAffected = true; -// } -// } -// } -// if (terrainAffected) { -// Dungeon.observe(); -// } -// for (Char ch : affected) { -// ch.damage(Random.NormalIntRange(20, 30), new Eye.DeathGaze()); -// -// if (Dungeon.level.heroFOV[pos]) { -// ch.sprite.flash(); -// CellEmitter.center(pos).burst(PurpleParticle.BURST, Random.IntRange(1, 2)); -// } -// if (!ch.isAlive() && ch == hero) { -// Dungeon.fail(getClass()); -// GLog.n(Messages.get(Char.class, "kill", name())); -// } -// } -// targetedCells.clear(); -// } -// -// if (abilityCooldown <= 0 && alignment == Alignment.ENEMY && firstActive) { -// int beams = 1; -// GLog.w(Messages.get(this, "message")); -// HashSet affectedCells = new HashSet<>(); -// for (int i = 0; i < beams; i++) { -// -// int targetPos = hero.pos; -// if (i != 0) { -// do { -// targetPos = hero.pos + PathFinder.NEIGHBOURS8[Random.Int(8)]; -// } while (Dungeon.level.trueDistance(pos, hero.pos) -// > Dungeon.level.trueDistance(pos, targetPos)); -// } -// targetedCells.add(targetPos); -// Ballistica b = new Ballistica(pos, targetPos, Ballistica.WONT_STOP); -// affectedCells.addAll(b.path); -// } -// -// //remove one beam if multiple shots would cause every cell next to the hero to be targeted -// boolean allAdjTargeted = true; -// for (int i : PathFinder.NEIGHBOURS9) { -// if (!affectedCells.contains(hero.pos + i) && Dungeon.level.passable[hero.pos + i]) { -// allAdjTargeted = false; -// break; -// } -// } -// if (allAdjTargeted) { -// targetedCells.remove(targetedCells.size() - 1); -// } -// for (int i : targetedCells) { -// Ballistica b = new Ballistica(pos, i, Ballistica.WONT_STOP); -// for (int p : b.path) { -// sprite.parent.add(new TargetedCell(p, 0xFF0000)); -// affectedCells.add(p); -// } -// } -// -// // 在14回合时发出警告 -// if (turnCount == 14) { -// for (int i : affectedCells) { -// sprite.parent.add(new TargetedCell(i, 0xFF0000)); -// } -// } -// -// // don't want to overly punish players with slow move or attack speed -// spend(GameMath.gate(TICK, hero.cooldown(), 3 * TICK)); -// hero.interrupt(); -// -// abilityCooldown += Random.NormalFloat(MIN_ABILITY_CD, MAX_ABILITY_CD); -// -// } else { -// spend(TICK); -// if (abilityCooldown > 0) abilityCooldown--; -// } -// -// turnCount++; // 回合数自增 -// -// -// return true; -// } -// -// @Override -// protected void zap() { -// next(); -// } -// } -// -// -// -// -// -// -// public static class PhantomPillar extends SeptiumPillar { -// -// { -// spriteClass = PillarSprite.Phantom.class; -// -// } -// -// @Override -// protected boolean act() { -// { -// state = PASSIVE; -// } -// return super.act(); -// } -// -// @Override -// protected void zap() { -// -// Buff.affect( hero, Vertigo.class, 3f); -// for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) { -// mob.beckon( hero.pos ); -// } -// hero.sprite.centerEmitter().start( Speck.factory( Speck.SCREAM ), 0.3f, 3 ); -// GLog.w(Messages.get( this, "message") ); -// spend(15f); -// } -// -// -// -// -// } -// -// -// -//} -// diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/ImpShopkeeper.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/ImpShopkeeper.java index 2c5896f2a..5660e8fdd 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/ImpShopkeeper.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/ImpShopkeeper.java @@ -22,12 +22,14 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ImpSprite; public class ImpShopkeeper extends Shopkeeper { @@ -73,4 +75,22 @@ public class ImpShopkeeper extends Shopkeeper { sprite.emitter().burst( Speck.factory( Speck.WOOL ), 15 ); sprite.killAndErase(); } + + @Override + public void destroy() { + super.destroy(); + for (Heap heap: Dungeon.level.heaps.valueList()) { + if (heap.type == Heap.Type.FOR_SALE) { + if (ShatteredPixelDungeon.scene() instanceof GameScene) { + 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; + } + } + } + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Shopkeeper.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Shopkeeper.java index 3aca34f54..ce87ecede 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Shopkeeper.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Shopkeeper.java @@ -21,16 +21,23 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; +import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero; + +import com.shatteredpixel.shatteredpixeldungeon.Conducts; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ClearBleesdGoodBuff.BlessNoMoney; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicGirlDebuff.MagicGirlSayMoneyMore; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; +import com.shatteredpixel.shatteredpixeldungeon.items.Ankh; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; +import com.shatteredpixel.shatteredpixeldungeon.items.food.Food; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; import com.shatteredpixel.shatteredpixeldungeon.journal.Notes; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; @@ -59,23 +66,34 @@ public class Shopkeeper extends NPC { public static int MAX_BUYBACK_HISTORY = 4; public ArrayList buybackItems = new ArrayList<>(); - + public static boolean seenBefore = false; @Override protected boolean act() { + if (!seenBefore && Dungeon.level.heroFOV[pos]) { + yell(Messages.get(this, "greetings", hero.name())); + seenBefore = true; + } else if(seenBefore && !Dungeon.level.heroFOV[pos]) { + seenBefore = false; + yell(Messages.get(this, "goodbye", hero.name())); + } if (Dungeon.level.visited[pos]){ Notes.add(Notes.Landmark.SHOP); } - sprite.turnTo( pos, Dungeon.hero.pos ); + sprite.turnTo( pos, hero.pos ); spend( TICK ); return super.act(); } @Override public void damage( int dmg, Object src ) { - flee(); + } + + @Override + public int defenseSkill( Char enemy ) { + return INFINITE_EVASION; } @Override @@ -84,31 +102,10 @@ public class Shopkeeper extends NPC { public void flee() { destroy(); - Notes.remove(Notes.Landmark.SHOP); - - if (sprite != null) { - sprite.killAndErase(); - CellEmitter.get(pos).burst(ElmoParticle.FACTORY, 6); - } - } - - @Override - public void destroy() { - super.destroy(); - for (Heap heap: Dungeon.level.heaps.valueList()) { - if (heap.type == Heap.Type.FOR_SALE) { - if (ShatteredPixelDungeon.scene() instanceof GameScene) { - 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; - } - } - } + CellEmitter.get(pos).burst(ElmoParticle.FACTORY, 6); + hero.sprite.burst(15597568, 9); + sprite.killAndErase(); } @Override @@ -116,9 +113,35 @@ public class Shopkeeper extends NPC { return true; } + @Override + 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 ); + heap.type = Heap.Type.HEAP; + } + } + } + //shopkeepers are greedy! public static int sellPrice(Item item){ - return item.value() * 5 * (Dungeon.depth / 5 + 1); + int price = item.value() * 5 * (Dungeon.depth / 5 + 1); + + if(hero.buff(MagicGirlSayMoneyMore.class) != null){ + if(item instanceof Ankh ||item instanceof Food || item instanceof PotionOfHealing){ + price *= 2.5; + } + price *= 0.5; + //todo 3折 + } else if (hero.buff(BlessNoMoney.class) != null) { + price *= 0.3; + } + + if(Dungeon.isDLC(Conducts.Conduct.MONEYLETGO)){ + price *= 0.5; + } + return price; } public static WndBag sell() { @@ -129,7 +152,7 @@ public class Shopkeeper extends NPC { if (item.value() <= 0) return false; if (item.unique && !item.stackable) return false; if (item instanceof Armor && ((Armor) item).checkSeal() != null) return false; - if (item.isEquipped(Dungeon.hero) && item.cursed) return false; + if (item.isEquipped(hero) && item.cursed) return false; return true; } @@ -155,7 +178,7 @@ public class Shopkeeper extends NPC { @Override public boolean interact(Char c) { - if (c != Dungeon.hero) { + if (c != hero) { return true; } Game.runOnRenderThread(new Callback() { @@ -184,8 +207,8 @@ public class Shopkeeper extends NPC { Item returned = buybackItems.remove(index-2); Dungeon.gold -= returned.value(); Statistics.goldCollected -= returned.value(); - if (!returned.doPickUp(Dungeon.hero)){ - Dungeon.level.drop(returned, Dungeon.hero.pos); + if (!returned.doPickUp(hero)){ + Dungeon.level.drop(returned, hero.pos); } } } @@ -220,7 +243,7 @@ public class Shopkeeper extends NPC { public String chatText(){ switch (Dungeon.depth){ case 6: default: - return Messages.get(this, "talk_prison_intro") + "\n\n" + Messages.get(this, "talk_prison_" + Dungeon.hero.heroClass.name()); + return Messages.get(this, "talk_prison_intro") + "\n\n" + Messages.get(this, "talk_prison_" + hero.heroClass.name()); case 11:case 13: return Messages.get(this, "talk_caves"); case 16: case 18: diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/custom/testmode/MobPlacer.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/custom/testmode/MobPlacer.java index 9205abcd6..a25b02d0e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/custom/testmode/MobPlacer.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/custom/testmode/MobPlacer.java @@ -14,6 +14,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bandit; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bat; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.BlackHost; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Brute; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CausticSlime; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ColdMagicRat; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Crab; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100; @@ -74,8 +75,8 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.CheckBox; import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton; -import com.shatteredpixel.shatteredpixeldungeon.ui.OptionSlider; import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton; import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock; import com.shatteredpixel.shatteredpixeldungeon.ui.Window; @@ -85,12 +86,11 @@ import com.watabou.utils.PointF; import com.watabou.utils.Reflection; import java.util.ArrayList; -import java.util.Collections; import java.util.LinkedHashMap; -public class MobPlacer extends TestItem { +public class MobPlacer extends TestItem{ { - image = ItemSpriteSheet.CANDY_CANE; + image = ItemSpriteSheet.CANDLE; defaultAction = AC_PLACE; } @@ -100,7 +100,7 @@ public class MobPlacer extends TestItem { private int mobTier = 1; private int mobIndex = 0; private int elite = 0; - private static final int MAX_ELITE = 7; + private int elite_op = 0; private final ArrayList> eliteBuffs = new ArrayList<>(); { @@ -111,7 +111,16 @@ public class MobPlacer extends TestItem { eliteBuffs.add(ChampionEnemy.Growing.class); eliteBuffs.add(ChampionEnemy.Projecting.class); eliteBuffs.add(ChampionEnemy.Halo.class); - }; + eliteBuffs.add(ChampionEnemy.King.class); + eliteBuffs.add(ChampionEnemy.DelayMob.class); + + eliteBuffs.add(ChampionEnemy.Small.class); + eliteBuffs.add(ChampionEnemy.Bomber.class); + eliteBuffs.add(ChampionEnemy.Middle.class); + eliteBuffs.add(ChampionEnemy.Big.class); + eliteBuffs.add(ChampionEnemy.Sider.class); + eliteBuffs.add(ChampionEnemy.LongSider.class); + } @Override public ArrayList actions(Hero hero) { @@ -134,10 +143,11 @@ public class MobPlacer extends TestItem { Mob m = Reflection.newInstance(allData.get(dataThreshold(mobTier) + mobIndex).mobClass); m.pos = cell; GameScene.add(m); - if(elite>0){ - Collections.shuffle(eliteBuffs); - for(int i=0;i0){ + for(int i=0;i<15;++i){ + if((elite_op & (1<0){ + Buff.affect(m, eliteBuffs.get(i)); + } } } ScrollOfTeleportation.appear(m, cell); @@ -174,9 +184,7 @@ public class MobPlacer extends TestItem { case 3: return DataPack.DM201.ordinal() - DataPack.NEW_FIRE_ELE.ordinal() - 1; case 4: return DataPack.ELE_CHAOS.ordinal() - DataPack.DM201.ordinal() - 1; case 5: return DataPack.ACIDIC.ordinal() - DataPack.ELE_CHAOS.ordinal() - 1; - case 6: return DataPack.PIRANHA.ordinal() - DataPack.ACIDIC.ordinal() - 1; - case 7: return DataPack.NQHZ.ordinal() - DataPack.PIRANHA.ordinal() - 1; - case 8: default: return DataPack.IAS.ordinal() - DataPack.NQHZ.ordinal() - 1; + case 6: default: return DataPack.PIRANHA.ordinal() - DataPack.ACIDIC.ordinal() - 1; } } private int dataThreshold(int tier){ @@ -193,10 +201,6 @@ public class MobPlacer extends TestItem { return DataPack.ELE_CHAOS.ordinal()+1; case 6: return DataPack.ACIDIC.ordinal()+1; - case 7: - return DataPack.PIRANHA.ordinal()+1; - case 8: - return DataPack.NQHZ.ordinal()+1; } } @@ -206,6 +210,7 @@ public class MobPlacer extends TestItem { b.put("mobTier", mobTier); b.put("mobIndex", mobIndex); b.put("eliteTags", elite); + b.put("elite_ops", elite_op); } @Override @@ -214,31 +219,33 @@ public class MobPlacer extends TestItem { mobTier = b.getInt("mobTier"); mobIndex = b.getInt("mobIndex"); elite = b.getInt("eliteTags"); + elite_op = b.getInt("elite_ops"); } private class WndSetMob extends Window{ - private static final int WIDTH = 120; - private static final int HEIGHT = 118; + private static final int WIDTH = 150; + private static final int HEIGHT = 150; private static final int BTN_SIZE = 18; private static final int GAP = 2; private RenderedTextBlock selectedPage; private ArrayList mobButtons = new ArrayList<>(); private RenderedTextBlock selectedMob; + private ArrayList eliteOptions = new ArrayList<>(15); public WndSetMob(){ super(); resize(WIDTH, HEIGHT); - RedButton lhs = new RedButton("上一页", 6){ + RedButton lhs = new RedButton("<<<", 8){ @Override public void onClick(){ mobTier--; - if(mobTier < 1 || mobTier>8){ - mobTier = 8; + if(mobTier < 1 || mobTier>6){ + mobTier = 6; } mobIndex = Math.min(mobIndex, maxMobIndex(mobTier)); refreshImage(); @@ -248,11 +255,11 @@ public class MobPlacer extends TestItem { lhs.setRect(GAP, GAP, 24, 18); add(lhs); - RedButton rhs = new RedButton("下一页", 6){ + RedButton rhs = new RedButton(">>>", 8){ @Override public void onClick(){ mobTier++; - if(mobTier < 1 || mobTier > 8){ + if(mobTier < 1 || mobTier > 6){ mobTier = 1; } mobIndex = Math.min(mobIndex, maxMobIndex(mobTier)); @@ -271,7 +278,7 @@ public class MobPlacer extends TestItem { selectedMob.hardlight(0xFFFF44); PixelScene.align(selectedMob); add(selectedMob); - +/* OptionSlider op = new OptionSlider (M.L(MobPlacer.class, "elite"), "0", String.valueOf(MAX_ELITE), 0, MAX_ELITE) { @Override @@ -283,17 +290,47 @@ public class MobPlacer extends TestItem { op.setSelectedValue(elite); add(op); + */ + float pos = 92; + for (int i = 0; i < 15; ++i) { + CheckBox cb = new CheckBox(M.L(MobPlacer.class, "elite_name" + Integer.toString(i))); + cb.active = true; + cb.checked((elite & (1 << i)) > 0); + add(cb); + eliteOptions.add(cb); + + int row = i / 3; // 计算当前复选框所在的行数 + int column = i % 3; // 计算当前复选框所在的列数 + + float columnWidth = WIDTH / 3f - GAP * 4f / 3f; + float rowHeight = 16 + GAP; + + float columnOffset = (WIDTH - columnWidth * 3f - GAP * 2f) / 2f; + float rowOffset = pos + row * rowHeight; // 根据行数计算当前行的垂直偏移量 + + cb.setRect(columnOffset + column * (columnWidth + GAP), rowOffset, columnWidth, 16); + } + + createMobImage(); updateSelectedMob(); layout(); } + private void updateEliteSettings(){ + int el = 0; + for(int i=0;i<15;++i){ + el += eliteOptions.get(i).checked() ? (1< mobClass; private int imageId; @@ -448,4 +495,4 @@ public class MobPlacer extends TestItem { public int getImageId(){return imageId;} public Class getMobClass(){return mobClass;} } -} +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java index a89d15de4..c3b8e9d30 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java @@ -407,7 +407,7 @@ public class Generator { WashCrime.class }; - WEP_T5.probs = new float[]{ 1, 3, 2, 3, 2, 3,2}; + WEP_T5.probs = new float[]{ 3, 3, 3, 3, 3, 3,3}; WEP_T6.classes = new Class[]{ IceFishSword.class, diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Gold.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Gold.java index 163966aea..f743ea6f7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Gold.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Gold.java @@ -86,7 +86,7 @@ public class Gold extends Item { @Override public Item random() { - quantity = Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ? Random.Int( 130 + Dungeon.depth * 3, 160 + Dungeon.depth * 5 ) : + quantity = Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ? Random.Int( 130 + Dungeon.depth * 3, 160 + Dungeon.depth * 5 ) : Random.Int( 30 + Dungeon.depth * 10, 60 + Dungeon.depth * 20 ); return this; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java index e68b42268..9b7413205 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java @@ -24,6 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.items; import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.level; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Conducts; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper; @@ -72,7 +74,9 @@ public class Heap implements Bundlable { REMAINS, BLACK } - public Type type = Type.HEAP; + + //好好好 + public Type type = Dungeon.isDLC(Conducts.Conduct.MONEYLETGO) ? Type.FOR_SALE : Type.HEAP; public int pos = 0; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SakaMeat.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SakaMeat.java new file mode 100644 index 000000000..07046e07b --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SakaMeat.java @@ -0,0 +1,28 @@ +package com.shatteredpixel.shatteredpixeldungeon.items.food; + +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bless; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; + +public class SakaMeat extends Food { + + { + image = ItemSpriteSheet.FISHBONE; + energy = 200f; + } + + @Override + protected void satisfy(Hero hero) { + super.satisfy(hero); + Buff.affect(hero, Bless.class, 50f); + GLog.w( Messages.get(SakaMeat.class, "oks") ); + } + + public int value() { + return 25 * quantity; + } +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/SakaFishSketon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/SakaFishSketon.java new file mode 100644 index 000000000..b65243faa --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/SakaFishSketon.java @@ -0,0 +1,61 @@ +package com.shatteredpixel.shatteredpixeldungeon.items.quest; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.noosa.Game; + +import java.util.ArrayList; + +public class SakaFishSketon extends Item { + + { + image = ItemSpriteSheet.FISHSKELETON; + stackable = true; + } + + private static final String AC_INTER_TP = "interlevel_tp"; + + @Override + public ArrayList actions(Hero hero ) { + ArrayList actions = super.actions( hero ); + if(Dungeon.depth < 0) { + actions.add(AC_INTER_TP); + } + return actions; + } + + @Override + public void execute( Hero hero, String action ) { + super.execute( hero, action ); + if(action.equals(AC_INTER_TP)){ + if(Dungeon.hero.buff(LockedFloor.class) != null) { + GLog.w(Messages.get(this,"cannot_send")); + return; + } + InterlevelScene.mode = InterlevelScene.Mode.RETURN; + Game.switchScene(InterlevelScene.class); + } + } + + @Override + public boolean isUpgradable() { + return false; + } + + @Override + public boolean isIdentified() { + return true; + } + + @Override + public int value() { + return quantity * 1250; + } +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/LockSword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/LockSword.java index 56a69eb11..236b282b2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/LockSword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/LockSword.java @@ -5,7 +5,13 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.BackGoKey; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.HaloBlazing; @@ -13,24 +19,65 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Kineti import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Shocking; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Unstable; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.Icons; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions; +import com.watabou.noosa.Game; import com.watabou.utils.Bundle; import com.watabou.utils.Random; +import java.util.ArrayList; + public class LockSword extends MeleeWeapon { - - - private int lvl = 0; public LockSword() { super.image = ItemSpriteSheet.DG3; super.tier = 5; -// InterlevelScene.mode = InterlevelScene.Mode.ANCITYBOSS; -// Game.switchScene(InterlevelScene.class); } + private static final String AC_INTER_TP = "interlevel_tp"; + + @Override + public ArrayList actions(Hero hero ) { + ArrayList actions = super.actions( hero ); + if(Dungeon.depth >= 0 && Statistics.sakaBackStage == 0) { + actions.add(AC_INTER_TP); + } + return actions; + } + + @Override + public void execute( Hero hero, String action ) { + super.execute( hero, action ); + if(action.equals(AC_INTER_TP)){ + if(Dungeon.hero.buff(LockedFloor.class) != null) { + GLog.w(Messages.get(BackGoKey.class,"cannot_send")); + } else { + ShatteredPixelDungeon.scene().add(new WndOptions(Icons.get(Icons.WARNING), + Messages.get(this, "go_interlevel"), + Messages.get(this, "go_desc"), + Messages.get(this, "okay"), + Messages.get(this, "cancel")) { + @Override + protected void onSelect(int index) { + if (index == 0) { + InterlevelScene.mode = InterlevelScene.Mode.ANCITYBOSS; + Game.switchScene(InterlevelScene.class); + lvl -= 500; + } + } + }); + + } + } + } + + + @Override public int level() { if(lvl <=1000){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/SkyShield.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/SkyShield.java index 08a342b99..a2edc0d98 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/SkyShield.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/SkyShield.java @@ -44,6 +44,7 @@ public class SkyShield extends MeleeWeapon { return 6+3*buffedLvl(); //6 extra defence, plus 3 per level; } + @Override public String statsInfo(){ if (isIdentified()){ return Messages.get(this, "stats_desc", 12+3*buffedLvl()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java index f920bb041..6ab50f847 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java @@ -24,8 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Golem; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses.SakaFishBoss; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class WornShortsword extends MeleeWeapon { @@ -57,7 +57,7 @@ public class WornShortsword extends MeleeWeapon { * 当是魔像的时候,返回的伤害还会追加5上去 * 如果希望最大值能给予5,你也可以使用Math.max(damage, 5); **/ - if(mob instanceof Golem) { + if(mob instanceof SakaFishBoss) { damage+=5; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityBossLevel.java index 077c6a547..fc8282951 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityBossLevel.java @@ -1,16 +1,107 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; +import static com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel.State.END_BOSS; +import static com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel.State.FALL_BOSS; +import static com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel.State.ONE_BOSS; +import static com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel.State.TWO_BOSS; + 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.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses.DictFish; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses.RoomStone; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses.SakaFishBoss; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.utils.Bundle; import com.watabou.utils.PathFinder; import com.watabou.utils.Random; public class AncientMysteryCityBossLevel extends Level{ + public State pro; + + public State pro(){ + return pro; + } + + //地图状态 + public enum State { + ONE_BOSS, + TWO_BOSS, + END_BOSS, + FALL_BOSS + } + + public void progress() { + switch (pro) { + case ONE_BOSS: + //触发seal将枚举变为TWO_BOSS + seal(); + pro = TWO_BOSS; + break; + case TWO_BOSS: + //血量低于240后且在TWO_BOSS枚举中 + for (Mob boss : Dungeon.level.mobs.toArray(new Mob[0])) { + if(boss instanceof SakaFishBoss) { + //如果楼层为开始且boss血量小于240 2阶段 + if (pro == TWO_BOSS && boss.HP <= boss.HT/2) { + ScrollOfTeleportation.appear(boss, 175); + boss.HP= boss.HT/2; + boss.properties.add(Char.Property.IMMOVABLE); + boss.sprite.idle(); + pro = END_BOSS; + RoomStone roomStone = new RoomStone(); + roomStone.pos = 468; + GameScene.add(roomStone); + DictFish dictFish = new DictFish(); + GameScene.add(dictFish); + dictFish.pos = 476; + ScrollOfTeleportation.appear(dictFish, 476); + ScrollOfTeleportation.appear(roomStone, 468); + GLog.i(Messages.get(dictFish, "notice"),dictFish.name()); + GLog.n(Messages.get(roomStone, "notice"),roomStone.name()); + GLog.b(Messages.get(roomStone, "allget"),roomStone.name()); + } + } + } + break; + case END_BOSS: + for (Mob boss : Dungeon.level.mobs.toArray(new Mob[0])) { + if (boss instanceof SakaFishBoss) { + if (pro == END_BOSS) { + ScrollOfTeleportation.appear(boss, 337); + GLog.b(Messages.get(boss, "angry"),boss.name()); + boss.properties.remove(Char.Property.IMMOVABLE); + pro = FALL_BOSS; + } + } + } + break; + case FALL_BOSS: + break; + } + } + + private static final String PRO = "pro"; + + @Override + public void restoreFromBundle( Bundle bundle ) { + super.restoreFromBundle(bundle); + pro = bundle.getEnum(PRO, State.class); + } + + public void storeInBundle( Bundle bundle ) { + super.storeInBundle(bundle); + bundle.put(PRO, pro); + } + + + @Override public String tilesTex() { @@ -79,6 +170,8 @@ public class AncientMysteryCityBossLevel extends Level{ setSize(WIDTH, HEIGHT); map = WorldRoomShort.clone(); entrance = WIDTH*28+13; + //首次构建地图 + pro = ONE_BOSS; return true; } @@ -103,11 +196,11 @@ public class AncientMysteryCityBossLevel extends Level{ super.occupyCell( ch ); - boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero; + boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero && Dungeon.level.distance(ch.pos, entrance) >= 2; - //如果有生物来到BossDoor的下一个坐标,且生物是玩家,那么触发seal(). + //如果有生物来到BossDoor的下一个坐标,且生物是玩家,那么触发seal() . if (map[getBossDoor] == Terrain.DOOR && isTrue || map[getBossDoor] == Terrain.EMBERS && isTrue) { - seal(); + progress(); } } @@ -120,6 +213,11 @@ public class AncientMysteryCityBossLevel extends Level{ set( 688, Terrain.LOCKED_DOOR ); GameScene.updateMap( 688 ); Dungeon.observe(); + for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])){ + if (mob instanceof SakaFishBoss){ + ScrollOfTeleportation.appear(mob, 337); + } + } } /** @@ -128,7 +226,7 @@ public class AncientMysteryCityBossLevel extends Level{ @Override protected void createMobs() { SakaFishBoss boss = new SakaFishBoss(); - boss.pos = 337; + boss.pos = 175; mobs.add(boss); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityLevel.java new file mode 100644 index 000000000..e3756570b --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/AncientMysteryCityLevel.java @@ -0,0 +1,220 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.watabou.utils.Bundlable; +import com.watabou.utils.Bundle; +import com.watabou.utils.Random; + +import java.util.Collection; +import java.util.HashSet; + +public class AncientMysteryCityLevel extends Level { + + private static int WIDTH = 48; + private static int HEIGHT = 48; + { + color1 = 0x534f3e; + color2 = 0xb9d661; + } + + + public HashSet heapstogen; + public int[] heapgenspots; + public int[] teleportspots; + public int[] portswitchspots; + public int[] teleportassign; + public int[] destinationspots; + public int[] destinationassign; + public int prizeNo; + + private static final String HEAPSTOGEN = "heapstogen"; + private static final String HEAPGENSPOTS = "heapgenspots"; + private static final String TELEPORTSPOTS = "teleportspots"; + private static final String PORTSWITCHSPOTS = "portswitchspots"; + private static final String DESTINATIONSPOTS = "destinationspots"; + private static final String TELEPORTASSIGN = "teleportassign"; + private static final String DESTINATIONASSIGN= "destinationassign"; + private static final String PRIZENO = "prizeNo"; + + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(HEAPSTOGEN, heapstogen); + bundle.put(HEAPGENSPOTS, heapgenspots); + bundle.put(TELEPORTSPOTS, teleportspots); + bundle.put(PORTSWITCHSPOTS, portswitchspots); + bundle.put(DESTINATIONSPOTS, destinationspots); + bundle.put(DESTINATIONASSIGN, destinationassign); + bundle.put(TELEPORTASSIGN, teleportassign); + bundle.put(PRIZENO, prizeNo); + } + + + @Override + public String tileName(int tile) { + switch (tile) { + case Terrain.WATER: + return "Dark cold water."; + default: + return super.tileName(tile); + } + } + + + @Override + public String tileDesc(int tile) { + switch (tile) { + case Terrain.EMPTY_DECO: + return "There are old blood stains on the floor."; + case Terrain.BOOKSHELF: + return "This is probably a vestige of a prison library. Might it burn?"; + default: + return super.tileDesc(tile); + } + } + + + @Override + public void restoreFromBundle(Bundle bundle) { + + super.restoreFromBundle(bundle); + + heapgenspots = bundle.getIntArray(HEAPGENSPOTS); + teleportspots = bundle.getIntArray(TELEPORTSPOTS); + portswitchspots = bundle.getIntArray(PORTSWITCHSPOTS); + destinationspots = bundle.getIntArray(DESTINATIONSPOTS); + destinationassign = bundle.getIntArray(DESTINATIONASSIGN); + teleportassign = bundle.getIntArray(TELEPORTASSIGN); + prizeNo = bundle.getInt(PRIZENO); + + heapstogen = new HashSet(); + + Collection collectionheap = bundle.getCollection(HEAPSTOGEN); + for (Bundlable i : collectionheap) { + Item item = (Item) i; + if (item != null) { + heapstogen.add(item); + } + } + } + + @Override + public void create() { + heapstogen = new HashSet(); + heapgenspots = new int[20]; + teleportspots = new int[10]; + portswitchspots = new int[10]; + destinationspots = new int[10]; + destinationassign = new int[10]; + teleportassign = new int[10]; + super.create(); + } + + + public Item genPrizeItem(Class match) { + + if (heapstogen.size() == 0) + return null; + + for (Item item : heapstogen) { + if (match.isInstance(item)) { + heapstogen.remove(item); + return item; + } + } + + Item item = Random.element(heapstogen); + heapstogen.remove(item); + return item; + + } + + @Override + public String tilesTex() { + return Assets.Environment.TILES_ANCIENT; + } + + @Override + public String waterTex() { + return Assets.Environment.WATER_ANCIENT; + } + + @Override + protected boolean build() { + setSize(WIDTH, HEIGHT); + map = SokobanLayouts.SOKOBAN_CASTLE.clone(); + + buildFlagMaps(); + cleanWalls(); + createSwitches(); + + entrance = 15 + WIDTH * 11; + exit = 0; + + + return true; + } + + @Override + protected void createMobs() { + } + + + + protected void createSwitches(){ + + //spots where your portals are + teleportspots[0] = 11 + WIDTH * 10; + teleportspots[1] = 32 + WIDTH * 15; + teleportspots[2] = 25 + WIDTH * 40; + teleportspots[3] = 37 + WIDTH * 18; + teleportspots[4] = 45 + WIDTH * 33; + teleportspots[5] = 37 + WIDTH * 3; + teleportspots[6] = 43 + WIDTH * 2; + + //spots where your portal switches are + portswitchspots[0] = 19 + WIDTH * 10; + portswitchspots[1] = 19 + WIDTH * 6; + portswitchspots[2] = 9 + WIDTH * 8; + portswitchspots[3] = 16 + WIDTH * 37; + + + + //assign each switch to a portal + teleportassign[0] = 11 + WIDTH * 10; + teleportassign[1] = 11 + WIDTH * 10; + teleportassign[2] = 15 + WIDTH * 32; + teleportassign[3] = 37 + WIDTH * 3; + + //assign each switch to a destination spot + destinationassign[0] = 30 + WIDTH * 16; + destinationassign[1] = 23 + WIDTH * 40; + destinationassign[2] = 37 + WIDTH * 16; + destinationassign[3] = 42 + WIDTH * 2; + + + + //set the original destination of portals + destinationspots[0] = 0; + destinationspots[1] = 23 + WIDTH * 8; + destinationspots[2] = 23 + WIDTH * 8; + destinationspots[3] = 23 + WIDTH * 8; + destinationspots[4] = 34 + WIDTH * 6; + destinationspots[5] = 23 + WIDTH * 8; + destinationspots[6] = 23 + WIDTH * 8; + + + + + } + + + @Override + protected void createItems() { + + } + + +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java index 2a712d027..d81d9c388 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java @@ -271,7 +271,7 @@ public class ColdChestBossLevel extends Level { @Override public void occupyCell(Char ch) { super.occupyCell(ch); - boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero; + boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero && Dungeon.level.distance(ch.pos, entrance) >= 2; if (map[getBossDoor] == Terrain.DOOR && isTrue || map[getBossDoor] == Terrain.EMBERS && isTrue) { progress(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ForestBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ForestBossLevel.java index e04b03cf4..94488159d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ForestBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ForestBossLevel.java @@ -168,7 +168,7 @@ public class ForestBossLevel extends Level { super.occupyCell( ch ); - boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero; + boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero && Dungeon.level.distance(ch.pos, entrance) >= 2; //如果有生物来到BossDoor的下一个坐标,且生物是玩家,那么触发seal(). if (map[getBossDoor] == Terrain.DOOR && isTrue || map[getBossDoor] == Terrain.EMBERS && isTrue) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java index a1233eeb1..0243b5fdb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java @@ -38,7 +38,7 @@ public class LevelRules { case 17: case 27: Buff.affect(hero, RandomBuff.class).set(5, 1); - return new AncientMysteryCityBossLevel(); + return new AncityLevel(); case 1: case 3: case 6: case 7: case 9: case 11: case 13: case 15: case 18: case 20: case 24: return new ItemLevel(); @@ -109,7 +109,7 @@ public class LevelRules { if ((Statistics.boss_enhance & 0x4) != 0) { return new CavesGirlDeadLevel(); } else { - return Random.Float() <= 0.4f ? new CaveTwoBossLevel() : new NewCavesBossLevel(); + return Random.Float() <= 0.4f ? new CaveTwoBossLevel() : new CaveTwoBossLevel(); } case 16: case 17: diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java index 0cecd1f2c..172f36128 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -523,7 +523,10 @@ public abstract class RegularLevel extends Level { type = Heap.Type.CHEST; break; default: - type = Heap.Type.HEAP; + + type = Dungeon.isDLC(Conducts.Conduct.MONEYLETGO) ? Heap.Type.FOR_SALE : Heap.Type.HEAP; + + break; } @@ -551,7 +554,7 @@ public abstract class RegularLevel extends Level { for (Item item : itemsToSpawn) { int cell = randomDropCell(); - drop( item, cell ).type = Heap.Type.HEAP; + drop( item, cell ).type = Dungeon.isDLC(Conducts.Conduct.MONEYLETGO) ? Heap.Type.FOR_SALE : Heap.Type.HEAP; if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { map[cell] = Terrain.GRASS; losBlocking[cell] = false; @@ -581,7 +584,7 @@ public abstract class RegularLevel extends Level { if (rose.droppedPetals < 11) { item = new DriedRose.Petal(); int cell = randomDropCell(); - drop( item, cell ).type = Heap.Type.HEAP; + drop( item, cell ).type = Dungeon.isDLC(Conducts.Conduct.MONEYLETGO) ? Heap.Type.FOR_SALE : Heap.Type.HEAP; if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) { map[cell] = Terrain.GRASS; losBlocking[cell] = false; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SokobanLayouts.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SokobanLayouts.java new file mode 100644 index 000000000..eebf77f6e --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SokobanLayouts.java @@ -0,0 +1,245 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels; + +public class SokobanLayouts { + + //32X32 + private static final int W = Terrain.WALL; + private static final int T = Terrain.WATER; + private static final int Z = Terrain.HIGH_GRASS; + private static final int D = Terrain.DOOR; + private static final int L = Terrain.DOOR; + private static final int Q = Terrain.WATER; //for readability + + //private static final int T = Terrain.INACTIVE_TRAP; + + private static final int E = Terrain.EMPTY; + //private static final int X = Terrain.EXIT; + + private static final int M = Terrain.WALL_DECO; + //private static final int P = Terrain.PEDESTAL; + + private static final int A = Terrain.EMPTY; + private static final int X = Terrain.EMPTY; + private static final int C = Terrain.EMPTY; + private static final int B = Terrain.EMPTY; + private static final int H = Terrain.EMPTY; + private static final int I = Terrain.EMPTY; + private static final int F = Terrain.EMPTY; + private static final int U = Terrain.STATUE; + private static final int G = Terrain.EMPTY; + private static final int S = Terrain.SECRET_DOOR; + private static final int R = Terrain.EMPTY; + private static final int V = Terrain.EMPTY; + + public static final int[] SOKOBAN_INTRO_LEVEL = { + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, E, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, Q, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, U, A, U, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, S, W, W, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, U, F, U, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, C, Q, W, Q, C, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, U, U, Q, D, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, G, Q, Q, Q, G, Q, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, Q, Q, W, W, W, W, W, W, U, U, A, U, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, Q, Q, S, Q, Q, Q, Q, D, F, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, H, W, W, U, U, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, U, F, U, Q, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, U, F, A, Q, W, Q, Q, Q, Q, W, Q, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, Q, U, F, U, Q, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, U, U, X, U, W, Q, Q, Q, Q, W, Q, C, Q, Q, U, W, W, W, W, W, W, W, W, W, W, Q, U, F, U, Q, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, H, U, U, F, D, Q, Q, C, Q, W, Q, G, Q, Q, F, D, Q, Q, Q, Q, W, W, W, W, W, G, U, F, U, G, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, S, W, W, W, W, Q, Q, Q, Q, W, Q, Q, Q, Q, U, W, C, G, G, Q, W, W, W, W, W, C, U, H, U, C, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, F, W, W, W, W, Q, Q, Q, Q, D, Q, Q, Q, Q, Q, W, Q, Q, Q, Q, W, W, W, W, W, W, W, S, W, W, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, U, W, W, W, W, W, W, W, Q, W, W, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, S, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, U, F, W, W, W, W, W, W, W, Q, W, W, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, Q, B, Q, Q, Q, D, F, Q, Q, Q, D, Q, Q, Q, Q, W, W, W, W, W, W, D, W, W, W, W, W, W, W, Q, W, W, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, Q, Q, Q, W, U, U, U, Q, W, Q, Q, Q, Q, W, W, W, W, W, W, Q, W, W, W, W, W, W, Q, Q, Q, W, W, W, W, Q, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, R, Q, Q, W, B, B, Q, Q, W, Q, G, Q, Q, W, Q, Q, Q, Q, W, Q, H, W, W, W, W, W, Q, Q, B, W, Q, F, Q, A, I, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, Q, Q, Q, W, U, U, U, Q, W, Q, G, Q, Q, W, Q, Q, Q, Q, D, Q, W, W, W, W, W, W, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, Q, Q, Q, W, H, F, Q, Q, W, Q, G, Q, Q, W, Q, I, A, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, D, W, W, W, W, W, W, W, W, W, W, Q, C, Q, Q, W, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, Q, Q, Q, W, W, W, W, W, W, Q, Q, Q, Q, L, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, X, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, I, V, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, Q, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W + + }; + + public static final int[] SOKOBAN_CASTLE = { + W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, + W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,I,T,I,T,I,T,I,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W, + W,T,T,W,S,W,W,W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W,W,W,W,W,T,T,W, + W,T,T,W,R,U,Q,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,Q,F,H,W,T,T,W, + W,T,T,W,U,U,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,F,F,W,T,T,W, + W,T,T,W,Q,Q,Q,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,Q,Q,Q,W,T,T,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,W,W,W,W,M,W,W,H,W,H,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,Q,W,W,T,T,W, + W,T,T,W,W,Q,W,W,W,W,G,Q,W,F,G,C,F,Q,Q,F,Q,B,W,F,W,F,W,F,F,H,F,H,F,F,F,F,W,Q,Q,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,H,Q,S,F,F,X,F,Q,C,U,Q,Q,W,Q,W,Q,W,F,F,F,F,F,F,F,F,F,S,Q,X,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,Q,Q,W,F,F,X,F,G,C,U,Q,Q,W,Q,W,Q,W,F,F,F,F,F,F,F,F,F,W,Q,Q,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,F,F,W,H,F,Q,F,G,H,U,Q,Q,W,Q,W,Q,W,Q,X,X,X,X,X,Q,Q,Q,W,F,F,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,W,W,L,W,W,W,W,Q,B,Q,M,W,W,W,D,W,W,W,W,S,W,W,S,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,Q,F,F,F,Q,W,W,Q,M,Q,M,W,H,F,U,F,H,W,W,W,W,W,Q,Q,Q,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,U,F,U,F,U,W,W,Q,M,Q,M,W,U,U,Q,U,U,W,W,W,W,W,U,Q,H,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,Q,X,G,X,Q,W,W,Q,M,Q,M,W,Q,G,Q,G,Q,W,W,W,W,W,S,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,Q,C,G,C,Q,W,W,Q,M,Q,M,W,C,G,Q,G,C,W,W,H,H,Q,Q,M,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,W,W,D,W,W,W,W,Q,M,Q,M,W,W,W,S,W,W,W,W,Q,Q,X,Q,M,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,U,U,U,C,L,Q,W,W,W,F,W,W,W,W,Q,M,Q,W,W,W,W,F,W,W,W,W,U,Q,U,U,M,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,H,F,G,Q,W,Q,W,W,W,F,W,W,W,W,Q,W,Q,W,W,W,W,F,W,W,W,W,Q,Q,Q,Q,M,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,U,U,U,B,W,Q,W,W,W,G,G,I,W,W,Q,W,Q,W,W,Q,G,F,W,W,W,W,Q,Q,Q,Q,M,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,Q,W,W,W,X,Q,C,W,W,G,W,G,W,W,C,A,G,W,W,W,W,Q,Q,Q,Q,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,Q,U,U,F,D,Q,W,W,W,Q,Q,C,Q,G,X,C,X,G,Q,Q,C,Q,W,W,W,W,Q,Q,Q,Q,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,I,C,Q,F,W,Q,W,W,W,W,W,W,W,W,C,E,C,W,W,W,W,W,W,Q,W,W,W,W,Q,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,G,X,Q,Q,W,X,Q,Q,Q,Q,Q,Q,Q,G,X,C,X,G,Q,Q,Q,Q,Q,X,Q,W,W,W,L,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,Q,U,U,Q,W,Q,W,W,M,W,W,M,W,W,G,W,G,W,W,W,W,W,W,W,Q,W,Q,Q,Q,Q,Q,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,Q,W,F,F,F,F,F,U,W,Q,W,Q,W,W,W,W,W,W,W,Q,W,U,U,Q,U,U,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,U,U,Q,Q,W,Q,W,F,F,F,F,F,U,W,Q,W,Q,W,W,W,W,W,W,W,Q,W,Q,G,X,G,I,S,S,Q,W,T,T,W,W, + W,Q,T,W,W,Q,W,R,L,F,F,X,Q,W,Q,W,F,F,H,F,F,U,W,Q,W,Q,W,W,W,W,W,Q,Q,Q,W,U,F,Q,F,U,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,H,U,G,G,D,Q,W,F,F,F,F,F,U,W,Q,W,Q,W,W,W,W,W,Q,Q,Q,Q,Q,Q,X,Q,Q,W,W,Q,W,T,T,W,M, + W,T,T,W,W,Q,W,W,W,F,U,Q,C,W,Q,W,F,F,F,F,F,U,W,Q,W,Q,W,W,W,W,W,Q,Q,W,W,U,Q,X,Q,U,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,S,W,W,W,W,Q,W,Q,X,X,Q,Q,Q,W,Q,W,Q,W,W,W,W,W,Q,W,W,W,Q,Q,Q,Q,Q,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,A,W,W,W,W,D,W,W,W,W,L,W,W,W,Q,W,Q,W,W,H,S,I,Q,Q,W,W,W,W,W,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,G,W,W,W,W,Q,Q,Q,Q,Q,Q,Q,G,W,Q,W,Q,W,W,W,W,W,L,W,W,W,W,W,W,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,Q,Q,Q,W,W,W,Q,U,Q,U,Q,F,X,U,W,Q,W,Q,W,W,W,W,U,Q,U,S,Q,W,W,W,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,U,F,U,W,W,W,Q,Q,Q,Q,Q,Q,X,G,W,Q,W,Q,W,W,W,W,Q,X,Q,W,Q,Q,Q,Q,Q,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,I,H,C,W,W,W,Q,U,Q,U,Q,U,Q,U,W,Q,W,Q,W,W,W,W,Q,Q,Q,W,W,W,Q,R,Q,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,Q,U,Q,U,Q,U,Q,U,W,Q,B,Q,W,W,W,W,X,X,X,W,W,W,Q,Q,Q,W,W,W,Q,W,T,T,W,M, + W,T,T,W,W,Q,W,W,Q,Q,Q,W,W,W,Q,Q,X,Q,Q,Q,Q,B,W,Q,W,Q,W,W,W,W,Q,Q,Q,W,W,W,W,W,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,Q,Q,Q,W,W,W,Q,U,Q,U,Q,U,F,U,W,Q,W,Q,W,W,W,W,Q,X,Q,Q,Q,Q,Q,Q,Q,Q,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,X,X,X,W,W,W,Q,U,Q,U,F,U,F,U,W,Q,W,Q,W,W,W,W,Q,Q,Q,W,W,W,W,W,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,I,H,I,W,W,W,Q,Q,C,G,F,F,H,I,W,F,W,F,W,W,W,W,Q,H,V,W,W,W,W,W,W,W,W,W,Q,W,T,T,W,W, + W,T,T,W,W,Q,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,H,W,H,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,Q,W,W,T,W,W, + W,T,T,W,Q,Q,Q,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,Q,Q,Q,W,T,W,M, + W,T,Q,W,F,F,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,F,F,W,T,W,W, + W,T,T,W,H,F,Q,W,M,W,W,W,W,M,W,W,W,W,W,W,W,W,W,W,M,W,W,W,W,W,W,W,W,M,W,W,W,W,W,W,W,Q,F,H,S,T,W,W, + W,T,T,W,W,W,W,W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W,W,W,W,W,T,W,W, + W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W,W, + W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W + }; + + + + + public static final int[] SOKOBAN_TELEPORT_LEVEL = { + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, R, Q, Q, W, W, W, W, W, W, W, W, H, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, F, H, H, F, Q, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, Q, X, H, W, W, W, W, W, W, W, W, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, F, F, F, F, Q, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, B, F, Q, W, W, W, W, W, W, W, W, G, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, X, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, C, R, S, Q, L, B, W, F, R, W, W, W, W, W, W, W, Q, R, W, W, W, W, W, W, W, Q, Q, Q, W, W, W, W, W, + W, W, I, F, R, W, W, W, W, F, H, F, W, W, W, W, W, W, W, W, W, W, F, F, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, A, X, Q, W, W, W, W, W, + W, W, Q, F, F, W, W, W, W, F, F, F, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, F, F, F, Q, W, W, W, W, W, + W, W, Q, Q, Q, W, W, W, W, Q, X, Q, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, R, W, W, W, W, W, W, W, W, W, W, W, W, W, F, F, F, R, W, W, W, W, W, + W, W, Q, Q, H, W, W, W, W, Q, R, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, H, F, W, W, W, W, W, W, W, + W, W, R, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, C, G, G, G, G, F, F, F, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, Q, X, A, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, V, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, Q, X, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, F, W, W, Q, Q, Q, Q, W, W, Q, Q, Q, I, W, W, W, W, + W, W, W, W, W, W, W, Q, E, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, C, W, Q, V, X, Q, W, W, Q, X, V, Q, W, W, W, W, + W, W, Q, R, W, W, W, Q, R, X, Q, W, W, W, W, W, Q, R, Q, W, W, W, W, W, W, W, W, W, W, W, W, G, W, W, Q, Q, Q, R, W, W, R, Q, Q, Q, W, W, W, W, + W, W, Q, X, W, W, W, Q, Q, I, Q, W, W, W, W, W, Q, X, Q, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, C, G, W, W, W, Q, Q, Q, Q, W, W, W, W, W, F, F, F, W, W, W, W, H, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, C, G, W, W, W, W, W, W, W, W, W, W, W, W, Q, H, Q, W, W, W, W, S, W, W, W, W, W, W, W, Q, W, W, Q, Q, Q, R, W, W, R, Q, Q, Q, W, W, W, W, + W, W, C, G, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, R, Q, U, F, W, W, W, W, W, W, Q, W, W, Q, V, X, Q, W, W, Q, X, V, Q, W, W, W, W, + W, W, U, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, A, R, W, W, W, W, W, Q, W, W, I, Q, Q, Q, W, W, Q, Q, Q, H, W, W, W, W, + W, W, U, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, U, F, W, W, W, W, W, W, W, W, W, Q, C, R, W, W, W, W, W, Q, Q, Q, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, U, Q, Q, Q, Q, Q, W, Q, Q, W, W, Q, X, Q, W, W, W, W, W, Q, Q, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, U, Q, U, Q, Q, Q, L, Q, H, W, W, G, G, G, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, U, I, U, I, Q, Q, W, Q, Q, W, W, Q, Q, I, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, W, W, W, W, W, W, W, W, W, W, H, Q, Q, Q, Q, F, F, F, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, R, H, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, I, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, Q, U, Q, Q, Q, U, Q, U, Q, Q, U, Q, U, Q, Q, Q, Q, Q, Q, U, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, U, Q, U, Q, Q, U, Q, U, Q, Q, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, Q, U, Q, U, U, U, Q, U, F, F, U, Q, U, U, U, Q, Q, Q, Q, U, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, F, F, F, F, F, F, F, F, F, F, F, F, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, W, W, W, W, W, W, W, W, W, W, Q, U, G, U, F, Q, Q, Q, Q, Q, Q, Q, Q, F, U, G, Q, Q, Q, U, I, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, Q, F, F, F, Q, W, W, W, W, W, W, W, W, Q, Q, G, F, Q, Q, X, Q, X, X, Q, X, Q, Q, F, G, Q, Q, Q, Q, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, W, W, W, W, W, W, W, W, Q, U, G, U, F, V, Q, V, Q, Q, V, Q, V, F, U, G, Q, Q, Q, U, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, H, Q, Q, W, W, W, W, W, W, W, W, Q, Q, Q, F, F, Q, Q, Q, Q, Q, Q, Q, Q, F, F, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, U, Q, U, U, U, U, U, U, U, U, U, U, U, U, Q, Q, Q, Q, U, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, Q, Q, X, Q, Q, X, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, I, U, Q, Q, Q, Q, Q, X, Q, Q, X, Q, Q, Q, Q, Q, Q, Q, Q, U, I, W, W, + W, W, W, Q, Q, H, I, H, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, V, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, F, F, F, F, F, F, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, U, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, U, Q, W, W, + W, W, W, F, F, F, F, F, F, F, W, W, W, W, W, W, W, W, W, H, Q, W, W, W, W, U, U, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, W, W, + W, W, W, Q, X, X, R, C, Q, Q, W, W, W, W, W, W, W, W, W, H, Q, Q, Q, R, S, Q, U, Q, U, Q, U, Q, U, Q, U, Q, U, Q, U, Q, U, Q, U, Q, U, Q, W, W, + W, W, W, Q, Q, G, G, G, I, W, W, W, W, W, W, W, W, W, W, H, Q, W, W, W, W, H, U, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, H, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W + + + }; + + public static final int[] SOKOBAN_PUZZLE_LEVEL = { + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, R, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, Q, Q, Q, Q, U, S, R, W, W, W, Q, A, Q, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, C, C, U, H, U, C, C, W, W, W, W, W, W, W, W, W, W, W, Q, Q, H, H, Q, Q, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, G, G, U, F, U, G, G, W, W, W, W, W, W, W, W, W, W, W, Q, Q, H, H, Q, Q, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, Q, Q, S, Q, G, G, U, F, U, G, G, V, S, Q, Q, U, W, W, W, W, W, W, U, Q, Q, Q, Q, U, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, G, U, W, W, C, I, U, F, U, I, C, W, W, W, W, G, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, V, W, W, G, G, U, F, U, G, G, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, Q, W, W, C, Q, U, F, U, Q, C, W, W, W, W, G, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, Q, S, R, G, G, U, F, U, G, G, V, S, Q, Q, U, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, A, E, A, Q, I, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, I, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, U, G, C, U, C, G, U, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, U, H, U, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, H, Q, Q, Q, W, B, Q, Q, Q, B, W, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, F, F, F, F, W, G, G, Q, G, G, W, Q, Q, F, F, W, W, W, W, W, W, W, Q, Q, R, W, W, W, Q, Q, U, Q, H, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, H, Q, Q, Q, S, Q, Q, G, Q, Q, S, Q, G, F, H, W, W, W, W, W, W, W, Q, H, Q, W, W, W, Q, Q, Q, Q, H, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, F, F, F, F, W, Q, F, F, F, Q, W, Q, Q, F, F, W, W, W, W, W, W, W, Q, Q, Q, W, W, W, Q, Q, U, Q, H, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, H, Q, Q, Q, W, Q, F, H, F, Q, W, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, R, Q, Q, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, Q, C, G, C, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, X, G, X, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, F, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, C, C, C, C, C, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, I, Q, G, G, G, G, G, Q, I, W, W, W, W, W, W, W, W, W, W, W, W, W, F, F, H, H, Q, L, Q, W, W, W, W, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, Q, Q, U, U, U, U, U, Q, Q, W, W, W, W, W, W, W, W, W, Q, H, Q, W, F, U, U, U, U, W, T, W, W, W, W, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, C, G, U, F, Q, Q, Q, F, U, G, C, W, W, W, W, W, W, W, W, Q, Q, Q, W, A, X, B, I, Q, W, T, W, W, W, Q, Q, W, W, W, + W, W, W, W, W, W, W, W, W, W, C, G, U, Q, F, F, F, Q, U, G, C, W, W, W, W, W, W, W, W, Q, Q, Q, W, Q, Q, Q, Q, Q, W, T, W, W, W, U, A, W, W, W, + W, W, W, W, W, W, W, W, W, W, C, G, U, Q, U, F, U, Q, U, G, C, W, W, W, W, W, W, W, W, W, Q, W, W, Q, Q, Q, Q, Q, W, T, W, W, W, T, T, W, W, W, + W, W, W, W, W, W, W, W, W, W, C, G, U, Q, U, F, U, Q, U, G, C, W, W, W, W, W, W, W, W, W, Q, W, W, L, W, W, W, W, W, T, W, W, W, T, F, W, W, W, + W, W, W, W, W, W, W, W, W, W, C, G, U, F, U, H, U, F, U, G, C, W, W, W, W, W, W, W, Q, Q, Q, Q, A, F, F, Q, W, W, W, T, W, W, W, T, F, R, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, F, U, U, U, U, U, F, W, W, W, W, W, W, W, W, W, G, W, W, W, W, W, W, Q, W, W, W, T, W, W, W, T, F, W, W, W, + W, W, W, W, W, W, W, W, W, H, F, S, Q, B, Q, B, Q, B, Q, S, F, H, W, W, W, W, W, Q, Q, W, W, W, W, W, W, Q, W, W, W, T, W, W, W, T, T, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, L, W, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, Q, W, W, W, T, W, W, W, T, T, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, G, V, W, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, Q, W, W, W, T, T, T, T, T, T, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, B, G, G, G, G, G, F, F, Q, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, C, C, G, C, C, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, Q, Q, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, U, U, G, U, U, W, W, W, W, W, Q, Q, R, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, C, C, Q, C, C, W, W, W, W, W, X, Q, Q, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, U, G, Q, G, U, W, W, W, W, W, F, Q, Q, W, W, I, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, B, C, Q, C, Q, W, W, W, W, W, W, W, W, W, W, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, U, U, Q, U, U, W, W, W, W, Q, Q, Q, W, W, W, G, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, B, F, F, F, F, F, F, F, L, Q, B, Q, F, H, D, C, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, Q, Q, Q, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, + }; + + +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TreasuryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TreasuryRoom.java index 2a5543c56..8686be527 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TreasuryRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TreasuryRoom.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; +import com.shatteredpixel.shatteredpixeldungeon.Conducts; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic; import com.shatteredpixel.shatteredpixeldungeon.items.Gold; @@ -40,7 +41,7 @@ public class TreasuryRoom extends SpecialRoom { Painter.set( level, center(), Terrain.STATUE ); - Heap.Type heapType = Random.Int( 2 ) == 0 ? Heap.Type.CHEST : Heap.Type.HEAP; + Heap.Type heapType = Random.Int( 2 ) == 0 ? Heap.Type.CHEST : Dungeon.isDLC(Conducts.Conduct.MONEYLETGO) ? Heap.Type.FOR_SALE : Heap.Type.HEAP; int n = Random.IntRange( 2, 3 ); for (int i=0; i < n; i++) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index 848de8301..7d875efeb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes; import static com.shatteredpixel.shatteredpixeldungeon.Challenges.SBSG; import static com.shatteredpixel.shatteredpixeldungeon.Statistics.lanterfireactive; +import com.badlogic.gdx.Gdx; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.BGMPlayer; import com.shatteredpixel.shatteredpixeldungeon.Badges; @@ -162,7 +163,7 @@ import java.util.ArrayList; import java.util.Locale; public class GameScene extends PixelScene { - + public static boolean logActorThread; private void tell(String text) { Game.runOnRenderThread(new Callback() { @Override @@ -592,7 +593,9 @@ public class GameScene extends PixelScene { if (InterlevelScene.mode != InterlevelScene.Mode.NONE) { if (Dungeon.depth == Statistics.deepestFloor && (InterlevelScene.mode == InterlevelScene.Mode.DESCEND || InterlevelScene.mode == InterlevelScene.Mode.FALL)) { - if(Dungeon.depth < 0) { + if(Dungeon.depth == -30) { + GLog.h(Messages.get(this, "ancity"), Dungeon.depth); + } else if (Dungeon.depth == -15) { GLog.h(Messages.get(this, "snowcynon"), Dungeon.depth); } else { GLog.h(Messages.get(this, "descend"), Dungeon.depth); @@ -641,7 +644,9 @@ public class GameScene extends PixelScene { } else if (InterlevelScene.mode == InterlevelScene.Mode.RESURRECT) { GLog.h(Messages.get(this, "resurrect"), Dungeon.depth); } else { - if(Dungeon.depth < 0) { + if(Dungeon.depth == -31) { + GLog.h(Messages.get(this, "ancity"), Dungeon.depth); + } else if (Dungeon.depth == -15) { GLog.h(Messages.get(this, "snowcynon"), Dungeon.depth); } else { GLog.h(Messages.get(this, "return"), Dungeon.depth); @@ -795,6 +800,27 @@ public class GameScene extends PixelScene { public synchronized void update() { lastOffset = null; + if (logActorThread){ + if (actorThread != null){ + logActorThread = false; + String s = ""; + for (StackTraceElement t: + actorThread.getStackTrace()){ + s += "\n"; + s += t.toString(); + } + Class cl = + Actor.getCurrentActorClass(); + String msg = "Actor therad dump was requested." + "Seed:" + Dungeon.seed + + "depth:" + Dungeon.depth + "challenges:" + "current actor:" + cl + + "\ntrace:" + s; + Gdx.app.getClipboard().setContents(msg); + ShatteredPixelDungeon.reportException(new RuntimeException(msg) + ); + add(new WndMessage(Messages.get(this,"copied"))); + } + } + if (updateItemDisplays){ updateItemDisplays = false; QuickSlotButton.refresh(); @@ -1438,12 +1464,15 @@ public class GameScene extends PixelScene { scene.showBanner( bossSlain ); } break; - case 0: - if(Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ) { - bossSlain.texture(Assets.Interfaces.SakaBJY_Title); + case 5: + bossSlain.texture(Assets.Interfaces.QliPhoth_Title); bossSlain.show( Window.CYELLOW, 0.3f, 5f); scene.showBanner(bossSlain); - } + break; + case -31: + bossSlain.texture(Assets.Interfaces.SakaBJY_Title); + bossSlain.show( Window.CYELLOW, 0.3f, 5f); + scene.showBanner(bossSlain); break; } @@ -1472,12 +1501,15 @@ public class GameScene extends PixelScene { scene.showBanner( bossSlain ); } break; - case 0: - if(Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ) { - bossSlain.texture(Assets.Interfaces.SakaBJY_Clear); + case 5: + bossSlain.texture(Assets.Interfaces.QliPhoth_Clear); bossSlain.show( Window.CYELLOW, 0.3f, 5f); scene.showBanner(bossSlain); - } + break; + case -31: + bossSlain.texture(Assets.Interfaces.SakaBJY_Clear); + bossSlain.show( Window.CYELLOW, 0.3f, 5f); + scene.showBanner(bossSlain); break; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java index 19f50b1e8..557072f48 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java @@ -286,7 +286,7 @@ public class InterlevelScene extends PixelScene { exboss(2); break; case ANCITYBOSS: - exboss(3); + exboss(4); break; } @@ -569,6 +569,9 @@ public class InterlevelScene extends PixelScene { case 3: level=Dungeon.AncityWaterLevel(); break; + case 4: + level=Dungeon.AncityBossWaterLevel(); + break; default: level = Dungeon.newLevel(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java index 7da7f8dd5..6e62efb43 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java @@ -181,7 +181,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip turnTo( ch.pos, Random.Int( Dungeon.level.length() ) ); renderShadow = true; - //突变激素 粒子效果 + //TODO: this is a hack to get the hero to show up in the right place if (ch != Dungeon.hero) { if (health == null) { health = new CharHealthIndicator(ch); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/IceSlowGirlSprites.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/IceSlowGirlSprites.java new file mode 100644 index 000000000..8725dcd2d --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/IceSlowGirlSprites.java @@ -0,0 +1,31 @@ +package com.shatteredpixel.shatteredpixeldungeon.sprites; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.watabou.noosa.TextureFilm; + +public class IceSlowGirlSprites extends MobSprite { + + public IceSlowGirlSprites() { + super(); + + texture( Assets.Sprites.SXGR ); + + TextureFilm frames = new TextureFilm( texture, 24, 24 ); + + idle = new Animation( 2, true ); + idle.frames( frames, 0, 1, 0, 1,0,1 ); + + run = new Animation( 8, true ); + run.frames( frames, 2, 3, 4, 5 ); + + attack = new Animation( 15, false ); + attack.frames( frames, 6, 7, 8, 0 ); + + die = new Animation( 7, false ); + die.frames( frames, 9,10,11 ); + + play( idle ); + } + +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java index 9a17d28e8..b6d370722 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java @@ -822,6 +822,11 @@ public class ItemSpriteSheet { public static final int SOYBOOKS= MAINBOOKINDEX+14; + + private static final int EXFOODINDEX = xy(1, 38); //16 slots + public static final int FISHSKELETON= EXFOODINDEX+0; + public static final int FISHBONE= EXFOODINDEX+1; + private static final int MAINPALYBOOKS = xy(1, 40); public static final int MONEYBOOKS= MAINPALYBOOKS+1; public static final int PINKBOOKS= MAINPALYBOOKS+2; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/RoomStoneSprites.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/RoomStoneSprites.java index 9b6619228..a2f8f2da3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/RoomStoneSprites.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/RoomStoneSprites.java @@ -3,30 +3,69 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.watabou.noosa.MovieClip; import com.watabou.noosa.TextureFilm; +import com.watabou.utils.Callback; +import com.watabou.utils.Random; public class RoomStoneSprites extends MobSprite { - + private Animation leap; + private boolean alt = Random.Int(2) == 0; + private Animation stab; + private Animation prep; public RoomStoneSprites() { super(); texture( Assets.Sprites.ROOMSTONE); - TextureFilm frames = new TextureFilm( texture, 18, 20 ); + TextureFilm frames = new TextureFilm( texture, 20, 18 ); idle = new MovieClip.Animation( 2, true ); idle.frames( frames, 0, 0, 0, 1 ); run = new MovieClip.Animation( 10, true ); - run.frames( frames, 6, 7, 8, 9, 10 ); + run.frames( frames, 2,3 ); attack = new MovieClip.Animation( 15, false ); - attack.frames( frames, 2, 3, 4, 5, 0 ); + attack.frames( frames, 2, 3 ); die = new MovieClip.Animation( 10, false ); - die.frames( frames, 11, 12, 13, 14 ); + die.frames( frames, 4,5,6); + + leap = new Animation( 1, true ); + leap.frames( frames, 7 ); + + stab = new Animation( 12, false ); + stab.frames( frames, 0, 9, 8, 9 ); + + prep = new Animation( 1, true ); + prep.frames( frames, 9 ); play( idle ); } + public void leapPrep( int cell ){ + turnTo( ch.pos, cell ); + play( prep ); + } + + @Override + public void jump(int from, int to, Callback callback) { + super.jump(from, to, callback); + play( leap ); + } + + @Override + public void attack( int cell ) { + super.attack( cell ); + if (alt) { + play( stab ); + } + alt = !alt; + } + + @Override + public void onComplete( Animation anim ) { + super.onComplete( anim == stab ? attack : anim ); + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SakaFishBossSprites.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SakaFishBossSprites.java index c8aa73f12..45f510ded 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SakaFishBossSprites.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SakaFishBossSprites.java @@ -40,7 +40,7 @@ public class SakaFishBossSprites extends MobSprite { zap = attack.clone(); die = new Animation( 10, false ); - die.frames( frames, 1 ); + die.frames( frames, 23,24,25,26 ); leap = new Animation( 2, true ); leap.frames( frames, 52,53,54,55 ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SeaVastGirlSprites.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SeaVastGirlSprites.java index 13f8c910d..5fdee30f4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SeaVastGirlSprites.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SeaVastGirlSprites.java @@ -21,8 +21,8 @@ public class SeaVastGirlSprites extends MobSprite { attack = new Animation( 15, false ); attack.frames( frames, 7, 8, 9, 0 ); - die = new Animation( 10, false ); - die.frames( frames, 0 ); + die = new Animation( 7, false ); + die.frames( frames, 10,11,12); play( idle ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java index e1adee548..00f9b961d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java @@ -1,24 +1,3 @@ -/* - * Pixel Dungeon - * Copyright (C) 2012-2015 Oleg Dolya - * - * Shattered Pixel Dungeon - * Copyright (C) 2014-2022 Evan Debenham - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - package com.shatteredpixel.shatteredpixeldungeon.sprites; import com.shatteredpixel.shatteredpixeldungeon.Assets; @@ -27,28 +6,28 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Splash; import com.watabou.noosa.TextureFilm; public class YogSprite extends MobSprite { - + public YogSprite() { super(); perspectiveRaise = 5 / 16f; texture( Assets.Sprites.YOG ); - + TextureFilm frames = new TextureFilm( texture, 20, 19 ); - + idle = new Animation( 10, true ); idle.frames( frames, 0, 1, 2, 2, 1, 0, 3, 4, 4, 3, 0, 5, 6, 6, 5 ); - + run = new Animation( 12, true ); run.frames( frames, 0 ); - + attack = new Animation( 12, false ); attack.frames( frames, 0 ); - + die = new Animation( 10, false ); die.frames( frames, 0, 7, 8, 9 ); - + play( idle ); } @@ -61,7 +40,7 @@ public class YogSprite extends MobSprite { @Override public void die() { super.die(); - + Splash.at( center(), blood(), 12 ); } -} +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java index 5a9894a6a..5c8ad11c1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java @@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.NyzSprites; import com.shatteredpixel.shatteredpixeldungeon.sprites.OGPDNQHZTT; import com.shatteredpixel.shatteredpixeldungeon.sprites.RedSwarmSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.SRPDHBLRTT; +import com.shatteredpixel.shatteredpixeldungeon.sprites.SakaFishBossSprites; import com.shatteredpixel.shatteredpixeldungeon.sprites.SalamanderSprites; import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkKingSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkeeperSprite; @@ -55,6 +56,7 @@ import java.util.ArrayList; public class vM0_6_7_X_Changes { public static void addAllChanges(ArrayList changeInfos) { + add_v0_6_55_Changes(changeInfos); add_v0_6_54_Changes(changeInfos); add_v0_6_53_Changes(changeInfos); add_v0_6_52_Changes(changeInfos); @@ -112,6 +114,38 @@ public class vM0_6_7_X_Changes { add_v0_6_0_Changes(changeInfos); } + public static void add_v0_6_55_Changes( ArrayList changeInfos ) { + ChangeInfo changes = new ChangeInfo("v0.6.4.0-Beta2-3", true, ""); + changes.hardlight(Window.TITLE_COLOR); + changeInfos.add(changes); + + changes = new ChangeInfo("新内容", false, null); + changes.hardlight(Window.GREEN_COLOR); + changeInfos.add(changes); + + changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.LANTERNB), ("深度调查"), + ("娱乐模式改名为深度调查,并且追加黄金时代新娱乐模式。"))); + + Image a = new SakaFishBossSprites(); + a.scale.set(PixelScene.align(0.72f)); + changes.addButton(new ChangeButton(a, "新Boss:萨卡班甲鱼", + "远古遗迹的领袖级Boss")); + + changes = new ChangeInfo("改动", false, null); + changes.hardlight(Window.CYELLOW); + changeInfos.add(changes); + + changes.addButton(new ChangeButton(Icons.get(Icons.CHALLENGE_ON), ("支离破碎"), + ("支离破碎进行了一些怪组优化"))); + + changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.GREATSHIELD), ("5阶武器"), + ("现在5阶武器生成平均化"))); + + changes.addButton(new ChangeButton(new Image("sprites/spinner.png", 144, 0, 16, 16), + Messages.get(ChangesScene.class, "bugfixes"), Messages.get(vM0_6_7_X_Changes.class, "bug_06X82"))); + + } + public static void add_v0_6_54_Changes( ArrayList changeInfos ) { ChangeInfo changes = new ChangeInfo("v0.6.4.0-Beta1", true, ""); changes.hardlight(Window.TITLE_COLOR); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGame.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGame.java index 8aacca2fb..5e677b5fb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGame.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGame.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.windows; +import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.GamesInProgress; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; @@ -34,6 +35,8 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.Icons; import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton; import com.shatteredpixel.shatteredpixeldungeon.ui.Window; import com.watabou.noosa.Game; +import com.watabou.noosa.Image; +import com.watabou.utils.DeviceCompat; import java.io.IOException; @@ -96,6 +99,19 @@ public class WndGame extends Window { curBtn.icon(Icons.get(Icons.RANKINGS)); } + //玩家未准备好以及为DEBUG模式 + if(!Dungeon.hero.ready && DeviceCompat.isDebug()){ + addButton(curBtn = new + RedButton("DEBUG"){ + @Override + protected void onClick() { + GameScene.logActorThread = true; + } + }); + curBtn.icon(new + Image(Assets.Sprites.SPINNER,144,0,16,16)); + } + // Main menu addButton(curBtn = new RedButton( Messages.get(this, "menu") ) { @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGoShop.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGoShop.java index 07c476d80..595a9bae4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGoShop.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndGoShop.java @@ -62,7 +62,8 @@ public class WndGoShop extends Window { } } }; - btnBuy.setRect( (WIDTH - BTN_GAP) / 2 - BTN_SIZE, message.top() + message.height() + BTN_GAP, BTN_SIZE, BTN_SIZE ); + btnBuy.setRect( (WIDTH - BTN_GAP) / 2f - BTN_SIZE, message.top() + message.height() + BTN_GAP, BTN_SIZE, + BTN_SIZE ); btnBuy.textColor(Window.ANSDO_COLOR); add( btnBuy );