diff --git a/build.gradle b/build.gradle index 438ce0268..3e4d5ed16 100644 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,8 @@ allprojects { appName = 'Magic Ling Pixel Dungeon' appPackageName = 'com.ansdomagiclingpixeldungeon.ling' - appVersionCode =907550 - appVersionName = '0.6.5.0-Alpha4.5' + appVersionCode =907700 + appVersionName = '0.6.5.0-Alpha5.1' appJavaCompatibility = JavaVersion.VERSION_11 diff --git a/core/src/main/assets/SRPD/TorchHuntsman.png b/core/src/main/assets/SRPD/TorchHuntsman.png index 5e5fca123..34c037d2f 100644 Binary files a/core/src/main/assets/SRPD/TorchHuntsman.png and b/core/src/main/assets/SRPD/TorchHuntsman.png differ diff --git a/core/src/main/assets/environment/tiles_garden.png b/core/src/main/assets/environment/tiles_garden.png new file mode 100644 index 000000000..22982d700 Binary files /dev/null and b/core/src/main/assets/environment/tiles_garden.png differ diff --git a/core/src/main/assets/interfaces/icons.png b/core/src/main/assets/interfaces/icons.png index a1e2cdbb5..06f63f7e1 100644 Binary files a/core/src/main/assets/interfaces/icons.png and b/core/src/main/assets/interfaces/icons.png differ diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 69d467f1f..a28193f48 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -1,5 +1,54 @@ #####MLPD-P3文本 +actors.mobs.npcs.pinkghost.name=粉色幽灵 +actors.mobs.npcs.pinkghost.desc=这个幽灵正在发出非常靓丽的光芒,在地牢中就像一盏希望的冥灯。这个幽灵的脸上露出了灿烂的笑容…… + +actors.mobs.npcs.ghostnpc.name=悲伤幽灵 +actors.mobs.npcs.ghostnpc.desc=这个幽灵几乎不能被看见。它看起来像是由一片无形的昏暗光斑和一张悲痛的面孔所组成的。 + +actors.mobs.npcs.pinkghostnpc.name=粉色幽灵 +actors.mobs.npcs.pinkghostnpc.desc=这个幽灵正在发出非常靓丽的光芒,在地牢中就像一盏希望的冥灯。这个幽灵的脸上露出了灿烂的笑容…… + +actors.mobs.npcs.pinkghost.hello=你好呀,冒险家,啊,请不要害怕我,我曾经也是你们的一员。 +actors.mobs.npcs.pinkghost.hello_1=你能帮我一个忙吗?在这层地牢里有个隐藏的花园,在哪里我记不太清了,总之,里面有一朵白色的玫瑰,那是前一段时间我种下的,现在应该已经开花了。说起来,在地牢里收集玫瑰种子真不容易。另外,在那个花园有一些游走的幽灵,它们与我不一样,它们是可怕的怨灵。 +actors.mobs.npcs.pinkghost.hello_2=你可以帮我找回那朵花吗?如果可以的话,我这里有些可能有用的东西,到时候就和你交换好了。 +actors.mobs.npcs.pinkghost.hello_3=如果你后面准备好了,就再次和我对话,我会使用我的力量让你前往那里的。 +actors.mobs.npcs.pinkghost.good_desc=啊呀,谢谢你,我还以为我再也见不到这朵玫瑰了呢。\n\n把玫瑰给我吧,给你的东西我已经带过来了,希望对你接下来的旅途能有所帮助。 +actors.mobs.npcs.pinkghost.why_red=你已经回来了,但你这里并没有白玫瑰,你丢掉它了吗? +actors.mobs.npcs.pinkghost.giverose=给予白玫瑰 +actors.mobs.npcs.pinkghost.givemoon=给予小月饼 +actors.mobs.npcs.pinkghost.whatmoon=啊拉,谢谢你,幽灵是不用吃月饼的,你的心意我就收下了。 +actors.mobs.npcs.pinkghost.moonname=等等,这个月饼......上面为什么会有我的名字?\n\n什么,是一个幽灵给你的?难道他......他真的...... +actors.mobs.npcs.pinkghost.moonlost=粉色的幽灵带着月饼消失了...... +actors.mobs.npcs.pinkghost.goodluck=祝你一路顺风,冒险家! +actors.mobs.npcs.pinkghost.not_sorry=抱歉,冒险家,让你看见了我伤心的样子...... +actors.mobs.npcs.pinkghost.not_sorry_1=我之前说过,我也是冒险家,不过在我进地牢前就已经放弃了冒险家的身份了。我之所以在地牢里变成这副样子,是为了我的爱人。 +actors.mobs.npcs.pinkghost.not_sorry_2=我的爱人准备与我结婚前最后完成一件任务,我记得是在地牢浅层收集材料。可是过了好几天也不见他回来,我很着急,但是没有冒险家协会的许可或冒险家的担保的话是无法进入地牢的,所以我找到了_罗伦斯_,他是一名矮人工匠,也不是冒险家协会的成员。但是,他帮我找到了一条能够避开守卫的路,最终,我们成功进入了地牢。 +actors.mobs.npcs.pinkghost.not_sorry_3=进入地牢后,罗伦斯便不知所踪,我只得一个人探索。\n\n但是,我没能在前几层找到他,我猜想可能是他去到了更深的地方,便继续探索,直到我最终不幸倒在了毒气里......但是万幸,有位穿棕色斗篷的人救了我,只是我的肉体受伤太严重,他只得先冰封我的肉体,让我以灵魂姿态继续游荡在这黑暗的地牢......可是,我还是没能寻到他的线索。我便猜想,我可能太着急了,他应该早就回去了,只是先去旁边的镇子休整两天而已。可是,我已经没法再回头了。 +actors.mobs.npcs.pinkghost.not_sorry_4=既然你从一位幽灵那里拿到了这块月饼,那说明他也遭遇了不测......但我还会继续寻找他的。哪怕我们再也无法回到地面,再也无法像以前一样相拥而眠,再也无法笨拙地给对方烤制不知道什么馅的月饼,我也会寻找他的。 +actors.mobs.npcs.pinkghost.talk_desc=我相信他还在那里等我。\n\n总之,谢谢你。\n\n对了,这些东西忘记给你了,真诚的希望能帮上你的忙。\n\n白玫瑰就留给你做纪念了…… +actors.mobs.npcs.pinkghost.givego=收下物品 +actors.mobs.npcs.pinkghost.take=他就在这里! +actors.mobs.npcs.pinkghost.whathere=啊,他不在这里的。谢谢你安慰我…… +actors.mobs.npcs.pinkghost.rose=等等,这是......我送他的玫瑰!这么久了,竟然还没枯死吗......\n\n难道,他,他就在这附近? + +actors.mobs.npcs.pinkghost.love&love=他们以不存在的形体再次拥抱在一起。白玫瑰和红玫瑰轻轻地从他们手中落下。一种说不上来的情感布满了你的心头。 + +actors.mobs.npcs.ghostnpc.love=亲爱的,是我..... +actors.mobs.npcs.pinkghost.oh_no=天啊!你......你怎么也变成这副模样了? +actors.mobs.npcs.ghostnpc.sorry=对不起,我......疏忽了。 +actors.mobs.npcs.pinkghost.linklove=不,该说抱歉的是我,我应该和你一起去的...... + +actors.mobs.npcs.pinkghost.thanks=冒险家,我非常感谢您的帮助。 +actors.mobs.npcs.pinkghost.thanks_1=没有你,我无法和我的爱人重逢。 +actors.mobs.npcs.pinkghost.thanks_2=我的救命恩人在召唤我了,我的爱人也会和我一起去见祂。 +actors.mobs.npcs.pinkghost.thanks_3=或许在今后的轮回旅途中,我和你以及我的爱人见面次数会更少。但请告诉轮回中的他,我一直都在他旁边。 +actors.mobs.npcs.pinkghost.thanks_4=再见,%s。 +actors.mobs.npcs.pinkghost.thanks_5=它们消失在了空气中,只有一束白玫瑰和红玫瑰并发着红色光芒见证它们的挚爱之情…… + +actors.mobs.bluewraith.name=蓝色怨灵 +actors.mobs.bluewraith.desc=这个怨灵曾经与你一样都是地牢的佼佼者,由于一些原因被困在了这里,并最终迎接了死亡…… + actors.mobs.spical.gnollhero.name=豺狼部族长老 actors.mobs.spical.gnollhero.desc=与其他豺狼不同的是,它清楚最大的威胁不是冒险者。同时,它会使用古老的占卜魔法狩猎预知告知玩家即将要狩猎的稀有生物在何处。\n\n但它们并不是完全帮助冒险者,如果冒险者有出格的举动,部族长老会让冒险者知道”叛徒“的下场…… actors.mobs.spical.gnollhero.chat_1=哦,看看这是谁,这不是为了寻找水晶之心的冒险者吗? @@ -2015,6 +2064,9 @@ actors.mobs.gnoll.desc=豺狼是鬣狗状的类人生物。它们在密林和地 actors.mobs.gnolltrickster.name=豺狼诡术师 actors.mobs.gnolltrickster.desc=即使以豺狼人的标准来看,这个生物也非常的诡异。它佝偻着腰,鬼鬼祟祟地行进着,大嘴咧开,露出邪恶的笑容,肩上挂着的挎包鼓得同摇篮一般。它的瞳孔中混杂着恐惧与兴奋。\n\n它的挎包里有一大批粗制滥造的飞镖,它们似乎包含着各种有害物质。 +#actors.mobs.1r.name=兽型猎人 +#actors.mobs.1r.desc=半人半兽的残暴生物。\n\n他曾是一名正常的赏金猎人。地牢中的恐怖之物将他侵蚀,在他意识溃散殆尽后,这里只有仅存癫狂的人形野兽。 + actors.mobs.goldenmimic.name=金色宝箱怪 actors.mobs.goldenmimic.desc=宝箱怪是一种能随意改变外形的魔法生物。在地牢里它们几乎一直以宝箱形态出现,因为这样总能吸引不防备的冒险者。\n\n金色宝箱怪是试图吸引顶尖冒险者的强大宝箱怪。它们拥有更丰厚的财宝,但相对通常的宝箱怪也更为强大。 diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 244c4dc4f..897d4f90f 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -1,5 +1,18 @@ ####MLPD-P3文本 +### 特别武器 + +items.quest.red.name=白玫瑰 +items.quest.red.desc=在这危险而阴森的地牢中,这朵白玫瑰仿佛刺破了周遭的黑暗,向你展示着名为“人文”的力量。 +items.quest.red.ac_interlevel_tp=返回 + +items.quest.redwhiterose.name="一种载体" +items.quest.redwhiterose.desc=他们从未离开,这两束玫瑰配不上他们。\n\n情感无需载体,意志无需证明。\n\n而你也不曾放弃。 + +items.weapon.melee.fiveren.name=五仁月饼 +items.weapon.melee.fiveren.stats_desc=这是一件相当缓慢的武器。\n这把武器有额外的攻击距离。\n该武器有概率腐化敌人。 +items.weapon.melee.fiveren.desc=中秋佳节,祝各位玩家节日快乐。\n\n月饼在古代由来已久,其实月饼最初的原型叫“饼饵”。\n贾公谚:“以酒燚为饼,若今起胶饼”,中秋食月饼的记载多始见于明清时。\n明人田汝成在《西游览志余》中说:“八月十五谓之中秋,民间以月饼遗,取团圆之意。”因古人称中秋为“团圆节”,所以月饼又称“团圆饼”。\n明清时,中秋食月饼的风俗已相当盛行,清人富察敦崇在《燕京岁时记》中说:“中秋月饼,以前门致美斋者为京师第一,他处不足食也。至供月饼,到处皆有,大者尺余,上绘月宫蟾兔之形,有祭毕而食者,有留至除夕而食者,谓之团圆饼”。月饼除了是中秋佳节的必备食品外,还是馈赠亲友的节日礼物。\n\n随着时间的推移,月饼已由当初的家庭手工制作逐渐变成了一种专业化生产,品种不断增多,质量不断提高,明清时已发展成为传统的糕点形式。 + ### 传奇武器 items.weapon.melee.legend.legendweapon.typical_stats_desc=这是一件_%1$s阶_传奇武器,这件传奇武器的技能通常造成为:%2$s\n这个技能通常可以造成_%3$s~%4$s点伤害_。 @@ -101,12 +114,15 @@ items.lightblack.oilpotion.desc=里面蕴含了提灯需要的物质,在提灯 items.lightblack.oilpotion.ac_refill=装填 items.lightblack.oillantern.name = 提灯 -items.lightblack.oillantern.desc = 这盏来自硬化玻璃的提灯是暗无天日的地牢中不可缺少的物品。\n\n即使是在最黑暗的地牢里,这个简单的提灯也能照亮你的道路,只要你有油瓶来保持它的光亮。\n\n在你落寞的时候,她就是你身旁的最好归宿。 +items.lightblack.oillantern.desc = 这盏来自硬化玻璃的提灯是暗无天日的地牢中不可缺少的物品。\n\n即使是在最黑暗的地牢里,这个简单的提灯也能照亮你的道路,只要你有油瓶来保持它的光亮。\n\n在你落寞的时候,她就是你身旁的最好归宿。\n\n目前里面装填了_%1$s_个备用油瓶和_%2$s_个由火把转换的提灯火芯,这些可以补充提灯的灯油以保证它的光亮。 items.lightblack.oillantern.ac_light = 点亮 items.lightblack.oillantern.ac_snuff = 熄灭 items.lightblack.oillantern.ac_refill = 加油 items.lightblack.oillantern.ac_burn = 点燃 +items.lightblack.oillantern.lanternosoul=你陷入灵魂残缺的迷茫当中,因此无法引燃提灯。 +items.lightblack.oillantern.lantermostic=你已有其他光芒效果,在这些效果取消或主动失效前,暂时无法使用提灯的效果。 + items.lightblack.oillantern.lanterneedsx=你的提灯需要新的油瓶来加油。 items.lightblack.oillantern.lanterneedsxs=你的油瓶还未加入提灯中,请点击"加油"按钮 items.lightblack.oillantern.lanterdied=你的提灯忽隐忽现地熄灭了! @@ -376,8 +392,7 @@ items.wands.wandofgodice.bmage_desc=当_战斗法师_以冰雪悲歌之杖近战 items.quest.goldbao.name=黄金珍宝 items.quest.goldbao.desc=由钻石宝箱王守护的东西,据说是商人的喜爱产品。\n\n无论怎么样,现在珍宝已经在你手中,你已经打败了钻石宝箱王。\n提示:出价资金可能会和实际资金不同,因为商人随时可能变卦。 -items.quest.red.name=死灵精华十字架 -items.quest.red.desc=死灵领主的好东西,如果交给想要的人必然会有好运。 + items.weapon.melee.skyshield.name=筝型盾 items.weapon.melee.skyshield.typical_stats_desc=这件武器通常能格挡0~%d点伤害。通过升级可以使格挡量增长。 @@ -942,6 +957,7 @@ items.artifacts.wraithamulet$1.selectkill=选择刺杀目标 items.artifacts.wraithamulet$1.far=刺杀目标太远,无法进行刺杀。 items.artifacts.wraithamulet$1.rooted=你的身体被束缚在这里,无法进行刺杀。 items.artifacts.wraithamulet$1.notthere=那里没有任何目标! +items.artifacts.wraithamulet$1.notthere2=选择的目标是拟态怪,无法在它的睡梦中将它击杀。 items.artifacts.wraithamulet$1.notnpc=NPC不能被处决! items.artifacts.wraithamulet$1.killmobs=该生物成功被暗夜突袭处决! items.artifacts.wraithamulet$1.killboss=该首领成功被暗夜突袭重创! @@ -1080,6 +1096,10 @@ items.food.smallration.eat_msg=吃起来还行。 items.food.smallration.desc=它看起来和普通口粮一样,就是小了点。 items.food.smallration.descx=它看起来和普通口粮不一样,就是大了点。 +items.food.smallration$blackmoon.name=小月饼 +items.food.smallration$blackmoon.desc=一个小小的月饼,可能是火候控制不当,有一面已经烤的焦黑了。\n\n面团上歪歪扭扭的写了几个字,看不太清。\n\n你不太确定里面是什么馅......馅料看起来有点像完全凝固的咖喱。\n\n闻起来有点怪味,不过应该能吃。 +items.food.smallration$blackmoon.eat_msg=出乎你的意料,馅料是烤土豆的味道,挺好吃的。 + items.food.stewedmeat.name=炖肉 items.food.stewedmeat.eat_msg=吃起来还行。 items.food.stewedmeat.desc=烹煮的过程中杀死了肉上面可能携带的任何病菌或是寄生虫。现在应该可以安全的食用它了。 diff --git a/core/src/main/assets/messages/misc/misc.properties b/core/src/main/assets/messages/misc/misc.properties index 40c95f8ef..af4f8df62 100644 --- a/core/src/main/assets/messages/misc/misc.properties +++ b/core/src/main/assets/messages/misc/misc.properties @@ -347,6 +347,9 @@ challenges.exsg_desc=药水癔症详细规则:\n力量药水--60%概率力量- challenges.icedied = 雪虐风饕(未完成) challenges.icedied_desc=很显然,地牢的雪越下越大了,在这严寒里面,生存的法则将进一步让我们活得更久。\n篝火房间一旦被激活不再无限,变成40回合的寒冷抑制,商人会贩卖更多特殊物品。 +challenges.morelevel=变幻莫测(中秋实装) +challenges.morelevel_desc=地牢在时间的长河中渐渐的诞生了更多地形,这次探索地牢谁知道能遇到什么?\n\n_地牢环境已发生改变,请小心应对。 + challenges.dhxd =灯火前路 challenges.dhxd_desc= 灯火指引着前进的道路,提灯引路,灯火前行! \n\n此为三挑以上的特殊机制,但你也可以直接开启它!\n\n1.追加灯火祝福和魔女诅咒机制,灯火会随着深入楼层进行降低\n2.在较低的灯火下死亡会精神崩溃,诞生自己的暗影。\n3.追加提灯和灯油,合理使用这些道具,让自己能在灯火祝福中活下去!如果不幸遭到魔女的诅咒,也不会让你陷入绝境。\n\n灯火不灭,希望仍在,提灯引路,灯火前行! diff --git a/core/src/main/assets/messages/scenes/scenes.properties b/core/src/main/assets/messages/scenes/scenes.properties index a5d88fdd5..79bd2f4fd 100644 --- a/core/src/main/assets/messages/scenes/scenes.properties +++ b/core/src/main/assets/messages/scenes/scenes.properties @@ -157,6 +157,9 @@ scenes.gamescene.dark=你依稀听到敌人在黑暗中涌动... scenes.gamescene.large=这一层的规模貌似格外庞大... scenes.gamescene.traps=这一层的地面机关密布,暗藏杀机... + +scenes.gamescene.moretraps=这一层机关犹如刀山火海,稍不注意便可能被…… + scenes.gamescene.secrets=诡秘的气氛正暗示这层隐藏着众多秘密。 scenes.gamescene.choose_examine=选择检查目标 scenes.gamescene.multiple_examine=这里引人注意的东西不止一件,你想检查哪个? @@ -180,6 +183,7 @@ scenes.interlevelscene$mode.reset=重置中… scenes.interlevelscene$mode.exboss=你突然眼前一黑\n\n,随后便是守卫低沉的声音:\n\n将此人押送到雪凛峡谷处置。 scenes.interlevelscene$mode.frgirlboss=正在前往雪凛峡谷深处…… scenes.interlevelscene$mode.ancityboss=正在前往远古遗迹深处…… +scenes.interlevelscene$mode.garden=在粉色幽灵的魔法下,\n\n你被传送到了古老花园…… scenes.interlevelscene.install=安装游戏 scenes.interlevelscene.file_not_found=未能找到存档文件。如果重启后问题依旧存在, 那这个存档可能已经损坏。节哀顺变。 scenes.interlevelscene.io_error=未能找到存档文件。如果重启后问题依旧存在, 那这个存档可能已经损坏。节哀顺变。 diff --git a/core/src/main/assets/messages/windows/windows.properties b/core/src/main/assets/messages/windows/windows.properties index 87bd3fbff..36ba1d5ec 100644 --- a/core/src/main/assets/messages/windows/windows.properties +++ b/core/src/main/assets/messages/windows/windows.properties @@ -105,12 +105,16 @@ windows.wndgame.dialog_title=好的装备名字能让你在游戏中更有亲切 windows.wndgame.dialog_rename=重命名 windows.wndgame.dialog_revert=恢复默认 -windows.wndinfomob.dsinfo = 闪避概率: -windows.wndinfomob.maxinfo = 掉落限制LV: -windows.wndinfomob.getexp = 上次伤害: -windows.wndinfomob.getspeed = 移速属性: -windows.wndinfomob.itm = 常规掉落: -windows.wndinfomob.shield= 护甲属性: +windows.wndinfomob.boss=头目 +windows.wndinfomob.miniboss=小头目 +windows.wndinfomob.hunter=狩猎 +windows.wndinfomob.abyss=深渊 +windows.wndinfomob.undied=亡灵 +windows.wndinfomob.demon=恶魔 +windows.wndinfomob.ling=元素 +windows.wndinfomob.normal=常规 +windows.wndinfomob.canroll=可掉落 +windows.wndinfomob.noroll=不掉落 windows.wndnyzshop.nayazi=奈亚子 windows.wndnyzshop.nayaziwelcome=你好,冒险家。欢迎来到我的商店。和其他商店不同的是,我这里是一个智能终端的结合体!\n\n需要什么请进行选择,但是,智能终端通常会出现问题!一旦终端出现问题将无法再次购买。\n\n书籍一本起价720金币,炸弹一套起价270金币,欢迎你的挑选!\n\n有一些时候因为机器的缺陷性质可能实际费用会比预想的高! @@ -354,8 +358,11 @@ windows.wndsadghost.rat=谢谢你,那个可怕的老鼠被杀,我也终于 windows.wndsadghost.gnoll=谢谢你,那个诡计多端的豺狼被杀,我也终于可以安息了……不知道究竟是什么样畸形的魔法使它如此诡诈… windows.wndsadghost.crab=谢谢你,那只巨蟹被杀,我也终于可以安息了……不知道究竟是什么样畸形的魔法能让它活得那么长…… windows.wndsadghost.give_item=挑一个你喜欢的拿走吧,我再也用不着它们了...希望它们能帮助你继续走下去...\n\n还有...我在这地牢里弄丢了一件心爱之物...倘若你能...找到那...玫瑰... +windows.wndsadghost.ask=谢谢你,冒险者。\n\n我的爱人曾和我说过她很害怕那个怪物......所以,尽管那只怪物的死活对我来说已经毫无意义,我仍然愿意请求你击败它。\n\n我的爱人?唉,是的,我生前已经和她签订好婚约了,可惜时运不济,我本以为这只是一个轻松的任务,没想到却遭到了偷袭......我很后悔,可后悔又能有什么用呢。击败了她所惧怕的怪物,也许能算是对她的一点补偿吧。\n\n现在应该已经是中秋节了,我又想起了和她一起吃月饼赏月的日子......对了,我烤制了一些月饼,选好要的东西后也给你一个吧。\n\n地牢难以找到合适的厨具和食材,希望你不要嫌弃。 + windows.wndsadghost.confirm=确定 windows.wndsadghost.cancel=取消 +windows.wndsadghost.look=关闭预览 windows.wndsadghost.farewell=一路顺风,冒险者! windows.wndsettings$displaytab.title=显示设置 diff --git a/core/src/main/assets/sprites/bluewraith.png b/core/src/main/assets/sprites/bluewraith.png new file mode 100644 index 000000000..6d0a1b699 Binary files /dev/null and b/core/src/main/assets/sprites/bluewraith.png differ diff --git a/core/src/main/assets/sprites/ghost.png b/core/src/main/assets/sprites/ghost.png index 7729864e9..cfa07ba44 100644 Binary files a/core/src/main/assets/sprites/ghost.png and b/core/src/main/assets/sprites/ghost.png differ diff --git a/core/src/main/assets/sprites/huntress.png b/core/src/main/assets/sprites/huntress.png index 889c8084d..ae9a8499e 100644 Binary files a/core/src/main/assets/sprites/huntress.png and b/core/src/main/assets/sprites/huntress.png differ diff --git a/core/src/main/assets/sprites/items/items.png b/core/src/main/assets/sprites/items/items.png index e07ba8d7f..5548fa897 100644 Binary files a/core/src/main/assets/sprites/items/items.png and b/core/src/main/assets/sprites/items/items.png differ diff --git a/core/src/main/assets/sprites/mage.png b/core/src/main/assets/sprites/mage.png index 8ec1c3430..86b48fa79 100644 Binary files a/core/src/main/assets/sprites/mage.png and b/core/src/main/assets/sprites/mage.png differ diff --git a/core/src/main/assets/sprites/pinkghost.png b/core/src/main/assets/sprites/pinkghost.png new file mode 100644 index 000000000..349dbad64 Binary files /dev/null and b/core/src/main/assets/sprites/pinkghost.png differ diff --git a/core/src/main/assets/sprites/rogue.png b/core/src/main/assets/sprites/rogue.png index 242fbc011..79efb34e7 100644 Binary files a/core/src/main/assets/sprites/rogue.png and b/core/src/main/assets/sprites/rogue.png differ diff --git a/core/src/main/assets/sprites/warrior.png b/core/src/main/assets/sprites/warrior.png index 57d54f64c..48e095b61 100644 Binary files a/core/src/main/assets/sprites/warrior.png and b/core/src/main/assets/sprites/warrior.png differ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java index e9dd05571..f14b5326d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Assets.java @@ -55,6 +55,7 @@ public class Assets { public static class Environment { public static final String TERRAIN_FEATURES = "environment/terrain_features.png"; + public static final String TILES_GARDEN = "environment/tiles_garden.png"; public static final String LAVACAVE_OP = "environment/custom_tiles/lavecave_behind.png"; public static final String LAVACAVE_PO = "environment/custom_tiles/lavecave_above.png"; @@ -385,6 +386,9 @@ public class Assets { public static final String DM300 = "sprites/dm300.png"; public static final String DM720 = "sprites/dm720.png"; public static final String WRAITH = "sprites/wraith.png"; + + public static final String REDWRAITH = "sprites/bluewraith.png"; + public static final String UNDEAD = "sprites/undead.png"; public static final String KING = "sprites/king.png"; public static final String PIRANHA = "sprites/piranha.png"; @@ -417,6 +421,7 @@ public class Assets { public static final String YOG = "sprites/yog.png"; public static final String LARVA = "sprites/larva.png"; public static final String GHOST = "sprites/ghost.png"; + public static final String PINKGHOST = "sprites/pinkghost.png"; public static final String MAKER = "sprites/wandmaker.png"; public static final String NYZD = "Npcs/nyz.png"; public static final String TROLL = "sprites/blacksmith.png"; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Challenges.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Challenges.java index c2f574fdd..c4ff3570b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Challenges.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Challenges.java @@ -49,11 +49,15 @@ public class Challenges { public static final int STRONGER_BOSSES = 4096; public static final int DHXD = 8192; public static final int ICEDIED = 16384; + + public static final int PRO = 32768; - public static final int CS = 65536; + public static final int MORELEVEL = 65536; - public static final int MAX_VALUE = 131072; + public static final int CS = 131072; + + public static final int MAX_VALUE = 131072*2; public static final String[] NAME_IDS = { "no_food", "no_armor", @@ -71,13 +75,13 @@ public class Challenges { "dhxd", "icedied", "pro", - "cs", + "morelevel", "cs", }; public static final int[] MASKS = { NO_FOOD, NO_ARMOR, NO_HEALING, NO_HERBALISM, SWARM_INTELLIGENCE, DARKNESS, NO_SCROLLS - , AQUAPHOBIA, CHAMPION_ENEMIES,RLPT,SBSG,EXSG,STRONGER_BOSSES,DHXD,ICEDIED,PRO,CS,CS, + , AQUAPHOBIA, CHAMPION_ENEMIES,RLPT,SBSG,EXSG,STRONGER_BOSSES,DHXD,ICEDIED,PRO,MORELEVEL,CS, }; public String name; @@ -119,10 +123,12 @@ public class Challenges { } - public static int activeChallenges(){ + public static int activeChallenges() { int chCount = 0; - for (int ch : Challenges.MASKS){ - if ((Dungeon.challenges & ch) != 0 && ch <= STRONGER_BOSSES) chCount++; + for (int ch : Challenges.MASKS) { + if ((Dungeon.challenges & ch) != 0 && ch <= MORELEVEL && ch != PRO && ch != DHXD) { + chCount++; + } } return chCount; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index d75639632..3fa1574e2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -60,7 +60,9 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagicTorch; import com.shatteredpixel.shatteredpixeldungeon.journal.Notes; import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityBossLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.AncientMysteryCityLevel; +import com.shatteredpixel.shatteredpixeldungeon.levels.CityLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.DeadEndLevel; +import com.shatteredpixel.shatteredpixeldungeon.levels.GardenLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.LinkLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel; @@ -121,6 +123,42 @@ public class Dungeon { return level; } + public static Level GardenLevel(){ + + + Dungeon.level = null; + Actor.clear(); + + depth = 50; + + if (depth > Statistics.realdeepestFloor) { + Statistics.realdeepestFloor = depth;} + + Level level; + level = new GardenLevel(); + + level.create(); + + Statistics.qualifiedForNoKilling = !bossLevel(); + + return level; + } + + public static Level BackLevel(){ + Actor.clear(); + + depth = 17; + + Dungeon.level = new CityLevel(); + + if (depth > Statistics.realdeepestFloor) { + Statistics.realdeepestFloor = depth;} + + Statistics.qualifiedForNoKilling = !bossLevel(); + + return level; + } + //远古副本 public static Level AncityWaterLevel(){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java index 026410846..2d465c5ef 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Statistics.java @@ -32,6 +32,12 @@ public class Statistics { //吃保底 public static int bossWeapons; + //中秋节幽灵特别行动 + public static boolean findMoon = false; + + //妻管严 + public static boolean deadGo = false; + public static boolean happyMode = false; //萨卡班甲鱼二阶段 @@ -132,6 +138,9 @@ public class Statistics { happyMode = false; + findMoon = false; + deadGo = false; + //萨卡班甲鱼二阶段 sakaBackStage = 0; @@ -282,12 +291,19 @@ public class Statistics { private static final String BDTX = "bdtx"; + private static final String LOVE = "love"; + + private static final String LOVX = "lovx"; + public static void storeInBundle( Bundle bundle ) { bundle.put(BDTX,bossWeapons); + bundle.put(LOVE,findMoon); + bundle.put(LOVX,deadGo); + //分数 bundle.put( PROG_SCORE, progressScore ); bundle.put( ITEM_VAL, heldItemValue ); @@ -387,6 +403,8 @@ public class Statistics { sakaBackStage = bundle.getInt( SAKATWO ); + findMoon = bundle.getBoolean(LOVE); + deadGo = bundle.getBoolean(LOVX); //分数 progressScore = bundle.getInt( PROG_SCORE ); heldItemValue = bundle.getInt( ITEM_VAL ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java index 70bccf605..3c6472c49 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -91,7 +91,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Potential; import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMight; import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfCleansing; -import com.shatteredpixel.shatteredpixeldungeon.items.quest.MIME; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfElements; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; @@ -606,12 +605,6 @@ public abstract class Char extends Actor { public float speed() { float speed = baseSpeed; - - - //提升20%移速 - MIME.GOLD_THREE getSpeed = Dungeon.hero.belongings.getItem(MIME.GOLD_THREE.class); - if (getSpeed!=null) speed *= 1.2f; - //创世神之怒 if ( buff( AnkhInvulnerability.GodDied.class ) != null ) speed *= 2f; @@ -1058,7 +1051,9 @@ public abstract class Char extends Actor { ScrollOfPsionicBlast.class)),new HashSet()), LARGE, IMMOVABLE, - NPC; + NPC, + HUNTER, + MIMIC; private HashSet resistances; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index 98626732f..385d663ca 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -716,6 +716,12 @@ public class Hero extends Char { float speed = super.speed(); speed *= RingOfHaste.speedMultiplier(this); + + //提升20%移速 + MIME.GOLD_THREE getSpeed = Dungeon.hero.belongings.getItem(MIME.GOLD_THREE.class); + if (getSpeed!=null) { + speed *= 1.2f; + } if (belongings.armor() != null) { speed = belongings.armor().speedFactor(this, speed); @@ -959,7 +965,7 @@ public class Hero extends Char { exp = Random.NormalIntRange(10,20); } - ///测试坐标用 +// ///测试坐标用 // GLog.w(String.valueOf(hero.pos)); //携带该物品时,玩家血量低于一半后自动隐身一段回合。 diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java index 7d153a29f..302dd5961 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/HeroClass.java @@ -56,6 +56,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClothArmor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.LamellarArmor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.custom.AncityArmor; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CloakOfShadows; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.WraithAmulet; import com.shatteredpixel.shatteredpixeldungeon.items.bags.BookBag; @@ -75,6 +76,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMindVision import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.WaterSoul; import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfLightStromCloud; import com.shatteredpixel.shatteredpixeldungeon.items.quest.CrivusFruitsFlake; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.MIME; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfFlameCursed; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify; @@ -93,7 +95,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BloodthirstyThorn; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Dagger; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Gloves; -import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatsword; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.LockSword; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagicTorch; @@ -152,11 +153,11 @@ public enum HeroClass { new Amulet().quantity(1).identify().collect(); } - if (Dungeon.isChallenged(Challenges.PRO)){ new LevelTeleporter().quantity(1).identify().collect(); new LockSword().quantity(1).identify().collect(); - new Greatsword().quantity(1).identify().collect(); + new MIME.GOLD_THREE().quantity(1).identify().collect(); + new DriedRose().quantity(1).identify().collect(); new PotionOfInvisibility().quantity(45).identify().collect(); new AncityArmor().quantity(1).identify().collect(); new TengusMask().quantity(1).identify().collect(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/BlueWraith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/BlueWraith.java new file mode 100644 index 000000000..79b240c95 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/BlueWraith.java @@ -0,0 +1,66 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2014 Oleg Dolya + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; + + +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; +import com.shatteredpixel.shatteredpixeldungeon.sprites.BlueWraithSprite; +import com.watabou.utils.Random; + +public class BlueWraith extends Wraith { + + { + spriteClass = BlueWraithSprite.class; + + HP = HT = 60; + defenseSkill = 24; + baseSpeed = 2.5f; + + EXP = 11; + } + + @Override + public int attackProc(Char enemy, int damage) { + if (Random.Int(10) == 0) { + Buff.affect(enemy, Vertigo.class, Vertigo.DURATION); + Buff.affect(enemy, Terror.class, Terror.DURATION).object = enemy.id(); + } + + return damage; + } + + @Override + public void adjustStats(int level) { + defenseSkill = 24; + enemySeen = true; + } + + @Override + public int damageRoll() { + return Random.NormalIntRange(20, 30); + } + + @Override + public int attackSkill(Char target) { + return 46; + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/MagicGirlDead.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/MagicGirlDead.java index 9d603a9fe..ad1971cea 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/MagicGirlDead.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/MagicGirlDead.java @@ -365,8 +365,20 @@ public class MagicGirlDead extends Boss { super.damage(damage, src); int postHP = HP; if(preHP>healthThreshold[phase] && postHP<=healthThreshold[phase]){ - HP = healthThreshold[phase]; - goOnPhase(); + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + HP = healthThreshold[phase]; + goOnPhase(); + return true; + } + }); } if(phase>4) BossHealthBar.bleed(true); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mimic.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mimic.java index 9479f0704..698a6c5d3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mimic.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mimic.java @@ -57,6 +57,7 @@ public class Mimic extends Mob { spriteClass = MimicSprite.class; properties.add(Property.DEMONIC); + properties.add(Property.MIMIC); EXP = 0; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DiamondKnight.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DiamondKnight.java index bf883964e..231e4daa1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DiamondKnight.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DiamondKnight.java @@ -80,6 +80,7 @@ public class DiamondKnight extends Boss { } private int pumpedUp = 0; + public int phase; private int healInc = 1; @@ -223,39 +224,75 @@ public class DiamondKnight extends Boss { if (lock != null) lock.addTime(dmg*2); ColdChestBossLevel.State level = ((ColdChestBossLevel)Dungeon.level).pro(); - //血量低于360后追加phase并加载楼层的进度方法,加载迷宫 + //血量低于360后追加phase并加载楼层的进度方法,加载迷宫 if (level == ColdChestBossLevel.State.START && this.HP <= 360 && phase == 0) { - GLog.n(Messages.get(DiamondKnight.class,"now_go")); - GameScene.flash(0x808080); - ((ColdChestBossLevel)Dungeon.level).progress(); - phase++; + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + ((ColdChestBossLevel)Dungeon.level).progress(); + phase++; + GLog.n(Messages.get(DiamondKnight.class,"now_go")); + GameScene.flash(0x808080); + return true; + } + }); } else if (level == ColdChestBossLevel.State.VSBOSS_START && this.HP <= 240 && phase == 2) { ((ColdChestBossLevel)Dungeon.level).progress(); phase++; //血量低于200后变成玩家的样子,伤害和防御数值与玩家一致 } else if (level == ColdChestBossLevel.State.VSLINK_START && this.HP <= 200 && phase == 3) { - GLog.n(Messages.get(DiamondKnight.class,"iswar_go")); - GameScene.flash(0x808080); - ((ColdChestBossLevel)Dungeon.level).progress(); - spriteClass=DimandKingSprite.PrismaticSprite.class; - //强制刷新屏幕 - ShatteredPixelDungeon.resetScene(); - GameScene.flash(0x888888); - phase++; - //血量低于100后变回来,基础伤害二连击 + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + ((ColdChestBossLevel)Dungeon.level).progress(); + phase++; + GLog.n(Messages.get(DiamondKnight.class,"iswar_go")); + GameScene.flash(0x808080); + ((ColdChestBossLevel)Dungeon.level).progress(); + spriteClass=DimandKingSprite.PrismaticSprite.class; + ShatteredPixelDungeon.switchNoFade(GameScene.class); + GameScene.flash(0x888888); + return true; + } + }); + //最终决斗 } else if (level == ColdChestBossLevel.State.VSYOU_START && this.HP <= 100 && phase == 4) { - GLog.n(Messages.get(DiamondKnight.class,"ok_go")); - GameScene.flash(0x808080); - spriteClass=DimandKingSprite.class; - //强制刷新屏幕 - ShatteredPixelDungeon.resetScene(); - GameScene.flash(0x888888); - ((ColdChestBossLevel)Dungeon.level).progress(); - phase++; + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + ((ColdChestBossLevel)Dungeon.level).progress(); + GLog.n(Messages.get(DiamondKnight.class,"ok_go")); + GameScene.flash(0x808080); + spriteClass=DimandKingSprite.class; + ShatteredPixelDungeon.switchNoFade(GameScene.class); + GameScene.flash(0x888888); + ((ColdChestBossLevel)Dungeon.level).progress(); + phase++; + return true; + } + }); } } - //当boos血量低于360时,加载第二场景 + @Override public void die( Object cause ) { @@ -278,8 +315,6 @@ public class DiamondKnight extends Boss { Badges.KILL_SMK(); - - if(Statistics.dimandchestmazeCollected>=3){ PaswordBadges.validateOMP(); Statistics.bossScores[1] += 1000; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DwarfMaster.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DwarfMaster.java index 27b4c2583..45cc54aea 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DwarfMaster.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/DwarfMaster.java @@ -603,6 +603,10 @@ public class DwarfMaster extends Boss { @Override public void damage(int dmg, Object src) { + if(HP > 400 && dmg > 300){ + dmg = 300; + } + if (HP > 299 && HP <= 500 && dmg >= 9){ dmg = 15+ (int)(Math.sqrt(8*(dmg - 4) + 1) - 1)/2; } else { @@ -630,18 +634,30 @@ public class DwarfMaster extends Boss { if (phase == 1) { - int dmgTaken = preHP - HP; abilityCooldown -= dmgTaken/8f; summonCooldown -= dmgTaken/8f; if (HP <= 400) { - HP = 400; - sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable")); + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + HP = 400; + sprite.showStatus(CharSprite.POSITIVE, Messages.get(Char.class, "invulnerable")); + properties.add(Property.IMMOVABLE); + phase = 2; + summonsMade = 0; + sprite.idle(); + + return true; + } + }); ScrollOfTeleportation.appear(this, DwarfMasterBossLevel.throne); - properties.add(Property.IMMOVABLE); - phase = 2; - summonsMade = 0; - sprite.idle(); Buff.affect(this, DwarfMaster.DKBarrior.class).setShield(12*25); for (DwarfMaster.Summoning s : buffs(DwarfMaster.Summoning.class)) { s.detach(); @@ -697,71 +713,82 @@ public class DwarfMaster extends Boss { @Override protected boolean act() { if (phase == 1) { + Actor.add(new Actor() { - if (summonCooldown <= 0 && summonSubject(3)){ - summonsMade++; - summonCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN)-1f; - } else if (summonCooldown > 0){ - summonCooldown-=1f/speed(); - } - - if (paralysed > 0){ - spend(TICK); - return true; - } - - if (abilityCooldown <= 0){ - int alive = aliveSummons(); - //NEVER use skills if no mobs alive. - if(alive == 0) { - lastAbility = NONE; - //summon faster when no ability is available. - summonCooldown -= 2f; - } - else { - do { - rollForAbility(); - } while ((lastAbility == ENRAGE || lastAbility == SACRIFICE) && alive < 2); - } - if(buff(SacrificeSubjectListener.class)!= null){ - lastAbility = NONE; - //cd faster while prepare to sacrifice - abilityCooldown --; + { + actPriority = VFX_PRIO; } - if (lastAbility == LINK && lifeLinkSubject()){ - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); + @Override + protected boolean act() { + Actor.remove(this); + if (summonCooldown <= 0 && summonSubject(3)){ + summonsMade++; + summonCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN)-1f; + } else if (summonCooldown > 0){ + summonCooldown-=1f/speed(); + } + + if (paralysed > 0){ + spend(TICK); + return true; + } + + if (abilityCooldown <= 0){ + int alive = aliveSummons(); + //NEVER use skills if no mobs alive. + if(alive == 0) { + lastAbility = NONE; + //summon faster when no ability is available. + summonCooldown -= 2f; + } + else { + do { + rollForAbility(); + } while ((lastAbility == ENRAGE || lastAbility == SACRIFICE) && alive < 2); + } + if(buff(SacrificeSubjectListener.class)!= null){ + lastAbility = NONE; + //cd faster while prepare to sacrifice + abilityCooldown --; + } + + if (lastAbility == LINK && lifeLinkSubject()){ + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + return true; + } else if (lastAbility == TELE && teleportSubject()) { + lastAbility = TELE; + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + return true; + }else if(lastAbility == ENRAGE){ + enrageSubject(); + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + return true; + }else if(lastAbility == DEATHRATTLE){ + deathRattleSubject(); + lastAbility = DEATHRATTLE; + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + }else if(lastAbility == SACRIFICE){ + sacrificeSubject(); + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + }else if(lastAbility == SUMMON){ + extraSummonSubject(); + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + } + + } else { + abilityCooldown--; + } + return true; - } else if (lastAbility == TELE && teleportSubject()) { - lastAbility = TELE; - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - return true; - }else if(lastAbility == ENRAGE){ - enrageSubject(); - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - return true; - }else if(lastAbility == DEATHRATTLE){ - deathRattleSubject(); - lastAbility = DEATHRATTLE; - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - }else if(lastAbility == SACRIFICE){ - sacrificeSubject(); - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - }else if(lastAbility == SUMMON){ - extraSummonSubject(); - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); } - - } else { - abilityCooldown--; - } - + }); } else if (phase == 2){ actPhaseTwoSummon(); return true; @@ -783,49 +810,6 @@ public class DwarfMaster extends Boss { return targetAbilityUses; } - public boolean useAbility(){ - boolean abilityUsed = false; - int abilityToUse = -1; - - while (!abilityUsed){ - - if (abilitiesUsed == 0){ - abilityToUse = BOMB_ABILITY; - } else if (abilitiesUsed == 1){ - abilityToUse = SHOCKER_ABILITY; - } else { - abilityToUse = Random.Int(3); - } - - //If we roll the same ability as last time, 9/10 chance to reroll - if (abilityToUse != lastAbility || Random.Int(10) == 0){ - switch (abilityToUse){ - case BOMB_ABILITY : default: - abilityUsed = throwBomb(this, enemy); - //if Tengu cannot use his bomb ability first, use fire instead. - if (abilitiesUsed == 0 && !abilityUsed){ - abilityToUse = FIRE_ABILITY; - abilityUsed = throwFire(this, enemy); - } - break; - } - } - - } - - - //spend only 1 turn if seriously behind on ability uses - if (targetAbilityUses() - abilitiesUsed >= 4){ - spend(TICK); - } else { - spend(2 * TICK); - } - - lastAbility = abilityToUse; - abilitiesUsed++; - return lastAbility == FIRE_ABILITY; - } - public static boolean throwFire(final Char thrower, final Char target){ Ballistica aim = new Ballistica(thrower.pos, target.pos, Ballistica.WONT_STOP); @@ -1301,12 +1285,24 @@ public class DwarfMaster extends Boss { private void actPhaseTwoSummon(){ if(wave == 0){ - yell(Messages.get(this, "wave_1")); - new GnollShiled().spawnAround(pos); - summonSubject(2, DwarfMaster.DKGhoul.class); - summonSubject(3, DwarfMaster.DKGhoul.class); - ++wave; - spend(TICK*9); + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + yell(Messages.get(DwarfMaster.class, "wave_1")); + new GnollShiled().spawnAround(pos); + summonSubject(2, DwarfMaster.DKGhoul.class); + summonSubject(3, DwarfMaster.DKGhoul.class); + ++wave; + spend(TICK*9); + return true; + } + }); }else if(wave == 1){ summonSubject(1, DwarfMaster.DKGhoul.class); summonSubject(5, DwarfMaster.DKMonk.class); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/FireMagicDied.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/FireMagicDied.java index d32750d86..625d658f6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/FireMagicDied.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/FireMagicDied.java @@ -321,89 +321,138 @@ public class FireMagicDied extends Mob implements Callback { public boolean act() { int healInc = 1; if (phase == 1 && HP <= 350) { + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + if (Dungeon.level.water[pos] && HP < HT) { + HP += healInc; + + if (Dungeon.level.heroFOV[pos]) { + sprite.emitter().burst(Speck.factory(Speck.HEALING), healInc); + } + if (HP * 2 > HT) { + BossHealthBar.bleed(false); + ((FireMagicGirlSprite) sprite).spray(false); + HP = Math.min(HP, HT); + } + } + return true; + } + }); //actScanning(); - if (Dungeon.level.water[pos] && HP < HT) { - HP += healInc; - if (Dungeon.level.heroFOV[pos]) { - sprite.emitter().burst(Speck.factory(Speck.HEALING), healInc); - } - if (HP * 2 > HT) { - BossHealthBar.bleed(false); - ((FireMagicGirlSprite) sprite).spray(false); - HP = Math.min(HP, HT); - } - } }else if (phase == 2 && HP <= 300) { + Actor.add(new Actor() { - if (summonCooldown <= 0 && summonSubject(3)){ - summonsMade++; - summonCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN)-1f; - } else if (summonCooldown > 0){ - summonCooldown-=1f/speed(); - } - - if (paralysed > 0){ - spend(TICK); - return true; - } - - if (abilityCooldown <= 0){ - int alive = aliveSummons(); - //NEVER use skills if no mobs alive. - if(alive == 0) { - lastAbility = NONE; - //summon faster when no ability is available. - summonCooldown -= 2f; - } - else { - do { - rollForAbility(); - } while ((lastAbility == ENRAGE || lastAbility == SACRIFICE) && alive < 2); - } - if(buff(DwarfMaster.SacrificeSubjectListener.class)!= null){ - lastAbility = NONE; - //cd faster while prepare to sacrifice - abilityCooldown --; + { + actPriority = VFX_PRIO; } - if (lastAbility == LINK && lifeLinkSubject()){ - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); + @Override + protected boolean act() { + Actor.remove(this); + if (summonCooldown <= 0 && summonSubject(3)){ + summonsMade++; + summonCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN)-1f; + } else if (summonCooldown > 0){ + summonCooldown-=1f/speed(); + } + + if (paralysed > 0){ + spend(TICK); + return true; + } + + if (abilityCooldown <= 0){ + int alive = aliveSummons(); + //NEVER use skills if no mobs alive. + if(alive == 0) { + lastAbility = NONE; + //summon faster when no ability is available. + summonCooldown -= 2f; + } + else { + do { + rollForAbility(); + } while ((lastAbility == ENRAGE || lastAbility == SACRIFICE) && alive < 2); + } + if(buff(DwarfMaster.SacrificeSubjectListener.class)!= null){ + lastAbility = NONE; + //cd faster while prepare to sacrifice + abilityCooldown --; + } + + if (lastAbility == LINK && lifeLinkSubject()){ + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + return true; + } else if (lastAbility == TELE && teleportSubject()) { + lastAbility = TELE; + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + return true; + }else if(lastAbility == ENRAGE){ + enrageSubject(); + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + return true; + }else if(lastAbility == DEATHRATTLE){ + deathRattleSubject(); + lastAbility = DEATHRATTLE; + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + }else if(lastAbility == SACRIFICE){ + sacrificeSubject(); + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + }else if(lastAbility == SUMMON){ + extraSummonSubject(); + abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); + spend(TICK); + } + + } else { + abilityCooldown--; + } return true; - } else if (lastAbility == TELE && teleportSubject()) { - lastAbility = TELE; - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - return true; - }else if(lastAbility == ENRAGE){ - enrageSubject(); - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - return true; - }else if(lastAbility == DEATHRATTLE){ - deathRattleSubject(); - lastAbility = DEATHRATTLE; - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - }else if(lastAbility == SACRIFICE){ - sacrificeSubject(); - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); - }else if(lastAbility == SUMMON){ - extraSummonSubject(); - abilityCooldown += Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN); - spend(TICK); } - - } else { - abilityCooldown--; - } + }); } else if (phase == 3){ - if (summonSubject(2)) summonsMade++; + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + if (summonSubject(2)) summonsMade++; + return true; + } + }); + } else if (phase == 4 && buffs(FireMagicDied.Summoning.class).size() < 4){ - actPhaseTwoSummon(); + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + actPhaseTwoSummon(); + return true; + } + }); return true; } //actScanning(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java index 159c91f6a..1978802d0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/bosses/SakaFishBoss.java @@ -114,10 +114,23 @@ public class SakaFishBoss extends Boss { //phase 1 of the fight is over if (HP <= HT/2 && level==AncientMysteryCityBossLevel.State.TWO_BOSS){ - HP = (HT/2); - yell(Messages.get(this, "interesting")); - ((AncientMysteryCityBossLevel)Dungeon.level).progress(); - BossHealthBar.bleed(true); + Actor.add(new Actor() { + + { + actPriority = VFX_PRIO; + } + + @Override + protected boolean act() { + Actor.remove(this); + HP = (HT/2); + yell(Messages.get(this, "interesting")); + ((AncientMysteryCityBossLevel)Dungeon.level).progress(); + BossHealthBar.bleed(true); + return true; + } + }); + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Ghost.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Ghost.java index a732b0b81..e7b45eacf 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Ghost.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Ghost.java @@ -43,6 +43,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.LeatherArmor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.MailArmor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.PlateArmor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.ScaleArmor; +import com.shatteredpixel.shatteredpixeldungeon.items.food.Food; +import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon; import com.shatteredpixel.shatteredpixeldungeon.journal.Notes; @@ -216,13 +218,14 @@ public class Ghost extends NPC { public static int depth; public static Weapon weapon; + public static Food food; public static Armor armor; public static Weapon.Enchantment enchant; public static Armor.Glyph glyph; public static void reset() { spawned = false; - + food = null; weapon = null; armor = null; enchant = null; @@ -237,6 +240,8 @@ public class Ghost extends NPC { private static final String PROCESSED = "processed"; private static final String DEPTH = "depth"; private static final String WEAPON = "weapon"; + + private static final String FOOD = "food"; private static final String ARMOR = "armor"; private static final String ENCHANT = "enchant"; private static final String GLYPH = "glyph"; @@ -256,6 +261,7 @@ public class Ghost extends NPC { node.put( PROCESSED, processed ); node.put( WEAPON, weapon ); + node.put( FOOD, food ); node.put( ARMOR, armor ); if (enchant != null) { @@ -281,6 +287,7 @@ public class Ghost extends NPC { weapon = (Weapon)node.get( WEAPON ); armor = (Armor)node.get( ARMOR ); + food = (Food)node.get(FOOD); if (node.contains(ENCHANT)) { enchant = (Weapon.Enchantment) node.get(ENCHANT); @@ -351,7 +358,7 @@ public class Ghost extends NPC { int wepTier = Random.chances(new float[]{0, 0, 10, 6, 3, 1}); Generator.Category c = Generator.wepTiers[wepTier - 1]; weapon = (MeleeWeapon) Reflection.newInstance(c.classes[Random.chances(c.probs)]); - + food = new SmallRation.BlackMoon(); //26%:+0, 25%:+1, 15%:+2, 10%:+3, 5%:+4 ghostQuest(); @@ -419,7 +426,7 @@ public class Ghost extends NPC { public static void complete() { weapon = null; armor = null; - + food = null; Notes.remove( Notes.Landmark.GHOST ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/GhostNPC.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/GhostNPC.java new file mode 100644 index 000000000..e76e70f67 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/GhostNPC.java @@ -0,0 +1,20 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; + +import com.shatteredpixel.shatteredpixeldungeon.Statistics; +import com.shatteredpixel.shatteredpixeldungeon.sprites.GhostSprite; + +public class GhostNPC extends NTNPC{ + + { + spriteClass = GhostSprite.class; + } + + @Override + protected boolean act() { + if(Statistics.deadGo){ + die(true); + } + return super.act(); + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NTNPC.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NTNPC.java index 2e73794d9..e2f29fb4a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NTNPC.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/NTNPC.java @@ -11,13 +11,14 @@ import java.util.ArrayList; public class NTNPC extends NPC { { - properties.add(Property.IMMOVABLE); } protected ArrayList chat = new ArrayList<>(); protected ArrayList endChat = new ArrayList<>(); + protected ArrayList sChat = new ArrayList<>(); + @Override protected boolean act() { throwItem(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PinkGhost.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PinkGhost.java new file mode 100644 index 000000000..9116bbaac --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PinkGhost.java @@ -0,0 +1,161 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; + +import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero; + +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.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; +import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.Red; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfRoseShiled; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.FiveRen; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.GhostSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuest; +import com.watabou.noosa.Game; +import com.watabou.utils.Bundle; +import com.watabou.utils.Callback; + +import java.util.ArrayList; + +public class PinkGhost extends NTNPC { + + private boolean first=true; + private boolean secnod=true; + private boolean rd=true; + + private boolean sd=true; + + private static final String FIRST = "first"; + private static final String SECNOD = "secnod"; + private static final String RD = "rd"; + + private static final String SD = "sd"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(FIRST, first); + bundle.put(SECNOD,secnod); + bundle.put(RD,rd); + bundle.put(SD,sd); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + first = bundle.getBoolean(FIRST); + secnod = bundle.getBoolean(SECNOD); + rd = bundle.getBoolean(RD); + sd = bundle.getBoolean(SD); + } + + { + spriteClass = GhostSprite.PinkGhostSprites.class; + chat = new ArrayList() { + { + add(Messages.get(PinkGhost.class, "hello")); + add(Messages.get(PinkGhost.class, "hello_1")); + } + }; + endChat = new ArrayList() { + { + add(Messages.get(PinkGhost.class, "hello_2")); + add(Messages.get(PinkGhost.class, "hello_3")); + } + }; + } + + @Override + public boolean interact(Char c) { + Red red = hero.belongings.getItem(Red.class); + sprite.turnTo(pos, hero.pos); + if(first){ + WndQuest.chating(this,chat); + first = false; + } else if(secnod){ + WndQuest.chating(this,endChat); + secnod= false; + } else if(red == null && rd) { + rd = false; + InterlevelScene.mode = InterlevelScene.Mode.GARDEN; + Game.switchScene(InterlevelScene.class); + } else if(red == null) { + GLog.pink(Messages.get(PinkGhost.class,"why_red")); + } else { + tell(this); + } + return true; + } + + private void tells(String text) { + Game.runOnRenderThread(new Callback() { + @Override + public void call() { + GameScene.show(new WndQuest(new PinkGhost(), text)); + } + } + ); + } + + private void tell(Char ghost) { + Weapon w3; + w3 = (Weapon) Generator.random(Generator.Category.WEAPON); + w3.upgrade(3); + w3.identify(); + + Armor a3; + a3 = (Armor) Generator.randomUsingDefaults( Generator.Category.ARMOR ); + a3.upgrade(3); + a3.identify(); + + Game.runOnRenderThread(new Callback() { + @Override + public void call() { + + ShatteredPixelDungeon.scene().add(new WndOptions(new GhostSprite.PinkGhostSprites(), + Messages.get(PinkGhost.class, "name"), + Messages.get(PinkGhost.class, "good_desc"), + Messages.get(PinkGhost.class, "giverose"), + Messages.get(PinkGhost.class, "givemoon")) { + @Override + protected void onSelect(int index) { + SmallRation.BlackMoon moon = hero.belongings.getItem( SmallRation.BlackMoon.class); + Red red = hero.belongings.getItem(Red.class); + if (index == 0) { + if(red != null){ + GLog.p(Messages.get(PinkGhost.class, "goodluck")); + red.detach(hero.belongings.backpack); + + Dungeon.level.drop(a3, ghost.pos).sprite.drop(); + Dungeon.level.drop(w3, ghost.pos).sprite.drop(); + Dungeon.level.drop(new ScrollOfRoseShiled().identify(), ghost.pos ); + Dungeon.level.drop(new FiveRen().identify(), ghost.pos ); + die(null); + } + } else if (index == 1) { + if(moon == null){ + sprite.showLost(); + GLog.pink(Messages.get(PinkGhost.class, "whatmoon")); + } else { + tells(Messages.get(PinkGhost.class, "moonname")); + GLog.n(Messages.get(PinkGhost.class, "moonlost")); + moon.detach(hero.belongings.backpack); + Statistics.findMoon = true; + die( null ); + } + } + } + }); + } + }); + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PinkGhostNPC.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PinkGhostNPC.java new file mode 100644 index 000000000..b22b655aa --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PinkGhostNPC.java @@ -0,0 +1,241 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; + +import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.PaswordBadges; +import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.Statistics; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.RedWhiteRose; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfRoseShiled; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.FiveRen; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.GhostSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuest; +import com.watabou.noosa.Game; +import com.watabou.utils.Bundle; +import com.watabou.utils.Callback; + +import java.util.ArrayList; + +public class PinkGhostNPC extends NPC { + protected ArrayList chat = new ArrayList<>(); + protected ArrayList endChat = new ArrayList<>(); + + protected ArrayList sChat = new ArrayList<>(); + + protected ArrayList LChat = new ArrayList<>(); + + protected ArrayList TheEndChat = new ArrayList<>(); + protected ArrayList MChat = new ArrayList<>(); + + private boolean first=true; + private boolean secnod=true; + private boolean rd=true; + + private boolean sd=true; + + private static final String FIRST = "first"; + private static final String SECNOD = "secnod"; + private static final String RD = "rd"; + + private static final String SD = "sd"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(FIRST, first); + bundle.put(SECNOD,secnod); + bundle.put(RD,rd); + bundle.put(SD,sd); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + first = bundle.getBoolean(FIRST); + secnod = bundle.getBoolean(SECNOD); + rd = bundle.getBoolean(RD); + sd = bundle.getBoolean(SD); + } + + { + spriteClass = GhostSprite.PinkGhostSprites.class; + + state = SLEEPING; + chat = new ArrayList() { + { + add(Messages.get(PinkGhost.class, "not_sorry")); + add(Messages.get(PinkGhost.class, "not_sorry_1")); + add(Messages.get(PinkGhost.class, "not_sorry_2")); + add(Messages.get(PinkGhost.class, "not_sorry_3")); + add(Messages.get(PinkGhost.class, "not_sorry_4")); + } + }; + endChat = new ArrayList() { + { + add(Messages.get(GhostNPC.class, "love")); + } + }; + sChat = new ArrayList() { + { + add(Messages.get(PinkGhost.class, "oh_no")); + } + }; + LChat = new ArrayList() { + { + add(Messages.get(GhostNPC.class, "sorry")); + } + }; + TheEndChat = new ArrayList() { + { + add(Messages.get(PinkGhost.class, "linklove")); + } + }; + MChat = new ArrayList() { + { + add(Messages.get(PinkGhost.class, "thanks")); + add(Messages.get(PinkGhost.class, "thanks_1")); + add(Messages.get(PinkGhost.class, "thanks_2")); + add(Messages.get(PinkGhost.class, "thanks_3")); + add(Messages.get(PinkGhost.class, "thanks_4",hero.name())); + } + }; + } + + @Override + public int defenseSkill( Char enemy ) { + return INFINITE_EVASION; + } + + @Override + public float speed() { + return 1.5f; + } + + @Override + protected Char chooseEnemy() { + return null; + } + + @Override + public void damage( int dmg, Object src ) { + } + + @Override + public void add( Buff buff ) { + } + + @Override + public boolean reset() { + return true; + } + + private void tells(String text) { + Game.runOnRenderThread(new Callback() { + @Override + public void call() { + GameScene.show(new WndQuest(new PinkGhost(), text)); + } + } + ); + } + + @Override + public boolean interact(Char c) { + NPC questBoss; + questBoss = new GhostNPC(); + + sprite.turnTo( pos, c.pos ); + + if (c != Dungeon.hero){ + return super.interact(c); + } + + Weapon w3; + w3 = (Weapon) Generator.random(Generator.Category.WEAPON); + w3.upgrade(3); + w3.identify(); + + Armor a3; + a3 = (Armor) Generator.randomUsingDefaults( Generator.Category.ARMOR ); + a3.upgrade(3); + a3.identify(); + if (state == SLEEPING && first) { + WndQuest.chating(this, chat); + state = WANDERING; + first = false; + } else if(secnod) { + Game.runOnRenderThread(new Callback() { + @Override + public void call() { + ShatteredPixelDungeon.scene().add(new WndOptions(new GhostSprite.PinkGhostSprites(), + Messages.get(PinkGhost.class, "name"), + Messages.get(PinkGhost.class, "talk_desc"), + Messages.get(PinkGhost.class, "givego"), + Messages.get(PinkGhost.class, "take")) { + @Override + protected void onSelect(int index) { + DriedRose rose = Dungeon.hero.belongings.getItem(DriedRose.class); + if (index == 0) { + GLog.p(Messages.get(PinkGhost.class, "goodluck")); + Dungeon.level.drop(a3, pos).sprite.drop(); + Dungeon.level.drop(w3, pos).sprite.drop(); + Dungeon.level.drop(new ScrollOfRoseShiled().identify(), pos ); + Dungeon.level.drop(new FiveRen().identify(),pos ); + Statistics.findMoon = false; + die(null); + } else if (index == 1) { + if(rose == null){ + sprite.showLost(); + GLog.pink(Messages.get(PinkGhost.class, "whathere")); + } else { + tells(Messages.get(PinkGhost.class, "rose")); + secnod = false; + } + } + } + }); + } + }); + } else if(rd) { + questBoss.pos = pos+1; + GameScene.add(questBoss, 1f); + sprite.showAlert(); + WndQuest.chating(this, TheEndChat); + WndQuest.chating(questBoss,LChat); + WndQuest.chating(this, sChat); + WndQuest.chating(questBoss, endChat); + //GLog.p(Messages.get(PinkGhost.class,"love&love")); + rd = false; + } else if (sd) { + WndQuest.chating(this,MChat); + sd = false; + } else { + DriedRose rose = Dungeon.hero.belongings.getItem(DriedRose.class); + GLog.i(Messages.get(PinkGhost.class, "thanks_5")); + die(null); + Statistics.deadGo = true; + Dungeon.level.drop(a3, pos).sprite.drop(); + Dungeon.level.drop(w3, pos).sprite.drop(); + Dungeon.level.drop(new ScrollOfRoseShiled().identify(), pos ); + Dungeon.level.drop(new FiveRen().identify(),pos ); + Dungeon.level.drop( rose.ghostWeapon(), pos ).sprite.drop(); + Dungeon.level.drop( new RedWhiteRose(), pos ).sprite.drop(); + Dungeon.level.drop( rose.ghostArmor(), pos ).sprite.drop(); + rose.detach(hero.belongings.backpack); + PaswordBadges.ZQJ_FLOWER(); + } + return true; + } +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/REN.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/REN.java index 7e8bce763..1a322654f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/REN.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/REN.java @@ -3,13 +3,10 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; -import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.RenSprite; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.windows.WndQuest; -import com.watabou.noosa.Game; import com.watabou.utils.Bundle; -import com.watabou.utils.Callback; import com.watabou.utils.Random; import java.util.ArrayList; @@ -86,15 +83,5 @@ public class REN extends NTNPC { return true; } - - private void tell(String text) { - Game.runOnRenderThread(new Callback() { - @Override - public void call() { - GameScene.show(new WndQuest(new REN(), text)); - } - } - ); - } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/EmoIcon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/EmoIcon.java index e33795db7..1565d072f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/EmoIcon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/EmoIcon.java @@ -103,6 +103,20 @@ public class EmoIcon extends Image { y = owner.y - height; } } + + public static class Love extends EmoIcon { + + public Love( CharSprite owner ) { + + super( owner ); + + copy( Icons.get( Icons.LOVE ) ); + + maxSize = 1.3f; + timeScale = 2; + scale.set( Random.Float( 1, maxSize ) ); + } + } public static class Lost extends EmoIcon { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java index 9ec6ac7ec..df7d39292 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java @@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.artifacts; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.CorrosiveGas; @@ -50,6 +51,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetributio import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon; +import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; @@ -80,6 +82,10 @@ public class DriedRose extends Artifact { { image = ItemSpriteSheet.ARTIFACT_ROSE1; + if(RegularLevel.holiday == RegularLevel.Holiday.ZQJ){ + cursed = false; + } + levelCap = 10; charge = 100; @@ -94,7 +100,7 @@ public class DriedRose extends Artifact { private GhostHero ghost = null; private int ghostID = 0; - private MeleeWeapon weapon = null; + public MeleeWeapon weapon = null; private Armor armor = null; public int droppedPetals = 0; @@ -558,6 +564,10 @@ public class DriedRose extends Artifact { if (rose == null || !rose.isEquipped(Dungeon.hero)){ damage(1, this); } + + if(Statistics.findMoon){ + die(true); + } if (!isAlive()) { return true; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/WraithAmulet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/WraithAmulet.java index e530bc043..bbbac39c8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/WraithAmulet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/WraithAmulet.java @@ -10,6 +10,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Item; @@ -214,19 +216,26 @@ public class WraithAmulet extends Artifact { amulet.exp += 40; hero.pos = target; if (enemy.properties().contains(Char.Property.BOSS)) { - enemy.damage(enemy.HT/4, WraithAmulet.class); + enemy.damage(enemy.HT / 4, WraithAmulet.class); GLog.i(Messages.get(this, "killboss")); - enemy.sprite.showStatus(CharSprite.NEGATIVE, Messages.get(this,"koss")); + enemy.sprite.showStatus(CharSprite.NEGATIVE, Messages.get(this, "koss")); + } else if (enemy.properties().contains(Char.Property.MIMIC) && enemy.alignment == Char.Alignment.NEUTRAL){ + for (Mob m: Dungeon.level.mobs){ + if(m.state == m.PASSIVE && (m instanceof Mimic)){ + GLog.i(Messages.get(this, "notthere2")); + return; + } + } } else { enemy.die(true); GLog.i(Messages.get(this, "killmobs")); enemy.sprite.showStatus(CharSprite.NEGATIVE, Messages.get(this,"died")); + ScrollOfTeleportation.appear(hero, target); + Dungeon.observe(); + hero.sprite.emitter().start(ShadowParticle.UP, 0.05f, 10); + amulet.cooldown = 150 / (amulet.level() / 2); + amulet.charge -= 6; } - ScrollOfTeleportation.appear(hero, target); - Dungeon.observe(); - hero.sprite.emitter().start(ShadowParticle.UP, 0.05f, 10); - amulet.cooldown = 150 / (amulet.level() / 2); - amulet.charge -= 6; } else { GLog.w(Messages.get(this, "notnpc")); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SmallRation.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SmallRation.java index 19a4c1656..3f2ecdff2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SmallRation.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/SmallRation.java @@ -34,6 +34,12 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class SmallRation extends Food { + public static class BlackMoon extends SmallRation{ + { + image = ItemSpriteSheet.BLACKMOON; + } + } + @Override protected void satisfy( Hero hero ){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilLantern.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilLantern.java index caf5b778b..124d951cf 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilLantern.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilLantern.java @@ -105,7 +105,7 @@ public class OilLantern extends Item { GLog.w(Messages.get(OilLantern.class, "lanterneedsx")); } } else { - GLog.n("你陷入灵魂残缺的迷茫当中 无法引燃提灯"); + GLog.n(Messages.get(OilLantern.class, "lanternosoul")); } break; case AC_REFILL: @@ -156,7 +156,7 @@ public class OilLantern extends Item { public void activate(Hero hero, boolean voluntary) { if (voluntary) { if (Dungeon.hero.buff(Light.class) != null || Dungeon.hero.buff(MagicTorch.MagicLight.class) != null) { - GLog.n("你已有其他光芒效果,在这些效果取消或主动失效前,暂时无法使用提灯的效果。"); + GLog.n(Messages.get(OilLantern.class, "lantermostic")); } else { hero.spend(TIME_TO_USE); hero.busy(); @@ -192,6 +192,11 @@ public class OilLantern extends Item { Dungeon.observe(); } + @Override + public String desc() { + return Messages.get(this, "desc",flasks,plingks); + } + public int price() { return 0; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilPotion.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilPotion.java index 443a40454..40b58a07e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilPotion.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/lightblack/OilPotion.java @@ -15,16 +15,19 @@ public class OilPotion extends Item { stackable = true; } + @Override public boolean isIdentified() { return true; } + @Override public ArrayList actions(Hero hero) { ArrayList actions = OilPotion.super.actions(hero); actions.add(AC_REFILL); return actions; } + @Override public void execute(Hero hero, String action) { OilPotion.super.execute(hero, action); if (action.equals(AC_REFILL)) { @@ -38,11 +41,6 @@ public class OilPotion extends Item { detach(Dungeon.hero.belongings.backpack); } -// public int proc(Char attacker, Char defender, int damage) { -// Buff.prolong(defender, Slow.class, 10.0f); -// return OilPotion.super.proc(attacker, defender, damage); -// } - @Override public int value() { return quantity * 20; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Red.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Red.java index 4bfa98ff2..048c27388 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Red.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/Red.java @@ -21,18 +21,28 @@ package com.shatteredpixel.shatteredpixeldungeon.items.quest; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass; +import com.shatteredpixel.shatteredpixeldungeon.plants.Swiftthistle; +import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.Window; +import com.watabou.noosa.Game; + +import java.util.ArrayList; public class Red extends Item { { - image = ItemSpriteSheet.DG12; + image = ItemSpriteSheet.WHITEROSE; unique = true; } - + private static final String AC_BACK = "interlevel_tp"; @Override public boolean isUpgradable() { return false; @@ -43,8 +53,34 @@ public class Red extends Item { return true; } + @Override + public ArrayList actions(Hero hero ) { + ArrayList actions = super.actions( hero ); + if(Dungeon.depth == 50) { + actions.add(AC_BACK); + } + return actions; + } + + @Override + public void execute(Hero hero, String action ) { + super.execute(hero, action); + if (action.equals(AC_BACK)) { + Buff buff = hero.buff(TimekeepersHourglass.timeFreeze.class); + if (buff != null) buff.detach(); + buff = hero.buff(Swiftthistle.TimeBubble.class); + if (buff != null) buff.detach(); + InterlevelScene.mode = InterlevelScene.Mode.RETURN; + InterlevelScene.returnDepth = 17; + InterlevelScene.returnPos = -1; + Game.switchScene( InterlevelScene.class ); + } + } + + + @Override public ItemSprite.Glowing glowing() { - return new ItemSprite.Glowing(0x00ffff, 3f); + return new ItemSprite.Glowing(Window.WHITE, 3f); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/RedWhiteRose.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/RedWhiteRose.java new file mode 100644 index 000000000..8a7696820 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/RedWhiteRose.java @@ -0,0 +1,31 @@ +package com.shatteredpixel.shatteredpixeldungeon.items.quest; + +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.Window; + +public class RedWhiteRose extends Item { + + { + image = ItemSpriteSheet.REDWHITEROSE; + upgrade(99); + } + + @Override + public ItemSprite.Glowing glowing() { + return new ItemSprite.Glowing(Window.GDX_COLOR, 3f); + } + + @Override + public boolean isUpgradable() { + return false; + } + + @Override + public boolean isIdentified() { + return true; + } + +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/FiveRen.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/FiveRen.java new file mode 100644 index 000000000..9cbbb32e8 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/FiveRen.java @@ -0,0 +1,50 @@ +package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corrosion; +import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Random; + +public class FiveRen extends MeleeWeapon { + + { + image = ItemSpriteSheet.FIVEREN; + hitSound = Assets.Sounds.HIT_STAB; + hitSoundPitch = 0.9f; + + tier = 2; + DLY = 1.5f; //0.67x speed + RCH = 2; //extra reach + } + + @Override + public int proc(Char attacker, Char defender, int damage) { + switch (Random.Int(7)) { + case 0:case 1:case 2:case 3:case 4: + default: + return super.proc(attacker, defender, damage); + case 5:case 6:case 7: + if (Random.Int(10)==1) { + Buff.affect(defender, Corrosion.class).set(5f, Dungeon.depth/3); + if (Dungeon.level.heroFOV[defender.pos]) { + defender.sprite.centerEmitter().start(Speck.factory(Speck.HEART), 0.2f, 5); + Sample.INSTANCE.play(Assets.Sounds.CHARMS); + } + } + return super.proc(attacker, defender, damage); + } + } + + @Override + public int max(int lvl) { + return Math.round(6.67f*(tier+1)) + //20 base, up from 15 + lvl*Math.round(1.33f*(tier+1)); //+4 per level, up from +3 + } + +} + diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java index 021ddb9f7..4916ad01e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java @@ -22,7 +22,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; -import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Crushing; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class Greatsword extends MeleeWeapon { @@ -31,7 +30,6 @@ public class Greatsword extends MeleeWeapon { image = ItemSpriteSheet.GREATSWORD; hitSound = Assets.Sounds.HIT_SLASH; hitSoundPitch = 1f; - enchantment = new Crushing(); tier=5; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/legend/DiedCrossBow.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/legend/DiedCrossBow.java index 6219c5eb0..5b90bad23 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/legend/DiedCrossBow.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/legend/DiedCrossBow.java @@ -20,11 +20,13 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton; import com.shatteredpixel.shatteredpixeldungeon.ui.Window; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; import com.watabou.noosa.particles.Emitter; +import com.watabou.utils.Callback; import com.watabou.utils.PathFinder; import com.watabou.utils.Random; @@ -115,9 +117,7 @@ public class DiedCrossBow extends LegendWeapon { QuickSlotButton.target(Actor.findChar(cell)); } cooldown = 60-level()*2; - knockArrow().cast(curUser, target-2); knockArrow().cast(curUser, target); - knockArrow().cast(curUser, target+2); QuickSlotButton.target(Actor.findChar(target)); } @@ -132,7 +132,12 @@ public class DiedCrossBow extends LegendWeapon { return new BombArrow(); } + + + public static class BombArrow extends TippedDart { + public boolean sniperSpecial = false; + public float sniperSpecialBonusDamage = 0f; @Override public Emitter emitter() { Emitter emitter = new Emitter(); @@ -146,6 +151,9 @@ public class DiedCrossBow extends LegendWeapon { image = ItemSpriteSheet.DISPLACING_DART; } + int flurryCount = -1; + private int targetPos; + @Override public int proc(Char attacker, Char defender, int damage) { DiedCrossBow dartGun = hero.belongings.getItem(DiedCrossBow.class); @@ -155,6 +163,48 @@ public class DiedCrossBow extends LegendWeapon { return super.proc(attacker, defender, damage); } + @Override + public void cast(final Hero user, final int dst) { + final int cell = throwPos( user, dst ); + targetPos = cell; + + + final Char enemy = Actor.findChar( cell ); + + QuickSlotButton.target(enemy); + + + user.busy(); + + throwSound(); + + ((MissileSprite) user.sprite.parent.recycle(MissileSprite.class)). + reset(user.sprite, + cell, + this, + new Callback() { + @Override + public void call() { + curUser = user; + onThrow(cell); + onThrow(cell+2); + onThrow(cell-2); + } + }); + + user.sprite.zap(cell, new Callback() { + @Override + public void call() { + flurryCount--; + if (flurryCount > 0){ + cast(user, dst); + } + } + }); + super.cast(user, dst); + + } + @Override public ItemSprite.Glowing glowing() { return new ItemSprite.Glowing(0x880000, 6f); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java index d81d9c388..690f259f8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/ColdChestBossLevel.java @@ -321,19 +321,22 @@ public class ColdChestBossLevel extends Level { Dungeon.observe(); //进行Roll判定 - switch(Random.NormalIntRange(0,3)){ - case 0: - drop( new MIME.GOLD_ONE(),634 ); - break; - case 1: - drop( new MIME.GOLD_ONE(),660 ); - break; - case 2: - drop( new MIME.GOLD_ONE(),308 ); - break; - case 3: - drop( new MIME.GOLD_ONE(),286 ); - break; + + if(Statistics.dimandchestmazeCollected==0) { + switch (Random.NormalIntRange(0, 3)) { + case 0: + drop(new MIME.GOLD_ONE(), 634); + break; + case 1: + drop(new MIME.GOLD_ONE(), 660); + break; + case 2: + drop(new MIME.GOLD_ONE(), 308); + break; + case 3: + drop(new MIME.GOLD_ONE(), 286); + break; + } } pro = START; @@ -353,41 +356,43 @@ public class ColdChestBossLevel extends Level { boss.HP = 360; //进行Roll判定 获得一定的随机坐标 - if(Random.Float()<0.5f) { - switch(Random.NormalIntRange(0,4)){ - case 0: - drop( new MIME.GOLD_TWO(),570 ); - break; - case 1: - drop( new MIME.GOLD_TWO(),472 ); - break; - case 2: - drop( new MIME.GOLD_TWO(),1041 ); - break; - case 3: - drop( new MIME.GOLD_TWO(),52 ); - break; - case 4: - drop( new MIME.GOLD_TWO(),1096 ); - break; - } - } else { - switch(Random.NormalIntRange(0,4)){ - case 0: - drop( new MIME.GOLD_THREE(),570 ); - break; - case 1: - drop( new MIME.GOLD_THREE(),472 ); - break; - case 2: - drop( new MIME.GOLD_THREE(),1041 ); - break; - case 3: - drop( new MIME.GOLD_THREE(),52 ); - break; - case 4: - drop( new MIME.GOLD_THREE(),1096 ); - break; + if(Statistics.dimandchestmazeCollected==1) { + if (Random.Float() < 0.5f) { + switch (Random.NormalIntRange(0, 4)) { + case 0: + drop(new MIME.GOLD_TWO(), 570); + break; + case 1: + drop(new MIME.GOLD_TWO(), 472); + break; + case 2: + drop(new MIME.GOLD_TWO(), 1041); + break; + case 3: + drop(new MIME.GOLD_TWO(), 52); + break; + case 4: + drop(new MIME.GOLD_TWO(), 1096); + break; + } + } else { + switch (Random.NormalIntRange(0, 4)) { + case 0: + drop(new MIME.GOLD_THREE(), 570); + break; + case 1: + drop(new MIME.GOLD_THREE(), 472); + break; + case 2: + drop(new MIME.GOLD_THREE(), 1041); + break; + case 3: + drop(new MIME.GOLD_THREE(), 52); + break; + case 4: + drop(new MIME.GOLD_THREE(), 1096); + break; + } } } @@ -462,23 +467,25 @@ public class ColdChestBossLevel extends Level { //drop( new PotionOfPurity(),648 ); //进行Roll判定 - if(Random.Float()<0.5f) { - switch(Random.NormalIntRange(0,1)){ - case 0: - drop( new MIME.GOLD_FOUR(),217 ); - break; - case 1: - drop( new MIME.GOLD_FOUR(),1042 ); - break; - } - } else { - switch(Random.NormalIntRange(0,1)){ - case 0: - drop( new MIME.GOLD_FIVE(),217 ); - break; - case 1: - drop( new MIME.GOLD_FIVE(),1042 ); - break; + if(Statistics.dimandchestmazeCollected==2) { + if (Random.Float() < 0.5f) { + switch (Random.NormalIntRange(0, 1)) { + case 0: + drop(new MIME.GOLD_FOUR(), 217); + break; + case 1: + drop(new MIME.GOLD_FOUR(), 1042); + break; + } + } else { + switch (Random.NormalIntRange(0, 1)) { + case 0: + drop(new MIME.GOLD_FIVE(), 217); + break; + case 1: + drop(new MIME.GOLD_FIVE(), 1042); + break; + } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/GardenLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/GardenLevel.java new file mode 100644 index 000000000..10a9f2637 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/GardenLevel.java @@ -0,0 +1,112 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels; + +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.EMPTY; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.WALL; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.BlueWraith; +import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.Red; +import com.watabou.utils.Random; + +public class GardenLevel extends Level { + + private static final int W = WALL; + private static final int E = EMPTY; + private static final int L = Terrain.CRYSTAL_DOOR; + private static final int S =Terrain.EMPTY_SP; + + private static final int F =Terrain.FURROWED_GRASS; + + private static final int D = Terrain.SECRET_DOOR; + + private static final int M = Terrain.SECRET_DOOR; + private static final int X = Terrain.WATER; + + private static final int WIDTH = 24; + private static final int HEIGHT = 24; + + private static final int[] code_map = { + W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, + W,S,S,S,S,S,W,E,E,E,W,E,E,E,S,E,E,E,E,E,W,E,E,W, + W,E,E,E,E,E,D,S,S,S,W,S,S,S,S,E,E,E,E,E,W,E,E,W, + W,E,E,E,E,E,W,X,X,X,W,E,E,E,S,E,E,E,E,E,W,S,S,W, + W,W,M,W,D,W,W,X,X,X,W,W,W,W,W,W,D,W,W,W,W,E,E,W, + W,E,S,E,E,E,E,X,X,X,E,E,E,E,S,E,E,E,E,E,S,E,E,W, + W,E,S,E,E,E,E,X,X,X,E,S,S,S,S,S,S,E,E,E,S,E,E,W, + W,E,S,S,S,S,S,S,S,E,E,S,E,E,E,E,S,E,E,E,S,E,E,W, + W,E,E,E,E,E,E,E,S,E,E,S,E,E,E,E,W,W,W,W,D,W,W,W, + W,W,W,D,W,W,E,E,W,W,W,W,W,W,W,E,W,E,E,E,S,E,E,W, + W,S,E,E,E,W,E,E,W,F,F,F,F,F,W,E,W,E,E,E,S,E,E,W, + W,S,S,S,S,W,S,S,W,F,W,L,W,F,W,E,M,S,S,S,S,E,E,W, + W,X,S,X,X,W,E,E,W,F,W,S,W,F,W,E,W,E,S,X,X,X,X,W, + W,X,S,X,X,W,E,E,W,F,W,W,W,F,W,E,W,E,S,X,X,X,X,W, + W,X,S,X,X,W,E,E,W,F,F,F,F,F,W,E,W,E,S,X,X,X,X,W, + W,X,S,X,X,M,E,E,W,W,W,L,W,W,W,S,W,S,S,X,X,X,X,W, + W,X,S,X,X,W,S,S,S,S,S,S,S,S,S,S,W,W,W,D,W,W,W,W, + W,X,S,X,X,W,E,E,S,X,X,X,X,X,S,S,E,E,S,E,E,E,E,W, + W,X,S,X,X,W,E,E,S,X,X,S,S,S,S,E,E,E,S,E,E,E,E,W, + W,E,S,E,E,W,E,E,S,X,X,S,S,E,E,E,E,E,S,S,S,S,S,W, + W,W,W,D,W,W,S,S,S,S,S,S,S,S,W,W,W,W,D,W,W,M,W,W, + W,E,E,E,E,W,E,E,S,E,E,S,E,E,W,E,E,E,S,E,E,E,E,W, + W,E,E,E,E,M,E,E,S,E,E,S,E,E,W,E,E,E,S,E,E,E,E,W, + W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, + + }; + + @Override + protected boolean build() { + setSize(WIDTH, HEIGHT); + map = code_map.clone(); + this.entrance = 25; + exit = 0; + return true; + } + + /** + * + */ + @Override + protected void createMobs() { + //第一个i是初始值,第二个i是条件范围值,第三个是循环方式,这里是每次+2 + for (int i = 10; i < 15; i+=2){ + BlueWraith x = new BlueWraith(); + x.pos = (this.width * i + 5); + mobs.add(x); + } + + for (int i = 10; i < 15; i+=2){ + BlueWraith a = new BlueWraith(); + a.pos = (this.width * i + 16); + mobs.add(a); + } + } + + /** + * + */ + @Override + protected void createItems() { + float randomValue = Random.Float(); + int secondCoordinate = (randomValue < 0.3f) ? 529 : + (randomValue < 0.6f) ? 386 : + (randomValue < 0.9f) ? 62 : + (randomValue < 0.95f) ? 284 : 251; + drop(new CrystalKey( Dungeon.depth ), 546 ); + drop(new CrystalKey( Dungeon.depth ), secondCoordinate); + + + drop(new Red(), 299); + } + + @Override + public String tilesTex() { + return Assets.Environment.TILES_GARDEN; + } + + @Override + public String waterTex() { + return Assets.Environment.WATER_COLD; + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java index 7aceb831c..07df88f7b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; +import static com.shatteredpixel.shatteredpixeldungeon.Challenges.MORELEVEL; import static com.shatteredpixel.shatteredpixeldungeon.Challenges.SBSG; import com.shatteredpixel.shatteredpixeldungeon.Assets; @@ -164,7 +165,8 @@ public abstract class Level implements Bundlable { DARK, LARGE, TRAPS, - SECRETS + SECRETS, + BIGTRAP, } public boolean isLevelExplored( int depth ){ @@ -298,7 +300,7 @@ public abstract class Level implements Bundlable { addItemToSpawn( new StoneOfIntuition() ); } - if (Dungeon.depth > 1) { + if (Dungeon.depth > 1 && !Dungeon.bossLevel()) { //50% chance of getting a level feeling //~7.15% chance for each feeling switch (Random.Int( 14 )) { @@ -326,6 +328,11 @@ public abstract class Level implements Bundlable { case 6: feeling = Feeling.SECRETS; break; + case 7: + if(Dungeon.isChallenged(MORELEVEL)){ + feeling = Feeling.BIGTRAP; + } + break; } } } @@ -546,9 +553,7 @@ public abstract class Level implements Bundlable { Mob m = Reflection.newInstance(mobsToSpawn.remove(0)); ChampionEnemy.rollForChampion(m); - if(Dungeon.isChallenged(SBSG)){ - ChampionEnemy.rollForStateLing(m); - } + ChampionEnemy.rollForStateLing(m); Buff.affect(m, HasteLing.MobLing.class, HasteLing.MobLing.DURATION*2000f); return m; } @@ -693,7 +698,6 @@ public abstract class Level implements Bundlable { } if (!mob.buffs(ChampionEnemy.class).isEmpty() && Dungeon.isChallenged(SBSG)){ GLog.n(Messages.get(ChampionEnemy.class, "warn2")); - GLog.w(Messages.get(ChampionEnemy.class, "warn")); } else if(!mob.buffs(ChampionEnemy.class).isEmpty()) { GLog.w(Messages.get(ChampionEnemy.class, "warn")); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java index f9e046961..d8940042d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LevelRules.java @@ -136,6 +136,8 @@ public class LevelRules { } case 26: return new LastLevel(); + case 50: + return new GardenLevel(); default: Statistics.deepestFloor--; return new DeadEndLevel(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java index 172f36128..74655992d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -70,6 +70,8 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.AquariumRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.HeartRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.LoveRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.MagicDimandRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BlazingTrap; @@ -127,7 +129,7 @@ public abstract class RegularLevel extends Level { holiday = Holiday.NONE; } break; - //9.10-10.1 + //9.10-10.8 case Calendar.SEPTEMBER: if (calendar.get(Calendar.DAY_OF_MONTH) >= 10 ){ holiday = Holiday.ZQJ; @@ -136,7 +138,7 @@ public abstract class RegularLevel extends Level { } break; case Calendar.OCTOBER: - if (calendar.get(Calendar.DAY_OF_MONTH) == 1 ){ + if (calendar.get(Calendar.DAY_OF_MONTH) <= 8 ){ holiday = Holiday.ZQJ; } else { holiday = Holiday.NONE; @@ -259,6 +261,15 @@ public abstract class RegularLevel extends Level { // initRooms.add(new EyeRoom()); // initRooms.add(new YinYangRoom()); + if(RegularLevel.holiday == Holiday.ZQJ){ + if(Dungeon.depth == 17){ + initRooms.add(new HeartRoom()); + } + if(Statistics.findMoon && Dungeon.depth == 18){ + initRooms.add(new LoveRoom()); + } + } + if (Dungeon.NxhyshopOnLevel()) { initRooms.add(new NxhyShopRoom()); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SLMKingLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SLMKingLevel.java index 44fd36a25..7659fe111 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SLMKingLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SLMKingLevel.java @@ -28,8 +28,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.FigureEightBuilder; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.JunglePainter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; -import com.shatteredpixel.shatteredpixeldungeon.levels.painters.SewerPainter; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.RatKingRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.sewerboss.SewerBossEntranceRoom; @@ -90,7 +90,7 @@ public class SLMKingLevel extends SewerLevel { @Override protected Painter painter() { - return new SewerPainter() + return new JunglePainter() .setWater(0.50f, 5) .setGrass(0.20f, 4) .setTraps(nTraps(), trapClasses(), trapChances()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java index 30a9c3ab8..7be7e1d69 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java @@ -31,8 +31,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.FigureEightBuilder; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.JunglePainter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; -import com.shatteredpixel.shatteredpixeldungeon.levels.painters.SewerPainter; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.RatKingRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.sewerboss.GooBossRoom; @@ -122,7 +122,7 @@ public class SewerBossLevel extends SewerLevel { @Override protected Painter painter() { - return new SewerPainter() + return new JunglePainter() .setWater(0.50f, 5) .setGrass(0.20f, 4) .setTraps(nTraps(), trapClasses(), trapChances()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java index 7b19c719a..f7ac39653 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java @@ -26,8 +26,8 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost; import com.shatteredpixel.shatteredpixeldungeon.effects.Ripple; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.JunglePainter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; -import com.shatteredpixel.shatteredpixeldungeon.levels.painters.SewerPainter; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.AlarmTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ChillingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ConfusionTrap; @@ -73,7 +73,7 @@ public class SewerLevel extends RegularLevel { @Override protected Painter painter() { - return new SewerPainter() + return new JunglePainter() .setWater(feeling == Feeling.WATER ? 0.85f : 0.30f, 5) .setGrass(feeling == Feeling.GRASS ? 0.80f : 0.20f, 4) .setTraps(nTraps(), trapClasses(), trapChances()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/JunglePainter.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/JunglePainter.java new file mode 100644 index 000000000..cef347cad --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/JunglePainter.java @@ -0,0 +1,155 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2022 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.shatteredpixel.shatteredpixeldungeon.levels.painters; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; +import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet; +import com.watabou.utils.Random; + +import java.util.ArrayList; + +public class JunglePainter extends RegularPainter { + + private static final int SHAPE_RADIUS = 3; // + // 菱形的半径 + + @Override + protected void decorate(Level level, ArrayList rooms) { + int[] map = level.map; + int w = level.width(); + int l = level.length(); + + for (int i = 0; i < w; i++) { + if (map[i] == Terrain.WALL && map[i + w] == Terrain.WATER && Random.Int(4) == 0) { + map[i] = Terrain.WALL_DECO; + } + } + + for (int i = w; i < l - w; i++) { + if (map[i] == Terrain.WALL && map[i - w] == Terrain.WALL && map[i + w] == Terrain.WATER && Random.Int(2) == 0) { + map[i] = Terrain.WALL_DECO; + } + } + + for (Room room : rooms) { + if (!(room instanceof StandardRoom)) { + continue; + } + + if (room.width() <= 4 || room.height() <= 4) { + continue; + } + + int s = room.square(); + + if (Random.Int( s ) > 8) { + int corner = (room.left + 1) + (room.top + 1) * w; + if (map[corner - 1] == Terrain.WALL && map[corner - w] == Terrain.WALL) { + map[corner] = Terrain.WALL; + level.traps.remove(corner); + } + } + + if (Random.Int( s ) > 8) { + int corner = (room.right - 1) + (room.top + 1) * w; + if (map[corner + 1] == Terrain.WALL && map[corner - w] == Terrain.WALL) { + map[corner] = Terrain.WALL; + level.traps.remove(corner); + } + } + + if (Random.Int( s ) > 8) { + int corner = (room.left + 1) + (room.bottom - 1) * w; + if (map[corner - 1] == Terrain.WALL && map[corner + w] == Terrain.WALL) { + map[corner] = Terrain.WALL; + level.traps.remove(corner); + } + } + + if (Random.Int( s ) > 8) { + int corner = (room.right - 1) + (room.bottom - 1) * w; + if (map[corner + 1] == Terrain.WALL && map[corner + w] == Terrain.WALL) { + map[corner] = Terrain.WALL; + level.traps.remove(corner); + } + } + + } + + for (int i=0; i < l - w; i++) { + + if (map[i] == Terrain.EMPTY && Random.Int( 10 ) == 0) { + map[i] = Terrain.EMPTY_DECO; + + } else if (map[i] == Terrain.WALL + && !DungeonTileSheet.wallStitcheable(map[i + w]) + && Random.Int( 21 - Dungeon.depth ) == 0) { + map[i] = Terrain.WALL_DECO; + } + } + + for (int i = w + 1; i < l - w - 1; i++) { + if (map[i] == Terrain.EMPTY) { + int count = + (map[i + 1] == Terrain.WALL ? 1 : 0) + + (map[i - 1] == Terrain.WALL ? 1 : 0) + + (map[i + w] == Terrain.WALL ? 1 : 0) + + (map[i - w] == Terrain.WALL ? 1 : 0); + + if (Random.Int(16) < count * count) { + map[i] = Terrain.EMPTY_DECO; + } + } + } + + for (int i = 0; i < l; i++) { + if (map[i] == Terrain.WALL) { + if (checkShape(i % w, i / w, w, l)) { + map[i] = Terrain.WALL_DECO; + } + } else if (map[i] == Terrain.EMPTY && Random.Int(5) == 0) { + map[i] = Terrain.GRASS; + } + } + + for (Room r : rooms) { + for (Room n : r.neigbours) { + if (!r.connected.containsKey( n )) { + mergeRooms(level, r, n, null, Terrain.CHASM); + } + } + } + + } + + private boolean checkShape(int x, int y, int width, int length) { + int centerX = width / 2; + int centerY = length / 2; + + int distance = (x - centerX) * (x - centerX) + (y - centerY) * (y - centerY); + return distance <= SHAPE_RADIUS * SHAPE_RADIUS; + } +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java index abb2a8224..11e7f5459 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java @@ -121,7 +121,7 @@ public abstract class RegularPainter extends Painter { placeDoors( r ); r.paint( level ); } - + paintDoors( level, rooms ); if (waterFill > 0f) { @@ -440,10 +440,15 @@ public abstract class RegularPainter extends Painter { } //no more than one trap every 5 valid tiles. - nTraps = Math.min(nTraps, validCells.size()/5); + + nTraps = l.feeling == Level.Feeling.BIGTRAP ? Math.min(nTraps, + validCells.size()/2) : Math.min(nTraps, + validCells.size()/5); //5x traps on traps level feeling, but the extra traps are all visible - for (int i = 0; i < (l.feeling == Level.Feeling.TRAPS ? 5*nTraps : nTraps); i++) { + for (int i = 0; i < (l.feeling == Level.Feeling.BIGTRAP ? 25*nTraps : l.feeling == Level.Feeling.TRAPS ? + 5*nTraps : + nTraps); i++) { Trap trap = Reflection.newInstance(trapClasses[Random.chances( trapChances )]); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/SewerPainter.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/SewerPainter.java deleted file mode 100644 index 4ce67f316..000000000 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/SewerPainter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Pixel Dungeon - * Copyright (C) 2012-2015 Oleg Dolya - * - * Shattered Pixel Dungeon - * Copyright (C) 2014-2022 Evan Debenham - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -package com.shatteredpixel.shatteredpixeldungeon.levels.painters; - -import com.shatteredpixel.shatteredpixeldungeon.levels.Level; -import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; -import com.watabou.utils.Random; - -import java.util.ArrayList; - -public class SewerPainter extends RegularPainter { - - @Override - protected void decorate(Level level, ArrayList rooms) { - - int[] map = level.map; - int w = level.width(); - int l = level.length(); - - for (int i=0; i < w; i++) { - if (map[i] == Terrain.WALL && - map[i + w] == Terrain.WATER && - Random.Int( 4 ) == 0) { - - map[i] = Terrain.WALL_DECO; - } - } - - for (int i=w; i < l - w; i++) { - if (map[i] == Terrain.WALL && - map[i - w] == Terrain.WALL && - map[i + w] == Terrain.WATER && - Random.Int( 2 ) == 0) { - - map[i] = Terrain.WALL_DECO; - } - } - - for (int i=w + 1; i < l - w - 1; i++) { - if (map[i] == Terrain.EMPTY) { - - int count = - (map[i + 1] == Terrain.WALL ? 1 : 0) + - (map[i - 1] == Terrain.WALL ? 1 : 0) + - (map[i + w] == Terrain.WALL ? 1 : 0) + - (map[i - w] == Terrain.WALL ? 1 : 0); - - if (Random.Int( 16 ) < count * count) { - map[i] = Terrain.EMPTY_DECO; - } - } - } - } -} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HeartRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HeartRoom.java new file mode 100644 index 000000000..98e712377 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HeartRoom.java @@ -0,0 +1,101 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard; + +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.CHASM; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.EMPTY; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.EMPTY_SP; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.PEDESTAL; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.WALL; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.WATER; + +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.PinkGhost; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; +import com.watabou.utils.Point; + +public class HeartRoom extends SpecialRoom { + + @Override + public int minWidth() { + return 15; + } + + @Override + public int minHeight() { + return 15; + } + + @Override + public int maxWidth() { + return 15; + } + + @Override + public int maxHeight() { + return 15; + } + + @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 centerX = center.x; + int centerY = center.y; + int radius = (right - left) / 2; + + int MiddlePos = (top + 7) * level.width() + left + 7; + + Mob n = new PinkGhost(); + n.pos = MiddlePos; + level.mobs.add(n); + + Painter.drawLine(level, new Point(left, top), new Point(right, top), WATER); + Painter.drawLine(level, new Point(right, top), new Point(right, bottom), CHASM); + Painter.drawLine(level, new Point(right, bottom), new Point(left, bottom), WATER); + Painter.drawLine(level, new Point(left, bottom), new Point(left, top), CHASM); + + Painter.fill(level,this, WALL); + + // 绘制爱心 + + + Painter.drawLine(level, new Point(centerX - radius, centerY), new Point(centerX, centerY - radius), PEDESTAL); + + Painter.drawLine(level, new Point(centerX + radius, centerY), new Point(centerX, centerY - radius), PEDESTAL); + + Painter.drawLine(level, new Point(centerX - radius, centerY), new Point(centerX, centerY + radius), PEDESTAL); + + Painter.drawLine(level, new Point(centerX + radius, centerY), new Point(centerX, centerY + radius), PEDESTAL); + + // 绘制眼睛外圈和门 + int eyeRadius = radius / 2; + Painter.drawCircle(level, center, eyeRadius + 5, EMPTY); + + Painter.drawCircle(level, center, eyeRadius, CHASM); + + Painter.drawCircle(level, center, eyeRadius - 2, EMPTY_SP); + + // 左侧爱心 + Painter.drawLine(level, new Point(centerX - 4, centerY - 3), new Point(centerX - 2, centerY - 5), EMPTY_SP); + Painter.drawLine(level, new Point(centerX - 2, centerY - 5), new Point(centerX, centerY - 3), EMPTY_SP); + Painter.drawLine(level, new Point(centerX, centerY - 3), new Point(centerX - 4, centerY + 1),EMPTY_SP); + Painter.drawLine(level, new Point(centerX - 5, centerY), new Point(centerX - 5, centerY - 2), EMPTY_SP); + + Painter.drawLine(level, new Point(centerX + 3, centerY + 2), new Point(centerX + 1, centerY + 4), EMPTY_SP); + + Painter.drawLine(level, new Point(centerX, centerY + 5), new Point(centerX, centerY + 5), EMPTY_SP); + + Painter.drawLine(level, new Point(centerX - 3, centerY + 2), new Point(centerX - 1, centerY + 4), EMPTY_SP); + + // 右侧爱心 + Painter.drawLine(level, new Point(centerX + 4, centerY - 3), new Point(centerX + 2, centerY - 5), EMPTY_SP); + Painter.drawLine(level, new Point(centerX + 2, centerY - 5), new Point(centerX, centerY - 3), EMPTY_SP); + Painter.drawLine(level, new Point(centerX, centerY - 3), new Point(centerX + 4, centerY + 1), EMPTY_SP); + Painter.drawLine(level, new Point(centerX + 5, centerY), new Point(centerX + 5, centerY - 2), EMPTY_SP); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LoveRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LoveRoom.java new file mode 100644 index 000000000..717f4b83b --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LoveRoom.java @@ -0,0 +1,102 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard; + +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.CHASM; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.EMPTY; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.EMPTY_SP; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.FURROWED_GRASS; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.PEDESTAL; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.WALL; +import static com.shatteredpixel.shatteredpixeldungeon.levels.Terrain.WATER; + +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.PinkGhostNPC; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; +import com.watabou.utils.Point; + +public class LoveRoom extends SpecialRoom { + + @Override + public int minWidth() { + return 17; + } + + @Override + public int minHeight() { + return 17; + } + + @Override + public int maxWidth() { + return 17; + } + + @Override + public int maxHeight() { + return 17; + } + + @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 centerX = center.x; + int centerY = center.y; + int radius = (right - left) / 2; + + int MiddlePos = (top + 7) * level.width() + left + 7; + + Mob n = new PinkGhostNPC(); + n.pos = MiddlePos; + level.mobs.add(n); + + Painter.drawLine(level, new Point(left, top), new Point(right, top), WATER); + Painter.drawLine(level, new Point(right, top), new Point(right, bottom), CHASM); + Painter.drawLine(level, new Point(right, bottom), new Point(left, bottom), WATER); + Painter.drawLine(level, new Point(left, bottom), new Point(left, top), CHASM); + + Painter.fill(level,this, WALL); + + // 绘制爱心 + + + Painter.drawLine(level, new Point(centerX - radius, centerY), new Point(centerX, centerY - radius), PEDESTAL); + + Painter.drawLine(level, new Point(centerX + radius, centerY), new Point(centerX, centerY - radius), PEDESTAL); + + Painter.drawLine(level, new Point(centerX - radius, centerY), new Point(centerX, centerY + radius), PEDESTAL); + + Painter.drawLine(level, new Point(centerX + radius, centerY), new Point(centerX, centerY + radius), PEDESTAL); + + // 绘制眼睛外圈和门 + int eyeRadius = radius / 2; + Painter.drawCircle(level, center, eyeRadius + 5, EMPTY); + + Painter.drawCircle(level, center, eyeRadius, FURROWED_GRASS); + + Painter.drawCircle(level, center, eyeRadius - 2, EMPTY_SP); + + // 左侧爱心 + Painter.drawLine(level, new Point(centerX - 4, centerY - 3), new Point(centerX - 2, centerY - 5), EMPTY_SP); + Painter.drawLine(level, new Point(centerX - 2, centerY - 5), new Point(centerX, centerY - 3), EMPTY_SP); + Painter.drawLine(level, new Point(centerX, centerY - 3), new Point(centerX - 4, centerY + 1),EMPTY_SP); + Painter.drawLine(level, new Point(centerX - 5, centerY), new Point(centerX - 5, centerY - 2), EMPTY_SP); + + Painter.drawLine(level, new Point(centerX + 3, centerY + 2), new Point(centerX + 1, centerY + 4), EMPTY_SP); + + Painter.drawLine(level, new Point(centerX, centerY + 5), new Point(centerX, centerY + 5), EMPTY_SP); + + Painter.drawLine(level, new Point(centerX - 3, centerY + 2), new Point(centerX - 1, centerY + 4), EMPTY_SP); + + // 右侧爱心 + Painter.drawLine(level, new Point(centerX + 4, centerY - 3), new Point(centerX + 2, centerY - 5), EMPTY_SP); + Painter.drawLine(level, new Point(centerX + 2, centerY - 5), new Point(centerX, centerY - 3), EMPTY_SP); + Painter.drawLine(level, new Point(centerX, centerY - 3), new Point(centerX + 4, centerY + 1), EMPTY_SP); + Painter.drawLine(level, new Point(centerX + 5, centerY), new Point(centerX + 5, centerY - 2), EMPTY_SP); + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index 8013b60f9..cb8e77dd1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -711,12 +711,12 @@ public class GameScene extends PixelScene { case LARGE: GLog.w(Messages.get(this, "large")); break; case TRAPS: GLog.w(Messages.get(this, "traps")); break; case SECRETS: GLog.w(Messages.get(this, "secrets")); break; + case BIGTRAP: GLog.w(Messages.get(this, "moretraps")); break; } for (Mob mob : Dungeon.level.mobs) { if (!mob.buffs(ChampionEnemy.class).isEmpty() && Dungeon.isChallenged(SBSG)){ GLog.n(Messages.get(ChampionEnemy.class, "warn2")); - GLog.w(Messages.get(ChampionEnemy.class, "warn")); } else if(!mob.buffs(ChampionEnemy.class).isEmpty()) { GLog.w(Messages.get(ChampionEnemy.class, "warn")); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java index bd3156dbc..c83e1585c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java @@ -73,7 +73,7 @@ public class InterlevelScene extends PixelScene { public static int returnBranch; public enum Mode { - DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL, RESET, NONE,EXBOSS,GOBACK,FRGIRLBOSS,ANCITYBOSS,DR, + DESCEND, ASCEND, CONTINUE, RESURRECT, RETURN, FALL, RESET, NONE,EXBOSS,GOBACK,FRGIRLBOSS,ANCITYBOSS,DR,GARDEN } public static Mode mode; @@ -287,6 +287,8 @@ public class InterlevelScene extends PixelScene { break; case ANCITYBOSS: exboss(4); + case GARDEN: + exboss(5); break; } @@ -571,6 +573,9 @@ public class InterlevelScene extends PixelScene { case 4: level=Dungeon.AncityBossWaterLevel(); break; + case 5: + level=Dungeon.GardenLevel(); + break; default: level = Dungeon.newLevel(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/BlueWraithSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/BlueWraithSprite.java new file mode 100644 index 000000000..36bef50c1 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/BlueWraithSprite.java @@ -0,0 +1,34 @@ +package com.shatteredpixel.shatteredpixeldungeon.sprites; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.watabou.noosa.TextureFilm; + +public class BlueWraithSprite extends MobSprite { + + public BlueWraithSprite() { + super(); + + texture( Assets.Sprites.REDWRAITH ); + + TextureFilm frames = new TextureFilm( texture, 14, 15 ); + + idle = new Animation( 5, true ); + idle.frames( frames, 0, 1 ); + + run = new Animation( 10, true ); + run.frames( frames, 0, 1 ); + + attack = new Animation( 10, false ); + attack.frames( frames, 0, 2, 3 ); + + die = new Animation( 8, false ); + die.frames( frames, 0, 4, 5, 6, 7 ); + + play( idle ); + } + + @Override + public int blood() { + return 0x88000000; + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java index f7e377165..3b6a3f7e6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java @@ -694,6 +694,27 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip } } + public void showLove() { + synchronized (EmoIcon.class) { + if (!(emo instanceof EmoIcon.Love)) { + if (emo != null) { + emo.killAndErase(); + } + emo = new EmoIcon.Love(this); + emo.visible = visible; + } + } + } + + public void hideLove() { + synchronized (EmoIcon.class) { + if (emo instanceof EmoIcon.Love) { + emo.killAndErase(); + emo = null; + } + } + } + public void showLost() { synchronized (EmoIcon.class) { if (!(emo instanceof EmoIcon.Lost)) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GhostSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GhostSprite.java index 41ba2e380..62539a0f9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GhostSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GhostSprite.java @@ -28,12 +28,12 @@ import com.watabou.glwrap.Blending; import com.watabou.noosa.TextureFilm; public class GhostSprite extends MobSprite { - + public GhostSprite() { super(); texture( Assets.Sprites.GHOST ); - + TextureFilm frames = new TextureFilm( texture, 14, 15 ); idle = new Animation( 5, true ); @@ -69,4 +69,48 @@ public class GhostSprite extends MobSprite { public int blood() { return 0xFFFFFF; } + + public static class PinkGhostSprites extends MobSprite { + + public PinkGhostSprites() { + super(); + + texture(Assets.Sprites.PINKGHOST); + + TextureFilm frames = new TextureFilm(texture, 14, 15); + + idle = new Animation(5, true); + idle.frames(frames, 0, 1); + + run = new Animation(10, true); + run.frames(frames, 0, 1); + + attack = new Animation(10, false); + attack.frames(frames, 0, 2, 3); + + die = new Animation(8, false); + die.frames(frames, 0, 4, 5, 6, 7); + + play(idle); + } + + @Override + public void draw() { + Blending.setLightMode(); + super.draw(); + Blending.setNormalMode(); + } + + @Override + public void die() { + super.die(); + emitter().start(ShaftParticle.FACTORY, 0.3f, 4); + emitter().start(Speck.factory(Speck.LIGHT), 0.2f, 3); + } + + @Override + public int blood() { + return 0xFFFFFF; + } + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java index ae379e0c1..9d07fb751 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java @@ -87,10 +87,10 @@ public class ItemSpriteSheet { public static final int PETAL = UNCOLLECTIBLE+4; public static final int SANDBAG = UNCOLLECTIBLE+5; public static final int SPIRIT_ARROW = UNCOLLECTIBLE+6; - + public static final int GUIDE_PAGE = UNCOLLECTIBLE+8; public static final int ALCH_PAGE = UNCOLLECTIBLE+9; - + public static final int TENGU_BOMB = UNCOLLECTIBLE+11; public static final int TENGU_SHOCKER = UNCOLLECTIBLE+12; static{ @@ -101,10 +101,10 @@ public class ItemSpriteSheet { assignItemRect(PETAL, 8, 8); assignItemRect(SANDBAG, 10, 10); assignItemRect(SPIRIT_ARROW,11, 11); - + assignItemRect(GUIDE_PAGE, 10, 11); assignItemRect(ALCH_PAGE, 10, 11); - + assignItemRect(TENGU_BOMB, 10, 10); assignItemRect(TENGU_SHOCKER, 10, 10); } @@ -149,11 +149,11 @@ public class ItemSpriteSheet { static{ assignItemRect(ANKH, 10, 16); assignItemRect(STYLUS, 12, 13); - + assignItemRect(SEAL, 9, 15); assignItemRect(TORCH, 12, 15); assignItemRect(BEACON, 16, 15); - + assignItemRect(HONEYPOT, 14, 12); assignItemRect(SHATTPOT, 14, 12); assignItemRect(IRON_KEY, 8, 14); @@ -166,7 +166,7 @@ public class ItemSpriteSheet { assignItemRect(MASTERY, 13, 16); assignItemRect(KIT, 16, 15); } - + private static final int BOMBS = xy(1, 5); //16 slots public static final int BOMB = BOMBS+0; public static final int DBL_BOMB = BOMBS+1; @@ -181,7 +181,7 @@ public class ItemSpriteSheet { public static final int ARCANE_BOMB = BOMBS+10; public static final int SHRAPNEL_BOMB = BOMBS+11; public static final int BLACK_KEY = BOMBS+12; - + static{ assignItemRect(BOMB, 10, 13); assignItemRect(DBL_BOMB, 14, 13); @@ -198,8 +198,8 @@ public class ItemSpriteSheet { assignItemRect(BLACK_KEY, 8, 14); } - - //16 free slots + + //16 free slots private static final int WEP_TIER1 = xy(1, 7); //8 slots public static final int WORN_SHORTSWORD = WEP_TIER1+0; @@ -279,50 +279,50 @@ public class ItemSpriteSheet { assignItemRect(GAUNTLETS, 13, 15); } - //8 free slots + //8 free slots private static final int MISSILE_WEP = xy(1, 10); //16 slots. 3 per tier + boomerang public static final int SPIRIT_BOW = MISSILE_WEP+0; - + public static final int DART = MISSILE_WEP+1; public static final int THROWING_KNIFE = MISSILE_WEP+2; public static final int THROWING_STONE = MISSILE_WEP+3; - + public static final int FISHING_SPEAR = MISSILE_WEP+4; public static final int SHURIKEN = MISSILE_WEP+5; public static final int THROWING_CLUB = MISSILE_WEP+6; - + public static final int THROWING_SPEAR = MISSILE_WEP+7; public static final int BOLAS = MISSILE_WEP+8; public static final int KUNAI = MISSILE_WEP+9; - + public static final int JAVELIN = MISSILE_WEP+10; public static final int TOMAHAWK = MISSILE_WEP+11; public static final int BOOMERANG = MISSILE_WEP+12; - + public static final int TRIDENT = MISSILE_WEP+13; public static final int THROWING_HAMMER = MISSILE_WEP+14; public static final int FORCE_CUBE = MISSILE_WEP+15; - + static{ assignItemRect(SPIRIT_BOW, 16, 16); - + assignItemRect(DART, 15, 15); assignItemRect(THROWING_KNIFE, 12, 13); assignItemRect(THROWING_STONE, 12, 10); - + assignItemRect(FISHING_SPEAR, 11, 11); assignItemRect(SHURIKEN, 12, 12); assignItemRect(THROWING_CLUB, 12, 12); - + assignItemRect(THROWING_SPEAR, 13, 13); assignItemRect(BOLAS, 15, 14); assignItemRect(KUNAI, 15, 15); - + assignItemRect(JAVELIN, 16, 16); assignItemRect(TOMAHAWK, 13, 13); assignItemRect(BOOMERANG, 14, 14); - + assignItemRect(TRIDENT, 16, 16); assignItemRect(THROWING_HAMMER, 12, 12); assignItemRect(FORCE_CUBE, 11, 12); @@ -348,7 +348,7 @@ public class ItemSpriteSheet { for (int i = TIPPED_DARTS; i < TIPPED_DARTS+16; i++) assignItemRect(i, 15, 15); } - + private static final int ARMOR = xy(1, 12); //16 slots public static final int ARMOR_CLOTH = ARMOR+0; public static final int ARMOR_LEATHER = ARMOR+1; @@ -377,7 +377,7 @@ public class ItemSpriteSheet { assignItemRect(ARMOR_ANCITY, 15,14); } - //16 free slots + //16 free slots private static final int WANDS = xy(1, 14); //16 slots public static final int WAND_MAGIC_MISSILE = WANDS+0; @@ -450,7 +450,9 @@ public class ItemSpriteSheet { public static final int MIME_THREE = ARTIFACTS+26; public static final int MIME_FOUR = ARTIFACTS+27; public static final int MIME_FIVE = ARTIFACTS+28; + public static final int WHITEROSE = ARTIFACTS+29; + public static final int REDWHITEROSE = ARTIFACTS+30; static{ assignItemRect(ARTIFACT_CLOAK, 9, 15); assignItemRect(ARTIFACT_ARMBAND, 16, 13); @@ -476,9 +478,10 @@ public class ItemSpriteSheet { assignItemRect(ARTIFACT_ROSE2, 14, 14); assignItemRect(ARTIFACT_ROSE3, 14, 14); assignItemRect(Gold_Iron, 16, 16); + assignItemRect(REDWHITEROSE, 15, 15); } - //16 free slots + //16 free slots private static final int SCROLLS = xy(1, 19); //16 slots public static final int SCROLL_KAUNAN = SCROLLS+0; @@ -493,7 +496,7 @@ public class ItemSpriteSheet { public static final int SCROLL_BERKANAN = SCROLLS+9; public static final int SCROLL_ODAL = SCROLLS+10; public static final int SCROLL_TIWAZ = SCROLLS+11; - + public static final int SCROLL_CATALYST = SCROLLS+13; public static final int ARCANE_RESIN = SCROLLS+14; static { @@ -584,13 +587,13 @@ public class ItemSpriteSheet { for (int i = SEEDS; i < SEEDS+16; i++) assignItemRect(i, 10, 10); } - + private static final int BREWS = xy(1, 25); //8 slots public static final int BREW_INFERNAL = BREWS+0; public static final int BREW_BLIZZARD = BREWS+1; public static final int BREW_SHOCKING = BREWS+2; public static final int BREW_CAUSTIC = BREWS+3; - + private static final int ELIXIRS = xy(9, 25); //8 slots public static final int ELIXIR_HONEY = ELIXIRS+0; public static final int ELIXIR_AQUA = ELIXIRS+1; @@ -603,9 +606,9 @@ public class ItemSpriteSheet { for (int i = BREWS; i < BREWS+16; i++) assignItemRect(i, 12, 14); } - - //16 free slots - + + //16 free slots + private static final int SPELLS = xy(1, 27); //16 slots public static final int MAGIC_PORTER = SPELLS+0; public static final int PHASE_SHIFT = SPELLS+1; @@ -613,11 +616,11 @@ public class ItemSpriteSheet { public static final int WILD_ENERGY = SPELLS+3; public static final int RETURN_BEACON = SPELLS+4; public static final int SUMMON_ELE = SPELLS+5; - + public static final int AQUA_BLAST = SPELLS+7; public static final int FEATHER_FALL = SPELLS+8; public static final int RECLAIM_TRAP = SPELLS+9; - + public static final int CURSE_INFUSE = SPELLS+11; public static final int MAGIC_INFUSE = SPELLS+12; public static final int ALCHEMIZE = SPELLS+13; @@ -629,11 +632,11 @@ public class ItemSpriteSheet { assignItemRect(WILD_ENERGY, 8, 16); assignItemRect(RETURN_BEACON, 8, 16); assignItemRect(SUMMON_ELE, 8, 16); - + assignItemRect(AQUA_BLAST, 11, 11); assignItemRect(FEATHER_FALL, 11, 11); assignItemRect(RECLAIM_TRAP, 11, 11); - + assignItemRect(CURSE_INFUSE, 10, 15); assignItemRect(MAGIC_INFUSE, 10, 15); assignItemRect(ALCHEMIZE, 10, 15); @@ -735,8 +738,11 @@ public class ItemSpriteSheet { public static final int DIEDBOOK= LENGYWEAPONS+10; + public static final int FIVEREN= LENGYWEAPONS+11; + static { assignItemRect(DIEDCROSSBOW, 16, 15); + assignItemRect(FIVEREN, 16, 13); } private static final int BAGS = xy(1, 31); //16 slots @@ -857,6 +863,11 @@ public class ItemSpriteSheet { public static final int FISHSKELETON= EXFOODINDEX+0; public static final int FISHBONE= EXFOODINDEX+1; + public static final int BLACKMOON= EXFOODINDEX+2; + static { + assignItemRect(BLACKMOON, 15, 12); + } + private static final int MAINPALYBOOKS = xy(1, 40); public static final int MONEYBOOKS= MAINPALYBOOKS+1; public static final int PINKBOOKS= MAINPALYBOOKS+2; @@ -885,6 +896,8 @@ public class ItemSpriteSheet { public static final int CHALLANEESICON_15= CHALLANEESICONINDEX+14; + public static final int CHALLANEESICON_16= CHALLANEESICONINDEX+15; + //for smaller 8x8 icons that often accompany an item sprite public static class Icons { @@ -931,7 +944,7 @@ public class ItemSpriteSheet { assignIconRect( RING_WEALTH, 7, 6 ); } - //16 free slots + //16 free slots private static final int SCROLLS = xy(1, 3); //16 slots public static final int SCROLL_UPGRADE = SCROLLS+0; @@ -1005,7 +1018,7 @@ public class ItemSpriteSheet { assignIconRect( SCROLL_METAMORPH, 8, 8 ); } - //16 free slots + //16 free slots private static final int POTIONS = xy(1, 6); //16 slots public static final int POTION_STRENGTH = POTIONS+0; @@ -1072,7 +1085,7 @@ public class ItemSpriteSheet { assignIconRect( POTION_SRTDIED, 6, 7 ); } - //16 free slots + //16 free slots } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java index d03ad7619..4e33b11a3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/Icons.java @@ -102,10 +102,14 @@ public enum Icons { DEPTH_LARGE, DEPTH_TRAPS, DEPTH_SECRETS, + + DEPTH_BTRAPS, CHAL_COUNT, HAPPY_ICON, + LOVE, + //icons that appear in the about screen, variable spacing LIBGDX, ALEKS, @@ -333,12 +337,18 @@ public enum Icons { case DEPTH_SECRETS: icon.frame( icon.texture.uvRectBySize( 104, 64, 7, 7 ) ); break; + case DEPTH_BTRAPS: + icon.frame( icon.texture.uvRectBySize( 112, 64, 7, 7 ) ); + break; case CHAL_COUNT: icon.frame( icon.texture.uvRectBySize( 48, 72, 7, 7 ) ); break; case HAPPY_ICON: icon.frame( icon.texture.uvRectBySize( 56, 72, 7, 5 ) ); break; + case LOVE: + icon.frame( icon.texture.uvRectBySize( 65, 72, 10, 6 ) ); + break; case LIBGDX: icon.frame( icon.texture.uvRectBySize( 0, 96, 16, 13 ) ); @@ -409,6 +419,8 @@ public enum Icons { return get(DEPTH_LARGE); case TRAPS: return get(DEPTH_TRAPS); + case BIGTRAP: + return get(DEPTH_BTRAPS); case SECRETS: return get(DEPTH_SECRETS); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/MenuPane.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/MenuPane.java index a237e43ab..8d665dabe 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/MenuPane.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/MenuPane.java @@ -102,6 +102,7 @@ public class MenuPane extends Component { case DARK: return Messages.get(GameScene.class, "dark"); case LARGE: return Messages.get(GameScene.class, "large"); case TRAPS: return Messages.get(GameScene.class, "traps"); + case BIGTRAP: return Messages.get(GameScene.class, "moretraps"); case SECRETS: return Messages.get(GameScene.class, "secrets"); } return null; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java index c8fb2b758..23d097a1d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/mlpd/vM0_6_7_X_Changes.java @@ -146,6 +146,23 @@ public class vM0_6_7_X_Changes { changes.addButton(new ChangeButton(i, ("熔岩火龙"), ("丛林暴乱的真相"))); + changes = new ChangeInfo("v0.6.5.0-Alpha5-中秋", 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 GhostSprite.PinkGhostSprites(), ("新限时任务:映月离合之殇"), + ("在中秋和国庆节这个期间一起探索悲伤幽灵它们的故事……"))); + + changes = new ChangeInfo("改动", false, null); + changes.hardlight(Window.CYELLOW); + changeInfos.add(changes); + + changes.addButton(new ChangeButton(Icons.get(Icons.INFO), ("修复"), + ("修复上个版本的一些错误"))); changes = new ChangeInfo("v0.6.5.0-Alpha4.5", true, ""); changes.hardlight(Window.TITLE_COLOR); @@ -353,7 +370,7 @@ public class vM0_6_7_X_Changes { ("在高挑中,提灯的容量更多,商店售卖更多灯油,但灯火的每次减少可能会加剧!"))); changes.addButton(new ChangeButton(Icons.get(Icons.CHALLENGE_ON), ("支离破碎"), - ("支离破碎进行了一些怪组优化,并且调整了巨魔铁匠任务"))); + ("支离破碎进行了一些怪组优化,并且调整了巨魔铁匠任务(如果在支离破碎遇到巨魔的蝙蝠任务确实有突变buff)"))); changes.addButton(new ChangeButton(Icons.get(Icons.PREFS), ("杂项修改"), ("添加Boss专武保底机制,连续三局未获得,下次必定获得"))); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndChallenges.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndChallenges.java index f6ec2e610..d4cb9bd25 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndChallenges.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndChallenges.java @@ -109,7 +109,7 @@ public class WndChallenges extends Window { cb.active = editable; //Disable - if(Challenges.NAME_IDS[i].equals("cs")||(Challenges.NAME_IDS[i].equals("icedied"))){ + if(Challenges.NAME_IDS[i].equals("cs")||(Challenges.NAME_IDS[i].equals("icedied")||(Challenges.NAME_IDS[i].equals("morelevel")))){ cb.active = false; cb.checked(false); cb.visible=false; @@ -330,6 +330,8 @@ public class WndChallenges extends Window { return new ItemSprite(ItemSpriteSheet.CHALLANEESICON_14, new ItemSprite.Glowing(0x009999)); case "dhxd": return new ItemSprite(ItemSpriteSheet.CHALLANEESICON_15, new ItemSprite.Glowing(0x384976)); + case "morelevel": + return new ItemSprite(ItemSpriteSheet.CHALLANEESICON_16, new ItemSprite.Glowing(0x98bc76)); case "cs": return Icons.get(Icons.WARNING); default: diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java index 3098b7e02..5f54d1ad6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoMob.java @@ -81,6 +81,8 @@ public class WndInfoMob extends WndTitledMessage { String level; if(mob.speed() == 1){ level = "C"; + } else if (mob.speed() >= 2.5) { + level = "S+"; } else if (mob.speed() >= 2) { level = "S"; } else if (mob.speed() >= 1.5) { @@ -149,21 +151,23 @@ public class WndInfoMob extends WndTitledMessage { private String ProName(Mob mob) { String level; if (mob.properties.contains(Char.Property.BOSS)){ - level = "领袖"; + level = Messages.get(WndInfoMob.class,"boss"); } else if (mob.properties.contains(Char.Property.MINIBOSS)){ - level = "精英"; + level = Messages.get(WndInfoMob.class,"miniboss"); + } else if (mob.properties.contains(Char.Property.HUNTER)){ + level = Messages.get(WndInfoMob.class,"hunter"); } else if (mob.properties.contains(Char.Property.ABYSS)){ - level = "深渊"; + level = Messages.get(WndInfoMob.class,"abyss"); } else if (mob.properties.contains(Char.Property.UNDEAD)){ - level = "亡灵"; + level = Messages.get(WndInfoMob.class,"undied"); } else if (mob.properties.contains(Char.Property.DEMONIC)){ - level = "恶魔"; + level = Messages.get(WndInfoMob.class,"demon"); } else if (mob.properties.contains(Char.Property.NPC)){ - level = "中立"; + level = "NPC"; } else if (mob.properties.contains(Char.Property.FIERY) || mob.properties.contains(Char.Property.ICY) || mob.properties.contains(Char.Property.ELECTRIC)){ - level = "元素"; + level = Messages.get(WndInfoMob.class,"ling"); } else { - level = "普通"; + level = Messages.get(WndInfoMob.class,"normal"); } return level; } @@ -172,9 +176,9 @@ public class WndInfoMob extends WndTitledMessage { String level; if(Dungeon.hero.lvl <= mob.maxLvl || mob.properties.contains(Char.Property.BOSS) || mob.properties.contains(Char.Property.MINIBOSS)){ - level = "可掉落"; + level = Messages.get(WndInfoMob.class,"canroll"); } else { - level = "不掉落"; + level = Messages.get(WndInfoMob.class,"noroll"); } return level; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSadGhost.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSadGhost.java index 374b740ef..736fa633d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSadGhost.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndSadGhost.java @@ -21,6 +21,8 @@ package com.shatteredpixel.shatteredpixeldungeon.windows; +import static com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost.Quest.food; + import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.Chrome; @@ -29,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; +import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; @@ -46,7 +49,7 @@ import com.watabou.noosa.ui.Component; public class WndSadGhost extends Window { - private static final int WIDTH = 120; + private static final int WIDTH = RegularLevel.holiday == RegularLevel.Holiday.ZQJ ? 150 : 120; private static final int BTN_SIZE = 32; private static final int BTN_GAP = 5; private static final int GAP = 2; @@ -54,7 +57,7 @@ public class WndSadGhost extends Window { Ghost ghost; public WndSadGhost( final Ghost ghost, final int type ) { - + super(); this.ghost = ghost; @@ -65,19 +68,21 @@ public class WndSadGhost extends Window { case 1:default: titlebar.icon( new FetidRatSprite() ); titlebar.label( Messages.get(this, "rat_title") ); - message = PixelScene.renderTextBlock( Messages.get(this, "rat")+"\n\n"+Messages.get(this, "give_item"), 6 ); + message = PixelScene.renderTextBlock( Messages.get(this, "rat")+"\n\n"+(RegularLevel.holiday == RegularLevel.Holiday.ZQJ ? Messages.get(this, "ask") :Messages.get(this, + "give_item")),6 ); break; case 2: titlebar.icon( new GnollTricksterSprite() ); titlebar.label( Messages.get(this, "gnoll_title") ); - message = PixelScene.renderTextBlock( Messages.get(this, "gnoll")+"\n\n"+Messages.get(this, "give_item"), 6 ); + message = PixelScene.renderTextBlock( Messages.get(this, "gnoll")+"\n\n"+(RegularLevel.holiday == RegularLevel.Holiday.ZQJ ? Messages.get(this, "ask") :Messages.get(this, + "give_item")),6 ); break; case 3: titlebar.icon( new GreatCrabSprite()); titlebar.label( Messages.get(this, "crab_title") ); - message = PixelScene.renderTextBlock( Messages.get(this, "crab")+"\n\n"+Messages.get(this, "give_item"), 6 ); + message = PixelScene.renderTextBlock( Messages.get(this, "crab")+"\n\n"+(RegularLevel.holiday == RegularLevel.Holiday.ZQJ ? Messages.get(this, "ask") :Messages.get(this, + "give_item")),6 ); break; - } titlebar.setRect( 0, 0, WIDTH, 0 ); @@ -87,15 +92,32 @@ public class WndSadGhost extends Window { message.setPos(0, titlebar.bottom() + GAP); add( message ); - RewardButton btnWeapon = new RewardButton( Ghost.Quest.weapon ); - btnWeapon.setRect( (WIDTH - BTN_GAP) / 2 - BTN_SIZE, message.top() + message.height() + BTN_GAP, BTN_SIZE, BTN_SIZE ); - add( btnWeapon ); + /** 中秋节布局变成三栏*/ + RewardButton btnWeapon = new RewardButton(Ghost.Quest.weapon); + if(RegularLevel.holiday == RegularLevel.Holiday.ZQJ){ + btnWeapon.setRect((WIDTH - BTN_GAP) / 3f - BTN_SIZE, message.top() + message.height() + BTN_GAP, BTN_SIZE, BTN_SIZE); + add(btnWeapon); - RewardButton btnArmor = new RewardButton( Ghost.Quest.armor ); - btnArmor.setRect( btnWeapon.right() + BTN_GAP, btnWeapon.top(), BTN_SIZE, BTN_SIZE ); - add(btnArmor); + RewardButtonDouble btnFood = new RewardButtonDouble(food); + btnFood.setRect((WIDTH - BTN_GAP) / 3f * 1.5f - BTN_SIZE/2f, message.top() + message.height() + BTN_GAP, + BTN_SIZE, BTN_SIZE); + add(btnFood); - resize(WIDTH, (int) btnArmor.bottom() + BTN_GAP); + RewardButton btnArmor = new RewardButton(Ghost.Quest.armor); + btnArmor.setRect((WIDTH - BTN_GAP) / 3f * 2.3f - BTN_SIZE/2f, message.top() + message.height() + BTN_GAP, + BTN_SIZE, BTN_SIZE); + add(btnArmor); + resize(WIDTH, (int) btnArmor.bottom() + BTN_GAP); + } else { + btnWeapon.setRect( (WIDTH - BTN_GAP) / 2f - BTN_SIZE, message.top() + message.height() + BTN_GAP, + BTN_SIZE, BTN_SIZE ); + add( btnWeapon ); + + RewardButton btnArmor = new RewardButton( Ghost.Quest.armor ); + btnArmor.setRect( btnWeapon.right() + BTN_GAP, btnWeapon.top(), BTN_SIZE, BTN_SIZE ); + add(btnArmor); + resize(WIDTH, (int) btnArmor.bottom() + BTN_GAP); + } } private void selectReward( Item reward ) { @@ -119,6 +141,11 @@ public class WndSadGhost extends Window { } else { Dungeon.level.drop( reward, ghost.pos ).sprite.drop(); } + + //准备作为奖励区域 + if(RegularLevel.holiday == RegularLevel.Holiday.ZQJ){ + Dungeon.level.drop( food, ghost.pos ).sprite.drop(); + } ghost.yell( Messages.get(this, "farewell") ); ghost.die( null ); @@ -165,6 +192,63 @@ public class WndSadGhost extends Window { } } + private class RewardButtonDouble extends Component { + + protected NinePatch bg; + protected ItemSlot slot; + + public RewardButtonDouble( Item item ){ + bg = Chrome.get( Chrome.Type.WINDOW); + add( bg ); + + slot = new ItemSlot( item ){ + @Override + protected void onPointerDown() { + bg.brightness( 1.2f ); + Sample.INSTANCE.play( Assets.Sounds.CLICK ); + } + @Override + protected void onPointerUp() { + bg.resetColor(); + } + @Override + protected void onClick() { + GameScene.show(new RewardWindowDouble(item)); + } + }; + add(slot); + } + + @Override + protected void layout() { + super.layout(); + + bg.x = x; + bg.y = y; + bg.size( width, height ); + + slot.setRect( x + 2, y + 2, width - 4, height - 4 ); + } + } + + private class RewardWindowDouble extends WndInfoItem { + + public RewardWindowDouble( Item item ) { + super(item); + + RedButton btnCancel = new RedButton(Messages.get(WndSadGhost.class, "look")){ + @Override + protected void onClick() { + RewardWindowDouble.this.hide(); + } + }; + btnCancel.setRect(0, height+2, width, 16); + add(btnCancel); + + resize(width, (int)btnCancel.bottom()); + } + } + private class RewardWindow extends WndInfoItem { public RewardWindow( Item item ) {