happy birthday to me :)

This commit is contained in:
Ngọc Lam
2020-11-29 11:02:00 +07:00
committed by GitHub
30 changed files with 795 additions and 539 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -17,11 +17,14 @@ linkfail = 打开链接失败!\n网址已复制到您的剪贴板。
screenshot = 屏幕截图已保存到 {0}
screenshot.invalid = 地图太大,可能没有足够的内存用于截图。
gameover = 游戏结束
gameover.disconnect = 断开连接
gameover.pvp = [accent] {0}[]队获胜!
gameover.waiting = [accent]正在等待下一张地图...
highscore = [accent]新纪录!
copied = 已复制
copied = 已复制
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 = 这部分玩法还未开发完成。
indev.campaign = [accent]您已经到达战役模式的结尾![]\n\n这是内容所能做到的。 未来的更新中将添加行星际旅行。
load.sound = 音乐加载中
load.map = 地图加载中
@@ -57,6 +60,7 @@ schematic.rename = 重命名蓝图
schematic.info = {0}x{1}{2} 个方块
schematic.disabled = [scarlet]蓝图已禁用![]\n您不能在此[accent]地图[]或[accent]服务器[]上使用蓝图.
stats = 统计资料
stat.wave = 防守波数:[accent]{0}
stat.enemiesDestroyed = 消灭敌人:[accent]{0}
stat.built = 建造建筑:[accent]{0}
@@ -189,6 +193,10 @@ servers.local = 本地服务器
servers.remote = 远程服务器
servers.global = 全球服务器
servers.showhidden = 显示隐藏的服务器
server.shown = 显示
server.hidden = 隐藏
trace = 跟踪玩家
trace.playername = 玩家名称:[accent]{0}
trace.ip = IP 地址:[accent]{0}
@@ -267,6 +275,9 @@ cancel = 取消
openlink = 打开链接
copylink = 复制链接
back = 返回
crash.export = 导出崩溃日志
crash.none = 找不到崩溃日志。
crash.exported = 崩溃日志已导出。
data.export = 导出数据
data.import = 导入数据
data.openfolder = 打开数据文件夹
@@ -283,6 +294,7 @@ cancelbuilding = [accent][[{0}][]来清除规划
selectschematic = [accent][[{0}][]来选择复制
pausebuilding = [accent][[{0}][]来暂停建造
resumebuilding = [scarlet][[{0}][]来恢复建造
showui = UI已隐藏\n按[accent][[{0}][]显示UI
wave = [accent]第{0}波
wave.cap = [accent]Wave {0}/{1}
wave.waiting = [lightgray]下一波倒计时:{0}秒
@@ -290,6 +302,8 @@ wave.waveInProgress = [lightgray]波次袭来
waiting = [lightgray]等待中…
waiting.players = 等待玩家中…
wave.enemies = [lightgray]剩余 {0} 个敌人
wave.enemycores = [accent]{0}[lightgray] 敌人核心(多个)
wave.enemycore = [accent]{0}[lightgray] 敌人核心
wave.enemy = [lightgray]剩余 {0} 个敌人
wave.guardianwarn = Boss 将在[accent]{0}[]波后到来。
wave.guardianwarn.one = Boss 将在[accent]{0}[]波后到来。
@@ -350,6 +364,7 @@ waves.invalid = 剪贴板中的波次信息无效。
waves.copied = 波次信息已复制。
waves.none = 没有定义敌人。\n请注意这将自动替换为默认的敌人列表。
#these are intentionally in lower case
wavemode.counts = 数目
wavemode.totals = 总和
wavemode.health = 生命值
@@ -462,6 +477,8 @@ load = 载入游戏
save = 保存
fps = 帧数:{0}
ping = 延迟:{0}毫秒
memory = 内存: {0}mb
memory2 = 内存:\n {0}mb +\n {1}mb
language.restart = 为了使语言设置生效请重启游戏。
settings = 设置
tutorial = 教程
@@ -476,24 +493,21 @@ complete = [lightgray]完成:
requirement.wave = {1}中的第{0}波次
requirement.core = 在{0}中摧毁敌方核心
requirement.research = 研究 {0}
requirement.produce = 生产 {0}
requirement.capture = 占领 {0}
bestwave = [lightgray]最高波次:{0}
launch.text = 发射
research.multiplayer = 仅有服主可研究物品。
map.multiplayer = 仅有服主可查看区域。
uncover = 解锁
configure = 设定装运的数量
loadout = 装运
resources = 资源
bannedblocks = 禁用建筑
addall = 添加所有
launch.from = 发射地: [accent]{0}
launch.destination = 目的地: {0}
configure.invalid = 数量必须是0到{0}之间的数字。
zone.unlocked = [lightgray]{0} 已解锁。
zone.requirement.complete = 完成{0}。\n已达成解锁{1}的要求。
zone.resources = 地图中的资源:
zone.objective = [lightgray]目标:[accent]{0}
zone.objective.survival = 生存
zone.objective.attack = 摧毁敌方核心
add = 添加…
boss.health = Boss 生命值
@@ -517,17 +531,41 @@ weather.fog.name = 雾
sectors.unexplored = [lightgray]未探索
sectors.resources = 资源:
sectors.production = 产出:
sectors.export = 输出:
sectors.time = 时间:
sectors.threat = 威胁
sectors.wave = 进攻波:
sectors.stored = 贮存:
sectors.resume = 继续
sectors.launch = 发射
sectors.select = 选择
sectors.nonelaunch = [lightgray]无 (太阳)
sectors.rename = 重命名区块
sectors.enemybase = [scarlet]敌人基地
sectors.vulnerable = [scarlet]脆弱的
sectors.underattack = [scarlet]遭到攻击![accent]{0}% 被摧毁
sectors.survives = [accent]存活{0}波
sectors.go = 进入
sector.curcapture = 区域已占领
sector.curlost = 区域丢失
sector.missingresources = [scarlet]核心资源不足
sector.attacked = 区域[accent]{0}[white]受到攻击!
sector.lost = 区域[accent]{0}[white]已丢失!
#note: the missing space in the line below is intentional
sector.captured = 区域[accent]{0}[white]已占领!
threat.low =
threat.medium =
threat.high =
threat.extreme = 极高
threat.eradication = 根除
planets = 行星
planet.serpulo.name = 塞普罗
planet.sun.name = 太阳
sector.impact0078.name = 影响0078
sector.groundZero.name = 零号地区
sector.craters.name = 陨石带
sector.frozenForest.name = 冰冻森林
@@ -539,6 +577,10 @@ sector.overgrowth.name = 增生区
sector.tarFields.name = 油田
sector.saltFlats.name = 盐碱荒滩
sector.fungalPass.name = 真菌通道
sector.biomassFacility.name = 生物质合成设施
sector.windsweptIslands.name = 风吹群岛
sector.extractionOutpost.name = 萃取前哨
sector.planetaryTerminal.name = 行星发射终端
sector.groundZero.description = 踏上旅程的最佳位置。这儿的敌人威胁很小,但资源也少。\n收集尽可能多的铅和铜。\n出发吧
sector.frozenForest.description = 即使是靠近山脉的这里,孢子也已经扩散。他们不能长期停留在寒冷的温度中。\n\n开始运用电力。建造火力发电机并学会使用修理者。
@@ -573,7 +615,6 @@ settings.clearcampaignsaves.confirm = 您确定要清除战役进度?
paused = [accent]< 暂停 >
clear = 清除
banned = [scarlet]已禁止
unplaceable.sectorcaptured = [scarlet]需要占领区块
yes =
no =
info.title = [accent]详情
@@ -583,6 +624,7 @@ unit.nobuild = [scarlet]单位未能建造
lastaccessed = [lightgray]上次操作: {0}
block.unknown = [lightgray]???
stat.description = 介绍
stat.input = 输入
stat.output = 输出
stat.booster = 增强物品/液体
@@ -610,6 +652,8 @@ stat.memorycapacity = 内存容量
stat.basepowergeneration = 基础能源输出
stat.productiontime = 生产时间
stat.repairtime = 建筑完全修复时间
stat.weapons = 武器
stat.bullet = 子弹
stat.speedincrease = 提速
stat.range = 范围
stat.drilltier = 可钻探矿物
@@ -642,12 +686,15 @@ stat.minetier = 采矿等级
stat.payloadcapacity = 载货容量
stat.commandlimit = 指挥上限
stat.abilities = 能力
stat.canboost = 助推器
stat.flying = 飞行
ability.forcefield = 力墙场
ability.repairfield = 修复场
ability.statusfield = 状态场
ability.unitspawn = {0} 工厂
ability.shieldregenfield = 护盾再生场
ability.movelightning = 闪电移动
bar.drilltierreq = 需要更好的钻头
bar.noresources = 缺失资源
@@ -676,12 +723,14 @@ units.processorcontrol = [lightgray]由处理器控制
bullet.damage = [stat]{0}[lightgray] 伤害
bullet.splashdamage = [stat]{0}[lightgray] 范围伤害 ~[stat] {1}[lightgray] 格
bullet.incendiary = [stat] 燃烧
bullet.sapping = [stat]sapping
bullet.homing = [stat] 追踪
bullet.shock = [stat] 电击
bullet.frag = [stat] 分裂
bullet.knockback = [stat]{0}[lightgray] 击退
bullet.pierce = [stat]{0}[lightgray]x 穿透
bullet.infinitepierce = [stat]pierce
bullet.healpercent = [stat]{0}[lightgray]% 修复
bullet.freezing = [stat] 冰冻
bullet.tarred = [stat] 减速
bullet.multiplier = [stat]{0}[lightgray]x 装弹数量
@@ -706,6 +755,7 @@ unit.items = 物品
unit.thousands = K
unit.millions = M
unit.billions = B
category.purpose = 介绍
category.general = 普通
category.power = 能量
category.liquids = 液体
@@ -719,6 +769,7 @@ setting.blockreplace.name = 自动推荐合适的建筑
setting.linear.name = 抗锯齿
setting.hints.name = 提示
setting.flow.name = 显示资源传送速度[scarlet] (实验性)
setting.backgroundpause.name = 在背景中暂停
setting.buildautopause.name = 自动暂停建造
setting.animatedwater.name = 流动的水
setting.animatedshields.name = 动态画面
@@ -747,7 +798,6 @@ setting.conveyorpathfinding.name = 传送带自动寻路
setting.sensitivity.name = 控制器灵敏度
setting.saveinterval.name = 自动保存间隔
setting.seconds = {0} 秒
setting.blockselecttimeout.name = 建筑选择超时
setting.milliseconds = {0} 毫秒
setting.fullscreen.name = 全屏
setting.borderlesswindow.name = 无边界窗口[lightgray](可能需要重启)
@@ -836,6 +886,8 @@ keybind.menu.name = 菜单
keybind.pause.name = 暂停
keybind.pause_building.name = 暂停/继续建造
keybind.minimap.name = 小地图
keybind.planet_map.name = 行星地图
keybind.research.name = 研究
keybind.chat.name = 聊天
keybind.player_list.name = 玩家列表
keybind.console.name = 控制台
@@ -899,6 +951,7 @@ content.item.name = 物品
content.liquid.name = 液体
content.unit.name = 部队
content.block.name =
content.sector.name = 区域
item.copper.name =
item.lead.name =
@@ -959,6 +1012,7 @@ block.resupply-point.name = 补给点
block.parallax.name = 差扰光束
block.cliff.name = 悬崖
block.sand-boulder.name = 砂岩
block.basalt-boulder.name = 玄武岩巨石
block.grass.name = 草地
block.slag.name = 矿渣
block.space.name = 太空
@@ -1056,7 +1110,6 @@ block.conveyor.name = 传送带
block.titanium-conveyor.name = 钛传送带
block.plastanium-conveyor.name = 塑钢传送带
block.armored-conveyor.name = 装甲传送带
block.armored-conveyor.description = 运送物品,与钛传送带一样的速度,但有更强的装甲。除其他传送带,不接受任何边上的输入。
block.junction.name = 连接器
block.router.name = 路由器
block.distributor.name = 分配器
@@ -1064,7 +1117,6 @@ block.sorter.name = 分类器
block.inverted-sorter.name = 反向分类器
block.message.name = 信息板
block.illuminator.name = 照明器
block.illuminator.description = 小型、紧凑、可配置的光源。需要能量运行。
block.overflow-gate.name = 溢流门
block.underflow-gate.name = 反向溢流门
block.silicon-smelter.name = 硅冶炼厂
@@ -1160,6 +1212,11 @@ block.payload-router.name = 载荷路由器
block.disassembler.name = 解离机
block.silicon-crucible.name = 热能坩埚
block.overdrive-dome.name = 超速穹顶投射器
#experimental, may be removed
block.block-forge.name = 方块熔炉
block.block-loader.name = 方块装载机
block.block-unloader.name = 方块卸载机
block.interplanetary-accelerator.name = 行星际加速器
block.switch.name = 开关
block.micro-processor.name = 微型处理器
@@ -1178,30 +1235,45 @@ team.derelict.name = 灰
team.green.name = 绿
team.purple.name =
tutorial.next = [lightgray]<点击以继续>
tutorial.intro = 您已进入[scarlet] Mindustry 教程[]。[]\n使用[accent][[WASD][]键移动机甲和视角。\n[accent]按住[[Ctrl]并转动鼠标滚轮[]缩放视野。\n让我们从[accent]采集铜矿[]开始。先移动到铜矿旁边,然后点按矿脉附近散落的矿物。\n\n[accent]{0}/{1} 铜
tutorial.intro.mobile = 您已进入[scarlet] Mindustry 教程[]。\n在屏幕上滑动来继续。\n[accent]双指捏合[] 来缩小和放大。\n让我们从[accent]采集铜矿[]开始。先移动到铜矿旁边,然后点按矿脉附近散落的矿物。\n\n[accent]铜 {0}/{1}
tutorial.drill = 手动采矿效率不高。\n[accent]钻头[]可以自动采矿。\n让我们在在铜矿上放一个。\n点击右下角的钻头菜单。\n选择[accent]机械钻头[]。\n单击将其放置在铜矿上。\n[accent]右键单击[]来停止。
tutorial.drill.mobile = 手动采矿效率不高。\n[accent]钻头[]可以自动采矿。\n点右下角的钻头菜单。\n选择[accent]机械钻头[]。\n点一下将其放在铜矿上点[accent]对号[]来确定。\n点[accent]叉号[]来取消。
tutorial.blockinfo = 每种钻头都有其独特的数据。每个钻头只能开采部分矿石。\n若要查看建筑的详细信息[accent]在菜单中点击问号。[]\n\n[accent]现在查看机械钻头的数据吧。[]
tutorial.conveyor = [accent]传送带[]可以把物资传送到核心。\n请在钻头到核心间建造一条传送带。
tutorial.conveyor.mobile = [accent]传送带[]可以把物资传送到核心。\n请在钻头到核心间建造一条传送带。\n[accent]长按数秒[]并向一个方向拖动来直线放置。\n\n[accent]{0}/{1} 条传送带\n[accent]0/1 物品
tutorial.turret = 必须建造防御建筑来击退[lightgray]敌人[]。\n请在核心附近造一个双管炮。
tutorial.drillturret = 双管炮需要[accent]铜[]作弹药来射击。\n可以放一个钻头在炮塔附近供应铜。
tutorial.pause = 在战斗中,您可以[accent]暂停游戏[]。\n暂停时您可以规划建筑物。\n\n按[accent]空格[]暂停。
tutorial.pause.mobile = 在战斗中,您可以[accent]暂停游戏[]。\n暂停时您可以规划建筑物。\n\n[accent]点击左上角的按钮以暂停。
tutorial.unpause = 现在再次按空格以继续。
tutorial.unpause.mobile = 现在再次点按以继续
tutorial.breaking = 建筑经常需要拆除。\n[accent]按住鼠标右键[]来拆除选中的建筑。[]\n\n[accent]使用范围拆除来拆除核心左侧的废墙。
tutorial.breaking.mobile = 建筑经常需要拆除。\n[accent]选择拆除模式[],点击建筑以拆除。\n[accent]长按几秒[]并拖动来范围拆除。\n点击对号来确定。\n\n[accent]使用范围拆除来拆除核心左侧的废墙。
tutorial.withdraw = 有时,从建筑中取出物品是必要的。\n[accent]点击包含物品的建筑[],然后[accent]点击在方框中的物品[]。\n可以通过[accent]点击或长按[]来取出物品。\n\n[accent]从核心中取出一些铜[]。
tutorial.deposit = 将物品从机甲拖向建筑来放下物品。\n\n[accent]将铜放回核心[]。
tutorial.waves = [lightgray]敌人[]来了。\n\n保护核心防御两波攻击。造更多的炮塔。[accent]点击[]以射击。\n建造更多的炮塔和钻头并采更多的矿
tutorial.waves.mobile = [lightgray]敌人[]来了。\n\n保护核心防御两波攻击。造更多的炮塔。你的机甲将对敌人自动开火。\n建造更多的炮塔和钻头并采更多的矿
tutorial.launch = 进入特定波次后,你可以[accent]发射核心(起飞)[][accent]带走核心中的所有资源[]并抛下所有的建筑。\n装运的资源可用于研究科技。\n\n[accent]点击发射按钮。
hint.skip = 跳过
hint.desktopMove = 使用[accent][[WASD][]来移动.
hint.zoom = [accent]滚动[]放大或缩小.
hint.mine = 移动到\uf8c4铜矿附近并点按[accent]tap[]进行手动开采
hint.desktopShoot = [accent][[Left-click][]射击.
hint.depositItems = 要转移物品,请将其从飞船上拖到核心。
hint.respawn = 要重生飞船,请按[accent][[V][].
hint.respawn.mobile = 您已切换控制单元/结构. 如果要重生飞船请[accent]点击左上方的图标(那个和你长得一样的).[]
hint.desktopPause = 按[accent][[Space][]暂停和取消暂停游戏.
hint.placeDrill = 选择\ue85e[accent]钻头[]右下角菜单中的标签,然后选择一个\uf870 [accent]钻头[]然后单击铜矿将其放置.
hint.placeDrill.mobile = 选择\ue85e[accent]钻头[]右下角菜单中的标签,然后选择一个\uf870 [accent]钻头[]然后点击铜矿将其放置.\n\n按下\ue800 [accent]复选标记[]在右下角按钮确认.
hint.placeConveyor = 传送带将物品从钻头移到其他块中。选择一个\uf896 [accent]传送带[]从\ue814 [accent]布局[]标签.\n\n单击并拖动以放置多个传送带.\n[accent]滚动[]旋转.
hint.placeConveyor.mobile = 传送带将物品从钻头移到其他块中。选择一个\uf896 [accent]传送带[]从\ue814 [accent]布局[]标签.\n\n按住手指一秒钟然后拖动以放置多个传送带.
hint.placeTurret = 放置\uf861 [accent]炮塔[]保卫你的基地从敌人手中.\n\n炮塔需要弹药-在这种情况下e, \uf838copper.\n使用传送带和钻头为它们供弹
hint.breaking = [accent]右击[]并拖动以拆除方块.
hint.breaking.mobile = 激活\ue817 [accent]锤子[]在右下角点击以拆除方块.\n\n按住手指一秒钟然后拖动以选择.
hint.research = 使用\ue875 [accent]科技树[]按钮研究新技术.
hint.research.mobile = 使用\ue875 [accent]科技树[]按钮在\ue88c [accent]菜单[]去研究新技术.
hint.unitControl = 按住[accent][[L-ctrl][]和[accent]点击[]控制友军单位或炮塔
hint.unitControl.mobile = [accent][双击[]控制友军单位或炮塔(双击)
hint.launch = 一旦收集到足够的资源,您就可以[accent]发射[]通过选择附近的区域从\ue827 [accent]地图[]在右下角.
hint.launch.mobile = 一旦收集到足够的资源,您就可以[accent]发射[]通过选择附近的区域从\ue827 [accent]地图[]在\ue88c [accent]菜单[].
hint.schematicSelect = 按住[accent][[F][]并拖动以选择要复制和粘贴的块.\n\n[accent][[Middle Click][]复制单个块类型.
hint.conveyorPathfind = 按住[accent][[L-Ctrl][]拖动,传送带会自动生成路径.
hint.conveyorPathfind.mobile = 启用\ue844 [accent]对角线模式[]并拖动,传送带会自动生成路径.
hint.boost = 按住[accent][[L-Shift][]用当前单位飞越障碍物.\n\n只有少数地面单位有助推器.(首先排除爬虫家族)
hint.command = 按accent][[G][]指挥附近的单位编队.
hint.command.mobile = [accent][双击][]您的部队指挥附近的部队编队.(双击)
hint.payloadPickup = 按[accent][[[]捡起小方块或单位.
hint.payloadPickup.mobile = [accent]点住]一个小方块或一个单位来捡起来.
hint.payloadDrop = 按[accent]][]放下有效载荷.
hint.payloadDrop.mobile = [accent]点住[]一个空的位置将有效载荷丢到那里.(不是很精准)
hint.waveFire = [accent]进攻波[]炮塔加水弹药会自动扑灭附近的大火.(浪涌和海啸)
hint.generator = \uf879 [accent]燃烧发电机[]燃烧煤炭并将电力传输到相邻方块.\n\n电力传输范围可以扩展用\uf87f [accent]能量节点[].
item.copper.description = 一种最基本的的建筑材料。在各种类型的建筑中被广泛使用。
item.copper.details = 铜. 在Serpulo上的金属异常丰富。 除非加固,否则结构较弱。
item.lead.description = 一种基本的电力材料。广泛用于电子设备和液体输送模块。
item.lead.details = Dense. Inert. Extensively used in batteries.\nNote: Likely toxic to biological life forms. Not that there are many left here.
item.metaglass.description = 一种致密坚硬的复合玻璃。广泛用于液体输送和存储。
item.graphite.description = 一种高密度的碳材料,用于弹药和电器元件。
item.sand.description = 一种常见的材料,广泛用于冶炼,包括制作合金和助熔剂。

View File

@@ -103,3 +103,4 @@ newlocknew (freesound.org)
dsmolenaers (freesound.org)
Headphaze (freesound.org)
VolasYouKnow
Ángel Rodríguez Aguilera

View File

@@ -112,8 +112,8 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
super.add(module);
//autoload modules when necessary
if(module instanceof Loadable){
assets.load((Loadable)module);
if(module instanceof Loadable l){
assets.load(l);
}
}

View File

@@ -135,8 +135,8 @@ public class Logic implements ApplicationListener{
//convert all blocks to neutral, randomly killing them
if(tile.isCenter() && tile.build != null && tile.build.team == state.rules.waveTeam){
Building b = tile.build;
Call.setTeam(b, Team.derelict);
Time.run(Mathf.random(0f, 60f * 6f), () -> {
Call.setTeam(b, Team.derelict);
if(Mathf.chance(0.25)){
b.kill();
}

View File

@@ -15,7 +15,7 @@ public class Fires{
private static final float baseLifetime = 1000f;
private static final IntMap<Fire> map = new IntMap<>();
/** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */
/** Start a fire on the tile. If there already is a fire there, refreshes its lifetime. */
public static void create(Tile tile){
if(net.client() || tile == null || !state.rules.fire) return; //not clientside.

View File

@@ -273,7 +273,8 @@ public abstract class BulletType extends Content{
}
if(weaveMag > 0){
b.vel.rotate(Mathf.sin(Mathf.randomSeed(b.id, 10f) + b.time, weaveScale, weaveMag) * Time.delta);
float scl = Mathf.randomSeed(id, 0.9f, 1.1f);
b.vel.rotate(Mathf.sin(b.time + Mathf.PI * weaveScale/2f * scl, weaveScale * scl, weaveMag) * Time.delta);
}
if(trailChance > 0){

View File

@@ -14,6 +14,7 @@ import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.audio.*;
import mindustry.content.*;
@@ -29,8 +30,8 @@ import mindustry.logic.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.ConstructBlock.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.power.*;
@@ -621,6 +622,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
* containers, it gets added to the block's inventory.
*/
public void offload(Item item){
produced(item, 1);
int dump = this.cdump;
if(!net.client() && state.isCampaign() && team == state.rules.defaultTeam) item.unlock();
@@ -654,6 +656,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
return false;
}
public void produced(Item item){
produced(item, 1);
}
public void produced(Item item, int amount){
if(Vars.state.rules.sector != null && team == state.rules.defaultTeam) Vars.state.rules.sector.info.handleProduction(item, amount);
}
/** Try dumping any item near the */
public boolean dump(){
return dump(null);

View File

@@ -76,7 +76,11 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
if(mineTimer >= 50f + item.hardness*15f){
mineTimer = 0;
if(state.rules.sector != null && team() == state.rules.defaultTeam) state.rules.sector.info.handleProduction(item, 1);
if(core != null && within(core, mineTransferRange) && core.acceptStack(item, 1, this) == 1 && offloadImmediately()){
//add item to inventory before it is transferred
if(item() == item) addItem(item);
Call.transferItemTo(self(), item, 1,
mineTile.worldx() + Mathf.range(tilesize / 2f),
mineTile.worldy() + Mathf.range(tilesize / 2f), core);

View File

@@ -23,6 +23,8 @@ public class SectorInfo{
/** Core input statistics. */
public ObjectMap<Item, ExportStat> production = new ObjectMap<>();
/** Raw item production statistics. */
public ObjectMap<Item, ExportStat> rawProduction = new ObjectMap<>();
/** Export statistics. */
public ObjectMap<Item, ExportStat> export = new ObjectMap<>();
/** Items stored in all cores. */
@@ -77,15 +79,21 @@ public class SectorInfo{
/** Counter refresh state. */
private transient Interval time = new Interval();
/** Core item storage to prevent spoofing. */
private transient int[] coreItemCounts;
/** Core item storage input/output deltas. */
private @Nullable transient int[] coreDeltas;
/** Core item storage input/output deltas. */
private @Nullable transient int[] productionDeltas;
/** Handles core item changes. */
public void handleCoreItem(Item item, int amount){
if(coreItemCounts == null){
coreItemCounts = new int[content.items().size];
}
coreItemCounts[item.id] += amount;
if(coreDeltas == null) coreDeltas = new int[content.items().size];
coreDeltas[item.id] += amount;
}
/** Handles raw production stats. */
public void handleProduction(Item item, int amount){
if(productionDeltas == null) productionDeltas = new int[content.items().size];
productionDeltas[item.id] += amount;
}
/** @return the real location items go when launched on this sector */
@@ -176,6 +184,11 @@ public class SectorInfo{
damage = 0;
hasSpawns = spawner.countSpawns() > 0;
//cap production at raw production.
production.each((item, stat) -> {
stat.mean = Math.min(stat.mean, rawProduction.get(item, ExportStat::new).mean);
});
if(state.rules.sector != null){
state.rules.sector.saveInfo();
}
@@ -189,8 +202,6 @@ public class SectorInfo{
//updating in multiplayer as a client doesn't make sense
if(net.client()) return;
CoreBuild ent = state.rules.defaultTeam.core();
//refresh throughput
if(time.get(refreshPeriod)){
@@ -208,30 +219,34 @@ public class SectorInfo{
stat.mean = stat.means.rawMean();
});
if(coreItemCounts == null){
coreItemCounts = new int[content.items().size];
}
if(coreDeltas == null) coreDeltas = new int[content.items().size];
if(productionDeltas == null) productionDeltas = new int[content.items().size];
//refresh core items
for(Item item : content.items()){
ExportStat stat = production.get(item, ExportStat::new);
if(!stat.loaded){
stat.means.fill(stat.mean);
stat.loaded = true;
}
updateDelta(item, production, coreDeltas);
updateDelta(item, rawProduction, productionDeltas);
//get item delta
int delta = coreItemCounts[item.id];
//store means
stat.means.add(delta);
stat.mean = stat.means.rawMean();
production.get(item).mean = Math.min(production.get(item).mean, rawProduction.get(item).mean);
}
Arrays.fill(coreItemCounts, 0);
Arrays.fill(coreDeltas, 0);
Arrays.fill(productionDeltas, 0);
}
}
void updateDelta(Item item, ObjectMap<Item, ExportStat> map, int[] deltas){
ExportStat stat = map.get(item, ExportStat::new);
if(!stat.loaded){
stat.means.fill(stat.mean);
stat.loaded = true;
}
//store means
stat.means.add(deltas[item.id]);
stat.mean = stat.means.rawMean();
}
public ObjectFloatMap<Item> exportRates(){
ObjectFloatMap<Item> map = new ObjectFloatMap<>();
export.each((item, value) -> map.put(item, value.mean));

View File

@@ -105,7 +105,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public static void transferItemTo(@Nullable Unit unit, Item item, int amount, float x, float y, Building build){
if(build == null || build.items == null) return;
if(unit != null) unit.stack.amount = Math.max(unit.stack.amount - amount, 0);
if(unit != null && unit.item() == item) unit.stack.amount = Math.max(unit.stack.amount - amount, 0);
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, build, () -> {}));

View File

@@ -14,7 +14,7 @@ import mindustry.world.*;
/** "Compiles" a sequence of statements into instructions. */
public class LAssembler{
public static ObjectMap<String, Func<String[], LStatement>> customParsers = new ObjectMap<>();
public static final int maxTokenLength = 40;
public static final int maxTokenLength = 36;
private int lastVar;
/** Maps names to variable IDs. */

View File

@@ -247,7 +247,7 @@ public class Mods implements Loadable{
mods.add(mod);
}catch(Throwable e){
if(e instanceof ClassNotFoundException && e.getMessage().contains("mindustry.plugin.Plugin")){
Log.info("Plugin @ is outdated and needs to be ported to 6.0! Update its main class to inherit from 'mindustry.mod.Plugin'.");
Log.info("Plugin @ is outdated and needs to be ported to 6.0! Update its main class to inherit from 'mindustry.mod.Plugin'. See https://mindustrygame.github.io/wiki/modding/6-migrationv6/");
}else{
Log.err("Failed to load mod file @. Skipping.", file);
Log.err(e);

View File

@@ -13,7 +13,7 @@ import mindustry.io.*;
public class Weapon{
/** displayed weapon region */
public String name;
public String name = "";
/** bullet shot */
public BulletType bullet;
/** shell ejection effect */

View File

@@ -29,7 +29,11 @@ public class Bar extends Element{
public Bar(Prov<String> name, Prov<Color> color, Floatp fraction){
this.fraction = fraction;
lastValue = value = Mathf.clamp(fraction.get());
try{
lastValue = value = Mathf.clamp(fraction.get());
}catch(Exception e){ //getting the fraction may involve referring to invalid data
lastValue = value = 0f;
}
update(() -> {
try{
this.name = name.get();

View File

@@ -19,6 +19,7 @@ import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import mindustry.world.modules.*;
import static mindustry.Vars.*;
@@ -275,8 +276,9 @@ public class ConstructBlock extends Block{
if(clampedAmount > 0 && accumulated > 0){ //if it's positive, add it to the core
if(core != null && requirements[i].item.unlockedNow()){ //only accept items that are unlocked
int accepting = core.acceptStack(requirements[i].item, accumulated, builder);
core.handleStack(requirements[i].item, accepting, builder);
int accepting = Math.min(accumulated, ((CoreBuild)core).storageCapacity - core.items.get(requirements[i].item));
//transfer items directly, as this is not production.
core.items.add(requirements[i].item, accepting);
accumulator[i] -= accepting;
}else{
accumulator[i] -= accumulated;

View File

@@ -11,7 +11,7 @@ import mindustry.world.meta.*;
import static mindustry.Vars.*;
public abstract class BaseTurret extends Block{
public class BaseTurret extends Block{
public float range = 80f;
public float rotateSpeed = 5;

View File

@@ -9,7 +9,7 @@ import mindustry.world.meta.values.*;
import static mindustry.Vars.*;
public abstract class ReloadTurret extends BaseTurret{
public class ReloadTurret extends BaseTurret{
public float reloadTime = 10f;
public ReloadTurret(String name){

View File

@@ -27,7 +27,7 @@ import mindustry.world.meta.*;
import static mindustry.Vars.*;
public abstract class Turret extends ReloadTurret{
public class Turret extends ReloadTurret{
//after being logic-controlled and this amount of time passes, the turret will resume normal AI
public final static float logicControlCooldown = 60 * 2;

View File

@@ -234,6 +234,12 @@ public class PayloadConveyor extends Block{
updatePayload();
}
@Override
public void onRemoved(){
super.onRemoved();
if(item != null) item.dump();
}
@Override
public void write(Writes write){
super.write(write);

View File

@@ -3,7 +3,7 @@ package mindustry.world.blocks.power;
import mindustry.world.*;
import mindustry.world.meta.*;
public abstract class PowerBlock extends Block{
public class PowerBlock extends Block{
public PowerBlock(String name){
super(name);

View File

@@ -259,7 +259,7 @@ public class Drill extends Block{
progress += delta() * dominantItems * speed * warmup;
if(Mathf.chanceDelta(updateEffectChance * warmup))
updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f));
updateEffect.at(x + Mathf.range(size * 2f), y + Mathf.range(size * 2f));
}else{
lastDrillSpeed = 0f;
warmup = Mathf.lerpDelta(warmup, 0f, warmupSpeed);
@@ -274,7 +274,7 @@ public class Drill extends Block{
index ++;
progress %= delay;
drillEffect.at(getX() + Mathf.range(size), getY() + Mathf.range(size), dominantItem.color);
drillEffect.at(x + Mathf.range(size), y + Mathf.range(size), dominantItem.color);
}
}

View File

@@ -82,6 +82,12 @@ public class PayloadAcceptor extends Block{
return t;
}
@Override
public void onRemoved(){
super.onRemoved();
if(payload != null) payload.dump();
}
public boolean blends(int direction){
return PayloadAcceptor.blends(this, direction);
}

View File

@@ -21,7 +21,7 @@ public class WeaponListValue implements StatValue{
@Override
public void display(Table table){
table.row();
for(int i = 0;i < weapons.size;i ++){
for(int i = 0; i < weapons.size;i ++){
Weapon weapon = weapons.get(i);
if(weapon.flipSprite){
@@ -29,7 +29,7 @@ public class WeaponListValue implements StatValue{
continue;
}
TextureRegion region = weapon.outlineRegion.found() ? weapon.outlineRegion : unit.icon(Cicon.full);
TextureRegion region = !weapon.name.equals("") && weapon.outlineRegion.found() ? weapon.outlineRegion : unit.icon(Cicon.full);
table.image(region).size(60).scaling(Scaling.bounded).right().top();