diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 747643d5c5..8bf5346d59 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,7 +7,7 @@ assignees: '' --- -**Platform**: *Android/iOS/Mac/Windows/Linux* +**Platform**: *The type of device you were playing on - Android/iOS/Mac/Windows/Linux* ("All" is NOT a platform!) **Build**: *The build number under the title in the main menu. Required. "LATEST" IS NOT A VERSION, I NEED THE EXACT BUILD NUMBER OF YOUR GAME.* diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 434a1c55f9..e3558e43be 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -5,7 +5,7 @@ discord = 加入 Mindustry 的 Discord 聊天室! link.discord.description = 官方 Mindustry Discord 聊天室 link.reddit.description = Mindustry Reddit論壇 link.github.description = 遊戲原始碼 -link.changelog.description = 遊戲更新清單 +link.changelog.description = 遊戲更新日誌 link.dev-builds.description = 開發中版本 link.trello.description = 官方 Trello 功能規劃看板 link.itch.io.description = itch.io 電腦版下載網頁 @@ -45,7 +45,7 @@ mods.browser.selected = 已選模組 mods.browser.add = 安裝 mods.browser.reinstall = 重新安裝 mods.browser.view-releases = 檢視發行 -mods.browser.noreleases = [scarlet]No Releases Found\n[accent]Couldn't find any releases for this mod. Check if the mod's repository has any releases published. +mods.browser.noreleases = [scarlet]無發行紀錄\n[accent]無法找到該模組的任何發行。請確認此模組是否有發表。 mods.browser.latest = <最新> mods.browser.releases = 所有發行 mods.github.open = 查看Github @@ -589,26 +589,29 @@ launch.text = 發射 research.multiplayer = 只有管理者可以使用這個物品 map.multiplayer = 只有管理者可以查看地圖 uncover = 探索 -configure = 設定 -objective.research.name = Research -objective.produce.name = Obtain -objective.item.name = Obtain Item -objective.coreitem.name = Core Item -objective.buildcount.name = Build Count -objective.unitcount.name = Unit Count -objective.destroyunits.name = Destroy Units +configure = 資源配置 + +objective.research.name = 研究 +objective.produce.name = 生產 +objective.item.name = 獲取物品 +objective.coreitem.name = 核心物品 +objective.buildcount.name = 建造 +objective.unitcount.name = 製造單位 +objective.destroyunits.name = 摧毀單位 objective.timer.name = Timer -objective.destroyblock.name = Destroy Block -objective.destroyblocks.name = Destroy Blocks -objective.destroycore.name = Destroy Core -objective.commandmode.name = Command Mode -objective.flag.name = Flag -marker.shapetext.name = Shape Text -marker.minimap.name = Minimap -marker.shape.name = Shape -marker.text.name = Text -marker.background = Background -marker.outline = Outline +objective.destroyblock.name = 摧毀 +objective.destroyblocks.name = 摧毀 +objective.destroycore.name = 摧毀核心 +objective.commandmode.name = 指揮模式 +objective.flag.name = 全局Flag + +marker.shapetext.name = 稜框+文字標示 +marker.minimap.name = 小地圖標示 +marker.shape.name = 稜框標示 +marker.text.name = 文字標示 + +marker.background = 反黑背景 +marker.outline = 描邊 objective.research = [accent]研究:\n[]{0}[lightgray]{1} objective.produce = [accent]取得:\n[]{0}[lightgray]{1} @@ -623,6 +626,7 @@ objective.enemiesapproaching = [accent]的人在 [lightgray]{0} 到達[] objective.destroycore = [accent]摧毀敵人核心 objective.command = [accent]Command Units objective.nuclearlaunch = [accent]⚠ Nuclear launch detected: [lightgray]{0} + announce.nuclearstrike = [red]⚠ NUCLEAR STRIKE INBOUND ⚠ loadout = 裝載 @@ -741,18 +745,19 @@ sector.impact0078.description = 沉睡在此的是第一個進入本星系的星 sector.planetaryTerminal.description = 最終目標。\n\n這麼濱海基地具有能夠發射核心到其他行星的建築。 其防禦非常嚴密。\n\n生產海上單位。盡速摧毀敵人。研究該發射建築。 sector.onset.name = 著陸點 -sector.aegis.name = Aegis -sector.lake.name = Name -sector.intersect.name = Intersect -sector.atlas.name = Atlas -sector.split.name = Split -sector.basin.name = Basin +sector.aegis.name = 神盾 +sector.lake.name = 橙色湖泊 +sector.intersect.name = 交會點 +sector.atlas.name = 亞特拉斯 +sector.split.name = 分岔點 +sector.basin.name = 搖籃 + sector.onset.description = 新手教學地區。尚無作戰目標,請等候後續指示。 -sector.aegis.description = The enemy is protected by shields. An experimental shield breaker module has been detected in this sector.\nLocate this structure. Supply it with tungsten ammunition and destroy the enemy base. -sector.lake.description = This sector's slag lake greatly limits viable units. A hover unit is the only option.\nResearch the [accent]ship fabricator[] and produce an [accent]elude[] unit as soon as possible. -sector.intersect.description = Scans suggest that this sector will be attacked from multiple sides soon after landing.\nSet up defenses quickly and expand as soon as possible.\n[accent]Mech[] units will be required for the area's rough terrain. -sector.atlas.description = This sector contains varied terrain and will require a variety of units to attack effectively.\nUpgraded units may also be necessary to get past some of the tougher enemy bases detected here.\nResearch the [accent]Electrolyzer[] and the [accent]Tank Refabricator[]. -sector.split.description = The minimal enemy presence in this sector makes it perfect for testing new transport tech. +sector.aegis.description = 敵人受護盾保護。一個在實驗階段的護盾破壞器坐落在此區域,找到並提供鎢原料啟用它。摧毀敵方基地。 +sector.lake.description = 本地區的熔渣湖嚴重限縮普通單位的機動性。懸浮艇是唯一選擇。\n研究 [accent]飛船兵工廠[] 並盡早生產 [accent]掙脫[] 單位。 +sector.intersect.description = 掃描顯示本區域會在降落後遭受多面攻擊。快速築起防禦,加速擴張。必須建造\n [accent]機甲[] 單位通過陡峭的地形。 +sector.atlas.description = 本地區有多樣地形,建造不同單位以有效進攻。這裡偵測到大型敵方基地,可能需要用升級過的單位突破。\n研究 [accent]電解槽[] 和 [accent]戰車重塑者[]。 +sector.split.description = 較少敵軍活動適合本地區測試最新的運輸科技。 sector.basin.description = {Temporary}\n\nThe last sector for now. Consider this a challenge level - more sectors will be added in a later release. status.burning.name = 燃燒 @@ -760,7 +765,7 @@ status.freezing.name = 凍結 status.wet.name = 浸濕 status.muddy.name = 泥濘 status.melting.name = 融化 -status.sapped.name = 被吸血 +status.sapped.name = 遭吸血 status.electrified.name = 觸電 status.spore-slowed.name = 孢子緩速 status.tarred.name = 焦油 @@ -768,7 +773,7 @@ status.overdrive.name = 超載 status.overclock.name = 快轉 status.shocked.name = 電擊 status.blasted.name = 爆炸 -status.unmoving.name = 立定 +status.unmoving.name = 靜止 status.boss.name = 守衛者 settings.language = 語言 @@ -810,8 +815,8 @@ stat.output = 輸出 stat.maxefficiency = 最高效率 stat.booster = 強化 stat.tiles = 需求方塊 -stat.affinities = 親和方塊 -stat.opposites = 相對方塊 +stat.affinities = 加成傷害 +stat.opposites = 衝突狀態 stat.powercapacity = 蓄電量 stat.powershot = 能量/射擊 stat.damage = 傷害 @@ -871,15 +876,15 @@ stat.minespeed = 挖掘速度 stat.minetier = 挖掘等級 stat.payloadcapacity = 負荷量 stat.abilities = 能力 -stat.canboost = 可加速 -stat.flying = 飛行中 +stat.canboost = 推進器 +stat.flying = 飛行單位 stat.ammouse = 彈藥使用 stat.damagemultiplier = 傷害加成 stat.healthmultiplier = 血量加成 stat.speedmultiplier = 速度加成 stat.reloadmultiplier = 射速加成 stat.buildspeedmultiplier = 建造速度加成 -stat.reactive = 具反應性 +stat.reactive = 狀態傷害加成 stat.immunities = Immunities stat.healing = 治癒 @@ -1519,7 +1524,7 @@ block.payload-unloader.description = 將物品或是液體從方塊取出。 block.heat-source.name = Heat Source block.heat-source.description = A 1x1 block that gives virtualy infinite heat. -#TODO: temporary names! +#Erekir block.empty.name = 虛無 block.rhyolite-crater.name = 流紋岩隕坑 block.rough-rhyolite.name = 粗糙流紋岩 @@ -1601,12 +1606,12 @@ block.shielded-wall.name = 護盾牆 block.radar.name = 雷逹 block.build-tower.name = 建造塔 block.regen-projector.name = 再生投影儀 -block.shockwave-tower.name = Shockwave Tower +block.shockwave-tower.name = 震波塔 block.shield-projector.name = 護盾投影儀 block.large-shield-projector.name = 大型護盾投影儀 block.armored-duct.name = 裝甲真空管 block.overflow-duct.name = 真空管溢流器 -block.underflow-duct.name = Underflow Duct +block.underflow-duct.name = 反向真空管溢流器 block.duct-unloader.name = 真空管裝卸器 block.surge-conveyor.name = 波動輸送帶 block.surge-router.name = 波動分配器 @@ -1640,15 +1645,15 @@ block.breach.name = 突破者 block.sublimate.name = 昇華 block.titan.name = 巨人 block.disperse.name = 驅離者 -block.afflict.name = Afflict -block.lustre.name = Lustre -block.scathe.name = Scathe +block.afflict.name = 折磨 +block.lustre.name = 餘光 +block.scathe.name = 毀損 block.fabricator.name = 製造廠 block.tank-refabricator.name = 戰車重塑者 block.mech-refabricator.name = 機甲重塑者 -block.ship-refabricator.name = 船隻重塑者 +block.ship-refabricator.name = 飛船重塑者 block.tank-assembler.name = 重戰車組裝廠 -block.ship-assembler.name = 大型船組裝廠 +block.ship-assembler.name = 飛行艦組裝廠 block.mech-assembler.name = 重機甲組裝廠 block.reinforced-payload-conveyor.name = 強化重物輸送帶 block.reinforced-payload-router.name = 強化重物分配器 @@ -1658,9 +1663,9 @@ block.canvas.name = 畫布 block.world-processor.name = 世界處理器 block.world-cell.name = 世界單元 block.shield-breaker.name = 護盾破壞器 (未定名/貼圖) -block.tank-fabricator.name = 戰車製造廠 -block.mech-fabricator.name = 機甲製造廠 -block.ship-fabricator.name = 船隻製造廠 +block.tank-fabricator.name = 戰車兵工廠 +block.mech-fabricator.name = 機甲兵工廠 +block.ship-fabricator.name = 飛船兵工廠 block.prime-refabricator.name = 高級單位重塑者 block.unit-repair-tower.name = 維修塔 block.diffuse.name = 擴散 @@ -1947,7 +1952,7 @@ unit.navanax.description = 發射電磁脈衝砲彈。能對敵方電力建築 lst.read = [accent]讀取[]記憶體中的一項數值 lst.write = [accent]寫入[]一項數值到記憶體中 -lst.print = 將文字加入輸出的暫存中,搭配[accent]Print Flush[]使用 +lst.print = 將文字加入輸出的暫存中,搭配[accent]Print Flush[], [accent]Flush message[]使用 lst.draw = 將圖形加入顯示的暫存中,搭配[accent]Draw Flush[]使用 lst.drawflush = 將所有暫存的[accent]Draw[]指令推到顯示器上 lst.printflush = 將所有暫存的[accent]Print[]指令推到訊息板上 @@ -1956,7 +1961,7 @@ lst.control = 控制一個建築 lst.radar = 偵測建築範圍內的單位 lst.sensor = 獲取該建築或單位的數據 lst.set = 設一個變數 -lst.operation = 加減乘除和計算機概論 +lst.operation = 加減乘除和數字、位元運算 lst.end = 跳到第一個重頭開始執行 lst.wait = 等待特定秒數 lst.lookup = 以 ID 搜尋物品/液體/單位/方塊。\n各種類的總數可由 \n[accent]@unitCount[] / [accent]@itemCount[] / [accent]@liquidCount[] / [accent]@blockCount[] 讀取。 @@ -1993,7 +1998,8 @@ laccess.controller = 單位的控制者。受處理器控制時回傳處理器 laccess.dead = 單位或建築是否已死亡或不存在。 laccess.controlled = 將回傳:\n處理器控制:[accent]@ctrlProcessor[]\n玩家控制:[accent]@ctrlPlayer[]\n在隊形中:[accent]@ctrlFormation[]\n其他:[accent]0[]。 laccess.progress = 建造、生產進度。以 0 到 1 表示。以及砲台裝填。 -laccess.speed = Top speed of a unit, in tiles/sec. +laccess.speed = 單位最快速度(格子/秒) + lcategory.unknown = 未知 lcategory.unknown.description = Uncategorized instructions. lcategory.io = 輸入和輸出 @@ -2108,7 +2114,7 @@ unitlocate.outy = 回傳 Y 座標 unitlocate.group = 搜索建築種類 lenum.idle = 預設AI -lenum.stop = 停止移動/挖礦/建造 +lenum.stop = 停止 lenum.unbind = 完全停用邏輯控制\n恢復爲原始AI lenum.move = 移動到指定位置 lenum.approach = 移動到距離指定位置一段距離的地方 diff --git a/core/src/mindustry/ai/ControlPathfinder.java b/core/src/mindustry/ai/ControlPathfinder.java index 942f2004d6..2d590f0088 100644 --- a/core/src/mindustry/ai/ControlPathfinder.java +++ b/core/src/mindustry/ai/ControlPathfinder.java @@ -155,7 +155,10 @@ public class ControlPathfinder{ return lastTargetId ++; } - /** @return whether a path is ready */ + /** + * @return whether a path is ready. + * @param pathId a unique ID for this location query, which should change every time the 'destination' vector is modified. + * */ public boolean getPathPosition(Unit unit, int pathId, Vec2 destination, Vec2 out){ //uninitialized if(threads == null || !world.tiles.in(World.toTile(destination.x), World.toTile(destination.y))) return false; diff --git a/core/src/mindustry/ai/types/CommandAI.java b/core/src/mindustry/ai/types/CommandAI.java index cf0a2791d3..e2addfd0ae 100644 --- a/core/src/mindustry/ai/types/CommandAI.java +++ b/core/src/mindustry/ai/types/CommandAI.java @@ -129,8 +129,6 @@ public class CommandAI extends AIController{ attackTarget != null ? engageRange : 0f, unit.isFlying() ? 40f : 100f, false, null, true); } - - //calculateFlock().limit(unit.speed() * flockMult) } //if stopAtTarget is set, stop trying to move to the target once it is reached - used for defending @@ -145,7 +143,6 @@ public class CommandAI extends AIController{ } if(attackTarget == null){ - //TODO overshoot. if(unit.within(targetPos, Math.max(5f, unit.hitSize / 2f))){ targetPos = null; }else if(local.size > 1){ diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index 1bc1710eb7..50994efced 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -15,7 +15,7 @@ public class LogicAI extends AIController{ public LUnitControl control = LUnitControl.idle; public float moveX, moveY, moveRad; - public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer; + public float controlTimer = logicControlTimeout, targetTimer; @Nullable public Building controller; public BuildPlan plan = new BuildPlan(); @@ -39,8 +39,6 @@ public class LogicAI extends AIController{ @Override public void updateMovement(){ - if(itemTimer >= 0) itemTimer -= Time.delta; - if(payTimer >= 0) payTimer -= Time.delta; if(targetTimer > 0f){ targetTimer -= Time.delta; diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 9d390df496..904f9355d9 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -2123,17 +2123,20 @@ public class Blocks{ requirements(Category.liquid, with(Items.titanium, 10, Items.metaglass, 15)); liquidCapacity = 700f; size = 2; + solid = true; }}; liquidTank = new LiquidRouter("liquid-tank"){{ requirements(Category.liquid, with(Items.titanium, 30, Items.metaglass, 40)); size = 3; + solid = true; liquidCapacity = 1800f; health = 500; }}; liquidJunction = new LiquidJunction("liquid-junction"){{ requirements(Category.liquid, with(Items.graphite, 4, Items.metaglass, 8)); + solid = false; }}; bridgeConduit = new LiquidBridge("bridge-conduit"){{ @@ -2157,10 +2160,8 @@ public class Blocks{ //reinforced stuff - //TODO different name reinforcedPump = new Pump("reinforced-pump"){{ requirements(Category.liquid, with(Items.beryllium, 40, Items.tungsten, 30, Items.silicon, 20)); - //TODO CUSTOM DRAW ANIMATION - pistons - repurpose DrawBlock? consumeLiquid(Liquids.hydrogen, 1.5f / 60f); pumpAmount = 80f / 60f / 4f; @@ -5652,7 +5653,7 @@ public class Blocks{ }}; interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{ - requirements(Category.effect, BuildVisibility.hidden, with(Items.copper, 16000, Items.silicon, 11000, Items.thorium, 13000, Items.titanium, 12000, Items.surgeAlloy, 6000, Items.phaseFabric, 5000)); + requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 16000, Items.silicon, 11000, Items.thorium, 13000, Items.titanium, 12000, Items.surgeAlloy, 6000, Items.phaseFabric, 5000)); researchCostMultiplier = 0.1f; size = 7; hasPower = true; diff --git a/core/src/mindustry/editor/MapObjectivesCanvas.java b/core/src/mindustry/editor/MapObjectivesCanvas.java index 3d380b1558..7ededd6e61 100644 --- a/core/src/mindustry/editor/MapObjectivesCanvas.java +++ b/core/src/mindustry/editor/MapObjectivesCanvas.java @@ -1,14 +1,12 @@ package mindustry.editor; import arc.*; -import arc.graphics.*; import arc.graphics.g2d.*; import arc.input.*; import arc.math.*; import arc.math.geom.*; import arc.scene.event.*; import arc.scene.ui.*; -import arc.scene.ui.ImageButton.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; @@ -28,7 +26,7 @@ public class MapObjectivesCanvas extends WidgetGroup{ objWidth = 5, objHeight = 2, bounds = 100; - public static final float unitSize = 48f; + public final float unitSize = Scl.scl(48f); public Seq objectives = new Seq<>(); public ObjectiveTilemap tilemap; @@ -391,9 +389,9 @@ public class MapObjectivesCanvas extends WidgetGroup{ setTransform(false); setClip(false); - add(conParent = new Connector(true)).size(unitSize, unitSize * 2); + add(conParent = new Connector(true)).size(unitSize / Scl.scl(1f), unitSize * 2 / Scl.scl(1f)); table(Tex.whiteui, t -> { - float pad = (unitSize - 32f) / 2f - 4f; + float pad = (unitSize / Scl.scl(1f) - 32f) / 2f - 4f; t.margin(pad); t.touchable(() -> Touchable.enabled); t.setColor(Pal.gray); @@ -425,8 +423,8 @@ public class MapObjectivesCanvas extends WidgetGroup{ }); b.button(Icon.trashSmall, () -> removeTile(this)); }).left().grow(); - }).growX().height(unitSize * 2).get().addCaptureListener(mover = new Mover()); - add(conChildren = new Connector(false)).size(unitSize, unitSize * 2); + }).growX().height(unitSize / Scl.scl(1f) * 2).get().addCaptureListener(mover = new Mover()); + add(conChildren = new Connector(false)).size(unitSize / Scl.scl(1f), unitSize / Scl.scl(1f) * 2); setSize(getPrefWidth(), getPrefHeight()); pos(x, y); diff --git a/core/src/mindustry/editor/MapObjectivesDialog.java b/core/src/mindustry/editor/MapObjectivesDialog.java index 017afcdefb..488b53f6c8 100644 --- a/core/src/mindustry/editor/MapObjectivesDialog.java +++ b/core/src/mindustry/editor/MapObjectivesDialog.java @@ -427,12 +427,11 @@ public class MapObjectivesDialog extends BaseDialog{ stack( canvas = new MapObjectivesCanvas(), new Table(){{ - buttons.defaults().size(170f, 64f).pad(2f); + buttons.defaults().size(160f, 64f).pad(2f); buttons.button("@back", Icon.left, MapObjectivesDialog.this::hide); buttons.button("@add", Icon.add, () -> getProvider(MapObjective.class).get(new TypeInfo(MapObjective.class), canvas::query)); if(mobile){ - buttons.row(); buttons.button("@cancel", Icon.cancel, canvas::stopQuery).disabled(b -> !canvas.isQuerying()); buttons.button("@ok", Icon.ok, canvas::placeQuery).disabled(b -> !canvas.isQuerying()); } diff --git a/core/src/mindustry/entities/bullet/FlakBulletType.java b/core/src/mindustry/entities/bullet/FlakBulletType.java index 3fbf88a1b0..9184527a10 100644 --- a/core/src/mindustry/entities/bullet/FlakBulletType.java +++ b/core/src/mindustry/entities/bullet/FlakBulletType.java @@ -30,7 +30,7 @@ public class FlakBulletType extends BasicBulletType{ if(b.time >= flakDelay && b.fdata >= 0 && b.timer(2, flakInterval)){ Units.nearbyEnemies(b.team, Tmp.r1.setSize(explodeRange * 2f).setCenter(b.x, b.y), unit -> { //fdata < 0 means it's primed to explode - if(b.fdata < 0f || !unit.checkTarget(collidesAir, collidesGround)) return; + if(b.fdata < 0f || !unit.checkTarget(collidesAir, collidesGround) || !unit.type.targetable) return; if(unit.within(b, explodeRange + unit.hitSize/2f)){ //mark as primed diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index dd2be20678..b57349c71a 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1682,7 +1682,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, /** Called after efficiency is updated but before consumers are updated. Use to apply your own multiplier. */ public void updateEfficiencyMultiplier(){ + float scale = efficiencyScale(); + efficiency *= scale; + optionalEfficiency *= scale; + } + /** Calculate your own efficiency multiplier. By default, this is applied in updateEfficiencyMultiplier. */ + public float efficiencyScale(){ + return 1f; } public void updateConsumption(){ diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index aa6daf4b5a..06d81f201f 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -57,6 +57,17 @@ public class LExecutor{ public Team team = Team.derelict; public boolean privileged = false; + //yes, this is a minor memory leak, but it's probably not significant enough to matter + protected IntFloatMap unitTimeouts = new IntFloatMap(); + + boolean timeoutDone(Unit unit, float delay){ + return Time.time >= unitTimeouts.get(unit.id) + delay; + } + + void updateTimeout(Unit unit){ + unitTimeouts.put(unit.id, Time.time); + } + public boolean initialized(){ return instructions.length > 0; } @@ -428,15 +439,15 @@ public class LExecutor{ } } case payDrop -> { - if(ai.payTimer > 0) return; + if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return; if(unit instanceof Payloadc pay && pay.hasPayload()){ Call.payloadDropped(unit, unit.x, unit.y); - ai.payTimer = LogicAI.transferDelay; + exec.updateTimeout(unit); } } case payTake -> { - if(ai.payTimer > 0) return; + if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return; if(unit instanceof Payloadc pay){ //units @@ -460,7 +471,7 @@ public class LExecutor{ } } } - ai.payTimer = LogicAI.transferDelay; + exec.updateTimeout(unit); } } case payEnter -> { @@ -508,7 +519,7 @@ public class LExecutor{ } } case itemDrop -> { - if(ai.itemTimer > 0) return; + if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return; //clear item when dropping to @air if(exec.obj(p1) == Blocks.air){ @@ -516,7 +527,7 @@ public class LExecutor{ if(!net.client()){ unit.clearItem(); } - ai.itemTimer = LogicAI.transferDelay; + exec.updateTimeout(unit); }else{ Building build = exec.building(p1); int dropped = Math.min(unit.stack.amount, exec.numi(p2)); @@ -524,13 +535,13 @@ public class LExecutor{ int accepted = build.acceptStack(unit.item(), dropped, unit); if(accepted > 0){ Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build); - ai.itemTimer = LogicAI.transferDelay; + exec.updateTimeout(unit); } } } } case itemTake -> { - if(ai.itemTimer > 0) return; + if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return; Building build = exec.building(p1); int amount = exec.numi(p3); @@ -541,7 +552,7 @@ public class LExecutor{ if(taken > 0){ Call.takeItems(build, item, taken, unit); - ai.itemTimer = LogicAI.transferDelay; + exec.updateTimeout(unit); } } } @@ -1634,6 +1645,8 @@ public class LExecutor{ @Override public void run(LExecutor exec){ + if(net.client()) return; + float spawnX = World.unconv(exec.numf(x)), spawnY = World.unconv(exec.numf(y)); diff --git a/core/src/mindustry/maps/filters/MedianFilter.java b/core/src/mindustry/maps/filters/MedianFilter.java index 04074ece5c..c71fdde5b6 100644 --- a/core/src/mindustry/maps/filters/MedianFilter.java +++ b/core/src/mindustry/maps/filters/MedianFilter.java @@ -50,8 +50,7 @@ public class MedianFilter extends GenerateFilter{ floors.sort(); blocks.sort(); - int index = Math.min((int)(floors.size * percentile), floors.size - 1); - int floor = floors.get(index), block = blocks.get(index); + int floor = floors.get(Math.min((int)(floors.size * percentile), floors.size - 1)), block = blocks.get(Math.min((int)(blocks.size * percentile), blocks.size - 1)); in.floor = content.block(floor); if(!content.block(block).synthetic() && !in.block.synthetic()) in.block = content.block(block); diff --git a/core/src/mindustry/ui/dialogs/ColorPicker.java b/core/src/mindustry/ui/dialogs/ColorPicker.java index 97eb3ea13e..8fa0856f4f 100644 --- a/core/src/mindustry/ui/dialogs/ColorPicker.java +++ b/core/src/mindustry/ui/dialogs/ColorPicker.java @@ -158,7 +158,7 @@ public class ColorPicker extends BaseDialog{ return false; } }).get(); - }); + }).grow(); buttons.clear(); addCloseButton(); diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index dda0708dd7..d99304ca55 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -60,7 +60,7 @@ public class ModsDialog extends BaseDialog{ searchtxt = res; rebuildBrowser(); }).growX().get(); - table.button(Icon.list, Styles.clearNonei, 32f, () -> { + table.button(Icon.list, Styles.emptyi, 32f, () -> { orderDate = !orderDate; rebuildBrowser(); }).update(b -> b.getStyle().imageUp = (orderDate ? Icon.list : Icon.star)).size(40f).get() diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index e38a263538..a111aff5d7 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -110,6 +110,9 @@ public class Accelerator extends Block{ if(!state.isCampaign() || efficiency <= 0f) return; + ui.showInfo("This block doesn't work properly in the beta/alpha. It maybe removed, or reworked. Check back in a later update."); + + if(false) ui.planet.showPlanetLaunch(state.rules.sector, sector -> { //TODO cutscene, etc... diff --git a/core/src/mindustry/world/blocks/logic/CanvasBlock.java b/core/src/mindustry/world/blocks/logic/CanvasBlock.java index a74316bb8d..feb17ccfa0 100644 --- a/core/src/mindustry/world/blocks/logic/CanvasBlock.java +++ b/core/src/mindustry/world/blocks/logic/CanvasBlock.java @@ -224,6 +224,16 @@ public class CanvasBlock extends Block{ }).size(40f); } + @Override + public boolean onConfigureBuildTapped(Building other){ + if(this == other){ + deselect(); + return false; + } + + return true; + } + @Override public byte[] config(){ return data; diff --git a/core/src/mindustry/world/blocks/payloads/PayloadSource.java b/core/src/mindustry/world/blocks/payloads/PayloadSource.java index 8905d3fed3..9a2012fc5e 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadSource.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadSource.java @@ -2,6 +2,7 @@ package mindustry.world.blocks.payloads; import arc.graphics.g2d.*; import arc.math.*; +import arc.math.geom.*; import arc.scene.ui.layout.*; import arc.util.*; import arc.util.io.*; @@ -33,6 +34,7 @@ public class PayloadSource extends PayloadBlock{ noUpdateDisabled = true; clearOnDoubleTap = true; regionRotated1 = 1; + commandable = true; config(Block.class, (PayloadSourceBuild build, Block block) -> { if(canProduce(block) && build.block != block){ @@ -83,8 +85,19 @@ public class PayloadSource extends PayloadBlock{ public class PayloadSourceBuild extends PayloadBlockBuild{ public UnitType unit; public Block block; + public @Nullable Vec2 commandPos; public float scl; + @Override + public Vec2 getCommandPosition(){ + return commandPos; + } + + @Override + public void onCommand(Vec2 target){ + commandPos = target; + } + @Override public void buildConfiguration(Table table){ ItemSelection.buildTable(PayloadSource.this, table, @@ -110,6 +123,11 @@ public class PayloadSource extends PayloadBlock{ scl = 0f; if(unit != null){ payload = new UnitPayload(unit.create(team)); + + Unit p = ((UnitPayload)payload).unit; + if(commandPos != null && p.isCommandable()){ + p.command().commandPosition(commandPos); + } }else if(block != null){ payload = new BuildPayload(block, team); } diff --git a/core/src/mindustry/world/blocks/power/LightBlock.java b/core/src/mindustry/world/blocks/power/LightBlock.java index 12191f572d..882323d131 100644 --- a/core/src/mindustry/world/blocks/power/LightBlock.java +++ b/core/src/mindustry/world/blocks/power/LightBlock.java @@ -13,6 +13,7 @@ import mindustry.gen.*; import mindustry.graphics.*; import mindustry.input.*; import mindustry.logic.*; +import mindustry.ui.*; import mindustry.world.*; import mindustry.world.meta.*; @@ -86,12 +87,22 @@ public class LightBlock extends Block{ @Override public void buildConfiguration(Table table){ - table.button(Icon.pencil, () -> { + table.button(Icon.pencil, Styles.cleari, () -> { ui.picker.show(Tmp.c1.set(color).a(0.5f), false, res -> configure(res.rgba())); deselect(); }).size(40f); } + @Override + public boolean onConfigureBuildTapped(Building other){ + if(this == other){ + deselect(); + return false; + } + + return true; + } + @Override public void drawLight(){ Drawf.light(x, y, lightRadius * Math.min(smoothTime, 2f), Tmp.c1.set(color), brightness * efficiency); diff --git a/core/src/mindustry/world/blocks/production/AttributeCrafter.java b/core/src/mindustry/world/blocks/production/AttributeCrafter.java index 0c5a037cdc..e7d33cbf80 100644 --- a/core/src/mindustry/world/blocks/production/AttributeCrafter.java +++ b/core/src/mindustry/world/blocks/production/AttributeCrafter.java @@ -38,8 +38,8 @@ public class AttributeCrafter extends GenericCrafter{ if(!displayEfficiency) return; addBar("efficiency", (AttributeCrafterBuild entity) -> - new Bar(() -> - Core.bundle.format("bar.efficiency", (int)(entity.efficiencyScale() * 100 * displayEfficiencyScale)), + new Bar( + () -> Core.bundle.format("bar.efficiency", (int)(entity.efficiencyScale() * 100 * displayEfficiencyScale)), () -> Pal.lightOrange, entity::efficiencyScale)); } diff --git a/core/src/mindustry/world/blocks/production/HeatCrafter.java b/core/src/mindustry/world/blocks/production/HeatCrafter.java index 7ab6317608..498879f39d 100644 --- a/core/src/mindustry/world/blocks/production/HeatCrafter.java +++ b/core/src/mindustry/world/blocks/production/HeatCrafter.java @@ -67,11 +67,6 @@ public class HeatCrafter extends GenericCrafter{ } @Override - public void updateEfficiencyMultiplier(){ - efficiency *= efficiencyScale(); - potentialEfficiency *= efficiencyScale(); - } - public float efficiencyScale(){ float over = Math.max(heat - heatRequirement, 0f); return Math.min(Mathf.clamp(heat / heatRequirement) + over / heatRequirement * overheatScale, maxEfficiency); diff --git a/core/src/mindustry/world/blocks/units/UnitAssembler.java b/core/src/mindustry/world/blocks/units/UnitAssembler.java index c686a2cf1f..7c6efb7cb8 100644 --- a/core/src/mindustry/world/blocks/units/UnitAssembler.java +++ b/core/src/mindustry/world/blocks/units/UnitAssembler.java @@ -298,6 +298,8 @@ public class UnitAssembler extends PayloadBlock{ for(var module : modules){ Drawf.selected(module, Pal.accent); } + + Drawf.dashRect(Tmp.c1.set(Pal.accent).lerp(Pal.remove, invalidWarmup), getRect(Tmp.r1, x, y, rotation)); } @Override @@ -320,7 +322,7 @@ public class UnitAssembler extends PayloadBlock{ prev = mod.block; } - t.label(() -> "[accent] -> []" + unit().emoji() + " " + unit().name); + t.label(() -> "[accent] -> []" + unit().emoji() + " " + unit().localizedName); }).pad(4).padLeft(0f).fillX().left(); } diff --git a/core/src/mindustry/world/consumers/ConsumeLiquid.java b/core/src/mindustry/world/consumers/ConsumeLiquid.java index 03806918ad..bef8e3a8d6 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquid.java @@ -40,7 +40,7 @@ public class ConsumeLiquid extends ConsumeLiquidBase{ @Override public float efficiency(Building build){ - float ed = build.edelta(); + float ed = build.edelta() * build.efficiencyScale(); if(ed <= 0.00000001f) return 0f; //there can be more liquid than necessary, so cap at 1 return Math.min(build.liquids.get(liquid) / (amount * ed), 1f);