Update-V0.4.6.0-Beta2.0
|
@ -79,7 +79,6 @@ public class AndroidGame extends AndroidApplication {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FileUtils.setDefaultFileProperties(Files.FileType.Local, "");
|
FileUtils.setDefaultFileProperties(Files.FileType.Local, "");
|
||||||
|
|
||||||
// grab preferences directly using our instance first
|
// grab preferences directly using our instance first
|
||||||
|
|
|
@ -18,8 +18,8 @@ allprojects {
|
||||||
appName = 'Magic Ling Pixel Dungeon'
|
appName = 'Magic Ling Pixel Dungeon'
|
||||||
appPackageName = 'com.ansdomagiclingpixeldungeon.ling'
|
appPackageName = 'com.ansdomagiclingpixeldungeon.ling'
|
||||||
|
|
||||||
appVersionCode =900927
|
appVersionCode =901000
|
||||||
appVersionName = '0.6.3.0-Beta5.2'
|
appVersionName = '0.6.4.0-Beta1'
|
||||||
|
|
||||||
appJavaCompatibility = JavaVersion.VERSION_11
|
appJavaCompatibility = JavaVersion.VERSION_11
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
BIN
core/src/main/assets/interfaces/bosslogo/sakabjy-clear.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
core/src/main/assets/interfaces/bosslogo/sakabjy-title.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
|
@ -1,8 +1,31 @@
|
||||||
#####MLPD-P3文本
|
#####MLPD-P3文本
|
||||||
|
|
||||||
actors.mobs.bosses.sakafishboss.name=”远古意志“\n萨卡班甲鱼
|
actors.mobs.bosses.sakafishboss.name=萨卡班甲鱼
|
||||||
actors.mobs.bosses.sakafishboss.desc=曾经远古时代的海洋王者,因为不可避免的末日来临时,潜入了地底的阴暗水潭进入了沉睡。想着有朝一日回到大海,然而地牢的魔力和陆上的变化,它再也不可能回到那片理想的海洋。
|
actors.mobs.bosses.sakafishboss.desc=曾经远古时代的海洋王者,因为不可避免的末日来临时,潜入了地底的阴暗水潭进入了沉睡。想着有朝一日回到大海,然而地牢的魔力和陆上的变化,它再也不可能回到那片理想的海洋。
|
||||||
|
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.npcs.nxhy.talk=交谈
|
||||||
|
actors.mobs.npcs.nxhy.buyback=回忆很爽快的退还了相应的商品。
|
||||||
|
|
||||||
|
actors.mobs.npcs.nxhy.talk_prison_intro=冒险者,欢迎来到这个危机四伏的地牢。
|
||||||
|
actors.mobs.npcs.nxhy.talk_prison_warrior=蕾零安洁,你也是前往这里寻找水晶之心的吗?哦,嗯,我知道,地表三巨头的行动我可是了如指掌的,但本人已经不想参与这些事情,现在,我还是当个商人最好吧。
|
||||||
|
actors.mobs.npcs.nxhy.talk_prison_mage=茉莉姐,我知道你来到这里的目的不是寻找那个东西,而是听到了来自深渊的求救。但我能告诉你的事,别去参和他们的事情,这里毕竟不是你的家,你的力量无法完全展露的。
|
||||||
|
actors.mobs.npcs.nxhy.talk_prison_rogue=哦,这不是人人歌颂的皇家盗贼吗?你打算在我这里偷点东西吗?哈哈哈,骗你的,事实上,我很敬佩你,为了穷人,你不惜舍去皇室血脉也要和穷人一起同甘共苦。你的父王可能早就知道了,不信的话,你的斗篷已经被他秘密改造了,什么,你还不知道?哈哈哈,我为什么知道,这是秘密哦!
|
||||||
|
actors.mobs.npcs.nxhy.talk_prison_huntress=我曾经和小姐一样也是一位侠客,只不过瞬时变迁,我现在已经不再追求这些。小姐,你知道自从你走后你的部族就发生……,哎呀,别拿弓指着我,我不说就是了。还是希望小姐能在地牢中试炼中找到自己的目标吧。
|
||||||
|
actors.mobs.npcs.nxhy.talk_caves=这里的矿洞常年都是这么的冷,但曾经并不是这样。曾经有一位蓝发少女在我这里留了一本书,此后矿洞就变得如此寒冷,但那位少女再也找不到人影……
|
||||||
|
actors.mobs.npcs.nxhy.talk_city=矮人都市是我最后给你的物资中转站,再往下,已经不是我可以涉及的区域,曾经这里也是一片繁华,但是那场事变后,一切都变了……
|
||||||
|
|
||||||
|
actors.mobs.npcs.nxhy.guards=看来你需要更加艰难的试炼了。
|
||||||
|
actors.mobs.npcs.nxhy.thief=看来你需要更加艰难的试炼了。
|
||||||
|
actors.mobs.npcs.nxhy.why=抢劫商店?你可真有趣!
|
||||||
|
|
||||||
|
actors.mobs.npcs.nxhy.sell=选择一件要出售的物品
|
||||||
|
actors.mobs.npcs.nxhy.name=那些回忆
|
||||||
|
actors.mobs.npcs.nxhy.desc=这是一个拥有很多东西的商人,他的名字叫那些回忆。据说他知道300年前这地牢究竟发生了什么事情的,他在这里等着每一位冒险者的前来。他会给予冒险者相应的补给,但是他从来不告诉冒险者这个地牢的危险程度是多么的高。传言说,他曾经是一个侠客,只不过现在他已经成为了一个商人了。
|
||||||
|
actors.mobs.npcs.nxhy.greetings=你好,%s。欢迎来到我的大商店。
|
||||||
|
|
||||||
actors.hero.hero.heartdied=死亡不是终点,而是新的开始。
|
actors.hero.hero.heartdied=死亡不是终点,而是新的开始。
|
||||||
|
|
||||||
|
@ -705,15 +728,6 @@ actors.mobs.npcs.slyl.def_verb=风暴将临
|
||||||
actors.mobs.npcs.slyl.desc=_冷群_是一位掌握冰系力量的魔女,是300年前_寒冰圣都_的管理者。\n由于地下异常的不断出现,她来到这里调查异常的原因。\n看起来她似乎正在摸鱼。
|
actors.mobs.npcs.slyl.desc=_冷群_是一位掌握冰系力量的魔女,是300年前_寒冰圣都_的管理者。\n由于地下异常的不断出现,她来到这里调查异常的原因。\n看起来她似乎正在摸鱼。
|
||||||
actors.mobs.npcs.slyl.howuse=你好,我是冷群。\n\n欢迎使用我们_寒冰圣都_的可以扰乱_魔力流_的_魔法金币_,通过它我们可以看见_特定的首领_。\n\n其中_抛动一次_会出现_天痕粘咕(5层),天狗(10层),DM300(15层),矮人国王(20层),Yog(25层)_\n]抛动两次]是_史莱姆王(5层),钻石宝箱王(10层),DM720(15层),矮人将军(20层),Yog-Zot(25层)_\n[抛动三次[是_(15层 寒冰魔女)_(抛动三次次仅在_特定楼层显示_)\n\n同时,仅在Boss前一楼层显示,每一次的最后的一次抛动将会决定下一层Boss的生成。\n\n好的,以上就是_使用方法和介绍了_,祝你_地牢冒险愉快_。
|
actors.mobs.npcs.slyl.howuse=你好,我是冷群。\n\n欢迎使用我们_寒冰圣都_的可以扰乱_魔力流_的_魔法金币_,通过它我们可以看见_特定的首领_。\n\n其中_抛动一次_会出现_天痕粘咕(5层),天狗(10层),DM300(15层),矮人国王(20层),Yog(25层)_\n]抛动两次]是_史莱姆王(5层),钻石宝箱王(10层),DM720(15层),矮人将军(20层),Yog-Zot(25层)_\n[抛动三次[是_(15层 寒冰魔女)_(抛动三次次仅在_特定楼层显示_)\n\n同时,仅在Boss前一楼层显示,每一次的最后的一次抛动将会决定下一层Boss的生成。\n\n好的,以上就是_使用方法和介绍了_,祝你_地牢冒险愉快_。
|
||||||
|
|
||||||
actors.mobs.npcs.nxhy.guards=看来你需要更加艰难的试炼了。
|
|
||||||
actors.mobs.npcs.nxhy.thief=看来你需要更加艰难的试炼了。
|
|
||||||
actors.mobs.npcs.nxhy.why=抢劫商店?你可真有趣!
|
|
||||||
|
|
||||||
actors.mobs.npcs.nxhy.sell=选择一件要出售的物品
|
|
||||||
actors.mobs.npcs.nxhy.name=那些回忆
|
|
||||||
actors.mobs.npcs.nxhy.desc=这是一个拥有很多东西的商人,他的名字叫那些回忆。据说他知道300年前这地牢究竟发生了什么事情的,他在这里等着每一位冒险者的前来。他会给予冒险者相应的补给,但是他从来不告诉冒险者这个地牢的危险程度是多么的高。传言说,他曾经是一个侠客,只不过现在他已经成为了一个商人了。\n\n{ 请不要攻击他!!!否则他会让你痛不欲生!!! {
|
|
||||||
actors.mobs.npcs.nxhy.greetings=你好,%s。欢迎来到我的大商店。
|
|
||||||
|
|
||||||
actors.mobs.npcs.renshop.guards=看来你并不是好人。
|
actors.mobs.npcs.renshop.guards=看来你并不是好人。
|
||||||
actors.mobs.npcs.renshop.thief=看来你的命运多舛。
|
actors.mobs.npcs.renshop.thief=看来你的命运多舛。
|
||||||
actors.mobs.npcs.renshop.sell=选择一件要出售的物品
|
actors.mobs.npcs.renshop.sell=选择一件要出售的物品
|
||||||
|
@ -1750,6 +1764,7 @@ actors.mobs.npcs.impshopkeeper.name=野心勃勃的小恶魔
|
||||||
actors.mobs.npcs.impshopkeeper.greetings=你好,%s!
|
actors.mobs.npcs.impshopkeeper.greetings=你好,%s!
|
||||||
actors.mobs.npcs.impshopkeeper.thief=我以为我可以相信你!
|
actors.mobs.npcs.impshopkeeper.thief=我以为我可以相信你!
|
||||||
actors.mobs.npcs.impshopkeeper.desc=小恶魔是一种低等恶魔。它们既没有强大的力量也没有魔法天赋,但她们相当聪明而且善于交际,因此许多小恶魔喜欢生活在没有其他恶魔存在的地方。
|
actors.mobs.npcs.impshopkeeper.desc=小恶魔是一种低等恶魔。它们既没有强大的力量也没有魔法天赋,但她们相当聪明而且善于交际,因此许多小恶魔喜欢生活在没有其他恶魔存在的地方。
|
||||||
|
actors.mobs.npcs.impshopkeeper.buyback=小恶魔很爽快的退还了相应的商品。
|
||||||
|
|
||||||
actors.mobs.npcs.mirrorimage.name=镜像
|
actors.mobs.npcs.mirrorimage.name=镜像
|
||||||
actors.mobs.npcs.mirrorimage.desc=这个幻象和你非常相似,甚至还装备着你当前的武器和护甲。\n\n镜像会猎寻敌人,并用它们的镜像武器对其发动攻击。镜像武器的使用方式与特性和你手中的一样,但造成的伤害会低些。镜像出生的时候没有实体,但攻击后会显形。\n\n镜像有一定的攻击能力,但非常脆弱,受到伤害就会瞬间消散。
|
actors.mobs.npcs.mirrorimage.desc=这个幻象和你非常相似,甚至还装备着你当前的武器和护甲。\n\n镜像会猎寻敌人,并用它们的镜像武器对其发动攻击。镜像武器的使用方式与特性和你手中的一样,但造成的伤害会低些。镜像出生的时候没有实体,但攻击后会显形。\n\n镜像有一定的攻击能力,但非常脆弱,受到伤害就会瞬间消散。
|
||||||
|
@ -1792,6 +1807,17 @@ actors.mobs.npcs.shopkeeper.zcz=商人喊来了制裁者!
|
||||||
actors.mobs.npcs.shopkeeper.eye=商人喊来了真眼者!
|
actors.mobs.npcs.shopkeeper.eye=商人喊来了真眼者!
|
||||||
actors.mobs.npcs.shopkeeper.dead=商人为敌人们购买了精英系统,选好东西,迅速离开本层!!!
|
actors.mobs.npcs.shopkeeper.dead=商人为敌人们购买了精英系统,选好东西,迅速离开本层!!!
|
||||||
actors.mobs.npcs.shopkeeper.live=商人还为首领购买了精英系统,选好东西,迅速离开本层!!!
|
actors.mobs.npcs.shopkeeper.live=商人还为首领购买了精英系统,选好东西,迅速离开本层!!!
|
||||||
|
actors.mobs.npcs.shopkeeper.talk=交谈
|
||||||
|
actors.mobs.npcs.shopkeeper.buyback=店主不情不愿地退还了你的物品。
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_prison_intro=我这有你成功冒险所需的一切东西!
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_prison_warrior=你的那个纹章挺有意思的嘛,它们通常来讲都是一整个的。难不成你是一位蒙受了耻辱的英雄,还是别的什么人物?好啦,不管你做了些什么,都与我无关。我只对你的金币感兴趣。
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_prison_mage=嘻嘻,我想我在城里的什么地方有见过你的通缉令。在逃亡对吧?哦?你说你是无辜的,真的吗?行行行...放轻松,比起举报你,我还有更值得做的事情。但也许你应该消费消费以确保这一点?
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_prison_rogue=你是盗贼公会指派来清理这片区域的吗?不是?只是来交易?好吧,虽然你确实在这杀了些怪物,但也别指望我会给你打折。我已经交足了保护费,而你们几乎不能确保这里的安全。
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_prison_huntress=小姐,这似乎不是你该待的地方。狭窄的地牢走廊想来不如城镇大厅或者市郊森林那样宽敞,不是吗?嘿嘿,哦,请别在意我这碎嘴巴,为什么不买点东西呢?
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_prison_duelist=哇偶,这不是闯荡天下的大英雄嘛!如果你在尝试着拯救又一个小镇,那我只能说祝你好运了。毕竟这里的危机可比土匪帮派什么的糟糕多了。当然,我相信你会比任何人做得更棒,只是千万别死在我的店门口。
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_caves=花钱,你才能活得更久。\n\n哦,如果你看到那个巨魔铁匠,代我向他问好。顺便提醒这个笨蛋,他上周从我这买锤子的钱还没结清呢!
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_city=我的货可以保你平安。\n\n…另外,劳烦您别在这瞎晃悠。我花了很长很长时间才让这里的怪物离我远点,可不希望你把麻烦惹回来!
|
||||||
|
actors.mobs.npcs.shopkeeper.talk_halls=嘿,那边那位!我为狩猎恶魔的人提供特别优惠!\n\n哦还有,在下面可要当心!底下的恶魔可不在乎你有多勇敢。而且如果你挂掉了,你就没法回来花掉金币啦!(>ω^)\n\n那些恶魔都和我一样吗?嘿嘿,并不。我只是一个小小跟班儿,算不上战士,况且我还设法保全了心智呢。下面那些恶魔都比我猛得多,并且它们都遭到了...呃......的奴役,总之,你在下面当心点吧。
|
||||||
|
|
||||||
actors.mobs.npcs.wandmaker.name=老杖匠
|
actors.mobs.npcs.wandmaker.name=老杖匠
|
||||||
actors.mobs.npcs.wandmaker.intro_warrior=啊,能在这片压抑的地方遇见一位英雄可真是个惊喜!如果你愿意帮助我这个老人家脱离苦海的话,你可以帮忙做一个任务。
|
actors.mobs.npcs.wandmaker.intro_warrior=啊,能在这片压抑的地方遇见一位英雄可真是个惊喜!如果你愿意帮助我这个老人家脱离苦海的话,你可以帮忙做一个任务。
|
||||||
|
|
|
@ -2248,6 +2248,9 @@ items.heap.skeleton_desc=某个不幸的冒险者存在过的唯一证明。或
|
||||||
items.heap.remains=英雄遗骸
|
items.heap.remains=英雄遗骸
|
||||||
items.heap.remains_desc=你的某个先辈存在过的唯一证明。或许能找到点什么值钱的东西。
|
items.heap.remains_desc=你的某个先辈存在过的唯一证明。或许能找到点什么值钱的东西。
|
||||||
|
|
||||||
|
items.heap.wtomb=苍白之墓
|
||||||
|
items.heap.wtomb_desc=这个坟墓相对于其他的坟墓很不对劲,直觉告诉你不应该挖这里的东西。
|
||||||
|
|
||||||
items.honeypot.name=蜂蜜罐
|
items.honeypot.name=蜂蜜罐
|
||||||
items.honeypot.ac_shatter=击碎
|
items.honeypot.ac_shatter=击碎
|
||||||
items.honeypot.desc=这个巨型蜜罐只是薄薄地涂了一圈蜂蜜,作为替代里头住着一只巨型蜜蜂!这种大型蜜蜂一般只待在蜂巢里,也许罐子本身就是某种特殊陷阱屋?蜜蜂看起来对罐子很满意,当你看向它时它非常警惕地对你回以嗡鸣。
|
items.honeypot.desc=这个巨型蜜罐只是薄薄地涂了一圈蜂蜜,作为替代里头住着一只巨型蜜蜂!这种大型蜜蜂一般只待在蜂巢里,也许罐子本身就是某种特殊陷阱屋?蜜蜂看起来对罐子很满意,当你看向它时它非常警惕地对你回以嗡鸣。
|
||||||
|
|
|
@ -277,6 +277,13 @@ badges$badge.read_book_three.desc=一局累计阅读五本不同的书籍。
|
||||||
badges$badge.read_book_four.title=书籍博学家
|
badges$badge.read_book_four.title=书籍博学家
|
||||||
badges$badge.read_book_four.desc=一局累计阅读七本不同的书籍。
|
badges$badge.read_book_four.desc=一局累计阅读七本不同的书籍。
|
||||||
|
|
||||||
|
badges$badge.saka_died.title=远古生物档案调查员
|
||||||
|
badges$badge.saka_died.desc=击败栖息在阴暗水潭的神秘古生物
|
||||||
|
|
||||||
|
badges$badge.reset_day.title=重见天日?
|
||||||
|
badges$badge.reset_day.desc=携带神秘生物的遗物离开地牢,完成它未尽的心愿。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,7 @@ scenes.interlevelscene$mode.fall=跌落中…
|
||||||
scenes.interlevelscene$mode.reset=重置中…
|
scenes.interlevelscene$mode.reset=重置中…
|
||||||
scenes.interlevelscene$mode.exboss=你突然眼前一黑\n\n,随后便是守卫低沉的声音:\n\n将此人押送到雪凛峡谷处置。
|
scenes.interlevelscene$mode.exboss=你突然眼前一黑\n\n,随后便是守卫低沉的声音:\n\n将此人押送到雪凛峡谷处置。
|
||||||
scenes.interlevelscene$mode.frgirlboss=正在前往雪凛峡谷深处……
|
scenes.interlevelscene$mode.frgirlboss=正在前往雪凛峡谷深处……
|
||||||
|
scenes.interlevelscene$mode.ancityboss=正在前往远古遗迹深处……
|
||||||
scenes.interlevelscene.install=安装游戏
|
scenes.interlevelscene.install=安装游戏
|
||||||
scenes.interlevelscene.file_not_found=未能找到存档文件。如果重启后问题依旧存在, 那这个存档可能已经损坏。节哀顺变。
|
scenes.interlevelscene.file_not_found=未能找到存档文件。如果重启后问题依旧存在, 那这个存档可能已经损坏。节哀顺变。
|
||||||
scenes.interlevelscene.io_error=未能找到存档文件。如果重启后问题依旧存在, 那这个存档可能已经损坏。节哀顺变。
|
scenes.interlevelscene.io_error=未能找到存档文件。如果重启后问题依旧存在, 那这个存档可能已经损坏。节哀顺变。
|
||||||
|
|
|
@ -548,4 +548,6 @@ ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x79=-V0.6.3-Beta4.8\n1.修复一些
|
||||||
|
|
||||||
ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x80=1.修复灯火值不扣减的错误\n2.其他小错误修复
|
ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x80=1.修复灯火值不扣减的错误\n2.其他小错误修复
|
||||||
|
|
||||||
|
ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x81=1.优化灯火体验\n其他错误修复。
|
||||||
|
|
||||||
//ui.changelist.mlpd.vm0_5_x_changes.xxx//
|
//ui.changelist.mlpd.vm0_5_x_changes.xxx//
|
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 1.2 KiB |
BIN
core/src/main/assets/sprites/boss/DictFish.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
core/src/main/assets/sprites/boss/RoomStone.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.1 KiB |
|
@ -29,6 +29,9 @@ public class Assets {
|
||||||
public static final String BGM_5 = "music/Level5.ogg";
|
public static final String BGM_5 = "music/Level5.ogg";
|
||||||
public static final String BGM_0 = "music/Level0.ogg";
|
public static final String BGM_0 = "music/Level0.ogg";
|
||||||
public static final String SNOWCYON = "music/SnowCyon.ogg";
|
public static final String SNOWCYON = "music/SnowCyon.ogg";
|
||||||
|
|
||||||
|
public static final String SKBJY = "music/Boss-Saka.ogg";
|
||||||
|
|
||||||
public static final String TOWN = "music/town.ogg";
|
public static final String TOWN = "music/town.ogg";
|
||||||
public static final String BGM_BOSSA = "music/Boss1.ogg";
|
public static final String BGM_BOSSA = "music/Boss1.ogg";
|
||||||
public static final String BGM_BOSSB = "music/Boss2.ogg";
|
public static final String BGM_BOSSB = "music/Boss2.ogg";
|
||||||
|
@ -103,7 +106,8 @@ public class Assets {
|
||||||
public static final String QliPhoth_Title = "interfaces/bosslogo/qliphoth-title.png";
|
public static final String QliPhoth_Title = "interfaces/bosslogo/qliphoth-title.png";
|
||||||
public static final String QliPhoth_Clear = "interfaces/bosslogo/qliphoth-clear.png";
|
public static final String QliPhoth_Clear = "interfaces/bosslogo/qliphoth-clear.png";
|
||||||
|
|
||||||
|
public static final String SakaBJY_Title = "interfaces/bosslogo/sakabjy-title.png";
|
||||||
|
public static final String SakaBJY_Clear = "interfaces/bosslogo/sakabjy-clear.png";
|
||||||
|
|
||||||
public static final String ARCS_BG = "interfaces/arcs1.png";
|
public static final String ARCS_BG = "interfaces/arcs1.png";
|
||||||
public static final String ARCS_FG = "interfaces/arcs2.png";
|
public static final String ARCS_FG = "interfaces/arcs2.png";
|
||||||
|
@ -310,7 +314,9 @@ public class Assets {
|
||||||
|
|
||||||
//BOSS
|
//BOSS
|
||||||
public static final String FRDG = "sprites/boss/fireDragon.png";
|
public static final String FRDG = "sprites/boss/fireDragon.png";
|
||||||
|
public static final String DICT = "sprites/boss/DictFish.png";
|
||||||
|
|
||||||
|
public static final String ROOMSTONE = "sprites/boss/RoomStone.png";
|
||||||
public static final String VSGR = "sprites/boss/SeaVastGirl.png";
|
public static final String VSGR = "sprites/boss/SeaVastGirl.png";
|
||||||
|
|
||||||
public static final String SKFS = "sprites/boss/SakaFishBoss.png";
|
public static final String SKFS = "sprites/boss/SakaFishBoss.png";
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.watabou.utils.Callback;
|
||||||
public class BGMPlayer {
|
public class BGMPlayer {
|
||||||
|
|
||||||
|
|
||||||
|
//解决电脑端高质量ogg的闪退问题
|
||||||
public static void playBGM(String name, boolean loop) {
|
public static void playBGM(String name, boolean loop) {
|
||||||
Game.runOnRenderThread(new Callback() {
|
Game.runOnRenderThread(new Callback() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,7 +34,7 @@ public class BGMPlayer {
|
||||||
if (d == -1) {
|
if (d == -1) {
|
||||||
playBGM(Assets.SNOWCYON, true);
|
playBGM(Assets.SNOWCYON, true);
|
||||||
}else if (d == 0||d==27) {
|
}else if (d == 0||d==27) {
|
||||||
playBGM(Assets.SNOWCYON, true);
|
playBGM(Assets.SKBJY, true);
|
||||||
} else if (d > 0 && d <= 5) {
|
} else if (d > 0 && d <= 5) {
|
||||||
playBGM(Assets.BGM_1, true);
|
playBGM(Assets.BGM_1, true);
|
||||||
} else if (d > 5 && d <= 10) {
|
} else if (d > 5 && d <= 10) {
|
||||||
|
|
|
@ -209,7 +209,11 @@ public class Badges {
|
||||||
EXSG (135),
|
EXSG (135),
|
||||||
BRCLER (136),
|
BRCLER (136),
|
||||||
|
|
||||||
HIGH_SCORE_5 ( 137 );
|
HIGH_SCORE_5 ( 137 ),
|
||||||
|
|
||||||
|
SAKA_DIED ( 138 ),
|
||||||
|
|
||||||
|
RESET_DAY ( 139 );
|
||||||
|
|
||||||
public boolean meta;
|
public boolean meta;
|
||||||
|
|
||||||
|
|
|
@ -23,20 +23,19 @@ package com.shatteredpixel.shatteredpixeldungeon;
|
||||||
|
|
||||||
import static com.shatteredpixel.shatteredpixeldungeon.Challenges.PRO;
|
import static com.shatteredpixel.shatteredpixeldungeon.Challenges.PRO;
|
||||||
import static com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass.ROGUE;
|
import static com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass.ROGUE;
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.levels.LevelRules.createBossRushLevel;
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.levels.LevelRules.createStandardLevel;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Awareness;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ClearBleesdGoodBuff.BlessAnmy;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ClearBleesdGoodBuff.BlessAnmy;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LighS;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LighS;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicalSight;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicalSight;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MindVision;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MindVision;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RandomBuff;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RevealedArea;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RevealedArea;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.TestDwarfMasterLock;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk;
|
||||||
|
@ -59,34 +58,11 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
|
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagicTorch;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagicTorch;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.AncityLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CaveTwoBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesGirlDeadLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CityLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.ColdChestBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.DM920BossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.DeadEndLevel;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.DeadEndLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.DimandKingLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.DwarfMasterBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.ForestBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.HallsLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.ItemLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.LastLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.LinkLevel;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.LinkLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCityBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewHallsBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.SLMKingLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.SewerBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.SewerLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.ShopBossLevel;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.ShopBossLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.YogGodHardBossLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.ZeroLevel;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.SecretRoom;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.SecretRoom;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
@ -143,7 +119,28 @@ public class Dungeon {
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
//雪凛峡谷B
|
//远古副本
|
||||||
|
public static Level AncityWaterLevel(){
|
||||||
|
|
||||||
|
|
||||||
|
Dungeon.level = null;
|
||||||
|
Actor.clear();
|
||||||
|
|
||||||
|
depth = -20;
|
||||||
|
|
||||||
|
if (depth > Statistics.realdeepestFloor) {
|
||||||
|
Statistics.realdeepestFloor = depth;}
|
||||||
|
|
||||||
|
Level level;
|
||||||
|
level = new ShopBossLevel();
|
||||||
|
|
||||||
|
level.create();
|
||||||
|
|
||||||
|
Statistics.qualifiedForNoKilling = !bossLevel();
|
||||||
|
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
public static Level ColdFlowerCanyonDie(){
|
public static Level ColdFlowerCanyonDie(){
|
||||||
|
|
||||||
|
|
||||||
|
@ -391,145 +388,9 @@ public class Dungeon {
|
||||||
Level level;
|
Level level;
|
||||||
if (branch == 0) {
|
if (branch == 0) {
|
||||||
if (Dungeon.isDLC(Conducts.Conduct.BOSSRUSH)) {
|
if (Dungeon.isDLC(Conducts.Conduct.BOSSRUSH)) {
|
||||||
switch (depth) {
|
level = createBossRushLevel();
|
||||||
case 17:
|
|
||||||
case 27:
|
|
||||||
case 0:
|
|
||||||
level = new AncityLevel();
|
|
||||||
Buff.affect(hero, RandomBuff.class).set((5), 1);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 3:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
case 9:
|
|
||||||
case 11:
|
|
||||||
case 13:
|
|
||||||
case 15:
|
|
||||||
case 18:
|
|
||||||
case 20:
|
|
||||||
case 24:
|
|
||||||
level = new ItemLevel();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
level = new ForestBossLevel();
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
level = new SewerBossLevel();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
level = new SLMKingLevel();
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
level = new PrisonBossLevel();
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
level = new DimandKingLevel();
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
level = new NewCavesBossLevel();
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
level = new CaveTwoBossLevel();
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
level = new CavesGirlDeadLevel();
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
level = new ShopBossLevel();
|
|
||||||
break;
|
|
||||||
case 21:
|
|
||||||
level = new NewCityBossLevel();
|
|
||||||
break;
|
|
||||||
case 22:
|
|
||||||
case 23:
|
|
||||||
level = new CityLevel();
|
|
||||||
Buff.affect(hero, TestDwarfMasterLock.class).set((10), 1);
|
|
||||||
break;
|
|
||||||
//TODO FIXED LIST:矮人将军那里用没祝福的十字架复活,Boss会消失不见
|
|
||||||
case 25:
|
|
||||||
level = new DwarfMasterBossLevel();
|
|
||||||
break;
|
|
||||||
case 26:
|
|
||||||
level = new YogGodHardBossLevel();
|
|
||||||
break;
|
|
||||||
case 28:
|
|
||||||
level = new DM920BossLevel();
|
|
||||||
Buff.affect(hero, TestDwarfMasterLock.class).set((1), 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
level = new DeadEndLevel();
|
|
||||||
Statistics.deepestFloor--;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
switch (depth) {
|
level = createStandardLevel();
|
||||||
case 0:
|
|
||||||
level = new ZeroLevel();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
level = new SewerLevel();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
level = new ForestBossLevel();
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
case 9:
|
|
||||||
level = new PrisonLevel();
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
if ((Statistics.boss_enhance & 0x2) != 0 || Statistics.mimicking) {
|
|
||||||
level = new ColdChestBossLevel();
|
|
||||||
} else
|
|
||||||
level = new PrisonBossLevel();
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
case 12:
|
|
||||||
case 13:
|
|
||||||
case 14:
|
|
||||||
level = new CavesLevel();
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
if ((Statistics.boss_enhance & 0x4) != 0) {
|
|
||||||
level = new CavesGirlDeadLevel();
|
|
||||||
} else
|
|
||||||
level = Random.Float() <= 0.4f ? new CaveTwoBossLevel() : new NewCavesBossLevel();
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
case 17:
|
|
||||||
case 18:
|
|
||||||
case 19:
|
|
||||||
level = new CityLevel();
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
if ((Statistics.boss_enhance & 0x8) != 0) {
|
|
||||||
Buff.affect(hero, TestDwarfMasterLock.class).set((1), 1);
|
|
||||||
level = new DwarfMasterBossLevel();
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
level = new NewCityBossLevel();
|
|
||||||
break;
|
|
||||||
case 21:
|
|
||||||
case 22:
|
|
||||||
case 23:
|
|
||||||
case 24:
|
|
||||||
level = new HallsLevel();
|
|
||||||
break;
|
|
||||||
case 25:
|
|
||||||
if ((Statistics.boss_enhance & 0x10) != 0) level = new YogGodHardBossLevel();
|
|
||||||
else level = new NewHallsBossLevel();
|
|
||||||
break;
|
|
||||||
case 26:
|
|
||||||
level = new LastLevel();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
level = new DeadEndLevel();
|
|
||||||
Statistics.deepestFloor--;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
level = new DeadEndLevel();
|
level = new DeadEndLevel();
|
||||||
Statistics.deepestFloor--;
|
Statistics.deepestFloor--;
|
||||||
|
@ -574,7 +435,7 @@ public class Dungeon {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean NxhyshopOnLevel() {
|
public static boolean NxhyshopOnLevel() {
|
||||||
return depth == 9 || depth == 18;
|
return depth == 9 || depth == 13 || depth == 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean FireLevel() {
|
public static boolean FireLevel() {
|
||||||
|
@ -738,7 +599,7 @@ public class Dungeon {
|
||||||
int souLeftThisSet;
|
int souLeftThisSet;
|
||||||
//3 SOU each floor set, 1.5 (rounded) on forbidden runes challenge
|
//3 SOU each floor set, 1.5 (rounded) on forbidden runes challenge
|
||||||
if (isChallenged(Challenges.NO_SCROLLS)){
|
if (isChallenged(Challenges.NO_SCROLLS)){
|
||||||
souLeftThisSet = Math.round(1.5f - (LimitedDrops.UPGRADE_SCROLLS.count - (depth / 5) * 1.5f));
|
souLeftThisSet = Math.round(1.5f - (LimitedDrops.UPGRADE_SCROLLS.count - (depth / 5f) * 1.5f));
|
||||||
} else {
|
} else {
|
||||||
souLeftThisSet = 3 - (LimitedDrops.UPGRADE_SCROLLS.count - (depth / 5) * 3);
|
souLeftThisSet = 3 - (LimitedDrops.UPGRADE_SCROLLS.count - (depth / 5) * 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -955,7 +955,7 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
///测试坐标用
|
///测试坐标用
|
||||||
//GLog.w(String.valueOf(hero.pos));
|
GLog.w(String.valueOf(hero.pos));
|
||||||
|
|
||||||
//携带该物品时,玩家血量低于一半后自动隐身一段回合。
|
//携带该物品时,玩家血量低于一半后自动隐身一段回合。
|
||||||
//actMove实现
|
//actMove实现
|
||||||
|
@ -1166,7 +1166,7 @@ public class Hero extends Char {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (heap.type) {
|
switch (heap.type) {
|
||||||
case TOMB:
|
case TOMB: case WHITETOMB:
|
||||||
Sample.INSTANCE.play( Assets.Sounds.TOMB );
|
Sample.INSTANCE.play( Assets.Sounds.TOMB );
|
||||||
Camera.main.shake( 1, 0.5f );
|
Camera.main.shake( 1, 0.5f );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -169,6 +169,9 @@ public enum HeroClass {
|
||||||
new PotionOfDragonKingBreath().quantity(50).identify().collect();
|
new PotionOfDragonKingBreath().quantity(50).identify().collect();
|
||||||
|
|
||||||
new PotionOfHealing().quantity(50).identify().collect();
|
new PotionOfHealing().quantity(50).identify().collect();
|
||||||
|
|
||||||
|
new PotionOfMindVision().quantity(50).identify().collect();
|
||||||
|
|
||||||
new PotionOfLiquidFlame().quantity(50).identify().collect();
|
new PotionOfLiquidFlame().quantity(50).identify().collect();
|
||||||
new DimandBook().quantity(50).identify().collect();
|
new DimandBook().quantity(50).identify().collect();
|
||||||
new PotionOfExperience().quantity(100).identify().collect();
|
new PotionOfExperience().quantity(100).identify().collect();
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class CrystalMimic extends Mimic {
|
||||||
|
|
||||||
{
|
{
|
||||||
spriteClass = MimicSprite.Crystal.class;
|
spriteClass = MimicSprite.Crystal.class;
|
||||||
|
flying = true;
|
||||||
FLEEING = new Fleeing();
|
FLEEING = new Fleeing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,35 +43,28 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Beam;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing;
|
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.effects.particles.ShadowParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.LarvaSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.LarvaSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.YogSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.YogSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.watabou.noosa.Game;
|
import com.watabou.noosa.Game;
|
||||||
import com.watabou.noosa.audio.Music;
|
import com.watabou.noosa.audio.Music;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Callback;
|
import com.watabou.utils.Callback;
|
||||||
import com.watabou.utils.GameMath;
|
|
||||||
import com.watabou.utils.PathFinder;
|
import com.watabou.utils.PathFinder;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
import com.watabou.utils.Reflection;
|
import com.watabou.utils.Reflection;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
public class YogDzewa extends Mob {
|
public class YogDzewa extends Mob {
|
||||||
|
|
||||||
|
@ -196,98 +189,7 @@ public class YogDzewa extends Mob {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
boolean terrainAffected = false;
|
|
||||||
HashSet<Char> 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();
|
|
||||||
}
|
|
||||||
for (Char ch : affected) {
|
|
||||||
if (ch == Dungeon.hero) {
|
|
||||||
Statistics.bossScores[4] -= 1000;
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
if (!ch.isAlive() && ch == Dungeon.hero) {
|
|
||||||
Dungeon.fail(getClass());
|
|
||||||
GLog.n(Messages.get(Char.class, "kill", name()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
targetedCells.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abilityCooldown <= 0){
|
|
||||||
|
|
||||||
int beams = 1 + (HT - HP)/400;
|
|
||||||
HashSet<Integer> 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){
|
while (summonCooldown <= 0){
|
||||||
|
|
||||||
|
@ -640,4 +542,6 @@ public class YogDzewa extends Mob {
|
||||||
maxLvl = -2;
|
maxLvl = -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,643 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses;
|
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses;
|
||||||
|
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Boss;
|
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.LockedFloor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM720;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
|
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.wands.WandOfBlastWave;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.CaveTwoBossLevel;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.SakaFishBossSprites;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.SakaFishBossSprites;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
|
import com.watabou.noosa.Camera;
|
||||||
|
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 SakaFishBoss extends Boss {
|
public class SakaFishBoss extends Boss {
|
||||||
|
private int leapPos = -1;
|
||||||
|
private float leapCooldown = 0;
|
||||||
|
private int lastEnemyPos = -1;
|
||||||
|
|
||||||
|
private Ballistica beam;
|
||||||
|
private int beamTarget = -1;
|
||||||
|
private int beamCooldown;
|
||||||
|
public boolean beamCharged;
|
||||||
|
|
||||||
|
|
||||||
|
/**隐藏Boss 萨卡班甲鱼*/
|
||||||
{
|
{
|
||||||
spriteClass = SakaFishBossSprites.class;
|
spriteClass = SakaFishBossSprites.class;
|
||||||
initBaseStatus(19, 25, 6, 0, 700, 5, 12);
|
initBaseStatus(19, 25, 6, 0, 480, 5, 12);
|
||||||
state = SLEEPING;
|
state = SLEEPING;
|
||||||
initProperty();
|
initProperty();
|
||||||
|
HUNTING = new Hunting();
|
||||||
|
baseSpeed = 1.75f;
|
||||||
initStatus(76);
|
initStatus(76);
|
||||||
HP=700;
|
HP=480;
|
||||||
defenseSkill = 10;
|
defenseSkill = 10;
|
||||||
HT=700;
|
HT=480;
|
||||||
baseSpeed=1.5f;
|
|
||||||
|
properties.add(Property.ICY);
|
||||||
|
|
||||||
viewDistance = 30;
|
viewDistance = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int pumpedUp = 0;
|
||||||
|
private int healInc = 1;
|
||||||
|
|
||||||
|
public void damage(int dmg, Object src) {
|
||||||
|
if (!Dungeon.level.mobs.contains(this)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hpBracket = HT / 8;
|
||||||
|
|
||||||
|
int beforeHitHP = HP;
|
||||||
|
super.damage(dmg, src);
|
||||||
|
dmg = beforeHitHP - HP;
|
||||||
|
|
||||||
|
//tengu cannot be hit through multiple brackets at a time
|
||||||
|
if ((beforeHitHP/hpBracket - HP/hpBracket) >= 2){
|
||||||
|
HP = hpBracket * ((beforeHitHP/hpBracket)-1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LockedFloor lock = hero.buff(LockedFloor.class);
|
||||||
|
if (lock != null) {
|
||||||
|
lock.addTime(dmg*3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//phase 1 of the fight is over
|
||||||
|
if (HP <= HT/2){
|
||||||
|
HP = (HT/2);
|
||||||
|
yell(Messages.get(this, "interesting"));
|
||||||
|
// ((PrisonBossLevel)Dungeon.level).progress();
|
||||||
|
BossHealthBar.bleed(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canAttack( Char enemy ) {
|
||||||
|
|
||||||
|
if (beamCooldown == 0) {
|
||||||
|
Ballistica aim = new Ballistica(pos, enemy.pos, Ballistica.STOP_SOLID);
|
||||||
|
|
||||||
|
if (enemy.invisible == 0 && !isCharmedBy(enemy) && fieldOfView[enemy.pos] && aim.subPath(1, aim.dist).contains(enemy.pos)){
|
||||||
|
beam = aim;
|
||||||
|
beamTarget = aim.collisionPos;
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
//if the beam is charged, it has to attack, will aim at previous location of target.
|
||||||
|
return beamCharged;
|
||||||
|
} else
|
||||||
|
return super.canAttack(enemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int damageRoll() {
|
||||||
|
int min = 1;
|
||||||
|
int max = (HP*2 <= HT) ? 12 : 8;
|
||||||
|
if (pumpedUp > 0) {
|
||||||
|
pumpedUp = 0;
|
||||||
|
return Random.NormalIntRange( min*3, max*3 );
|
||||||
|
} else {
|
||||||
|
return Random.NormalIntRange( min, max );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int attackSkill( Char target ) {
|
||||||
|
int attack = 10;
|
||||||
|
if (HP*2 <= HT) attack = 15;
|
||||||
|
if (pumpedUp > 0) attack *= 2;
|
||||||
|
return attack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int defenseSkill(Char enemy) {
|
||||||
|
return (int)(super.defenseSkill(enemy) * ((HP*2 <= HT)? 1.5 : 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int drRoll() {
|
||||||
|
return Random.NormalIntRange(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void activate(){
|
||||||
|
((SakaFishBossSprites) sprite).activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean act() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (beamCharged && state != HUNTING){
|
||||||
|
beamCharged = false;
|
||||||
|
sprite.operate(this.pos);
|
||||||
|
}
|
||||||
|
if (beam == null && beamTarget != -1) {
|
||||||
|
beam = new Ballistica(pos, beamTarget, Ballistica.STOP_SOLID);
|
||||||
|
sprite.turnTo(pos, beamTarget);
|
||||||
|
}
|
||||||
|
if (beamCooldown > 0)
|
||||||
|
beamCooldown--;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean doAttack( Char enemy ) {
|
||||||
|
|
||||||
|
if (beamCooldown > 0) {
|
||||||
|
return super.doAttack(enemy);
|
||||||
|
} else if (!beamCharged){
|
||||||
|
((SakaFishBossSprites)sprite).charge( enemy.pos );
|
||||||
|
spend( attackDelay()*2f );
|
||||||
|
beamCharged = true;
|
||||||
|
return true;
|
||||||
|
} else if(HP*2>=HT) {
|
||||||
|
|
||||||
|
spend( 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);
|
||||||
|
deathGaze();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
//60% chance of 2 blobs, 30% chance of 3, 10% chance for 4. Average of 2.5
|
||||||
|
int blobs = Random.chances(new float[]{0, 0, 6, 3, 1});
|
||||||
|
for (int i = 0; i < blobs; i++){
|
||||||
|
int ofs;
|
||||||
|
do {
|
||||||
|
ofs = PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||||
|
} while (!Dungeon.level.passable[pos + ofs]);
|
||||||
|
Dungeon.level.drop( new GooBlob(), pos + ofs ).sprite.drop( pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
Badges.validateBossSlain();
|
||||||
|
|
||||||
|
yell( Messages.get(this, "defeated") );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notice() {
|
||||||
|
super.notice();
|
||||||
|
if (!BossHealthBar.isAssigned()) {
|
||||||
|
BossHealthBar.assignBoss(this);
|
||||||
|
Dungeon.level.seal();
|
||||||
|
yell(Messages.get(this, "notice"));
|
||||||
|
Camera.main.shake(1f,3f);
|
||||||
|
GameScene.bossReady();
|
||||||
|
activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String PUMPEDUP = "pumpedup";
|
||||||
|
private final String HEALINC = "healinc";
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
private static final String BEAM_TARGET = "beamTarget";
|
||||||
|
private static final String BEAM_COOLDOWN = "beamCooldown";
|
||||||
|
private static final String BEAM_CHARGED = "beamCharged";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle( Bundle bundle ) {
|
||||||
|
|
||||||
|
super.storeInBundle( bundle );
|
||||||
|
bundle.put( BEAM_TARGET, beamTarget);
|
||||||
|
bundle.put( BEAM_COOLDOWN, beamCooldown );
|
||||||
|
bundle.put( BEAM_CHARGED, beamCharged );
|
||||||
|
bundle.put( PUMPEDUP , pumpedUp );
|
||||||
|
bundle.put( HEALINC, healInc );
|
||||||
|
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 );
|
||||||
|
|
||||||
|
pumpedUp = bundle.getInt( PUMPEDUP );
|
||||||
|
if (state != SLEEPING) BossHealthBar.assignBoss(this);
|
||||||
|
if ((HP*2 <= HT)) BossHealthBar.bleed(true);
|
||||||
|
|
||||||
|
//if check is for pre-0.9.3 saves
|
||||||
|
healInc = bundle.getInt(HEALINC);
|
||||||
|
|
||||||
|
if (bundle.contains(BEAM_TARGET))
|
||||||
|
beamTarget = bundle.getInt(BEAM_TARGET);
|
||||||
|
beamCooldown = bundle.getInt(BEAM_COOLDOWN);
|
||||||
|
beamCharged = bundle.getBoolean(BEAM_CHARGED);
|
||||||
|
|
||||||
|
lastEnemyPos = bundle.getInt(LAST_ENEMY_POS);
|
||||||
|
leapPos = bundle.getInt(LEAP_POS);
|
||||||
|
leapCooldown = bundle.getFloat(LEAP_CD);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//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() {
|
||||||
|
|
||||||
|
{
|
||||||
|
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, 1, NewDM720.FallingRocks.class));
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Actor.remove(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Actor.addDelayed(a, Math.min(target.cooldown(), 3*TICK));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Hunting extends Mob.Hunting {
|
||||||
|
|
||||||
|
@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];
|
||||||
|
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());
|
||||||
|
dropRocks(enemy);
|
||||||
|
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 (endPos != leapPos){
|
||||||
|
Actor.addDelayed(new Pushing(SakaFishBoss.this, leapPos, endPos), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = endPos;
|
||||||
|
leapPos = -1;
|
||||||
|
sprite.operate(pos);
|
||||||
|
Dungeon.level.occupyCell(SakaFishBoss.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( SakaFishBoss.this );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leapCooldown <= 0 && enemyInFOV && !rooted
|
||||||
|
&& Dungeon.level.distance(pos, enemy.pos) >= 3) {
|
||||||
|
|
||||||
|
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(SakaFishBoss.this, "leap"));
|
||||||
|
sprite.parent.addToBack(new TargetedCell(leapPos, 0xFF0000));
|
||||||
|
((SakaFishBossSprites)sprite).leapPrep( leapPos );
|
||||||
|
hero.interrupt();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldPos = pos;
|
||||||
|
if (target != -1 && getCloser( target )) {
|
||||||
|
|
||||||
|
spend( 6f );
|
||||||
|
return moveSprite( oldPos, pos );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
spend(TICK);
|
||||||
|
if (!enemyInFOV) {
|
||||||
|
sprite.showLost();
|
||||||
|
state = WANDERING;
|
||||||
|
target = Dungeon.level.randomDestination( SakaFishBoss.this );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static class DeathGaze{}
|
||||||
|
public void deathGaze(){
|
||||||
|
if (!beamCharged || beamCooldown > 0 || beam == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beamCharged = false;
|
||||||
|
beamCooldown = Random.IntRange(4, 6);
|
||||||
|
|
||||||
|
boolean terrainAffected = false;
|
||||||
|
|
||||||
|
for (int pos : beam.subPath(1, beam.dist)) {
|
||||||
|
|
||||||
|
if (Dungeon.level.flamable[pos]) {
|
||||||
|
|
||||||
|
Dungeon.level.destroy( pos );
|
||||||
|
GameScene.updateMap( pos );
|
||||||
|
terrainAffected = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Char ch = Actor.findChar( pos );
|
||||||
|
if (ch == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit( this, ch, true )) {
|
||||||
|
ch.damage( Random.NormalIntRange( 20, 40 ), new DeathGaze() );
|
||||||
|
|
||||||
|
if (Dungeon.level.heroFOV[pos]) {
|
||||||
|
ch.sprite.flash();
|
||||||
|
CellEmitter.center( pos ).burst( RainbowParticle.BURST, Random.IntRange( 1, 2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ch.isAlive() && ch == hero) {
|
||||||
|
Dungeon.fail( getClass() );
|
||||||
|
GLog.n( Messages.get(this, "deathgaze_kill") );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ch.sprite.showStatus( CharSprite.NEUTRAL, ch.defenseVerb() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (terrainAffected) {
|
||||||
|
Dungeon.observe();
|
||||||
|
}
|
||||||
|
|
||||||
|
beam = null;
|
||||||
|
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;
|
||||||
|
ConeAOE aoe = new ConeAOE(aim, aoeSize, 360, projectileProps);
|
||||||
|
|
||||||
|
for (Ballistica ray : aoe.outerRays){
|
||||||
|
((MagicMissile)ch.sprite.parent.recycle( MagicMissile.class )).reset(
|
||||||
|
MagicMissile.FROST,
|
||||||
|
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));
|
||||||
|
Level.set(ray.path.get(ray.dist), Terrain.EMPTY);
|
||||||
|
GameScene.updateMap( ray.path.get(ray.dist) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,476 @@
|
||||||
|
//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<Integer> 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<Char> 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<Integer> 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);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
//
|
|
@ -21,10 +21,7 @@
|
||||||
|
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
||||||
|
|
||||||
import static com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper.sell;
|
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
|
@ -32,10 +29,8 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ImpSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ImpSprite;
|
||||||
import com.watabou.noosa.Game;
|
|
||||||
import com.watabou.utils.Callback;
|
|
||||||
|
|
||||||
public class ImpShopkeeper extends NPC {
|
public class ImpShopkeeper extends Shopkeeper {
|
||||||
|
|
||||||
{
|
{
|
||||||
spriteClass = ImpSprite.class;
|
spriteClass = ImpSprite.class;
|
||||||
|
@ -54,20 +49,6 @@ public class ImpShopkeeper extends NPC {
|
||||||
return super.act();
|
return super.act();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean interact(Char c) {
|
|
||||||
if (c != Dungeon.hero) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Game.runOnRenderThread(new Callback() {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
sell();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage( int dmg, Object src ) {
|
public void damage( int dmg, Object src ) {
|
||||||
//flee();
|
//flee();
|
||||||
|
|
|
@ -1,22 +1,15 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.NxhySprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.NxhySprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
|
||||||
import com.watabou.noosa.Game;
|
|
||||||
import com.watabou.utils.Callback;
|
|
||||||
|
|
||||||
public class Nxhy extends NPC {
|
public class Nxhy extends Shopkeeper {
|
||||||
|
|
||||||
{
|
{
|
||||||
spriteClass = NxhySprite.class;
|
spriteClass = NxhySprite.class;
|
||||||
|
@ -74,48 +67,5 @@ public class Nxhy extends NPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean reset() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WndBag sell() {
|
|
||||||
return GameScene.selectItem( itemSelector );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static WndBag.ItemSelector itemSelector = new WndBag.ItemSelector() {
|
|
||||||
@Override
|
|
||||||
public String textPrompt() {
|
|
||||||
return Messages.get(Shopkeeper.class, "sell");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean itemSelectable(Item item) {
|
|
||||||
return Shopkeeper.canSell(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSelect( Item item ) {
|
|
||||||
if (item != null) {
|
|
||||||
WndBag parentWnd = sell();
|
|
||||||
GameScene.show( new WndTradeItem( item, parentWnd ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean interact(Char c) {
|
|
||||||
if (c != Dungeon.hero) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Game.runOnRenderThread(new Callback() {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
sell();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,142 +21,92 @@
|
||||||
|
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs;
|
||||||
|
|
||||||
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
|
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ClearBleesdGoodBuff.BlessNoMoney;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicGirlDebuff.MagicGirlSayMoneyMore;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Ankh;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.food.Food;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkeeperSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkeeperSprite;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTitledMessage;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndTradeItem;
|
||||||
import com.watabou.noosa.Game;
|
import com.watabou.noosa.Game;
|
||||||
|
import com.watabou.noosa.Image;
|
||||||
|
import com.watabou.utils.Bundlable;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Callback;
|
import com.watabou.utils.Callback;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Shopkeeper extends NPC {
|
public class Shopkeeper extends NPC {
|
||||||
|
|
||||||
{
|
{
|
||||||
spriteClass = ShopkeeperSprite.class;
|
spriteClass = ShopkeeperSprite.class;
|
||||||
|
|
||||||
properties.add(Property.IMMOVABLE);
|
properties.add(Property.IMMOVABLE);
|
||||||
}
|
}
|
||||||
public static boolean seenBefore = false;
|
|
||||||
|
|
||||||
@Override
|
public static int MAX_BUYBACK_HISTORY = 4;
|
||||||
public boolean interact(Char c) {
|
public ArrayList<Item> buybackItems = new ArrayList<>();
|
||||||
if (c != hero) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Game.runOnRenderThread(new Callback() {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
sell();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storeInBundle(Bundle bundle) {
|
|
||||||
super.storeInBundle(bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean act() {
|
protected boolean act() {
|
||||||
if (!seenBefore && Dungeon.level.heroFOV[pos]) {
|
|
||||||
yell(Messages.get(this, "greetings", Dungeon.hero.name()));
|
if (Dungeon.level.visited[pos]){
|
||||||
seenBefore = true;
|
Notes.add(Notes.Landmark.SHOP);
|
||||||
//Buff.affect(this, ChampionEnemy.AntiMagic.class);
|
|
||||||
//Buff.affect(this, ChampionEnemy.Halo.class);
|
|
||||||
} else if(seenBefore && !Dungeon.level.heroFOV[pos]) {
|
|
||||||
seenBefore = false;
|
|
||||||
yell(Messages.get(this, "goodbye", Dungeon.hero.name()));
|
|
||||||
}
|
}
|
||||||
throwItem();
|
|
||||||
|
|
||||||
sprite.turnTo( pos, Dungeon.hero.pos );
|
sprite.turnTo( pos, Dungeon.hero.pos );
|
||||||
spend( TICK );
|
spend( TICK );
|
||||||
return true;
|
return super.act();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage( int dmg, Object src ) {
|
public void damage( int dmg, Object src ) {
|
||||||
|
flee();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int defenseSkill( Char enemy ) {
|
public void add(Buff buff ) {
|
||||||
return INFINITE_EVASION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Buff.prolong(Dungeon.hero, Blindness.class, Blindness.DURATION * 4f);
|
|
||||||
GameScene.flash(0x80FFFFFF);
|
|
||||||
Buff.affect(hero, Burning.class).reignite(hero, 15f);
|
|
||||||
Dungeon.level.seal();
|
|
||||||
Mob moa = new MoloHR();
|
|
||||||
moa.pos = pos;
|
|
||||||
GameScene.add(moa);
|
|
||||||
yell(Messages.get(this, "arise"));
|
|
||||||
new ShopGuardEye().spawnAround(pos);
|
|
||||||
new ShopGuard().spawnAround(pos);
|
|
||||||
Buff.affect(moa, ChampionEnemy.Growing.class);
|
|
||||||
Buff.affect(moa, ChampionEnemy.Projecting.class);
|
|
||||||
Buff.affect(moa, ChampionEnemy.AntiMagic.class);
|
|
||||||
Buff.affect(moa, ChampionEnemy.Giant.class);
|
|
||||||
Buff.affect(moa, ChampionEnemy.Blessed.class);
|
|
||||||
Buff.affect(moa, ChampionEnemy.Halo.class);
|
|
||||||
for (Mob mob : Dungeon.level.mobs) {
|
|
||||||
switch (Random.Int(7)) {
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
Buff.affect(mob, ChampionEnemy.Blazing.class);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
Buff.affect(mob, ChampionEnemy.Projecting.class);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
Buff.affect(mob, ChampionEnemy.AntiMagic.class);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
Buff.affect(mob, ChampionEnemy.Giant.class);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
Buff.affect(mob, ChampionEnemy.Blessed.class);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
Buff.affect(mob, ChampionEnemy.Growing.class);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
Buff.affect(mob, ChampionEnemy.Halo.class);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yell(Messages.get(this, "dead"));*/
|
|
||||||
|
|
||||||
public void flee() {
|
public void flee() {
|
||||||
destroy();
|
destroy();
|
||||||
CellEmitter.get(pos).burst(ElmoParticle.FACTORY, 6);
|
|
||||||
hero.sprite.burst(15597568, 9);
|
Notes.remove(Notes.Landmark.SHOP);
|
||||||
sprite.killAndErase();
|
|
||||||
|
if (sprite != null) {
|
||||||
|
sprite.killAndErase();
|
||||||
|
CellEmitter.get(pos).burst(ElmoParticle.FACTORY, 6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private DriedRose.GhostHero ghost = null;
|
|
||||||
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
for (Heap heap: Dungeon.level.heaps.valueList()) {
|
for (Heap heap: Dungeon.level.heaps.valueList()) {
|
||||||
if (heap.type == Heap.Type.FOR_SALE) {
|
if (heap.type == Heap.Type.FOR_SALE) {
|
||||||
CellEmitter.get( heap.pos ).burst( ElmoParticle.FACTORY, 4 );
|
if (ShatteredPixelDungeon.scene() instanceof GameScene) {
|
||||||
heap.type = Heap.Type.HEAP;//Allow them to be picked up
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,18 +118,7 @@ public class Shopkeeper extends NPC {
|
||||||
|
|
||||||
//shopkeepers are greedy!
|
//shopkeepers are greedy!
|
||||||
public static int sellPrice(Item item){
|
public static int sellPrice(Item item){
|
||||||
int price = item.value() * 5 * (Dungeon.depth / 5 + 1);
|
return item.value() * 5 * (Dungeon.depth / 5 + 1);
|
||||||
|
|
||||||
if(Dungeon.hero.buff(MagicGirlSayMoneyMore.class) != null){
|
|
||||||
if(item instanceof Ankh ||item instanceof Food || item instanceof PotionOfHealing){
|
|
||||||
price *= 0.1;
|
|
||||||
}
|
|
||||||
price *= 1.5;
|
|
||||||
//todo 3折
|
|
||||||
} else if (Dungeon.hero.buff(BlessNoMoney.class) != null) {
|
|
||||||
price *= 0.3;
|
|
||||||
}
|
|
||||||
return price;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WndBag sell() {
|
public static WndBag sell() {
|
||||||
|
@ -213,4 +152,100 @@ public class Shopkeeper extends NPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public boolean interact(Char c) {
|
||||||
|
if (c != Dungeon.hero) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Game.runOnRenderThread(new Callback() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
String[] options = new String[2+ buybackItems.size()];
|
||||||
|
int i = 0;
|
||||||
|
options[i++] = Messages.get(Shopkeeper.this, "sell");
|
||||||
|
options[i++] = Messages.get(Shopkeeper.this, "talk");
|
||||||
|
for (Item item : buybackItems){
|
||||||
|
options[i] = Messages.get(Heap.class, "for_sale", item.value(),
|
||||||
|
Messages.titleCase(item.trueName()+"x"+item.quantity()));
|
||||||
|
if (options[i].length() > 26) options[i] = options[i].substring(0, 23) + "...";
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
GameScene.show(new WndOptions(sprite(), Messages.titleCase(name()), description(), options){
|
||||||
|
@Override
|
||||||
|
protected void onSelect(int index) {
|
||||||
|
super.onSelect(index);
|
||||||
|
if (index == 0){
|
||||||
|
sell();
|
||||||
|
} else if (index == 1){
|
||||||
|
GameScene.show(new WndTitledMessage(sprite(), Messages.titleCase(name()), chatText()));
|
||||||
|
} else if (index > 1){
|
||||||
|
GLog.i(Messages.get(Shopkeeper.this, "buyback"));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean enabled(int index) {
|
||||||
|
if (index > 1){
|
||||||
|
return Dungeon.gold >= buybackItems.get(index-2).value();
|
||||||
|
} else {
|
||||||
|
return super.enabled(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasIcon(int index) {
|
||||||
|
return index > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Image getIcon(int index) {
|
||||||
|
if (index > 1){
|
||||||
|
return new ItemSprite(buybackItems.get(index-2));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
case 11:case 13:
|
||||||
|
return Messages.get(this, "talk_caves");
|
||||||
|
case 16: case 18:
|
||||||
|
return Messages.get(this, "talk_city");
|
||||||
|
case 20:
|
||||||
|
return Messages.get(this, "talk_halls");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String BUYBACK_ITEMS = "buyback_items";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put(BUYBACK_ITEMS, buybackItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
buybackItems.clear();
|
||||||
|
if (bundle.contains(BUYBACK_ITEMS)){
|
||||||
|
for (Bundlable i : bundle.getCollection(BUYBACK_ITEMS)){
|
||||||
|
buybackItems.add((Item) i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,8 +21,9 @@
|
||||||
|
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.items;
|
package com.shatteredpixel.shatteredpixeldungeon.items;
|
||||||
|
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.level;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
||||||
|
@ -42,6 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
|
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
@ -56,7 +58,7 @@ import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class Heap implements Bundlable {
|
public class Heap implements Bundlable {
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
HEAP,
|
HEAP,
|
||||||
FOR_SALE,
|
FOR_SALE,
|
||||||
|
@ -64,6 +66,8 @@ public class Heap implements Bundlable {
|
||||||
LOCKED_CHEST,
|
LOCKED_CHEST,
|
||||||
CRYSTAL_CHEST,
|
CRYSTAL_CHEST,
|
||||||
TOMB,
|
TOMB,
|
||||||
|
TELECRYSTL,
|
||||||
|
WHITETOMB,
|
||||||
SKELETON,
|
SKELETON,
|
||||||
REMAINS,
|
REMAINS,
|
||||||
BLACK
|
BLACK
|
||||||
|
@ -85,6 +89,12 @@ public class Heap implements Bundlable {
|
||||||
case TOMB:
|
case TOMB:
|
||||||
Wraith.spawnAround( hero.pos );
|
Wraith.spawnAround( hero.pos );
|
||||||
break;
|
break;
|
||||||
|
case WHITETOMB:
|
||||||
|
ScrollOfTeleportation.appear( hero,hero.pos+5 );
|
||||||
|
break;
|
||||||
|
case TELECRYSTL:
|
||||||
|
ScrollOfTeleportation.appear( hero,level.entrance );
|
||||||
|
break;
|
||||||
case REMAINS:
|
case REMAINS:
|
||||||
case SKELETON:
|
case SKELETON:
|
||||||
CellEmitter.center( pos ).start(Speck.factory(Speck.RATTLE), 0.1f, 3);
|
CellEmitter.center( pos ).start(Speck.factory(Speck.RATTLE), 0.1f, 3);
|
||||||
|
@ -227,7 +237,7 @@ public class Heap implements Bundlable {
|
||||||
|
|
||||||
if (burnt || evaporated) {
|
if (burnt || evaporated) {
|
||||||
|
|
||||||
if (Dungeon.level.heroFOV[pos]) {
|
if (level.heroFOV[pos]) {
|
||||||
if (burnt) {
|
if (burnt) {
|
||||||
burnFX( pos );
|
burnFX( pos );
|
||||||
} else {
|
} else {
|
||||||
|
@ -248,7 +258,7 @@ public class Heap implements Bundlable {
|
||||||
public void explode() {
|
public void explode() {
|
||||||
|
|
||||||
//breaks open most standard containers, mimics die.
|
//breaks open most standard containers, mimics die.
|
||||||
if (type == Type.CHEST || type == Type.SKELETON) {
|
if (type == Type.CHEST || type == Type.SKELETON || type == Type.TELECRYSTL) {
|
||||||
type = Type.HEAP;
|
type = Type.HEAP;
|
||||||
sprite.link();
|
sprite.link();
|
||||||
sprite.drop();
|
sprite.drop();
|
||||||
|
@ -343,7 +353,7 @@ public class Heap implements Bundlable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
Dungeon.level.heaps.remove( this.pos );
|
level.heaps.remove( this.pos );
|
||||||
if (sprite != null) {
|
if (sprite != null) {
|
||||||
sprite.kill();
|
sprite.kill();
|
||||||
}
|
}
|
||||||
|
@ -364,10 +374,12 @@ public class Heap implements Bundlable {
|
||||||
return Messages.get(this, "chest");
|
return Messages.get(this, "chest");
|
||||||
case LOCKED_CHEST:
|
case LOCKED_CHEST:
|
||||||
return Messages.get(this, "locked_chest");
|
return Messages.get(this, "locked_chest");
|
||||||
case CRYSTAL_CHEST:
|
case CRYSTAL_CHEST: case TELECRYSTL:
|
||||||
return Messages.get(this, "crystal_chest");
|
return Messages.get(this, "crystal_chest");
|
||||||
case TOMB:
|
case TOMB:
|
||||||
return Messages.get(this, "tomb");
|
return Messages.get(this, "tomb");
|
||||||
|
case WHITETOMB:
|
||||||
|
return Messages.get(this, "wtomb");
|
||||||
case SKELETON:
|
case SKELETON:
|
||||||
return Messages.get(this, "skeleton");
|
return Messages.get(this, "skeleton");
|
||||||
case REMAINS:
|
case REMAINS:
|
||||||
|
@ -381,7 +393,7 @@ public class Heap implements Bundlable {
|
||||||
|
|
||||||
public String info(){
|
public String info(){
|
||||||
switch(type){
|
switch(type){
|
||||||
case CHEST:
|
case CHEST:case TELECRYSTL:
|
||||||
return Messages.get(this, "chest_desc");
|
return Messages.get(this, "chest_desc");
|
||||||
case LOCKED_CHEST:
|
case LOCKED_CHEST:
|
||||||
return Messages.get(this, "locked_chest_desc");
|
return Messages.get(this, "locked_chest_desc");
|
||||||
|
@ -396,6 +408,8 @@ public class Heap implements Bundlable {
|
||||||
return Messages.get(this, "crystal_chest_desc", Messages.get(this, "unknow") );
|
return Messages.get(this, "crystal_chest_desc", Messages.get(this, "unknow") );
|
||||||
case TOMB:
|
case TOMB:
|
||||||
return Messages.get(this, "tomb_desc");
|
return Messages.get(this, "tomb_desc");
|
||||||
|
case WHITETOMB:
|
||||||
|
return Messages.get(this, "wtomb_desc");
|
||||||
case BLACK:
|
case BLACK:
|
||||||
return Messages.get(this, "black_chest_desc");
|
return Messages.get(this, "black_chest_desc");
|
||||||
case SKELETON:
|
case SKELETON:
|
||||||
|
|
|
@ -23,6 +23,8 @@ package com.shatteredpixel.shatteredpixeldungeon.items.spells;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
|
@ -108,14 +110,21 @@ public class Alchemize extends Spell {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
|
||||||
float pos = height;
|
float pos = height;
|
||||||
|
Shopkeeper shop = null;
|
||||||
|
for (Char ch : Actor.chars()){
|
||||||
|
if (ch instanceof Shopkeeper){
|
||||||
|
shop = (Shopkeeper) ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Shopkeeper finalShop = shop;
|
||||||
if (Shopkeeper.canSell(item)) {
|
if (Shopkeeper.canSell(item)) {
|
||||||
if (item.quantity() == 1) {
|
if (item.quantity() == 1) {
|
||||||
|
|
||||||
RedButton btnSell = new RedButton(Messages.get(this, "sell", item.value())) {
|
RedButton btnSell = new RedButton(Messages.get(this, "sell", item.value())) {
|
||||||
@Override
|
@Override
|
||||||
protected void onClick() {
|
protected void onClick() {
|
||||||
WndTradeItem.sell(item);
|
WndTradeItem.sell(item,finalShop);
|
||||||
hide();
|
hide();
|
||||||
consumeAlchemize();
|
consumeAlchemize();
|
||||||
}
|
}
|
||||||
|
@ -143,7 +152,7 @@ public class Alchemize extends Spell {
|
||||||
RedButton btnSellAll = new RedButton(Messages.get(this, "sell_all", priceAll)) {
|
RedButton btnSellAll = new RedButton(Messages.get(this, "sell_all", priceAll)) {
|
||||||
@Override
|
@Override
|
||||||
protected void onClick() {
|
protected void onClick() {
|
||||||
WndTradeItem.sell(item);
|
WndTradeItem.sell(item,finalShop);
|
||||||
hide();
|
hide();
|
||||||
consumeAlchemize();
|
consumeAlchemize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,17 @@ import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class LockSword extends MeleeWeapon {
|
public class LockSword extends MeleeWeapon {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private int lvl = 0;
|
private int lvl = 0;
|
||||||
|
|
||||||
public LockSword() {
|
public LockSword() {
|
||||||
super.image = ItemSpriteSheet.DG3;
|
super.image = ItemSpriteSheet.DG3;
|
||||||
super.tier = 5;
|
super.tier = 5;
|
||||||
|
// InterlevelScene.mode = InterlevelScene.Mode.ANCITYBOSS;
|
||||||
|
// Game.switchScene(InterlevelScene.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
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.bosses.SakaFishBoss;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses.SakaFishBoss;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
|
import com.watabou.utils.PathFinder;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
public class AncientMysteryCityBossLevel extends Level{
|
public class AncientMysteryCityBossLevel extends Level{
|
||||||
|
|
||||||
|
@ -26,7 +32,7 @@ public class AncientMysteryCityBossLevel extends Level{
|
||||||
private static final short E = Terrain.STATUE;
|
private static final short E = Terrain.STATUE;
|
||||||
private static final short C = Terrain.HIGH_GRASS;
|
private static final short C = Terrain.HIGH_GRASS;
|
||||||
private static final short M = Terrain.CRYSTAL_DOOR;
|
private static final short M = Terrain.CRYSTAL_DOOR;
|
||||||
private static final short G = Terrain.LOCKED_DOOR;
|
private static final short G = Terrain.DOOR;
|
||||||
|
|
||||||
private static final short K = Terrain.WELL;
|
private static final short K = Terrain.WELL;
|
||||||
|
|
||||||
|
@ -76,14 +82,54 @@ public class AncientMysteryCityBossLevel extends Level{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int randomRespawnCell( Char ch ) {
|
||||||
|
int pos = WIDTH + 16; //random cell adjacent to the entrance.
|
||||||
|
int cell;
|
||||||
|
do {
|
||||||
|
cell = pos + PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||||
|
} while (!passable[cell]
|
||||||
|
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
|
||||||
|
|| Actor.findChar(cell) != null);
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final int getBossDoor = 688;
|
||||||
|
private static final int LDBossDoor = 661;
|
||||||
|
@Override
|
||||||
|
public void occupyCell( Char ch ) {
|
||||||
|
|
||||||
|
super.occupyCell( ch );
|
||||||
|
|
||||||
|
boolean isTrue = ch.pos == LDBossDoor && ch == Dungeon.hero;
|
||||||
|
|
||||||
|
//如果有生物来到BossDoor的下一个坐标,且生物是玩家,那么触发seal().
|
||||||
|
if (map[getBossDoor] == Terrain.DOOR && isTrue || map[getBossDoor] == Terrain.EMBERS && isTrue) {
|
||||||
|
seal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seal() {
|
||||||
|
super.seal();
|
||||||
|
|
||||||
|
set( getBossDoor, Terrain.WALL );
|
||||||
|
GameScene.updateMap( getBossDoor );
|
||||||
|
set( 688, Terrain.LOCKED_DOOR );
|
||||||
|
GameScene.updateMap( 688 );
|
||||||
|
Dungeon.observe();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void createMobs() {
|
protected void createMobs() {
|
||||||
SakaFishBoss saka= new SakaFishBoss();
|
SakaFishBoss boss = new SakaFishBoss();
|
||||||
saka.pos = (WIDTH*20+13);
|
boss.pos = 337;
|
||||||
mobs.add(saka);
|
mobs.add(boss);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||||
|
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.depth;
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RandomBuff;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.TestDwarfMasterLock;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
//Level Rules
|
||||||
|
public class LevelRules {
|
||||||
|
public static Level createBossRushLevel() {
|
||||||
|
switch (depth) {
|
||||||
|
case 0:
|
||||||
|
case 17:
|
||||||
|
case 27:
|
||||||
|
Buff.affect(hero, RandomBuff.class).set(5, 1);
|
||||||
|
return new AncientMysteryCityBossLevel();
|
||||||
|
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();
|
||||||
|
case 2:
|
||||||
|
return new ForestBossLevel();
|
||||||
|
case 4:
|
||||||
|
return new SewerBossLevel();
|
||||||
|
case 5:
|
||||||
|
return new SLMKingLevel();
|
||||||
|
case 8:
|
||||||
|
return new PrisonBossLevel();
|
||||||
|
case 10:
|
||||||
|
return new DimandKingLevel();
|
||||||
|
case 12:
|
||||||
|
return new NewCavesBossLevel();
|
||||||
|
case 14:
|
||||||
|
return new CaveTwoBossLevel();
|
||||||
|
case 16:
|
||||||
|
return new CavesGirlDeadLevel();
|
||||||
|
case 19:
|
||||||
|
return new ShopBossLevel();
|
||||||
|
case 21:
|
||||||
|
return new NewCityBossLevel();
|
||||||
|
case 22: case 23:
|
||||||
|
Buff.affect(hero, TestDwarfMasterLock.class).set(10, 1);
|
||||||
|
return new CityLevel();
|
||||||
|
case 25:
|
||||||
|
return new DwarfMasterBossLevel();
|
||||||
|
case 26:
|
||||||
|
return new YogGodHardBossLevel();
|
||||||
|
case 28:
|
||||||
|
Buff.affect(hero, TestDwarfMasterLock.class).set(1, 1);
|
||||||
|
return new DM920BossLevel();
|
||||||
|
default:
|
||||||
|
Statistics.deepestFloor--;
|
||||||
|
return new DeadEndLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Level createStandardLevel() {
|
||||||
|
switch (depth) {
|
||||||
|
case 0:
|
||||||
|
return new ZeroLevel();
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
return new SewerLevel();
|
||||||
|
case 5:
|
||||||
|
return new ForestBossLevel();
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
return new PrisonLevel();
|
||||||
|
case 10:
|
||||||
|
if ((Statistics.boss_enhance & 0x2) != 0 || Statistics.mimicking) {
|
||||||
|
return new ColdChestBossLevel();
|
||||||
|
} else {
|
||||||
|
return new PrisonBossLevel();
|
||||||
|
}
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
return new CavesLevel();
|
||||||
|
case 15:
|
||||||
|
if ((Statistics.boss_enhance & 0x4) != 0) {
|
||||||
|
return new CavesGirlDeadLevel();
|
||||||
|
} else {
|
||||||
|
return Random.Float() <= 0.4f ? new CaveTwoBossLevel() : new NewCavesBossLevel();
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
case 17:
|
||||||
|
case 18:
|
||||||
|
case 19:
|
||||||
|
return new CityLevel();
|
||||||
|
case 20:
|
||||||
|
if ((Statistics.boss_enhance & 0x8) != 0) {
|
||||||
|
Buff.affect(hero, TestDwarfMasterLock.class).set(1, 1);
|
||||||
|
return new DwarfMasterBossLevel();
|
||||||
|
} else {
|
||||||
|
return new NewCityBossLevel();
|
||||||
|
}
|
||||||
|
case 21:
|
||||||
|
case 22:
|
||||||
|
case 23:
|
||||||
|
case 24:
|
||||||
|
return new HallsLevel();
|
||||||
|
case 25:
|
||||||
|
if ((Statistics.boss_enhance & 0x10) != 0) {
|
||||||
|
return new YogGodHardBossLevel();
|
||||||
|
} else {
|
||||||
|
return new NewHallsBossLevel();
|
||||||
|
}
|
||||||
|
case 26:
|
||||||
|
return new LastLevel();
|
||||||
|
default:
|
||||||
|
Statistics.deepestFloor--;
|
||||||
|
return new DeadEndLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -256,6 +256,9 @@ public abstract class RegularLevel extends Level {
|
||||||
initRooms.add(new MagicDimandRoom());
|
initRooms.add(new MagicDimandRoom());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initRooms.add(new EyeRoom());
|
||||||
|
// initRooms.add(new YinYangRoom());
|
||||||
|
|
||||||
if (Dungeon.NxhyshopOnLevel()) {
|
if (Dungeon.NxhyshopOnLevel()) {
|
||||||
initRooms.add(new NxhyShopRoom());
|
initRooms.add(new NxhyShopRoom());
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,22 @@ public abstract class Painter {
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
|
|
||||||
|
|
||||||
|
//绘制圆形
|
||||||
|
public static void drawCircle(Level level, Point center, int radius, int terrain) {
|
||||||
|
int cx = center.x;
|
||||||
|
int cy = center.y;
|
||||||
|
for (int x = cx - radius; x <= cx + radius; x++) {
|
||||||
|
for (int y = cy - radius; y <= cy + radius; y++) {
|
||||||
|
int dx = x - cx;
|
||||||
|
int dy = y - cy;
|
||||||
|
if (dx * dx + dy * dy <= radius * radius) {
|
||||||
|
Painter.set(level, x, y, terrain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void set( Level level, int cell, int value ) {
|
public static void set( Level level, int cell, int value ) {
|
||||||
level.map[cell] = value;
|
level.map[cell] = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import com.shatteredpixel.shatteredpixeldungeon.Conducts;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EyeRoom;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.YinYangRoom;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
import com.watabou.utils.Reflection;
|
import com.watabou.utils.Reflection;
|
||||||
|
@ -85,12 +87,13 @@ public abstract class SpecialRoom extends Room {
|
||||||
new ArrayList<>( Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ? Arrays.asList(
|
new ArrayList<>( Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ? Arrays.asList(
|
||||||
CryptRoom.class, PoolRoom.class, ArmoryRoom.class, SentryRoom.class,
|
CryptRoom.class, PoolRoom.class, ArmoryRoom.class, SentryRoom.class,
|
||||||
StatueRoom.class, CrystalVaultRoom.class, CrystalPathRoom.class, CrystalChoiceRoom.class,
|
StatueRoom.class, CrystalVaultRoom.class, CrystalPathRoom.class, CrystalChoiceRoom.class,
|
||||||
SacrificeRoom.class
|
YinYangRoom.class,
|
||||||
|
SacrificeRoom.class, EyeRoom.class
|
||||||
) :
|
) :
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
WeakFloorRoom.class, CryptRoom.class, PoolRoom.class, ArmoryRoom.class, SentryRoom.class,
|
WeakFloorRoom.class, CryptRoom.class, PoolRoom.class, ArmoryRoom.class, SentryRoom.class,
|
||||||
StatueRoom.class, CrystalVaultRoom.class, CrystalPathRoom.class, CrystalChoiceRoom.class,
|
StatueRoom.class, CrystalVaultRoom.class, CrystalPathRoom.class, CrystalChoiceRoom.class, YinYangRoom.class,
|
||||||
SacrificeRoom.class
|
SacrificeRoom.class,EyeRoom.class
|
||||||
));
|
));
|
||||||
|
|
||||||
//9 special rooms which give consumables more often than equipment
|
//9 special rooms which give consumables more often than equipment
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
|
||||||
|
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.depth;
|
||||||
|
import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.EMPTY;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.BruteBot;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Crab;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalMimic;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM201;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.SRPDHBLR;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
|
||||||
|
import com.watabou.utils.Point;
|
||||||
|
|
||||||
|
public class EyeRoom extends SpecialRoom {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int minWidth() {
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int minHeight() {
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxWidth() {
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxHeight() {
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canMerge(Level l, Point p, int mergeTerrain) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Level level) {
|
||||||
|
Point center = new Point((left + right) / 2, (top + bottom) / 2);
|
||||||
|
int eyeRadius = (right - left) / 4;
|
||||||
|
Painter.fill(level,this, EMPTY);
|
||||||
|
|
||||||
|
// 绘制外围墙壁
|
||||||
|
Painter.drawLine(level, new Point(left, top), new Point(right, top), Terrain.WALL);
|
||||||
|
Painter.drawLine(level, new Point(right, top), new Point(right, bottom), Terrain.WALL);
|
||||||
|
Painter.drawLine(level, new Point(right, bottom), new Point(left, bottom), Terrain.WALL);
|
||||||
|
Painter.drawLine(level, new Point(left, bottom), new Point(left, top), Terrain.WALL);
|
||||||
|
|
||||||
|
// 绘制眼睛外圈和门
|
||||||
|
Painter.drawCircle(level, center, eyeRadius, Terrain.EMPTY_SP);
|
||||||
|
Painter.drawCircle(level, center, eyeRadius + 1, Terrain.WALL);
|
||||||
|
|
||||||
|
int doorX = center.x;
|
||||||
|
int doorY = center.y + eyeRadius;
|
||||||
|
|
||||||
|
// 绘制眼睛中心和瞳孔
|
||||||
|
Painter.set(level, center, Terrain.EMPTY_SP);
|
||||||
|
int pupilRadius = eyeRadius / 2;
|
||||||
|
Point pupilPos = center.offset(0, pupilRadius / 2);
|
||||||
|
Painter.drawCircle(level, pupilPos, pupilRadius+1, Terrain.EMPTY_SP);
|
||||||
|
|
||||||
|
// 绘制眼睛眉毛
|
||||||
|
Point browStart = center.offset(-eyeRadius - 1, -3);
|
||||||
|
Point browEnd = center.offset(eyeRadius + 1, -3);
|
||||||
|
|
||||||
|
// 绘制眼瞳
|
||||||
|
Painter.set(level, doorX, doorY - 3, Terrain.PEDESTAL);
|
||||||
|
|
||||||
|
int chestPos = (top + 6) * level.width() + left + 6;
|
||||||
|
|
||||||
|
/** 套五个宝箱 */
|
||||||
|
level.drop( new Gold(),chestPos).type = Heap.Type.TELECRYSTL;
|
||||||
|
level.mobs.add(Mimic.spawnAt(chestPos,( Generator.randomUsingDefaults( Generator.Category.POTION ) ), CrystalMimic.class));
|
||||||
|
level.mobs.add(Mimic.spawnAt(chestPos,( Generator.randomUsingDefaults( Generator.Category.SCROLL ) ), CrystalMimic.class));
|
||||||
|
level.mobs.add(Mimic.spawnAt(chestPos,( Generator.randomUsingDefaults( Generator.Category.WEAPON ) ),
|
||||||
|
CrystalMimic.class));
|
||||||
|
level.mobs.add(Mimic.spawnAt(chestPos,( Generator.randomUsingDefaults( Generator.Category.ARMOR ) ), CrystalMimic.class));
|
||||||
|
|
||||||
|
//四大恶人
|
||||||
|
int[] MBTPOS = new int[]{
|
||||||
|
(top + 4) * level.width() + left + 6,
|
||||||
|
(top + 8) * level.width() + left + 6,
|
||||||
|
(top + 6) * level.width() + left + 4,
|
||||||
|
(top + 6) * level.width() + left + 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
for (int i : MBTPOS) {
|
||||||
|
Mob n = new Crab();
|
||||||
|
if(depth >= 20){
|
||||||
|
n = new Eye();
|
||||||
|
} else if(depth >= 15) {
|
||||||
|
n = new BruteBot();
|
||||||
|
} else if(depth >= 10) {
|
||||||
|
n = new DM201();
|
||||||
|
} else if(depth >= 6){
|
||||||
|
n = new SRPDHBLR();
|
||||||
|
}
|
||||||
|
|
||||||
|
n.pos = i;
|
||||||
|
level.mobs.add(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int TopPos = (top + 1) * level.width() + left + 6;
|
||||||
|
|
||||||
|
int BotPos = (top + 11) * level.width() + left + 6;
|
||||||
|
|
||||||
|
int LeftPos = (top + 6) * level.width() + left + 1;
|
||||||
|
|
||||||
|
int RightPos = (top + 6) * level.width() + left + 11;
|
||||||
|
|
||||||
|
/** 小时候诋毁cocoa,长大后质疑cocoa,成年后认可cocoa,现在成为cocoa
|
||||||
|
/** Watabou看看你的房间是多么的恶心
|
||||||
|
/** 由于房间类的特殊性质,无法直接从外部调用 */
|
||||||
|
level.drop( ( Generator.randomUsingDefaults( Generator.Category.ARTIFACT )),LeftPos).type = Heap.Type.WHITETOMB;
|
||||||
|
level.drop( ( Generator.randomUsingDefaults( Generator.Category.GOLD )),RightPos).type = Heap.Type.TOMB;
|
||||||
|
level.drop( ( Generator.randomUsingDefaults( Generator.Category.GOLD )),BotPos).type = Heap.Type.TOMB;
|
||||||
|
level.drop( ( Generator.randomUsingDefaults( Generator.Category.GOLD )),TopPos).type = Heap.Type.TOMB;
|
||||||
|
|
||||||
|
// 添加边界检查
|
||||||
|
browStart.x = Math.max(browStart.x, left + 1);
|
||||||
|
browStart.x = Math.min(browStart.x, right - 1);
|
||||||
|
browEnd.x = Math.max(browEnd.x, left + 1);
|
||||||
|
browEnd.x = Math.min(browEnd.x, right - 1);
|
||||||
|
Painter.drawLine(level, browStart, browEnd, Terrain.WALL);
|
||||||
|
|
||||||
|
for (Door door : connected.values()) {
|
||||||
|
door.set(Door.Type.HIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CrystalMimic;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLevitation;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
|
||||||
|
import com.watabou.utils.Point;
|
||||||
|
import com.watabou.utils.Random;
|
||||||
|
import com.watabou.utils.Rect;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class YinYangRoom extends SpecialRoom {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int minWidth() { return 11; }
|
||||||
|
@Override
|
||||||
|
public int minHeight() {
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int maxWidth() { return 11; }
|
||||||
|
@Override
|
||||||
|
public int maxHeight() {
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean canMerge(Level l, Point p, int mergeTerrain) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect resize(int w, int h) {
|
||||||
|
super.resize(w, h);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item prize() {
|
||||||
|
Generator.Category cat = prizeClasses.remove(0);
|
||||||
|
prizeClasses.add(cat);
|
||||||
|
Item prize;
|
||||||
|
do {
|
||||||
|
prize = Generator.random(cat);
|
||||||
|
prize.level= Random.NormalIntRange(1,2);
|
||||||
|
prize.cursed = false;
|
||||||
|
} while (Challenges.isItemBlocked(prize));
|
||||||
|
return prize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item Blackprize() {
|
||||||
|
Generator.Category cat = prizeClasses.remove(0);
|
||||||
|
prizeClasses.add(cat);
|
||||||
|
Item prize;
|
||||||
|
do {
|
||||||
|
prize = Generator.random(cat);
|
||||||
|
prize.level= Random.NormalIntRange(2,3);
|
||||||
|
prize.cursed = true;
|
||||||
|
} while (Challenges.isItemBlocked(prize));
|
||||||
|
return prize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Generator.Category> prizeClasses = new ArrayList<>(
|
||||||
|
Arrays.asList(Generator.Category.WAND,
|
||||||
|
Generator.Category.RING,
|
||||||
|
Generator.Category.ARTIFACT));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Level level) {
|
||||||
|
Point a = new Point((left + right) / 2 + (right - left + 2) / 4 - 1,top + (right - left + 2) / 4 - 1);
|
||||||
|
Point b = new Point((left + right) / 2 - (right - left + 2) / 4 + 1,bottom - (right - left + 2) / 4 + 1);
|
||||||
|
|
||||||
|
Painter.fill(level,this,Terrain.WALL);
|
||||||
|
Painter.fill(level,left + 1,top + 1,width() - 2,height() - 2,Terrain.WATER);
|
||||||
|
|
||||||
|
for (int i = 1;i < right - left;i++) {
|
||||||
|
for (int j =1;j < bottom - top;j++) {
|
||||||
|
if (i + j < right - left + 1) {
|
||||||
|
Painter.set(level,left + i,top + j,Terrain.CHASM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter.fill(level,a.x,top + 1,right - a.x,a.y - top + 1,Terrain.WATER);
|
||||||
|
Painter.fill(level,left + 1,b.y,b.x - left,bottom - b.y,Terrain.CHASM);
|
||||||
|
|
||||||
|
Painter.drawLine(level,new Point((left + right) / 2,top),a,Terrain.WALL);
|
||||||
|
Painter.drawLine(level,new Point((left + right) / 2,bottom),b,Terrain.WALL);
|
||||||
|
Painter.drawLine(level,a.offset(0,1),b.offset(0,-1),Terrain.WALL);
|
||||||
|
|
||||||
|
int chestPos = left + right - a.x + a.y * level.width();
|
||||||
|
|
||||||
|
int chestPos2 = left + right - b.x + b.y * level.width();
|
||||||
|
|
||||||
|
Painter.set(level,chestPos,Terrain.PEDESTAL);
|
||||||
|
level.drop(prize(), chestPos).type = Heap.Type.CRYSTAL_CHEST;
|
||||||
|
Painter.set(level,chestPos2,Terrain.EMPTY_SP);
|
||||||
|
|
||||||
|
if (Random.Int(10) == 0){
|
||||||
|
level.mobs.add(Mimic.spawnAt(chestPos2,Blackprize(), CrystalMimic.class));
|
||||||
|
} else {
|
||||||
|
level.drop(prize(), chestPos2).type = Heap.Type.CRYSTAL_CHEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter.set(level,left + 1,top + 1,Terrain.WALL);
|
||||||
|
Painter.set(level,right - 1,top + 1,Terrain.WALL);
|
||||||
|
Painter.set(level,left + 1,bottom - 1,Terrain.WALL);
|
||||||
|
Painter.set(level,right - 1,bottom - 1,Terrain.WALL);
|
||||||
|
|
||||||
|
for (Door door : connected.values()) {
|
||||||
|
door.set(Door.Type.HIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
level.addItemToSpawn( new CrystalKey( Dungeon.depth ) );
|
||||||
|
level.addItemToSpawn( new PotionOfLevitation());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1423,7 +1423,7 @@ public class GameScene extends PixelScene {
|
||||||
Buff.detach( ch, MagicGirlSayTimeLast.class );
|
Buff.detach( ch, MagicGirlSayTimeLast.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Boss 出场的Logo显示 灵感:泰拉瑞亚灾厄炼狱 */
|
||||||
public static void bossReady() {
|
public static void bossReady() {
|
||||||
if (Dungeon.hero.isAlive()) {
|
if (Dungeon.hero.isAlive()) {
|
||||||
Banner bossSlain = new Banner( BannerSprites.get( BannerSprites.Type.NULL ) );
|
Banner bossSlain = new Banner( BannerSprites.get( BannerSprites.Type.NULL ) );
|
||||||
|
@ -1438,10 +1438,10 @@ public class GameScene extends PixelScene {
|
||||||
scene.showBanner( bossSlain );
|
scene.showBanner( bossSlain );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 0:
|
||||||
if(!Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ) {
|
if(Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ) {
|
||||||
bossSlain.texture(Assets.Interfaces.QliPhoth_Title);
|
bossSlain.texture(Assets.Interfaces.SakaBJY_Title);
|
||||||
bossSlain.show(0xFFFFFF, 0.3f, 5f);
|
bossSlain.show( Window.CYELLOW, 0.3f, 5f);
|
||||||
scene.showBanner(bossSlain);
|
scene.showBanner(bossSlain);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1472,10 +1472,10 @@ public class GameScene extends PixelScene {
|
||||||
scene.showBanner( bossSlain );
|
scene.showBanner( bossSlain );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 0:
|
||||||
if(!Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ) {
|
if(Dungeon.isDLC(Conducts.Conduct.BOSSRUSH) ) {
|
||||||
bossSlain.texture(Assets.Interfaces.QliPhoth_Clear);
|
bossSlain.texture(Assets.Interfaces.SakaBJY_Clear);
|
||||||
bossSlain.show(0xFFFFFF, 0.3f, 5f);
|
bossSlain.show( Window.CYELLOW, 0.3f, 5f);
|
||||||
scene.showBanner(bossSlain);
|
scene.showBanner(bossSlain);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class InterlevelScene extends PixelScene {
|
||||||
public static int returnBranch;
|
public static int returnBranch;
|
||||||
|
|
||||||
public enum Mode {
|
public enum Mode {
|
||||||
DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL, RESET, NONE,EXBOSS,GOBACK,FRGIRLBOSS,DR,
|
DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL, RESET, NONE,EXBOSS,GOBACK,FRGIRLBOSS,ANCITYBOSS,DR,
|
||||||
}
|
}
|
||||||
public static Mode mode;
|
public static Mode mode;
|
||||||
|
|
||||||
|
@ -285,6 +285,9 @@ public class InterlevelScene extends PixelScene {
|
||||||
case FRGIRLBOSS:
|
case FRGIRLBOSS:
|
||||||
exboss(2);
|
exboss(2);
|
||||||
break;
|
break;
|
||||||
|
case ANCITYBOSS:
|
||||||
|
exboss(3);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +566,9 @@ public class InterlevelScene extends PixelScene {
|
||||||
case 2:
|
case 2:
|
||||||
level=Dungeon.ColdFlowerCanyonDie();
|
level=Dungeon.ColdFlowerCanyonDie();
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
level=Dungeon.AncityWaterLevel();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
level = Dungeon.newLevel();
|
level = Dungeon.newLevel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,13 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
|
||||||
jump( from, to, callback, distance * 2, distance * 0.1f );
|
jump( from, to, callback, distance * 2, distance * 0.1f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dirtcar( int from, int to, Callback callback ) {
|
||||||
|
float distance = Dungeon.level.trueDistance( from, to );
|
||||||
|
jump( from, to, callback, 0, distance * 0.1f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void jump( int from, int to, Callback callback, float height, float duration ) {
|
public void jump( int from, int to, Callback callback, float height, float duration ) {
|
||||||
jumpCallback = callback;
|
jumpCallback = callback;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.watabou.noosa.TextureFilm;
|
||||||
|
|
||||||
|
public class DictFishSprites extends MobSprite {
|
||||||
|
|
||||||
|
public DictFishSprites() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
texture( Assets.Sprites.DICT );
|
||||||
|
|
||||||
|
TextureFilm frames = new TextureFilm( texture, 24, 11 );
|
||||||
|
|
||||||
|
idle = new Animation( 2, true );
|
||||||
|
idle.frames( frames, 0, 0, 0, 1 );
|
||||||
|
|
||||||
|
run = new Animation( 10, true );
|
||||||
|
run.frames( frames, 6, 7, 8, 9, 10 );
|
||||||
|
|
||||||
|
attack = new Animation( 15, false );
|
||||||
|
attack.frames( frames, 2, 3, 4, 5, 0 );
|
||||||
|
|
||||||
|
die = new Animation( 10, false );
|
||||||
|
die.frames( frames, 11, 12, 13, 14,15 );
|
||||||
|
|
||||||
|
play( idle );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -207,10 +207,12 @@ public class ItemSprite extends MovieClip {
|
||||||
return view( ItemSpriteSheet.CHEST, null );
|
return view( ItemSpriteSheet.CHEST, null );
|
||||||
case LOCKED_CHEST:
|
case LOCKED_CHEST:
|
||||||
return view( ItemSpriteSheet.LOCKED_CHEST, null );
|
return view( ItemSpriteSheet.LOCKED_CHEST, null );
|
||||||
case CRYSTAL_CHEST:
|
case CRYSTAL_CHEST:case TELECRYSTL:
|
||||||
return view( ItemSpriteSheet.CRYSTAL_CHEST, null );
|
return view( ItemSpriteSheet.CRYSTAL_CHEST, null );
|
||||||
case TOMB:
|
case TOMB:
|
||||||
return view( ItemSpriteSheet.TOMB, null );
|
return view( ItemSpriteSheet.TOMB, null );
|
||||||
|
case WHITETOMB:
|
||||||
|
return view( ItemSpriteSheet.GRAVE, null );
|
||||||
case SKELETON:
|
case SKELETON:
|
||||||
return view( ItemSpriteSheet.BONES, null );
|
return view( ItemSpriteSheet.BONES, null );
|
||||||
case REMAINS:
|
case REMAINS:
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
||||||
|
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.watabou.noosa.MovieClip;
|
||||||
|
import com.watabou.noosa.TextureFilm;
|
||||||
|
|
||||||
|
public class RoomStoneSprites extends MobSprite {
|
||||||
|
|
||||||
|
public RoomStoneSprites() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
texture( Assets.Sprites.ROOMSTONE);
|
||||||
|
|
||||||
|
TextureFilm frames = new TextureFilm( texture, 18, 20 );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
attack = new MovieClip.Animation( 15, false );
|
||||||
|
attack.frames( frames, 2, 3, 4, 5, 0 );
|
||||||
|
|
||||||
|
die = new MovieClip.Animation( 10, false );
|
||||||
|
die.frames( frames, 11, 12, 13, 14 );
|
||||||
|
|
||||||
|
play( idle );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,24 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.bosses.SakaFishBoss;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Beam;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
|
||||||
import com.watabou.noosa.TextureFilm;
|
import com.watabou.noosa.TextureFilm;
|
||||||
|
import com.watabou.noosa.audio.Sample;
|
||||||
|
import com.watabou.noosa.particles.Emitter;
|
||||||
|
|
||||||
public class SakaFishBossSprites extends MobSprite {
|
public class SakaFishBossSprites extends MobSprite {
|
||||||
|
private Animation leap;
|
||||||
|
|
||||||
|
private int zapPos;
|
||||||
|
private Animation activeIdle;
|
||||||
|
|
||||||
|
private Animation charging;
|
||||||
|
private Emitter chargeParticles;
|
||||||
public SakaFishBossSprites() {
|
public SakaFishBossSprites() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -15,17 +29,120 @@ public class SakaFishBossSprites extends MobSprite {
|
||||||
idle = new Animation( 4, true );
|
idle = new Animation( 4, true );
|
||||||
idle.frames( frames, 14,15,16,17 );
|
idle.frames( frames, 14,15,16,17 );
|
||||||
|
|
||||||
|
activeIdle = new Animation( 4, true );
|
||||||
|
activeIdle.frames( frames, 18,19,20,21);
|
||||||
|
|
||||||
run = new Animation( 10, true );
|
run = new Animation( 10, true );
|
||||||
run.frames( frames, 2,3 );
|
run.frames( frames, 2,3 );
|
||||||
|
|
||||||
attack = new Animation( 15, false );
|
attack = new Animation( 15, false );
|
||||||
attack.frames( frames, 4,5,6 );
|
attack.frames( frames, 4,5,6 );
|
||||||
|
zap = attack.clone();
|
||||||
|
|
||||||
die = new Animation( 10, false );
|
die = new Animation( 10, false );
|
||||||
die.frames( frames, 1 );
|
die.frames( frames, 1 );
|
||||||
|
|
||||||
|
leap = new Animation( 2, true );
|
||||||
|
leap.frames( frames, 52,53,54,55 );
|
||||||
|
|
||||||
|
charging = new Animation( 20, true);
|
||||||
|
charging.frames( frames, 28, 29,30,31,32,33,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31,29,30,31 );
|
||||||
|
|
||||||
play( idle );
|
play( idle );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//哦 创死你
|
||||||
|
public void leapPrep( int cell ){
|
||||||
|
turnTo( ch.pos, cell );
|
||||||
|
play( leap );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activate(){
|
||||||
|
idle = activeIdle.clone();
|
||||||
|
idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zap( int pos ) {
|
||||||
|
zapPos = pos;
|
||||||
|
super.zap( pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
//超级激光
|
||||||
|
public void charge( int pos ){
|
||||||
|
turnTo(ch.pos, pos);
|
||||||
|
play(charging);
|
||||||
|
if (visible) Sample.INSTANCE.play( Assets.Sounds.CHARGEUP );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void link(Char ch) {
|
||||||
|
super.link(ch);
|
||||||
|
|
||||||
|
chargeParticles = centerEmitter();
|
||||||
|
chargeParticles.autoKill = false;
|
||||||
|
chargeParticles.pour(MagicMissile.MagicParticle.ATTRACTING, 0.05f);
|
||||||
|
chargeParticles.on = false;
|
||||||
|
|
||||||
|
if (((SakaFishBoss)ch).beamCharged) play(charging);
|
||||||
|
|
||||||
|
if (((SakaFishBoss) ch).state != ((SakaFishBoss) ch).SLEEPING){
|
||||||
|
activate();
|
||||||
|
}
|
||||||
|
renderShadow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
super.update();
|
||||||
|
if (chargeParticles != null){
|
||||||
|
chargeParticles.pos( center() );
|
||||||
|
chargeParticles.visible = visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void die() {
|
||||||
|
super.die();
|
||||||
|
if (chargeParticles != null){
|
||||||
|
chargeParticles.on = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void kill() {
|
||||||
|
super.kill();
|
||||||
|
if (chargeParticles != null){
|
||||||
|
chargeParticles.killAndErase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void play(Animation anim) {
|
||||||
|
if (chargeParticles != null) chargeParticles.on = anim == charging;
|
||||||
|
super.play(anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete( Animation anim ) {
|
||||||
|
super.onComplete( anim );
|
||||||
|
|
||||||
|
if (anim == zap) {
|
||||||
|
idle();
|
||||||
|
if (Actor.findChar(zapPos) != null){
|
||||||
|
parent.add(new Beam.DeathRayS(center(), Actor.findChar(zapPos).sprite.center()));
|
||||||
|
} else {
|
||||||
|
parent.add(new Beam.DeathRayS(center(), DungeonTilemap.raisedTileCenterToWorld(zapPos)));
|
||||||
|
}
|
||||||
|
((SakaFishBoss)ch).deathGaze();
|
||||||
|
ch.next();
|
||||||
|
} else if (anim == die){
|
||||||
|
chargeParticles.killAndErase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class SalamanderSprites extends MobSprite {
|
||||||
cast = attack.clone();
|
cast = attack.clone();
|
||||||
|
|
||||||
die = new MovieClip.Animation( 12, false );
|
die = new MovieClip.Animation( 12, false );
|
||||||
die.frames( frames, 7 );
|
die.frames( frames, 7,8,9 );
|
||||||
|
|
||||||
play( idle );
|
play( idle );
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.RedSwarmSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.SRPDHBLRTT;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.SRPDHBLRTT;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.SalamanderSprites;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.SalamanderSprites;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkKingSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkKingSprite;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ShopkeeperSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.SlimeKingSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.SlimeKingSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.SnakeSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.SnakeSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.WFSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.WFSprite;
|
||||||
|
@ -54,6 +55,7 @@ import java.util.ArrayList;
|
||||||
public class vM0_6_7_X_Changes {
|
public class vM0_6_7_X_Changes {
|
||||||
|
|
||||||
public static void addAllChanges(ArrayList<ChangeInfo> changeInfos) {
|
public static void addAllChanges(ArrayList<ChangeInfo> changeInfos) {
|
||||||
|
add_v0_6_54_Changes(changeInfos);
|
||||||
add_v0_6_53_Changes(changeInfos);
|
add_v0_6_53_Changes(changeInfos);
|
||||||
add_v0_6_52_Changes(changeInfos);
|
add_v0_6_52_Changes(changeInfos);
|
||||||
add_v0_6_51_Changes(changeInfos);
|
add_v0_6_51_Changes(changeInfos);
|
||||||
|
@ -110,6 +112,34 @@ public class vM0_6_7_X_Changes {
|
||||||
add_v0_6_0_Changes(changeInfos);
|
add_v0_6_0_Changes(changeInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void add_v0_6_54_Changes( ArrayList<ChangeInfo> changeInfos ) {
|
||||||
|
ChangeInfo changes = new ChangeInfo("v0.6.4.0-Beta1", 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 Image(Assets.Environment.TILES_SEWERS, 48, 48, 16
|
||||||
|
, 16), "房间改动",
|
||||||
|
"全新房间:慧眼墓碑房/太极八卦房加入"));
|
||||||
|
|
||||||
|
changes.addButton(new ChangeButton(new ShopkeeperSprite(), ("回购系统"),
|
||||||
|
("商店追加回购系统,除了商人领主和奈亚子均可原价退回商品")));
|
||||||
|
|
||||||
|
changes = new ChangeInfo("改动", false, null);
|
||||||
|
changes.hardlight(Window.CYELLOW);
|
||||||
|
changeInfos.add(changes);
|
||||||
|
|
||||||
|
changes.addButton(new ChangeButton(new PinkLingSprite(), ("杂项改动"),
|
||||||
|
("优化地牢部分数据,并且为即将更新的每日狩猎等设好底层。")));
|
||||||
|
|
||||||
|
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_06X81")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void add_v0_6_53_Changes( ArrayList<ChangeInfo> changeInfos ) {
|
public static void add_v0_6_53_Changes( ArrayList<ChangeInfo> changeInfos ) {
|
||||||
ChangeInfo changes = new ChangeInfo("v0.6.3.0-Beta5-5.1", true, "");
|
ChangeInfo changes = new ChangeInfo("v0.6.3.0-Beta5-5.1", true, "");
|
||||||
changes.hardlight(Window.TITLE_COLOR);
|
changes.hardlight(Window.TITLE_COLOR);
|
||||||
|
|
|
@ -195,7 +195,7 @@ public class WndRedDragon extends Window {
|
||||||
@Override
|
@Override
|
||||||
protected void onClick() {
|
protected void onClick() {
|
||||||
RewardWindow.this.hide();
|
RewardWindow.this.hide();
|
||||||
if (rewardObtained == false) {
|
if (!rewardObtained) {
|
||||||
WndRedDragon.this.selectReward(item);
|
WndRedDragon.this.selectReward(item);
|
||||||
} else {
|
} else {
|
||||||
GLog.b(Messages.get(this, "why"));
|
GLog.b(Messages.get(this, "why"));
|
||||||
|
|
|
@ -26,6 +26,8 @@ import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.shopOnLevel;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Conducts;
|
import com.shatteredpixel.shatteredpixeldungeon.Conducts;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ShopGuardDead;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ShopGuardDead;
|
||||||
|
@ -61,13 +63,20 @@ public class WndTradeItem extends WndInfoItem {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
|
||||||
float pos = height;
|
float pos = height;
|
||||||
|
Shopkeeper shop = null;
|
||||||
|
for (Char ch : Actor.chars()){
|
||||||
|
if (ch instanceof Shopkeeper){
|
||||||
|
shop = (Shopkeeper) ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Shopkeeper finalShop = shop;
|
||||||
if (item.quantity() == 1) {
|
if (item.quantity() == 1) {
|
||||||
|
|
||||||
RedButton btnSell = new RedButton( Messages.get(this, "sell", item.value()) ) {
|
RedButton btnSell = new RedButton( Messages.get(this, "sell", item.value()) ) {
|
||||||
@Override
|
@Override
|
||||||
protected void onClick() {
|
protected void onClick() {
|
||||||
sell( item );
|
sell( item,finalShop );
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -93,7 +102,7 @@ public class WndTradeItem extends WndInfoItem {
|
||||||
RedButton btnSellAll = new RedButton( Messages.get(this, "sell_all", priceAll ) ) {
|
RedButton btnSellAll = new RedButton( Messages.get(this, "sell_all", priceAll ) ) {
|
||||||
@Override
|
@Override
|
||||||
protected void onClick() {
|
protected void onClick() {
|
||||||
sell( item );
|
sell( item,finalShop );
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -217,11 +226,11 @@ public class WndTradeItem extends WndInfoItem {
|
||||||
}
|
}
|
||||||
if (selling) Shopkeeper.sell();
|
if (selling) Shopkeeper.sell();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sell( Item item ) {
|
public static void sell( Item item, Shopkeeper shop ) {
|
||||||
|
|
||||||
Hero hero = Dungeon.hero;
|
Hero hero = Dungeon.hero;
|
||||||
|
|
||||||
if (item.isEquipped( hero ) && !((EquipableItem)item).doUnequip( hero, false )) {
|
if (item.isEquipped( hero ) && !((EquipableItem)item).doUnequip( hero, false )) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -229,24 +238,42 @@ public class WndTradeItem extends WndInfoItem {
|
||||||
|
|
||||||
//selling items in the sell interface doesn't spend time
|
//selling items in the sell interface doesn't spend time
|
||||||
hero.spend(-hero.cooldown());
|
hero.spend(-hero.cooldown());
|
||||||
Statistics.totalScore += 400;
|
|
||||||
new Gold( item.value() ).doPickUp( hero );
|
new Gold( item.value() ).doPickUp( hero );
|
||||||
|
|
||||||
|
if (shop != null){
|
||||||
|
shop.buybackItems.add(item);
|
||||||
|
while (shop.buybackItems.size() > Shopkeeper.MAX_BUYBACK_HISTORY){
|
||||||
|
shop.buybackItems.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sellOne( Item item ) {
|
public static void sellOne( Item item ) {
|
||||||
|
sellOne( item, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sellOne( Item item, Shopkeeper shop ) {
|
||||||
|
|
||||||
if (item.quantity() <= 1) {
|
if (item.quantity() <= 1) {
|
||||||
sell( item );
|
sell( item, shop );
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Hero hero = Dungeon.hero;
|
Hero hero = Dungeon.hero;
|
||||||
Statistics.totalScore += 100;
|
|
||||||
item = item.detach( hero.belongings.backpack );
|
item = item.detach( hero.belongings.backpack );
|
||||||
|
|
||||||
//selling items in the sell interface doesn't spend time
|
//selling items in the sell interface doesn't spend time
|
||||||
hero.spend(-hero.cooldown());
|
hero.spend(-hero.cooldown());
|
||||||
|
|
||||||
new Gold( item.value() ).doPickUp( hero );
|
new Gold( item.value() ).doPickUp( hero );
|
||||||
|
|
||||||
|
if (shop != null){
|
||||||
|
shop.buybackItems.add(item);
|
||||||
|
while (shop.buybackItems.size() > Shopkeeper.MAX_BUYBACK_HISTORY){
|
||||||
|
shop.buybackItems.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|