Update MLPD BetaXI

This commit is contained in:
LingASDJ 2022-07-27 21:13:14 +08:00
parent bb130d3a96
commit 20a3946036
72 changed files with 1204 additions and 1351 deletions

View File

@ -60,7 +60,7 @@ public class Game implements ApplicationListener {
public static int bottomInset;
// Density: mdpi=1, hdpi=1.5, xhdpi=2...
public static float density = 1;
public static float density =2;
public static String version;
public static int versionCode;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,4 +1,15 @@
###MLPD
text.herostat.hunger = 饥饿
text.herostat.skill = 命中/闪避
text.herostat.duration = 总回合数
text.herostat.score = 分数
text.herostat.real_time = 总时间
text.herostat.seed_dungeon = 种子序列号
text.herostat.seed_custom_no = SD
text.textchallenges.seed_custom_title = 种子
text.textchallenges.hint = 不输入即为随机种子
text.textchallenges.delete_seed_input = 清除
actors.buffs.halomethaneburning.name=磷火缠身
actors.buffs.halomethaneburning.heromsg=磷火像恶魔一样缠在了你的身上!
actors.buffs.halomethaneburning.burnsup=%s被烧的渣都不剩了
@ -656,6 +667,8 @@ actors.buffs.championenemy$blessed.name=天佑精英
actors.buffs.championenemy$blessed.desc=天佑精英拥有 200% 额外精准与躲避。
actors.buffs.championenemy$growing.name=成长精英
actors.buffs.championenemy$growing.desc=成长精英拥有会稳步增长的额外精准、躲避、近战伤害与伤害减免。\n\n当前精准、躲避、近战伤害加成%1$d%%\n当前伤害减免%2$d%%
actors.buffs.championenemy$halo.name=鬼磷精英
actors.buffs.championenemy$halo.desc=鬼磷精英造成 65% 额外近战伤害,会使用更强大的磷火点燃攻击目标,免疫火焰,免疫磷火,且会在死亡时引燃周遭。
actors.buffs.charm.name=魅惑
actors.buffs.charm.heromsg=你被魅惑了!
@ -1485,22 +1498,22 @@ actors.mobs.dm201.name=DM-201
actors.mobs.dm201.vent=DM-201 投出了一枚腐蚀榴弹!
actors.mobs.dm201.desc=矮人曾做过一些围绕 DM-200 的机动性缺陷展开的实验,并据此设计制造了一批完全固定的 DM 系列机器。DM-201 是经过改装的 DM-200其作为哨戒炮塔完全没有移动能力。作为交换DM-201 们的坚固程度与攻击能力都得到了显著的提升。\n\n由于 DM-201 们并没有引擎来排放废气矮人给它们装备了腐蚀气体榴弹不过DM-201 对榴弹的使用很谨慎,只有在受到来自远处的攻击时才会向敌人投掷榴弹。
actors.mobs.dm300.name=DM-300
actors.mobs.dm300.notice=侦 测 到 未 授 权 单 位
actors.mobs.dm300.shield=DM-300从外露的管线中抽取能量用护罩裹住自身
actors.mobs.dm300.vent=DM-300从喷气装置中喷出了剧毒的废气
actors.mobs.dm300.rocks=DM-300重砸地面使洞窟穹顶的岩石松脱了
actors.mobs.dm300.charging=受 到 伤 害 !正 在 启 动 能 量 塔
actors.mobs.dm300.charging_hint=DM-300 在接受能量塔供电时无法受到伤害!
actors.mobs.dm300.supercharged=毁 灭 !毁 灭 !毁 灭
actors.mobs.dm300.charge_lost=能 量 塔 损 坏 !切 换 至 本 地 供 能 模 式
actors.mobs.dm300.pylons_destroyed=警 告 !检 测 到 电 网 故 障
actors.mobs.dm300.rankings_desc=被DM-300碾压致死
actors.mobs.dm300.def_verb=格挡
actors.mobs.dm300.defeated=受 到 严 重 损 伤 !正 在 尝 试 关-
actors.mobs.dm300.desc=DM-300是矮人有史以来发明的最强大的“防御机器”。这样一台令人生畏的机器是极难制造的所以矮人们仅仅造出了几台来守护她们地下大都会的入口。\n\n它配备了可以喷出剧毒废气的通风口和一个可以用来攻击和破坏地表的高功率钻头。DM-300还可以连接到能源电网进一步增强它的力量。
actors.mobs.dm300.desc_supercharged=DM-300已被完全充能。现在DM-300能免疫外界的伤害并以两倍速度移动而且它的电钻功率现在足以_钻透墙壁_不过这会大幅降低它的移动速度。\n\n直接攻击充能状态下的DM-300毫无意义不过这附近一定有为它_提供能量的装置_摧毁了的话也许能削弱它。
actors.mobs.dm300$fallingrocks.desc=松动的岩块正从层顶滚滚而下,似乎要塌方了!
actors.mobs.newdm300.name=DM-300
actors.mobs.newdm300.notice=侦 测 到 未 授 权 单 位
actors.mobs.newdm300.shield=DM-300从外露的管线中抽取能量用护罩裹住自身
actors.mobs.newdm300.vent=DM-300从喷气装置中喷出了剧毒的废气
actors.mobs.newdm300.rocks=DM-300重砸地面使洞窟穹顶的岩石松脱了
actors.mobs.newdm300.charging=受 到 伤 害 !正 在 启 动 能 量 塔
actors.mobs.newdm300.charging_hint=DM-300 在接受能量塔供电时无法受到伤害!
actors.mobs.newdm300.supercharged=毁 灭 !毁 灭 !毁 灭
actors.mobs.newdm300.charge_lost=能 量 塔 损 坏 !切 换 至 本 地 供 能 模 式
actors.mobs.newdm300.pylons_destroyed=警 告 !检 测 到 电 网 故 障
actors.mobs.newdm300.rankings_desc=被DM-300碾压致死
actors.mobs.newdm300.def_verb=格挡
actors.mobs.newdm300.defeated=受 到 严 重 损 伤 !正 在 尝 试 关-
actors.mobs.newdm300.desc=DM-300是矮人有史以来发明的最强大的“防御机器”。这样一台令人生畏的机器是极难制造的所以矮人们仅仅造出了几台来守护她们地下大都会的入口。\n\n它配备了可以喷出剧毒废气的通风口和一个可以用来攻击和破坏地表的高功率钻头。DM-300还可以连接到能源电网进一步增强它的力量。
actors.mobs.newdm300.desc_supercharged=DM-300已被完全充能。现在DM-300能免疫外界的伤害并以两倍速度移动而且它的电钻功率现在足以_钻透墙壁_不过这会大幅降低它的移动速度。\n\n直接攻击充能状态下的DM-300毫无意义不过这附近一定有为它_提供能量的装置_摧毁了的话也许能削弱它。
actors.mobs.newdm300$fallingrocks.desc=松动的岩块正从层顶滚滚而下,似乎要塌方了!
actors.mobs.dwarfking.name=矮人国王
actors.mobs.dwarfking.notice=汝竟敢进犯王家重地!不知天高地厚!

View File

@ -1,4 +1,16 @@
###MLPD
items.scrolls.exotic.scrollofpolymorph.name=羊化秘卷
items.scrolls.exotic.scrollofpolymorph.desc=这张秘卷富含强大的转换能力。当使用时,所有在使用者视野范围内的单位都将变形成一只魔法绵羊!\n\n这种变形过程是不可逆的但不是所有敌人都会被影响。强大的敌人将抵抗这种魔法。同时变形后目标敌人身上的物品将会消失。
items.scrolls.exotic.scrollofaffection.name=魅惑秘卷
items.scrolls.exotic.scrollofaffection.desc=阅读这张秘卷会释放出一段诱人的魔音,使所有听到它的人陷入魅惑之中。
items.scrolls.exotic.scrollofconfusion.name=迷乱秘卷
items.scrolls.exotic.scrollofconfusion.desc=当阅读这张秘卷后,所有你视野范围内的生物都会陷入眩晕和失明。
items.scrolls.exotic.scrollofpetrification.name=石化秘卷
items.scrolls.exotic.scrollofpetrification.desc=一道红色的诡异闪光将以恐惧压垮使用者视觉范围内生物的心智并使它们呆立在原地。
items.wands.wandofbluefuck.name=磷焰法杖
items.wands.wandofbluefuck.staff_name=鬼磷之杖
items.wands.wandofbluefuck.desc=这根法杖由欧松木制成,饰以紫色宝石,这使它看起来相当庄严。它的顶端噼啪作响嘶嘶而鸣,渴望着释放其强大的魔法。
@ -143,6 +155,16 @@ items.food.alldrink.name=全能治疗饮料
items.food.alldrink.eat_msg=你感觉你又满血复活了。
items.food.alldrink.desc=由三个治疗药水通过回忆的技术造就了这个全能治疗饮料。\n使用者可以有一段时间的治疗且处于饱腹阶段。
items.scrolls.scrollofflamecursed.name=极度秘卷
items.scrolls.scrollofflamecursed.desc=代表着严寒。度代表着炎热。奇异的魔法能量被禁锢在秘卷羊皮纸内当这股能量被释放时会发出_耀眼的紫色审判光芒_视野中的所有敌人都会被秘卷蕴藏的魔法力量审判。 \n\n由于这个秘卷有专属标识所以无需被鉴定。
items.scrolls.scrollofflamecursed.none=这个卷轴产生了一阵耀眼的幻蓝光芒。
items.scrolls.scrollofflamecursed.one=这个卷轴产生了一阵耀眼的幻蓝光芒的同时%s被点燃了
items.scrolls.scrollofflamecursed.many=这个卷轴产生了一阵耀眼的幻蓝光芒的同时怪物们被点燃了!
items.scrolls.scrollofflamecursed.null=极度秘卷
items.potions.exotic.potionofholyfuror.name=神圣祝福合剂
items.potions.exotic.potionofholyfuror.desc=神圣的能量被浓缩为液态,这瓶合剂能够赐予你更长时间的祝福。
items.weapon.melee.magicbluesword.name=符文之刃
items.weapon.melee.magicbluesword.stats_desc=这把武器从升级中获得更多伤害。
items.weapon.melee.magicbluesword.desc=来自失落之地的神秘武器,有着明亮的蓝色刀刃。
@ -835,6 +857,7 @@ items.keys.skeletonkey.desc=这个钥匙看起来不能等闲视之:其顶端
###potions
###potions
items.potions.potion.ac_drink=饮用
items.potions.potion.turquoise=青绿药剂
@ -845,6 +868,8 @@ items.potions.potion.golden=金黄药剂
items.potions.potion.magenta=品红药剂
items.potions.potion.charcoal=煤黑药剂
items.potions.potion.ivory=乳白药剂
items.potions.potion.skyblue=天蓝药剂
items.potions.potion.deepyellow=深黄药剂
items.potions.potion.amber=琥珀药剂
items.potions.potion.bistre=深褐药剂
items.potions.potion.indigo=靛紫药剂
@ -1682,9 +1707,10 @@ items.weapon.melee.flail.name=链枷
items.weapon.melee.flail.stats_desc=这件武器精确性不高。\n这件武器不能用来偷袭。
items.weapon.melee.flail.desc=铁链上附着的一个带刺的钢球。笨重难用,能命中的话威力极强。
items.weapon.melee.gauntlet.name=魔岩拳套
items.weapon.melee.gauntlet.stats_desc=这是一套非常快的武器。
items.weapon.melee.gauntlet.desc=这个巨大的拳套由一匹红布和层层覆盖在布上的魔法岩石交织而成。戴上后,布料紧紧裹住你的整个前臂,让厚重的岩板变得像一层坚硬的皮肤。要有足够的力量才能将如此沉重的武器自如挥舞,但正是这种力量和重量的结合让这件武器发挥出可怕的威力。
items.weapon.melee.gauntlet.name=碧灰双刃
items.weapon.melee.gauntlet.typical_stats_desc=这件武器通常能格挡0~%d点伤害。通过升级可以使格挡量增长。
items.weapon.melee.gauntlet.stats_desc=这是一套极快的武器。\n\n这件武器通常能格挡0~%d点伤害。通过升级可以使格挡量增长。
items.weapon.melee.gauntlet.desc=碧绿的宝石加上纯黑的宝石再加上Δ矮人工匠—Mr.LunRes的Δ鬼斧神工造就了这个无与伦比的产物。它可以在攻击的时候有几率对敌人造成Γ燃烧Γ效果但同时会让攻击者Γ获得5回合的残废Γ效果。不过这个Δ武器的潜能Δ无比强大因此它Δ需要的力量Δ也更加强大。
items.weapon.melee.glaive.name=关刀
items.weapon.melee.glaive.stats_desc=这是一件相当缓慢的武器。\n这把武器有额外的攻击距离。
@ -1758,9 +1784,9 @@ items.weapon.melee.roundshield.typical_stats_desc=这件武器通常能格挡0~%
items.weapon.melee.roundshield.stats_desc=这件武器能格挡0~%d点伤害。通过升级可以使格挡量增长。
items.weapon.melee.roundshield.desc=这个大盾可以有效格挡攻击,在危机时刻也可以作为不错的武器使用。
items.weapon.melee.sai.name=双钗
items.weapon.melee.sai.stats_desc=这是一套非常快的武器
items.weapon.melee.sai.desc=一对轻薄的铁刃,刚好一手一把。在快速斩击方面十分出色。
items.weapon.melee.sai.name=吸血鬼刀
items.weapon.melee.sai.stats_desc=这是一套非常快的武器,且能在攻击过程中得到一定的治疗值。不幸的是,这个武器的精准十分的差
items.weapon.melee.sai.desc=泛红的身躯表示着他并不是平凡之辈能使用的武器,在快速斩击方面十分出色,在精准方面略微逊色。
items.weapon.melee.scimitar.name=弯刀
items.weapon.melee.scimitar.stats_desc=这是一把比较快的武器。
@ -1773,16 +1799,16 @@ items.weapon.melee.spear.desc=这是一根装着锋锐铁刺的细长木杆。
items.weapon.melee.sword.name=单手剑
items.weapon.melee.sword.desc=平衡性良好的剑。不算太大,但是依然比短剑长上不少。
items.weapon.melee.warhammer.name=战锤
items.weapon.melee.warhammer.stats_desc=这是一把比较精准的武器
items.weapon.melee.warhammer.desc=很少有生物能抵挡这铅铁巨块的辗压,但也只有最强壮的冒险者才能有效使用它
items.weapon.melee.warhammer.name=白金真银战锤大剑
items.weapon.melee.warhammer.stats_desc=这是一把十分精准的武器但攻速较慢。\n\n注意_恐惧过程中再次攻击敌人会激怒敌人从而失效_
items.weapon.melee.warhammer.desc=外表看起来像_大剑_实质却是被Γ地牢的魔法Γ扭曲成这个样子。\n\n别看它看起来威力不大实际上非常危险。\n\n它可以使在攻击的过程可能对Δ敌人造成恐惧+眩晕Δ效果。\n\n但同时攻击方会被Γ战锤大剑Γ反噬每次成功对敌人造成效果后Γ获得5回合易伤Γ效果
items.weapon.melee.whip.name=长鞭
items.weapon.melee.whip.stats_desc=这把武器拥有惊人的攻击距离。
items.weapon.melee.whip.desc=虽然这把武器另一端带倒刺的绳子伤害不高,但它的攻击范围是数一数二的。
items.weapon.melee.whip.name=冰霜长剑
items.weapon.melee.whip.stats_desc=这把武器拥有_惊人的攻击距离_并且可能对_敌人造成冻伤效果_
items.weapon.melee.whip.desc=虽然这把武器另一端带倒刺的绳子伤害不高,但它的_攻击范围_是数一数二的。\n\n看起来因为地牢长期_寒气弥漫_长剑已经有了_不一样的变化_了
items.weapon.melee.wornshortsword.name=破损的短剑
items.weapon.melee.wornshortsword.desc=一把十分短的剑,在大量使用后有一定的磨损。它比正常情况的短剑更轻,也更弱。
items.weapon.melee.wornshortsword.desc=一把十分短的剑,在大量使用后有一定的磨损。它比正常情况的短剑更轻,也更弱。\n\n受到地牢魔力影响现在它有不可见的剑气这可以使他能远程攻击。
###missile weapons

View File

@ -54,10 +54,10 @@ badges$badge.victory=取得Yendor护符
badges$badge.get_sc=净化怨灵根源\n将尸尘交给老杖匠
badges$badge.victory_all_classes=分别使用战士法师盗贼和女猎手取得Yendor护符
badges$badge.mastery_combo=达成10连击
badges$badge.potions_cooked_1=一场游戏中酿造3瓶药水
badges$badge.potions_cooked_2=一场游戏中酿造6瓶药水
badges$badge.potions_cooked_3=一场游戏中酿造9瓶药水
badges$badge.potions_cooked_4=一场游戏中酿造12瓶药水
badges$badge.items_crafted_1=一场游戏中酿造3瓶药水
badges$badge.items_crafted_2=一场游戏中酿造6瓶药水
badges$badge.items_crafted_3=一场游戏中酿造9瓶药水
badges$badge.items_crafted_4=一场游戏中酿造12瓶药水
badges$badge.no_monsters_slain=在不击杀怪物的情况下通过楼层
badges$badge.grim_weapon=通过"残酷"武器附魔秒杀一个怪物
badges$badge.piranhas=消灭6只食人鱼
@ -66,7 +66,6 @@ badges$badge.games_played_2=进行50场游戏
badges$badge.games_played_3=进行250场游戏
badges$badge.games_played_4=进行1000场游戏
badges$badge.godd_make=老人与海\n累计完成老杖匠的全部任务
badges$badge.death_good=作死小能手-支离破碎中免费复活次数用完
badges$badge.halofire_died=死于磷火烈焰
badges$badge.happy_end=幸福结局
badges$badge.champion_1=开启1项挑战通关
@ -81,12 +80,12 @@ badges$badge.unlock_rogue=解锁盗贼
badges$badge.unlock_huntress=解锁女猎手
badges$badge.rlpt=_支离破碎征服者_\n\n开启挑战并击败古神
badges$badge.sbdjs=风暴袭来,未完待续\n\n你通过它成功离开却不知外面风暴袭来\n\n水晶之心仍然在你手中闪闪发光,或许,这事还没完!
badges$badge.kill_mg=击败冰雪魔女
badges$badge.kill_mg=击败冰雪魔女\n\n冰雪之地的女王
badges$badge.firegirl=击败浊焰魔女\n\n浊焰地狱的恶灵
badges$badge.slimepr=击败史莱姆公主\n\n妥协的结果
badges$badge.drawf_head=击败矮人大师领主\n\n矮人王国的正规军残党
badges$badge.spicealboss=累计击败全部特殊BOSS\n\n风暴正在降临
badges$badge.nyz_shop=奈亚大亨\n\n让奈亚子自愿入驻0层
challenges.no_food=缩餐节食
challenges.no_food_desc=食物本就稀缺,但你还需要注意节食!\n\n・使用各类食物与丰饶之角的饱腹效果为原本的三分之一。\n・其他恢复饥饿的机制不受影响。
challenges.no_armor=信念护体
@ -119,16 +118,16 @@ challenges.hard = 梦境之声-T2挑战
challenges.warning = 寻觅之声-T3挑战
challenges.test = 测试时间-DEBUG
challenges.rlpt = Π支离破碎Π
challenges.rlpt_desc=地牢的魔力正在不断侵蚀这里,现实不过只是一场噩梦。\n\n击败第五层Boss后所有怪物全部随机Boss则固定刷新并且不会出现冰女那些阴间Boss\n\n特殊说明盗贼开局斗篷替换成5个隐形药水。并且没有NPC!\n\n启用本挑战你可以获得3次免费复活机会
challenges.rlpt_desc=地牢的魔力正在不断侵蚀这里,现实不过只是一场噩梦。\n\n击败第五层Boss后所有怪物楼层全部随机Boss则固定刷新并且不会出现冰女那些阴间Boss\n\n特殊说明没有任务类型NPC!\n\n启用本挑战你开局可以额外获得1个十字架
challenges.sbsg = Π突变巨兽Π
challenges.sbsg_desc=人类回想起了,被巨人支配的恐惧\n-所有生物都会突变激素变得更大,但一些因为一些其他不良反应原因会变得更小。\n-生物的大小决定了他们的移动速度、防御、闪避和近战伤害。\n-你的极度饥饿也会变得更加致命。\n-同时,如果怪物失去了你的视野,他将变回去,属性也会和无挑一样。
challenges.sbsg_desc=人类回想起了,被怪物支配的恐惧\n-所有生物都会突变激素变得更大,但一些因为一些其他不良反应原因会变得更小。\n-生物的大小决定了他们的移动速度、防御、闪避和近战伤害。\n-你的极度饥饿也会变得更加致命。\n-同时,如果怪物失去了你的视野,他将变回去,属性也会和无挑一样。
challenges.exsg = Π药水癔症Π
challenges.exsg_desc=药水癔症详细规则:\n力量药水 力量-1\n灵视药剂 喝后失明5回合\n隐形药剂 喝后立刻怒吼\n经验药剂 喝后立刻流血6回合\n极速药剂 喝后立刻残废8回合\n==========================\n小型口粮 吃后立刻获得极速8回合\n炖肉 吃后立刻升级\n冷冻生肉片 吃后获得奥术护盾\n全肉大饼 吃后立刻获得8回合极速 且+1力量\n不知道何种原因大部分正面药水你都感觉有毒\n部分药水完全处于DeBuff,但食物却会很有用!\n恐药异症的效果同样存在
challenges.light&black = Π空洞旅程Π
challenges.light&black_desc=\n_一次次的踏入地牢只会使自己更加的被恶毒的魔法侵蚀。_这一次你已不知道是何时再来到这个地牢但邪恶的诡异气氛扑面而来。一个神秘人给了你一个提灯。你却不知道何时会被这里的魔法吞噬。\n\n开启本挑战将会获得在开局获得特殊理智Buff并且追加一个新道具_提灯_提灯的精神力量需要玩家击败敌人获得。\n\n_只有光芒中你才能活下去。否则你会被黑暗蚕食一点点的丧失理智成为怪物。_\n\n一旦你理智过低将会出现特殊怪物和Debuff。理智为0将立刻死亡并成为怪物如果有十字架将会复活并回复100理智,但你上次的东西将全部在上一次你理智变为0的怪物身上。\n\n_它是你前世的回响。打败它夺回它的力量让自己重归完整。_\n\n_完成光与影挑战将会在0层追加神秘人物……以及解锁全新物品和武器!_\n\n开启本挑战将会在开局获得240点理智在_没有光芒下_和_部分怪物的近战_将会使你理智降低。详情查看下表:\n\n-棕色老鼠:20%概率(-1理智/每回合)\n-黑色怨灵:10%概率(-3理智/每回合)\n-火把猎人:40%概率(-1理智/每回合)\n-矮人术士:15%概率(-5理智/每回合)\n-寒冰老鼠:25%概率(-2理智/每回合)\n-DM200:10%概率(-7理智/每回合)\n-矮人武僧:30%的概率(-3理智/每回合)\n\n_环境理智扣除_:\n-没有光芒Buff的情况下\n:\n\n_理智回复策略_:\n-_1_:存在光芒的情况下以:[(+1理智+楼层深度/10)/每回合](举例:20层没有光芒的情况下,1+20/10=3(+3智/每回合)\n-_2_.商人售卖信仰药水喝下去追加40回合理智\n-_3_.击败敌人可以获得敌人的灵魂,灵魂到一定数量可以使提灯可以再次点亮道路。灵魂也可以缓慢回复理智。(50灵魂=1理智回复)
challenges.light&black_desc=\n_一次次的踏入地牢只会使自己更加的被恶毒的魔法侵蚀。_这一次你已不知道是何时再来到这个地牢但邪恶的诡异气氛扑面而来。一个神秘人给了你一个提灯。你却不知道何时会被这里的魔法吞噬。\n\n开启本挑战将会获得在开局获得特殊理智Buff并且追加一个新道具_提灯_提灯的精神力量需要玩家击败敌人获得。\n\n_只有光芒中你才能活下去。否则你会被黑暗蚕食一点点的丧失理智成为怪物。_\n\n详情请看更新记录
challenges.happy = 追加内容
challenges.boss = _[BossRush]_
challenges.boss_desc=在一次又一次的冒险中,首领越来越熟悉你了,这一次,首领将会全方面对你实行进攻。\n\n但地牢里面将没有常规作战楼层但是会对战8个首领。每个首领前都会有一个补给层\n\n_据说还有第9个首领它是曾经直接导致矮人王国堕落的元凶。_\n\n未完成
challenges.boss_desc=在一次又一次的冒险中,首领越来越熟悉你了,这一次,首领将会全方面对你实行进攻。\n\n但地牢里面将没有常规作战楼层但是会对战8个首领。每个首领前都会有一个补给层\n\n未完成

View File

@ -34,7 +34,7 @@ scenes.interlevelscene.dialog_4=魔绫像素地牢-始于_2021年2月_\n\n感
scenes.interlevelscene.dialog_5=有些时候_直面失败_,\n\n或许并不是什么坏事
scenes.interlevelscene.dialog_6=_小心奸商_\n\n他甚至不会卖给你_未诅咒的物品_
scenes.interlevelscene.dialog_7=Δ种子Δ是个好东西,\n\n_关键看你_会不会用
scenes.interlevelscene.dialog_8=_死灵领主_是无敌的\n\n你需要击败_骷髅王_!
scenes.interlevelscene.dialog_8=你的运气常常是通关的必要东西之一,当然你可以试试自定义种子来盘爽局!
scenes.interlevelscene.dialog_9=呐呐呐,\n\n你听说过Ξ水晶之城Ξ的谣言吗
scenes.interlevelscene.dialog_10=_总是暴毙?_这可能并不是你的问题。\n\nΞ总之不要气馁菜就多练练Ξ。
scenes.interlevelscene.dialog_11=魔绫像素地牢,绝望与希望并存。
@ -45,7 +45,7 @@ scenes.interlevelscene.dialog_15=你知道吗?\n\n作者游玩的第一个地
scenes.interlevelscene.dialog_16=_太难打了?试着做一些新东西_\n\n让你的敌人只能抱头鼠窜!
scenes.interlevelscene.dialog_17=_魔绫像素地牢_\n\n上半段圆满结束感谢各位参与_Demo_的人员。
scenes.interlevelscene.dialog_18=_史莱姆王子_太难打\n\n试着靠门打他。
scenes.interlevelscene.dialog_19=DM920矮人王国噩梦的开始。
scenes.interlevelscene.dialog_19=史莱姆公主,古堡最后的守护者!
scenes.interlevelscene.dialog_20=感谢_那些回忆_和_罗贝里_的大力支持
scenes.interlevelscene.dialog_21=Hod:\n\n明明清了水却还带电太屑了。
scenes.interlevelscene.dialog_22=笑笑就好:\n\n咒杖会意想不到的好用敢赌吗?
@ -93,9 +93,9 @@ scenes.changesscene.who=MLPD详细日志摘要
scenes.aboutselectscene.title=关于游戏
scenes.alchemyscene.title=炼金
scenes.alchemyscene.text=放入材料以制作新的道具!
scenes.alchemyscene.select=选择一件物品
scenes.alchemyscene.select=选择一件物品z
scenes.alchemyscene.cost=能量消耗:%d
scenes.alchemyscene.energy=炼金能量:%d
scenes.alchemyscene.energy=能量:
scenes.amuletscene.exit=回到主城,未完待续
scenes.amuletscene.stay=留在这里,稍后离开
@ -197,8 +197,8 @@ scenes.titlescene.patreon_body=《破碎像素地牢》是一款完全免费的
scenes.titlescene.patreon_button=Patreon 赞助页面
scenes.welcomescene.welcome_msg=魔绫的像素地牢是一个roguelike类RPG游戏有着随机生成的敌人、关卡、物品和陷阱\n\n每一轮游戏都是一次全新的挑战注意死亡是永久的\n\n祝你在地牢一路顺风
scenes.welcomescene.update_intro=魔绫的像素地牢已经更新!
scenes.welcomescene.update_msg=0.5.0.5经过56天终于出炉基于破碎0.8.1!具体请看更新记录!By JDSA——Ling
scenes.welcomescene.update_intro=魔绫的像素地牢---重大更新!
scenes.welcomescene.update_msg=0.6.0.0经过一段时间终于出炉基于破碎1.2.3!!! 具体请看更新记录!By JDSA——Ling
scenes.welcomescene.patch_intro=魔绫的像素地牢补丁已经成功安装!
scenes.welcomescene.patch_bugfixes=本次补丁包含少量Bug修复。
scenes.welcomescene.patch_translations=本次补丁包含翻译文本更新。

View File

@ -448,4 +448,7 @@ ui.changelist.mlpd.vm0_5_x_changes.bug_05x18=-修复十字架重置没有生效
ui.changelist.mlpd.vm0_5_x_changes.fr=
ui.changelist.mlpd.vm0_5_x_changes.frlogs=尚待调查……
ui.changelist.mlpd.vm0_6_7_x_changes.bug_06x20=-1.支离破碎bug已修复\n2.部分符石文本缺失已修复\n3.0层饱食度问题已修复\n4.炼金移植有问题已修复\n5.药水文本缺失已修复\n6.钥匙材质有问题已修复\n7.怨灵血量异常已修复\n8.种子显示问题已修复\n9.快捷栏优化问题已修复\n10.初始升级卷轴,以及初始物品已修复\n12.奈亚子初始奖励异常已修复\n13.由于V1.2.3楼层名字导致部分BOSS超类闪退已修复\n14.精英强敌鬼磷文本缺失已修复\n15.炼金合成表已移植\n16.风行水上部分buff已经重做\n17.部分原始Java类已合并\n18.英雄类逻辑楼层应该为0已修复\n19.光Buff有问题已修复\n20.恶魔层贴图有问题已修复\n21.部分buff尚未定义在破碎123英雄类里面已修复\n22.尚方宝剑属性问题已修复
//ui.changelist.mlpd.vm0_5_x_changes.xxx//

View File

@ -2,6 +2,9 @@ windows.textchallenges.seed_custom_title = 种子
windows.textchallenges.hint = 不输入即为随机种子
windows.textchallenges.delete_seed_input = 清除
windows.wndsettings$extendtab.quickslots=快捷栏设置
windows.wndsettings$extendtab.wxts=温馨提示:进入游戏后才能调整快捷栏\n\n这是因为技术问题但是这里已经提醒你了。\n\n当你进入游戏后,这里就会变成快捷栏设置区!
windows.wndinfomob.dsinfo = 闪避概率:
windows.wndinfomob.maxinfo = 掉落限制LV:
windows.wndinfomob.getexp = 可获经验:

View File

@ -76,7 +76,7 @@ public class Badges {
KILL_ROTHEART ( 20 ),
GET_SC ( 21 ),
KILL_COLDELE ( 22 ),
DEATH_GOOD ( 23 ),
HALOFIRE_DIED ( 24 ),
//silver
@ -623,12 +623,6 @@ public class Badges {
validateGOODMAKE();
}
public static void DEATH_GOOD() {
Badge badge = Badge.DEATH_GOOD;
local.add( badge );
displayBadge( badge );
}
public static void HALOFIRE_DIED() {
Badge badge = Badge.HALOFIRE_DIED;
local.add( badge );

View File

@ -236,6 +236,7 @@ public class Dungeon {
depth = -1;
gold = 0;
energy = 0;
nyzbuy = 1;
droppedItems = new SparseArray<>();
portedItems = new SparseArray<>();

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon;
import com.shatteredpixel.shatteredpixeldungeon.custom.utils.Constants;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
@ -37,7 +38,7 @@ public class QuickSlot {
*/
//note that the current max size is coded at 4, due to UI constraints, but it could be much much bigger with no issue.
public static int SIZE = 6;
public static int SIZE = Constants.MAX_QUICKSLOTS;
private Item[] slots = new Item[SIZE];
@ -92,11 +93,11 @@ public class QuickSlot {
}
public void convertToPlaceholder(Item item){
if (contains(item)) {
Item placeholder = item.virtual();
if (placeholder == null) return;
for (int i = 0; i < SIZE; i++) {
if (getItem(i) == item) setSlot(i, placeholder);
}
@ -107,7 +108,7 @@ public class QuickSlot {
ArrayList<Item> result = new ArrayList<>();
for (int i = 0; i < SIZE; i ++)
if (getItem(i) != null && !isPlaceholder(i))
if (getItem(i) != null && !isPlaceholder(i))
result.add(getItem(i));
return Random.element(result);

View File

@ -21,6 +21,7 @@
package com.shatteredpixel.shatteredpixeldungeon;
import com.shatteredpixel.shatteredpixeldungeon.custom.utils.Constants;
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
@ -38,7 +39,13 @@ public class SPDSettings extends GameSettings {
//Version info
public static final String KEY_VERSION = "version";
public static void quickslots( int value ){
put( KEY_QUICKSLOTS, value );
}
public static int quickslots(){
return getInt( KEY_QUICKSLOTS, 4, Constants.MIN_QUICKSLOTS, Constants.MAX_QUICKSLOTS);
}
private static final String DEBUG_REPORT = "debug_report";
public static boolean debugReport() {
return getBoolean(DEBUG_REPORT,false);

View File

@ -45,7 +45,7 @@ public class ShatteredPixelDungeon extends Game {
public static final int v1_0_3 = 574;
public static final int v1_1_2 = 587;
public static final int v1_2_0 = 609;
public static final int v1_2_0 = 619;
public ShatteredPixelDungeon( PlatformSupport platform ) {
super( sceneClass == null ? GoScene.class : sceneClass, platform );
@ -101,7 +101,7 @@ public class ShatteredPixelDungeon extends Game {
com.shatteredpixel.shatteredpixeldungeon.levels.PrisonBossLevel.ExitVisualWalls.class,
"com.shatteredpixel.shatteredpixeldungeon.levels.NewPrisonBossLevel$exitVisualWalls" );
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300.class,
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300.class,
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300" );
com.watabou.utils.Bundle.addAlias(
com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel.class,

View File

@ -34,7 +34,7 @@ public class Statistics {
public static int ankhsUsed;
public static int spawnersIce;
public static int naiyaziCollected;
public static boolean isCustomSeed = false;
//used for hero unlock badges
public static int upgradesUsed;
public static int sneakAttacks;

View File

@ -44,9 +44,11 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Dread;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FireImbue;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FrostImbue;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FrostImbueEX;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Fury;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HaloFireImBlue;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HasteLing;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hex;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LifeLink;
@ -57,6 +59,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Preparation;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RoseShiled;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Slow;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
@ -387,6 +390,7 @@ public abstract class Char extends Actor {
if (buff(FireImbue.class) != null) buff(FireImbue.class).proc(enemy);
if (buff(FrostImbue.class) != null) buff(FrostImbue.class).proc(enemy);
if (buff(FrostImbueEX.class) != null) buff(FrostImbue.class).proc(enemy);
if (enemy.isAlive() && enemy.alignment != alignment && prep != null && prep.canKO(enemy)){
enemy.HP = 0;
@ -513,6 +517,7 @@ public abstract class Char extends Actor {
if ( buff( Stamina.class ) != null) speed *= 1.5f;
if ( buff( Adrenaline.class ) != null) speed *= 2f;
if ( buff( Haste.class ) != null) speed *= 3f;
if ( buff( HasteLing.class ) != null) speed *= 3f;
if ( buff( Dread.class ) != null) speed *= 2f;
return speed;
}
@ -540,6 +545,10 @@ public abstract class Char extends Actor {
return;
}
if(buff(RoseShiled.class) != null && !this.isImmune(RoseShiled.class)){
return;
}
if(isInvulnerable(src.getClass())){
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
return;

View File

@ -30,7 +30,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
public class Degrade extends FlavourBuff {
public static final float DURATION = 30f;
public static final float ADURATION = 5f;
{
type = buffType.NEGATIVE;
announced = true;

View File

@ -0,0 +1,4 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
public class HasteLing extends Haste{
}

View File

@ -67,7 +67,7 @@ public class Hunger extends Buff implements Hero.Doom {
if (Dungeon.level.locked
|| target.buff(WellFed.class) != null
|| target.buff(ScrollOfChallenge.ChallengeArena.class) != null){
|| target.buff(ScrollOfChallenge.ChallengeArena.class) != null|| Dungeon.depth == 0){
spend(STEP);
return true;
}

View File

@ -23,49 +23,37 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.items.lightblack.OilLantern;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
public class Light extends FlavourBuff {
private static final float DELAY = 5.0f;
public static final int DISTANCE = 6;
public static final float DURATION = 300.0f;
public Light() {
this.type = Buff.buffType.POSITIVE;
{
type = buffType.POSITIVE;
}
public boolean attachTo(Char target) {
if (!Light.super.attachTo(target)) {
public static final float DURATION = 250f;
public static final int DISTANCE = 6;
@Override
public boolean attachTo( Char target ) {
if (super.attachTo( target )) {
if (Dungeon.level != null) {
target.viewDistance = Math.max( Dungeon.level.viewDistance, DISTANCE );
Dungeon.observe();
}
return true;
} else {
return false;
}
if (Dungeon.level == null) {
return true;
}
target.viewDistance = Math.max(Dungeon.level.viewDistance, 6);
Dungeon.observe();
return true;
}
public boolean act() {
OilLantern lantern = Dungeon.hero.belongings.getItem(OilLantern.class);
if (lantern == null || !lantern.isActivated() || lantern.getCharge() <= 0) {
assert lantern != null;
lantern.deactivate(Dungeon.hero, false);
detach();
return true;
}
lantern.spendCharge();
spend(DELAY);
return true;
}
@Override
public void detach() {
this.target.viewDistance = Dungeon.level.viewDistance;
target.viewDistance = Dungeon.level.viewDistance;
Dungeon.observe();
Light.super.detach();
super.detach();
}
public void weaken( int amount ){
@ -77,18 +65,23 @@ public class Light extends FlavourBuff {
return BuffIndicator.LIGHT;
}
public void fx(boolean on) {
if (on) {
this.target.sprite.add(CharSprite.State.ILLUMINATED);
} else {
this.target.sprite.remove(CharSprite.State.ILLUMINATED);
}
@Override
public float iconFadePercent() {
return Math.max(0, (DURATION - visualcooldown()) / DURATION);
}
@Override
public void fx(boolean on) {
if (on) target.sprite.add(CharSprite.State.ILLUMINATED);
else target.sprite.remove(CharSprite.State.ILLUMINATED);
}
@Override
public String toString() {
return Messages.get(this, "name");
}
@Override
public String desc() {
return Messages.get(this, "desc", dispTurns());
}

View File

@ -0,0 +1,95 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.items.lightblack.OilLantern;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
public class LightSan extends FlavourBuff {
private static final float DELAY = 5.0f;
public static final int DISTANCE = 6;
public static final float DURATION = 300.0f;
public LightSan() {
this.type = Buff.buffType.POSITIVE;
}
public boolean attachTo(Char target) {
if (!LightSan.super.attachTo(target)) {
return false;
}
if (Dungeon.level == null) {
return true;
}
target.viewDistance = Math.max(Dungeon.level.viewDistance, 6);
Dungeon.observe();
return true;
}
public boolean act() {
OilLantern lantern = Dungeon.hero.belongings.getItem(OilLantern.class);
if (lantern == null || !lantern.isActivated() || lantern.getCharge() <= 0) {
assert lantern != null;
lantern.deactivate(Dungeon.hero, false);
detach();
return true;
}
lantern.spendCharge();
spend(DELAY);
return true;
}
public void detach() {
this.target.viewDistance = Dungeon.level.viewDistance;
Dungeon.observe();
LightSan.super.detach();
}
public void weaken( int amount ){
spend(-amount);
}
@Override
public int icon() {
return BuffIndicator.LIGHT;
}
public void fx(boolean on) {
if (on) {
this.target.sprite.add(CharSprite.State.ILLUMINATED);
} else {
this.target.sprite.remove(CharSprite.State.ILLUMINATED);
}
}
public String toString() {
return Messages.get(this, "name");
}
public String desc() {
return Messages.get(this, "desc", dispTurns());
}
}

View File

@ -50,6 +50,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Drowsy;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Foresight;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FrostImbueEX;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HasteLing;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.HoldFast;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
@ -1063,7 +1064,7 @@ public class Hero extends Char {
//TODO this is slightly brittle, it assumes there are no disjointed sets of entrance tiles
} else if (Dungeon.level.map[pos] == Terrain.ENTRANCE) {
if (Dungeon.depth == 1) {
if (Dungeon.depth == 0) {
if (belongings.getItem( Amulet.class ) == null) {
Game.runOnRenderThread(new Callback() {
@ -1654,7 +1655,7 @@ public class Hero extends Char {
return stealth;
}
@Override
public void die( Object cause ) {
@ -1679,6 +1680,8 @@ public class Hero extends Char {
Buff.affect(s, DeadSoul.class);
GameScene.flash(0x80FF0000);
}
if (ankh != null) {
interrupt();
resting = false;
@ -1828,11 +1831,11 @@ public class Hero extends Char {
if (Dungeon.PrisonWaterLevel()&& Dungeon.level.water[pos]){
Buff.affect(hero, Barkskin.class).set( 2 + hero.lvl/4, 10 );
Buff.prolong(this, Bless.class,Bless.GODSPOERF);
Buff.affect(this, Haste.class, Haste.DURATION/20);
Buff.affect(this, HasteLing.class, Haste.DURATION/20);
Buff.affect(this, Shadows.class, Shadows.DURATION/10f);
} else if(Dungeon.PrisonWaterLevel()&& !Dungeon.level.water[pos])
for (Buff buff : hero.buffs()) {
if (buff instanceof Shadows||buff instanceof Haste ) {
if (buff instanceof Shadows||buff instanceof HasteLing) {
buff.detach();
}
}

View File

@ -55,6 +55,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CloakOfShadows;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.MasterThievesArmband;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.BookBag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.HerbBag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.KingBag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.VelvetPouch;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.BrokenBooks;
@ -72,6 +73,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.lightblack.OilLantern;
import com.shatteredpixel.shatteredpixeldungeon.items.lightblack.OilPotion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.AlchemicalCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfInvisibility;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLightningShiledX;
@ -82,10 +84,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfDragonKingBreath;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.GoldBAo;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfFlameCursed;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfLullaby;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRage;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTerror;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfMysticalEnergy;
@ -124,8 +128,6 @@ import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.AikeLaier;
import com.shatteredpixel.shatteredpixeldungeon.plants.Blindweed;
import com.shatteredpixel.shatteredpixeldungeon.plants.Firebloom;
import com.shatteredpixel.shatteredpixeldungeon.plants.SkyBlueFireBloom;
import com.watabou.utils.DeviceCompat;
public enum HeroClass {
@ -144,6 +146,10 @@ public enum HeroClass {
public void initHero( Hero hero ) {
if (Dungeon.isChallenged(Challenges.RLPT)) {
new Ankh().quantity(1).identify().collect();
}
if (Dungeon.isChallenged(Challenges.PRO)){
new FrozenCarpaccio().quantity(11).identify().collect();
@ -208,10 +214,12 @@ public enum HeroClass {
new FireFishSword().quantity(1).identify().collect();
new EndingBlade().quantity(1).identify().collect();
new PotionOfDragonKingBreath().quantity(1).identify().collect();
new PotionOfFrost().quantity(100).identify().collect();
new WandOfBlueFuck().quantity(1).identify().collect();
new SkyBlueFireBloom.Seed().quantity(10).identify().collect();
new ScrollOfFlameCursed().quantity(10).identify().collect();
new PotionOfLightningShiled().quantity(42).collect();
new ScrollOfRoseShiled().quantity(45).identify().collect();
new ScrollOfTerror().quantity(45).identify().collect();
Dungeon.gold = 600000000;
hero.STR = 27;
hero.lvl = 31;
@ -227,13 +235,19 @@ public enum HeroClass {
if (!Challenges.isItemBlocked(i)) hero.belongings.armor = (ClothArmor)i;
i = new Food();
new HerbBag().quantity(1).identify().collect();
new PotionOfHealing().quantity(3).identify().collect();
new ScrollOfUpgrade().quantity(1).identify().collect();
//new IndexBooks().quantity(1).identify().collect();
if (!Challenges.isItemBlocked(i)) i.collect();
new ScrollOfIdentify().identify();
new VelvetPouch().collect();
Dungeon.LimitedDrops.VELVET_POUCH.drop();
if (DeviceCompat.isDebug()){
new MeatPie().quantity(100).identify().collect();
}
Waterskin waterskin = new Waterskin();
waterskin.collect();
@ -482,6 +496,8 @@ public enum HeroClass {
return Messages.get(HeroClass.class, "rogue_unlock");
case HUNTRESS:
return Messages.get(HeroClass.class, "huntress_unlock");
case COMINGSOON:
return Messages.get(HeroClass.class, "slime_unlock");
}
}

View File

@ -46,7 +46,7 @@ public class Bestiary {
case 1:
//3x rat, 1x snake
return new ArrayList<>(Arrays.asList(
SlimePrincess.class, Rat.class,
Rat.class, Rat.class,
Rat.class, OGPDZSLS.class, Snake.class,
Snake.class,Snake.class,Snake.class));
case 2:

View File

@ -1,685 +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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Slow;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.EarthParticle;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.MetalShard;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.DM300Sprite;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Camera;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.particles.Emitter;
import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import com.watabou.utils.Rect;
import java.util.ArrayList;
import java.util.List;
public class DM300 extends Mob {
{
spriteClass = DM300Sprite.class;
HP = HT = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 400 : 300;
EXP = 30;
defenseSkill = 15;
properties.add(Property.BOSS);
properties.add(Property.INORGANIC);
properties.add(Property.LARGE);
}
@Override
public int damageRoll() {
return Random.NormalIntRange( 15, 25 );
}
@Override
public int attackSkill( Char target ) {
return 20;
}
@Override
public int drRoll() {
return Random.NormalIntRange(0, 10);
}
public int pylonsActivated = 0;
public boolean supercharged = false;
public boolean chargeAnnounced = false;
private final int MIN_COOLDOWN = 5;
private final int MAX_COOLDOWN = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 7 : 9;
private int turnsSinceLastAbility = -1;
private int abilityCooldown = Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN);
private int lastAbility = 0;
private static final int NONE = 0;
private static final int GAS = 1;
private static final int ROCKS = 2;
private static final String PYLONS_ACTIVATED = "pylons_activated";
private static final String SUPERCHARGED = "supercharged";
private static final String CHARGE_ANNOUNCED = "charge_announced";
private static final String TURNS_SINCE_LAST_ABILITY = "turns_since_last_ability";
private static final String ABILITY_COOLDOWN = "ability_cooldown";
private static final String LAST_ABILITY = "last_ability";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(PYLONS_ACTIVATED, pylonsActivated);
bundle.put(SUPERCHARGED, supercharged);
bundle.put(CHARGE_ANNOUNCED, chargeAnnounced);
bundle.put(TURNS_SINCE_LAST_ABILITY, turnsSinceLastAbility);
bundle.put(ABILITY_COOLDOWN, abilityCooldown);
bundle.put(LAST_ABILITY, lastAbility);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
pylonsActivated = bundle.getInt(PYLONS_ACTIVATED);
supercharged = bundle.getBoolean(SUPERCHARGED);
chargeAnnounced = bundle.getBoolean(CHARGE_ANNOUNCED);
turnsSinceLastAbility = bundle.getInt(TURNS_SINCE_LAST_ABILITY);
abilityCooldown = bundle.getInt(ABILITY_COOLDOWN);
lastAbility = bundle.getInt(LAST_ABILITY);
if (turnsSinceLastAbility != -1){
BossHealthBar.assignBoss(this);
if (!supercharged && pylonsActivated == totalPylonsToActivate()) BossHealthBar.bleed(true);
}
}
@Override
protected boolean act() {
if (paralysed > 0){
return super.act();
}
//ability logic only triggers if DM is not supercharged
if (!supercharged){
if (turnsSinceLastAbility >= 0) turnsSinceLastAbility++;
//in case DM-300 hasn't been able to act yet
if (fieldOfView == null || fieldOfView.length != Dungeon.level.length()){
fieldOfView = new boolean[Dungeon.level.length()];
Dungeon.level.updateFieldOfView( this, fieldOfView );
}
//determine if DM can reach its enemy
boolean canReach;
if (enemy == null){
if (Dungeon.level.adjacent(pos, Dungeon.hero.pos)){
canReach = true;
} else {
canReach = (Dungeon.findStep(this, Dungeon.hero.pos, Dungeon.level.openSpace, fieldOfView, true) != -1);
}
} else {
if (Dungeon.level.adjacent(pos, enemy.pos)){
canReach = true;
} else {
canReach = (Dungeon.findStep(this, enemy.pos, Dungeon.level.openSpace, fieldOfView, true) != -1);
}
}
if (state != HUNTING){
if (Dungeon.hero.invisible <= 0 && canReach){
beckon(Dungeon.hero.pos);
}
} else {
if (enemy == null && Dungeon.hero.invisible <= 0) enemy = Dungeon.hero;
//more aggressive ability usage when DM can't reach its target
if (enemy != null && !canReach){
//try to fire gas at an enemy we can't reach
if (turnsSinceLastAbility >= MIN_COOLDOWN){
//use a coneAOE to try and account for trickshotting angles
ConeAOE aim = new ConeAOE(new Ballistica(pos, enemy.pos, Ballistica.WONT_STOP), Float.POSITIVE_INFINITY, 30, Ballistica.STOP_SOLID);
if (aim.cells.contains(enemy.pos)) {
lastAbility = GAS;
turnsSinceLastAbility = 0;
GLog.w(Messages.get(this, "vent"));
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
sprite.zap(enemy.pos);
return false;
} else {
ventGas(enemy);
Sample.INSTANCE.play(Assets.Sounds.GAS);
return true;
}
//if we can't gas, then drop rocks
//unless enemy is already stunned, we don't want to stunlock them
} else if (enemy.paralysed <= 0) {
lastAbility = ROCKS;
turnsSinceLastAbility = 0;
GLog.w(Messages.get(this, "rocks"));
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
((DM300Sprite)sprite).slam(enemy.pos);
return false;
} else {
dropRocks(enemy);
Sample.INSTANCE.play(Assets.Sounds.ROCKS);
return true;
}
}
}
} else if (enemy != null && fieldOfView[enemy.pos]) {
if (turnsSinceLastAbility > abilityCooldown) {
if (lastAbility == NONE) {
//50/50 either ability
lastAbility = Random.Int(2) == 0 ? GAS : ROCKS;
} else if (lastAbility == GAS) {
//more likely to use rocks
lastAbility = Random.Int(4) == 0 ? GAS : ROCKS;
} else {
//more likely to use gas
lastAbility = Random.Int(4) != 0 ? GAS : ROCKS;
}
//doesn't spend a turn if enemy is at a distance
if (Dungeon.level.adjacent(pos, enemy.pos)){
spend(TICK);
}
turnsSinceLastAbility = 0;
abilityCooldown = Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN);
if (lastAbility == GAS) {
GLog.w(Messages.get(this, "vent"));
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
sprite.zap(enemy.pos);
return false;
} else {
ventGas(enemy);
Sample.INSTANCE.play(Assets.Sounds.GAS);
return true;
}
} else {
GLog.w(Messages.get(this, "rocks"));
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
((DM300Sprite)sprite).slam(enemy.pos);
return false;
} else {
dropRocks(enemy);
Sample.INSTANCE.play(Assets.Sounds.ROCKS);
return true;
}
}
}
}
}
} else {
if (!chargeAnnounced){
yell(Messages.get(this, "supercharged"));
chargeAnnounced = true;
}
if (Dungeon.hero.invisible <= 0){
beckon(Dungeon.hero.pos);
state = HUNTING;
enemy = Dungeon.hero;
}
}
return super.act();
}
@Override
protected Char chooseEnemy() {
Char enemy = super.chooseEnemy();
if (supercharged && enemy == null){
enemy = Dungeon.hero;
}
return enemy;
}
@Override
public void move(int step, boolean travelling) {
super.move(step, travelling);
if (travelling) Camera.main.shake( supercharged ? 3 : 1, 0.25f );
if (Dungeon.level.map[step] == Terrain.INACTIVE_TRAP && state == HUNTING) {
//don't gain energy from cells that are energized
if (CavesBossLevel.PylonEnergy.volumeAt(pos, CavesBossLevel.PylonEnergy.class) > 0){
return;
}
if (Dungeon.level.heroFOV[step]) {
if (buff(Barrier.class) == null) {
GLog.w(Messages.get(this, "shield"));
}
Sample.INSTANCE.play(Assets.Sounds.LIGHTNING);
sprite.emitter().start(SparkParticle.STATIC, 0.05f, 20);
}
Buff.affect(this, Barrier.class).setShield( 30 + (HT - HP)/10);
}
}
@Override
public float speed() {
return super.speed() * (supercharged ? 2 : 1);
}
@Override
public void notice() {
super.notice();
if (!BossHealthBar.isAssigned()) {
BossHealthBar.assignBoss(this);
turnsSinceLastAbility = 0;
yell(Messages.get(this, "notice"));
for (Char ch : Actor.chars()){
if (ch instanceof DriedRose.GhostHero){
((DriedRose.GhostHero) ch).sayBoss();
}
}
}
}
public void onZapComplete(){
ventGas(enemy);
next();
}
public void ventGas( Char target ){
Dungeon.hero.interrupt();
int gasVented = 0;
Ballistica trajectory = new Ballistica(pos, target.pos, Ballistica.STOP_TARGET);
int gasMulti = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2 : 1;
for (int i : trajectory.subPath(0, trajectory.dist)){
GameScene.add(Blob.seed(i, 20*gasMulti, ToxicGas.class));
gasVented += 20*gasMulti;
}
GameScene.add(Blob.seed(trajectory.collisionPos, 100*gasMulti, ToxicGas.class));
if (gasVented < 250*gasMulti){
int toVentAround = (int)Math.ceil(((250*gasMulti) - gasVented)/8f);
for (int i : PathFinder.NEIGHBOURS8){
GameScene.add(Blob.seed(pos+i, toVentAround, ToxicGas.class));
}
}
}
public void onSlamComplete(){
dropRocks(enemy);
next();
}
public void dropRocks( Char target ) {
Dungeon.hero.interrupt();
final int rockCenter;
if (Dungeon.level.adjacent(pos, target.pos)){
int oppositeAdjacent = target.pos + (target.pos - pos);
Ballistica trajectory = new Ballistica(target.pos, oppositeAdjacent, Ballistica.MAGIC_BOLT);
WandOfBlastWave.throwChar(target, trajectory, 2, false, false);
if (target == Dungeon.hero){
Dungeon.hero.interrupt();
}
rockCenter = trajectory.path.get(Math.min(trajectory.dist, 2));
} else {
rockCenter = target.pos;
}
int safeCell;
do {
safeCell = rockCenter + PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (safeCell == pos
|| (Dungeon.level.solid[safeCell] && Random.Int(2) == 0)
|| (Blob.volumeAt(safeCell, CavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0));
ArrayList<Integer> rockCells = new ArrayList<>();
int start = rockCenter - Dungeon.level.width() * 3 - 3;
int pos;
for (int y = 0; y < 7; y++) {
pos = start + Dungeon.level.width() * y;
for (int x = 0; x < 7; x++) {
if (!Dungeon.level.insideMap(pos)) {
pos++;
continue;
}
//add rock cell to pos, if it is not solid, and isn't the safecell
if (!Dungeon.level.solid[pos] && pos != safeCell && Random.Int(Dungeon.level.distance(rockCenter, pos)) == 0) {
//don't want to overly punish players with slow move or attack speed
rockCells.add(pos);
}
pos++;
}
}
Buff.append(this, FallingRockBuff.class, Math.min(target.cooldown(), 3*TICK)).setRockPositions(rockCells);
}
private boolean invulnWarned = false;
@Override
public void damage(int dmg, Object src) {
int preHP = HP;
super.damage(dmg, src);
if (isInvulnerable(src.getClass())){
return;
}
int dmgTaken = preHP - HP;
if (dmgTaken > 0) {
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
if (lock != null && !isImmune(src.getClass())) lock.addTime(dmgTaken*1.5f);
}
int threshold;
if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){
threshold = HT / 4 * (3 - pylonsActivated);
} else {
threshold = HT / 3 * (2 - pylonsActivated);
}
if (HP < threshold){
HP = threshold;
supercharge();
}
}
public int totalPylonsToActivate(){
return Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 3 : 2;
}
@Override
public boolean isInvulnerable(Class effect) {
if (supercharged && !invulnWarned){
invulnWarned = true;
GLog.w(Messages.get(this, "charging_hint"));
}
return supercharged;
}
public void supercharge(){
supercharged = true;
((CavesBossLevel)Dungeon.level).activatePylon();
pylonsActivated++;
spend(Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2f : 3f);
yell(Messages.get(this, "charging"));
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
((DM300Sprite)sprite).updateChargeState(true);
((DM300Sprite)sprite).charge();
chargeAnnounced = false;
}
public boolean isSupercharged(){
return supercharged;
}
public void loseSupercharge(){
supercharged = false;
((DM300Sprite)sprite).updateChargeState(false);
if (pylonsActivated < totalPylonsToActivate()){
yell(Messages.get(this, "charge_lost"));
} else {
yell(Messages.get(this, "pylons_destroyed"));
BossHealthBar.bleed(true);
}
}
@Override
public boolean isAlive() {
return super.isAlive() || pylonsActivated < totalPylonsToActivate();
}
@Override
public void die( Object cause ) {
super.die( cause );
GameScene.bossSlain();
Dungeon.level.unseal();
//60% chance of 2 shards, 30% chance of 3, 10% chance for 4. Average of 2.5
int shards = Random.chances(new float[]{0, 0, 6, 3, 1});
for (int i = 0; i < shards; i++){
int ofs;
do {
ofs = PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (!Dungeon.level.passable[pos + ofs]);
Dungeon.level.drop( new MetalShard(), pos + ofs ).sprite.drop( pos );
}
Badges.validateBossSlain();
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
if (beacon != null) {
beacon.upgrade();
}
yell( Messages.get(this, "defeated") );
}
@Override
protected boolean getCloser(int target) {
if (super.getCloser(target)){
return true;
} else {
if (!supercharged || state != HUNTING || rooted || target == pos || Dungeon.level.adjacent(pos, target)) {
return false;
}
int bestpos = pos;
for (int i : PathFinder.NEIGHBOURS8){
if (Actor.findChar(pos+i) == null &&
Dungeon.level.trueDistance(bestpos, target) > Dungeon.level.trueDistance(pos+i, target)){
bestpos = pos+i;
}
}
if (bestpos != pos){
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
Rect gate = CavesBossLevel.gate;
for (int i : PathFinder.NEIGHBOURS9){
if (Dungeon.level.map[pos+i] == Terrain.WALL || Dungeon.level.map[pos+i] == Terrain.WALL_DECO){
Point p = Dungeon.level.cellToPoint(pos+i);
if (p.y < gate.bottom && p.x > gate.left-2 && p.x < gate.right+2){
continue; //don't break the gate or walls around the gate
}
Level.set(pos+i, Terrain.EMPTY_DECO);
GameScene.updateMap(pos+i);
}
}
Dungeon.level.cleanWalls();
Dungeon.observe();
spend(Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2f : 3f);
bestpos = pos;
for (int i : PathFinder.NEIGHBOURS8){
if (Actor.findChar(pos+i) == null && Dungeon.level.openSpace[pos+i] &&
Dungeon.level.trueDistance(bestpos, target) > Dungeon.level.trueDistance(pos+i, target)){
bestpos = pos+i;
}
}
if (bestpos != pos) {
move(bestpos);
}
Camera.main.shake( 5, 1f );
return true;
}
return false;
}
}
@Override
public String description() {
String desc = super.description();
if (supercharged) {
desc += "\n\n" + Messages.get(this, "desc_supercharged");
}
return desc;
}
{
immunities.add(Sleep.class);
resistances.add(Terror.class);
resistances.add(Charm.class);
resistances.add(Vertigo.class);
resistances.add(Cripple.class);
resistances.add(Chill.class);
resistances.add(Frost.class);
resistances.add(Roots.class);
resistances.add(Slow.class);
}
public static class FallingRockBuff extends FlavourBuff {
private int[] rockPositions;
private ArrayList<Emitter> rockEmitters = new ArrayList<>();
public void setRockPositions( List<Integer> rockPositions ) {
this.rockPositions = new int[rockPositions.size()];
for (int i = 0; i < rockPositions.size(); i++){
this.rockPositions[i] = rockPositions.get(i);
}
fx(true);
}
@Override
public boolean act() {
for (int i : rockPositions){
CellEmitter.get( i ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 );
Char ch = Actor.findChar(i);
if (ch != null && !(ch instanceof DM300)){
Buff.prolong( ch, Paralysis.class, Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 5 : 3 );
}
}
Camera.main.shake( 3, 0.7f );
Sample.INSTANCE.play(Assets.Sounds.ROCKS);
detach();
return super.act();
}
@Override
public void fx(boolean on) {
if (on && rockPositions != null){
for (int i : this.rockPositions){
Emitter e = CellEmitter.get(i);
e.y -= DungeonTilemap.SIZE*0.2f;
e.height *= 0.4f;
e.pour(EarthParticle.FALLING, 0.1f);
rockEmitters.add(e);
}
} else {
for (Emitter e : rockEmitters){
e.on = false;
}
}
}
private static final String POSITIONS = "positions";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(POSITIONS, rockPositions);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
rockPositions = bundle.getIntArray(POSITIONS);
}
}
}

View File

@ -182,12 +182,12 @@ public abstract class Mob extends Char {
alerted = false;
if (Dungeon.isChallenged(Challenges.SBSG) && scaleFactor == 1f && !properties().contains(Property.NOBIG)&&!properties().contains(Property.BOSS)){
scaleFactor = Random.Float(1f, 1.8f);
scaleFactor = Random.Float(0.5f, 1.4f);
HP = HT = (int) (HT * scaleFactor);
if (scaleFactor >= 1.15f){
HP = HT = (int) (HT * 1.15f);
}else if (scaleFactor >= 1.4f) {
HP = HT = (int) (HT * 1.4f);
}else if (scaleFactor >= 0.8f) {
HP = HT = (int) (HT * 0.8f);
}
sprite.linkVisuals(this);
sprite.link(this);

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2021 Evan Debenham
* 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
@ -21,10 +21,9 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@ -49,10 +48,11 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.EarthParticle;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.MetalShard;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
@ -64,7 +64,6 @@ import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Camera;
import com.watabou.noosa.audio.Music;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.particles.Emitter;
import com.watabou.utils.Bundle;
@ -81,7 +80,7 @@ public class NewDM300 extends Mob {
{
spriteClass = DM300Sprite.class;
HP = HT = 300;
HP = HT = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 400 : 300;
EXP = 30;
defenseSkill = 15;
@ -109,12 +108,12 @@ public class NewDM300 extends Mob {
public boolean supercharged = false;
public boolean chargeAnnounced = false;
private final int MIN_COOLDOWN = 5;
private final int MAX_COOLDOWN = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 7 : 9;
private int turnsSinceLastAbility = -1;
private int abilityCooldown = Random.NormalIntRange(MIN_COOLDOWN, MAX_COOLDOWN);
private static final int MIN_COOLDOWN = 5;
private static final int MAX_COOLDOWN = 9;
private int lastAbility = 0;
private static final int NONE = 0;
private static final int GAS = 1;
@ -152,7 +151,7 @@ public class NewDM300 extends Mob {
if (turnsSinceLastAbility != -1){
BossHealthBar.assignBoss(this);
if (!supercharged && pylonsActivated == 4) BossHealthBar.bleed(true);
if (!supercharged && pylonsActivated == totalPylonsToActivate()) BossHealthBar.bleed(true);
}
}
@ -176,10 +175,10 @@ public class NewDM300 extends Mob {
//determine if DM can reach its enemy
boolean canReach;
if (enemy == null){
if (Dungeon.level.adjacent(pos, hero.pos)){
if (Dungeon.level.adjacent(pos, Dungeon.hero.pos)){
canReach = true;
} else {
canReach = (Dungeon.findStep(this, hero.pos, Dungeon.level.openSpace, fieldOfView, true) != -1);
canReach = (Dungeon.findStep(this, Dungeon.hero.pos, Dungeon.level.openSpace, fieldOfView, true) != -1);
}
} else {
if (Dungeon.level.adjacent(pos, enemy.pos)){
@ -190,12 +189,12 @@ public class NewDM300 extends Mob {
}
if (state != HUNTING){
if (hero.invisible <= 0 && canReach){
beckon(hero.pos);
if (Dungeon.hero.invisible <= 0 && canReach){
beckon(Dungeon.hero.pos);
}
} else {
if (enemy == null && hero.invisible <= 0) enemy = hero;
if (enemy == null && Dungeon.hero.invisible <= 0) enemy = Dungeon.hero;
//more aggressive ability usage when DM can't reach its target
if (enemy != null && !canReach){
@ -203,7 +202,7 @@ public class NewDM300 extends Mob {
//try to fire gas at an enemy we can't reach
if (turnsSinceLastAbility >= MIN_COOLDOWN){
//use a coneAOE to try and account for trickshotting angles
ConeAOE aim = new ConeAOE(new Ballistica(pos, enemy.pos, Ballistica.PROJECTILE), 30);
ConeAOE aim = new ConeAOE(new Ballistica(pos, enemy.pos, Ballistica.WONT_STOP), Float.POSITIVE_INFINITY, 30, Ballistica.STOP_SOLID);
if (aim.cells.contains(enemy.pos)) {
lastAbility = GAS;
turnsSinceLastAbility = 0;
@ -218,7 +217,8 @@ public class NewDM300 extends Mob {
return true;
}
//if we can't gas, then drop rocks
} else {
//unless enemy is already stunned, we don't want to stunlock them
} else if (enemy.paralysed <= 0) {
lastAbility = ROCKS;
turnsSinceLastAbility = 0;
GLog.w(Messages.get(this, "rocks"));
@ -287,10 +287,10 @@ public class NewDM300 extends Mob {
chargeAnnounced = true;
}
if (hero.invisible <= 0){
beckon(hero.pos);
if (Dungeon.hero.invisible <= 0){
beckon(Dungeon.hero.pos);
state = HUNTING;
enemy = hero;
enemy = Dungeon.hero;
}
}
@ -302,21 +302,21 @@ public class NewDM300 extends Mob {
protected Char chooseEnemy() {
Char enemy = super.chooseEnemy();
if (supercharged && enemy == null){
enemy = hero;
enemy = Dungeon.hero;
}
return enemy;
}
@Override
public void move(int step) {
super.move(step);
public void move(int step, boolean travelling) {
super.move(step, travelling);
Camera.main.shake( supercharged ? 3 : 1, 0.25f );
if (travelling) Camera.main.shake( supercharged ? 3 : 1, 0.25f );
if (Dungeon.level.map[step] == Terrain.INACTIVE_TRAP && state == HUNTING) {
//don't gain energy from cells that are energized
if (NewCavesBossLevel.PylonEnergy.volumeAt(pos, NewCavesBossLevel.PylonEnergy.class) > 0){
if (CavesBossLevel.PylonEnergy.volumeAt(pos, CavesBossLevel.PylonEnergy.class) > 0){
return;
}
@ -345,7 +345,6 @@ public class NewDM300 extends Mob {
BossHealthBar.assignBoss(this);
turnsSinceLastAbility = 0;
yell(Messages.get(this, "notice"));
Music.INSTANCE.play(Assets.BGM_BOSSC, true);
for (Char ch : Actor.chars()){
if (ch instanceof DriedRose.GhostHero){
((DriedRose.GhostHero) ch).sayBoss();
@ -360,21 +359,23 @@ public class NewDM300 extends Mob {
}
public void ventGas( Char target ){
hero.interrupt();
Dungeon.hero.interrupt();
int gasVented = 0;
Ballistica trajectory = new Ballistica(pos, target.pos, Ballistica.STOP_TARGET);
int gasMulti = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2 : 1;
for (int i : trajectory.subPath(0, trajectory.dist)){
GameScene.add(Blob.seed(i, 20, ToxicGas.class));
gasVented += 20;
GameScene.add(Blob.seed(i, 20*gasMulti, ToxicGas.class));
gasVented += 20*gasMulti;
}
GameScene.add(Blob.seed(trajectory.collisionPos, 100, ToxicGas.class));
GameScene.add(Blob.seed(trajectory.collisionPos, 100*gasMulti, ToxicGas.class));
if (gasVented < 250){
int toVentAround = (int)Math.ceil((250 - gasVented)/8f);
if (gasVented < 250*gasMulti){
int toVentAround = (int)Math.ceil(((250*gasMulti) - gasVented)/8f);
for (int i : PathFinder.NEIGHBOURS8){
GameScene.add(Blob.seed(pos+i, toVentAround, ToxicGas.class));
}
@ -390,15 +391,15 @@ public class NewDM300 extends Mob {
public void dropRocks( Char target ) {
hero.interrupt();
Dungeon.hero.interrupt();
final int rockCenter;
if (Dungeon.level.adjacent(pos, target.pos)){
int oppositeAdjacent = target.pos + (target.pos - pos);
Ballistica trajectory = new Ballistica(target.pos, oppositeAdjacent, Ballistica.MAGIC_BOLT);
WandOfBlastWave.throwChar(target, trajectory, 2, false, false);
if (target == hero){
hero.interrupt();
if (target == Dungeon.hero){
Dungeon.hero.interrupt();
}
rockCenter = trajectory.path.get(Math.min(trajectory.dist, 2));
} else {
@ -410,7 +411,7 @@ public class NewDM300 extends Mob {
safeCell = rockCenter + PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (safeCell == pos
|| (Dungeon.level.solid[safeCell] && Random.Int(2) == 0)
|| (Blob.volumeAt(safeCell, NewCavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0));
|| (Blob.volumeAt(safeCell, CavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0));
ArrayList<Integer> rockCells = new ArrayList<>();
@ -447,11 +448,16 @@ public class NewDM300 extends Mob {
int dmgTaken = preHP - HP;
if (dmgTaken > 0) {
LockedFloor lock = hero.buff(LockedFloor.class);
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
if (lock != null && !isImmune(src.getClass())) lock.addTime(dmgTaken*1.5f);
}
int threshold = HT/4 * (4- pylonsActivated);
int threshold;
if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){
threshold = HT / 4 * (3 - pylonsActivated);
} else {
threshold = HT / 3 * (2 - pylonsActivated);
}
if (HP < threshold){
HP = threshold;
@ -460,6 +466,10 @@ public class NewDM300 extends Mob {
}
public int totalPylonsToActivate(){
return Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 3 : 2;
}
@Override
public boolean isInvulnerable(Class effect) {
if (supercharged && !invulnWarned){
@ -471,12 +481,11 @@ public class NewDM300 extends Mob {
public void supercharge(){
supercharged = true;
((NewCavesBossLevel)Dungeon.level).activatePylon();
((CavesBossLevel)Dungeon.level).activatePylon();
pylonsActivated++;
spend(2.5f);
spend(Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2f : 3f);
yell(Messages.get(this, "charging"));
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
((DM300Sprite)sprite).updateChargeState(true);
((DM300Sprite)sprite).charge();
@ -492,7 +501,7 @@ public class NewDM300 extends Mob {
supercharged = false;
((DM300Sprite)sprite).updateChargeState(false);
if (pylonsActivated < 4){
if (pylonsActivated < totalPylonsToActivate()){
yell(Messages.get(this, "charge_lost"));
} else {
yell(Messages.get(this, "pylons_destroyed"));
@ -502,18 +511,12 @@ public class NewDM300 extends Mob {
@Override
public boolean isAlive() {
return HP > 0 || pylonsActivated < 4;
return super.isAlive() || pylonsActivated < totalPylonsToActivate();
}
@Override
public void die( Object cause ) {
for (Mob mob : (Iterable<Mob>)Dungeon.level.mobs.clone()) {
if (mob instanceof MolotovHuntsman || mob instanceof RedSwarm||
mob instanceof DM100|| mob instanceof FireGhost||mob instanceof BlackHost||
mob instanceof GnollShiled||mob instanceof Spinner) {
mob.die( cause );
}
}
super.die( cause );
GameScene.bossSlain();
@ -531,6 +534,11 @@ public class NewDM300 extends Mob {
Badges.validateBossSlain();
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
if (beacon != null) {
beacon.upgrade();
}
yell( Messages.get(this, "defeated") );
}
@ -554,7 +562,7 @@ public class NewDM300 extends Mob {
if (bestpos != pos){
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
Rect gate = NewCavesBossLevel.gate;
Rect gate = CavesBossLevel.gate;
for (int i : PathFinder.NEIGHBOURS9){
if (Dungeon.level.map[pos+i] == Terrain.WALL || Dungeon.level.map[pos+i] == Terrain.WALL_DECO){
Point p = Dungeon.level.cellToPoint(pos+i);
@ -567,7 +575,7 @@ public class NewDM300 extends Mob {
}
Dungeon.level.cleanWalls();
Dungeon.observe();
spend(3f);
spend(Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2f : 3f);
bestpos = pos;
for (int i : PathFinder.NEIGHBOURS8){
@ -632,12 +640,10 @@ public class NewDM300 extends Mob {
Char ch = Actor.findChar(i);
if (ch != null && !(ch instanceof NewDM300)){
Buff.prolong( ch, Paralysis.class, 3 );
Buff.prolong( ch, Paralysis.class, Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 5 : 3 );
}
}
Camera.main.shake( 3, 0.7f );
Sample.INSTANCE.play(Assets.Sounds.ROCKS);

View File

@ -27,7 +27,6 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Dread;
@ -38,7 +37,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
@ -120,12 +118,12 @@ public class Pylon extends Mob {
}
private void shockChar( Char ch ){
if (ch != null && !(ch instanceof DM300)){
if (ch != null && !(ch instanceof NewDM300)){
ch.sprite.flash();
ch.damage(Random.NormalIntRange(10, 20), new Electricity());
if (ch == Dungeon.hero && !ch.isAlive()){
Dungeon.fail(DM300.class);
Dungeon.fail(NewDM300.class);
GLog.n( Messages.get(Electricity.class, "ondeath") );
}
}

View File

@ -25,8 +25,6 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
import com.shatteredpixel.shatteredpixeldungeon.items.LostBackpack;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.WraithSprite;
import com.watabou.noosa.tweeners.AlphaTweener;
@ -44,7 +42,7 @@ public class Wraith extends Mob {
{
spriteClass = WraithSprite.class;
HP = HT = 20;
HP = HT = 1;
EXP = 0;
maxLvl = -2;
@ -58,10 +56,10 @@ public class Wraith extends Mob {
public void die( Object cause ) {
super.die( cause );
if (gold > 0) {
Dungeon.level.drop( new Gold(gold), pos ).sprite.drop();
Dungeon.level.drop( new LostBackpack(), pos).sprite.drop( pos );
}
//if (gold > 0) {
// Dungeon.level.drop( new Gold(gold), pos ).sprite.drop();
// Dungeon.level.drop( new LostBackpack(), pos).sprite.drop( pos );
//}
}

View File

@ -21,7 +21,10 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import static com.shatteredpixel.shatteredpixeldungeon.Challenges.RLPT;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
@ -460,6 +463,10 @@ public class YogDzewa extends Mob {
}
}
if(Dungeon.isChallenged(RLPT)){
Badges.GOODRLPT();
}
updateVisibility(Dungeon.level);
GameScene.bossSlain();

View File

@ -145,7 +145,7 @@ public class LevelTeleporter extends TestItem {
float xpos = (WIDTH - 5*BTN_SIZE - GAP*8)/2f;
float ypos = 0;
float each = GAP*2 + BTN_SIZE;
for(int i=0; i< Constants.MAX_DEPTH; ++i){
for(int i=-1; i< Constants.MAX_DEPTH; ++i){
int column = i % 5;
int row = i / 5;
final int j = i+1;

View File

@ -20,7 +20,7 @@ public class Constants {
//############################## UI STUFF ##############################
//
public static final int MAX_QUICKSLOTS = 9;
public static final int MAX_QUICKSLOTS = 12;
public static final int MIN_QUICKSLOTS = 3;
public static boolean gameIsAndroid(){

View File

@ -352,7 +352,7 @@ public class Generator {
MagesStaff.class,
BlackDog.class,
};
WEP_T1.probs = new float[]{ 1, 1, 1, 0, 4 };
WEP_T1.probs = new float[]{ 1, 1, 1, 0, 0 };
WEP_T2.classes = new Class<?>[]{
Shortsword.class,

View File

@ -22,13 +22,14 @@
package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.AlchemistsToolkit;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
import com.shatteredpixel.shatteredpixeldungeon.items.food.LightFood;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MeatPie;
import com.shatteredpixel.shatteredpixeldungeon.items.food.StewedMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.AlchemicalCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfNoWater;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.brews.BlizzardBrew;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.brews.CausticBrew;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.brews.InfernalBrew;
@ -42,7 +43,9 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMi
import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfToxicEssence;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.ExoticPotion;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfFlameCursed;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ExoticScroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfRoseShiled;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.Alchemize;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.AquaBlast;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.ArcaneCatalyst;
@ -58,6 +61,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.spells.SummonElemental;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.TelekineticGrab;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.WildEnergy;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlueFuck;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.IceFishSword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.watabou.utils.Reflection;
@ -208,13 +213,20 @@ public abstract class Recipe {
new WildEnergy.Recipe(),
new TelekineticGrab.Recipe(),
new SummonElemental.Recipe(),
new StewedMeat.twoMeat()
new StewedMeat.twoMeat(),
new PotionOfNoWater.Recipe(),
};
private static Recipe[] threeIngredientRecipes = new Recipe[]{
new Potion.SeedToPotion(),
new StewedMeat.threeMeat(),
new MeatPie.Recipe()
new MeatPie.Recipe(),
new ScrollOfRoseShiled.Recipe(),
new WandOfBlueFuck.Recipe(),
new IceFishSword.Recipe(),
new LightFood.Recipe(),
new ScrollOfFlameCursed.Recipe(),
};
public static ArrayList<Recipe> findRecipes(ArrayList<Item> ingredients){

View File

@ -46,7 +46,7 @@ public class MagicalHolster extends Bag {
}
public int capacity(){
return 19;
return 34; // default container size
}
@Override

View File

@ -42,7 +42,7 @@ public class PotionBandolier extends Bag {
}
public int capacity(){
return 19;
return 35; // default container size
}
@Override

View File

@ -43,7 +43,7 @@ public class ScrollHolder extends Bag {
}
public int capacity(){
return 19;
return 36; // default container size
}
@Override

View File

@ -45,7 +45,7 @@ public class VelvetPouch extends Bag {
}
public int capacity(){
return 19;
return 40; // default container size
}
@Override

View File

@ -111,7 +111,7 @@ public class Potion extends Item {
mustThrowPots.add(PotionOfLiquidFlame.class);
mustThrowPots.add(PotionOfParalyticGas.class);
mustThrowPots.add(PotionOfFrost.class);
mustThrowPots.add(PotionOfLiquidFlameX.class);
//exotic
mustThrowPots.add(PotionOfCorrosiveGas.class);
mustThrowPots.add(PotionOfSnapFreeze.class);

View File

@ -24,15 +24,21 @@ package com.shatteredpixel.shatteredpixeldungeon.items.scrolls;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bleeding;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
public class ScrollOfFlameCursed extends Scroll {
@ -41,6 +47,32 @@ public class ScrollOfFlameCursed extends Scroll {
unique = true;
}
public void bolt(Integer target, final Mob mob){
if (target != null) {
final Ballistica shot = new Ballistica( Dungeon.hero.pos, target, Ballistica.PROJECTILE);
fx(shot, () -> onHit(shot, mob));
}
}
protected void fx(Ballistica bolt, Callback callback) {
MagicMissile.boltFromChar( Dungeon.hero.sprite.emitter(), MagicMissile.WARD, Dungeon.hero.sprite,
bolt.collisionPos,
callback);
}
protected void onHit(Ballistica bolt, Mob mob) {
//presses all tiles in the AOE first
if (mob != null){
if (mob.isAlive() && bolt.path.size() > bolt.dist+1) {
Buff.prolong(mob, Chill.class, Chill.DURATION/3f);
Buff.affect(mob, Bleeding.class).set((float) (10));
}
}
}
@Override
public void doRead() {
@ -53,7 +85,7 @@ public class ScrollOfFlameCursed extends Scroll {
for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) {
if (mob.alignment != Char.Alignment.ALLY && Dungeon.level.heroFOV[mob.pos]) {
Buff.affect( mob, Burning.class ).reignite( mob, 7f );
bolt(mob.pos, mob);
if (mob.buff(Burning.class) != null){
count++;
affected = mob;
@ -78,22 +110,23 @@ public class ScrollOfFlameCursed extends Scroll {
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
{
inputs = new Class[]{PotionOfLiquidFlame.class, ScrollOfTerror.class};
inQuantity = new int[]{1, 1};
inputs = new Class[]{PotionOfLiquidFlame.class, ScrollOfTerror.class, PotionOfFrost.class};
inQuantity = new int[]{1, 1, 1};
cost = 7;
cost = 24;
output = ScrollOfFlameCursed.class;
outQuantity = 2;
outQuantity = 3;
}
}
@Override
public boolean isIdentified() {
return true;
return isKnown();
}
@Override
public int value() {
return isKnown() ? 40 * quantity : super.value();

View File

@ -36,7 +36,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportat
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTerror;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
import com.watabou.utils.Reflection;
import java.util.ArrayList;
@ -113,54 +112,43 @@ public abstract class ExoticScroll extends Scroll {
@Override
//20 gold more than its none-exotic equivalent
public int value() {
return (Reflection.newInstance(exoToReg.get(getClass())).value() + 20) * quantity;
return (Reflection.newInstance(exoToReg.get(getClass())).value() + 30) * quantity;
}
@Override
//6 more energy than its none-exotic equivalent
public int energyVal() {
return (Reflection.newInstance(exoToReg.get(getClass())).energyVal() + 6) * quantity;
}
public static class ScrollToExotic extends Recipe {
@Override
public boolean testIngredients(ArrayList<Item> ingredients) {
int r = 0;
Scroll s = null;
for (Item i : ingredients){
if (i instanceof Runestone){
r++;
} else if (regToExo.containsKey(i.getClass())) {
s = (Scroll)i;
}
if (ingredients.size() == 1 && regToExo.containsKey(ingredients.get(0).getClass())){
return true;
}
return s != null && r == 2;
return false;
}
@Override
public int cost(ArrayList<Item> ingredients) {
return 0;
return 6;
}
@Override
public Item brew(ArrayList<Item> ingredients) {
Item result = null;
for (Item i : ingredients){
i.quantity(i.quantity()-1);
if (regToExo.containsKey(i.getClass())) {
result = Reflection.newInstance(regToExo.get(i.getClass()));
}
}
return result;
return Reflection.newInstance(regToExo.get(ingredients.get(0).getClass()));
}
@Override
public Item sampleOutput(ArrayList<Item> ingredients) {
for (Item i : ingredients){
if (regToExo.containsKey(i.getClass())) {
return Reflection.newInstance(regToExo.get(i.getClass()));
}
}
return null;
return Reflection.newInstance(regToExo.get(ingredients.get(0).getClass()));
}
}
}
}

View File

@ -45,10 +45,10 @@ public class ScrollOfRoseShiled extends Scroll {
inputs = new Class[]{PotionOfPurity.class, AlchemicalCatalyst.class, StoneOfBlink.class};
inQuantity = new int[]{1, 1, 1};
cost = 9;
cost = 20;
output = ScrollOfRoseShiled.class;
outQuantity = 2;
outQuantity = 3;
}
}

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,24 +21,60 @@
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Degrade;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.utils.Random;
public class Gauntlet extends MeleeWeapon {
{
image = ItemSpriteSheet.GAUNTLETS;
hitSound = Assets.Sounds.HIT_CRUSH;
hitSoundPitch = 1.2f;
tier = 5;
DLY = 0.5f; //2x speed
DLY = 0.25f; //2x speed
}
@Override
public int defenseFactor( Char owner ) {
return 6+3*buffedLvl(); //6 extra defence, plus 3 per level;
}
@Override
public int max(int lvl) {
return Math.round(2.5f*(tier+1)) + //15 base, down from 30
lvl*Math.round(0.5f*(tier+1)); //+3 per level, down from +6
}
@Override
public int proc(Char attacker, Char defender, int damage ) {
switch (Random.Int(2)) {
case 0:
default:
return max(buffedLvl());
case 1:
Buff.affect(defender, Burning.class).reignite(defender);
Buff.affect(hero, Cripple.class, Degrade.ADURATION);
return super.proc(attacker, defender, damage);
}
}
public String statsInfo(){
if (isIdentified()){
return Messages.get(this, "stats_desc", 1+1*buffedLvl());
} else {
return Messages.get(this, "typical_stats_desc", 1);
}
}
}

View File

@ -9,6 +9,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.food.FrozenCarpaccio;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.AlchemicalCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.MagicalInfusion;
@ -30,13 +31,18 @@ public class IceFishSword extends Weapon {
DLY = 0.7f; //2x speed
}
@Override
public Item upgrade() {
return upgrade(false);
}
public static class Recipe extends com.shatteredpixel.shatteredpixeldungeon.items.Recipe.SimpleRecipe {
{
inputs = new Class[]{FrozenCarpaccio.class, MagicalInfusion.class, AlchemicalCatalyst.class};
inQuantity = new int[]{1, 1, 1};
cost = 9+Dungeon.depth/2;
cost = 20+Dungeon.depth/2;
output = IceFishSword.class;
outQuantity = 1;

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,20 +21,58 @@
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
import static com.shatteredpixel.shatteredpixeldungeon.Dungeon.hero;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Random;
public class Sai extends MeleeWeapon {
public int R;
{
image = ItemSpriteSheet.SAI;
hitSound = Assets.Sounds.HIT_STAB;
hitSoundPitch = 1.3f;
tier = 3;
tier = 4;
DLY = 0.5f; //2x speed
}
@Override
public ItemSprite.Glowing glowing() {
return new ItemSprite.Glowing(0x880000, 6f);
}
public String statsInfo(){
return ("持有这个武器,你在迅猛一击的时候可以吸血!你上次吸血的结果为"+"_"+R+"_"+"");
}
@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 Random.NormalIntRange( 5, 12 );
case 5:case 6:case 7:
//角色最大血量*0.01+武器等级*0.5+0.8
if(hero.HP >= hero.HT){
GLog.p("血量已满!无法回血");
} else {
R = (int) (hero.HT * 0.01 + (buffedLvl() * 0.5) + 0.8);
hero.HP += (int) hero.HT * 0.01 + (buffedLvl()) + 0.8;
hero.sprite.showStatus(CharSprite.POSITIVE, ("+" + R + "HP"));
GLog.p("迅猛一击,回血成功!");
}
return super.proc(attacker, defender, damage);
}
}
@Override
public int max(int lvl) {
return Math.round(2.5f*(tier+1)) + //10 base, down from 20

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,7 +22,14 @@
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Degrade;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vulnerable;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.utils.Random;
public class WarHammer extends MeleeWeapon {
@ -32,7 +39,8 @@ public class WarHammer extends MeleeWeapon {
hitSoundPitch = 1f;
tier = 5;
ACC = 1.20f; //20% boost to accuracy
ACC = 1.90f; //20% boost to accuracy
DLY = 1.50f; //2x speed
}
@Override
@ -41,4 +49,18 @@ public class WarHammer extends MeleeWeapon {
lvl*(tier+1); //scaling unchanged
}
@Override
public int proc(Char attacker, Char defender, int damage ) {
switch (Random.Int(2)) {
case 0:
default:
return max(buffedLvl());
case 1:
Buff.prolong(defender, Vertigo.class, 6f);
Buff.prolong(defender, Terror.class, 18f);
Buff.affect(attacker, Vulnerable.class, Degrade.ADURATION);
return super.proc(attacker, defender, damage);
}
}
}

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,7 +22,11 @@
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.utils.Random;
public class Whip extends MeleeWeapon {
@ -41,4 +45,16 @@ public class Whip extends MeleeWeapon {
lvl*(tier); //+3 per level, down from +4
}
@Override
public int proc(Char attacker, Char defender, int damage ) {
switch (Random.Int(2)) {
case 0:
default:
return Random.NormalIntRange( 1, 6 );
case 1:
Buff.prolong(defender, Chill.class, Chill.DURATION);
return super.proc(attacker, defender, damage);
}
}
}

View File

@ -43,13 +43,25 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.SandalsOfNature;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.UnstableSpellbook;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.BrokenBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.DeepBloodBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.GrassKingBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.IceCityBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.MagicGirlBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.NoKingMobBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.bookslist.YellowSunBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.playbookslist.DeYiZiBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.playbookslist.MoneyMoreBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.books.playbookslist.PinkRandomBooks;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHaste;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfInvisibility;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLevitation;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLightningShiledX;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlameX;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMindVision;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfParalyticGas;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity;
@ -93,9 +105,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfTransfusion;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.AssassinsBlade;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BattleAxe;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.BlackDog;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Crossbow;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Dagger;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Dairikyan;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Dirk;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.FireFishSword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Flail;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Gauntlet;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Glaive;
@ -103,11 +118,15 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Gloves;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greataxe;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatshield;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Greatsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.GreenSword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.HandAxe;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.IceFishSword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.LockSword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Longsword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Mace;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Quarterstaff;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.RedBloodMoon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.RoundShield;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.RunicBlade;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Sai;
@ -134,7 +153,9 @@ public enum Catalog {
RINGS,
ARTIFACTS,
POTIONS,
SCROLLS;
SCROLLS,
BOOKS,
PLAYBOOKS;
private LinkedHashMap<Class<? extends Item>, Boolean> seen = new LinkedHashMap<>();
@ -179,6 +200,13 @@ public enum Catalog {
WEAPONS.seen.put( Greataxe.class, false);
WEAPONS.seen.put( Greatshield.class, false);
WEAPONS.seen.put( Gauntlet.class, false);
WEAPONS.seen.put( GreenSword.class, false);
WEAPONS.seen.put( LockSword.class, false);
WEAPONS.seen.put( RedBloodMoon.class, false);
WEAPONS.seen.put( Dairikyan.class, false);
WEAPONS.seen.put( BlackDog.class, false);
WEAPONS.seen.put( IceFishSword.class, false);
WEAPONS.seen.put( FireFishSword.class, false);
ARMOR.seen.put( ClothArmor.class, false);
ARMOR.seen.put( LeatherArmor.class, false);
@ -229,7 +257,7 @@ public enum Catalog {
ARTIFACTS.seen.put( TalismanOfForesight.class, false);
ARTIFACTS.seen.put( TimekeepersHourglass.class, false);
ARTIFACTS.seen.put( UnstableSpellbook.class, false);
POTIONS.seen.put( PotionOfHealing.class, false);
POTIONS.seen.put( PotionOfStrength.class, false);
POTIONS.seen.put( PotionOfLiquidFlame.class, false);
@ -242,6 +270,8 @@ public enum Catalog {
POTIONS.seen.put( PotionOfInvisibility.class, false);
POTIONS.seen.put( PotionOfExperience.class, false);
POTIONS.seen.put( PotionOfHaste.class, false);
POTIONS.seen.put( PotionOfLiquidFlameX.class, false);
POTIONS.seen.put( PotionOfLightningShiledX.class, false);
SCROLLS.seen.put( ScrollOfIdentify.class, false);
SCROLLS.seen.put( ScrollOfUpgrade.class, false);
@ -255,6 +285,18 @@ public enum Catalog {
SCROLLS.seen.put( ScrollOfRage.class, false);
SCROLLS.seen.put( ScrollOfRetribution.class, false);
SCROLLS.seen.put( ScrollOfTransmutation.class, false);
BOOKS.seen.put( IceCityBooks.class, false);
BOOKS.seen.put( DeepBloodBooks.class, false);
BOOKS.seen.put( GrassKingBooks.class, false);
BOOKS.seen.put( YellowSunBooks.class, false);
BOOKS.seen.put( MagicGirlBooks.class, false);
BOOKS.seen.put( NoKingMobBooks.class, false);
BOOKS.seen.put( BrokenBooks.class, false);
PLAYBOOKS.seen.put( MoneyMoreBooks.class, true);
PLAYBOOKS.seen.put( PinkRandomBooks.class, true);
PLAYBOOKS.seen.put( DeYiZiBooks.class, true);
}
public static LinkedHashMap<Catalog, Badges.Badge> catalogBadges = new LinkedHashMap<>();

View File

@ -30,7 +30,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Pylon;
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
@ -277,7 +277,7 @@ public class CavesBossLevel extends Level {
Camera.main.shake( 3, 0.7f );
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
DM300 boss = new DM300();
NewDM300 boss = new NewDM300();
boss.state = boss.WANDERING;
do {
boss.pos = pointToCell(Random.element(mainArena.getPoints()));
@ -355,8 +355,8 @@ public class CavesBossLevel extends Level {
if (customArenaVisuals != null) customArenaVisuals.updateState();
int pylonsRemaining = 0;
for (Mob m : mobs){
if (m instanceof DM300){
((DM300) m).loseSupercharge();
if (m instanceof NewDM300){
((NewDM300) m).loseSupercharge();
PylonEnergy.energySourceSprite = m.sprite;
} else if (m instanceof Pylon){
pylonsRemaining++;
@ -789,13 +789,13 @@ public class CavesBossLevel extends Level {
if (off[cell] > 0){
Char ch = Actor.findChar(cell);
if (ch != null && !(ch instanceof DM300)) {
if (ch != null && !(ch instanceof NewDM300)) {
Sample.INSTANCE.play( Assets.Sounds.LIGHTNING );
ch.damage( Random.NormalIntRange(6, 12), Electricity.class);
ch.sprite.flash();
if (ch == Dungeon.hero && !ch.isAlive()) {
Dungeon.fail(DM300.class);
Dungeon.fail(NewDM300.class);
GLog.n( Messages.get(Electricity.class, "ondeath") );
}
}
@ -820,7 +820,7 @@ public class CavesBossLevel extends Level {
if (c instanceof Pylon && c.alignment != Char.Alignment.NEUTRAL){
energySourceSprite = c.sprite;
break;
} else if (c instanceof DM300){
} else if (c instanceof NewDM300){
energySourceSprite = c.sprite;
}
}

View File

@ -70,7 +70,7 @@ public class NewCavesBossLevel extends Level {
@Override
public String tilesTex() {
return Assets.Environment.TILES_CAVES;
return Assets.Environment.TILES_COLD;
}
@Override

View File

@ -161,7 +161,7 @@ public class ZeroLevel extends Level {
if ( !Badges.isUnlocked(Badges.Badge.NYZ_SHOP)){
if (Badges.isUnlocked(Badges.Badge.NYZ_SHOP)){
Nyz npc4= new Nyz();
npc4.pos = (this.width * 28 + 7);
mobs.add(npc4);

View File

@ -115,7 +115,7 @@ public class PixelScene extends Scene {
defaultZoom = SPDSettings.scale();
if (defaultZoom < Math.ceil( Game.density * 2 ) || defaultZoom > maxDefaultZoom){
defaultZoom = (int)GameMath.gate(2, (int)Math.ceil( Game.density * scaleFactor ), maxDefaultZoom);
defaultZoom = (int)GameMath.gate(2, (int)Math.ceil( Game.density * 2.5 ), maxDefaultZoom);
if (SPDSettings.interfaceSize() > 0 && defaultZoom < (maxDefaultZoom+1)/2){
defaultZoom = (maxDefaultZoom+1)/2;

View File

@ -12,10 +12,10 @@ import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.services.news.News;
import com.shatteredpixel.shatteredpixeldungeon.services.updates.AvailableUpdateData;
import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates;
import com.shatteredpixel.shatteredpixeldungeon.sprites.FireMagicGirlSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.DiedMonkLoaderSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.sprites.RedNecromancerSprite_EX;
import com.shatteredpixel.shatteredpixeldungeon.sprites.SlimePrincessSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.Archs;
import com.shatteredpixel.shatteredpixeldungeon.ui.EndButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
@ -284,13 +284,13 @@ public class TitleScene extends PixelScene {
}
private void placeTorch2( float x, float y ) {
Image fb = (new RedNecromancerSprite_EX());
Image fb = (new SlimePrincessSprite());
fb.setPos( x, y );
add( fb );
}
private void placeTorch3( float x, float y ) {
Image fb = (new FireMagicGirlSprite());
Image fb = (new DiedMonkLoaderSprite());
fb.setPos( x, y );
add( fb );
}

View File

@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
@ -94,7 +94,7 @@ public class DM300Sprite extends MobSprite {
new Callback() {
@Override
public void call() {
((DM300)ch).onZapComplete();
((NewDM300)ch).onZapComplete();
}
} );
Sample.INSTANCE.play( Assets.Sounds.GAS );
@ -119,7 +119,7 @@ public class DM300Sprite extends MobSprite {
}
if (anim == slam){
((DM300)ch).onSlamComplete();
((NewDM300)ch).onSlamComplete();
}
super.onComplete( anim );
@ -146,7 +146,7 @@ public class DM300Sprite extends MobSprite {
superchargeSparks.pour(SparkParticle.STATIC, 0.05f);
superchargeSparks.on = false;
if (ch instanceof DM300 && ((DM300) ch).isSupercharged()){
if (ch instanceof NewDM300 && ((NewDM300) ch).isSupercharged()){
updateChargeState(true);
}
}

View File

@ -0,0 +1,4 @@
package com.shatteredpixel.shatteredpixeldungeon.text;
public class HeroStat {
}

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2021 Evan Debenham
* 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
@ -48,7 +48,7 @@ public class KeyDisplay extends Visual {
private FloatBuffer quads;
private Vertexbuffer buffer;
private SmartTexture tx = TextureCache.get(Assets.Interfaces.MENU);
private SmartTexture tx = TextureCache.get(Assets.Interfaces.MENU_BTN);
private boolean dirty = true;
private int[] keys;
@ -216,4 +216,11 @@ public class KeyDisplay extends Visual {
}
@Override
public void destroy() {
super.destroy();
if (buffer != null)
buffer.delete();
}
}

View File

@ -28,15 +28,23 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.LiquidMetal;
import com.shatteredpixel.shatteredpixeldungeon.items.Recipe;
import com.shatteredpixel.shatteredpixeldungeon.items.Stylus;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Food;
import com.shatteredpixel.shatteredpixeldungeon.items.food.FrozenCarpaccio;
import com.shatteredpixel.shatteredpixeldungeon.items.food.LightFood;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MeatPie;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Pasty;
import com.shatteredpixel.shatteredpixeldungeon.items.food.StewedMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.AlchemicalCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlameX;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfNoWater;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.brews.BlizzardBrew;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.brews.CausticBrew;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.brews.InfernalBrew;
@ -50,7 +58,10 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMi
import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfToxicEssence;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.ExoticPotion;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfFlameCursed;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTerror;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ExoticScroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfRoseShiled;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.Alchemize;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.AquaBlast;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.ArcaneCatalyst;
@ -58,7 +69,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.spells.BeaconOfReturning;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.CurseInfusion;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.FeatherFall;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.MagicalInfusion;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.MagicalPorter;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.PhaseShift;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.ReclaimTrap;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.Recycle;
@ -66,9 +76,15 @@ import com.shatteredpixel.shatteredpixeldungeon.items.spells.SummonElemental;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.TelekineticGrab;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.WildEnergy;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAugmentation;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlueFuck;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.IceFishSword;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.AikeLaier;
import com.shatteredpixel.shatteredpixeldungeon.plants.Blindweed;
import com.shatteredpixel.shatteredpixeldungeon.plants.Firebloom;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.AlchemyScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
@ -292,6 +308,17 @@ public class QuickRecipe extends Component {
result.add(new QuickRecipe( new MeatPie.Recipe(),
new ArrayList<Item>(Arrays.asList(new Pasty(), new Food(), new MysteryMeat.PlaceHolder())),
new MeatPie()));
result.add(new QuickRecipe( new LightFood.Recipe(),
new ArrayList<Item>(Arrays.asList(new AikeLaier.Seed(), new Food(),
new FrozenCarpaccio())),
new LightFood()));
result.add(new QuickRecipe( new PotionOfNoWater.Recipe(),
new ArrayList<Item>(Arrays.asList(new Blindweed.Seed(), new Firebloom.Seed())),
new PotionOfNoWater()));
result.add(new QuickRecipe( new IceFishSword.Recipe(),
new ArrayList<Item>(Arrays.asList(new FrozenCarpaccio(), new MagicalInfusion(),
new AlchemicalCatalyst())),
new IceFishSword()));
result.add(null);
result.add(new QuickRecipe( new Blandfruit.CookFruit(),
new ArrayList<>(Arrays.asList(new Blandfruit(), new Plant.Seed.PlaceHolder())),
@ -314,6 +341,18 @@ public class QuickRecipe extends Component {
ArrayList<Item> in = new ArrayList<>(Arrays.asList(pot));
result.add(new QuickRecipe( r, in, r.sampleOutput(in)));
}
result.add(new QuickRecipe( new ScrollOfFlameCursed.Recipe(),
new ArrayList<Item>(Arrays.asList(new PotionOfLiquidFlame(), new ScrollOfTerror(),
new PotionOfFrost())),
new ScrollOfFlameCursed().quantity(3)));
result.add(new QuickRecipe( new ScrollOfRoseShiled.Recipe(),
new ArrayList<Item>(Arrays.asList(new PotionOfPurity(), new AlchemicalCatalyst(),
new StoneOfAugmentation())),
new ScrollOfRoseShiled().quantity(3)));
result.add(new QuickRecipe( new WandOfBlueFuck.Recipe(),
new ArrayList<Item>(Arrays.asList(new PotionOfLiquidFlameX(), new ScrollOfFlameCursed(),
new Stylus())),
new WandOfBlueFuck()));
return result;
case 4:
r = new ExoticScroll.ScrollToExotic();

View File

@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2022 Evan Debenham
* Copyright (C) 2014-2021 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,11 +22,10 @@
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.QuickSlot;
import com.shatteredpixel.shatteredpixeldungeon.SPDAction;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LostInventory;
import com.shatteredpixel.shatteredpixeldungeon.custom.utils.Constants;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@ -34,53 +33,60 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndBag;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndKeyBindings;
import com.watabou.input.GameAction;
import com.watabou.noosa.Image;
import com.watabou.utils.PathFinder;
public class QuickSlotButton extends Button {
private static QuickSlotButton[] instance = new QuickSlotButton[QuickSlot.SIZE];
public class QuickSlotButton extends Button {
private static QuickSlotButton[] instance = new QuickSlotButton[Constants.MAX_QUICKSLOTS];
private int slotNum;
private ItemSlot slot;
private static Image crossB;
private static Image crossM;
private static boolean targeting = false;
public static Char lastTarget = null;
public QuickSlotButton( int slotNum ) {
super();
this.slotNum = slotNum;
item( select( slotNum ) );
instance[slotNum] = this;
}
public static void useTargeting(int idx){
instance[idx].useTargeting();
}
@Override
public void destroy() {
super.destroy();
reset();
}
public void slotMargins( int left, int top, int right, int bottom){
slot.setMargins(left, top, right, bottom);
}
public static void reset() {
instance = new QuickSlotButton[QuickSlot.SIZE];
instance = new QuickSlotButton[Constants.MAX_QUICKSLOTS];
lastTarget = null;
}
@Override
protected void createChildren() {
super.createChildren();
slot = new ItemSlot() {
@Override
protected void onClick() {
if (!Dungeon.hero.isAlive() || !Dungeon.hero.ready){
if (!Dungeon.hero.isAlive()){
return;
}
if (targeting) {
@ -94,21 +100,13 @@ public class QuickSlotButton extends Button {
}
} else {
Item item = select(slotNum);
if (Dungeon.hero.belongings.contains(item) && !GameScene.cancel()) {
GameScene.centerNextWndOnInvPane();
item.execute(Dungeon.hero);
if (item.usesTargeting) {
useTargeting();
}
if (item.usesTargeting) {
useTargeting();
}
item.execute( Dungeon.hero );
}
}
@Override
protected void onRightClick() {
QuickSlotButton.this.onLongClick();
}
@Override
public GameAction keyAction() {
return QuickSlotButton.this.keyAction();
@ -125,33 +123,24 @@ public class QuickSlotButton extends Button {
protected void onPointerUp() {
sprite.resetColor();
}
@Override
protected String hoverText() {
if (item == null){
return Messages.titleCase(Messages.get(WndKeyBindings.class, "quickslot_" + (slotNum+1)));
} else {
return super.hoverText();
}
}
};
slot.showExtraInfo( false );
add( slot );
crossB = Icons.TARGET.get();
crossB.visible = false;
add( crossB );
crossM = new Image();
crossM.copy( crossB );
}
@Override
protected void layout() {
super.layout();
slot.fill( this );
crossB.x = x + (width - crossB.width) / 2;
crossB.y = y + (height - crossB.height) / 2;
PixelScene.align(crossB);
@ -176,31 +165,18 @@ public class QuickSlotButton extends Button {
return SPDAction.QUICKSLOT_3;
case 3:
return SPDAction.QUICKSLOT_4;
case 4:
return SPDAction.QUICKSLOT_5;
case 5:
return SPDAction.QUICKSLOT_6;
default:
return super.keyAction();
}
}
@Override
protected String hoverText() {
if (slot.item == null){
return Messages.titleCase(Messages.get(WndKeyBindings.class, "quickslot_" + (slotNum+1)));
} else {
return super.hoverText();
}
}
@Override
protected void onClick() {
if (Dungeon.hero.ready && !GameScene.cancel()) {
GameScene.selectItem(itemSelector);
}
}
@Override
protected boolean onLongClick() {
if (Dungeon.hero.ready && !GameScene.cancel()) {
@ -233,7 +209,7 @@ public class QuickSlotButton extends Button {
private static Item select(int slotNum){
return Dungeon.quickslot.getItem( slotNum );
}
public void item( Item item ) {
slot.item( item );
enableSlot();
@ -247,19 +223,9 @@ public class QuickSlotButton extends Button {
slot.enable( false );
}
}
private void enableSlot() {
//TODO check if item persists!
slot.enable(Dungeon.quickslot.isNonePlaceholder( slotNum )
&& (Dungeon.hero.buff(LostInventory.class) == null || Dungeon.quickslot.getItem(slotNum).keptThoughLostInvent));
}
public void slotMargins( int left, int top, int right, int bottom){
slot.setMargins(left, top, right, bottom);
}
public static void useTargeting(int idx){
instance[idx].useTargeting();
slot.enable(Dungeon.quickslot.isNonePlaceholder( slotNum ));
}
private void useTargeting() {
@ -273,10 +239,8 @@ public class QuickSlotButton extends Button {
targeting = true;
CharSprite sprite = lastTarget.sprite;
if (sprite.parent != null) {
sprite.parent.addToFront(crossM);
crossM.point(sprite.center(crossM));
}
sprite.parent.addToFront( crossM );
crossM.point(sprite.center(crossM));
crossB.point(slot.sprite.center(crossB));
crossB.visible = true;
@ -319,20 +283,18 @@ public class QuickSlotButton extends Button {
for (int i = 0; i < instance.length; i++) {
if (instance[i] != null) {
instance[i].item(select(i));
instance[i].enable(instance[i].active);
}
}
}
public static void target( Char target ) {
if (target != null && target.alignment != Char.Alignment.ALLY) {
lastTarget = target;
TargetHealthIndicator.instance.target( target );
InventoryPane.lastTarget = target;
}
}
public static void cancel() {
if (targeting) {
crossB.visible = false;

View File

@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.SPDAction;
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
import com.shatteredpixel.shatteredpixeldungeon.custom.utils.Constants;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
@ -77,14 +78,13 @@ public class Toolbar extends Component {
@Override
protected void createChildren() {
//TODO add a changer function to the 4th quickslot if there isn't room for 6?
int quickSlots = 4;
if (PixelScene.uiCamera.width > 152) quickSlots ++;
if (PixelScene.uiCamera.width > 170) quickSlots ++;
btnQuick = new QuickslotTool[Constants.MAX_QUICKSLOTS];
btnQuick = new QuickslotTool[quickSlots];
for (int i = 0; i < quickSlots; i++){
add( btnQuick[i] = new QuickslotTool(64, 0, 22, 24, i) );
for (int i = 0; i < btnQuick.length; i++) {
btnQuick[i] = new QuickslotTool(64, 0, 22, 24, i);
if (i < SPDSettings.quickslots()) {
add(btnQuick[i]);
}
}
add(btnWait = new Tool(24, 0, 20, 26) {
@ -225,14 +225,12 @@ public class Toolbar extends Component {
@Override
protected void layout() {
final int maxHorizontalQuickslots = PixelScene.landscape() ? 5 : 3;
float right = width;
if (SPDSettings.interfaceSize() > 0){
btnInventory.setPos(right - btnInventory.width(), y);
btnWait.setPos(btnInventory.left() - btnWait.width(), y);
btnSearch.setPos(btnWait.left() - btnSearch.width(), y);
right = btnSearch.left();
for(int i = btnQuick.length-1; i >= 0; i--) {
if (i == btnQuick.length-1){
@ -248,25 +246,35 @@ public class Toolbar extends Component {
btnQuick[i].setPos(right-btnQuick[i].width(), y+2);
right = btnQuick[i].left();
}
return;
}
for(int i = 0; i < btnQuick.length; i++) {
if (i == 0 && !SPDSettings.flipToolbar() ||
i == btnQuick.length-1 && SPDSettings.flipToolbar()){
btnQuick[i].border(0, 2);
btnQuick[i].frame(106, 0, 19, 24);
} else if (i == 0 && SPDSettings.flipToolbar() ||
i == btnQuick.length-1 && !SPDSettings.flipToolbar()){
btnQuick[i].border(2, 1);
btnQuick[i].frame(86, 0, 20, 24);
for (int i = 0; i < btnQuick.length; i++) {
if (i < SPDSettings.quickslots()) {
if (btnQuick[i] == null) btnQuick[i] = new QuickslotTool(64, 0, 24, 24, i);
add(btnQuick[i]);
} else {
btnQuick[i].border(0, 1);
btnQuick[i].frame(88, 0, 18, 24);
remove(btnQuick[i]);
}
}
for(int i = 0; i < Constants.MAX_QUICKSLOTS; i++) {
//FIXME doesn't work for portrait mode and no longer dynamically resizes.
if (i == 0 && !SPDSettings.flipToolbar() ||
i == Math.min(SPDSettings.quickslots(), maxHorizontalQuickslots)-1 && SPDSettings.flipToolbar()) {
btnQuick[i].border(0, 2);
btnQuick[i].frame(106, 0, 19, 24);
} else if (i == 0 && SPDSettings.flipToolbar() ||
i == Math.min(SPDSettings.quickslots(), maxHorizontalQuickslots)-1 && !SPDSettings.flipToolbar()) {
btnQuick[i].border(2, 1);
btnQuick[i].frame(86, 0, 20, 24);
} else {
btnQuick[i].border(2, 2);
btnQuick[i].frame(64, 0, 22, 24);
}
}
float startX, startY;
switch(Mode.valueOf(SPDSettings.toolbarMode())){
case SPLIT:
btnWait.setPos(x, y);
@ -274,47 +282,34 @@ public class Toolbar extends Component {
btnInventory.setPos(right - btnInventory.width(), y);
btnQuick[0].setPos(btnInventory.left() - btnQuick[0].width(), y + 2);
for (int i = 1; i < btnQuick.length; i++) {
btnQuick[i].setPos(btnQuick[i-1].left() - btnQuick[i].width(), y + 2);
startX = btnInventory.left() - btnQuick[0].width();
for (int i = 0; i < maxHorizontalQuickslots; i++) {
QuickslotTool tool = btnQuick[i];
tool.setPos(startX, y);
if (i + 1 < btnQuick.length) {
startX = btnQuick[i].left() - btnQuick[i+1].width();
}
}
startY = 40;
for (int i = maxHorizontalQuickslots; i < btnQuick.length; i++) {
QuickslotTool tool = btnQuick[i];
tool.setPos(width - (tool.width() + 2), startY);
if (i + 1 < btnQuick.length) {
startY = btnQuick[i].bottom();
}
}
//center the quickslots if they
if (btnQuick[btnQuick.length-1].left() < btnSearch.right()){
float diff = Math.round(btnSearch.right() - btnQuick[btnQuick.length-1].left())/2;
for( int i = 0; i < btnQuick.length; i++){
for( int i = 0; i < Constants.MAX_QUICKSLOTS; i++){
btnQuick[i].setPos( btnQuick[i].left()+diff, btnQuick[i].top() );
}
}
break;
//center = group but.. well.. centered, so all we need to do is pre-emptively set the right side further in.
case CENTER:
float toolbarWidth = btnWait.width() + btnSearch.width() + btnInventory.width();
for(Button slot : btnQuick){
if (slot.visible) toolbarWidth += slot.width();
}
right = (width + toolbarWidth)/2;
case GROUP:
btnWait.setPos(right - btnWait.width(), y);
btnSearch.setPos(btnWait.left() - btnSearch.width(), y);
btnInventory.setPos(btnSearch.left() - btnInventory.width(), y);
btnQuick[0].setPos(btnInventory.left() - btnQuick[0].width(), y + 2);
for (int i = 1; i < btnQuick.length; i++) {
btnQuick[i].setPos(btnQuick[i-1].left() - btnQuick[i].width(), y + 2);
}
if (btnQuick[btnQuick.length-1].left() < 0){
float diff = -Math.round(btnQuick[btnQuick.length-1].left())/2;
for( int i = 0; i < btnQuick.length; i++){
btnQuick[i].setPos( btnQuick[i].left()+diff, btnQuick[i].top() );
}
}
break;
}
right = width;
@ -324,12 +319,10 @@ public class Toolbar extends Component {
btnSearch.setPos( (right - btnSearch.right()), y);
btnInventory.setPos( (right - btnInventory.right()), y);
for(int i = 0; i < btnQuick.length; i++) {
btnQuick[i].setPos( right - btnQuick[i].right(), y+2);
for (QuickslotTool tool : btnQuick) {
tool.setPos( right - tool.right(), y+2);
}
}
}
public static void updateLayout(){
@ -471,8 +464,7 @@ public class Toolbar extends Component {
@Override
protected void layout() {
super.layout();
slot.setRect( x, y, width, height );
slot.slotMargins(borderLeft, 2, borderRight, 2);
slot.setRect( x + borderLeft, y + 2, width - borderLeft-borderRight, height - 4 );
}
@Override

View File

@ -1,5 +1,9 @@
package com.shatteredpixel.shatteredpixeldungeon.ui.changelist.mlpd;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.ChangesScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.FlameBoiSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
@ -21,12 +25,39 @@ public class vM0_6_7_X_Changes {
changes.hardlight(Window.TITLE_COLOR);
changeInfos.add(changes);
changes = new ChangeInfo("新内容", false, null);
changes.hardlight(Window.GREEN_COLOR);
changeInfos.add(changes);
changes.addButton(new ChangeButton((new Image("Ling.png", 0, 0, 16, 16)), ("开发者的话"),
("你好这里是绫。如你所见这是全新的魔绫像素地牢她已经步入了破碎1.2" +
".3的版本。\n\n至此魔绫像素地牢以后将针对于此破碎底层进行更新。今后不会继续同步底层破碎版本。\n\n" +
"同时,本次更新后,后续应该还有几个补丁版。很高兴一路以来有那么多的朋友,非常谢谢你们的支持。\n\n现在旅途才刚刚开始魔绫下半段将会更加精彩。\n" +
"在这之前,就让我们继续在上半段的魔绫里面探索前进吧。")));
changes.addButton(new ChangeButton(Icons.get(Icons.CHALLENGE_ON), ("新挑战:空洞旅程"),
("开启本挑战将会在开局获得240点理智在_没有光芒下_和_部分怪物的近战_将会使你理智降低。详情查看下表:\n" +
"-棕色老鼠:20%概率(-1理智/每回合)\n-黑色怨灵:10%概率(-3理智/每回合)\n-火把猎人:40%概率(-1理智/每回合)\n-矮人术士:15%概率" +
"(-5理智/每回合)\n-寒冰老鼠:25%概率(-2理智/每回合)\n-DM200:10%概率(-7理智/每回合)\n-矮人武僧:30%的概率(-3理智/每回合)" +
"\n-没有光芒Buff的情况下:-1/每回合\n\n_理智回复策略_:\n-_1_:存在光芒的情况下以:[(+1理智+楼层深度/10)/每回合]" +
"(举例:20层没有光芒的情况下,1+20/10=3(+3智/每回合)\n-_2_.商人售卖信仰药水喝下去追加40回合理智\n-_3_.击败敌人可以获得敌人的灵魂," +
"灵魂到一定数量可以使提灯可以再次点亮道路。灵魂也可以缓慢回复理智。(50灵魂=1理智回复)\n\n尚未制作完成敬请期待")));
changes = new ChangeInfo("改动", false, null);
changes.hardlight(Window.SKYBULE_COLOR);
changeInfos.add(changes);
changes.addButton(new ChangeButton(new Image("sprites/spinner.png", 144, 0, 16, 16), (Messages.get(ChangesScene.class, "bugfixes")),
Messages.get(vM0_6_7_X_Changes.class, "bug_06X20")));
changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.DG24), ("极度秘卷"),
("原炎魔秘卷,现在重做。具体请游戏里面自行探索。")));
changes.addButton(new ChangeButton(Icons.get(Icons.INFO), ("快捷栏调整"),
("快捷栏使用说明:\n-1.请最好根据自己的分辨率进行调整,避免出现快捷栏叠加情况\n-2.由于技术问题,快捷栏仅在游戏中才可以设置\n-3.最多支持12个快捷栏玩得高兴")));
changes.addButton(new ChangeButton(Icons.get(Icons.CHANGES), ("重大更新"),
("魔绫现已更新底层到破碎123版本")));
("魔绫现已更新底层到破碎V1.2.3版本!")));
changes.addButton(new ChangeButton(Icons.get(Icons.CHALLENGE_ON), ("新挑战和部分挑战改动"),
("部分挑战进行重新调整,同时追加全新挑战,欢迎前来探索\n\n注意部分挑战尚未完成请等待后续版本")));
@ -37,20 +68,32 @@ public class vM0_6_7_X_Changes {
changes.addButton(new ChangeButton(Icons.get(Icons.DISPLAY), ("UI优化改动"),
("魔绫已经对UI优化改动进行大规模调整欢迎前来体验")));
changes.addButton(new ChangeButton((new Image("Ling.png", 0, 0, 16, 16)), ("开发者的话"),
("你好这里是绫。如你所见这是全新的魔绫像素地牢她已经步入了破碎1.2" +
".3的版本。\n\n至此魔绫像素地牢以后将针对于此破碎底层进行更新。今后不会继续同步底层破碎版本。\n\n" +
"同时,本次更新后,后续应该还有几个补丁版。很高兴一路以来有那么多的朋友,非常谢谢你们的支持。\n\n现在旅途才刚刚开始魔绫下半段将会更加精彩。\n" +
"在这之前,就让我们继续在上半段的魔绫里面探索前进吧。")));
changes = new ChangeInfo("调整", false, null);
changes.hardlight(Window.GREEN_COLOR);
changes.hardlight(Window.CYELLOW);
changeInfos.add(changes);
changes.addButton( new ChangeButton(new Image(Assets.Environment.TILES_SEWERS, 48, 80, 16, 16 ), "水晶十字房加强",
"水晶十字房间改动说明:\n" +
"第一个房间概率在80-270范围给予金币\n" +
"第二个房间:概率在符石,种子,卷轴,食物中随机抽取\n" +
"第三个房间概率在135阶武器戒指中随机抽取\n" +
"第四个房间:概率在护甲,符石,法杖,神器中随机抽取"));
changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.FIREFISHSWORD), ("尚方宝剑特效重写"),
("优化了尚方宝剑特效,并最大程度上进行了处理")));
changes = new ChangeInfo("移除", false, null);
changes.hardlight(Window.RED_COLOR);
changeInfos.add(changes);
changes.addButton(new ChangeButton(new FlameBoiSprite(), ("火焰机器人"),
("移除火焰机器人在常规局的出现,仅出现在支离破碎的精英怪概率里面")));
changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.DG1), ("炸弹匕首"),
("移除炸弹匕首,它实在没有太大的用处。")));
changes.addButton(new ChangeButton(new ItemSprite(ItemSpriteSheet.BlackDog), ("黑狗爪"),
("移除黑狗爪,它已不再有当年的威风")));
}
}

View File

@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui.changelist;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DwarfKing;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
@ -499,7 +499,7 @@ public class v0_8_X_Changes {
Image i = new Image(new DM300Sprite());
i.scale.set(PixelScene.align(0.74f));
changes.addButton( new ChangeButton(i, Messages.get(DM300.class, "name"),
changes.addButton( new ChangeButton(i, Messages.get(NewDM300.class, "name"),
"The DM-300 fight has been reworked! DM-300 now has redesigned abilities, a new boss arena, and multiple phases!\n\n" +
"As a part of this rework, DM-300's direct stats have been adjusted:\n" +
"_-_ Health increased to 300 from 200\n" +

View File

@ -27,6 +27,9 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.BookBag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.HerbBag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.LingBag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.MagicalHolster;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.PotionBandolier;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.ScrollHolder;
@ -396,6 +399,12 @@ public class WndBag extends WndTabbed {
return Icons.get( Icons.WAND_HOLSTER );
} else if (bag instanceof PotionBandolier) {
return Icons.get( Icons.POTION_BANDOLIER );
} else if (bag instanceof HerbBag) {
return new ItemSprite(ItemSpriteSheet.PASTY);
} else if (bag instanceof LingBag) {
return new Image("Ling.png", 0, 0, 16, 16);
} else if (bag instanceof BookBag) {
return Icons.get(Icons.NEWS);
} else {
return Icons.get( Icons.BACKPACK );
}

View File

@ -96,7 +96,6 @@ public class WndChallenges extends Window {
final int happy_mode =14;
final int Test_Debug = 15;
boolean isCustom = false;
//boolean isCustom = false;
float pos = 0;
for (int i = 0; i < Challenges.NAME_IDS.length; i++) {
@ -138,13 +137,21 @@ public class WndChallenges extends Window {
cb.checked((checked & Challenges.MASKS[i]) != 0);
cb.active = editable;
//暂时禁用
//Disable
if(Challenges.NAME_IDS[i].equals("light&black")||Challenges.NAME_IDS[i].equals("exsg")||Challenges.NAME_IDS[i].equals("boss")||Challenges.NAME_IDS[i].equals("aquaphobia")){
cb.active = false;
cb.checked(false);
cb.alpha(0.5f);
}
//if(Challenges.NAME_IDS[i].equals("no_food") && cb.active == editable){
// if(boxes.get( 12 ).checked()){
// cb.active = false;
// cb.checked(false);
// cb.alpha(0.5f);
// }
//}
if (i > 0) {
pos += GAP;

View File

@ -21,16 +21,17 @@
package com.shatteredpixel.shatteredpixeldungeon.windows;
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.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.custom.messages.M;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite;
import com.shatteredpixel.shatteredpixeldungeon.text.HeroStat;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIcon;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton;
@ -41,12 +42,10 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.TalentButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.TalentsPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.shatteredpixel.shatteredpixeldungeon.utils.DungeonSeed;
import com.watabou.noosa.Gizmo;
import com.watabou.noosa.Group;
import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.ui.Component;
import java.util.ArrayList;
@ -54,7 +53,7 @@ import java.util.Locale;
public class WndHero extends WndTabbed {
private static final int WIDTH = 120;
private static final int WIDTH = 160;
private static final int HEIGHT = 120;
private StatsTab stats;
@ -189,6 +188,9 @@ public class WndHero extends WndTabbed {
statSlot( Messages.get(this, "gold"), Statistics.goldCollected );
statSlot( Messages.get(this, "depth"), Statistics.deepestFloor );
statSlot( M.L(HeroStat.class,"seed_dungeon"), M.L(HeroStat.class, Statistics.isCustomSeed ?"seed_custom_yes":"seed_custom_no")
+ "-" + DungeonSeed.convertToCode(Dungeon.seed).toUpperCase());
pos += GAP;
}

View File

@ -53,48 +53,54 @@ import java.util.Comparator;
import java.util.HashMap;
public class WndJournal extends WndTabbed {
public static final int WIDTH_P = 126;
public static final int HEIGHT_P = 180;
public static final int WIDTH_L = 200;
public static final int HEIGHT_L = 130;
private static final int ITEM_HEIGHT = 18;
private GuideTab guideTab;
private AlchemyTab alchemyTab;
private NotesTab notesTab;
private CatalogTab catalogTab;
private BooksTab booksTab;
public static int last_index = 0;
public WndJournal(){
int width = PixelScene.landscape() ? WIDTH_L : WIDTH_P;
int height = PixelScene.landscape() ? HEIGHT_L : HEIGHT_P;
resize(width, height);
guideTab = new GuideTab();
add(guideTab);
guideTab.setRect(0, 0, width, height);
guideTab.updateList();
alchemyTab = new AlchemyTab();
add(alchemyTab);
alchemyTab.setRect(0, 0, width, height);
notesTab = new NotesTab();
add(notesTab);
notesTab.setRect(0, 0, width, height);
notesTab.updateList();
catalogTab = new CatalogTab();
add(catalogTab);
catalogTab.setRect(0, 0, width, height);
catalogTab.updateList();
booksTab = new BooksTab();
add(booksTab);
booksTab.setRect(0, 0, width, height);
booksTab.updateList();
Tab[] tabs = {
new IconTab( new ItemSprite(ItemSpriteSheet.GUIDE_PAGE, null) ) {
protected void select( boolean value ) {
@ -123,15 +129,23 @@ public class WndJournal extends WndTabbed {
catalogTab.active = catalogTab.visible = value;
if (value) last_index = 3;
}
},
new IconTab( new ItemSprite(ItemSpriteSheet.DG20, null) ) {
protected void select( boolean value ) {
super.select( value );
booksTab.active = booksTab.visible = value;
if (value) last_index = 4;
}
}
};
for (Tab tab : tabs) {
add( tab );
}
layoutTabs();
select(last_index);
}
@ -145,76 +159,76 @@ public class WndJournal extends WndTabbed {
}
private static class ListItem extends Component {
protected RenderedTextBlock label;
protected BitmapText depth;
protected ColorBlock line;
protected Image icon;
public ListItem( Image icon, String text ) {
this(icon, text, -1);
}
public ListItem( Image icon, String text, int d ) {
super();
this.icon.copy(icon);
label.text( text );
if (d >= 0) {
depth.text(Integer.toString(d));
depth.measure();
if (d == Dungeon.depth) {
label.hardlight(TITLE_COLOR);
depth.hardlight(TITLE_COLOR);
}
}
}
@Override
protected void createChildren() {
label = PixelScene.renderTextBlock( 7 );
add( label );
icon = new Image();
add( icon );
depth = new BitmapText( PixelScene.pixelFont);
add( depth );
line = new ColorBlock( 1, 1, 0xFF222222);
add(line);
}
@Override
protected void layout() {
icon.y = y + 1 + (height() - 1 - icon.height()) / 2f;
icon.x = x + (16 - icon.width())/2f;
PixelScene.align(icon);
depth.x = icon.x + (icon.width - depth.width()) / 2f;
depth.y = icon.y + (icon.height - depth.height()) / 2f + 1;
PixelScene.align(depth);
line.size(width, 1);
line.x = 0;
line.y = y;
label.maxWidth((int)(width - 16 - 1));
label.setPos(17, y + 1 + (height() - label.height()) / 2f);
PixelScene.align(label);
}
}
public static class GuideTab extends Component {
private ScrollPane list;
private ArrayList<GuideItem> pages = new ArrayList<>();
@Override
protected void createChildren() {
list = new ScrollPane( new Component() ){
@ -230,64 +244,64 @@ public class WndJournal extends WndTabbed {
};
add( list );
}
@Override
protected void layout() {
super.layout();
list.setRect( 0, 0, width, height);
}
private void updateList(){
Component content = list.content();
float pos = 0;
ColorBlock line = new ColorBlock( width(), 1, 0xFF222222);
line.y = pos;
content.add(line);
RenderedTextBlock title = PixelScene.renderTextBlock(Document.ADVENTURERS_GUIDE.title(), 9);
title.hardlight(TITLE_COLOR);
title.maxWidth( (int)width() - 2 );
title.setPos( (width() - title.width())/2f, pos + 1 + ((ITEM_HEIGHT) - title.height())/2f);
PixelScene.align(title);
content.add(title);
pos += Math.max(ITEM_HEIGHT, title.height());
for (String page : Document.ADVENTURERS_GUIDE.pageNames()){
GuideItem item = new GuideItem( page );
item.setRect( 0, pos, width(), ITEM_HEIGHT );
content.add( item );
pos += item.height();
pages.add(item);
}
content.setSize( width(), pos );
list.setSize( list.width(), list.height() );
}
private static class GuideItem extends ListItem {
private boolean found = false;
private String page;
public GuideItem( String page ){
super( iconForPage(page), Messages.titleCase(Document.ADVENTURERS_GUIDE.pageTitle(page)));
this.page = page;
found = Document.ADVENTURERS_GUIDE.isPageFound(page);
if (!found) {
icon.hardlight( 0.5f, 0.5f, 0.5f);
label.text( Messages.titleCase(Messages.get( this, "missing" )));
label.hardlight( 0x999999 );
}
}
public boolean onClick( float x, float y ) {
if (inside( x, y ) && found) {
GameScene.show( new WndStory( iconForPage(page),
@ -299,7 +313,7 @@ public class WndJournal extends WndTabbed {
return false;
}
}
}
//TODO might just want this to be part of the Document class
@ -338,22 +352,22 @@ public class WndJournal extends WndTabbed {
}
}
public static class AlchemyTab extends Component {
private RedButton[] pageButtons;
private static final int NUM_BUTTONS = 10;
private static final int[] spriteIndexes = {10, 12, 7, 9, 11, 8, 3, 13, 14, 15};
public static int currentPageIdx = -1;
private IconTitle title;
private RenderedTextBlock body;
private ScrollPane list;
private ArrayList<QuickRecipe> recipes = new ArrayList<>();
@Override
protected void createChildren() {
pageButtons = new RedButton[NUM_BUTTONS];
@ -374,21 +388,21 @@ public class WndJournal extends WndTabbed {
}
add( pageButtons[i] );
}
title = new IconTitle();
title.icon( new ItemSprite(ItemSpriteSheet.ALCH_PAGE));
title.visible = false;
body = PixelScene.renderTextBlock(6);
list = new ScrollPane(new Component());
add(list);
}
@Override
protected void layout() {
super.layout();
if (PixelScene.landscape()){
float buttonWidth = width()/pageButtons.length;
for (int i = 0; i < NUM_BUTTONS; i++) {
@ -411,13 +425,13 @@ public class WndJournal extends WndTabbed {
}
}
}
list.setRect(0, pageButtons[NUM_BUTTONS-1].bottom() + 1, width,
height - pageButtons[NUM_BUTTONS-1].bottom() - 1);
updateList();
}
private void updateList() {
for (int i = 0; i < NUM_BUTTONS; i++) {
@ -427,11 +441,11 @@ public class WndJournal extends WndTabbed {
pageButtons[i].icon().resetColor();
}
}
if (currentPageIdx == -1){
return;
}
for (QuickRecipe r : recipes){
if (r != null) {
r.killAndErase();
@ -439,25 +453,25 @@ public class WndJournal extends WndTabbed {
}
}
recipes.clear();
Component content = list.content();
content.clear();
title.visible = true;
title.label(Document.ALCHEMY_GUIDE.pageTitle(currentPageIdx));
title.setRect(0, 0, width(), 10);
content.add(title);
body.maxWidth((int)width());
body.text(Document.ALCHEMY_GUIDE.pageBody(currentPageIdx));
body.setPos(0, title.bottom());
content.add(body);
Document.ALCHEMY_GUIDE.readPage(currentPageIdx);
ArrayList<QuickRecipe> toAdd = QuickRecipe.getRecipes(currentPageIdx);
float left;
float top = body.bottom()+2;
int w;
@ -467,14 +481,14 @@ public class WndJournal extends WndTabbed {
toAdd.remove(0);
top += 6;
}
w = 0;
while(!toAdd.isEmpty() && toAdd.get(0) != null
&& w + toAdd.get(0).width() <= width()){
toAddThisRow.add(toAdd.remove(0));
w += toAddThisRow.get(0).width();
}
float spacing = (width() - w)/(toAddThisRow.size() + 1);
left = spacing;
while (!toAddThisRow.isEmpty()){
@ -491,11 +505,11 @@ public class WndJournal extends WndTabbed {
recipes.add(r);
content.add(r);
}
if (!toAdd.isEmpty() && toAdd.get(0) == null){
toAdd.remove(0);
}
if (!toAdd.isEmpty() && toAdd.get(0) != null) {
ColorBlock spacer = new ColorBlock(width(), 1, 0xFF222222);
spacer.y = top + 16;
@ -511,42 +525,42 @@ public class WndJournal extends WndTabbed {
list.scrollTo(0, 0);
}
}
private static class NotesTab extends Component {
private ScrollPane list;
@Override
protected void createChildren() {
list = new ScrollPane( new Component() );
add( list );
}
@Override
protected void layout() {
super.layout();
list.setRect( 0, 0, width, height);
}
private void updateList(){
Component content = list.content();
float pos = 0;
//Keys
ArrayList<Notes.KeyRecord> keys = Notes.getRecords(Notes.KeyRecord.class);
if (!keys.isEmpty()){
ColorBlock line = new ColorBlock( width(), 1, 0xFF222222);
line.y = pos;
content.add(line);
RenderedTextBlock title = PixelScene.renderTextBlock(Messages.get(this, "keys"), 9);
title.hardlight(TITLE_COLOR);
title.maxWidth( (int)width() - 2 );
title.setPos( (width() - title.width())/2f, pos + 1 + ((ITEM_HEIGHT) - title.height())/2f);
PixelScene.align(title);
content.add(title);
pos += Math.max(ITEM_HEIGHT, title.height());
}
for(Notes.Record rec : keys){
@ -554,24 +568,24 @@ public class WndJournal extends WndTabbed {
Messages.titleCase(rec.desc()), rec.depth() );
item.setRect( 0, pos, width(), ITEM_HEIGHT );
content.add( item );
pos += item.height();
}
//Landmarks
ArrayList<Notes.LandmarkRecord> landmarks = Notes.getRecords(Notes.LandmarkRecord.class);
if (!landmarks.isEmpty()){
ColorBlock line = new ColorBlock( width(), 1, 0xFF222222);
line.y = pos;
content.add(line);
RenderedTextBlock title = PixelScene.renderTextBlock(Messages.get(this, "landmarks"), 9);
title.hardlight(TITLE_COLOR);
title.maxWidth( (int)width() - 2 );
title.setPos( (width() - title.width())/2f, pos + 1 + ((ITEM_HEIGHT) - title.height())/2f);
PixelScene.align(title);
content.add(title);
pos += Math.max(ITEM_HEIGHT, title.height());
}
for (Notes.Record rec : landmarks) {
@ -579,23 +593,194 @@ public class WndJournal extends WndTabbed {
Messages.titleCase(rec.desc()), rec.depth() );
item.setRect( 0, pos, width(), ITEM_HEIGHT );
content.add( item );
pos += item.height();
}
content.setSize( width(), pos );
list.setSize( list.width(), list.height() );
}
}
private static class BooksTab extends Component{
private RedButton[] itemButtons;
private static final int NUM_BUTTONS = 2;
private static int currentItemIdx = 0;
//sprite locations
private static final int WEAPON_IDX = 0;
private static final int CUSTOM_IDX = 1;
private static final int spriteIndexes[] = {1, 2, 4, 5, 6, 9, 11};
private ScrollPane list;
private ArrayList<CatalogItem> items = new ArrayList<>();
@Override
protected void createChildren() {
itemButtons = new RedButton[NUM_BUTTONS];
for (int i = 0; i < NUM_BUTTONS; i++){
final int idx = i;
itemButtons[i] = new RedButton( "" ){
@Override
protected void onClick() {
currentItemIdx = idx;
updateList();
}
};
itemButtons[i].icon(new ItemSprite(ItemSpriteSheet.GRRENSHILED+ spriteIndexes[i], null));
add( itemButtons[i] );
}
list = new ScrollPane( new Component() ) {
@Override
public void onClick( float x, float y ) {
int size = items.size();
for (int i=0; i < size; i++) {
if (items.get( i ).onClick( x, y )) {
break;
}
}
}
};
add( list );
}
@Override
protected void layout() {
super.layout();
int perRow = NUM_BUTTONS;
float buttonWidth = width()/perRow;
for (int i = 0; i < NUM_BUTTONS; i++) {
itemButtons[i].setRect((i%perRow) * (buttonWidth), (i/perRow) * (ITEM_HEIGHT ),
buttonWidth, ITEM_HEIGHT);
PixelScene.align(itemButtons[i]);
}
list.setRect(0, itemButtons[NUM_BUTTONS-1].bottom() + 1, width,
height - itemButtons[NUM_BUTTONS-1].bottom() - 1);
}
private void updateList() {
items.clear();
for (int i = 0; i < NUM_BUTTONS; i++){
if (i == currentItemIdx){
itemButtons[i].icon().resetColor();
} else {
itemButtons[i].icon().resetColor();
}
}
Component content = list.content();
content.clear();
list.scrollTo( 0, 0 );
ArrayList<Class<? extends Item>> itemClasses;
final HashMap<Class<? extends Item>, Boolean> known = new HashMap<>();
if (currentItemIdx == WEAPON_IDX) {
itemClasses = new ArrayList<>(Catalog.BOOKS.items());
for (Class<? extends Item> cls : itemClasses) known.put(cls, true);
} else if (currentItemIdx == CUSTOM_IDX){
itemClasses = new ArrayList<>(Catalog.PLAYBOOKS.items());
for (Class<? extends Item> cls : itemClasses) known.put(cls, true);
} else {
itemClasses = new ArrayList<>();
}
Collections.sort(itemClasses, new Comparator<Class<? extends Item>>() {
@Override
public int compare(Class<? extends Item> a, Class<? extends Item> b) {
int result = 0;
//specifically known items appear first, then seen items, then unknown items.
if (known.get(a) && Catalog.isSeen(a)) result -= 2;
if (known.get(b) && Catalog.isSeen(b)) result += 2;
if (Catalog.isSeen(a)) result --;
if (Catalog.isSeen(b)) result ++;
return result;
}
});
float pos = 0;
for (Class<? extends Item> itemClass : itemClasses) {
CatalogItem item = new CatalogItem(Reflection.newInstance(itemClass), known.get(itemClass), Catalog.isSeen(itemClass));
item.setRect( 0, pos, width, ITEM_HEIGHT );
content.add( item );
items.add( item );
pos += item.height();
}
content.setSize( width, pos );
list.setSize( list.width(), list.height() );
}
private static class CatalogItem extends ListItem {
private Item item;
private boolean seen;
public CatalogItem(Item item, boolean IDed, boolean seen ) {
super( new ItemSprite(item), Messages.titleCase(item.trueName()));
this.item = item;
this.seen = seen;
if ( seen && !IDed ){
if (item instanceof Ring){
((Ring) item).anonymize();
} else if (item instanceof Potion){
((Potion) item).anonymize();
} else if (item instanceof Scroll){
((Scroll) item).anonymize();
}
}
if (!seen) {
icon.copy( new ItemSprite( ItemSpriteSheet.ICEBOOKS + spriteIndexes[currentItemIdx], null) );
label.text(Messages.get("notfound"));
label.hardlight( 0x999999 );
} else if (!IDed) {
icon.copy( new ItemSprite( ItemSpriteSheet.ICEBOOKS + spriteIndexes[currentItemIdx], null) );
label.hardlight( 0xCCCCCC );
}
}
public boolean onClick( float x, float y ) {
if (inside( x, y ) && seen) {
if (item instanceof ClassArmor){
GameScene.show(new WndTitledMessage(new Image(icon),
Messages.titleCase(item.trueName()), item.desc()));
} else {
GameScene.show(new WndTitledMessage(new Image(icon),
Messages.titleCase(item.trueName()), item.info()));
}
return true;
} else {
return false;
}
}
}
}
private static class CatalogTab extends Component{
private RedButton[] itemButtons;
private static final int NUM_BUTTONS = 7;
private static int currentItemIdx = 0;
//sprite locations
private static final int WEAPON_IDX = 0;
private static final int ARMOR_IDX = 1;
@ -604,13 +789,13 @@ public class WndJournal extends WndTabbed {
private static final int ARTIF_IDX = 4;
private static final int POTION_IDX = 5;
private static final int SCROLL_IDX = 6;
private static final int spriteIndexes[] = {1, 2, 4, 5, 6, 9, 11};
private ScrollPane list;
private ArrayList<CatalogItem> items = new ArrayList<>();
@Override
protected void createChildren() {
itemButtons = new RedButton[NUM_BUTTONS];
@ -626,7 +811,7 @@ public class WndJournal extends WndTabbed {
itemButtons[i].icon(new ItemSprite(ItemSpriteSheet.SOMETHING + spriteIndexes[i], null));
add( itemButtons[i] );
}
list = new ScrollPane( new Component() ) {
@Override
public void onClick( float x, float y ) {
@ -640,28 +825,28 @@ public class WndJournal extends WndTabbed {
};
add( list );
}
@Override
protected void layout() {
super.layout();
int perRow = NUM_BUTTONS;
float buttonWidth = width()/perRow;
for (int i = 0; i < NUM_BUTTONS; i++) {
itemButtons[i].setRect((i%perRow) * (buttonWidth), (i/perRow) * (ITEM_HEIGHT ),
buttonWidth, ITEM_HEIGHT);
PixelScene.align(itemButtons[i]);
}
list.setRect(0, itemButtons[NUM_BUTTONS-1].bottom() + 1, width,
height - itemButtons[NUM_BUTTONS-1].bottom() - 1);
}
private void updateList() {
items.clear();
for (int i = 0; i < NUM_BUTTONS; i++){
if (i == currentItemIdx){
itemButtons[i].icon().color(TITLE_COLOR);
@ -669,11 +854,11 @@ public class WndJournal extends WndTabbed {
itemButtons[i].icon().resetColor();
}
}
Component content = list.content();
content.clear();
list.scrollTo( 0, 0 );
ArrayList<Class<? extends Item>> itemClasses;
final HashMap<Class<? extends Item>, Boolean> known = new HashMap<>();
if (currentItemIdx == WEAPON_IDX) {
@ -700,44 +885,44 @@ public class WndJournal extends WndTabbed {
} else {
itemClasses = new ArrayList<>();
}
Collections.sort(itemClasses, new Comparator<Class<? extends Item>>() {
@Override
public int compare(Class<? extends Item> a, Class<? extends Item> b) {
int result = 0;
//specifically known items appear first, then seen items, then unknown items.
if (known.get(a) && Catalog.isSeen(a)) result -= 2;
if (known.get(b) && Catalog.isSeen(b)) result += 2;
if (Catalog.isSeen(a)) result --;
if (Catalog.isSeen(b)) result ++;
return result;
}
});
float pos = 0;
for (Class<? extends Item> itemClass : itemClasses) {
CatalogItem item = new CatalogItem(Reflection.newInstance(itemClass), known.get(itemClass), Catalog.isSeen(itemClass));
item.setRect( 0, pos, width, ITEM_HEIGHT );
content.add( item );
items.add( item );
pos += item.height();
}
content.setSize( width, pos );
list.setSize( list.width(), list.height() );
}
private static class CatalogItem extends ListItem {
private Item item;
private boolean seen;
public CatalogItem(Item item, boolean IDed, boolean seen ) {
super( new ItemSprite(item), Messages.titleCase(item.trueName()));
this.item = item;
this.seen = seen;
@ -750,7 +935,7 @@ public class WndJournal extends WndTabbed {
((Scroll) item).anonymize();
}
}
if (!seen) {
icon.copy( new ItemSprite( ItemSpriteSheet.SOMETHING + spriteIndexes[currentItemIdx], null) );
label.text("???");
@ -759,9 +944,9 @@ public class WndJournal extends WndTabbed {
icon.copy( new ItemSprite( ItemSpriteSheet.SOMETHING + spriteIndexes[currentItemIdx], null) );
label.hardlight( 0xCCCCCC );
}
}
public boolean onClick( float x, float y ) {
if (inside( x, y ) && seen) {
if (item instanceof ClassArmor){
@ -777,7 +962,7 @@ public class WndJournal extends WndTabbed {
}
}
}
}
}

View File

@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.custom.utils.Constants;
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@ -390,7 +391,9 @@ public class WndSettings extends WndTabbed {
ColorBlock sep1;
OptionSlider optUISize;
RenderedTextBlock barDesc;
RedButton btnSplit; RedButton btnGrouped; RedButton btnCentered;
RedButton btnSplit;
RedButton btnGrouped;
RedButton btnCentered;
CheckBox chkFlipToolbar;
CheckBox chkFlipTags;
ColorBlock sep2;
@ -436,9 +439,6 @@ public class WndSettings extends WndTabbed {
btnSplit = new RedButton(Messages.get(this, "split")) {
@Override
protected void onClick() {
textColor(TITLE_COLOR);
btnGrouped.textColor(WHITE);
btnCentered.textColor(WHITE);
SPDSettings.toolbarMode(Toolbar.Mode.SPLIT.name());
Toolbar.updateLayout();
}
@ -447,34 +447,6 @@ public class WndSettings extends WndTabbed {
btnSplit.textColor(TITLE_COLOR);
add(btnSplit);
btnGrouped = new RedButton(Messages.get(this, "group")) {
@Override
protected void onClick() {
btnSplit.textColor(WHITE);
textColor(TITLE_COLOR);
btnCentered.textColor(WHITE);
SPDSettings.toolbarMode(Toolbar.Mode.GROUP.name());
Toolbar.updateLayout();
}
};
if (SPDSettings.toolbarMode().equals(Toolbar.Mode.GROUP.name()))
btnGrouped.textColor(TITLE_COLOR);
add(btnGrouped);
btnCentered = new RedButton(Messages.get(this, "center")) {
@Override
protected void onClick() {
btnSplit.textColor(WHITE);
btnGrouped.textColor(WHITE);
textColor(TITLE_COLOR);
SPDSettings.toolbarMode(Toolbar.Mode.CENTER.name());
Toolbar.updateLayout();
}
};
if (SPDSettings.toolbarMode().equals(Toolbar.Mode.CENTER.name()))
btnCentered.textColor(TITLE_COLOR);
add(btnCentered);
chkFlipToolbar = new CheckBox(Messages.get(this, "flip_toolbar")) {
@Override
protected void onClick() {
@ -554,17 +526,17 @@ public class WndSettings extends WndTabbed {
if (barDesc != null) {
barDesc.setPos((width - barDesc.width()) / 2f, height + GAP);
PixelScene.align(barDesc);
int btnWidth = (int) (width - 2 * GAP) / 3;
btnSplit.setRect(0, barDesc.bottom() + GAP, btnWidth, 16);
btnGrouped.setRect(btnSplit.right() + GAP, btnSplit.top(), btnWidth, 16);
btnCentered.setRect(btnGrouped.right() + GAP, btnSplit.top(), btnWidth, 16);
if(Game.scene()!=null && Game.scene().getClass() == GameScene.class) {
btnSplit.setRect(0, barDesc.bottom() + GAP, width, 16);
} else {
btnSplit.setRect(9999, barDesc.bottom() + GAP, width, 16);
}
if (width > 200) {
chkFlipToolbar.setRect(0, btnGrouped.bottom() + GAP, width / 2 - 1, BTN_HEIGHT);
chkFlipToolbar.setRect(0, btnSplit.bottom() + GAP, width / 2 - 1, BTN_HEIGHT);
chkFlipTags.setRect(chkFlipToolbar.right() + GAP, chkFlipToolbar.top(), width / 2 - 1, BTN_HEIGHT);
} else {
chkFlipToolbar.setRect(0, btnGrouped.bottom() + GAP, width, BTN_HEIGHT);
chkFlipToolbar.setRect(0, btnSplit.bottom() + GAP, width, BTN_HEIGHT);
chkFlipTags.setRect(0, chkFlipToolbar.bottom() + GAP, width, BTN_HEIGHT);
}
} else {
@ -600,9 +572,11 @@ public class WndSettings extends WndTabbed {
private static class ExtendTab extends Component {
RenderedTextBlock title;
RenderedTextBlock wxts;
ColorBlock sep1;
CheckBox ClassUI;
OptionSlider optSplashScreen;
OptionSlider quickslots;
@Override
protected void createChildren() {
@ -636,6 +610,21 @@ public class WndSettings extends WndTabbed {
};
optSplashScreen.setSelectedValue(SPDSettings.splashScreen());
add(optSplashScreen);
quickslots = new OptionSlider(Messages.get(this, "quickslots"), "" + Constants.MIN_QUICKSLOTS,
"" + Constants.MAX_QUICKSLOTS, Constants.MIN_QUICKSLOTS, Constants.MAX_QUICKSLOTS) {
@Override
protected void onChange() {
SPDSettings.quickslots(getSelectedValue());
Toolbar.updateLayout();
}
};
quickslots.setSelectedValue(SPDSettings.quickslots());
add(quickslots);
wxts = PixelScene.renderTextBlock(Messages.get(this, "wxts"), 6);
wxts.hardlight(GREEN_COLOR);
add(wxts);
}
@Override
@ -652,10 +641,23 @@ public class WndSettings extends WndTabbed {
if (width > 200){
ClassUI.setRect(0, bottom, width, SLIDER_HEIGHT);
optSplashScreen.setRect(0, ClassUI.bottom() + GAP, width, SLIDER_HEIGHT);
if(Game.scene()!=null && Game.scene().getClass() == GameScene.class) {
quickslots.setRect(0, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
wxts.setRect(9999, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
} else {
quickslots.setRect(9999, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
wxts.setRect(0, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
}
} else {
//quickslots.setRect(0, bottom + GAP, width, SLIDER_HEIGHT);
ClassUI.setRect(0, bottom + GAP, width, SLIDER_HEIGHT);
optSplashScreen.setRect(0, ClassUI.bottom() + GAP, width, SLIDER_HEIGHT);
if(Game.scene()!=null && Game.scene().getClass() == GameScene.class) {
wxts.setRect(9999, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
quickslots.setRect(0, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
} else {
quickslots.setRect(9999, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
wxts.setRect(0, optSplashScreen.bottom() + GAP, width, SLIDER_HEIGHT);
}
//GameScene
}

2
gradlew vendored
View File

@ -174,7 +174,7 @@ fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
for i do printf %s\n\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`

View File

@ -1 +0,0 @@
/build

View File

@ -1,35 +0,0 @@
plugins {
id 'com.android.library'
}
android {
compileSdk 32
defaultConfig {
minSdk 23
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
testImplementation 'junit:junit:4.+'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

View File

@ -1,25 +0,0 @@
package com.example.myapplication;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.example.myapplication.test", appContext.getPackageName());
}
}

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
</manifest>

View File

@ -1,17 +0,0 @@
package com.example.myapplication;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}