Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
baf6bdf6a5 | ||
|
|
889fd64656 | ||
|
|
59b5d809db | ||
|
|
6c3372e71c | ||
|
|
1cdea49383 | ||
|
|
a6307039b0 | ||
|
|
aaacf244d2 | ||
|
|
2a0af620be | ||
|
|
b801093597 | ||
|
|
81dae580a4 | ||
|
|
03f58a1b02 | ||
|
|
b2b0082c7d | ||
|
|
1d85495f7a | ||
|
|
41d388aa7f | ||
|
|
e88921c77e | ||
|
|
705728f16a | ||
|
|
a7c24d4bfd | ||
|
|
79ace277ed | ||
|
|
bc035f9490 | ||
|
|
73a5af2e5e | ||
|
|
ee7bdbf44e | ||
|
|
b611726c3e | ||
|
|
819686e812 | ||
|
|
94e40a32b9 | ||
|
|
3b2669fa21 | ||
|
|
801ff1701e | ||
|
|
364a2b43c2 | ||
|
|
279d898d68 | ||
|
|
a930b34c3e | ||
|
|
232a3dfe87 | ||
|
|
ddbca62f92 | ||
|
|
646b022d38 | ||
|
|
19ef414e5c | ||
|
|
f46eb24615 | ||
|
|
4e6faf3bac | ||
|
|
48f5007306 | ||
|
|
56acbcecfd | ||
|
|
7d0952d858 | ||
|
|
ef40a2e78e | ||
|
|
b4abd3b23d | ||
|
|
f2a984f3e7 | ||
|
|
1ffa3f21f0 | ||
|
|
7e323f1ebf | ||
|
|
bff79d7c27 | ||
|
|
117f002545 | ||
|
|
953c1889b5 | ||
|
|
cc024a0bac | ||
|
|
42bfab6e40 | ||
|
|
c8ef7ebafb | ||
|
|
5512c1817d | ||
|
|
877999dd1e | ||
|
|
699f2ca5a2 | ||
|
|
89f04ed3e9 | ||
|
|
956840b50b | ||
|
|
b79e0373f4 |
|
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 322 B |
|
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 521 B |
|
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 354 B |
|
Before Width: | Height: | Size: 287 B After Width: | Height: | Size: 420 B |
|
Before Width: | Height: | Size: 337 B After Width: | Height: | Size: 507 B |
|
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 337 B After Width: | Height: | Size: 481 B |
|
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 308 B |
|
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 360 B |
|
Before Width: | Height: | Size: 327 B After Width: | Height: | Size: 386 B |
|
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 380 B |
|
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 539 B |
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 489 B |
|
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 458 B |
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 527 B |
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 508 B |
|
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 484 B |
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 519 B |
@@ -581,7 +581,6 @@ settings.clearcampaignsaves.confirm = Are you sure you want to clear all of your
|
|||||||
paused = [accent]< Paused >
|
paused = [accent]< Paused >
|
||||||
clear = Clear
|
clear = Clear
|
||||||
banned = [scarlet]Banned
|
banned = [scarlet]Banned
|
||||||
unplaceable.sectorcaptured = [scarlet]Requires captured sector
|
|
||||||
yes = Yes
|
yes = Yes
|
||||||
no = No
|
no = No
|
||||||
info.title = Info
|
info.title = Info
|
||||||
@@ -640,7 +639,7 @@ stat.lightningchance = Lightning Chance
|
|||||||
stat.lightningdamage = Lightning Damage
|
stat.lightningdamage = Lightning Damage
|
||||||
stat.flammability = Flammability
|
stat.flammability = Flammability
|
||||||
stat.radioactivity = Radioactivity
|
stat.radioactivity = Radioactivity
|
||||||
stat.heatcapacity = HeatCapacity
|
stat.heatcapacity = Heat Capacity
|
||||||
stat.viscosity = Viscosity
|
stat.viscosity = Viscosity
|
||||||
stat.temperature = Temperature
|
stat.temperature = Temperature
|
||||||
stat.speed = Speed
|
stat.speed = Speed
|
||||||
@@ -727,6 +726,7 @@ setting.blockreplace.name = Automatic Block Suggestions
|
|||||||
setting.linear.name = Linear Filtering
|
setting.linear.name = Linear Filtering
|
||||||
setting.hints.name = Hints
|
setting.hints.name = Hints
|
||||||
setting.flow.name = Display Resource Flow Rate
|
setting.flow.name = Display Resource Flow Rate
|
||||||
|
setting.backgroundpause.name = Pause In Background
|
||||||
setting.buildautopause.name = Auto-Pause Building
|
setting.buildautopause.name = Auto-Pause Building
|
||||||
setting.animatedwater.name = Animated Surfaces
|
setting.animatedwater.name = Animated Surfaces
|
||||||
setting.animatedshields.name = Animated Shields
|
setting.animatedshields.name = Animated Shields
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
credits.text = 作者[royal]Anuken[] - [sky]anukendev@gmail.com[] 译者[orange]老滑稽[] - [cyan]QQ:1290419934[]
|
credits.text = 作者[royal]Anuken[] - [sky]anukendev@gmail.com[]
|
||||||
credits = 致谢
|
credits = 致谢
|
||||||
contributors = 翻译者和贡献者
|
contributors = 翻译者和贡献者
|
||||||
discord = 加入 Mindustry 的 Discord!
|
discord = 加入 Mindustry 的 Discord!
|
||||||
@@ -20,8 +20,8 @@ gameover = 游戏结束
|
|||||||
gameover.pvp = [accent] {0}[]队获胜!
|
gameover.pvp = [accent] {0}[]队获胜!
|
||||||
highscore = [accent]新纪录!
|
highscore = [accent]新纪录!
|
||||||
copied = 已复制。
|
copied = 已复制。
|
||||||
indev.popup = [accent]v6[]仍在[accent]测试版[].\n[lightgray]这意味着:[]\n[scarlet]- 战役不完善[]\n- 内容不完整\n - 大多[scarlet]单位AI[]运行不佳\n- 单位系统不完整\n- 一切内容都可能发生变动或调整。\n\n向[accent]主群(QQ681962751)[]提交错误报告。
|
indev.popup = [accent]6.0[]仍在[accent]测试版[].\n[lightgray]这意味着:[]\n[scarlet]- 战役玩法完全没有完成[]\n- 很多内容还没有做完\n - 大多[scarlet]单位AI[]无法正确地运行\n- 单位系统完全没有完成\n- 一切您所看到的内容都可能会移除或调整。\n\n在[accent]Github[]提交错误报告。\n[#66ccff]来自译者WinterUnderTheSnow的忠告:不建议新玩家游玩还在测试阶段的6.0!建议您先从[orange]v104.6[#66ccff]或[orange]v104.10[#66ccff]开始游玩!
|
||||||
indev.notready = 还没做好看NM
|
indev.notready = 这部分玩法还未开发完成。
|
||||||
|
|
||||||
load.sound = 音乐加载中
|
load.sound = 音乐加载中
|
||||||
load.map = 地图加载中
|
load.map = 地图加载中
|
||||||
@@ -66,7 +66,7 @@ stat.delivered = 装运资源:
|
|||||||
stat.playtime = 游玩时间:[accent] {0}
|
stat.playtime = 游玩时间:[accent] {0}
|
||||||
stat.rank = 最终评级:[accent]{0}
|
stat.rank = 最终评级:[accent]{0}
|
||||||
|
|
||||||
globalitems = [accent]Global Items
|
globalitems = [accent]全局物品
|
||||||
map.delete = 确定要删除“[accent]{0}[]”地图吗?
|
map.delete = 确定要删除“[accent]{0}[]”地图吗?
|
||||||
level.highscore = 最高分:[accent]{0}
|
level.highscore = 最高分:[accent]{0}
|
||||||
level.select = 选择关卡
|
level.select = 选择关卡
|
||||||
@@ -115,7 +115,7 @@ mod.disable = 禁用
|
|||||||
mod.content = 内容:
|
mod.content = 内容:
|
||||||
mod.delete.error = 无法删除模组。可能文件被占用。
|
mod.delete.error = 无法删除模组。可能文件被占用。
|
||||||
mod.requiresversion = [scarlet]所需的游戏版本:[accent]{0}
|
mod.requiresversion = [scarlet]所需的游戏版本:[accent]{0}
|
||||||
mod.outdated = [scarlet]模组不兼容6.0(缺失 minGameVersion: 105)
|
mod.outdated = [scarlet]该模组可能不能在6.0上正确地运行(缺失 minGameVersion: 105)
|
||||||
mod.missingdependencies = [scarlet]缺少前置模组:{0}
|
mod.missingdependencies = [scarlet]缺少前置模组:{0}
|
||||||
mod.erroredcontent = [scarlet]内容错误
|
mod.erroredcontent = [scarlet]内容错误
|
||||||
mod.errors = 读取内容时发生错误.
|
mod.errors = 读取内容时发生错误.
|
||||||
@@ -127,14 +127,14 @@ mod.reloadrequired = [scarlet]需要重启
|
|||||||
mod.import = 导入模组
|
mod.import = 导入模组
|
||||||
mod.import.file = 导入文件
|
mod.import.file = 导入文件
|
||||||
mod.import.github = 从 GitHub 导入模组
|
mod.import.github = 从 GitHub 导入模组
|
||||||
mod.jarwarn = [scarlet]JAR模组存在危险性。[]\n请确保此模组来源安全可靠!
|
mod.jarwarn = [scarlet]JAR模组注定存在危险性。[]\n请确保此模组来源安全可靠!
|
||||||
mod.item.remove = 这个物品是[accent] '{0}'[]模组的一部分. 删除物品需要先卸载此模组.
|
mod.item.remove = 这个物品是[accent] '{0}'[]模组的一部分. 删除物品需要先卸载此模组.
|
||||||
mod.remove.confirm = 此模组将被删除。
|
mod.remove.confirm = 此模组将被删除。
|
||||||
mod.author = [lightgray]作者:[] {0}
|
mod.author = [lightgray]作者:[] {0}
|
||||||
mod.missing = 此存档包含您最近已更新或者现在未安装的模组。存档可能会损坏。确定要加载它吗?\n[lightgray]模组:\n{0}
|
mod.missing = 此存档包含您最近已更新或者现在未安装的模组。存档可能会损坏。确定要加载它吗?\n[lightgray]模组:\n{0}
|
||||||
mod.preview.missing = 在创意工坊中发布此模组前,您必须添加一则预览图像。\n请将名为[accent] preview.png[] 的图像放入模组文件夹,然后重试。
|
mod.preview.missing = 在创意工坊中发布此模组前,您必须添加一则预览图像。\n请将名为[accent] preview.png[] 的图像放入模组文件夹,然后重试。
|
||||||
mod.folder.missing = 只有文件夹形式的模组能在创意工坊上发布。\n若要将任何模组转换为文件夹,只需将其文件解压缩到文件夹中并删除旧压缩包,然后重新启动游戏或重新加载模组。
|
mod.folder.missing = 只有文件夹形式的模组能在创意工坊上发布。\n若要将任何模组转换为文件夹,只需将其文件解压缩到文件夹中并删除旧压缩包,然后重新启动游戏或重新加载模组。
|
||||||
mod.scripts.disable = 你的设备不支持含有脚本的模组。必须禁用相关模组以进入游戏。
|
mod.scripts.disable = 您的设备不支持含有脚本的模组。必须禁用相关模组以进入游戏。
|
||||||
|
|
||||||
about.button = 关于
|
about.button = 关于
|
||||||
name = 名字:
|
name = 名字:
|
||||||
@@ -157,22 +157,22 @@ server.closing = [accent]服务器关闭…
|
|||||||
server.kicked.kick = 你被踢出了服务器。
|
server.kicked.kick = 你被踢出了服务器。
|
||||||
server.kicked.whitelist = 你不在服务器白名单中。
|
server.kicked.whitelist = 你不在服务器白名单中。
|
||||||
server.kicked.serverClose = 服务器已关闭。
|
server.kicked.serverClose = 服务器已关闭。
|
||||||
server.kicked.vote = 你被投票踢出了服务器。
|
server.kicked.vote = 您被投票踢出了服务器。
|
||||||
server.kicked.clientOutdated = 客户端过旧,请更新你的游戏。
|
server.kicked.clientOutdated = 客户端过旧,请更新你的游戏。
|
||||||
server.kicked.serverOutdated = 服务器过旧,请联系服务器管理员升级服务器。
|
server.kicked.serverOutdated = 服务器过旧,请联系服务器管理员升级服务器。
|
||||||
server.kicked.banned = 你在这个服务器上被封禁了。
|
server.kicked.banned = 您在这个服务器上被封禁了。
|
||||||
server.kicked.typeMismatch = 此服务器与你的不稳定测试版不兼容。
|
server.kicked.typeMismatch = 此服务器与你的不稳定测试版不兼容。
|
||||||
server.kicked.playerLimit = 服务器已满,请等待一个空位。
|
server.kicked.playerLimit = 服务器已满,请等待一个空位。
|
||||||
server.kicked.recentKick = 你刚刚被踢出服务器。\n请稍后重新连接!
|
server.kicked.recentKick = 你刚刚被踢出服务器。\n请稍后重新连接!
|
||||||
server.kicked.nameInUse = 你的名字与服务器中的一个人重复了。
|
server.kicked.nameInUse = 您的名字与服务器中的一个人重复了。
|
||||||
server.kicked.nameEmpty = 无效的名字!
|
server.kicked.nameEmpty = 无效的名字!
|
||||||
server.kicked.idInUse = 你已经连接了这个服务器!不允许在一台电脑上用两个客户端连接。
|
server.kicked.idInUse = 您已经连接了这个服务器!不允许在一台设备上用两个客户端连接。
|
||||||
server.kicked.customClient = 这个服务器不支持自定义客户端。请下载官方版本。
|
server.kicked.customClient = 这个服务器不支持自定义客户端。请下载官方版本。
|
||||||
server.kicked.gameover = 游戏结束!
|
server.kicked.gameover = 游戏结束!
|
||||||
server.kicked.serverRestarting = 服务器正在重启.
|
server.kicked.serverRestarting = 服务器正在重启.
|
||||||
server.versions = 客户端版本:[accent] {0}[]\n服务器版本:[accent] {1}[]
|
server.versions = 客户端版本:[accent] {0}[]\n服务器版本:[accent] {1}[]
|
||||||
host.info = [accent]创建局域网游戏[]按钮会在[scarlet] 6567 []端口运行一个服务器。[]\n任何在同一个[lightgray] Wi-Fi 或本地网络[]下的人应该都可以在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过 IP 地址连接,你需要设定[accent]端口转发[]。\n\n[lightgray]注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了 Mindustry 访问本地网络。
|
host.info = [accent]创建局域网游戏[]按钮会在[scarlet] 6567 []端口运行一个服务器。[]\n任何在同一个[lightgray] Wi-Fi 或本地网络[]下的人应该都可以在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过 IP 地址连接,你需要设定[accent]端口转发[]。\n\n[lightgray]注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了 Mindustry 访问本地网络。
|
||||||
join.info = 您可以输入[accent]服务器的 IP 地址[]来连接,或寻找[accent]本地网络[]中的服务器来连接。\n支持局域网或广域网的多人游戏。\n\n[lightgray]注意:没有全球服务器列表;如果你想通过 IP 地址连接某个服务器,你需要向房主询问 IP 地址。
|
join.info = 您可以输入[accent]服务器的 IP 地址[]来连接,或寻找[accent]本地网络[]中的服务器来连接。\n支持局域网或广域网的多人游戏。\n\n[lightgray]注意:没有全球服务器列表;如果你想通过 IP 地址连接某个服务器,你需要向服主询问 IP 地址。
|
||||||
hostserver = 创建服务器
|
hostserver = 创建服务器
|
||||||
invitefriends = 邀请朋友
|
invitefriends = 邀请朋友
|
||||||
hostserver.mobile = 创建\n服务器
|
hostserver.mobile = 创建\n服务器
|
||||||
@@ -201,7 +201,7 @@ server.bans.none = 没有被封禁的玩家!
|
|||||||
server.admins = 管理员
|
server.admins = 管理员
|
||||||
server.admins.none = 该服务器没有管理员!
|
server.admins.none = 该服务器没有管理员!
|
||||||
server.add = 添加服务器
|
server.add = 添加服务器
|
||||||
server.delete = 你确定要删除这个服务器吗?
|
server.delete = 您确定要删除这个服务器吗?
|
||||||
server.edit = 编辑服务器
|
server.edit = 编辑服务器
|
||||||
server.outdated = [crimson]服务器过旧![]
|
server.outdated = [crimson]服务器过旧![]
|
||||||
server.outdated.client = [crimson]客户端过旧![]
|
server.outdated.client = [crimson]客户端过旧![]
|
||||||
@@ -228,11 +228,11 @@ server.addressinuse = 地址已在使用!
|
|||||||
server.invalidport = 无效的端口!
|
server.invalidport = 无效的端口!
|
||||||
server.error = [crimson]创建服务器错误:[accent]{0}
|
server.error = [crimson]创建服务器错误:[accent]{0}
|
||||||
save.new = 新存档
|
save.new = 新存档
|
||||||
save.overwrite = 你确定你要覆盖这个存档吗?
|
save.overwrite = 您确定要覆盖这个存档吗?
|
||||||
overwrite = 覆盖
|
overwrite = 覆盖
|
||||||
save.none = 没有找到存档!
|
save.none = 没有找到存档!
|
||||||
savefail = 保存失败!
|
savefail = 保存失败!
|
||||||
save.delete.confirm = 你确定你要删除这个存档吗?
|
save.delete.confirm = 您确定要删除这个存档吗?
|
||||||
save.delete = 删除
|
save.delete = 删除
|
||||||
save.export = 导出存档
|
save.export = 导出存档
|
||||||
save.import.invalid = [accent]此存档无效!
|
save.import.invalid = [accent]此存档无效!
|
||||||
@@ -245,7 +245,7 @@ save.rename.text = 新名称:
|
|||||||
selectslot = 选择一个存档。
|
selectslot = 选择一个存档。
|
||||||
slot = [accent]存档位 {0}
|
slot = [accent]存档位 {0}
|
||||||
editmessage = 编辑消息
|
editmessage = 编辑消息
|
||||||
save.corrupted = [accent]存档损坏或无效!\n如果你刚刚升级了游戏,那么这可能是因为存档格式改变了,而[scarlet]不是[] bug 。
|
save.corrupted = [accent]存档损坏或无效!\n如果您刚刚升级了游戏,那么这可能是因为存档格式改变了,而[scarlet]不是[] bug 。
|
||||||
empty = < 空 >
|
empty = < 空 >
|
||||||
on = 开
|
on = 开
|
||||||
off = 关
|
off = 关
|
||||||
@@ -297,8 +297,8 @@ loadimage = 加载图片
|
|||||||
saveimage = 保存图片
|
saveimage = 保存图片
|
||||||
unknown = 未知
|
unknown = 未知
|
||||||
custom = 自定义
|
custom = 自定义
|
||||||
builtin = 内建的
|
builtin = 内置的
|
||||||
map.delete.confirm = 你确定你想要删除这张地图吗?这个操作无法撤销!
|
map.delete.confirm = 您确定你想要删除这张地图吗?这个操作无法撤销!
|
||||||
map.random = [accent]随机地图
|
map.random = [accent]随机地图
|
||||||
map.nospawn = 这个地图没有核心!请在编辑器中添加一个[royal]己方[]的核心。
|
map.nospawn = 这个地图没有核心!请在编辑器中添加一个[royal]己方[]的核心。
|
||||||
map.nospawn.pvp = 这个地图没有敌人的核心!请在编辑器中添加一个[royal]敌人[]的核心。
|
map.nospawn.pvp = 这个地图没有敌人的核心!请在编辑器中添加一个[royal]敌人[]的核心。
|
||||||
@@ -363,7 +363,7 @@ editor.removeunit = 移除单位
|
|||||||
editor.teams = 队伍
|
editor.teams = 队伍
|
||||||
editor.errorload = 读取文件出错:\n[accent]{0}
|
editor.errorload = 读取文件出错:\n[accent]{0}
|
||||||
editor.errorsave = 保存文件出错:\n[accent]{0}
|
editor.errorsave = 保存文件出错:\n[accent]{0}
|
||||||
editor.errorimage = 这是一幅图片,不是地图。请不要更改文件的扩展名来导入。\n\n如果你想导入地图,请在编辑器中使用“导入地图”按钮。
|
editor.errorimage = 这是一幅图片,不是地图。请不要更改文件的扩展名来导入。\n\n如果您想导入地图,请在编辑器中使用“导入地图”按钮。
|
||||||
editor.errorlegacy = 此地图太旧了,旧的地图格式已不再支持。
|
editor.errorlegacy = 此地图太旧了,旧的地图格式已不再支持。
|
||||||
editor.errornot = 这不是地图文件。
|
editor.errornot = 这不是地图文件。
|
||||||
editor.errorheader = 此地图文件无效或已损坏。
|
editor.errorheader = 此地图文件无效或已损坏。
|
||||||
@@ -376,8 +376,8 @@ editor.resize = 调整大小
|
|||||||
editor.loadmap = 载入地图
|
editor.loadmap = 载入地图
|
||||||
editor.savemap = 保存地图
|
editor.savemap = 保存地图
|
||||||
editor.saved = 已保存!
|
editor.saved = 已保存!
|
||||||
editor.save.noname = 你的地图没有名字!在“地图信息”菜单里设置一个。
|
editor.save.noname = 您的地图没有名字!在“地图信息”菜单里设置一个。
|
||||||
editor.save.overwrite = 你的地图覆盖了一个内置的地图!在“地图信息”菜单里重新设置一个不同的名称。
|
editor.save.overwrite = 您的地图覆盖了一个内置的地图!在“地图信息”菜单里重新设置一个不同的名称。
|
||||||
editor.import.exists = [scarlet]无法导入:[]存在名为“{0}”的内置地图!
|
editor.import.exists = [scarlet]无法导入:[]存在名为“{0}”的内置地图!
|
||||||
editor.import = 导入…
|
editor.import = 导入…
|
||||||
editor.importmap = 导入地图
|
editor.importmap = 导入地图
|
||||||
@@ -794,8 +794,8 @@ keybind.clear_building.name = 清除建筑
|
|||||||
keybind.press = 请按一个键…
|
keybind.press = 请按一个键…
|
||||||
keybind.press.axis = 请按一个轴或键…
|
keybind.press.axis = 请按一个轴或键…
|
||||||
keybind.screenshot.name = 地图截图
|
keybind.screenshot.name = 地图截图
|
||||||
keybind.toggle_power_lines.name = 显隐能量标识线
|
keybind.toggle_power_lines.name = 显示/隐藏能量标识线
|
||||||
keybind.toggle_block_status.name = 显隐方块状态
|
keybind.toggle_block_status.name = 显示/隐藏方块状态
|
||||||
keybind.move_x.name = 水平移动
|
keybind.move_x.name = 水平移动
|
||||||
keybind.move_y.name = 竖直移动
|
keybind.move_y.name = 竖直移动
|
||||||
keybind.mouse_move.name = 跟随鼠标
|
keybind.mouse_move.name = 跟随鼠标
|
||||||
@@ -922,36 +922,36 @@ liquid.oil.name = 石油
|
|||||||
liquid.cryofluid.name = 冷冻液
|
liquid.cryofluid.name = 冷冻液
|
||||||
|
|
||||||
unit.dagger.name = 尖刀
|
unit.dagger.name = 尖刀
|
||||||
unit.mace.name = 牙狼
|
unit.mace.name = 战锤
|
||||||
unit.fortress.name = 堡垒
|
unit.fortress.name = 堡垒
|
||||||
unit.nova.name = 新星
|
unit.nova.name = 新星
|
||||||
unit.pulsar.name = 脉冲星
|
unit.pulsar.name = 恒星
|
||||||
unit.quasar.name = 超星
|
unit.quasar.name = 超星
|
||||||
unit.crawler.name = 爬虫
|
unit.crawler.name = 爬虫
|
||||||
unit.atrax.name = 火蛛
|
unit.atrax.name = 毒蛛
|
||||||
unit.spiroct.name = 天蝎
|
unit.spiroct.name = 血蛭
|
||||||
unit.arkyid.name = 血蛭
|
unit.arkyid.name = 毒蛊
|
||||||
unit.toxopid.name = 毒蟒
|
unit.toxopid.name = 天蝎
|
||||||
unit.flare.name = 星耀
|
unit.flare.name = 星辉
|
||||||
unit.horizon.name = 天垠
|
unit.horizon.name = 天垠
|
||||||
unit.zenith.name = 苍穹
|
unit.zenith.name = 苍穹
|
||||||
unit.antumbra.name = 半影
|
unit.antumbra.name = 月影
|
||||||
unit.eclipse.name = 日蚀
|
unit.eclipse.name = 日蚀
|
||||||
unit.mono.name = 独影
|
unit.mono.name = 独影
|
||||||
unit.poly.name = 聚幻
|
unit.poly.name = 聚辉
|
||||||
unit.mega.name = 巨像
|
unit.mega.name = 巨灵
|
||||||
unit.quad.name = 雷霆
|
unit.quad.name = 雷霆
|
||||||
unit.oct.name = 要塞
|
unit.oct.name = 要塞
|
||||||
unit.risso.name = 梭鱼
|
unit.risso.name = 梭鱼
|
||||||
unit.minke.name = 刺鲸
|
unit.minke.name = 刺鲸
|
||||||
unit.bryde.name = 虎鲨
|
unit.bryde.name = 戟鲸
|
||||||
unit.sei.name = 湖妖
|
unit.sei.name = 水怪
|
||||||
unit.omura.name = 海神
|
unit.omura.name = 海神
|
||||||
unit.alpha.name = 阿尔法
|
unit.alpha.name = 沉思者
|
||||||
unit.beta.name = 贝塔
|
unit.beta.name = 贝塔
|
||||||
unit.gamma.name = 伽玛
|
unit.gamma.name = 伽马
|
||||||
unit.scepter.name = 权杖
|
unit.scepter.name = 权杖
|
||||||
unit.reign.name = 君王
|
unit.reign.name = 王座
|
||||||
unit.vela.name = 灾星
|
unit.vela.name = 灾星
|
||||||
unit.corvus.name = 死星
|
unit.corvus.name = 死星
|
||||||
|
|
||||||
@@ -1056,7 +1056,7 @@ block.conveyor.name = 传送带
|
|||||||
block.titanium-conveyor.name = 钛传送带
|
block.titanium-conveyor.name = 钛传送带
|
||||||
block.plastanium-conveyor.name = 塑钢传送带
|
block.plastanium-conveyor.name = 塑钢传送带
|
||||||
block.armored-conveyor.name = 装甲传送带
|
block.armored-conveyor.name = 装甲传送带
|
||||||
block.armored-conveyor.description = 运送物品,与钛传送带一样的速度,但有更强的装甲。除其他传送带,不接受任何边的输入。
|
block.armored-conveyor.description = 运送物品,与钛传送带一样的速度,但有更强的装甲。除其他传送带,不接受任何边上的输入。
|
||||||
block.junction.name = 连接器
|
block.junction.name = 连接器
|
||||||
block.router.name = 路由器
|
block.router.name = 路由器
|
||||||
block.distributor.name = 分配器
|
block.distributor.name = 分配器
|
||||||
@@ -1148,26 +1148,26 @@ block.launch-pad.name = 发射台
|
|||||||
block.launch-pad-large.name = 大型发射台
|
block.launch-pad-large.name = 大型发射台
|
||||||
block.segment.name = 裂解光束
|
block.segment.name = 裂解光束
|
||||||
block.command-center.name = 指挥中心
|
block.command-center.name = 指挥中心
|
||||||
block.ground-factory.name = 陆战单位工厂
|
block.ground-factory.name = 陆军工厂
|
||||||
block.air-factory.name = 空战单位工厂
|
block.air-factory.name = 空军工厂
|
||||||
block.naval-factory.name = 海战单位工厂
|
block.naval-factory.name = 海军工厂
|
||||||
block.additive-reconstructor.name = 数增级单位重构工厂
|
block.additive-reconstructor.name = 添改单位重构工厂
|
||||||
block.multiplicative-reconstructor.name = 倍增级单位重构工厂
|
block.multiplicative-reconstructor.name = 多倍单位重构工厂
|
||||||
block.exponential-reconstructor.name = 幂乘级单位重构工厂
|
block.exponential-reconstructor.name = 多幂级单位重构工厂
|
||||||
block.tetrative-reconstructor.name = 无量级单位重构工厂
|
block.tetrative-reconstructor.name = 实验性泰坦重构工厂
|
||||||
block.payload-conveyor.name = 载荷传送带
|
block.payload-conveyor.name = 载荷传送带
|
||||||
block.payload-router.name = 载荷路由器
|
block.payload-router.name = 载荷路由器
|
||||||
block.disassembler.name = 分离机
|
block.disassembler.name = 离心机
|
||||||
block.silicon-crucible.name = 热能坩埚
|
block.silicon-crucible.name = 硅坩埚
|
||||||
block.overdrive-dome.name = 超速场投射器
|
block.overdrive-dome.name = 超速穹顶投射器
|
||||||
|
|
||||||
block.switch.name = 开关
|
block.switch.name = 开关
|
||||||
block.micro-processor.name = 微型处理器
|
block.micro-processor.name = 微型处理器
|
||||||
block.logic-processor.name = 逻辑处理器
|
block.logic-processor.name = 逻辑处理器
|
||||||
block.hyper-processor.name = 超频处理器
|
block.hyper-processor.name = 超核处理器
|
||||||
block.logic-display.name = 逻辑显示屏
|
block.logic-display.name = 逻辑显示屏
|
||||||
block.large-logic-display.name = 大型逻辑显示屏
|
block.large-logic-display.name = 大型逻辑显示屏
|
||||||
block.memory-cell.name = 存储单元
|
block.memory-cell.name = 内存单位
|
||||||
block.memory-bank.name = Memory Bank
|
block.memory-bank.name = Memory Bank
|
||||||
|
|
||||||
team.blue.name = 蓝
|
team.blue.name = 蓝
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 562 KiB After Width: | Height: | Size: 556 KiB |
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 185 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@@ -36,8 +36,8 @@ public class Vars implements Loadable{
|
|||||||
public static boolean loadLocales = true;
|
public static boolean loadLocales = true;
|
||||||
/** Whether the logger is loaded. */
|
/** Whether the logger is loaded. */
|
||||||
public static boolean loadedLogger = false, loadedFileLogger = false;
|
public static boolean loadedLogger = false, loadedFileLogger = false;
|
||||||
/** Whether to show the cliff button in the editor*/
|
/** Whether to enable various experimental features (e.g. cliffs) */
|
||||||
public static boolean addCliffButton = false;
|
public static boolean experimental = false;
|
||||||
/** Maximum extra padding around deployment schematics. */
|
/** Maximum extra padding around deployment schematics. */
|
||||||
public static final int maxLoadoutSchematicPad = 5;
|
public static final int maxLoadoutSchematicPad = 5;
|
||||||
/** Maximum schematic size.*/
|
/** Maximum schematic size.*/
|
||||||
|
|||||||
@@ -312,6 +312,28 @@ public class BlockIndexer{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Find the closest ore block relative to a position. */
|
||||||
|
public Tile findClosestOre(Unit unit, Item item){
|
||||||
|
if(!(unit instanceof Minerc miner)) return null;
|
||||||
|
|
||||||
|
TileArray arr = getOrePositions(item);
|
||||||
|
|
||||||
|
arr.tiles.sort(t -> t.dst2(unit.x, unit.y));
|
||||||
|
|
||||||
|
for(Tile tile : arr.tiles){
|
||||||
|
for(int x = Math.max(0, tile.x - quadrantSize / 2); x < tile.x + quadrantSize / 2 && x < world.width(); x++){
|
||||||
|
for(int y = Math.max(0, tile.y - quadrantSize / 2); y < tile.y + quadrantSize / 2 && y < world.height(); y++){
|
||||||
|
Tile res = world.tile(x, y);
|
||||||
|
if(res.drop() == item && miner.validMine(res, false)){
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return extra unit cap of a team. This is added onto the base value. */
|
/** @return extra unit cap of a team. This is added onto the base value. */
|
||||||
public int getExtraUnits(Team team){
|
public int getExtraUnits(Team team){
|
||||||
return unitCaps[team.id];
|
return unitCaps[team.id];
|
||||||
@@ -457,8 +479,8 @@ public class BlockIndexer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class TileArray implements Iterable<Tile>{
|
public static class TileArray implements Iterable<Tile>{
|
||||||
private Seq<Tile> tiles = new Seq<>(false, 16);
|
Seq<Tile> tiles = new Seq<>(false, 16);
|
||||||
private IntSet contained = new IntSet();
|
IntSet contained = new IntSet();
|
||||||
|
|
||||||
public void add(Tile tile){
|
public void add(Tile tile){
|
||||||
if(contained.add(tile.pos())){
|
if(contained.add(tile.pos())){
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class LogicAI extends AIController{
|
public class LogicAI extends AIController{
|
||||||
/** Minimum delay between item transfers. */
|
/** Minimum delay between item transfers. */
|
||||||
public static final float transferDelay = 60f * 3f;
|
public static final float transferDelay = 60f * 2f;
|
||||||
/** Time after which the unit resets its controlled and reverts to a normal unit. */
|
/** Time after which the unit resets its controlled and reverts to a normal unit. */
|
||||||
public static final float logicControlTimeout = 10f * 60f;
|
public static final float logicControlTimeout = 10f * 60f;
|
||||||
|
|
||||||
@@ -44,8 +44,8 @@ public class LogicAI extends AIController{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateMovement(){
|
protected void updateMovement(){
|
||||||
if(itemTimer > 0) itemTimer -= Time.delta;
|
if(itemTimer >= 0) itemTimer -= Time.delta;
|
||||||
if(payTimer > 0) payTimer -= Time.delta;
|
if(payTimer >= 0) payTimer -= Time.delta;
|
||||||
|
|
||||||
if(targetTimer > 0f){
|
if(targetTimer > 0f){
|
||||||
targetTimer -= Time.delta;
|
targetTimer -= Time.delta;
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public class MinerAI extends AIController{
|
|||||||
if(unit.stack.amount >= unit.type.itemCapacity || (targetItem != null && !unit.acceptsItem(targetItem))){
|
if(unit.stack.amount >= unit.type.itemCapacity || (targetItem != null && !unit.acceptsItem(targetItem))){
|
||||||
mining = false;
|
mining = false;
|
||||||
}else{
|
}else{
|
||||||
if(retarget() && targetItem != null){
|
if(timer.get(timerTarget, 60) && targetItem != null){
|
||||||
ore = indexer.findClosestOre(unit.x, unit.y, targetItem);
|
ore = indexer.findClosestOre(unit, targetItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ore != null){
|
if(ore != null){
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public class Blocks implements ContentList{
|
|||||||
alwaysReplace = true;
|
alwaysReplace = true;
|
||||||
hasShadow = false;
|
hasShadow = false;
|
||||||
useColor = false;
|
useColor = false;
|
||||||
|
wall = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void drawBase(Tile tile){}
|
@Override public void drawBase(Tile tile){}
|
||||||
@@ -1651,17 +1652,19 @@ public class Blocks implements ContentList{
|
|||||||
float brange = range + 10f;
|
float brange = range + 10f;
|
||||||
|
|
||||||
ammo(
|
ammo(
|
||||||
Items.thorium, new ShrapnelBulletType(){{
|
|
||||||
length = brange;
|
|
||||||
damage = 105f;
|
|
||||||
ammoMultiplier = 5f;
|
|
||||||
}},
|
|
||||||
Items.titanium, new ShrapnelBulletType(){{
|
Items.titanium, new ShrapnelBulletType(){{
|
||||||
length = brange;
|
length = brange;
|
||||||
damage = 66f;
|
damage = 66f;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
width = 17f;
|
width = 17f;
|
||||||
reloadMultiplier = 1.3f;
|
reloadMultiplier = 1.3f;
|
||||||
|
}},
|
||||||
|
Items.thorium, new ShrapnelBulletType(){{
|
||||||
|
length = brange;
|
||||||
|
damage = 105f;
|
||||||
|
ammoMultiplier = 5f;
|
||||||
|
toColor = Pal.thoriumPink;
|
||||||
|
shootEffect = smokeEffect = Fx.thoriumShoot;
|
||||||
}}
|
}}
|
||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
@@ -2034,7 +2037,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
microProcessor = new LogicBlock("micro-processor"){{
|
microProcessor = new LogicBlock("micro-processor"){{
|
||||||
requirements(Category.logic, with(Items.copper, 80, Items.lead, 50, Items.silicon, 50));
|
requirements(Category.logic, with(Items.copper, 80, Items.lead, 50, Items.silicon, 30));
|
||||||
|
|
||||||
instructionsPerTick = 2;
|
instructionsPerTick = 2;
|
||||||
|
|
||||||
@@ -2042,7 +2045,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
logicProcessor = new LogicBlock("logic-processor"){{
|
logicProcessor = new LogicBlock("logic-processor"){{
|
||||||
requirements(Category.logic, with(Items.lead, 320, Items.silicon, 100, Items.graphite, 60, Items.thorium, 50));
|
requirements(Category.logic, with(Items.lead, 320, Items.silicon, 60, Items.graphite, 60, Items.thorium, 50));
|
||||||
|
|
||||||
instructionsPerTick = 8;
|
instructionsPerTick = 8;
|
||||||
|
|
||||||
@@ -2052,7 +2055,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
hyperProcessor = new LogicBlock("hyper-processor"){{
|
hyperProcessor = new LogicBlock("hyper-processor"){{
|
||||||
requirements(Category.logic, with(Items.lead, 450, Items.silicon, 150, Items.thorium, 75, Items.surgeAlloy, 50));
|
requirements(Category.logic, with(Items.lead, 450, Items.silicon, 130, Items.thorium, 75, Items.surgeAlloy, 50));
|
||||||
|
|
||||||
consumes.liquid(Liquids.cryofluid, 0.08f);
|
consumes.liquid(Liquids.cryofluid, 0.08f);
|
||||||
hasLiquids = true;
|
hasLiquids = true;
|
||||||
|
|||||||
@@ -1217,7 +1217,15 @@ public class Fx{
|
|||||||
randLenVectors(e.id, 7, 25f * e.finpow(), e.rotation, 50f, (x, y) -> {
|
randLenVectors(e.id, 7, 25f * e.finpow(), e.rotation, 50f, (x, y) -> {
|
||||||
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 5f + 2f);
|
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 5f + 2f);
|
||||||
});
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
thoriumShoot = new Effect(12f, e -> {
|
||||||
|
color(Color.white, Pal.thoriumPink, e.fin());
|
||||||
|
stroke(e.fout() * 1.2f + 0.5f);
|
||||||
|
|
||||||
|
randLenVectors(e.id, 7, 25f * e.finpow(), e.rotation, 50f, (x, y) -> {
|
||||||
|
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 5f + 2f);
|
||||||
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
reactorsmoke = new Effect(17, e -> {
|
reactorsmoke = new Effect(17, e -> {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ public class SectorPresets implements ContentList{
|
|||||||
|
|
||||||
groundZero = new SectorPreset("groundZero", serpulo, 15){{
|
groundZero = new SectorPreset("groundZero", serpulo, 15){{
|
||||||
alwaysUnlocked = true;
|
alwaysUnlocked = true;
|
||||||
|
addStartingItems = true;
|
||||||
captureWave = 10;
|
captureWave = 10;
|
||||||
difficulty = 1;
|
difficulty = 1;
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import arc.math.*;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -18,6 +20,7 @@ public class StatusEffects implements ContentList{
|
|||||||
none = new StatusEffect("none");
|
none = new StatusEffect("none");
|
||||||
|
|
||||||
burning = new StatusEffect("burning"){{
|
burning = new StatusEffect("burning"){{
|
||||||
|
color = Pal.lightFlame;
|
||||||
damage = 0.12f; //over 8 seconds, this would be 60 damage
|
damage = 0.12f; //over 8 seconds, this would be 60 damage
|
||||||
effect = Fx.burning;
|
effect = Fx.burning;
|
||||||
|
|
||||||
@@ -32,6 +35,7 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
freezing = new StatusEffect("freezing"){{
|
freezing = new StatusEffect("freezing"){{
|
||||||
|
color = Color.valueOf("6ecdec");
|
||||||
speedMultiplier = 0.6f;
|
speedMultiplier = 0.6f;
|
||||||
healthMultiplier = 0.8f;
|
healthMultiplier = 0.8f;
|
||||||
effect = Fx.freezing;
|
effect = Fx.freezing;
|
||||||
@@ -47,10 +51,12 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
unmoving = new StatusEffect("unmoving"){{
|
unmoving = new StatusEffect("unmoving"){{
|
||||||
|
color = Pal.gray;
|
||||||
speedMultiplier = 0.001f;
|
speedMultiplier = 0.001f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
slow = new StatusEffect("slow"){{
|
slow = new StatusEffect("slow"){{
|
||||||
|
color = Pal.lightishGray;
|
||||||
speedMultiplier = 0.4f;
|
speedMultiplier = 0.4f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -80,6 +86,7 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
melting = new StatusEffect("melting"){{
|
melting = new StatusEffect("melting"){{
|
||||||
|
color = Color.valueOf("ffa166");
|
||||||
speedMultiplier = 0.8f;
|
speedMultiplier = 0.8f;
|
||||||
healthMultiplier = 0.8f;
|
healthMultiplier = 0.8f;
|
||||||
damage = 0.3f;
|
damage = 0.3f;
|
||||||
@@ -92,6 +99,7 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
sapped = new StatusEffect("sapped"){{
|
sapped = new StatusEffect("sapped"){{
|
||||||
|
color = Pal.sap;
|
||||||
speedMultiplier = 0.7f;
|
speedMultiplier = 0.7f;
|
||||||
healthMultiplier = 0.8f;
|
healthMultiplier = 0.8f;
|
||||||
effect = Fx.sapped;
|
effect = Fx.sapped;
|
||||||
@@ -99,12 +107,14 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
sporeSlowed = new StatusEffect("spore-slowed"){{
|
sporeSlowed = new StatusEffect("spore-slowed"){{
|
||||||
|
color = Pal.spore;
|
||||||
speedMultiplier = 0.8f;
|
speedMultiplier = 0.8f;
|
||||||
effect = Fx.sapped;
|
effect = Fx.sapped;
|
||||||
effectChance = 0.04f;
|
effectChance = 0.04f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
tarred = new StatusEffect("tarred"){{
|
tarred = new StatusEffect("tarred"){{
|
||||||
|
color = Color.valueOf("313131");
|
||||||
speedMultiplier = 0.6f;
|
speedMultiplier = 0.6f;
|
||||||
effect = Fx.oily;
|
effect = Fx.oily;
|
||||||
|
|
||||||
@@ -115,6 +125,7 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
overdrive = new StatusEffect("overdrive"){{
|
overdrive = new StatusEffect("overdrive"){{
|
||||||
|
color = Pal.accent;
|
||||||
healthMultiplier = 0.95f;
|
healthMultiplier = 0.95f;
|
||||||
speedMultiplier = 1.15f;
|
speedMultiplier = 1.15f;
|
||||||
damageMultiplier = 1.4f;
|
damageMultiplier = 1.4f;
|
||||||
@@ -124,6 +135,7 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
overclock = new StatusEffect("overclock"){{
|
overclock = new StatusEffect("overclock"){{
|
||||||
|
color = Pal.accent;
|
||||||
speedMultiplier = 1.15f;
|
speedMultiplier = 1.15f;
|
||||||
damageMultiplier = 1.15f;
|
damageMultiplier = 1.15f;
|
||||||
reloadMultiplier = 1.25f;
|
reloadMultiplier = 1.25f;
|
||||||
@@ -132,20 +144,27 @@ public class StatusEffects implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
shielded = new StatusEffect("shielded"){{
|
shielded = new StatusEffect("shielded"){{
|
||||||
|
color = Pal.accent;
|
||||||
healthMultiplier = 3f;
|
healthMultiplier = 3f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
boss = new StatusEffect("boss"){{
|
boss = new StatusEffect("boss"){{
|
||||||
|
color = Pal.health;
|
||||||
permanent = true;
|
permanent = true;
|
||||||
damageMultiplier = 2f;
|
damageMultiplier = 2f;
|
||||||
healthMultiplier = 2f;
|
healthMultiplier = 2f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
shocked = new StatusEffect("shocked");
|
shocked = new StatusEffect("shocked"){{
|
||||||
|
color = Pal.lancerLaser;
|
||||||
|
}};
|
||||||
|
|
||||||
blasted = new StatusEffect("blasted");
|
blasted = new StatusEffect("blasted"){{
|
||||||
|
color = Color.valueOf("ff795e");
|
||||||
|
}};
|
||||||
|
|
||||||
corroded = new StatusEffect("corroded"){{
|
corroded = new StatusEffect("corroded"){{
|
||||||
|
color = Pal.plastanium;
|
||||||
damage = 0.1f;
|
damage = 0.1f;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1200,7 +1200,7 @@ public class UnitTypes implements ContentList{
|
|||||||
mineTier = 3;
|
mineTier = 3;
|
||||||
health = 500;
|
health = 500;
|
||||||
armor = 5f;
|
armor = 5f;
|
||||||
speed = 2.3f;
|
speed = 2.4f;
|
||||||
accel = 0.06f;
|
accel = 0.06f;
|
||||||
drag = 0.017f;
|
drag = 0.017f;
|
||||||
lowAltitude = true;
|
lowAltitude = true;
|
||||||
@@ -1770,6 +1770,7 @@ public class UnitTypes implements ContentList{
|
|||||||
health = 1;
|
health = 1;
|
||||||
rotateSpeed = 360f;
|
rotateSpeed = 360f;
|
||||||
itemCapacity = 0;
|
itemCapacity = 0;
|
||||||
|
commandLimit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class Weathers implements ContentList{
|
|||||||
minAlpha = 0f;
|
minAlpha = 0f;
|
||||||
maxAlpha = 0.2f;
|
maxAlpha = 0.2f;
|
||||||
density = 1500f;
|
density = 1500f;
|
||||||
baseSpeed = 6.1f;
|
baseSpeed = 5.4f;
|
||||||
attrs.set(Attribute.light, -0.1f);
|
attrs.set(Attribute.light, -0.1f);
|
||||||
attrs.set(Attribute.water, -0.1f);
|
attrs.set(Attribute.water, -0.1f);
|
||||||
opacityMultiplier = 0.8f;
|
opacityMultiplier = 0.8f;
|
||||||
|
|||||||
@@ -181,6 +181,12 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
Time.run(Fx.coreLand.lifetime, () -> {
|
Time.run(Fx.coreLand.lifetime, () -> {
|
||||||
Fx.launch.at(core);
|
Fx.launch.at(core);
|
||||||
Effect.shake(5f, 5f, core);
|
Effect.shake(5f, 5f, core);
|
||||||
|
|
||||||
|
if(state.isCampaign()){
|
||||||
|
ui.announce("[accent]" + state.rules.sector.name() + "\n" +
|
||||||
|
(state.rules.sector.info.resources.any() ? "[lightgray]" + bundle.get("sectors.resources") + "[white] " +
|
||||||
|
state.rules.sector.info.resources.toString(" ", u -> u.emoji()) : ""), 5);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -264,7 +270,6 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
slot.load();
|
slot.load();
|
||||||
slot.setAutosave(true);
|
slot.setAutosave(true);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
state.secinfo = state.rules.sector.info;
|
|
||||||
|
|
||||||
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
//if there is no base, simulate a new game and place the right loadout at the spawn position
|
||||||
if(state.rules.defaultTeam.cores().isEmpty()){
|
if(state.rules.defaultTeam.cores().isEmpty()){
|
||||||
@@ -282,8 +287,12 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
//reset wave so things are more fair
|
//reset wave so things are more fair
|
||||||
state.wave = 1;
|
state.wave = 1;
|
||||||
|
|
||||||
|
//reset win wave??
|
||||||
|
state.rules.winWave = sector.preset != null ? sector.preset.captureWave : 40;
|
||||||
|
|
||||||
//kill all units, since they should be dead anwyay
|
//kill all units, since they should be dead anwyay
|
||||||
Groups.unit.clear();
|
Groups.unit.clear();
|
||||||
|
Groups.fire.clear();
|
||||||
|
|
||||||
Tile spawn = world.tile(sector.info.spawnPosition);
|
Tile spawn = world.tile(sector.info.spawnPosition);
|
||||||
Schematics.placeLaunchLoadout(spawn.x, spawn.y);
|
Schematics.placeLaunchLoadout(spawn.x, spawn.y);
|
||||||
@@ -311,8 +320,8 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
world.loadSector(sector);
|
world.loadSector(sector);
|
||||||
state.rules.sector = sector;
|
state.rules.sector = sector;
|
||||||
//assign origin when launching
|
//assign origin when launching
|
||||||
state.secinfo.origin = origin;
|
sector.info.origin = origin;
|
||||||
state.secinfo.destination = origin;
|
sector.info.destination = origin;
|
||||||
logic.play();
|
logic.play();
|
||||||
control.saves.saveSector(sector);
|
control.saves.saveSector(sector);
|
||||||
Events.fire(Trigger.newGame);
|
Events.fire(Trigger.newGame);
|
||||||
@@ -403,13 +412,15 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause(){
|
public void pause(){
|
||||||
|
if(settings.getBool("backgroundpause", true)){
|
||||||
wasPaused = state.is(State.paused);
|
wasPaused = state.is(State.paused);
|
||||||
if(state.is(State.playing)) state.set(State.paused);
|
if(state.is(State.playing)) state.set(State.paused);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resume(){
|
public void resume(){
|
||||||
if(state.is(State.paused) && !wasPaused){
|
if(state.is(State.paused) && !wasPaused && settings.getBool("backgroundpause", true)){
|
||||||
state.set(State.playing);
|
state.set(State.playing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ public class GameState{
|
|||||||
public GameStats stats = new GameStats();
|
public GameStats stats = new GameStats();
|
||||||
/** Global attributes of the environment, calculated by weather. */
|
/** Global attributes of the environment, calculated by weather. */
|
||||||
public Attributes envAttrs = new Attributes();
|
public Attributes envAttrs = new Attributes();
|
||||||
/** Sector information. Only valid in the campaign. */
|
|
||||||
public SectorInfo secinfo = new SectorInfo();
|
|
||||||
/** Team data. Gets reset every new game. */
|
/** Team data. Gets reset every new game. */
|
||||||
public Teams teams = new Teams();
|
public Teams teams = new Teams();
|
||||||
/** Number of enemies in the game; only used clientside in servers. */
|
/** Number of enemies in the game; only used clientside in servers. */
|
||||||
|
|||||||
@@ -55,15 +55,14 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(LaunchItemEvent.class, e -> state.secinfo.handleItemExport(e.stack));
|
|
||||||
|
|
||||||
//when loading a 'damaged' sector, propagate the damage
|
//when loading a 'damaged' sector, propagate the damage
|
||||||
Events.on(SaveLoadEvent.class, e -> {
|
Events.on(SaveLoadEvent.class, e -> {
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.write();
|
SectorInfo info = state.rules.sector.info;
|
||||||
|
info.write();
|
||||||
|
|
||||||
//how much wave time has passed
|
//how much wave time has passed
|
||||||
int wavesPassed = state.secinfo.wavesPassed;
|
int wavesPassed = info.wavesPassed;
|
||||||
|
|
||||||
//wave has passed, remove all enemies, they are assumed to be dead
|
//wave has passed, remove all enemies, they are assumed to be dead
|
||||||
if(wavesPassed > 0){
|
if(wavesPassed > 0){
|
||||||
@@ -84,10 +83,10 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//reset values
|
//reset values
|
||||||
state.secinfo.damage = 0f;
|
info.damage = 0f;
|
||||||
state.secinfo.wavesPassed = 0;
|
info.wavesPassed = 0;
|
||||||
state.secinfo.hasCore = true;
|
info.hasCore = true;
|
||||||
state.secinfo.secondsPassed = 0;
|
info.secondsPassed = 0;
|
||||||
|
|
||||||
state.rules.sector.saveInfo();
|
state.rules.sector.saveInfo();
|
||||||
}
|
}
|
||||||
@@ -273,7 +272,7 @@ public class Logic implements ApplicationListener{
|
|||||||
state.teams.updateTeamStats();
|
state.teams.updateTeamStats();
|
||||||
|
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.update();
|
state.rules.sector.info.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
|
|||||||
@@ -293,6 +293,13 @@ public class NetClient implements ApplicationListener{
|
|||||||
setHudText(message);
|
setHudText(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Remote(variants = Variant.both)
|
||||||
|
public static void announce(String message){
|
||||||
|
if(message == null) return;
|
||||||
|
|
||||||
|
ui.announce(message);
|
||||||
|
}
|
||||||
|
|
||||||
@Remote(variants = Variant.both)
|
@Remote(variants = Variant.both)
|
||||||
public static void infoMessage(String message){
|
public static void infoMessage(String message){
|
||||||
if(message == null) return;
|
if(message == null) return;
|
||||||
|
|||||||
@@ -378,6 +378,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
cont.add(text).pad(2f).growX().wrap().get().setAlignment(Align.center);
|
cont.add(text).pad(2f).growX().wrap().get().setAlignment(Align.center);
|
||||||
cont.row();
|
cont.row();
|
||||||
cont.button("@ok", this::hide).size(120, 50).pad(4);
|
cont.button("@ok", this::hide).size(120, 50).pad(4);
|
||||||
|
closeOnBack();
|
||||||
}}.show();
|
}}.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,6 +406,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
cont.button("@ok", this::hide).size(110, 50).fillX().left();
|
cont.button("@ok", this::hide).size(110, 50).fillX().left();
|
||||||
cont.row();
|
cont.row();
|
||||||
cont.add(col).colspan(2).pad(2);
|
cont.add(col).colspan(2).pad(2);
|
||||||
|
closeOnBack();
|
||||||
}}.show();
|
}}.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,6 +422,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
cont.add(text).width(400f).wrap().get().setAlignment(align, align);
|
cont.add(text).width(400f).wrap().get().setAlignment(align, align);
|
||||||
cont.row();
|
cont.row();
|
||||||
buttons.button("@ok", this::hide).size(110, 50).pad(4);
|
buttons.button("@ok", this::hide).size(110, 50).pad(4);
|
||||||
|
closeOnBack();
|
||||||
}}.show();
|
}}.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,6 +430,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
new Dialog(titleText){{
|
new Dialog(titleText){{
|
||||||
cont.margin(15).add(text).width(400f).wrap().left().get().setAlignment(Align.left, Align.left);
|
cont.margin(15).add(text).width(400f).wrap().left().get().setAlignment(Align.left, Align.left);
|
||||||
buttons.button("@ok", this::hide).size(110, 50).pad(4);
|
buttons.button("@ok", this::hide).size(110, 50).pad(4);
|
||||||
|
closeOnBack();
|
||||||
}}.show();
|
}}.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,6 +440,7 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
titleTable.row();
|
titleTable.row();
|
||||||
titleTable.image().color(Pal.accent).height(3f).growX().pad(2f);
|
titleTable.image().color(Pal.accent).height(3f).growX().pad(2f);
|
||||||
buttons.button("@ok", this::hide).size(110, 50).pad(4);
|
buttons.button("@ok", this::hide).size(110, 50).pad(4);
|
||||||
|
closeOnBack();
|
||||||
}}.show();
|
}}.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,13 +492,19 @@ public class UI implements ApplicationListener, Loadable{
|
|||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Display text in the middle of the screen, then fade out. */
|
||||||
public void announce(String text){
|
public void announce(String text){
|
||||||
Table t = new Table();
|
announce(text, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Display text in the middle of the screen, then fade out. */
|
||||||
|
public void announce(String text, float duration){
|
||||||
|
Table t = new Table(Styles.black3);
|
||||||
t.touchable = Touchable.disabled;
|
t.touchable = Touchable.disabled;
|
||||||
t.background(Styles.black3).margin(8f)
|
t.margin(8f).add(text).style(Styles.outlineLabel).labelAlign(Align.center);
|
||||||
.add(text).style(Styles.outlineLabel).labelAlign(Align.center);
|
|
||||||
t.update(() -> t.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight()/2f, Align.center));
|
t.update(() -> t.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight()/2f, Align.center));
|
||||||
t.actions(Actions.fadeOut(3, Interp.pow4In), Actions.remove());
|
t.actions(Actions.fadeOut(duration, Interp.pow4In), Actions.remove());
|
||||||
|
t.pack();
|
||||||
Core.scene.add(t);
|
Core.scene.add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -570,7 +570,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
}).growX().top();
|
}).growX().top();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addCliffButton){
|
if(experimental){
|
||||||
mid.row();
|
mid.row();
|
||||||
|
|
||||||
mid.table(t -> {
|
mid.table(t -> {
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ public class WaveInfoDialog extends BaseDialog{
|
|||||||
super("@waves.title");
|
super("@waves.title");
|
||||||
|
|
||||||
shown(this::setup);
|
shown(this::setup);
|
||||||
hidden(() -> {
|
hidden(() -> state.rules.spawns = groups);
|
||||||
state.rules.spawns = groups;
|
|
||||||
});
|
|
||||||
|
|
||||||
addCloseListener();
|
addCloseListener();
|
||||||
|
|
||||||
@@ -96,6 +94,14 @@ public class WaveInfoDialog extends BaseDialog{
|
|||||||
view(1);
|
view(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(experimental){
|
||||||
|
buttons.button("Random", Icon.refresh, () -> {
|
||||||
|
groups.clear();
|
||||||
|
groups = DefaultWaves.generate(1f / 10f);
|
||||||
|
updateWaves();
|
||||||
|
}).width(200f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void view(int amount){
|
void view(int amount){
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ class GroupDefs<G>{
|
|||||||
@GroupDef(value = Buildingc.class) G build;
|
@GroupDef(value = Buildingc.class) G build;
|
||||||
@GroupDef(value = Syncc.class, mapping = true) G sync;
|
@GroupDef(value = Syncc.class, mapping = true) G sync;
|
||||||
@GroupDef(value = Drawc.class) G draw;
|
@GroupDef(value = Drawc.class) G draw;
|
||||||
|
@GroupDef(value = Firec.class) G fire;
|
||||||
@GroupDef(value = WeatherStatec.class) G weather;
|
@GroupDef(value = WeatherStatec.class) G weather;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -869,7 +869,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
public void placed(){
|
public void placed(){
|
||||||
if(net.client()) return;
|
if(net.client()) return;
|
||||||
|
|
||||||
if((block.consumesPower && !block.outputsPower) || (!block.consumesPower && block.outputsPower)){
|
if(block.consumesPower || block.outputsPower){
|
||||||
int range = 10;
|
int range = 10;
|
||||||
tempTiles.clear();
|
tempTiles.clear();
|
||||||
Geometry.circle(tileX(), tileY(), range, (x, y) -> {
|
Geometry.circle(tileX(), tileY(), range, (x, y) -> {
|
||||||
@@ -1319,7 +1319,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void control(LAccess type, Object p1, double p2, double p3, double p4){
|
public void control(LAccess type, Object p1, double p2, double p3, double p4){
|
||||||
|
if(type == LAccess.configure && block.logicConfigurable){
|
||||||
|
//change config only if it's new
|
||||||
|
Object prev = senseObject(LAccess.config);
|
||||||
|
if(prev != p1){
|
||||||
|
configureAny(p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,12 +32,16 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean mining(){
|
boolean mining(){
|
||||||
return mineTile != null && !(((Object)this) instanceof Builderc && ((Builderc)(Object)this).activelyBuilding());
|
return mineTile != null && !(((Object)this) instanceof Builderc b && b.activelyBuilding());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validMine(Tile tile, boolean checkDst){
|
||||||
|
return !(tile == null || tile.block() != Blocks.air || (!within(tile.worldx(), tile.worldy(), miningRange) && checkDst)
|
||||||
|
|| tile.drop() == null || !canMine(tile.drop())) && state.teams.canMine(self(), tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validMine(Tile tile){
|
public boolean validMine(Tile tile){
|
||||||
return !(tile == null || tile.block() != Blocks.air || !within(tile.worldx(), tile.worldy(), miningRange)
|
return validMine(tile, true);
|
||||||
|| tile.drop() == null || !canMine(tile.drop()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,6 +62,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTile = null;
|
mineTile = null;
|
||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}else if(mining()){
|
}else if(mining()){
|
||||||
|
state.teams.registerMined(mineTile, self());
|
||||||
Item item = mineTile.drop();
|
Item item = mineTile.drop();
|
||||||
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
lookAt(angleTo(mineTile.worldx(), mineTile.worldy()));
|
||||||
mineTimer += Time.delta *type.mineSpeed;
|
mineTimer += Time.delta *type.mineSpeed;
|
||||||
@@ -84,8 +89,6 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{
|
|||||||
mineTimer = 0f;
|
mineTimer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
|||||||
team = state.rules.defaultTeam;
|
team = state.rules.defaultTeam;
|
||||||
admin = typing = false;
|
admin = typing = false;
|
||||||
textFadeTime = 0f;
|
textFadeTime = 0f;
|
||||||
|
x = y = 0f;
|
||||||
if(!dead()){
|
if(!dead()){
|
||||||
unit.controller(unit.type.createController());
|
unit.controller(unit.type.createController());
|
||||||
unit = Nulls.unit;
|
unit = Nulls.unit;
|
||||||
|
|||||||
@@ -114,13 +114,14 @@ abstract class StatusComp implements Posc, Flyingc{
|
|||||||
StatusEntry entry = statuses.get(index++);
|
StatusEntry entry = statuses.get(index++);
|
||||||
|
|
||||||
entry.time = Math.max(entry.time - Time.delta, 0);
|
entry.time = Math.max(entry.time - Time.delta, 0);
|
||||||
applied.set(entry.effect.id);
|
|
||||||
|
|
||||||
if(entry.time <= 0 && !entry.effect.permanent){
|
if(entry.effect == null || (entry.time <= 0 && !entry.effect.permanent)){
|
||||||
Pools.free(entry);
|
Pools.free(entry);
|
||||||
index --;
|
index --;
|
||||||
statuses.remove(index);
|
statuses.remove(index);
|
||||||
}else{
|
}else{
|
||||||
|
applied.set(entry.effect.id);
|
||||||
|
|
||||||
speedMultiplier *= entry.effect.speedMultiplier;
|
speedMultiplier *= entry.effect.speedMultiplier;
|
||||||
healthMultiplier *= entry.effect.healthMultiplier;
|
healthMultiplier *= entry.effect.healthMultiplier;
|
||||||
damageMultiplier *= entry.effect.damageMultiplier;
|
damageMultiplier *= entry.effect.damageMultiplier;
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean retarget(){
|
protected boolean retarget(){
|
||||||
return timer.get(timerTarget, 30);
|
return timer.get(timerTarget, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
|
||||||
|
|||||||
@@ -262,9 +262,7 @@ public class DefaultWaves{
|
|||||||
{dagger, mace, fortress, scepter, reign},
|
{dagger, mace, fortress, scepter, reign},
|
||||||
{nova, pulsar, quasar, vela, corvus},
|
{nova, pulsar, quasar, vela, corvus},
|
||||||
{crawler, atrax, spiroct, arkyid, toxopid},
|
{crawler, atrax, spiroct, arkyid, toxopid},
|
||||||
//{risso, minke, bryde, sei, omura}, //questionable choices
|
{flare, horizon, rand.chance(0.2) && difficulty > 0.5 ? poly : zenith, rand.chance(0.5) ? quad : antumbra, rand.chance(0.1) ? quad : eclipse}
|
||||||
{flare, horizon, difficulty > 0.5 ? poly : zenith, quad, quad},
|
|
||||||
{flare, horizon, zenith, antumbra, eclipse}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//required progression:
|
//required progression:
|
||||||
@@ -276,6 +274,7 @@ public class DefaultWaves{
|
|||||||
int cap = 150;
|
int cap = 150;
|
||||||
|
|
||||||
float shieldStart = 30, shieldsPerWave = 20 + difficulty*30f;
|
float shieldStart = 30, shieldsPerWave = 20 + difficulty*30f;
|
||||||
|
float[] scaling = {1, 1, 1.5f, 3f, 4f};
|
||||||
|
|
||||||
Intc createProgression = start -> {
|
Intc createProgression = start -> {
|
||||||
//main sequence
|
//main sequence
|
||||||
@@ -284,18 +283,19 @@ public class DefaultWaves{
|
|||||||
|
|
||||||
for(int i = start; i < cap;){
|
for(int i = start; i < cap;){
|
||||||
int f = i;
|
int f = i;
|
||||||
int next = rand.random(8, 16);
|
int next = rand.random(8, 16) + curTier * 4;
|
||||||
|
|
||||||
float shieldAmount = Math.max((i - shieldStart) * shieldsPerWave, 0);
|
float shieldAmount = Math.max((i - shieldStart) * shieldsPerWave, 0);
|
||||||
int space = start == 0 ? 1 : rand.random(1, 2);
|
int space = start == 0 ? 1 : rand.random(1, 2);
|
||||||
|
int ctier = curTier;
|
||||||
|
|
||||||
//main progression
|
//main progression
|
||||||
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
||||||
unitAmount = f == 0 ? 1 : 10;
|
unitAmount = f == start ? 1 : 6 / (int)scaling[ctier];
|
||||||
begin = f;
|
begin = f;
|
||||||
end = f + next >= cap ? never : f + next;
|
end = f + next >= cap ? never : f + next;
|
||||||
max = 14;
|
max = 14;
|
||||||
unitScaling = rand.random(1f, 3f);
|
unitScaling = (difficulty < 0.4f ? rand.random(2f, 4f) : rand.random(1f, 3f)) * scaling[ctier];
|
||||||
shields = shieldAmount;
|
shields = shieldAmount;
|
||||||
shieldScaling = shieldsPerWave;
|
shieldScaling = shieldsPerWave;
|
||||||
spacing = space;
|
spacing = space;
|
||||||
@@ -303,18 +303,18 @@ public class DefaultWaves{
|
|||||||
|
|
||||||
//extra progression that tails out, blends in
|
//extra progression that tails out, blends in
|
||||||
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
||||||
unitAmount = 6;
|
unitAmount = 3 / (int)scaling[ctier];
|
||||||
begin = f + next;
|
begin = f + next - 1;
|
||||||
end = f + next + rand.random(8, 12);
|
end = f + next + rand.random(6, 10);
|
||||||
max = 11;
|
max = 6;
|
||||||
unitScaling = rand.random(2f);
|
unitScaling = rand.random(1f, 2f);
|
||||||
spacing = rand.random(2, 3);
|
spacing = rand.random(2, 4);
|
||||||
shields = shieldAmount;
|
shields = shieldAmount/2f;
|
||||||
shieldScaling = shieldsPerWave;
|
shieldScaling = shieldsPerWave;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
i += next;
|
i += next + 1;
|
||||||
if(curTier < 3 || rand.chance(0.2)){
|
if(curTier < 3 || rand.chance(0.05)){
|
||||||
curTier ++;
|
curTier ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,11 +330,11 @@ public class DefaultWaves{
|
|||||||
|
|
||||||
createProgression.get(0);
|
createProgression.get(0);
|
||||||
|
|
||||||
int step = 5 + rand.random(3);
|
int step = 5 + rand.random(5);
|
||||||
|
|
||||||
while(step <= cap){
|
while(step <= cap){
|
||||||
createProgression.get(step);
|
createProgression.get(step);
|
||||||
step += (int)(rand.random(13, 25) * Mathf.lerp(1f, 0.5f, difficulty));
|
step += (int)(rand.random(15, 30) * Mathf.lerp(1f, 0.5f, difficulty));
|
||||||
}
|
}
|
||||||
|
|
||||||
int bossWave = (int)(rand.random(30, 60) * Mathf.lerp(1f, 0.7f, difficulty));
|
int bossWave = (int)(rand.random(30, 60) * Mathf.lerp(1f, 0.7f, difficulty));
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class Objectives{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean complete(){
|
public boolean complete(){
|
||||||
return preset.sector.save != null && preset.sector.save.meta.wave >= preset.captureWave;
|
return preset.sector.save != null && !preset.sector.isAttacked() && preset.sector.hasBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -288,6 +288,10 @@ public class Schematics implements Loadable{
|
|||||||
return loadouts.get(block, Seq::new);
|
return loadouts.get(block, Seq::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObjectMap<CoreBlock, Seq<Schematic>> getLoadouts(){
|
||||||
|
return loadouts;
|
||||||
|
}
|
||||||
|
|
||||||
/** Checks a schematic for deployment validity and adds it to the cache. */
|
/** Checks a schematic for deployment validity and adds it to the cache. */
|
||||||
private void checkLoadout(Schematic s, boolean validate){
|
private void checkLoadout(Schematic s, boolean validate){
|
||||||
Stile core = s.tiles.find(t -> t.block instanceof CoreBlock);
|
Stile core = s.tiles.find(t -> t.block instanceof CoreBlock);
|
||||||
|
|||||||
@@ -156,7 +156,6 @@ public class SectorInfo{
|
|||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
if(state.rules.sector != null){
|
if(state.rules.sector != null){
|
||||||
state.rules.sector.info = this;
|
|
||||||
state.rules.sector.saveInfo();
|
state.rules.sector.saveInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import mindustry.content.*;
|
|||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.payloads.*;
|
import mindustry.world.blocks.payloads.*;
|
||||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ public class Teams{
|
|||||||
public Seq<TeamData> active = new Seq<>();
|
public Seq<TeamData> active = new Seq<>();
|
||||||
/** Teams with block or unit presence. */
|
/** Teams with block or unit presence. */
|
||||||
public Seq<TeamData> present = new Seq<>(TeamData.class);
|
public Seq<TeamData> present = new Seq<>(TeamData.class);
|
||||||
|
/** Ores currently being mined. */
|
||||||
|
private IntMap<Unit> mined = new IntMap<>();
|
||||||
|
|
||||||
public Teams(){
|
public Teams(){
|
||||||
active.add(get(Team.crux));
|
active.add(get(Team.crux));
|
||||||
@@ -142,7 +145,20 @@ public class Teams{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether this ore is taken. */
|
||||||
|
public boolean canMine(Unit unit, Tile tile){
|
||||||
|
if(tile == null) return false;
|
||||||
|
Unit u = mined.get(tile.pos());
|
||||||
|
return u == unit || u == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerMined(Tile tile, Unit unit){
|
||||||
|
if(tile == null || unit == null) return;
|
||||||
|
mined.put(tile.pos(), unit);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateTeamStats(){
|
public void updateTeamStats(){
|
||||||
|
mined.clear();
|
||||||
present.clear();
|
present.clear();
|
||||||
|
|
||||||
for(Team team : Team.all){
|
for(Team team : Team.all){
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ public class Universe{
|
|||||||
if(!sector.isAttacked() && turn > invasionGracePeriod){
|
if(!sector.isAttacked() && turn > invasionGracePeriod){
|
||||||
//invasion chance depends on # of nearby bases
|
//invasion chance depends on # of nearby bases
|
||||||
if(Mathf.chance(baseInvasionChance * sector.near().count(Sector::hasEnemyBase))){
|
if(Mathf.chance(baseInvasionChance * sector.near().count(Sector::hasEnemyBase))){
|
||||||
int waveMax = Math.max(sector.info.winWave, sector.isBeingPlayed() ? state.wave : 0) + Mathf.random(2, 5) * 5;
|
int waveMax = Math.max(sector.info.winWave, state.wave) + Mathf.random(2, 5) * 5;
|
||||||
|
|
||||||
//assign invasion-related things
|
//assign invasion-related things
|
||||||
if(sector.isBeingPlayed()){
|
if(sector.isBeingPlayed()){
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import arc.graphics.*;
|
|||||||
public class Pal{
|
public class Pal{
|
||||||
public static Color
|
public static Color
|
||||||
|
|
||||||
|
thoriumPink = Color.valueOf("f9a3c7"),
|
||||||
|
|
||||||
items = Color.valueOf("2ea756"),
|
items = Color.valueOf("2ea756"),
|
||||||
command = Color.valueOf("eab678"),
|
command = Color.valueOf("eab678"),
|
||||||
|
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
|
|
||||||
if(isPlacing() && mode == placing){
|
if(isPlacing() && mode == placing){
|
||||||
updateLine(selectX, selectY);
|
updateLine(selectX, selectY);
|
||||||
}else if(!selectRequests.isEmpty()){
|
}else if(!selectRequests.isEmpty() && !ui.chatfrag.shown()){
|
||||||
rotateRequests(selectRequests, Mathf.sign(Core.input.axisTap(Binding.rotate)));
|
rotateRequests(selectRequests, Mathf.sign(Core.input.axisTap(Binding.rotate)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,7 +660,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update commander unit
|
//update commander unit
|
||||||
if(Core.input.keyTap(Binding.command)){
|
if(Core.input.keyTap(Binding.command) && unit.type.commandLimit > 0){
|
||||||
Call.unitCommand(player);
|
Call.unitCommand(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,6 +336,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
public static void unitControl(Player player, @Nullable Unit unit){
|
public static void unitControl(Player player, @Nullable Unit unit){
|
||||||
if(player == null) return;
|
if(player == null) return;
|
||||||
|
|
||||||
|
//make sure player is allowed to control the unit
|
||||||
|
if(net.server() && !netServer.admins.allowAction(player, ActionType.control, action -> action.unit = unit)){
|
||||||
|
throw new ValidateException(player, "Player cannot control a unit.");
|
||||||
|
}
|
||||||
|
|
||||||
//clear player unit when they possess a core
|
//clear player unit when they possess a core
|
||||||
if((unit instanceof BlockUnitc && ((BlockUnitc)unit).tile() instanceof CoreBuild)){
|
if((unit instanceof BlockUnitc && ((BlockUnitc)unit).tile() instanceof CoreBuild)){
|
||||||
Fx.spawn.at(player);
|
Fx.spawn.at(player);
|
||||||
@@ -376,6 +381,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
public static void unitCommand(Player player){
|
public static void unitCommand(Player player){
|
||||||
if(player == null || player.dead() || !(player.unit() instanceof Commanderc commander)) return;
|
if(player == null || player.dead() || !(player.unit() instanceof Commanderc commander)) return;
|
||||||
|
|
||||||
|
//make sure player is allowed to make the command
|
||||||
|
if(net.server() && !netServer.admins.allowAction(player, ActionType.command, action -> {})){
|
||||||
|
throw new ValidateException(player, "Player cannot command a unit.");
|
||||||
|
}
|
||||||
|
|
||||||
if(commander.isCommanding()){
|
if(commander.isCommanding()){
|
||||||
commander.clearCommand();
|
commander.clearCommand();
|
||||||
}else if(player.unit().type.commandLimit > 0){
|
}else if(player.unit().type.commandLimit > 0){
|
||||||
@@ -935,10 +945,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
|
|
||||||
boolean canMine(Tile tile){
|
boolean canMine(Tile tile){
|
||||||
return !Core.scene.hasMouse()
|
return !Core.scene.hasMouse()
|
||||||
&& tile.drop() != null && player.miner().canMine(tile.drop())
|
&& tile.drop() != null
|
||||||
|
&& player.miner().validMine(tile)
|
||||||
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
|
||||||
&& player.unit().acceptsItem(tile.drop())
|
&& player.unit().acceptsItem(tile.drop())
|
||||||
&& tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= miningRange;
|
&& tile.block() == Blocks.air;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the tile at the specified MOUSE coordinates. */
|
/** Returns the tile at the specified MOUSE coordinates. */
|
||||||
@@ -1203,7 +1214,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
line.x = point.x;
|
line.x = point.x;
|
||||||
line.y = point.y;
|
line.y = point.y;
|
||||||
if(!overrideLineRotation || diagonal){
|
if(!overrideLineRotation || diagonal){
|
||||||
line.rotation = next != null ? Tile.relativeTo(point.x, point.y, next.x, next.y) : baseRotation;
|
if(next != null){
|
||||||
|
line.rotation = Tile.relativeTo(point.x, point.y, next.x, next.y);
|
||||||
|
}else if(block.conveyorPlacement && i > 0){
|
||||||
|
Point2 prev = points.get(i - 1);
|
||||||
|
line.rotation = Tile.relativeTo(prev.x, prev.y, point.x, point.y);
|
||||||
|
}else{
|
||||||
|
line.rotation = baseRotation;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
line.rotation = rotation;
|
line.rotation = rotation;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -613,7 +613,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
|||||||
//reset payload target
|
//reset payload target
|
||||||
payloadTarget = null;
|
payloadTarget = null;
|
||||||
//apply command on double tap when own unit is tapped
|
//apply command on double tap when own unit is tapped
|
||||||
if(Mathf.within(worldx, worldy, player.unit().x, player.unit().y, player.unit().hitSize * 0.6f + 8f)){
|
if(!player.dead() && Mathf.within(worldx, worldy, player.unit().x, player.unit().y, player.unit().hitSize * 0.6f + 8f) && player.unit().type.commandLimit > 0){
|
||||||
Call.unitCommand(player);
|
Call.unitCommand(player);
|
||||||
}else{
|
}else{
|
||||||
//control a unit/block
|
//control a unit/block
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
||||||
//prepare campaign data for writing
|
//prepare campaign data for writing
|
||||||
if(state.isCampaign()){
|
if(state.isCampaign()){
|
||||||
state.secinfo.prepare();
|
state.rules.sector.info.prepare();
|
||||||
state.rules.sector.saveInfo();
|
state.rules.sector.saveInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,11 +110,6 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
|
if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get();
|
||||||
lastReadBuild = map.getInt("build", -1);
|
lastReadBuild = map.getInt("build", -1);
|
||||||
|
|
||||||
//load in sector info
|
|
||||||
if(state.rules.sector != null){
|
|
||||||
state.secinfo = state.rules.sector.info;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!headless){
|
if(!headless){
|
||||||
Tmp.v1.tryFromString(map.get("viewpos"));
|
Tmp.v1.tryFromString(map.get("viewpos"));
|
||||||
Core.camera.position.set(Tmp.v1);
|
Core.camera.position.set(Tmp.v1);
|
||||||
|
|||||||
@@ -38,12 +38,15 @@ public enum LAccess{
|
|||||||
//values with parameters are considered controllable
|
//values with parameters are considered controllable
|
||||||
enabled("to"), //"to" is standard for single parameter access
|
enabled("to"), //"to" is standard for single parameter access
|
||||||
shoot("x", "y", "shoot"),
|
shoot("x", "y", "shoot"),
|
||||||
shootp(true, "unit", "shoot")
|
shootp(true, "unit", "shoot"),
|
||||||
|
configure(true, 30, "to")
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
public final String[] params;
|
public final String[] params;
|
||||||
public final boolean isObj;
|
public final boolean isObj;
|
||||||
|
/** Tick cooldown between invocations. */
|
||||||
|
public float cooldown = -1;
|
||||||
|
|
||||||
public static final LAccess[]
|
public static final LAccess[]
|
||||||
all = values(),
|
all = values(),
|
||||||
@@ -59,4 +62,10 @@ public enum LAccess{
|
|||||||
this.params = params;
|
this.params = params;
|
||||||
isObj = obj;
|
isObj = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LAccess(boolean obj, float cooldown, String... params){
|
||||||
|
this.params = params;
|
||||||
|
this.cooldown = cooldown;
|
||||||
|
isObj = obj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ public class LExecutor{
|
|||||||
this.outX = outX;
|
this.outX = outX;
|
||||||
this.outY = outY;
|
this.outY = outY;
|
||||||
this.outFound = outFound;
|
this.outFound = outFound;
|
||||||
|
this.outBuild = outBuild;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnitLocateI(){
|
public UnitLocateI(){
|
||||||
@@ -245,7 +246,7 @@ public class LExecutor{
|
|||||||
switch(locate){
|
switch(locate){
|
||||||
case ore -> {
|
case ore -> {
|
||||||
if(exec.obj(ore) instanceof Item item){
|
if(exec.obj(ore) instanceof Item item){
|
||||||
res = indexer.findClosestOre(unit.x, unit.y, item);
|
res = indexer.findClosestOre(unit, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case building -> {
|
case building -> {
|
||||||
@@ -272,8 +273,9 @@ public class LExecutor{
|
|||||||
cache.found = false;
|
cache.found = false;
|
||||||
exec.setnum(outFound, 0);
|
exec.setnum(outFound, 0);
|
||||||
}
|
}
|
||||||
exec.setobj(outFound, res != null && res.build != null && res.build.team == exec.team ? res.build : null);
|
exec.setobj(outBuild, res != null && res.build != null && res.build.team == exec.team ? cache.build = res.build : null);
|
||||||
}else{
|
}else{
|
||||||
|
exec.setobj(outBuild, cache.build);
|
||||||
exec.setbool(outFound, cache.found);
|
exec.setbool(outFound, cache.found);
|
||||||
exec.setnum(outX, cache.x);
|
exec.setnum(outX, cache.x);
|
||||||
exec.setnum(outY, cache.y);
|
exec.setnum(outY, cache.y);
|
||||||
@@ -284,20 +286,22 @@ public class LExecutor{
|
|||||||
static class Cache{
|
static class Cache{
|
||||||
float x, y;
|
float x, y;
|
||||||
boolean found;
|
boolean found;
|
||||||
|
Building build;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Controls the unit based on some parameters. */
|
/** Controls the unit based on some parameters. */
|
||||||
public static class UnitControlI implements LInstruction{
|
public static class UnitControlI implements LInstruction{
|
||||||
public LUnitControl type = LUnitControl.move;
|
public LUnitControl type = LUnitControl.move;
|
||||||
public int p1, p2, p3, p4;
|
public int p1, p2, p3, p4, p5;
|
||||||
|
|
||||||
public UnitControlI(LUnitControl type, int p1, int p2, int p3, int p4){
|
public UnitControlI(LUnitControl type, int p1, int p2, int p3, int p4, int p5){
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.p1 = p1;
|
this.p1 = p1;
|
||||||
this.p2 = p2;
|
this.p2 = p2;
|
||||||
this.p3 = p3;
|
this.p3 = p3;
|
||||||
this.p4 = p4;
|
this.p4 = p4;
|
||||||
|
this.p5 = p5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnitControlI(){
|
public UnitControlI(){
|
||||||
@@ -435,7 +439,7 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
ai.plan.set(x, y, rot, block);
|
ai.plan.set(x, y, rot, block);
|
||||||
ai.plan.config = null;
|
ai.plan.config = exec.obj(p5) instanceof Content c ? c : null;
|
||||||
|
|
||||||
builder.clearBuilding();
|
builder.clearBuilding();
|
||||||
|
|
||||||
@@ -462,9 +466,8 @@ public class LExecutor{
|
|||||||
if(ai.itemTimer > 0) return;
|
if(ai.itemTimer > 0) return;
|
||||||
|
|
||||||
Building build = exec.building(p1);
|
Building build = exec.building(p1);
|
||||||
int amount = exec.numi(p2);
|
int dropped = Math.min(unit.stack.amount, exec.numi(p2));
|
||||||
int dropped = Math.min(unit.stack.amount, amount);
|
if(build != null && dropped > 0 && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
||||||
if(build != null && dropped > 0 && unit.within(build, logicItemTransferRange)){
|
|
||||||
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
||||||
if(accepted > 0){
|
if(accepted > 0){
|
||||||
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
||||||
@@ -478,7 +481,7 @@ public class LExecutor{
|
|||||||
Building build = exec.building(p1);
|
Building build = exec.building(p1);
|
||||||
int amount = exec.numi(p3);
|
int amount = exec.numi(p3);
|
||||||
|
|
||||||
if(build != null && build.items != null && exec.obj(p2) instanceof Item item && unit.within(build, logicItemTransferRange)){
|
if(build != null && build.items != null && exec.obj(p2) instanceof Item item && unit.within(build, logicItemTransferRange + build.block.size * tilesize/2f)){
|
||||||
int taken = Math.min(build.items.get(item), Math.min(amount, unit.maxAccepted(item)));
|
int taken = Math.min(build.items.get(item), Math.min(amount, unit.maxAccepted(item)));
|
||||||
|
|
||||||
if(taken > 0){
|
if(taken > 0){
|
||||||
@@ -498,6 +501,7 @@ public class LExecutor{
|
|||||||
public int target;
|
public int target;
|
||||||
public LAccess type = LAccess.enabled;
|
public LAccess type = LAccess.enabled;
|
||||||
public int p1, p2, p3, p4;
|
public int p1, p2, p3, p4;
|
||||||
|
public Interval timer = new Interval(1);
|
||||||
|
|
||||||
public ControlI(LAccess type, int target, int p1, int p2, int p3, int p4){
|
public ControlI(LAccess type, int target, int p1, int p2, int p3, int p4){
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -513,7 +517,7 @@ public class LExecutor{
|
|||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
Object obj = exec.obj(target);
|
Object obj = exec.obj(target);
|
||||||
if(obj instanceof Building b && b.team == exec.team && exec.linkIds.contains(b.id)){
|
if(obj instanceof Building b && b.team == exec.team && exec.linkIds.contains(b.id) && (type.cooldown <= 0 || timer.get(type.cooldown))){
|
||||||
if(type.isObj){
|
if(type.isObj){
|
||||||
b.control(type, exec.obj(p1), exec.num(p2), exec.num(p3), exec.num(p4));
|
b.control(type, exec.obj(p1), exec.num(p2), exec.num(p3), exec.num(p4));
|
||||||
}else{
|
}else{
|
||||||
@@ -872,10 +876,11 @@ public class LExecutor{
|
|||||||
if(v.isobj && value != 0){
|
if(v.isobj && value != 0){
|
||||||
String strValue =
|
String strValue =
|
||||||
v.objval == null ? "null" :
|
v.objval == null ? "null" :
|
||||||
v.objval instanceof String ? (String)v.objval :
|
v.objval instanceof String s ? s :
|
||||||
|
v.objval instanceof MappableContent content ? content.name :
|
||||||
v.objval instanceof Content ? "[content]" :
|
v.objval instanceof Content ? "[content]" :
|
||||||
v.objval instanceof Building ? "[building]" :
|
v.objval instanceof Building build ? build.block.name :
|
||||||
v.objval instanceof Unit ? "[unit]" :
|
v.objval instanceof Unit unit ? unit.type.name :
|
||||||
"[object]";
|
"[object]";
|
||||||
|
|
||||||
exec.textBuffer.append(strValue);
|
exec.textBuffer.append(strValue);
|
||||||
|
|||||||
@@ -748,7 +748,7 @@ public class LStatements{
|
|||||||
@RegisterStatement("ucontrol")
|
@RegisterStatement("ucontrol")
|
||||||
public static class UnitControlStatement extends LStatement{
|
public static class UnitControlStatement extends LStatement{
|
||||||
public LUnitControl type = LUnitControl.move;
|
public LUnitControl type = LUnitControl.move;
|
||||||
public String p1 = "0", p2 = "0", p3 = "0", p4 = "0";
|
public String p1 = "0", p2 = "0", p3 = "0", p4 = "0", p5 = "0";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(Table table){
|
public void build(Table table){
|
||||||
@@ -777,9 +777,13 @@ public class LStatements{
|
|||||||
int c = 0;
|
int c = 0;
|
||||||
for(int i = 0; i < type.params.length; i++){
|
for(int i = 0; i < type.params.length; i++){
|
||||||
|
|
||||||
fields(table, type.params[i], i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : p4, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : v -> p4 = v).width(110f);
|
fields(table, type.params[i], i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : i == 3 ? p4 : p5, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : i == 3 ? v -> p4 = v : v -> p5 = v).width(100f);
|
||||||
|
|
||||||
if(++c % 2 == 0) row(table);
|
if(++c % 2 == 0) row(table);
|
||||||
|
|
||||||
|
if(i == 3){
|
||||||
|
table.row();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,7 +794,7 @@ public class LStatements{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LInstruction build(LAssembler builder){
|
public LInstruction build(LAssembler builder){
|
||||||
return new UnitControlI(type, builder.var(p1), builder.var(p2), builder.var(p3), builder.var(p4));
|
return new UnitControlI(type, builder.var(p1), builder.var(p2), builder.var(p3), builder.var(p4), builder.var(p5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,7 +865,7 @@ public class LStatements{
|
|||||||
table.table(ts -> {
|
table.table(ts -> {
|
||||||
ts.color.set(table.color);
|
ts.color.set(table.color);
|
||||||
|
|
||||||
field(ts, ore, str -> ore = str);
|
fields(ts, ore, str -> ore = str);
|
||||||
|
|
||||||
ts.button(b -> {
|
ts.button(b -> {
|
||||||
b.image(Icon.pencilSmall);
|
b.image(Icon.pencilSmall);
|
||||||
@@ -905,8 +909,10 @@ public class LStatements{
|
|||||||
table.add(" found ").left();
|
table.add(" found ").left();
|
||||||
fields(table, outFound, str -> outFound = str);
|
fields(table, outFound, str -> outFound = str);
|
||||||
|
|
||||||
|
if(locate != LLocate.ore){
|
||||||
table.add(" building ").left();
|
table.add(" building ").left();
|
||||||
fields(table, outBuild, str -> outBuild = str);
|
fields(table, outBuild, str -> outBuild = str);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public enum LUnitControl{
|
|||||||
payTake("takeUnits"),
|
payTake("takeUnits"),
|
||||||
mine("x", "y"),
|
mine("x", "y"),
|
||||||
flag("value"),
|
flag("value"),
|
||||||
build("x", "y", "block", "rotation"),
|
build("x", "y", "block", "rotation", "config"),
|
||||||
getBlock("x", "y", "type", "building"),
|
getBlock("x", "y", "type", "building"),
|
||||||
within("x", "y", "radius", "result");
|
within("x", "y", "radius", "result");
|
||||||
|
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ public class SectorDamage{
|
|||||||
/** Applies wave damage based on sector parameters. */
|
/** Applies wave damage based on sector parameters. */
|
||||||
public static void applyCalculatedDamage(){
|
public static void applyCalculatedDamage(){
|
||||||
//calculate base damage fraction
|
//calculate base damage fraction
|
||||||
float damage = getDamage(state.secinfo);
|
float damage = getDamage(state.rules.sector.info);
|
||||||
|
|
||||||
//scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier)
|
//scaled damage has a power component to make it seem a little more realistic (as systems fail, enemy capturing gets easier and easier)
|
||||||
float scaled = Mathf.pow(damage, 1.5f);
|
float scaled = Mathf.pow(damage, 1.5f);
|
||||||
|
|
||||||
//apply damage to units
|
//apply damage to units
|
||||||
float unitDamage = damage * state.secinfo.sumHealth;
|
float unitDamage = damage * state.rules.sector.info.sumHealth;
|
||||||
Tile spawn = spawner.getFirstSpawn();
|
Tile spawn = spawner.getFirstSpawn();
|
||||||
|
|
||||||
//damage only units near the spawn point
|
//damage only units near the spawn point
|
||||||
@@ -114,7 +114,7 @@ public class SectorDamage{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.secinfo.wavesPassed > 0){
|
if(state.rules.sector.info.wavesPassed > 0){
|
||||||
//simply remove each block in the spawner range if a wave passed
|
//simply remove each block in the spawner range if a wave passed
|
||||||
for(Tile spawner : spawner.getSpawns()){
|
for(Tile spawner : spawner.getSpawns()){
|
||||||
spawner.circle((int)(state.rules.dropZoneRadius / tilesize), tile -> {
|
spawner.circle((int)(state.rules.dropZoneRadius / tilesize), tile -> {
|
||||||
@@ -207,7 +207,7 @@ public class SectorDamage{
|
|||||||
//first, calculate the total health of blocks in the path
|
//first, calculate the total health of blocks in the path
|
||||||
|
|
||||||
//radius around the path that gets counted
|
//radius around the path that gets counted
|
||||||
int radius = 7;
|
int radius = 9;
|
||||||
IntSet counted = new IntSet();
|
IntSet counted = new IntSet();
|
||||||
|
|
||||||
for(Tile t : sparse2){
|
for(Tile t : sparse2){
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public abstract class GenerateFilter{
|
|||||||
apply();
|
apply();
|
||||||
|
|
||||||
tile.setFloor(in.floor.asFloor());
|
tile.setFloor(in.floor.asFloor());
|
||||||
tile.setOverlay(!in.floor.asFloor().hasSurface() ? Blocks.air : in.overlay);
|
tile.setOverlay(!in.floor.asFloor().hasSurface() && in.overlay.asFloor().needsSurface ? Blocks.air : in.overlay);
|
||||||
|
|
||||||
if(!tile.block().synthetic() && !in.block.synthetic()){
|
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||||
tile.setBlock(in.block);
|
tile.setBlock(in.block);
|
||||||
@@ -49,7 +49,7 @@ public abstract class GenerateFilter{
|
|||||||
apply();
|
apply();
|
||||||
|
|
||||||
tile.setFloor(in.floor.asFloor());
|
tile.setFloor(in.floor.asFloor());
|
||||||
tile.setOverlay(!in.floor.asFloor().hasSurface() ? Blocks.air : in.overlay);
|
tile.setOverlay(!in.floor.asFloor().hasSurface() && in.overlay.asFloor().needsSurface ? Blocks.air : in.overlay);
|
||||||
|
|
||||||
if(!tile.block().synthetic() && !in.block.synthetic()){
|
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||||
tile.setBlock(in.block);
|
tile.setBlock(in.block);
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class FileMapGenerator implements WorldGenerator{
|
public class FileMapGenerator implements WorldGenerator{
|
||||||
public final Map map;
|
public final Map map;
|
||||||
|
public final SectorPreset preset;
|
||||||
|
|
||||||
public FileMapGenerator(String mapName){
|
public FileMapGenerator(String mapName, SectorPreset preset){
|
||||||
this.map = maps != null ? maps.loadInternalMap(mapName) : null;
|
this.map = maps != null ? maps.loadInternalMap(mapName) : null;
|
||||||
|
this.preset = preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -56,6 +58,10 @@ public class FileMapGenerator implements WorldGenerator{
|
|||||||
if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){
|
if(tile.isCenter() && tile.block() instanceof CoreBlock && tile.team() == state.rules.defaultTeam && !anyCores){
|
||||||
Schematics.placeLaunchLoadout(tile.x, tile.y);
|
Schematics.placeLaunchLoadout(tile.x, tile.y);
|
||||||
anyCores = true;
|
anyCores = true;
|
||||||
|
|
||||||
|
if(preset.addStartingItems){
|
||||||
|
tile.build.items.add(state.rules.loadout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -569,7 +569,9 @@ public class ContentParser{
|
|||||||
if(field.field.getType().isPrimitive()) return;
|
if(field.field.getType().isPrimitive()) return;
|
||||||
|
|
||||||
if(!field.field.isAnnotationPresent(Nullable.class) && field.field.get(object) == null && !implicitNullable.contains(field.field.getType())){
|
if(!field.field.isAnnotationPresent(Nullable.class) && field.field.get(object) == null && !implicitNullable.contains(field.field.getType())){
|
||||||
throw new RuntimeException("'" + field.field.getName() + "' in " + object.getClass().getSimpleName() + " is missing!");
|
throw new RuntimeException("'" + field.field.getName() + "' in " +
|
||||||
|
((object.getClass().isAnonymousClass() ? object.getClass().getSuperclass() : object.getClass()).getSimpleName()) +
|
||||||
|
" is missing! Object = " + object + ", field = (" + field.field.getName() + " = " + field.field.get(object) + ")");
|
||||||
}
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|||||||
@@ -142,11 +142,18 @@ public class Administration{
|
|||||||
|
|
||||||
/** @return whether this action is allowed by the action filters. */
|
/** @return whether this action is allowed by the action filters. */
|
||||||
public boolean allowAction(Player player, ActionType type, Tile tile, Cons<PlayerAction> setter){
|
public boolean allowAction(Player player, ActionType type, Tile tile, Cons<PlayerAction> setter){
|
||||||
|
return allowAction(player, type, action -> setter.get(action.set(player, type, tile)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether this action is allowed by the action filters. */
|
||||||
|
public boolean allowAction(Player player, ActionType type, Cons<PlayerAction> setter){
|
||||||
//some actions are done by the server (null player) and thus are always allowed
|
//some actions are done by the server (null player) and thus are always allowed
|
||||||
if(player == null) return true;
|
if(player == null) return true;
|
||||||
|
|
||||||
PlayerAction act = Pools.obtain(PlayerAction.class, PlayerAction::new);
|
PlayerAction act = Pools.obtain(PlayerAction.class, PlayerAction::new);
|
||||||
setter.get(act.set(player, type, tile));
|
act.player = player;
|
||||||
|
act.type = type;
|
||||||
|
setter.get(act);
|
||||||
for(ActionFilter filter : actionFilters){
|
for(ActionFilter filter : actionFilters){
|
||||||
if(!filter.allow(act)){
|
if(!filter.allow(act)){
|
||||||
Pools.free(act);
|
Pools.free(act);
|
||||||
@@ -699,7 +706,7 @@ public class Administration{
|
|||||||
public static class PlayerAction implements Poolable{
|
public static class PlayerAction implements Poolable{
|
||||||
public Player player;
|
public Player player;
|
||||||
public ActionType type;
|
public ActionType type;
|
||||||
public Tile tile;
|
public @Nullable Tile tile;
|
||||||
|
|
||||||
/** valid for block placement events only */
|
/** valid for block placement events only */
|
||||||
public @Nullable Block block;
|
public @Nullable Block block;
|
||||||
@@ -712,6 +719,9 @@ public class Administration{
|
|||||||
public @Nullable Item item;
|
public @Nullable Item item;
|
||||||
public int itemAmount;
|
public int itemAmount;
|
||||||
|
|
||||||
|
/** valid for unit-type events only, and even in that case may be null. */
|
||||||
|
public @Nullable Unit unit;
|
||||||
|
|
||||||
public PlayerAction set(Player player, ActionType type, Tile tile){
|
public PlayerAction set(Player player, ActionType type, Tile tile){
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -719,6 +729,13 @@ public class Administration{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PlayerAction set(Player player, ActionType type, Unit unit){
|
||||||
|
this.player = player;
|
||||||
|
this.type = type;
|
||||||
|
this.unit = unit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset(){
|
public void reset(){
|
||||||
item = null;
|
item = null;
|
||||||
@@ -728,11 +745,12 @@ public class Administration{
|
|||||||
type = null;
|
type = null;
|
||||||
tile = null;
|
tile = null;
|
||||||
block = null;
|
block = null;
|
||||||
|
unit = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ActionType{
|
public enum ActionType{
|
||||||
breakBlock, placeBlock, rotate, configure, withdrawItem, depositItem
|
breakBlock, placeBlock, rotate, configure, withdrawItem, depositItem, control, command
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
public Cons<Rules> rules = rules -> rules.winWave = captureWave;
|
public Cons<Rules> rules = rules -> rules.winWave = captureWave;
|
||||||
/** Difficulty, 0-10. */
|
/** Difficulty, 0-10. */
|
||||||
public float difficulty;
|
public float difficulty;
|
||||||
|
public boolean addStartingItems = false;
|
||||||
|
|
||||||
public SectorPreset(String name, Planet planet, int sector){
|
public SectorPreset(String name, Planet planet, int sector){
|
||||||
super(name);
|
super(name);
|
||||||
this.generator = new FileMapGenerator(name);
|
this.generator = new FileMapGenerator(name, this);
|
||||||
this.planet = planet;
|
this.planet = planet;
|
||||||
sector %= planet.sectors.size;
|
sector %= planet.sectors.size;
|
||||||
this.sector = planet.sectors.get(sector);
|
this.sector = planet.sectors.get(sector);
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
|
|
||||||
stats.add(Stat.health, health);
|
stats.add(Stat.health, health);
|
||||||
stats.add(Stat.speed, speed);
|
stats.add(Stat.speed, speed);
|
||||||
stats.add(Stat.itemCapacity, health);
|
stats.add(Stat.itemCapacity, itemCapacity);
|
||||||
stats.add(Stat.range, (int)(maxRange / tilesize), StatUnit.blocks);
|
stats.add(Stat.range, (int)(maxRange / tilesize), StatUnit.blocks);
|
||||||
stats.add(Stat.commandLimit, commandLimit);
|
stats.add(Stat.commandLimit, commandLimit);
|
||||||
//TODO abilities, maybe try something like DPS
|
//TODO abilities, maybe try something like DPS
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class Weapon{
|
|||||||
public float x = 5f, y = 0f;
|
public float x = 5f, y = 0f;
|
||||||
/** random spread on the X axis */
|
/** random spread on the X axis */
|
||||||
public float xRand = 0f;
|
public float xRand = 0f;
|
||||||
/** radius of occlusion drawn under the weapon; <0 to diable */
|
/** radius of occlusion drawn under the weapon; <0 to disable */
|
||||||
public float occlusion = -1f;
|
public float occlusion = -1f;
|
||||||
/** fraction of velocity that is random */
|
/** fraction of velocity that is random */
|
||||||
public float velocityRnd = 0f;
|
public float velocityRnd = 0f;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class ParticleWeather extends Weather{
|
|||||||
float sspeed = 1f, sscl = 1f, salpha = 1f, offset = 0f;
|
float sspeed = 1f, sscl = 1f, salpha = 1f, offset = 0f;
|
||||||
Color col = Tmp.c1.set(noiseColor);
|
Color col = Tmp.c1.set(noiseColor);
|
||||||
for(int i = 0; i < noiseLayers; i++){
|
for(int i = 0; i < noiseLayers; i++){
|
||||||
drawNoise(noise, noiseColor, noiseScale * sscl, state.opacity * salpha * opacityMultiplier, baseSpeed * sspeed, state.intensity, windx, windy, offset);
|
drawNoise(noise, noiseColor, noiseScale * sscl, state.opacity * salpha * opacityMultiplier, sspeed * (useWindVector ? 1f : baseSpeed), state.intensity, windx, windy, offset);
|
||||||
sspeed *= noiseLayerSpeedM;
|
sspeed *= noiseLayerSpeedM;
|
||||||
salpha *= noiseLayerAlphaM;
|
salpha *= noiseLayerAlphaM;
|
||||||
sscl *= noiseLayerSclM;
|
sscl *= noiseLayerSclM;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.input.*;
|
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
@@ -54,11 +53,7 @@ public class BaseDialog extends Dialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addCloseListener(){
|
public void addCloseListener(){
|
||||||
keyDown(key -> {
|
closeOnBack();
|
||||||
if(key == KeyCode.escape || key == KeyCode.back){
|
|
||||||
Core.app.post(this::hide);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -99,7 +99,9 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
|||||||
cont.pane(t -> {
|
cont.pane(t -> {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for(Schematic s : schematics.getLoadouts(core)){
|
for(var entry : schematics.getLoadouts()){
|
||||||
|
if(entry.key.size <= core.size){
|
||||||
|
for(Schematic s : entry.value){
|
||||||
|
|
||||||
t.button(b -> b.add(new SchematicImage(s)), Styles.togglet, () -> {
|
t.button(b -> b.add(new SchematicImage(s)), Styles.togglet, () -> {
|
||||||
selected = s;
|
selected = s;
|
||||||
@@ -111,6 +113,10 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
|||||||
t.row();
|
t.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}).growX().get().setScrollingDisabled(true, false);
|
}).growX().get().setScrollingDisabled(true, false);
|
||||||
|
|
||||||
cont.row();
|
cont.row();
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
|
|
||||||
shouldPause = true;
|
shouldPause = true;
|
||||||
|
|
||||||
|
addCloseListener();
|
||||||
|
|
||||||
buttons.defaults().size(200f, 56f).pad(2);
|
buttons.defaults().size(200f, 56f).pad(2);
|
||||||
buttons.button("@back", Icon.left, this::hide);
|
buttons.button("@back", Icon.left, this::hide);
|
||||||
buttons.button("@techtree", Icon.tree, () -> ui.research.show());
|
buttons.button("@techtree", Icon.tree, () -> ui.research.show());
|
||||||
@@ -242,7 +244,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
addListener(new ElementGestureListener(){
|
addListener(new ElementGestureListener(){
|
||||||
@Override
|
@Override
|
||||||
public void tap(InputEvent event, float x, float y, int count, KeyCode button){
|
public void tap(InputEvent event, float x, float y, int count, KeyCode button){
|
||||||
if(hovered != null && ((mode == look ? canSelect(hovered) && hovered != launchSector : hovered.unlocked()) || debugSelect)){
|
if(hovered != null && (canSelect(hovered) || debugSelect)){
|
||||||
selected = hovered;
|
selected = hovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -281,7 +281,9 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
game.checkPref("blockreplace", true);
|
game.checkPref("blockreplace", true);
|
||||||
game.checkPref("conveyorpathfinding", true);
|
game.checkPref("conveyorpathfinding", true);
|
||||||
game.checkPref("hints", true);
|
game.checkPref("hints", true);
|
||||||
|
|
||||||
if(!mobile){
|
if(!mobile){
|
||||||
|
game.checkPref("backgroundpause", true);
|
||||||
game.checkPref("buildautopause", false);
|
game.checkPref("buildautopause", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -368,9 +368,9 @@ public class HudFragment extends Fragment{
|
|||||||
c.clearChildren();
|
c.clearChildren();
|
||||||
|
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
if(state.secinfo.getExport(item) >= 1){
|
if(state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1){
|
||||||
c.image(item.icon(Cicon.small));
|
c.image(item.icon(Cicon.small));
|
||||||
c.label(() -> (int)state.secinfo.getExport(item) + " /s").color(Color.lightGray);
|
c.label(() -> (int)state.rules.sector.info.getExport(item) + " /s").color(Color.lightGray);
|
||||||
c.row();
|
c.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ public class HudFragment extends Fragment{
|
|||||||
c.update(() -> {
|
c.update(() -> {
|
||||||
boolean wrong = false;
|
boolean wrong = false;
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
boolean has = state.secinfo.getExport(item) >= 1;
|
boolean has = state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1;
|
||||||
if(used.get(item.id) != has){
|
if(used.get(item.id) != has){
|
||||||
used.set(item.id, has);
|
used.set(item.id, has);
|
||||||
wrong = true;
|
wrong = true;
|
||||||
@@ -389,7 +389,7 @@ public class HudFragment extends Fragment{
|
|||||||
rebuild.run();
|
rebuild.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).visible(() -> state.isCampaign() && content.items().contains(i -> state.secinfo.getExport(i) > 0));
|
}).visible(() -> state.isCampaign() && content.items().contains(i -> state.rules.sector != null && state.rules.sector.info.getExport(i) > 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
blockfrag.build(parent);
|
blockfrag.build(parent);
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
topTable.row();
|
topTable.row();
|
||||||
topTable.table(b -> {
|
topTable.table(b -> {
|
||||||
b.image(Icon.cancel).padRight(2).color(Color.scarlet);
|
b.image(Icon.cancel).padRight(2).color(Color.scarlet);
|
||||||
b.add(!player.isBuilder() ? "@unit.nobuild" : displayBlock.unplaceableMessage()).width(190f).wrap();
|
b.add(!player.isBuilder() ? "@unit.nobuild" : "@banned").width(190f).wrap();
|
||||||
b.left();
|
b.left();
|
||||||
}).padTop(2).left();
|
}).padTop(2).left();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ public class Block extends UnlockableContent{
|
|||||||
public int unitCapModifier = 0;
|
public int unitCapModifier = 0;
|
||||||
/** Whether the block can be tapped and selected to configure. */
|
/** Whether the block can be tapped and selected to configure. */
|
||||||
public boolean configurable;
|
public boolean configurable;
|
||||||
|
/** If true, this block can be configured by logic. */
|
||||||
|
public boolean logicConfigurable = false;
|
||||||
/** Whether this block consumes touchDown events when tapped. */
|
/** Whether this block consumes touchDown events when tapped. */
|
||||||
public boolean consumesTap;
|
public boolean consumesTap;
|
||||||
/** Whether to draw the glow of the liquid for this block, if it has one. */
|
/** Whether to draw the glow of the liquid for this block, if it has one. */
|
||||||
@@ -189,8 +191,6 @@ public class Block extends UnlockableContent{
|
|||||||
public float buildCost;
|
public float buildCost;
|
||||||
/** Whether this block is visible and can currently be built. */
|
/** Whether this block is visible and can currently be built. */
|
||||||
public BuildVisibility buildVisibility = BuildVisibility.hidden;
|
public BuildVisibility buildVisibility = BuildVisibility.hidden;
|
||||||
/** Defines when this block can be placed. */
|
|
||||||
public BuildPlaceability buildPlaceability = BuildPlaceability.always;
|
|
||||||
/** Multiplier for speed of building this block. */
|
/** Multiplier for speed of building this block. */
|
||||||
public float buildCostMultiplier = 1f;
|
public float buildCostMultiplier = 1f;
|
||||||
/** Multiplier for cost of research in tech tree. */
|
/** Multiplier for cost of research in tech tree. */
|
||||||
@@ -519,7 +519,7 @@ public class Block extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlaceable(){
|
public boolean isPlaceable(){
|
||||||
return isVisible() && buildPlaceability.placeable() && !state.rules.bannedBlocks.contains(this);
|
return isVisible() && !state.rules.bannedBlocks.contains(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when building of this block begins. */
|
/** Called when building of this block begins. */
|
||||||
@@ -532,11 +532,6 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return a message detailing why this block can't be placed. */
|
|
||||||
public String unplaceableMessage(){
|
|
||||||
return state.rules.bannedBlocks.contains(this) ? Core.bundle.get("banned") : buildPlaceability.message();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFloor(){
|
public boolean isFloor(){
|
||||||
return this instanceof Floor;
|
return this instanceof Floor;
|
||||||
}
|
}
|
||||||
@@ -622,7 +617,7 @@ public class Block extends UnlockableContent{
|
|||||||
public ItemStack[] researchRequirements(){
|
public ItemStack[] researchRequirements(){
|
||||||
ItemStack[] out = new ItemStack[requirements.length];
|
ItemStack[] out = new ItemStack[requirements.length];
|
||||||
for(int i = 0; i < out.length; i++){
|
for(int i = 0; i < out.length; i++){
|
||||||
int quantity = 40 + Mathf.round(Mathf.pow(requirements[i].amount, 1.15f) * 20 * researchCostMultiplier, 10);
|
int quantity = 60 + Mathf.round(Mathf.pow(requirements[i].amount, 1.15f) * 20 * researchCostMultiplier, 10);
|
||||||
|
|
||||||
out[i] = new ItemStack(requirements[i].item, UI.roundAmount(quantity));
|
out[i] = new ItemStack(requirements[i].item, UI.roundAmount(quantity));
|
||||||
}
|
}
|
||||||
@@ -674,6 +669,14 @@ public class Block extends UnlockableContent{
|
|||||||
|
|
||||||
consumes.init();
|
consumes.init();
|
||||||
|
|
||||||
|
if(!logicConfigurable){
|
||||||
|
configurations.each((key, val) -> {
|
||||||
|
if(UnlockableContent.class.isAssignableFrom(key)){
|
||||||
|
logicConfigurable = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(!outputsPower && consumes.hasPower() && consumes.getPower().buffered){
|
if(!outputsPower && consumes.hasPower() && consumes.getPower().buffered){
|
||||||
throw new IllegalArgumentException("Consumer using buffered power: " + name);
|
throw new IllegalArgumentException("Consumer using buffered power: " + name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ public class Build{
|
|||||||
for(int dy = 0; dy < type.size; dy++){
|
for(int dy = 0; dy < type.size; dy++){
|
||||||
int wx = dx + offsetx + tile.x, wy = dy + offsety + tile.y;
|
int wx = dx + offsetx + tile.x, wy = dy + offsety + tile.y;
|
||||||
|
|
||||||
|
|
||||||
Tile check = world.tile(wx, wy);
|
Tile check = world.tile(wx, wy);
|
||||||
|
|
||||||
if(
|
if(
|
||||||
@@ -136,6 +135,10 @@ public class Build{
|
|||||||
!check.interactable(team) || //cannot interact
|
!check.interactable(team) || //cannot interact
|
||||||
!check.floor().placeableOn || //solid wall
|
!check.floor().placeableOn || //solid wall
|
||||||
!((type.canReplace(check.block()) || //can replace type
|
!((type.canReplace(check.block()) || //can replace type
|
||||||
|
//controversial change: allow rebuilding damaged blocks
|
||||||
|
//this could be buggy and abusable, so I'm not enabling it yet
|
||||||
|
//note that this requires a change in BuilderComp as well
|
||||||
|
//(type == check.block() && check.centerX() == x && check.centerY() == y && check.build != null && check.build.health < check.build.maxHealth - 0.0001f) ||
|
||||||
(check.block instanceof ConstructBlock && check.<ConstructBuild>bc().cblock == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
(check.block instanceof ConstructBlock && check.<ConstructBuild>bc().cblock == type && check.centerX() == tile.x && check.centerY() == tile.y)) && //same type in construction
|
||||||
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
type.bounds(tile.x, tile.y, Tmp.r1).grow(0.01f).contains(check.block.bounds(check.centerX(), check.centerY(), Tmp.r2))) || //no replacement
|
||||||
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
(type.requiresWater && check.floor().liquidDrop != Liquids.water) //requires water but none found
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class LaunchPad extends Block{
|
|||||||
|
|
||||||
table.row();
|
table.row();
|
||||||
table.label(() -> {
|
table.label(() -> {
|
||||||
Sector dest = state.secinfo.getRealDestination();
|
Sector dest = state.rules.sector == null ? null : state.rules.sector.info.getRealDestination();
|
||||||
|
|
||||||
return Core.bundle.format("launch.destination",
|
return Core.bundle.format("launch.destination",
|
||||||
dest == null ? Core.bundle.get("sectors.nonelaunch") :
|
dest == null ? Core.bundle.get("sectors.nonelaunch") :
|
||||||
@@ -135,7 +135,11 @@ public class LaunchPad extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.button(Icon.upOpen, Styles.clearTransi, () -> {
|
table.button(Icon.upOpen, Styles.clearTransi, () -> {
|
||||||
ui.planet.showSelect(state.rules.sector, other -> state.secinfo.destination = other);
|
ui.planet.showSelect(state.rules.sector, other -> {
|
||||||
|
if(state.isCampaign()){
|
||||||
|
state.rules.sector.info.destination = other;
|
||||||
|
}
|
||||||
|
});
|
||||||
deselect();
|
deselect();
|
||||||
}).size(40f);
|
}).size(40f);
|
||||||
}
|
}
|
||||||
@@ -208,7 +212,7 @@ public class LaunchPad extends Block{
|
|||||||
public void remove(){
|
public void remove(){
|
||||||
if(!state.isCampaign()) return;
|
if(!state.isCampaign()) return;
|
||||||
|
|
||||||
Sector destsec = state.secinfo.getRealDestination();
|
Sector destsec = state.rules.sector.info.getRealDestination();
|
||||||
|
|
||||||
//actually launch the items upon removal
|
//actually launch the items upon removal
|
||||||
if(team() == state.rules.defaultTeam){
|
if(team() == state.rules.defaultTeam){
|
||||||
@@ -219,7 +223,7 @@ public class LaunchPad extends Block{
|
|||||||
dest.add(stack);
|
dest.add(stack);
|
||||||
|
|
||||||
//update export
|
//update export
|
||||||
state.secinfo.handleItemExport(stack);
|
state.rules.sector.info.handleItemExport(stack);
|
||||||
Events.fire(new LaunchItemEvent(stack));
|
Events.fire(new LaunchItemEvent(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
protected void getPotentialLinks(Tile tile, Cons<Building> others){
|
protected void getPotentialLinks(Tile tile, Cons<Building> others){
|
||||||
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.power != null &&
|
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.power != null &&
|
||||||
((!other.block.outputsPower && other.block.consumesPower) || (other.block.outputsPower && !other.block.consumesPower) || other.block instanceof PowerNode) &&
|
(other.block.outputsPower || other.block.consumesPower || other.block instanceof PowerNode) &&
|
||||||
overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile(), laserRange * tilesize) && other.team == player.team()
|
overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile(), laserRange * tilesize) && other.team == player.team()
|
||||||
&& !other.proximity.contains(e -> e.tile == tile) && !graphs.contains(other.power.graph);
|
&& !other.proximity.contains(e -> e.tile == tile) && !graphs.contains(other.power.graph);
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,6 @@ public class GenericCrafter extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStats(){
|
public void setStats(){
|
||||||
if(consumes.has(ConsumeType.liquid)){
|
|
||||||
ConsumeLiquidBase cons = consumes.get(ConsumeType.liquid);
|
|
||||||
cons.timePeriod = craftTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setStats();
|
super.setStats();
|
||||||
stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds);
|
stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds);
|
||||||
|
|
||||||
@@ -50,7 +45,7 @@ public class GenericCrafter extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(outputLiquid != null){
|
if(outputLiquid != null){
|
||||||
stats.add(Stat.output, outputLiquid.liquid, outputLiquid.amount, false);
|
stats.add(Stat.output, outputLiquid.liquid, outputLiquid.amount * (60f / craftTime), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class LiquidConverter extends GenericCrafter{
|
|||||||
public void setStats(){
|
public void setStats(){
|
||||||
super.setStats();
|
super.setStats();
|
||||||
stats.remove(Stat.output);
|
stats.remove(Stat.output);
|
||||||
stats.add(Stat.output, outputLiquid.liquid, outputLiquid.amount * craftTime, false);
|
stats.add(Stat.output, outputLiquid.liquid, outputLiquid.amount * 60f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LiquidConverterBuild extends GenericCrafterBuild{
|
public class LiquidConverterBuild extends GenericCrafterBuild{
|
||||||
|
|||||||
@@ -34,11 +34,6 @@ public class Separator extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStats(){
|
public void setStats(){
|
||||||
if(consumes.has(ConsumeType.liquid)){
|
|
||||||
ConsumeLiquidBase cons = consumes.get(ConsumeType.liquid);
|
|
||||||
cons.timePeriod = craftTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setStats();
|
super.setStats();
|
||||||
|
|
||||||
stats.add(Stat.output, new ItemFilterValue(item -> {
|
stats.add(Stat.output, new ItemFilterValue(item -> {
|
||||||
|
|||||||
@@ -339,15 +339,15 @@ public class CoreBlock extends StorageBlock{
|
|||||||
public void itemTaken(Item item){
|
public void itemTaken(Item item){
|
||||||
if(state.isCampaign() && team == state.rules.defaultTeam){
|
if(state.isCampaign() && team == state.rules.defaultTeam){
|
||||||
//update item taken amount
|
//update item taken amount
|
||||||
state.secinfo.handleCoreItem(item, -1);
|
state.rules.sector.info.handleCoreItem(item, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleItem(Building source, Item item){
|
public void handleItem(Building source, Item item){
|
||||||
if(net.server() || !net.active()){
|
if(net.server() || !net.active()){
|
||||||
if(team == state.rules.defaultTeam){
|
if(team == state.rules.defaultTeam && state.isCampaign()){
|
||||||
state.secinfo.handleCoreItem(item, 1);
|
state.rules.sector.info.handleCoreItem(item, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items.get(item) >= getMaximumAccepted(item)){
|
if(items.get(item) >= getMaximumAccepted(item)){
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ public class UnitFactory extends UnitBlock{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
//flags = EnumSet.of(BlockFlag.producer, BlockFlag.unitModifier);
|
|
||||||
//unitCapModifier = 2;
|
|
||||||
configurable = true;
|
configurable = true;
|
||||||
outputsPayload = true;
|
outputsPayload = true;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
@@ -44,6 +42,11 @@ public class UnitFactory extends UnitBlock{
|
|||||||
tile.progress = 0;
|
tile.progress = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
config(UnitType.class, (UnitFactoryBuild tile, UnitType val) -> {
|
||||||
|
tile.currentPlan = plans.indexOf(p -> p.unit == val);
|
||||||
|
tile.progress = 0;
|
||||||
|
});
|
||||||
|
|
||||||
consumes.add(new ConsumeItemDynamic((UnitFactoryBuild e) -> e.currentPlan != -1 ? plans.get(e.currentPlan).requirements : ItemStack.empty));
|
consumes.add(new ConsumeItemDynamic((UnitFactoryBuild e) -> e.currentPlan != -1 ? plans.get(e.currentPlan).requirements : ItemStack.empty));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +91,18 @@ public class UnitFactory extends UnitBlock{
|
|||||||
super.setStats();
|
super.setStats();
|
||||||
|
|
||||||
stats.remove(Stat.itemCapacity);
|
stats.remove(Stat.itemCapacity);
|
||||||
|
|
||||||
|
stats.add(Stat.output, table -> {
|
||||||
|
Seq<UnitPlan> p = plans.select(u -> u.unit.unlockedNow());
|
||||||
|
table.row();
|
||||||
|
for(var plan : p){
|
||||||
|
if(plan.unit.unlockedNow()){
|
||||||
|
table.image(plan.unit.icon(Cicon.small)).size(8 * 3).padRight(2).right();
|
||||||
|
table.add(plan.unit.localizedName).left();
|
||||||
|
table.row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -46,6 +46,6 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void display(Stats stats){
|
public void display(Stats stats){
|
||||||
stats.add(booster ? Stat.booster : Stat.input, liquid, amount * timePeriod, timePeriod == 60);
|
stats.add(booster ? Stat.booster : Stat.input, liquid, amount * 60f, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,6 @@ import mindustry.gen.*;
|
|||||||
public abstract class ConsumeLiquidBase extends Consume{
|
public abstract class ConsumeLiquidBase extends Consume{
|
||||||
/** amount used per frame */
|
/** amount used per frame */
|
||||||
public final float amount;
|
public final float amount;
|
||||||
/**
|
|
||||||
* How much time is taken to use this liquid, in ticks. Used only for visual purposes.
|
|
||||||
* Example: a normal ConsumeLiquid with 10/s and a 10 second timePeriod would display as "100 seconds".
|
|
||||||
* Without a time override, it would display as "10 liquid/second".
|
|
||||||
* This is used for generic crafters.
|
|
||||||
*/
|
|
||||||
public float timePeriod = 60;
|
|
||||||
|
|
||||||
public ConsumeLiquidBase(float amount){
|
public ConsumeLiquidBase(float amount){
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
|
|||||||
@@ -50,6 +50,6 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void display(Stats stats){
|
public void display(Stats stats){
|
||||||
stats.add(booster ? Stat.booster : Stat.input, new LiquidFilterValue(filter, amount * timePeriod, timePeriod == 60f));
|
stats.add(booster ? Stat.booster : Stat.input, new LiquidFilterValue(filter, amount * 60f, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
package mindustry.world.meta;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.func.*;
|
|
||||||
import mindustry.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like BuildVisiblity, but defines whether a block can be *placed*, with an extra message.
|
|
||||||
* This is like defining a conditionally banned block.
|
|
||||||
* */
|
|
||||||
public enum BuildPlaceability{
|
|
||||||
always(() -> true),
|
|
||||||
sectorCaptured(() -> Vars.state.rules.sector != null && Vars.state.rules.sector.isCaptured());
|
|
||||||
|
|
||||||
private final Boolp placeability;
|
|
||||||
|
|
||||||
BuildPlaceability(Boolp placeability){
|
|
||||||
this.placeability = placeability;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean placeable(){
|
|
||||||
return placeability.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return why this block is banned. */
|
|
||||||
public String message(){
|
|
||||||
return Core.bundle.get("unplaceable." + name().toLowerCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@ public enum BuildVisibility{
|
|||||||
debugOnly(() -> false),
|
debugOnly(() -> false),
|
||||||
sandboxOnly(() -> Vars.state.rules.infiniteResources),
|
sandboxOnly(() -> Vars.state.rules.infiniteResources),
|
||||||
campaignOnly(() -> Vars.state.isCampaign()),
|
campaignOnly(() -> Vars.state.isCampaign()),
|
||||||
lightingOnly(() -> Vars.state.rules.lighting),
|
lightingOnly(() -> Vars.state.rules.lighting || Vars.state.isCampaign()),
|
||||||
ammoOnly(() -> Vars.state.rules.unitAmmo);
|
ammoOnly(() -> Vars.state.rules.unitAmmo);
|
||||||
|
|
||||||
private final Boolp visible;
|
private final Boolp visible;
|
||||||
|
|||||||
12
fastlane/metadata/android/en-US/changelogs/29675.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
- Added 4 new custom game maps (untested)
|
||||||
|
- Added new stats to unit info
|
||||||
|
- Added buttons to clear campaign research+saves
|
||||||
|
- Added fog weather
|
||||||
|
- Added weather to some custom game maps
|
||||||
|
- Added support for weather in JSON mods
|
||||||
|
- Added better control sync for commanded units
|
||||||
|
- Added recipe display for reconstructors
|
||||||
|
- Added titanium fuse ammo
|
||||||
|
- Made campaign load research from older versions (5.0)
|
||||||
|
- Campaign: Added more schematics for bases to use
|
||||||
|
- router.
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=f8ef0f3a72de0f79ca49da895fed0b6889cd597e
|
archash=7090a07ce5d02dcb697f6c5a8d1fb6e0a00de45f
|
||||||
|
|||||||