From dbe2f7eefac6736067b1f4412e171ebf689d00f8 Mon Sep 17 00:00:00 2001 From: TranquillyUnpleasant <62061444+TranquillyUnpleasant@users.noreply.github.com> Date: Sun, 3 Jan 2021 23:45:35 +0500 Subject: [PATCH 001/426] Fix mirror being offset (#4248) Because apparently it isn't a valid map even though its been a known issue for months. --- core/src/mindustry/maps/filters/MirrorFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/maps/filters/MirrorFilter.java b/core/src/mindustry/maps/filters/MirrorFilter.java index 3ebdb45a71..d5642381ad 100644 --- a/core/src/mindustry/maps/filters/MirrorFilter.java +++ b/core/src/mindustry/maps/filters/MirrorFilter.java @@ -68,8 +68,8 @@ public class MirrorFilter extends GenerateFilter{ void mirror(Vec2 p, float x0, float y0, float x1, float y1){ //special case: uneven map mirrored at 45 degree angle if(in.width != in.height && angle % 90 != 0){ - p.x = (p.x - in.width/2f) * -1 + in.width/2f; - p.y = (p.y - in.height/2f) * -1 + in.height/2f; + p.x = in.width - p.x - 1; + p.y = in.height - p.y - 1; }else{ float dx = x1 - x0; float dy = y1 - y0; From 0f3716b8dd6e04ce9efa26887b696a8a8076c9db Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Sun, 3 Jan 2021 12:38:09 -0800 Subject: [PATCH 002/426] Logic: Fix radar from value bug (#4236) * Logic: Fix radar from value bug * Use constructor to modify variable initialization --- core/src/mindustry/logic/LStatements.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index d8fce354ad..ead24094ed 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -819,6 +819,10 @@ public class LStatements{ @RegisterStatement("uradar") public static class UnitRadarStatement extends RadarStatement{ + public UnitRadarStatement(){ + radar = "0"; + } + @Override public boolean buildFrom(){ //do not build the "from" section From 3eb08579069c88ad2bec4d6b5dc7aae0528023a2 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sun, 3 Jan 2021 22:18:39 +0100 Subject: [PATCH 003/426] Building tile > Building build @ Inputhandler.java (#4241) Was weird to see `if(player != null) tile.lastAccessed = player.name;` in there. --- core/src/mindustry/input/InputHandler.java | 136 ++++++++++----------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 0f50a26ffa..8d9d1c15e7 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -129,11 +129,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(called = Loc.server, targets = Loc.both, forward = true) - public static void requestItem(Player player, Building tile, Item item, int amount){ - if(player == null || tile == null || !tile.interactable(player.team()) || !player.within(tile, buildingRange) || player.dead()) return; + public static void requestItem(Player player, Building build, Item item, int amount){ + if(player == null || build == null || !build.interactable(player.team()) || !player.within(build, buildingRange) || player.dead()) return; - if(net.server() && (!Units.canInteract(player, tile) || - !netServer.admins.allowAction(player, ActionType.withdrawItem, tile.tile(), action -> { + if(net.server() && (!Units.canInteract(player, build) || + !netServer.admins.allowAction(player, ActionType.withdrawItem, build.tile(), action -> { action.item = item; action.itemAmount = amount; }))){ @@ -142,20 +142,20 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ //remove item for every controlling unit player.unit().eachGroup(unit -> { - Call.takeItems(tile, item, unit.maxAccepted(item), unit); + Call.takeItems(build, item, unit.maxAccepted(item), unit); if(unit == player.unit()){ - Events.fire(new WithdrawEvent(tile, player, item, amount)); + Events.fire(new WithdrawEvent(build, player, item, amount)); } }); } @Remote(targets = Loc.both, forward = true, called = Loc.server) - public static void transferInventory(Player player, Building tile){ - if(player == null || tile == null || !player.within(tile, buildingRange) || tile.items == null || player.dead()) return; + public static void transferInventory(Player player, Building build){ + if(player == null || build == null || !player.within(build, buildingRange) || build.items == null || player.dead()) return; - if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, tile) || - !netServer.admins.allowAction(player, ActionType.depositItem, tile.tile, action -> { + if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, build) || + !netServer.admins.allowAction(player, ActionType.depositItem, build.tile, action -> { action.itemAmount = player.unit().stack.amount; action.item = player.unit().item(); }))){ @@ -165,12 +165,12 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ //deposit for every controlling unit player.unit().eachGroup(unit -> { Item item = unit.item(); - int accepted = tile.acceptStack(item, unit.stack.amount, unit); + int accepted = build.acceptStack(item, unit.stack.amount, unit); - Call.transferItemTo(unit, item, accepted, unit.x, unit.y, tile); + Call.transferItemTo(unit, item, accepted, unit.x, unit.y, build); if(unit == player.unit()){ - Events.fire(new DepositEvent(tile, player, item, accepted)); + Events.fire(new DepositEvent(build, player, item, accepted)); } }); } @@ -194,22 +194,22 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(targets = Loc.both, called = Loc.server) - public static void requestBuildPayload(Player player, Building tile){ + public static void requestBuildPayload(Player player, Building build){ if(player == null) return; Unit unit = player.unit(); Payloadc pay = (Payloadc)unit; - if(tile != null && tile.team == unit.team - && unit.within(tile, tilesize * tile.block.size * 1.2f + tilesize * 5f)){ + if(build != null && build.team == unit.team + && unit.within(build, tilesize * build.block.size * 1.2f + tilesize * 5f)){ //pick up block's payload - Payload current = tile.getPayload(); + Payload current = build.getPayload(); if(current != null && pay.canPickupPayload(current)){ - Call.pickedBuildPayload(unit, tile, false); + Call.pickedBuildPayload(unit, build, false); //pick up whole building directly - }else if(tile.block.buildVisibility != BuildVisibility.hidden && tile.canPickup() && pay.canPickup(tile)){ - Call.pickedBuildPayload(unit, tile, true); + }else if(build.block.buildVisibility != BuildVisibility.hidden && build.canPickup() && pay.canPickup(build)){ + Call.pickedBuildPayload(unit, build, true); } } } @@ -224,29 +224,29 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(targets = Loc.server, called = Loc.server) - public static void pickedBuildPayload(Unit unit, Building tile, boolean onGround){ - if(tile != null && unit instanceof Payloadc pay){ + public static void pickedBuildPayload(Unit unit, Building build, boolean onGround){ + if(build != null && unit instanceof Payloadc pay){ if(onGround){ - if(tile.block.buildVisibility != BuildVisibility.hidden && tile.canPickup() && pay.canPickup(tile)){ - pay.pickup(tile); + if(build.block.buildVisibility != BuildVisibility.hidden && build.canPickup() && pay.canPickup(build)){ + pay.pickup(build); }else{ - Fx.unitPickup.at(tile); - tile.tile.remove(); + Fx.unitPickup.at(build); + build.tile.remove(); } }else{ - Payload current = tile.getPayload(); + Payload current = build.getPayload(); if(current != null && pay.canPickupPayload(current)){ - Payload taken = tile.takePayload(); + Payload taken = build.takePayload(); if(taken != null){ pay.addPayload(taken); - Fx.unitPickup.at(tile); + Fx.unitPickup.at(build); } } } - }else if(tile != null && onGround){ - Fx.unitPickup.at(tile); - tile.tile.remove(); + }else if(build != null && onGround){ + Fx.unitPickup.at(build); + build.tile.remove(); } } @@ -293,27 +293,27 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(targets = Loc.both, called = Loc.server, forward = true, unreliable = true) - public static void rotateBlock(@Nullable Player player, Building tile, boolean direction){ - if(tile == null) return; + public static void rotateBlock(@Nullable Player player, Building build, boolean direction){ + if(build == null) return; - if(net.server() && (!Units.canInteract(player, tile) || - !netServer.admins.allowAction(player, ActionType.rotate, tile.tile(), action -> action.rotation = Mathf.mod(tile.rotation + Mathf.sign(direction), 4)))){ + if(net.server() && (!Units.canInteract(player, build) || + !netServer.admins.allowAction(player, ActionType.rotate, build.tile(), action -> action.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4)))){ throw new ValidateException(player, "Player cannot rotate a block."); } - if(player != null) tile.lastAccessed = player.name; - tile.rotation = Mathf.mod(tile.rotation + Mathf.sign(direction), 4); - tile.updateProximity(); - tile.noSleep(); + if(player != null) build.lastAccessed = player.name; + build.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4); + build.updateProximity(); + build.noSleep(); } @Remote(targets = Loc.both, called = Loc.both, forward = true) - public static void tileConfig(@Nullable Player player, Building tile, @Nullable Object value){ - if(tile == null) return; - if(net.server() && (!Units.canInteract(player, tile) || - !netServer.admins.allowAction(player, ActionType.configure, tile.tile, action -> action.config = value))) throw new ValidateException(player, "Player cannot configure a tile."); - tile.configured(player == null || player.dead() ? null : player.unit(), value); - Core.app.post(() -> Events.fire(new ConfigEvent(tile, player, value))); + public static void tileConfig(@Nullable Player player, Building build, @Nullable Object value){ + if(build == null) return; + if(net.server() && (!Units.canInteract(player, build) || + !netServer.admins.allowAction(player, ActionType.configure, build.tile, action -> action.config = value))) throw new ValidateException(player, "Player cannot configure a tile."); + build.configured(player == null || player.dead() ? null : player.unit(), value); + Core.app.post(() -> Events.fire(new ConfigEvent(build, player, value))); } //only useful for servers or local mods, and is not replicated across clients @@ -461,10 +461,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(target != null){ Call.requestUnitPayload(player, target); }else{ - Building tile = world.buildWorld(pay.x(), pay.y()); + Building build = world.buildWorld(pay.x(), pay.y()); - if(tile != null && tile.team == unit.team){ - Call.requestBuildPayload(player, tile); + if(build != null && build.team == unit.team){ + Call.requestBuildPayload(player, build); } } } @@ -866,8 +866,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } /** Handles tile tap events that are not platform specific. */ - boolean tileTapped(@Nullable Building tile){ - if(tile == null){ + boolean tileTapped(@Nullable Building build){ + if(build == null){ frag.inv.hide(); frag.config.hideConfig(); return false; @@ -875,18 +875,18 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ boolean consumed = false, showedInventory = false; //check if tapped block is configurable - if(tile.block.configurable && tile.interactable(player.team())){ + if(build.block.configurable && build.interactable(player.team())){ consumed = true; - if(((!frag.config.isShown() && tile.shouldShowConfigure(player)) //if the config fragment is hidden, show + if(((!frag.config.isShown() && build.shouldShowConfigure(player)) //if the config fragment is hidden, show //alternatively, the current selected block can 'agree' to switch config tiles - || (frag.config.isShown() && frag.config.getSelectedTile().onConfigureTileTapped(tile)))){ - Sounds.click.at(tile); - frag.config.showConfig(tile); + || (frag.config.isShown() && frag.config.getSelectedTile().onConfigureTileTapped(build)))){ + Sounds.click.at(build); + frag.config.showConfig(build); } //otherwise... }else if(!frag.config.hasConfigMouse()){ //make sure a configuration fragment isn't on the cursor //then, if it's shown and the current block 'agrees' to hide, hide it. - if(frag.config.isShown() && frag.config.getSelectedTile().onConfigureTileTapped(tile)){ + if(frag.config.isShown() && frag.config.getSelectedTile().onConfigureTileTapped(build)){ consumed = true; frag.config.hideConfig(); } @@ -897,16 +897,16 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } //call tapped event - if(!consumed && tile.interactable(player.team())){ - tile.tapped(); + if(!consumed && build.interactable(player.team())){ + build.tapped(); } //consume tap event if necessary - if(tile.interactable(player.team()) && tile.block.consumesTap){ + if(build.interactable(player.team()) && build.block.consumesTap){ consumed = true; - }else if(tile.interactable(player.team()) && tile.block.synthetic() && !consumed){ - if(tile.block.hasItems && tile.items.total() > 0){ - frag.inv.showFor(tile); + }else if(build.interactable(player.team()) && build.block.synthetic() && !consumed){ + if(build.block.hasItems && build.items.total() > 0){ + frag.inv.showFor(build); consumed = true; showedInventory = true; } @@ -1006,8 +1006,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } } - Building tile = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); - if(tile instanceof ControlBlock cont && cont.canControl() && tile.team == player.team()){ + Building build = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); + if(build instanceof ControlBlock cont && cont.canControl() && build.team == player.team()){ return cont.unit(); } @@ -1071,7 +1071,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ return droppingItem && !canTapPlayer(Core.input.mouseWorldX(), Core.input.mouseWorldY()); } - public void tryDropItems(@Nullable Building tile, float x, float y){ + public void tryDropItems(@Nullable Building build, float x, float y){ if(!droppingItem || player.unit().stack.amount <= 0 || canTapPlayer(x, y) || state.isPaused() ){ droppingItem = false; return; @@ -1081,8 +1081,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ ItemStack stack = player.unit().stack; - if(tile != null && tile.acceptStack(stack.item, stack.amount, player.unit()) > 0 && tile.interactable(player.team()) && tile.block.hasItems && player.unit().stack().amount > 0 && tile.interactable(player.team())){ - Call.transferInventory(player, tile); + if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) && build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){ + Call.transferInventory(player, build); }else{ Call.dropItem(player.angleTo(x, y)); } From 0cfdacdd28b3b770694cfca285f05376ecb4739f Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sun, 3 Jan 2021 22:48:25 +0100 Subject: [PATCH 004/426] Allow for core incineration via rules (#4242) --- core/src/mindustry/game/Rules.java | 2 ++ core/src/mindustry/world/blocks/storage/CoreBlock.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index e0db8ac94a..f9d594e83e 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -97,6 +97,8 @@ public class Rules{ public Team waveTeam = Team.crux; /** name of the custom mode that this ruleset describes, or null. */ public @Nullable String modeName; + /** Whether cores incinerate items when full, just like in the campaign. */ + public boolean coreIncinerates = false; /** special tags for additional info. */ public StringMap tags = new StringMap(); diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 18299cd02a..ed7c2d7849 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -319,7 +319,7 @@ public class CoreBlock extends StorageBlock{ } public boolean incinerate(){ - return state.isCampaign(); + return state.isCampaign() || state.rules.coreIncinerates; } @Override From af636f74fcabd67ec571e32a08fed3a3f2f8aeda Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 3 Jan 2021 16:52:54 -0500 Subject: [PATCH 005/426] Core incineration tweaks --- core/src/mindustry/core/Logic.java | 3 +++ core/src/mindustry/world/blocks/storage/CoreBlock.java | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 91a0c410c1..6e7ba9b957 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -57,6 +57,8 @@ public class Logic implements ApplicationListener{ //when loading a 'damaged' sector, propagate the damage Events.on(SaveLoadEvent.class, e -> { if(state.isCampaign()){ + state.rules.coreIncinerates = true; + SectorInfo info = state.rules.sector.info; info.write(); @@ -107,6 +109,7 @@ public class Logic implements ApplicationListener{ if(!(state.getSector().preset != null && !state.getSector().preset.useAI)){ state.rules.waveTeam.rules().ai = true; } + state.rules.coreIncinerates = true; state.rules.waveTeam.rules().aiTier = state.getSector().threat * 0.8f; state.rules.waveTeam.rules().infiniteResources = true; diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index ed7c2d7849..9a3e2539bc 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -233,7 +233,7 @@ public class CoreBlock extends StorageBlock{ @Override public int getMaximumAccepted(Item item){ - return incinerate() ? storageCapacity * 2 : storageCapacity; + return state.rules.coreIncinerates ? storageCapacity * 2 : storageCapacity; } @Override @@ -318,10 +318,6 @@ public class CoreBlock extends StorageBlock{ return tile instanceof StorageBuild b && (b.linkedCore == core || b.linkedCore == null); } - public boolean incinerate(){ - return state.isCampaign() || state.rules.coreIncinerates; - } - @Override public float handleDamage(float amount){ if(player != null && team == player.team()){ @@ -386,7 +382,7 @@ public class CoreBlock extends StorageBlock{ }else{ super.handleItem(source, item); } - }else if(incinerate()){ + }else if(state.rules.coreIncinerates){ if(items.get(item) >= storageCapacity){ //create item incineration effect at random intervals if(!noEffect){ From 5712190dab4cff76dde4a1d2b9091c6cf25ce1ad Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 3 Jan 2021 18:01:44 -0500 Subject: [PATCH 006/426] cleanup --- core/src/mindustry/world/blocks/storage/CoreBlock.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 9a3e2539bc..677c3a83b6 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -382,13 +382,9 @@ public class CoreBlock extends StorageBlock{ }else{ super.handleItem(source, item); } - }else if(state.rules.coreIncinerates){ - if(items.get(item) >= storageCapacity){ - //create item incineration effect at random intervals - if(!noEffect){ - incinerateEffect(this, source); - } - } + }else if(state.rules.coreIncinerates && items.get(item) >= storageCapacity && !noEffect){ + //create item incineration effect at random intervals + incinerateEffect(this, source); } } } From 4b71b4f80a7920e75fff400d74d509e1aadfbf8d Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Mon, 4 Jan 2021 18:33:43 +0300 Subject: [PATCH 007/426] Make mod browser case insensitive (#4258) --- core/src/mindustry/ui/dialogs/ModsDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 75dbdca5c7..ec704500bb 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -175,7 +175,7 @@ public class ModsDialog extends BaseDialog{ tablebrow.clear(); for(ModListing mod : listings){ - if(mod.hasJava || !searchtxt.isEmpty() && !mod.repo.contains(searchtxt) || (Vars.ios && mod.hasScripts)) continue; + if(mod.hasJava || !searchtxt.isEmpty() && !mod.repo.toLowerCase().contains(searchtxt.toLowerCase()) || (Vars.ios && mod.hasScripts)) continue; tablebrow.button(btn -> { btn.top().left(); From 6bd8f99be3ea9a35dff073b826792a645ba9ea21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Mon, 4 Jan 2021 23:38:18 +0800 Subject: [PATCH 008/426] Updated Search Bar cleanup for zh-TW (#4186) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update bundle_zh_TW.properties Corrected some machine translations. Modified some others for more clear understanding. * Update bundle_zh_TW.properties * Update bundle_zh_TW.properties new translations 1 * Update bundle_zh_TW.properties New translations 2 * Update bundle_zh_TW.properties New translations 3 * New translations 1-3 Removed "zones" from v121.4: "Fixed sectors not auto-unlocking". 衝擊反應堆 -->動能反應爐 * New translations 1-4 * New translations 1-5 * New translations 1-6 up to line 1250 * Indexing finished. Translations 1-7 lines are now matching with English bundle. * update bundle_zh_TW.properties * edit zh_TW * zh-tw * community server disclaimer * Finished sector descriptions, slight modifications up to line 606 * zh-TW * Many translations, include Always-on weather rule * corrected missing character * Update achievements.vdf Oct not translated * Update description.txt * bundle_zh_TW.properties * Bullet stats update, hints finished * added line: public confirm really * contributors * Merging conflicts Almost done... * Synced * Update ammo-stat translation * Update contributors * Unit names * Update bundle_zh_TW.properties * Unit names * Update bundle_zh_TW.properties * Review (#15) * Update bundle_zh_TW.properties * Unit names * Update bundle_zh_TW.properties * Finished Please review * minor correction * minor correction Hopefully there are no more "minor corrections" required. * Review * Close inspection * Revisions, change chat mode * Sapping Correction * Merge down (#16, post 122) * Fixed #4108 * [QoL] Chat modes (#3869) Credits: Remint32 (idea); sk7725 (korean i18n); Volas171 (spanish i18n). * add new io server (#4109) soon to be up gamemode * typo (#4110) * Fixed mined item flashing on clients * Block Forge improvements (#4112) * minBlockSize, maxBlockSize, icon * removed fixed size * same line * revert to 3 * I almost forgot * Up-to-date zh-TW translations (#4083) * Update bundle_zh_TW.properties Corrected some machine translations. Modified some others for more clear understanding. * Update bundle_zh_TW.properties * Update bundle_zh_TW.properties new translations 1 * Update bundle_zh_TW.properties New translations 2 * Update bundle_zh_TW.properties New translations 3 * New translations 1-3 Removed "zones" from v121.4: "Fixed sectors not auto-unlocking". 衝擊反應堆 -->動能反應爐 * New translations 1-4 * New translations 1-5 * New translations 1-6 up to line 1250 * Indexing finished. Translations 1-7 lines are now matching with English bundle. * update bundle_zh_TW.properties * edit zh_TW * zh-tw * community server disclaimer * Finished sector descriptions, slight modifications up to line 606 * zh-TW * Many translations, include Always-on weather rule * corrected missing character * Update achievements.vdf Oct not translated * Update description.txt * bundle_zh_TW.properties * Bullet stats update, hints finished * added line: public confirm really * contributors * Merging conflicts Almost done... * Synced * Update ammo-stat translation * Update contributors * Unit names * Update bundle_zh_TW.properties * Unit names * Update bundle_zh_TW.properties * Review (#15) * Update bundle_zh_TW.properties * Unit names * Update bundle_zh_TW.properties * Finished Please review * minor correction * minor correction Hopefully there are no more "minor corrections" required. * Review * Close inspection * Revisions, change chat mode * Sapping Correction Co-authored-by: simba-fs Co-authored-by: Simba-Fs <39305460+simba-fs@users.noreply.github.com> * Higher power source output * Update servers_v6.json (#4095) * Update servers_v6.json the ip changed to not make users confuse * Update servers_v6.json * Fixed #4120 * Fixed #4121 * Fixed #4122 * Better build beam visuals * Don't render weather in full map screenshots * Building priority fix * Fixed #4128 * SearchBar class - add search bars to mods (#3267) * Create SearchBar and make ModsDialog use it * add search bar to servers * Update core/src/mindustry/ui/SearchBar.java Co-authored-by: Antsiferov Andrew * a * fix mods menu not rowing * remove search bar for remote servers * h * hide searchbar on landscape mobile * anukes feedback * Update core/src/mindustry/ui/SearchBar.java Co-authored-by: Anuken * java dumb Co-authored-by: Antsiferov Andrew Co-authored-by: Anuken * Search bar cleanup * Block (un)loader major improvements (#4127) * make it consider consVaild * make this too * pattern style and max block size * Is there a better way to do this? * Update BlockUnloader.java * do not the /0 * prevent /0 * test 1 * yup it works for enabled Co-authored-by: Anuken Co-authored-by: Antsiferov Andrew Co-authored-by: fuzzbuck <54221024+fuzzbuck@users.noreply.github.com> Co-authored-by: Sunny Kim <58885089+sk7725@users.noreply.github.com> Co-authored-by: simba-fs Co-authored-by: Simba-Fs <39305460+simba-fs@users.noreply.github.com> Co-authored-by: Volas171 <60143910+Volas171@users.noreply.github.com> Co-authored-by: DeltaNedas <39013340+DeltaNedas@users.noreply.github.com> * "Search bar cleanup" update * Hope this fixes merge conflict * Delete servers_v6.json * pain * Sync (#21) * Fixed #4108 * [QoL] Chat modes (#3869) Credits: Remint32 (idea); sk7725 (korean i18n); Volas171 (spanish i18n). * add new io server (#4109) soon to be up gamemode * typo (#4110) * Fixed mined item flashing on clients * Block Forge improvements (#4112) * minBlockSize, maxBlockSize, icon * removed fixed size * same line * revert to 3 * I almost forgot * Up-to-date zh-TW translations (#4083) * Update bundle_zh_TW.properties Corrected some machine translations. Modified some others for more clear understanding. * Update bundle_zh_TW.properties * Update bundle_zh_TW.properties new translations 1 * Update bundle_zh_TW.properties New translations 2 * Update bundle_zh_TW.properties New translations 3 * New translations 1-3 Removed "zones" from v121.4: "Fixed sectors not auto-unlocking". 衝擊反應堆 -->動能反應爐 * New translations 1-4 * New translations 1-5 * New translations 1-6 up to line 1250 * Indexing finished. Translations 1-7 lines are now matching with English bundle. * update bundle_zh_TW.properties * edit zh_TW * zh-tw * community server disclaimer * Finished sector descriptions, slight modifications up to line 606 * zh-TW * Many translations, include Always-on weather rule * corrected missing character * Update achievements.vdf Oct not translated * Update description.txt * bundle_zh_TW.properties * Bullet stats update, hints finished * added line: public confirm really * contributors * Merging conflicts Almost done... * Synced * Update ammo-stat translation * Update contributors * Unit names * Update bundle_zh_TW.properties * Unit names * Update bundle_zh_TW.properties * Review (#15) * Update bundle_zh_TW.properties * Unit names * Update bundle_zh_TW.properties * Finished Please review * minor correction * minor correction Hopefully there are no more "minor corrections" required. * Review * Close inspection * Revisions, change chat mode * Sapping Correction Co-authored-by: simba-fs Co-authored-by: Simba-Fs <39305460+simba-fs@users.noreply.github.com> * Higher power source output * Update servers_v6.json (#4095) * Update servers_v6.json the ip changed to not make users confuse * Update servers_v6.json * Fixed #4120 * Fixed #4121 * Fixed #4122 * Better build beam visuals * Don't render weather in full map screenshots * Building priority fix * Fixed #4128 * SearchBar class - add search bars to mods (#3267) * Create SearchBar and make ModsDialog use it * add search bar to servers * Update core/src/mindustry/ui/SearchBar.java Co-authored-by: Antsiferov Andrew * a * fix mods menu not rowing * remove search bar for remote servers * h * hide searchbar on landscape mobile * anukes feedback * Update core/src/mindustry/ui/SearchBar.java Co-authored-by: Anuken * java dumb Co-authored-by: Antsiferov Andrew Co-authored-by: Anuken * Search bar cleanup * Block (un)loader major improvements (#4127) * make it consider consVaild * make this too * pattern style and max block size * Is there a better way to do this? * Update BlockUnloader.java * do not the /0 * prevent /0 * test 1 * yup it works for enabled * bugfixes, call me the mother of the block forge (#4135) (anuke is the father) * Fixed #4141 / Fixed #4136 * Faster power graph reload / Fixed iOS editor margin * Remove 4 square blocks from the accelerator (#4139) * Normalize rule comment line endings Just so i can get a new patch-## branch where i can drag my accelerator sprite on since github isn't smart enough yet to see that as a possible pull request by itself. * Add files via upload * Add files via upload * Use sector preset name for maps if possible * Fixed #4147 * Update servers_v6.json (#4148) changed the port number for our attack server. sorry for the inconvenience, i don't have control over the port number of this "alexmindustryattac.ddns.net" hosted server. * Removed packed sprite section from CONTRIBUTING.md (#4152) * Return large launchpad item costs (#4134) * Return large launchpad item costs hidden -> debugonly * Remove the 4 orange squares from the large launch pad Leaving the lights and launchpod alignments alone since that is campaign only. * Sector damage tweaks * Block loader/unloader progress bar changes (#4138) * Change block loader/unloader progess bar color & bundle ammo -> items * Make block unloader bar go down * Draw reconstructor in region during placement & unconnected (#4143) * Draw reconstructor in region during placement & unconnected * Same as the previous commit, but for block loaders & unloaders * Bugfixes * Fixed #4164 / Fixed #4159 * fix german translation for editor.unsaved (#4169) * update KO bundles (#3956) * Update steam description for 6.0 update * Update achievements.vdf * oops. * Update full_description.txt * Update summary.txt * add recent changelog * Update bundle_ko.properties * last update on this week (well, sunday) * upload android recent change-log * critical fix * [KO] Small fix (#4133) * why * Update bundle_ko.properties * bundle_hu.properties (#4170) I'am continue translating and adding lines to v6. * [Bundle][RO] Translation update (#4115) * [Bundle][RO] Translation update This PR was tested in-game and is _**ready to merge at any time**_ (unless marked as draft). Changelog: - New strings/changes up to commit 43757a247ef3bd0508d25dce2c4c38846cb1fb1c - Typo fixes & various other improvements * no * yet another in_ID translation update (#4086) * yet another in_ID translation update * more id translate Co-authored-by: Quick-Korc <68910156+Quick-korkc@users.noreply.github.com> * Cleanup Co-authored-by: Anuken Co-authored-by: Antsiferov Andrew Co-authored-by: fuzzbuck <54221024+fuzzbuck@users.noreply.github.com> Co-authored-by: Sunny Kim <58885089+sk7725@users.noreply.github.com> Co-authored-by: simba-fs Co-authored-by: Simba-Fs <39305460+simba-fs@users.noreply.github.com> Co-authored-by: Volas171 <60143910+Volas171@users.noreply.github.com> Co-authored-by: DeltaNedas <39013340+DeltaNedas@users.noreply.github.com> Co-authored-by: Patrick 'Quezler' Mounier Co-authored-by: alex <67626131+alexpvpmindustry@users.noreply.github.com> Co-authored-by: Catchears <57631841+Catchears@users.noreply.github.com> Co-authored-by: Sharlotte <60801210+sharlotte-mobile@users.noreply.github.com> Co-authored-by: Vajda Simon <75036456+VajdaSimon@users.noreply.github.com> Co-authored-by: YellOw139 <70975516+YellOw139@users.noreply.github.com> Co-authored-by: Thomas Widyantoko <40286070+DaGamerFiles@users.noreply.github.com> Co-authored-by: Quick-Korc <68910156+Quick-korkc@users.noreply.github.com> * Update gradle.properties * Update bundle_zh_TW.properties Co-authored-by: simba-fs Co-authored-by: Simba-Fs <39305460+simba-fs@users.noreply.github.com> Co-authored-by: Anuken Co-authored-by: Antsiferov Andrew Co-authored-by: fuzzbuck <54221024+fuzzbuck@users.noreply.github.com> Co-authored-by: Sunny Kim <58885089+sk7725@users.noreply.github.com> Co-authored-by: Volas171 <60143910+Volas171@users.noreply.github.com> Co-authored-by: DeltaNedas <39013340+DeltaNedas@users.noreply.github.com> Co-authored-by: Patrick 'Quezler' Mounier Co-authored-by: alex <67626131+alexpvpmindustry@users.noreply.github.com> Co-authored-by: Catchears <57631841+Catchears@users.noreply.github.com> Co-authored-by: Sharlotte <60801210+sharlotte-mobile@users.noreply.github.com> Co-authored-by: Vajda Simon <75036456+VajdaSimon@users.noreply.github.com> Co-authored-by: YellOw139 <70975516+YellOw139@users.noreply.github.com> Co-authored-by: Thomas Widyantoko <40286070+DaGamerFiles@users.noreply.github.com> Co-authored-by: Quick-Korc <68910156+Quick-korkc@users.noreply.github.com> --- core/assets/bundles/bundle_zh_TW.properties | 5 +++-- gradle.properties | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 77a37663b1..b8f7cde747 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -89,6 +89,7 @@ joingame = 多人連線 customgame = 自訂遊戲 newgame = 新遊戲 none = 〈沒有〉 +none.found = [lightgray]〈查無結果〉 minimap = 小地圖 position = 位置 close = 關閉 @@ -296,7 +297,7 @@ data.exported = 資料已匯出。 data.invalid = 這不是有效的遊戲資料。 data.import.confirm = 導入外部資料將會覆寫您目前[scarlet]所有的[]遊戲資料,\n[accent]此動作無法復原![]\n\n匯入資料後,您的遊戲將立刻結束。 quit.confirm = 您確定要結束嗎? -quit.confirm.tutorial = 您確定您知道自己在做什麼嗎?\n可以在[accent] 設定->遊戲[] 選項中重設教學。 +quit.confirm.tutorial = 您確定您知道自己在做什麼嗎?\n可以在[accent] 設定-遊戲[] 選項中重設教學。 loading = [accent]載入中…… reloading = [accent]模組重新載入中…… saving = [accent]儲存中…… @@ -621,7 +622,7 @@ settings.sound = 音效 settings.graphics = 圖形 settings.cleardata = 清除遊戲資料…… settings.clear.confirm = 您確定要清除資料嗎?\n此動作無法復原! -settings.clearall.confirm = [scarlet]警告![]\n這會清除所有資料,包括存檔、地圖、解鎖項目和快捷鍵綁定。\n按「是」後,遊戲將刪除所有資料並自動結束。 +settings.clearall.confirm = [scarlet]警告![]\n這會清除所有資料,包括存檔、地圖、解鎖項目和快捷鍵綁定。\n按「確定」後,遊戲將刪除所有資料並自動結束。 settings.clearsaves.confirm = 您確定您想要清除所有存檔嗎? settings.clearsaves = 清除存檔 settings.clearresearch = 清除研究 diff --git a/gradle.properties b/gradle.properties index f42373473e..067e8595ff 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=5e9176c3feefa5ee2f14b08f82da1f01f790e64a +archash=5e9176c3feefa5ee2f14b08f82da1f01f790e64a \ No newline at end of file From 8cdb4c083179fa54e7f5a01e586cee0b59367c71 Mon Sep 17 00:00:00 2001 From: Quick-Korc <68910156+Quick-korkc@users.noreply.github.com> Date: Mon, 4 Jan 2021 22:56:39 +0700 Subject: [PATCH 009/426] Indonesian Gplay Translate (#3708) * Indonesian Gplay Translate * Create 29741.txt --- fastlane/metadata/android/in/full_description.txt | 10 +++++----- .../android/in/https:/github.com/changelogs/29741.txt | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt diff --git a/fastlane/metadata/android/in/full_description.txt b/fastlane/metadata/android/in/full_description.txt index cd5adae89b..de36ab1262 100644 --- a/fastlane/metadata/android/in/full_description.txt +++ b/fastlane/metadata/android/in/full_description.txt @@ -2,13 +2,13 @@ Buat rantai pasokan pengantar berjalan yang rumit untuk memasukkan amunisi ke me Fitur: - 24 peta bawaan -- Kampanye, lengkap dengan pohon teknologi dan area yang dapat dibuka -- 4 bos gelombang yang kuat untuk dikalahkan +- Kampanye, lengkap dengan pohon teknologi dan sebuah planet untuk dikuasai +- Pasukan penjaga yang sangat kuat untuk dikalahkan - Sistem transportasi energi, cairan dan barang -- 19 jenis drone, mech, dan kapal -- 120+ blok teknologi untuk dikuasai +- 33 jenis unit yang terdiri dari drone, meka, dan kapal +- 120+ blok teknologi yang bisa dipelajari - 75+ blok lingkungan yang berbeda - Multipemain lintas platform melalui jaringan lokal atau server khusus -- Aturan permainan khusus: Ubah biaya blok, statistik musuh, item awal, waktu gelombang, dan lainnya +- Pengaturan permainan khusus: Ubah biaya blok, statistik musuh, item awal, waktu gelombang, dan lainnya - Editor yang andal, dengan alat untuk menghasilkan sumber daya, medan, dekorasi, dan menerapkan simetri ke peta secara acak - Tata letak gelombang peta yang dapat disesuaikan diff --git a/fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt b/fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt new file mode 100644 index 0000000000..bce5747339 --- /dev/null +++ b/fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt @@ -0,0 +1,5 @@ +[Ini adalah log perubahan yang terpotong, lihat Github untuk catatan lengkapnya] +- Memperbaiki 2 crash yang jarang terjadi +- Unit yang dibuat bergantung pada bahan produksinya di pohon teknologi +- Distributor sekarang dapat menimpa pengantar +- Memperbarui terjemahan From 961331c8325227e61625f71119c15b0b839563fd Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 4 Jan 2021 11:06:11 -0500 Subject: [PATCH 010/426] Minor turret targeting fix --- core/src/mindustry/world/blocks/defense/turrets/Turret.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 044f583722..60b31fa8d7 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -210,7 +210,7 @@ public class Turret extends ReloadTurret{ } public void targetPosition(Posc pos){ - if(!hasAmmo() || target == null) return; + if(!hasAmmo() || pos == null) return; BulletType bullet = peekAmmo(); float speed = bullet.speed; //slow bullets never intersect @@ -218,7 +218,7 @@ public class Turret extends ReloadTurret{ targetPos.set(Predict.intercept(this, pos, speed)); if(targetPos.isZero()){ - targetPos.set(target); + targetPos.set(pos); } } From 0ab4f01d5d47e92331cd27e80ad690d8dd19f0d9 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 4 Jan 2021 11:20:01 -0500 Subject: [PATCH 011/426] Better suicide bomb trigger check --- core/src/mindustry/entities/comp/UnitComp.java | 4 +++- gradle.properties | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 81a604e455..bce58a2c9d 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -46,6 +46,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I transient Seq abilities = new Seq<>(0); private transient float resupplyTime = Mathf.random(10f); + private transient boolean wasPlayer; public void moveAt(Vec2 vector){ moveAt(vector, type.accel); @@ -423,7 +424,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I Events.fire(new UnitDestroyEvent(self())); - if(explosiveness > 7f && isLocal()){ + if(explosiveness > 7f && (isLocal() || wasPlayer)){ Events.fire(Trigger.suicideBomb); } @@ -481,6 +482,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I @Override public void killed(){ + wasPlayer = isLocal(); health = 0; dead = true; diff --git a/gradle.properties b/gradle.properties index 067e8595ff..f42373473e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=5e9176c3feefa5ee2f14b08f82da1f01f790e64a \ No newline at end of file +archash=5e9176c3feefa5ee2f14b08f82da1f01f790e64a From 69eb8faf67e49d83f4b3c18278937f373c08b012 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 4 Jan 2021 17:22:18 -0500 Subject: [PATCH 012/426] Fixed #4261 / Basic rotation shine effect --- core/src/mindustry/audio/SoundControl.java | 6 +++++- core/src/mindustry/content/Fx.java | 6 ++++++ core/src/mindustry/entities/comp/BuildingComp.java | 4 ++-- core/src/mindustry/entities/comp/UnitComp.java | 2 +- core/src/mindustry/input/InputHandler.java | 1 + core/src/mindustry/ui/dialogs/CustomRulesDialog.java | 4 ++-- core/src/mindustry/world/Build.java | 1 + gradle.properties | 2 +- 8 files changed, 19 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/audio/SoundControl.java b/core/src/mindustry/audio/SoundControl.java index bed176f972..6dc130c53f 100644 --- a/core/src/mindustry/audio/SoundControl.java +++ b/core/src/mindustry/audio/SoundControl.java @@ -130,7 +130,11 @@ public class SoundControl{ Core.audio.soundBus.play(); setupFilters(); }else{ - Core.audio.soundBus.stop(); + for(Sound sound : Core.assets.getAll(Sound.class, new Seq<>())){ + if(sound.bus == Core.audio.soundBus){ + sound.stop(); + } + } } } diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index 7688108ebe..c862885e2f 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -1564,6 +1564,12 @@ public class Fx{ Fill.square(e.x, e.y, e.rotation * tilesize / 2f); }), + rotateBlock = new Effect(30, e -> { + color(Pal.accent); + alpha(e.fout() * 1); + Fill.square(e.x, e.y, e.rotation * tilesize / 2f); + }), + overdriveBlockFull = new Effect(60, e -> { color(e.color); alpha(e.fslope() * 0.4f); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 1ac7394258..37a5775124 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -970,8 +970,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, } if(block.hasLiquids){ - flammability += liquids.sum((liquid, amount) -> liquid.explosiveness * amount / 2f); - explosiveness += liquids.sum((liquid, amount) -> liquid.flammability * amount / 2f); + flammability += liquids.sum((liquid, amount) -> liquid.flammability * amount / 2f); + explosiveness += liquids.sum((liquid, amount) -> liquid.explosiveness * amount / 2f); } if(block.consumes.hasPower() && block.consumes.getPower().buffered){ diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index bce58a2c9d..fd3f1810ff 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -273,7 +273,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I team.data().updateCount(type, 1); //check if over unit cap - if(count() > cap() && !spawnedByCore && !dead){ + if(count() > cap() && !spawnedByCore && !dead && !state.rules.editor){ Call.unitCapDeath(self()); team.data().updateCount(type, -1); } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 8d9d1c15e7..7bc5fe5e80 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -305,6 +305,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ build.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4); build.updateProximity(); build.noSleep(); + Fx.rotateBlock.at(build.x, build.y, build.block.size); } @Remote(targets = Loc.both, called = Loc.both, forward = true) diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index ece89b15f8..6026232f39 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -142,7 +142,7 @@ public class CustomRulesDialog extends BaseDialog{ check("@rules.reactorexplosions", b -> rules.reactorExplosions = b, () -> rules.reactorExplosions); check("@rules.schematic", b -> rules.schematicsAllowed = b, () -> rules.schematicsAllowed); number("@rules.buildcostmultiplier", false, f -> rules.buildCostMultiplier = f, () -> rules.buildCostMultiplier, () -> !rules.infiniteResources); - number("@rules.buildspeedmultiplier", f -> rules.buildSpeedMultiplier = f, () -> rules.buildSpeedMultiplier, 0.00001f, 10000f); + number("@rules.buildspeedmultiplier", f -> rules.buildSpeedMultiplier = f, () -> rules.buildSpeedMultiplier, 0.001f, 50f); number("@rules.deconstructrefundmultiplier", false, f -> rules.deconstructRefundMultiplier = f, () -> rules.deconstructRefundMultiplier, () -> !rules.infiniteResources); number("@rules.blockhealthmultiplier", f -> rules.blockHealthMultiplier = f, () -> rules.blockHealthMultiplier); number("@rules.blockdamagemultiplier", f -> rules.blockDamageMultiplier = f, () -> rules.blockDamageMultiplier); @@ -162,7 +162,7 @@ public class CustomRulesDialog extends BaseDialog{ check("@rules.unitammo", b -> rules.unitAmmo = b, () -> rules.unitAmmo); number("@rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier); number("@rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); - number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0.00001f, 100f); + number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0.001f, 50f); title("@rules.title.enemy"); check("@rules.attack", b -> rules.attackMode = b, () -> rules.attackMode); diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index b450509c7b..62840ebd9b 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -71,6 +71,7 @@ public class Build{ tile.build.rotation = Mathf.mod(rotation, 4); tile.build.updateProximity(); tile.build.noSleep(); + Fx.rotateBlock.at(tile.build.x, tile.build.y, tile.build.block.size); return; } diff --git a/gradle.properties b/gradle.properties index f42373473e..b16e790ee1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=5e9176c3feefa5ee2f14b08f82da1f01f790e64a +archash=0f1967eae73429ade796500d5ec352c6a4d1d19d From 0c4750781a716fadc6c7362207847448b667983a Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 4 Jan 2021 19:50:49 -0500 Subject: [PATCH 013/426] Sound cleanup --- core/src/mindustry/audio/SoundControl.java | 6 +----- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/audio/SoundControl.java b/core/src/mindustry/audio/SoundControl.java index 6dc130c53f..c7d61df9b9 100644 --- a/core/src/mindustry/audio/SoundControl.java +++ b/core/src/mindustry/audio/SoundControl.java @@ -130,11 +130,7 @@ public class SoundControl{ Core.audio.soundBus.play(); setupFilters(); }else{ - for(Sound sound : Core.assets.getAll(Sound.class, new Seq<>())){ - if(sound.bus == Core.audio.soundBus){ - sound.stop(); - } - } + Core.audio.soundBus.replay(); } } diff --git a/gradle.properties b/gradle.properties index b16e790ee1..865cb902a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=0f1967eae73429ade796500d5ec352c6a4d1d19d +archash=224199824e400942bc2da35fd6445720f135720d From 42fb6ffa0dd24b61127b78ded16cae7b056375cb Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 5 Jan 2021 16:37:37 +0100 Subject: [PATCH 014/426] Add core incineration to custom rules dialog (#4264) * Update CustomRulesDialog.java * Update bundle.properties * Update core/assets/bundles/bundle.properties Co-authored-by: YellOw139 <70975516+YellOw139@users.noreply.github.com> Co-authored-by: YellOw139 <70975516+YellOw139@users.noreply.github.com> --- core/assets/bundles/bundle.properties | 1 + core/src/mindustry/ui/dialogs/CustomRulesDialog.java | 1 + 2 files changed, 2 insertions(+) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index ca33ac045b..9834514f8c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -935,6 +935,7 @@ mode.custom = Custom Rules rules.infiniteresources = Infinite Resources rules.reactorexplosions = Reactor Explosions +rules.coreincinerates = Core Incinerates Overflow rules.schematic = Schematics Allowed rules.wavetimer = Wave Timer rules.waves = Waves diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index 6026232f39..2e6d923063 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -141,6 +141,7 @@ public class CustomRulesDialog extends BaseDialog{ check("@rules.infiniteresources", b -> rules.infiniteResources = b, () -> rules.infiniteResources); check("@rules.reactorexplosions", b -> rules.reactorExplosions = b, () -> rules.reactorExplosions); check("@rules.schematic", b -> rules.schematicsAllowed = b, () -> rules.schematicsAllowed); + check("@rules.coreincinerates", b -> rules.coreIncinerates = b, () -> rules.coreIncinerates); number("@rules.buildcostmultiplier", false, f -> rules.buildCostMultiplier = f, () -> rules.buildCostMultiplier, () -> !rules.infiniteResources); number("@rules.buildspeedmultiplier", f -> rules.buildSpeedMultiplier = f, () -> rules.buildSpeedMultiplier, 0.001f, 50f); number("@rules.deconstructrefundmultiplier", false, f -> rules.deconstructRefundMultiplier = f, () -> rules.deconstructRefundMultiplier, () -> !rules.infiniteResources); From fdf08ed51d9d589a1e939873b37671d4f5ea30a1 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 5 Jan 2021 16:43:36 +0100 Subject: [PATCH 015/426] Highlight all linked inventories on core selection (#4256) * Highlight all linked inventories on core selection * Loop cores instead of storage blocks --- .../mindustry/world/blocks/storage/CoreBlock.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 677c3a83b6..13e84e1dd8 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -296,17 +296,17 @@ public class CoreBlock extends StorageBlock{ @Override public void drawSelect(){ Lines.stroke(1f, Pal.accent); - Cons outline = t -> { + Cons outline = b -> { for(int i = 0; i < 4; i++){ Point2 p = Geometry.d8edge[i]; - float offset = -Math.max(t.block.size - 1, 0) / 2f * tilesize; - Draw.rect("block-select", t.x + offset * p.x, t.y + offset * p.y, i * 90); + float offset = -Math.max(b.block.size - 1, 0) / 2f * tilesize; + Draw.rect("block-select", b.x + offset * p.x, b.y + offset * p.y, i * 90); } }; - if(proximity.contains(e -> owns(e) && e.items == items)){ - outline.get(this); - } - proximity.each(e -> owns(e) && e.items == items, outline); + team.cores().each(core -> { + outline.get(core); + core.proximity.each(storage -> storage.items == items, outline); + }); Draw.reset(); } From 5c24254d8485c8668b10c24a5bffe7c53e3126c4 Mon Sep 17 00:00:00 2001 From: PAP6 <68839421+PAP6@users.noreply.github.com> Date: Wed, 6 Jan 2021 01:52:21 +1000 Subject: [PATCH 016/426] Update servers_v6.json (#4263) Reason: This server is currently running version 104.10, so it shouldn't be here. --- servers_v6.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/servers_v6.json b/servers_v6.json index ff486ea497..115b18db01 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -35,10 +35,6 @@ "name": "TWS", "address": ["twsmindustry.24x7.hk:6701", "twsmindustry.24x7.hk:6702"] }, - { - "address": "cheginde.ddns.net" - - }, { "name": "mindustry.ddns.net", "address": ["mindustry.ddns.net:1000", "mindustry.ddns.net:2000", "mindustry.ddns.net:3000", "mindustry.ddns.net:4000"] From 5516435619843e0b1781c97a5208f0983bdd1779 Mon Sep 17 00:00:00 2001 From: VozDuh <61590217+Voz-Duh@users.noreply.github.com> Date: Tue, 5 Jan 2021 23:17:18 +0300 Subject: [PATCH 017/426] Custom Launch Pad Pod Textures (#4203) * Custom Launch Pad Pod Textures * Facepalm * Fix * Fix * Fix Co-authored-by: Anuken * Fix Anuke! Co-authored-by: Anuken --- core/src/mindustry/world/blocks/campaign/LaunchPad.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/blocks/campaign/LaunchPad.java b/core/src/mindustry/world/blocks/campaign/LaunchPad.java index d0804bd4cf..838efde720 100644 --- a/core/src/mindustry/world/blocks/campaign/LaunchPad.java +++ b/core/src/mindustry/world/blocks/campaign/LaunchPad.java @@ -32,7 +32,7 @@ public class LaunchPad extends Block{ public Sound launchSound = Sounds.none; public @Load("@-light") TextureRegion lightRegion; - public @Load("launchpod") TextureRegion podRegion; + public @Load(value = "@-pod", fallback = "launchpod") TextureRegion podRegion; public Color lightColor = Color.valueOf("eab678"); public LaunchPad(String name){ @@ -200,7 +200,7 @@ public class LaunchPad extends Block{ Draw.z(Layer.weather - 1); - TextureRegion region = Core.atlas.find("launchpod"); + TextureRegion region = blockOn() instanceof mindustry.world.blocks.campaign.LaunchPad p ? p.podRegion : Core.atlas.find("launchpod"); float rw = region.width * Draw.scl * scale, rh = region.height * Draw.scl * scale; Draw.alpha(alpha); From f4bf8fd998087d6620b953dcb35b48a7483e1e09 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 5 Jan 2021 21:32:43 +0100 Subject: [PATCH 018/426] Add boost bars to overdrive projectors (#4255) * Add boost bars to overdrive projectors * Add bar.boost to bundle * Intelij lied to me --- core/assets/bundles/bundle.properties | 1 + .../blocks/defense/OverdriveProjector.java | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 9834514f8c..2bd0b64eaf 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -720,6 +720,7 @@ bar.corereq = Core Base Required bar.drillspeed = Drill Speed: {0}/s bar.pumpspeed = Pump Speed: {0}/s bar.efficiency = Efficiency: {0}% +bar.boost = Boost: {0}% bar.powerbalance = Power: {0}/s bar.powerstored = Stored: {0}/{1} bar.poweramount = Power: {0} diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index ad845991c7..5066186e71 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -1,5 +1,6 @@ package mindustry.world.blocks.defense; +import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; @@ -9,6 +10,7 @@ import mindustry.annotations.Annotations.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.logic.*; +import mindustry.ui.*; import mindustry.world.*; import mindustry.world.meta.*; @@ -62,6 +64,12 @@ public class OverdriveProjector extends Block{ } } + @Override + public void setBars(){ + super.setBars(); + bars.add("boost", (OverdriveBuild entity) -> new Bar(() -> Core.bundle.format("bar.boost", (int)(entity.realBoost() * 100)), () -> Pal.accent, () -> entity.realBoost() / (hasBoost ? speedBoost + speedBoostPhase : speedBoost))); + } + public class OverdriveBuild extends Building implements Ranged{ float heat; float charge = Mathf.random(reload); @@ -88,17 +96,20 @@ public class OverdriveProjector extends Block{ phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(cons.optionalValid()), 0.1f); } + if(charge >= reload){ + float realRange = range + phaseHeat * phaseRangeBoost; + + charge = 0f; + indexer.eachBlock(this, realRange, other -> true, other -> other.applyBoost(realBoost(), reload + 1f)); + } + if(timer(timerUse, useTime) && efficiency() > 0 && consValid()){ consume(); } + } - if(charge >= reload){ - float realRange = range + phaseHeat * phaseRangeBoost; - float realBoost = (speedBoost + phaseHeat * speedBoostPhase) * efficiency(); - - charge = 0f; - indexer.eachBlock(this, realRange, other -> true, other -> other.applyBoost(realBoost, reload + 1f)); - } + public float realBoost(){ + return consValid() ? (speedBoost + phaseHeat * speedBoostPhase) * efficiency() : 0f; } @Override From ebf4435af46d1565bf9691d12fc4301eb3e2e770 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 5 Jan 2021 18:59:46 -0500 Subject: [PATCH 019/426] Fixed #4270 --- .../android/in/https:/github.com/changelogs/29741.txt | 5 ----- gradle.properties | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt diff --git a/fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt b/fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt deleted file mode 100644 index bce5747339..0000000000 --- a/fastlane/metadata/android/in/https:/github.com/changelogs/29741.txt +++ /dev/null @@ -1,5 +0,0 @@ -[Ini adalah log perubahan yang terpotong, lihat Github untuk catatan lengkapnya] -- Memperbaiki 2 crash yang jarang terjadi -- Unit yang dibuat bergantung pada bahan produksinya di pohon teknologi -- Distributor sekarang dapat menimpa pengantar -- Memperbarui terjemahan diff --git a/gradle.properties b/gradle.properties index 865cb902a7..203de61508 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=224199824e400942bc2da35fd6445720f135720d +archash=71b1c84015119f57bf4d215f594ead1ffc9e8744 From 1be91961d6cb54a6676c91318d259ff398eaed02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Thu, 7 Jan 2021 01:15:34 +0800 Subject: [PATCH 020/426] core inc & boost meter (#4272) --- core/assets/bundles/bundle_zh_TW.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index b8f7cde747..0264786742 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -720,6 +720,7 @@ bar.corereq = 需由核心升級 bar.drillspeed = 鑽頭速度:{0}/秒 bar.pumpspeed = 液體泵送速度:{0}/秒 bar.efficiency = 效率:{0}% +bar.boost = 速度加成:{0}% bar.powerbalance = 能量變化:{0} bar.powerstored = 能量存量:{0}/{1} bar.poweramount = 能量:{0} @@ -935,6 +936,7 @@ mode.custom = 自訂規則 rules.infiniteresources = 無限資源 rules.reactorexplosions = 反應爐爆炸 +rules.coreincinerates = 核心銷毀物品 rules.schematic = 允許使用藍圖 rules.wavetimer = 波次時間 rules.waves = 波次 From 99aec4ad15c98270a23947382fe16d66368b391f Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 6 Jan 2021 16:25:05 -0500 Subject: [PATCH 021/426] Fixed #4277 --- core/src/mindustry/logic/LExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 29811c8205..45c28bb75a 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -952,7 +952,7 @@ public class LExecutor{ Var vb = exec.var(compare); boolean cmp; - if(op.objFunction != null && (va.isobj || vb.isobj)){ + if(op.objFunction != null && va.isobj && vb.isobj){ //use object function if provided, and one of the variables is an object cmp = op.objFunction.get(exec.obj(value), exec.obj(compare)); }else{ From c7d059a58f1cc0dfdb92ed963377555566f19317 Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Thu, 7 Jan 2021 17:52:02 +0300 Subject: [PATCH 022/426] Don't terminate socket server on connection reset (#4282) --- server/src/mindustry/server/ServerControl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index 553fd6af74..44f0603c5c 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -1045,7 +1045,7 @@ public class ServerControl implements ApplicationListener{ }catch(BindException b){ err("Command input socket already in use. Is another instance of the server running?"); }catch(IOException e){ - if(!e.getMessage().equals("Socket closed")){ + if(!e.getMessage().equals("Socket closed") && !e.getMessage().equals("Connection reset")){ err("Terminating socket server."); err(e); } From f231849a42c1a44dc9f9794ba0c515d2cf75d6af Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 7 Jan 2021 10:08:28 -0500 Subject: [PATCH 023/426] UnitCreateEvent / UnitDeployEvent split --- core/src/mindustry/game/EventType.java | 14 +++++++++++++- .../world/blocks/payloads/UnitPayload.java | 3 +++ .../world/blocks/units/Reconstructor.java | 2 +- .../mindustry/world/blocks/units/UnitBlock.java | 15 --------------- .../mindustry/world/blocks/units/UnitFactory.java | 2 ++ 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index 3efe48932e..405398c370 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -351,10 +351,22 @@ public class EventType{ } } + /** Called when a unit is created in a reconstructor or factory. */ public static class UnitCreateEvent{ public final Unit unit; + public final Building spawner; - public UnitCreateEvent(Unit unit){ + public UnitCreateEvent(Unit unit, Building spawner){ + this.unit = unit; + this.spawner = spawner; + } + } + + /** Called when a unit is dumped from any payload block. */ + public static class UnitUnloadEvent{ + public final Unit unit; + + public UnitUnloadEvent(Unit unit){ this.unit = unit; } } diff --git a/core/src/mindustry/world/blocks/payloads/UnitPayload.java b/core/src/mindustry/world/blocks/payloads/UnitPayload.java index c02ca68f5d..cb04b5f36d 100644 --- a/core/src/mindustry/world/blocks/payloads/UnitPayload.java +++ b/core/src/mindustry/world/blocks/payloads/UnitPayload.java @@ -1,5 +1,6 @@ package mindustry.world.blocks.payloads; +import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; @@ -9,6 +10,7 @@ import arc.util.io.*; import mindustry.*; import mindustry.entities.EntityCollisions.*; import mindustry.entities.*; +import mindustry.game.EventType.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.ui.*; @@ -67,6 +69,7 @@ public class UnitPayload implements Payload{ //prevents stacking unit.vel.add(Mathf.range(0.5f), Mathf.range(0.5f)); unit.add(); + Events.fire(new UnitUnloadEvent(unit)); return true; } diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index 3f65908068..849e999059 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -179,7 +179,7 @@ public class Reconstructor extends UnitBlock{ Effect.shake(2f, 3f, this); Fx.producesmoke.at(this); consume(); - Events.fire(new UnitCreateEvent(payload.unit)); + Events.fire(new UnitCreateEvent(payload.unit, this)); } } } diff --git a/core/src/mindustry/world/blocks/units/UnitBlock.java b/core/src/mindustry/world/blocks/units/UnitBlock.java index 5de6fd135b..ac38d3452f 100644 --- a/core/src/mindustry/world/blocks/units/UnitBlock.java +++ b/core/src/mindustry/world/blocks/units/UnitBlock.java @@ -36,21 +36,6 @@ public class UnitBlock extends PayloadAcceptor{ public void spawned(){ progress = 0f; - - Tmp.v1.trns(rotdeg(), size * tilesize/2f); - Fx.smeltsmoke.at(x + Tmp.v1.x, y + Tmp.v1.y); - - if(!net.client() && payload != null){ - Unit unit = payload.unit; - unit.set(x, y); - unit.rotation(rotdeg()); - unit.vel().trns(rotdeg(), payloadSpeed * 2f).add(Mathf.range(0.3f), Mathf.range(0.3f)); - unit.trns(Tmp.v1.trns(rotdeg(), size * tilesize/2f)); - unit.trns(unit.vel()); - unit.add(); - Events.fire(new UnitCreateEvent(unit)); - } - payload = null; } diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 1a257d9565..9f62c198e6 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -12,6 +12,7 @@ import arc.util.io.*; import mindustry.*; import mindustry.entities.*; import mindustry.entities.units.*; +import mindustry.game.EventType.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.logic.*; @@ -228,6 +229,7 @@ public class UnitFactory extends UnitBlock{ payload = new UnitPayload(plan.unit.create(team)); payVector.setZero(); consume(); + Events.fire(new UnitCreateEvent(payload.unit, this)); } progress = Mathf.clamp(progress, 0, plan.time); From 13fbcb9ba8f2b23d6cc68faac32fc44f511a0319 Mon Sep 17 00:00:00 2001 From: genNAowl <68400583+genNAowl@users.noreply.github.com> Date: Thu, 7 Jan 2021 10:38:31 -0800 Subject: [PATCH 024/426] Launch UI Max Button (#4238) * max * Add @Nullable Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com> --- core/assets/bundles/bundle.properties | 1 + .../mindustry/ui/dialogs/LaunchLoadoutDialog.java | 5 ++++- core/src/mindustry/ui/dialogs/LoadoutDialog.java | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 2bd0b64eaf..db940ba4a2 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -287,6 +287,7 @@ cancel = Cancel openlink = Open Link copylink = Copy Link back = Back +max = Max crash.export = Export Crash Logs crash.none = No crash logs found. crash.exported = Crash logs exported. diff --git a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java index c8ea27ae97..77ae944639 100644 --- a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java +++ b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java @@ -86,7 +86,10 @@ public class LaunchLoadoutDialog extends BaseDialog{ ItemSeq stacks = universe.getLaunchResources(); Seq out = stacks.toSeq(); - loadout.show(selected.findCore().itemCapacity, out, UnlockableContent::unlocked, out::clear, () -> {}, () -> { + ItemSeq realItems = sitems.copy(); + selected.requirements().each(realItems::remove); + + loadout.show(selected.findCore().itemCapacity, realItems, out, UnlockableContent::unlocked, out::clear, () -> {}, () -> { universe.updateLaunchResources(new ItemSeq(out)); update.run(); rebuildItems.run(); diff --git a/core/src/mindustry/ui/dialogs/LoadoutDialog.java b/core/src/mindustry/ui/dialogs/LoadoutDialog.java index d818f5ecda..24e3b2d8f4 100644 --- a/core/src/mindustry/ui/dialogs/LoadoutDialog.java +++ b/core/src/mindustry/ui/dialogs/LoadoutDialog.java @@ -22,6 +22,7 @@ public class LoadoutDialog extends BaseDialog{ private Boolf validator = i -> true; private Table items; private int capacity; + private @Nullable ItemSeq total; public LoadoutDialog(){ super("@configure"); @@ -46,6 +47,8 @@ public class LoadoutDialog extends BaseDialog{ buttons.button("@back", Icon.left, this::hide).size(210f, 64f); + buttons.button("@max", Icon.export, this::maxItems).size(210f, 64f); + buttons.button("@settings.reset", Icon.refresh, () -> { resetter.run(); reseed(); @@ -54,12 +57,23 @@ public class LoadoutDialog extends BaseDialog{ }).size(210f, 64f); } + public void maxItems() { + for(ItemStack stack : stacks){ + stack.amount = total == null ? capacity : Math.min(capacity, total.get(stack.item)); + } + } + public void show(int capacity, Seq stacks, Boolf validator, Runnable reseter, Runnable updater, Runnable hider){ + show(capacity, null, stacks, validator, reseter, updater, hider); + } + + public void show(int capacity, ItemSeq total, Seq stacks, Boolf validator, Runnable reseter, Runnable updater, Runnable hider){ this.originalStacks = stacks; this.validator = validator; this.resetter = reseter; this.updater = updater; this.capacity = capacity; + this.total = total; this.hider = hider; reseed(); show(); From bd0f47c3253ec01507c0d09a898465c025a3540a Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 7 Jan 2021 15:18:44 -0500 Subject: [PATCH 025/426] Faster weapon copy --- core/src/mindustry/type/Weapon.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index f98150c85d..af5f63050b 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -9,9 +9,8 @@ import mindustry.entities.*; import mindustry.entities.bullet.*; import mindustry.gen.*; import mindustry.graphics.*; -import mindustry.io.*; -public class Weapon{ +public class Weapon implements Cloneable{ /** displayed weapon region */ public String name = ""; /** bullet shot */ @@ -98,9 +97,11 @@ public class Weapon{ } public Weapon copy(){ - Weapon out = new Weapon(); - JsonIO.json().copyFields(this, out); - return out; + try{ + return (Weapon)clone(); + }catch(CloneNotSupportedException suck){ + throw new RuntimeException("very good language design", suck); + } } public void load(){ From ff84d788a699fbe72fe317ee36b0712b2962c7fa Mon Sep 17 00:00:00 2001 From: xzarfs <59253058+xzarfs@users.noreply.github.com> Date: Fri, 8 Jan 2021 00:11:06 +0200 Subject: [PATCH 026/426] Changes to finnish translation (#4144) Made existing translations more user friendly and added new translations. There are still big areas the translation is lacking, e.g. the tutorial. --- core/assets/bundles/bundle_fi.properties | 214 +++++++++++------------ 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/core/assets/bundles/bundle_fi.properties b/core/assets/bundles/bundle_fi.properties index 9e516c89c9..d2a998db77 100644 --- a/core/assets/bundles/bundle_fi.properties +++ b/core/assets/bundles/bundle_fi.properties @@ -1,9 +1,9 @@ -credits.text = Pelin tehnyt [royal]Anuken[] - [sky]anukendev@gmail.com[] +credits.text = Pelin on luonut [royal]Anuken[] - [sky]anukendev@gmail.com[] credits = Tekijät contributors = Kääntäjät ja avustajat discord = Liity Mindustryn Discordiin! link.discord.description = Mindustryn virallinen Discord-keskusteluhuone -link.reddit.description = Mindustryn alireddit +link.reddit.description = Mindustryn reddit sivu link.github.description = Pelin lähdekoodi link.changelog.description = Lista päivityksien muutoksista link.dev-builds.description = Epävakaat kehitysversiot @@ -15,7 +15,7 @@ link.wiki.description = Virallinen Mindustry wiki link.suggestions.description = Ehdota uusia ominaisuuksia linkfail = Linkin avaaminen epäonnistui!\nOsoite on kopioitu leikepöydällesi. screenshot = Kuvankaappaus tallennettu sijaintiin {0} -screenshot.invalid = Kartta liian laaja, kuvankaappaukselle ei mahdollisesti ole tarpeeksi tilaa. +screenshot.invalid = Kartta liian laaja, levytila voi olla liian vähissä kuvankaappausta varten. gameover = Peli ohi gameover.pvp = [accent] {0}[] joukkue voittaa! highscore = [accent]Uusi ennätys! @@ -46,7 +46,7 @@ schematic.exists = Kaavio tällä nimellä on jo olemassa. schematic.import = Tuo kaavio... schematic.exportfile = Vie tiedosto schematic.importfile = Tuo tiedosto -schematic.browseworkshop = Selaa Workshoppia +schematic.browseworkshop = Selaa Steam Workshoppia schematic.copy = Kopioi leikepöydälle schematic.copy.import = Tuo leikepöydältä schematic.shareworkshop = Jaa Workshoppiin @@ -64,15 +64,15 @@ stat.destroyed = Rakennuksia tuhottu:[accent] {0} stat.deconstructed = Rakennuksia purettu:[accent] {0} stat.delivered = Resursseja laukaistu: stat.playtime = Pelattu aika:[accent] {0} -stat.rank = Lopullinen arvosana: [accent]{0} +stat.rank = Arvosana: [accent]{0} -globalitems = [accent]Global Items -map.delete = Oletko varma että haluat poistaa kartan "[accent]{0}[]"? +globalitems = [accent]Yhteiset tavarat +map.delete = Oletko varma että haluat poistaa kartan: "[accent]{0}[]"? level.highscore = Ennätys: [accent]{0} level.select = Tason valinta level.mode = Pelimuoto: coreattack = < Ytimeen hyökätään! > -nearpoint = [[ [scarlet]POISTU PUDOTUSPISTEELTÄ VÄLITTÖMÄSTI[]\nvälitön tuhoutuminen +nearpoint = [[ [scarlet]POISTU VIHOLLISEN PUDOTUSPISTEELTÄ VÄLITTÖMÄSTI[]\nvälitön tuhoutuminen database = Ytimen tietokanta savegame = Tallenna peli loadgame = Lataa peli @@ -92,11 +92,11 @@ continue = Jatka maps.none = [lightgray]Karttoja ei löytynyt! invalid = Virheellinen pickcolor = Valitse väri -preparingconfig = Preparing Config -preparingcontent = Preparing Content -uploadingcontent = Uploading Content -uploadingpreviewfile = Uploading Preview File -committingchanges = Comitting Changes +preparingconfig = Valmistellaan asetuksia +preparingcontent = Valmistellaan sisältöä +uploadingcontent = Julkaistaan sisältöä +uploadingpreviewfile = Julkaistaan esikatseltavaa tiedostoa +committingchanges = Varmistetaan muutokset done = Valmis feature.unsupported = Laitteesi ei tue tätä toimintoa. @@ -139,16 +139,16 @@ mod.scripts.disable = Laitteesi ei tue modeja skripteillä. Sinun on sammutettav about.button = Tietoa name = Nimi: noname = Valitse ensin[accent] pelaajanimi[]. -planetmap = Planet Map -launchcore = Launch Core +planetmap = Avaruuskartta +launchcore = Laukaise tukikohta filename = Tiedostonimi: unlocked = Uutta sisältöä avattu! completed = [accent]Suoritettu -techtree = Tekniikkapuu +techtree = Edistyspuu research.list = [lightgray]Tutki: research = Tutki researched = [lightgray]{0} tutkittu. -research.progress = {0}% complete +research.progress = {0}% valmis players = {0} pelaajaa paikalla players.single = {0} pelaaja paikalla players.search = etsiä @@ -180,7 +180,7 @@ host = Isäntä hosting = [accent]Avataan palvelinta... hosts.refresh = Päivitä hosts.discovering = Etsitään LAN pelejä -hosts.discovering.any = Etsitään Pelejä +hosts.discovering.any = Etsitään pelejä server.refreshing = Päivitetään palvelimen tietoja hosts.none = [lightgray]Paikallisia pelejä ei löytynyt! host.invalid = [scarlet]Isäntään ei voitu yhdistää. @@ -192,8 +192,8 @@ servers.global = Yhteisön palvelimet trace = Seuraa pelaajaa trace.playername = Pelaajanimi: [accent]{0} trace.ip = IP-osoite: [accent]{0} -trace.id = Uniikki tunniste: [accent]{0} -trace.mobile = Mobile Client: [accent]{0} +trace.id = Pelaajakohtainen tunniste: [accent]{0} +trace.mobile = Mobiililaite: [accent]{0} trace.modclient = Custom Client: [accent]{0} invalidid = Invalid client ID! Submit a bug report. server.bans = Porttikiellot @@ -225,7 +225,7 @@ connecting = [accent]Yhdistetään... connecting.data = [accent]Ladataan maailman tietoja... server.port = Portti: server.addressinuse = Osoite on jo käytössä! -server.invalidport = Invalid port number! +server.invalidport = Tällä portilla ei löytynyt peliä! server.error = [crimson]Error hosting server: [accent]{0} save.new = Uusi tallennus save.overwrite = Haluatko varmasti korvata \ntämän tallennuspaikan?? @@ -260,39 +260,39 @@ confirm = Vahvista delete = Poista view.workshop = View In Workshop workshop.listing = Edit Workshop Listing -ok = OK +ok = Juu open = Avaa customize = Muokkaa sääntöjä cancel = Peruuta openlink = Avaa linkki copylink = Kopioi linkki back = Takaisin -data.export = Vie data -data.import = Tuo data +data.export = Vie dataa +data.import = Tuo dataa data.openfolder = Avaa datakansio -data.exported = Data viety. +data.exported = Dataa on viety. data.invalid = This isn't valid game data. data.import.confirm = Importing external data will overwrite[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately. quit.confirm = Oletko varma että haluat poistua? -quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[] +quit.confirm.tutorial = Oletko varma että tiedät mitä teet?\nVoit tehdä tutoriaalin milloin vain[accent] Asetukset->Peli->Tee Tutoriaali Uudelleen[] loading = [accent]Ladataan... reloading = [accent]Ladataan Modeja... saving = [accent]Tallennetaan... -respawn = [accent][[{0}][] to respawn in core -cancelbuilding = [accent][[{0}][] to clear plan -selectschematic = [accent][[{0}][] to select+copy -pausebuilding = [accent][[{0}][] to pause building -resumebuilding = [scarlet][[{0}][] to resume building +respawn = [accent][[{0}][] uudelleensyntymiseen ytimessä +cancelbuilding = [accent][[{0}][] tyhjentääksesi suunnitelman +selectschematic = [accent][[{0}][] jotta voisit kopioida ja liittää +pausebuilding = [accent][[{0}][] pysäyttääksesi rakentamisen +resumebuilding = [scarlet][[{0}][] jatkaaksesi rakentamista wave = [accent]Taso {0} wave.cap = [accent]Wave {0}/{1} wave.waiting = [lightgray]Seuraava taso {0} -wave.waveInProgress = [lightgray]Wave in progress +wave.waveInProgress = [lightgray]Taso käynnissä waiting = [lightgray]Odotetaan... waiting.players = Odotetaan pelaajia... wave.enemies = [lightgray]{0} vihollista jäljellä wave.enemy = [lightgray]{0} vihollinen jäljellä -wave.guardianwarn = Guardian approaching in [accent]{0}[] waves. -wave.guardianwarn.one = Guardian approaching in [accent]{0}[] wave. +wave.guardianwarn = Suojelija tulossa [accent]{0}[] tason päästä. +wave.guardianwarn.one = Suojelija tulee rökittämään sinut [accent]{0}[] tasolla. loadimage = Lataa kuva saveimage = Tallenna kuva unknown = Tuntematon @@ -306,10 +306,10 @@ map.nospawn.attack = This map does not have any enemy cores for player to attack map.invalid = Virhe ladatessa karttaa: korruptoitunut tai väärä karttatiedosto. workshop.update = Update Item workshop.error = Error fetching workshop details: {0} -map.publish.confirm = Are you sure you want to publish this map?\n\n[lightgray]Make sure you agree to the Workshop EULA first, or your maps will not show up! -workshop.menu = Select what you would like to do with this item. +map.publish.confirm = Oletko varma että haluat julkaista tämän kartan?\n\n[lightgray]Hyväksy Workshopin EULA ehdot, muuten karttasi ei tule näkyviin! +workshop.menu = Mitä haluat tehdä tälle asialle? workshop.info = Kohteen Tiedot -changelog = Muutosloki (valinnainen): +changelog = Loki (valinnainen): eula = Steam EULA missing = This item has been deleted or moved.\n[lightgray]The workshop listing has now been automatically un-linked. publishing = [accent]Publishing... @@ -402,9 +402,9 @@ editor.exists = Kartta tällä nimellä on jo olemassa. editor.selectmap = Valitse kartta ladattavaksi: toolmode.replace = Korvaa -toolmode.replace.description = Draws only on solid blocks. +toolmode.replace.description = Piirtää vain kiinteille objekteille. toolmode.replaceall = Korvaa kaikki -toolmode.replaceall.description = Replace all blocks in map. +toolmode.replaceall.description = Korvaa kaikki palikat kartassa. toolmode.orthogonal = Orthogonal toolmode.orthogonal.description = Draws only orthogonal lines. toolmode.square = Square @@ -423,15 +423,15 @@ filter.enemyspawn = Enemy Spawn Select filter.spawnpath = Path To Spawn filter.corespawn = Valitse Ydin filter.median = Mediaani -filter.oremedian = Malmin mediaani +filter.oremedian = Malmin keskiarvo filter.blend = Sekoitus -filter.defaultores = Oletuksena malmit +filter.defaultores = Oletus malmit filter.ore = Malmi filter.rivernoise = Jokien melu filter.mirror = Peili filter.clear = Selkeä -filter.option.ignore = Ohittaa -filter.scatter = Scatter +filter.option.ignore = Ohitta +filter.scatter = Hajauta filter.terrain = Maasto filter.option.scale = Mittakaava filter.option.chance = Mahdollisuus @@ -448,10 +448,10 @@ filter.option.flooronto = Target Floor filter.option.target = Target filter.option.wall = Seinä filter.option.ore = Malmi -filter.option.floor2 = Secondary Floor +filter.option.floor2 = Toinen lattia filter.option.threshold2 = Secondary Threshold -filter.option.radius = Radius -filter.option.percentile = Percentile +filter.option.radius = Säde +filter.option.percentile = Prosentti width = Leveys: height = Korkeus: @@ -483,7 +483,7 @@ research.multiplayer = Only the host can research items. uncover = Paljasta configure = Configure Loadout loadout = Loadout -resources = Resources +resources = Resurssit bannedblocks = Kielletyt Palikat addall = Lisää kaikki launch.destination = Destination: {0} @@ -508,37 +508,37 @@ error.io = Network I/O error. error.any = Unknown network error. error.bloom = Failed to initialize bloom.\nYour device may not support it. -weather.rain.name = Rain -weather.snow.name = Snow -weather.sandstorm.name = Sandstorm -weather.sporestorm.name = Sporestorm -weather.fog.name = Fog +weather.rain.name = Sade +weather.snow.name = Lumi +weather.sandstorm.name = Hiekkamyrsky +weather.sporestorm.name = Sienimyräkkä +weather.fog.name = Sumu sectors.unexplored = [lightgray]Unexplored -sectors.resources = Resources: -sectors.production = Production: -sectors.stored = Stored: -sectors.resume = Resume -sectors.launch = Launch -sectors.select = Select -sectors.nonelaunch = [lightgray]none (sun) -sectors.rename = Rename Sector -sector.missingresources = [scarlet]Insufficient Core Resources +sectors.resources = Resurssit: +sectors.production = Produktio: +sectors.stored = Säilötty: +sectors.resume = Jatka +sectors.launch = Laukaise +sectors.select = Valitse +sectors.nonelaunch = [lightgray]ei mitään (sun) +sectors.rename = Nimeä sektori +sector.missingresources = [scarlet]Sinulla ei ole tarpeeksi resursseja. planet.serpulo.name = Serpulo -planet.sun.name = Sun +planet.sun.name = Aurinko -sector.groundZero.name = Ground Zero -sector.craters.name = The Craters -sector.frozenForest.name = Frozen Forest -sector.ruinousShores.name = Ruinous Shores -sector.stainedMountains.name = Stained Mountains -sector.desolateRift.name = Desolate Rift -sector.nuclearComplex.name = Nuclear Production Complex -sector.overgrowth.name = Overgrowth -sector.tarFields.name = Tar Fields -sector.saltFlats.name = Salt Flats -sector.fungalPass.name = Fungal Pass +sector.groundZero.name = Tapahtumahorisontti +sector.craters.name = Kraatterit +sector.frozenForest.name = Jäätyneet Metsät +sector.ruinousShores.name = Taistelujen Ranta +sector.stainedMountains.name = Kalliovuoret +sector.desolateRift.name = Musta Kanjoni +sector.nuclearComplex.name = Hylätty Ydinvoimalaitos +sector.overgrowth.name = Jätti Viidakko +sector.tarFields.name = Tervakentät +sector.saltFlats.name = Suola Autio +sector.fungalPass.name = Sienirihmasto sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. @@ -633,15 +633,15 @@ stat.lightningdamage = Lightning Damage stat.flammability = Flammability stat.radioactivity = Radioactivity stat.heatcapacity = HeatCapacity -stat.viscosity = Viscosity -stat.temperature = Temperature -stat.speed = Speed +stat.viscosity = Tahmeus +stat.temperature = Lämpötila +stat.speed = Nopeus stat.buildspeed = Build Speed stat.minespeed = Mine Speed stat.minetier = Mine Tier stat.payloadcapacity = Payload Capacity stat.commandlimit = Command Limit -stat.abilities = Abilities +stat.abilities = Erikoisvoimat ability.forcefield = Force Field ability.repairfield = Repair Field @@ -684,11 +684,11 @@ bullet.pierce = [stat]{0}[lightgray]x pierce bullet.infinitepierce = [stat]pierce bullet.freezing = [stat]jäädyttävä bullet.tarred = [stat]tervattu -bullet.multiplier = [stat]{0}[lightgray]x ammusten kerroin +bullet.multiplier = [stat]{0}[lightgray]x ammusmäärän kerroin bullet.reload = [stat]{0}[lightgray]x ampumisnopeus unit.blocks = palikat -unit.blockssquared = blocks² +unit.blockssquared = palikat² unit.powersecond = energiayksikköä/sekunti unit.liquidsecond = nesteyksikköä/sekunti unit.itemssecond = esinettä/sekunti @@ -696,12 +696,12 @@ unit.liquidunits = nesteyksikköä unit.powerunits = energiayksikköä unit.degrees = astetta unit.seconds = sekunttia -unit.minutes = mins +unit.minutes = minuuttia unit.persecond = /s unit.perminute = /min unit.timesspeed = x nopeus unit.percent = % -unit.shieldhealth = shield health +unit.shieldhealth = suojan elinpisteet unit.items = esinettä unit.thousands = t unit.millions = mil @@ -733,24 +733,24 @@ setting.fpscap.none = Ei Mitään setting.fpscap.text = {0} FPS setting.uiscale.name = UI Koko[lightgray] (vaatii uudelleenkäynnistyksen)[] setting.swapdiagonal.name = Aina vino korvaus -setting.difficulty.training = Treeni -setting.difficulty.easy = Helppo -setting.difficulty.normal = Keskivaikea -setting.difficulty.hard = Haastava -setting.difficulty.insane = Järjetön +setting.difficulty.training = Treenaus +setting.difficulty.easy = Huoleton +setting.difficulty.normal = Haasteeton +setting.difficulty.hard = Taidonnäyte +setting.difficulty.insane = Hullun Vaikea setting.difficulty.name = Vaikeustaso: setting.screenshake.name = Näytön keikkuminen setting.effects.name = Naytön Efektit setting.destroyedblocks.name = Näytä tuhoutuneet palikat -setting.blockstatus.name = Display Block Status +setting.blockstatus.name = Näytä Palikan Toimintakunto setting.conveyorpathfinding.name = Conveyor Placement Pathfinding setting.sensitivity.name = Ohjauksen herkkyys setting.saveinterval.name = Tallennuksen Aikaväli -setting.seconds = {0} Sekunttia +setting.seconds = {0} Sekuntia setting.blockselecttimeout.name = Block Select Timeout -setting.milliseconds = {0} millisekunttia -setting.fullscreen.name = Fullscreen -setting.borderlesswindow.name = Borderless Window[lightgray] (vaatii uudelleenkäynnistyksen) +setting.milliseconds = {0} millisekuntia +setting.fullscreen.name = Täysnäyttö +setting.borderlesswindow.name = Reunaton Ikkuna[lightgray] (vaatii uudelleenkäynnistyksen) setting.fps.name = Näytä FPS setting.smoothcamera.name = Smooth Camera setting.vsync.name = VSync @@ -776,8 +776,8 @@ public.confirm = Do you want to make your game public?\n[accent]Anyone will be a public.beta = Note that beta versions of the game cannot make public lobbies. uiscale.reset = UI scale has been changed.\nPress "OK" to confirm this scale.\n[scarlet]Reverting and exiting in[accent] {0}[] seconds... uiscale.cancel = Peruuta ja poistu -setting.bloom.name = Bloom -keybind.title = Rebind Keys +setting.bloom.name = Hehkeys +keybind.title = Kontrollit keybinds.mobile = [scarlet]Most keybinds here are not functional on mobile. Only basic movement is supported. category.general.name = General category.view.name = View @@ -786,10 +786,10 @@ category.blocks.name = Block Select command.attack = Hyökkäys command.rally = Kokoontuminen command.retreat = Perääntyminen -command.idle = Idle +command.idle = AFK placement.blockselectkeys = \n[lightgray]Key: [{0}, -keybind.respawn.name = Respawn -keybind.control.name = Control Unit +keybind.respawn.name = Synny Uudelleen +keybind.control.name = Käytä Yksikköä keybind.clear_building.name = Clear Building keybind.press = Press a key... keybind.press.axis = Press an axis or key... @@ -907,19 +907,19 @@ item.graphite.name = Grafiitti item.titanium.name = Titaani item.thorium.name = Torium item.silicon.name = Pii -item.plastanium.name = Plastaniumi -item.phase-fabric.name = Kiihdekuitu -item.surge-alloy.name = Taiteseos +item.plastanium.name = Plastiikkaseos +item.phase-fabric.name = Kiihtokuitu +item.surge-alloy.name = Venttikovete item.spore-pod.name = Itiöpalko item.sand.name = Hiekka -item.blast-compound.name = Räjähdeyhdiste -item.pyratite.name = Pyratiitti -item.metaglass.name = Metallilasi +item.blast-compound.name = Erikoisruuti +item.pyratite.name = Rikkikiisu +item.metaglass.name = Teräslasi item.scrap.name = Romu liquid.water.name = Vesi liquid.slag.name = Kuona liquid.oil.name = Öljy -liquid.cryofluid.name = Kryoneste +liquid.cryofluid.name = Kryölitku unit.dagger.name = Tikari unit.mace.name = Mace @@ -991,9 +991,9 @@ block.spawn.name = Vihollisten syntymispiste block.core-shard.name = Ydin: Siru block.core-foundation.name = Ydin: Pohjaus block.core-nucleus.name = Ydin: Tuma -block.deepwater.name = Syvä vesi -block.water.name = Vesi -block.tainted-water.name = Pilaantunut vesi +block.deepwater.name = Syvää vettä +block.water.name = Vettä +block.tainted-water.name = Saastevettä block.darksand-tainted-water.name = Dark Sand Tainted Water block.tar.name = Terva block.stone.name = Kivi @@ -1057,7 +1057,7 @@ block.titanium-conveyor.name = Titanium Conveyor block.plastanium-conveyor.name = Plastanium Conveyor block.armored-conveyor.name = Armored Conveyor block.armored-conveyor.description = Moves items at the same speed as titanium conveyors, but possesses more armor. Does not accept inputs from the sides from anything but other conveyor belts. -block.junction.name = Junction +block.junction.name = Junktio block.router.name = Reititin block.distributor.name = Distributor block.sorter.name = Lajittelija From 0435140bb595d4a89b7c2b8ef0f4e103ae2a2a94 Mon Sep 17 00:00:00 2001 From: alex <67626131+alexpvpmindustry@users.noreply.github.com> Date: Fri, 8 Jan 2021 22:53:57 +0800 Subject: [PATCH 027/426] Update servers_v6.json (#4287) A new game mode to share with the public! Turbo PVP --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index 115b18db01..b5446d6fd3 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -49,7 +49,7 @@ }, { "name": "ALEX", - "address": ["alexmindustryhub.ddns.net:6568", "alexmindustry.ddns.net:6568", "alexmindustry.ddns.net:6569", "alexmindustryattac.ddns.net:25800"] + "address": ["alexmindustryhub.ddns.net:6568", "alexmindustry.ddns.net:6568", "alexmindustry.ddns.net:6569", "alexmindustryattac.ddns.net:25800","alexmindustryturbo.ddns.net:25854"] }, { "name": "Minty [subzero]", From 01d972f015b83ca95e6533f5c014bdf1621f9b9b Mon Sep 17 00:00:00 2001 From: _owler_#0954 <63801085+owler0954@users.noreply.github.com> Date: Fri, 8 Jan 2021 19:21:25 +0300 Subject: [PATCH 028/426] Update servers_v6.json (#4194) * Update servers_v6.json * Update servers_v6.json Co-authored-by: Antsiferov Andrew * Update servers_v6.json Co-authored-by: Antsiferov Andrew --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index b5446d6fd3..6b1e4bb38c 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -54,5 +54,9 @@ { "name": "Minty [subzero]", "address": ["minty-server.ddns.net"] + }, + { + "name": "Minigames", + "address": ["shizashizashiza.ml"] } ] From 2f83ba7f5c658d44193c30547b9788687a89fad2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 8 Jan 2021 12:22:32 -0500 Subject: [PATCH 029/426] Logic battery control + Slight swarmer range buff --- core/src/mindustry/content/Blocks.java | 2 +- .../mindustry/entities/bullet/MissileBulletType.java | 2 +- core/src/mindustry/world/blocks/defense/Wall.java | 1 + .../mindustry/world/blocks/logic/LogicDisplay.java | 1 + .../src/mindustry/world/blocks/logic/MemoryBlock.java | 1 + .../mindustry/world/blocks/logic/MessageBlock.java | 1 + core/src/mindustry/world/blocks/power/PowerGraph.java | 11 +++++------ core/src/mindustry/world/blocks/power/PowerNode.java | 1 + .../src/mindustry/world/blocks/storage/CoreBlock.java | 1 + gradle.properties | 2 +- 10 files changed, 14 insertions(+), 9 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index d071e7dab9..1665d28b8f 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1595,7 +1595,7 @@ public class Blocks implements ContentList{ shots = 4; burstSpacing = 5; inaccuracy = 10f; - range = 190f; + range = 200f; xRand = 6f; size = 2; health = 300 * size * size; diff --git a/core/src/mindustry/entities/bullet/MissileBulletType.java b/core/src/mindustry/entities/bullet/MissileBulletType.java index 274a806f5e..7d8cf7b8a3 100644 --- a/core/src/mindustry/entities/bullet/MissileBulletType.java +++ b/core/src/mindustry/entities/bullet/MissileBulletType.java @@ -15,7 +15,7 @@ public class MissileBulletType extends BasicBulletType{ height = 8f; hitSound = Sounds.explosion; trailChance = 0.2f; - lifetime = 49f; + lifetime = 52f; } public MissileBulletType(float speed, float damage){ diff --git a/core/src/mindustry/world/blocks/defense/Wall.java b/core/src/mindustry/world/blocks/defense/Wall.java index 6f59fb8e34..cde36ba964 100644 --- a/core/src/mindustry/world/blocks/defense/Wall.java +++ b/core/src/mindustry/world/blocks/defense/Wall.java @@ -37,6 +37,7 @@ public class Wall extends Block{ group = BlockGroup.walls; buildCostMultiplier = 6f; canOverdrive = false; + drawDisabled = false; } @Override diff --git a/core/src/mindustry/world/blocks/logic/LogicDisplay.java b/core/src/mindustry/world/blocks/logic/LogicDisplay.java index 22e2b0fb6e..419be008a9 100644 --- a/core/src/mindustry/world/blocks/logic/LogicDisplay.java +++ b/core/src/mindustry/world/blocks/logic/LogicDisplay.java @@ -35,6 +35,7 @@ public class LogicDisplay extends Block{ update = true; solid = true; group = BlockGroup.logic; + drawDisabled = false; } @Override diff --git a/core/src/mindustry/world/blocks/logic/MemoryBlock.java b/core/src/mindustry/world/blocks/logic/MemoryBlock.java index 5b91425a27..cff63b98a3 100644 --- a/core/src/mindustry/world/blocks/logic/MemoryBlock.java +++ b/core/src/mindustry/world/blocks/logic/MemoryBlock.java @@ -13,6 +13,7 @@ public class MemoryBlock extends Block{ destructible = true; solid = true; group = BlockGroup.logic; + drawDisabled = false; } @Override diff --git a/core/src/mindustry/world/blocks/logic/MessageBlock.java b/core/src/mindustry/world/blocks/logic/MessageBlock.java index f47b613d72..0e34825b49 100644 --- a/core/src/mindustry/world/blocks/logic/MessageBlock.java +++ b/core/src/mindustry/world/blocks/logic/MessageBlock.java @@ -29,6 +29,7 @@ public class MessageBlock extends Block{ solid = true; destructible = true; group = BlockGroup.logic; + drawDisabled = false; config(String.class, (MessageBuild tile, String text) -> { if(text.length() > maxTextLength){ diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index 26c34268d9..8c79b63804 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -102,7 +102,7 @@ public class PowerGraph{ float totalAccumulator = 0f; for(Building battery : batteries){ Consumers consumes = battery.block.consumes; - if(consumes.hasPower()){ + if(battery.enabled && consumes.hasPower()){ totalAccumulator += battery.power.status * consumes.getPower().capacity; } } @@ -112,7 +112,7 @@ public class PowerGraph{ public float getBatteryCapacity(){ float totalCapacity = 0f; for(Building battery : batteries){ - if(battery.block.consumes.hasPower()){ + if(battery.enabled && battery.block.consumes.hasPower()){ ConsumePower power = battery.block.consumes.getPower(); totalCapacity += (1f - battery.power.status) * power.capacity; } @@ -123,7 +123,7 @@ public class PowerGraph{ public float getTotalBatteryCapacity(){ float totalCapacity = 0f; for(Building battery : batteries){ - if(battery.block.consumes.hasPower()){ + if(battery.enabled && battery.block.consumes.hasPower()){ totalCapacity += battery.block.consumes.getPower().capacity; } } @@ -138,7 +138,7 @@ public class PowerGraph{ float consumedPowerPercentage = Math.min(1.0f, needed / stored); for(Building battery : batteries){ Consumers consumes = battery.block.consumes; - if(consumes.hasPower()){ + if(battery.enabled && consumes.hasPower()){ battery.power.status *= (1f-consumedPowerPercentage); } } @@ -153,7 +153,7 @@ public class PowerGraph{ for(Building battery : batteries){ Consumers consumes = battery.block.consumes; - if(consumes.hasPower()){ + if(battery.enabled && consumes.hasPower()){ ConsumePower consumePower = consumes.getPower(); if(consumePower.capacity > 0f){ battery.power.status += (1f- battery.power.status) * chargedPercent; @@ -216,7 +216,6 @@ public class PowerGraph{ lastScaledPowerIn = powerProduced / Time.delta; lastScaledPowerOut = powerNeeded / Time.delta; lastCapacity = getTotalBatteryCapacity(); - lastPowerStored = getBatteryStored(); powerBalance.add((lastPowerProduced - lastPowerNeeded) / Time.delta); diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index f5801d98a7..1e77e2b41d 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -43,6 +43,7 @@ public class PowerNode extends PowerBlock{ outputsPower = false; canOverdrive = false; swapDiagonalPlacement = true; + drawDisabled = false; config(Integer.class, (entity, value) -> { PowerModule power = entity.power; diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 13e84e1dd8..da2ac30b8f 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -53,6 +53,7 @@ public class CoreBlock extends StorageBlock{ loopSound = Sounds.respawning; loopSoundVolume = 1f; group = BlockGroup.none; + drawDisabled = false; } @Remote(called = Loc.server) diff --git a/gradle.properties b/gradle.properties index 203de61508..ad549888ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=71b1c84015119f57bf4d215f594ead1ffc9e8744 +archash=b2f3d212c1a88a62f140f5cb04f4c86e61332d1c From a0c7b33ff12a10680f412196d7d2e290d73f82f1 Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Sat, 9 Jan 2021 18:06:12 +0300 Subject: [PATCH 030/426] Add ModMeta#toString (#4292) --- core/src/mindustry/mod/Mods.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 4c6605fbbf..02bea3e464 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -853,6 +853,18 @@ public class Mods implements Loadable{ if(author != null) author = Strings.stripColors(author); if(description != null) description = Strings.stripColors(description); } + + @Override + public String toString() { + return "ModMeta{" + + "name='" + name + '\'' + + ", author='" + author + '\'' + + ", version='" + version + '\'' + + ", main='" + main + '\'' + + ", minGameVersion='" + minGameVersion + '\'' + + ", hidden=" + hidden + + '}'; + } } public enum ModState{ From 21fd20ea5bad59218547b85a47e28c2ff9027262 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 9 Jan 2021 10:31:44 -0500 Subject: [PATCH 031/426] Targetp support for allied targets --- core/src/mindustry/ai/types/LogicAI.java | 5 +++++ core/src/mindustry/entities/bullet/BulletType.java | 1 + core/src/mindustry/entities/bullet/ShrapnelBulletType.java | 2 ++ core/src/mindustry/entities/comp/PayloadComp.java | 2 +- core/src/mindustry/entities/units/AIController.java | 6 +++++- core/src/mindustry/type/UnitType.java | 4 ++-- core/src/mindustry/world/blocks/units/CommandCenter.java | 1 + gradle.properties | 2 +- 8 files changed, 18 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index a0eb6d1fa9..b20bc87db6 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -131,6 +131,11 @@ public class LogicAI extends AIController{ unit.approach(vec); } + @Override + protected boolean checkTarget(Teamc target, float x, float y, float range){ + return false; + } + //always retarget @Override protected boolean retarget(){ diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 73e0fb93ba..53aad2f052 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -334,6 +334,7 @@ public abstract class BulletType extends Content{ bullet.type = this; bullet.owner = owner; bullet.team = team; + bullet.time = 0f; bullet.vel.trns(angle, speed * velocityScl); if(backMove){ bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta); diff --git a/core/src/mindustry/entities/bullet/ShrapnelBulletType.java b/core/src/mindustry/entities/bullet/ShrapnelBulletType.java index 236ede8887..3d89e4d272 100644 --- a/core/src/mindustry/entities/bullet/ShrapnelBulletType.java +++ b/core/src/mindustry/entities/bullet/ShrapnelBulletType.java @@ -33,6 +33,8 @@ public class ShrapnelBulletType extends BulletType{ @Override public void init(Bullet b){ + super.init(b); + Damage.collideLaser(b, length, hitLarge); } diff --git a/core/src/mindustry/entities/comp/PayloadComp.java b/core/src/mindustry/entities/comp/PayloadComp.java index 8db8656d88..9afd26bb9a 100644 --- a/core/src/mindustry/entities/comp/PayloadComp.java +++ b/core/src/mindustry/entities/comp/PayloadComp.java @@ -158,7 +158,7 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{ pad = (width - (itemSize) * items) / items; } - for (Payload p : payloads){ + for(Payload p : payloads){ table.image(p.icon(Cicon.small)).size(itemSize).padRight(pad); } } diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 0eb12d7a6a..b42c5efdb7 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -123,7 +123,7 @@ public class AIController implements UnitController{ targets[i] = findTarget(mountX, mountY, weapon.bullet.range(), weapon.bullet.collidesAir, weapon.bullet.collidesGround); } - if(Units.invalidateTarget(targets[i], unit.team, mountX, mountY, weapon.bullet.range())){ + if(checkTarget(targets[i], mountX, mountY, weapon.bullet.range())){ targets[i] = null; } } @@ -149,6 +149,10 @@ public class AIController implements UnitController{ } } + protected boolean checkTarget(Teamc target, float x, float y, float range){ + return Units.invalidateTarget(target, unit.team, x, y, range); + } + protected boolean shouldShoot(){ return true; } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index e41050118f..19a06c3196 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -182,11 +182,11 @@ public class UnitType extends UnlockableContent{ var count = new float[]{-1}; bars.table().update(t -> { - if(count[0] != payload.payloadUsed()) { + if(count[0] != payload.payloadUsed()){ payload.contentInfo(t, 8 * 2, 270); count[0] = payload.payloadUsed(); } - }).growX().left(); + }).growX().left().height(0f).pad(0f); } }).growX(); diff --git a/core/src/mindustry/world/blocks/units/CommandCenter.java b/core/src/mindustry/world/blocks/units/CommandCenter.java index a564f4dc07..19a721832b 100644 --- a/core/src/mindustry/world/blocks/units/CommandCenter.java +++ b/core/src/mindustry/world/blocks/units/CommandCenter.java @@ -31,6 +31,7 @@ public class CommandCenter extends Block{ destructible = true; solid = true; configurable = true; + drawDisabled = false; config(UnitCommand.class, (CommandBuild build, UnitCommand command) -> { build.team.data().command = command; diff --git a/gradle.properties b/gradle.properties index ad549888ac..9b15d50c4d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=b2f3d212c1a88a62f140f5cb04f4c86e61332d1c +archash=c55aa1fe790c50db389225d9a2287b57f71260ff From 0a5a301573302dda466327717a0d664a4fe49f20 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 9 Jan 2021 22:13:41 -0500 Subject: [PATCH 032/426] Save building enabled state --- core/src/mindustry/ai/types/FormationAI.java | 2 +- .../src/mindustry/entities/comp/BuildingComp.java | 15 ++++++++++++--- .../mindustry/world/blocks/logic/LogicBlock.java | 14 -------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/core/src/mindustry/ai/types/FormationAI.java b/core/src/mindustry/ai/types/FormationAI.java index 8a4f351b4e..49ca55c68b 100644 --- a/core/src/mindustry/ai/types/FormationAI.java +++ b/core/src/mindustry/ai/types/FormationAI.java @@ -46,7 +46,7 @@ public class FormationAI extends AIController implements FormationMember{ unit.lookAt(unit.vel.angle()); } - Vec2 realtarget = vec.set(target).add(leader.vel.x, leader.vel.y); + Vec2 realtarget = vec.set(target).add(leader.vel); float speed = unit.realSpeed() * unit.floorSpeedMultiplier() * Time.delta; unit.approach(Mathf.arrive(unit.x, unit.y, realtarget.x, realtarget.y, unit.vel, speed, 0f, speed, 1f).scl(1f / Time.delta)); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 37a5775124..2067c328db 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -147,7 +147,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, write.f(health); write.b(rotation | 0b10000000); write.b(team.id); - write.b(0); //extra padding for later use + write.b(1); //version + write.b(enabled ? 1 : 0); if(items != null) items.write(write); if(power != null) power.write(write); if(liquids != null) liquids.write(write); @@ -162,7 +163,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, rotation = rot & 0b01111111; boolean legacy = true; if((rot & 0b10000000) != 0){ - read.b(); //padding + byte ver = read.b(); //version of entity save + if(ver == 1){ + byte on = read.b(); + this.enabled = on == 1; + if(!this.enabled){ + enabledControlTime = timeToUncontrol; + } + } legacy = false; } @@ -1376,7 +1384,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, timeScale = 1f; } - if(block.autoResetEnabled){ + if(!enabled && block.autoResetEnabled){ + noSleep(); enabledControlTime -= Time.delta; if(enabledControlTime <= 0){ diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index 8a74a1d575..e37492de30 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -529,7 +529,6 @@ public class LogicBlock extends Block{ read.b(bytes); readCompressed(bytes, false); }else{ - code = read.str(); links.clear(); short total = read.s(); @@ -568,17 +567,4 @@ public class LogicBlock extends Block{ }); } } - - public static class LogicConfig{ - public String code; - public IntSeq connections; - - public LogicConfig(String code, IntSeq connections){ - this.code = code; - this.connections = connections; - } - - public LogicConfig(){ - } - } } From 7372bf37c28561ef66898995f607aba4f2c14d6f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 10 Jan 2021 15:23:15 -0500 Subject: [PATCH 033/426] Fixed #4301 --- core/src/mindustry/entities/comp/UnitComp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index fd3f1810ff..64a717d75e 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -105,7 +105,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I @Override public float range(){ - return type.range; + return type.maxRange; } @Replace From 9c846bd2c9f3bda017fc1622f210e71dc665f297 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 10 Jan 2021 15:27:17 -0500 Subject: [PATCH 034/426] Invasion chance tweaks (#4297) --- core/src/mindustry/game/Universe.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index 6ebf66afad..c8c3702a17 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -217,8 +217,10 @@ public class Universe{ //queue random invasions if(!sector.isAttacked() && turn > invasionGracePeriod && sector.info.hasSpawns){ + int count = sector.near().count(Sector::hasEnemyBase); + //invasion chance depends on # of nearby bases - if(Mathf.chance(baseInvasionChance * Math.min(sector.near().count(Sector::hasEnemyBase), 1))){ + if(count > 0 && Mathf.chance(baseInvasionChance * (0.75f + (count - 1) * 0.3f))){ int waveMax = Math.max(sector.info.winWave, sector.isBeingPlayed() ? state.wave : sector.info.wave + sector.info.wavesPassed) + Mathf.random(2, 4) * 5; //assign invasion-related things From 8b9b11f77fa9197f6fbade466b8f64441373698d Mon Sep 17 00:00:00 2001 From: BlueWolf <61173114+BlueWolf3682@users.noreply.github.com> Date: Sun, 10 Jan 2021 13:33:31 -0700 Subject: [PATCH 035/426] 1mil source output (#4299) --- core/src/mindustry/content/Blocks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 1665d28b8f..ed8013c4d2 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1992,7 +1992,7 @@ public class Blocks implements ContentList{ powerSource = new PowerSource("power-source"){{ requirements(Category.power, BuildVisibility.sandboxOnly, with()); - powerProduction = 100000f / 60f; + powerProduction = 1000000f / 60f; alwaysUnlocked = true; }}; From 9b1c66ba1519096c991d3461c582f2f6776bb79c Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 10 Jan 2021 15:39:00 -0500 Subject: [PATCH 036/426] #4298 --- core/src/mindustry/entities/comp/PlayerComp.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 5e6c214cc6..aababe65e3 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -59,6 +59,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra return team.core(); } + /** @return largest/closest core, with largest cores getting priority */ + @Nullable + public CoreBuild bestCore(){ + return team.cores().min(Structs.comps(Structs.comparingInt(c -> -c.block.size), Structs.comparingFloat(c -> c.dst(x, y)))); + } + public TextureRegion icon(){ //display default icon for dead players if(dead()) return core() == null ? UnitTypes.alpha.icon(Cicon.full) : ((CoreBlock)core().block).unitType.icon(Cicon.full); @@ -112,7 +118,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra clearUnit(); } - CoreBuild core = closestCore(); + CoreBuild core; if(!dead()){ set(unit); @@ -124,7 +130,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra Tile tile = unit.tileOn(); unit.elevation = Mathf.approachDelta(unit.elevation, (tile != null && tile.solid()) || boosting ? 1f : 0f, 0.08f); } - }else if(core != null){ + }else if((core = bestCore()) != null){ //have a small delay before death to prevent the camera from jumping around too quickly //(this is not for balance, it just looks better this way) deathTimer += Time.delta; From 96c8e0f415f97e37ea1f1579e4eea570f8ff7f1b Mon Sep 17 00:00:00 2001 From: Milan Date: Sun, 10 Jan 2021 21:39:50 +0100 Subject: [PATCH 037/426] add resolveDependencies gradle task (#4302) --- build.gradle | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.gradle b/build.gradle index 98744b1358..4653b46904 100644 --- a/build.gradle +++ b/build.gradle @@ -410,3 +410,13 @@ task deployAll{ dependsOn "server:deploy" dependsOn "android:deploy" } + +task resolveDependencies{ + doLast{ + rootProject.allprojects{project -> + Set configurations = project.buildscript.configurations + project.configurations + configurations.findAll{c -> c.canBeResolved} + .forEach{c -> c.resolve()} + } + } +} From 2927348a6caab5cfa955197321150fff73ab84e4 Mon Sep 17 00:00:00 2001 From: Slava0135 <40753025+Slava0135@users.noreply.github.com> Date: Sun, 10 Jan 2021 23:46:29 +0300 Subject: [PATCH 038/426] power info fixes (#4303) * power info fixes * a better solution * one little detail --- .../mindustry/world/blocks/power/PowerDiode.java | 4 ++-- .../mindustry/world/blocks/power/PowerGraph.java | 14 +++++++++++++- .../mindustry/world/blocks/power/PowerNode.java | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/PowerDiode.java b/core/src/mindustry/world/blocks/power/PowerDiode.java index 75f589eabd..03892d1c54 100644 --- a/core/src/mindustry/world/blocks/power/PowerDiode.java +++ b/core/src/mindustry/world/blocks/power/PowerDiode.java @@ -71,8 +71,8 @@ public class PowerDiode extends Block{ // prevent sending more than the front can handle amount = Mathf.clamp(amount, 0, frontGraph.getTotalBatteryCapacity() * (1 - frontStored)); - backGraph.useBatteries(amount); - frontGraph.chargeBatteries(amount); + backGraph.transferPower(-amount); + frontGraph.transferPower(amount); } } } diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index 8c79b63804..03aa029f19 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -21,6 +21,8 @@ public class PowerGraph{ private final WindowedMean powerBalance = new WindowedMean(60); private float lastPowerProduced, lastPowerNeeded, lastPowerStored; private float lastScaledPowerIn, lastScaledPowerOut, lastCapacity; + //diodes workaround for correct energy production info + private float energyDelta = 0f; private long lastFrameUpdated = -1; private final int graphID; @@ -62,6 +64,15 @@ public class PowerGraph{ return lastPowerStored; } + public void transferPower(float amount){ + if(amount > 0){ + chargeBatteries(amount); + }else{ + useBatteries(-amount); + } + energyDelta += amount; + } + public float getSatisfaction(){ if(Mathf.zero(lastPowerProduced)){ return 0f; @@ -218,7 +229,8 @@ public class PowerGraph{ lastCapacity = getTotalBatteryCapacity(); lastPowerStored = getBatteryStored(); - powerBalance.add((lastPowerProduced - lastPowerNeeded) / Time.delta); + powerBalance.add((lastPowerProduced - lastPowerNeeded + energyDelta) / Time.delta); + energyDelta = 0f; if(!(consumers.size == 0 && producers.size == 0 && batteries.size == 0)){ diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 1e77e2b41d..43c292e5b0 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -107,7 +107,7 @@ public class PowerNode extends PowerBlock{ super.setBars(); bars.add("power", entity -> new Bar(() -> Core.bundle.format("bar.powerbalance", - ((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + Strings.fixed(entity.power.graph.getPowerBalance() * 60, 1))), + ((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + UI.formatAmount((int)(entity.power.graph.getPowerBalance() * 60)))), () -> Pal.powerBar, () -> Mathf.clamp(entity.power.graph.getLastPowerProduced() / entity.power.graph.getLastPowerNeeded()))); From c0e955dc1fd2f6a02d55f8219dccb88b3a8b2236 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 10 Jan 2021 16:33:20 -0500 Subject: [PATCH 039/426] Updated to Gradle 6.8 --- build.gradle | 5 ++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 4653b46904..0829666d01 100644 --- a/build.gradle +++ b/build.gradle @@ -413,10 +413,9 @@ task deployAll{ task resolveDependencies{ doLast{ - rootProject.allprojects{project -> + rootProject.allprojects{ project -> Set configurations = project.buildscript.configurations + project.configurations - configurations.findAll{c -> c.canBeResolved} - .forEach{c -> c.resolve()} + configurations.findAll{c -> c.canBeResolved}.forEach{c -> c.resolve()} } } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6c9a224775..da9702f9e7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From f188563052a687f5c35465a6034c4d58eb980e30 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 10 Jan 2021 16:58:39 -0500 Subject: [PATCH 040/426] Sort mod browser entries by date --- core/src/mindustry/ui/dialogs/ModsDialog.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index ec704500bb..998b401558 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -23,6 +23,8 @@ import mindustry.mod.Mods.*; import mindustry.ui.*; import java.io.*; +import java.text.*; +import java.util.*; import static mindustry.Vars.*; @@ -74,12 +76,25 @@ public class ModsDialog extends BaseDialog{ if(status != HttpStatus.OK){ ui.showErrorMessage(Core.bundle.format("connectfail", status)); }else{ - modList = new Json().fromJson(Seq.class, ModListing.class, strResult); + try{ + modList = new Json().fromJson(Seq.class, ModListing.class, strResult); - //potentially sort mods by game version compatibility, or other criteria - //modList.sort(Structs.comparingBool(m -> !Version.isAtLeast(m.minGameVersion))); + var d = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + Func parser = text -> { + try{ + return d.parse(text); + }catch(Exception e){ + throw new RuntimeException(e); + } + }; + + modList.sortComparing(m -> parser.get(m.lastUpdated)).reverse(); + listener.get(modList); + }catch(Exception e){ + e.printStackTrace(); + ui.showException(e); + } - listener.get(modList); } }); }, error -> Core.app.post(() -> ui.showException(error))); From c716c167467cb373cb763a6fea1183956a286bae Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 11 Jan 2021 10:11:31 -0500 Subject: [PATCH 041/426] Fixed #4305 / Fixed #4309 --- core/src/mindustry/content/Fx.java | 2 +- .../mindustry/entities/comp/BuilderComp.java | 19 ++++++++++++++++--- .../defense/turrets/TractorBeamTurret.java | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index c862885e2f..7edc5d5cc3 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -896,7 +896,7 @@ public class Fx{ }); }), - dynamicExplosion = new Effect(30, e -> { + dynamicExplosion = new Effect(30, 100f, e -> { float intensity = e.rotation; e.scaled(5 + intensity * 2, i -> { diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index a5c55485ec..12f5428324 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -1,6 +1,7 @@ package mindustry.entities.comp; import arc.*; +import arc.func.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; @@ -136,10 +137,17 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ /** Draw all current build plans. Does not draw the beam effect, only the positions. */ void drawBuildPlans(){ + Boolf skip = plan -> plan.progress > 0.01f || (buildPlan() == plan && plan.initialized && (within(plan.x * tilesize, plan.y * tilesize, buildingRange) || state.isEditor())); - for(BuildPlan plan : plans){ - if(plan.progress > 0.01f || (buildPlan() == plan && plan.initialized && (within(plan.x * tilesize, plan.y * tilesize, buildingRange) || state.isEditor()))) continue; - drawPlan(plan, 1f); + for(int i = 0; i < 2; i++){ + for(BuildPlan plan : plans){ + if(skip.get(plan)) continue; + if(i == 0){ + drawPlan(plan, 1f); + }else{ + drawPlanTop(plan, 1f); + } + } } Draw.reset(); @@ -153,7 +161,11 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ request.block.drawPlan(request, control.input.allRequests(), Build.validPlace(request.block, team, request.x, request.y, request.rotation) || control.input.requestMatches(request), alpha); + } + } + void drawPlanTop(BuildPlan request, float alpha){ + if(!request.breaking){ Draw.reset(); Draw.mixcol(Color.white, 0.24f + Mathf.absin(Time.globalTime, 6f, 0.28f)); Draw.alpha(alpha); @@ -251,6 +263,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ if(core != null && active && !isLocal() && !(tile.block() instanceof ConstructBlock)){ Draw.z(Layer.plans - 1f); drawPlan(plan, 0.5f); + drawPlanTop(plan, 0.5f); Draw.z(Layer.flyingUnit); } diff --git a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java index 34e960ea2d..162cb1cc70 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java @@ -46,6 +46,7 @@ public class TractorBeamTurret extends BaseTurret{ //disabled due to version mismatch problems acceptCoolant = false; + expanded = true; } @Override From 994194452d5ab31217d5eb4b39e44f7034563a15 Mon Sep 17 00:00:00 2001 From: BlueWolf <61173114+BlueWolf3682@users.noreply.github.com> Date: Mon, 11 Jan 2021 08:13:28 -0700 Subject: [PATCH 042/426] fix a comment typo (#4307) --- core/src/mindustry/world/Block.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index b82a1ddb1a..76eec40dd1 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -80,9 +80,9 @@ public class Block extends UnlockableContent{ public boolean breakable; /** whether to add this block to brokenblocks */ public boolean rebuildable = true; - /** whether this water can only be placed on water */ + /** whether this block can only be placed on water */ public boolean requiresWater = false; - /** whether this water can be placed on any liquids, anywhere */ + /** whether this block can be placed on any liquids, anywhere */ public boolean placeableLiquid = false; /** whether this floor can be placed on. */ public boolean placeableOn = true; From 6417073a825e9bf2eb30f6fa2008b6448a0bb4bc Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 11 Jan 2021 10:14:23 -0500 Subject: [PATCH 043/426] Corrected parallax target check --- .../world/blocks/defense/turrets/TractorBeamTurret.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java index 162cb1cc70..42e33dc2e3 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java @@ -97,7 +97,7 @@ public class TractorBeamTurret extends BaseTurret{ any = false; //look at target - if(target != null && target.within(this, range) && target.team() != team && target.type.flying && efficiency() > 0.02f){ + if(target != null && target.within(this, range) && target.team() != team && target.checkTarget(targetAir, targetGround) && efficiency() > 0.02f){ if(!headless){ control.sound.loop(shootSound, this, shootSoundVolume); } From e83cfe6cabf0198c562395ae846896d1a8d71d10 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Mon, 11 Jan 2021 20:30:58 +0100 Subject: [PATCH 044/426] Display unit cap modifier for core blocks (#4163) * Display unit cap modifier for core blocks * Move maxUnits stat from crafting to general * Omit string formatting --- core/src/mindustry/world/Block.java | 2 ++ core/src/mindustry/world/meta/Stat.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 76eec40dd1..c7e9d73b33 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -375,6 +375,8 @@ public class Block extends UnlockableContent{ if(hasItems && configurable){ bars.add("items", entity -> new Bar(() -> Core.bundle.format("bar.items", entity.items.total()), () -> Pal.items, () -> (float)entity.items.total() / itemCapacity)); } + + if(flags.contains(BlockFlag.unitModifier)) stats.add(Stat.maxUnits, (unitCapModifier < 0 ? "-" : "+") + Math.abs(unitCapModifier)); } public boolean canReplace(Block other){ diff --git a/core/src/mindustry/world/meta/Stat.java b/core/src/mindustry/world/meta/Stat.java index 2f933bb46a..1f9d1d0022 100644 --- a/core/src/mindustry/world/meta/Stat.java +++ b/core/src/mindustry/world/meta/Stat.java @@ -30,6 +30,7 @@ public enum Stat{ lightningDamage, abilities, canBoost, + maxUnits, itemCapacity(StatCat.items), itemsMoved(StatCat.items), @@ -51,7 +52,6 @@ public enum Stat{ productionTime(StatCat.crafting), drillTier(StatCat.crafting), drillSpeed(StatCat.crafting), - maxUnits(StatCat.crafting), linkRange(StatCat.crafting), instructions(StatCat.crafting), From 0cbc4c0cc5f15529bf3220a3dc2941f17bed3f0a Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 11 Jan 2021 16:07:46 -0500 Subject: [PATCH 045/426] Fixed #4311 --- .../mindustry/ui/fragments/HudFragment.java | 59 ++++++++++--------- gradle.properties | 2 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index a8ae12eed2..a5f1269cbc 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -224,7 +224,7 @@ public class HudFragment extends Fragment{ int i = 0; for(Team team : Team.baseTeams){ ImageButton button = teams.button(Tex.whiteui, Styles.clearTogglePartiali, 40f, () -> Call.setPlayerTeamEditor(player, team)) - .size(50f).margin(6f).get(); + .size(50f).margin(6f).get(); button.getImageCell().grow(); button.getStyle().imageUpColor = team.color; button.update(() -> button.setChecked(player.team() == team)); @@ -342,39 +342,39 @@ public class HudFragment extends Fragment{ //TODO DEBUG: rate table if(false) - parent.fill(t -> { - t.name = "rates"; - t.bottom().left(); - t.table(Styles.black6, c -> { - Bits used = new Bits(content.items().size); + parent.fill(t -> { + t.name = "rates"; + t.bottom().left(); + t.table(Styles.black6, c -> { + Bits used = new Bits(content.items().size); - Runnable rebuild = () -> { - c.clearChildren(); + Runnable rebuild = () -> { + c.clearChildren(); - for(Item item : content.items()){ - if(state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1){ - c.image(item.icon(Cicon.small)); - c.label(() -> (int)state.rules.sector.info.getExport(item) + " /s").color(Color.lightGray); - c.row(); + for(Item item : content.items()){ + if(state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1){ + c.image(item.icon(Cicon.small)); + c.label(() -> (int)state.rules.sector.info.getExport(item) + " /s").color(Color.lightGray); + c.row(); + } } - } - }; + }; - c.update(() -> { - boolean wrong = false; - for(Item item : content.items()){ - boolean has = state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1; - if(used.get(item.id) != has){ - used.set(item.id, has); - wrong = true; + c.update(() -> { + boolean wrong = false; + for(Item item : content.items()){ + boolean has = state.rules.sector != null && state.rules.sector.info.getExport(item) >= 1; + if(used.get(item.id) != has){ + used.set(item.id, has); + wrong = true; + } } - } - if(wrong){ - rebuild.run(); - } - }); - }).visible(() -> state.isCampaign() && content.items().contains(i -> state.rules.sector != null && state.rules.sector.info.getExport(i) > 0)); - }); + if(wrong){ + rebuild.run(); + } + }); + }).visible(() -> state.isCampaign() && content.items().contains(i -> state.rules.sector != null && state.rules.sector.info.getExport(i) > 0)); + }); blockfrag.build(parent); } @@ -765,6 +765,7 @@ public class HudFragment extends Fragment{ count[0] = payload.payloadUsed(); } }else{ + count[0] = -1; t.clear(); } }).growX().visible(() -> player.unit() instanceof Payloadc p && p.payloadUsed() > 0).colspan(2); diff --git a/gradle.properties b/gradle.properties index 9b15d50c4d..581d1f703c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=c55aa1fe790c50db389225d9a2287b57f71260ff +archash=78fdeeda71a4bb2d46e81d936beccf8727d95388 From c6b60a262036d74c07fc77e4bd6bd5674f0ce9fb Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Tue, 12 Jan 2021 06:39:27 -0800 Subject: [PATCH 046/426] `shootLength` for other turrets that aren't `PointDefenceTurret`s (#4312) --- .../world/blocks/defense/turrets/LaserTurret.java | 2 +- .../blocks/defense/turrets/TractorBeamTurret.java | 6 +++--- .../world/blocks/defense/turrets/Turret.java | 15 +++++++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java index fd971e55d7..8ac3461dd3 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -55,7 +55,7 @@ public class LaserTurret extends PowerTurret{ if(bulletLife > 0 && bullet != null){ wasShooting = true; - tr.trns(rotation, size * tilesize / 2f, 0f); + tr.trns(rotation, shootLength, 0f); bullet.rotation(rotation); bullet.set(x + tr.x, y + tr.y); bullet.time(0f); diff --git a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java index 42e33dc2e3..a56d648b3d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java @@ -24,8 +24,9 @@ public class TractorBeamTurret extends BaseTurret{ public @Load("block-@size") TextureRegion baseRegion; public @Load("@-laser") TextureRegion laser; public @Load("@-laser-end") TextureRegion laserEnd; - + public float shootCone = 6f; + public float shootLength = 5f; public float laserWidth = 0.6f; public float force = 0.3f; public float scaledForce = 0f; @@ -141,12 +142,11 @@ public class TractorBeamTurret extends BaseTurret{ if(any){ Draw.z(Layer.bullet); float ang = angleTo(lastX, lastY); - float len = 5f; Draw.mixcol(laserColor, Mathf.absin(4f, 0.6f)); Drawf.laser(team, laser, laserEnd, - x + Angles.trnsx(ang, len), y + Angles.trnsy(ang, len), + x + Angles.trnsx(ang, shootLength), y + Angles.trnsy(ang, shootLength), lastX, lastY, strength * efficiency() * laserWidth); Draw.mixcol(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 60b31fa8d7..ab320b7863 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -54,6 +54,7 @@ public class Turret extends ReloadTurret{ public float coolantUsage = 0.2f; public float shootCone = 8f; public float shootShake = 0f; + public float shootLength = -1; public float xRand = 0f; /** Currently used for artillery only. */ public float minRange = 0f; @@ -122,6 +123,8 @@ public class Turret extends ReloadTurret{ hasLiquids = true; consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, coolantUsage)).update(false).boost(); } + + if(shootLength < 0) shootLength = size * tilesize / 2f; super.init(); } @@ -371,14 +374,14 @@ public class Turret extends ReloadTurret{ if(chargeTime > 0){ useAmmo(); - tr.trns(rotation, size * tilesize / 2f); + tr.trns(rotation, shootLength); chargeBeginEffect.at(x + tr.x, y + tr.y, rotation); chargeSound.at(x + tr.x, y + tr.y, 1); for(int i = 0; i < chargeEffects; i++){ Time.run(Mathf.random(chargeMaxDelay), () -> { if(!isValid()) return; - tr.trns(rotation, size * tilesize / 2f); + tr.trns(rotation, shootLength); chargeEffect.at(x + tr.x, y + tr.y, rotation); }); } @@ -387,7 +390,7 @@ public class Turret extends ReloadTurret{ Time.run(chargeTime, () -> { if(!isValid()) return; - tr.trns(rotation, size * tilesize / 2f); + tr.trns(rotation, shootLength); recoil = recoilAmount; heat = 1f; bullet(type, rotation + Mathf.range(inaccuracy)); @@ -403,7 +406,7 @@ public class Turret extends ReloadTurret{ recoil = recoilAmount; - tr.trns(rotation, size * tilesize / 2f, Mathf.range(xRand)); + tr.trns(rotation, shootLength, Mathf.range(xRand)); bullet(type, rotation + Mathf.range(inaccuracy)); effects(); useAmmo(); @@ -418,10 +421,10 @@ public class Turret extends ReloadTurret{ if(alternate){ float i = (shotCounter % shots) - (shots-1)/2f; - tr.trns(rotation - 90, spread * i + Mathf.range(xRand), size * tilesize / 2f); + tr.trns(rotation - 90, spread * i + Mathf.range(xRand), shootLength); bullet(type, rotation + Mathf.range(inaccuracy)); }else{ - tr.trns(rotation, size * tilesize / 2f, Mathf.range(xRand)); + tr.trns(rotation, shootLength, Mathf.range(xRand)); for(int i = 0; i < shots; i++){ bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy) + (i - (int)(shots / 2f)) * spread); From e7885a405ea804a4f1eeee82123d713862382617 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 12 Jan 2021 10:19:17 -0500 Subject: [PATCH 047/426] Removed 3.5 map image message Reasoning: 3.5 images and most other map images won't work in the editor. If you try to import a random image, it will give you an empty map. Only maps that were exported as images previously will work correctly. --- core/assets/bundles/bundle.properties | 2 +- core/src/mindustry/io/MapIO.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index db940ba4a2..9f1a3a1b63 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -391,7 +391,7 @@ editor.removeunit = Remove Unit editor.teams = Teams editor.errorload = Error loading file. editor.errorsave = Error saving file. -editor.errorimage = That's an image, not a map.\n\nIf you want to import a 3.5/build 40 map, use the 'Import Legacy Map' button in the editor. +editor.errorimage = That's an image, not a map. editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. editor.errornot = This is not a map file. editor.errorheader = This map file is either not valid or corrupt. diff --git a/core/src/mindustry/io/MapIO.java b/core/src/mindustry/io/MapIO.java index 18f6a712bd..7b1256e543 100644 --- a/core/src/mindustry/io/MapIO.java +++ b/core/src/mindustry/io/MapIO.java @@ -11,6 +11,7 @@ import mindustry.core.*; import mindustry.game.*; import mindustry.maps.*; import mindustry.world.*; +import mindustry.world.blocks.environment.*; import mindustry.world.blocks.storage.*; import java.io.*; @@ -204,6 +205,11 @@ public class MapIO{ } } } + + //default to stone floor + if(tile.floor() == Blocks.air){ + tile.setFloorUnder((Floor)Blocks.stone); + } } } } From 3dc70be516b8ecbbe196921a9bdb4718ec360b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Wed, 13 Jan 2021 00:25:41 +0800 Subject: [PATCH 048/426] Update zh-TW translations (#4290) * Update zh-TW bundle, surge correction Changed surge ammo characteristic "shock". Thought "shock" as in only stunning or making the enemy flinch. It means shocking the enemy with electricity and deal bonus damage when the unit is covered in water. * Launch max UI * Minor correction wave spawning --- core/assets/bundles/bundle_zh_TW.properties | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 0264786742..780df32819 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -287,6 +287,7 @@ cancel = 取消 openlink = 開啟連結 copylink = 複製連結 back = 返回 +max = 最大量 crash.export = 匯出當機報告。 crash.none = 無當機報告。 crash.exported = 已匯出當機報告。 @@ -361,7 +362,7 @@ editor.center = 中心 workshop = 工作坊 waves.title = 波次 waves.remove = 移除 -waves.never = 〈永不〉 +waves.never = 〈永遠〉 waves.every = 每 waves.waves = 波次 waves.perspawn = 每次生成 @@ -743,7 +744,7 @@ bullet.splashdamage = [stat]{0}[lightgray]範圍傷害 ~[stat] {1}[lightgray]格 bullet.incendiary = [stat]燃燒 bullet.sapping = [stat]吸血 bullet.homing = [stat]追蹤 -bullet.shock = [stat]震懾 +bullet.shock = [stat]電擊 bullet.frag = [stat]破片彈 bullet.buildingdamage = [stat]{0}%[lightgray] 建築傷害 bullet.knockback = [stat]{0}[lightgray]擊退 From ee79bc5501139d35f307749ec504cf845f8dd482 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 12 Jan 2021 10:20:07 -0500 Subject: [PATCH 049/426] =?UTF-8?q?Replaced=20waves.never=20with=20?= =?UTF-8?q?=E2=88=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/assets/bundles/bundle.properties | 1 - core/src/mindustry/editor/WaveInfoDialog.java | 2 +- core/src/mindustry/io/MapIO.java | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 9f1a3a1b63..57d9fa6755 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -362,7 +362,6 @@ editor.center = Center workshop = Workshop waves.title = Waves waves.remove = Remove -waves.never = waves.every = every waves.waves = wave(s) waves.perspawn = per spawn diff --git a/core/src/mindustry/editor/WaveInfoDialog.java b/core/src/mindustry/editor/WaveInfoDialog.java index a98d03a923..a71d0a2d8f 100644 --- a/core/src/mindustry/editor/WaveInfoDialog.java +++ b/core/src/mindustry/editor/WaveInfoDialog.java @@ -190,7 +190,7 @@ public class WaveInfoDialog extends BaseDialog{ group.end = never; updateWaves(); } - }).width(100f).get().setMessageText(Core.bundle.get("waves.never")); + }).width(100f).get().setMessageText("∞"); }); t.row(); t.table(p -> { diff --git a/core/src/mindustry/io/MapIO.java b/core/src/mindustry/io/MapIO.java index 7b1256e543..c484524709 100644 --- a/core/src/mindustry/io/MapIO.java +++ b/core/src/mindustry/io/MapIO.java @@ -200,7 +200,7 @@ public class MapIO{ for(Point2 p : Geometry.d4){ Tile other = tiles.get(tile.x + p.x, tile.y + p.y); if(other != null && other.floor() != Blocks.air){ - tile.setFloor(other.floor()); + tile.setFloorUnder(other.floor()); break; } } From c2602fe6a0125ff7768ebefa24e05b0ba8e4ba82 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 13 Jan 2021 10:43:04 -0500 Subject: [PATCH 050/426] Fixed #4319 --- core/src/mindustry/core/Control.java | 2 +- core/src/mindustry/core/Renderer.java | 16 +++++++++++----- gradle.properties | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 8dd487034b..8109bbcd7c 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -74,7 +74,7 @@ public class Control implements ApplicationListener, Loadable{ Events.on(WorldLoadEvent.class, event -> { if(Mathf.zero(player.x) && Mathf.zero(player.y)){ - Building core = state.teams.closestCore(0, 0, player.team()); + Building core = player.bestCore(); if(core != null){ player.set(core); camera.position.set(core); diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 8f5423cbc1..7b812f03f9 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -15,6 +15,7 @@ import mindustry.gen.*; import mindustry.graphics.*; import mindustry.graphics.g3d.*; import mindustry.ui.*; +import mindustry.world.blocks.storage.CoreBlock.*; import static arc.Core.*; import static mindustry.Vars.*; @@ -36,6 +37,7 @@ public class Renderer implements ApplicationListener{ /** minZoom = zooming out, maxZoom = zooming in */ public float minZoom = 1.5f, maxZoom = 6f; + private @Nullable CoreBuild landCore; //TODO unused private FxProcessor fx = new FxProcessor(); private Color clearColor = new Color(0f, 0f, 0f, 1f); @@ -62,6 +64,10 @@ public class Renderer implements ApplicationListener{ if(settings.getBool("bloom", !ios)){ setupBloom(); } + + Events.on(WorldLoadEvent.class, e -> { + landCore = player.bestCore(); + }); } @Override @@ -284,25 +290,25 @@ public class Renderer implements ApplicationListener{ } private void drawLanding(){ - if(landTime > 0 && player.closestCore() != null){ + CoreBuild entity = landCore == null ? player.bestCore() : landCore; + if(landTime > 0 && entity != null){ float fract = landTime / Fx.coreLand.lifetime; - Building entity = player.closestCore(); TextureRegion reg = entity.block.icon(Cicon.full); float scl = Scl.scl(4f) / camerascale; float s = reg.width * Draw.scl * scl * 4f * fract; Draw.color(Pal.lightTrail); - Draw.rect("circle-shadow", entity.getX(), entity.getY(), s, s); + Draw.rect("circle-shadow", entity.x, entity.y, s, s); Angles.randLenVectors(1, (1f- fract), 100, 1000f * scl * (1f-fract), (x, y, fin, fout) -> { Lines.stroke(scl * fin); - Lines.lineAngle(entity.getX() + x, entity.getY() + y, Mathf.angle(x, y), (fin * 20 + 1f) * scl); + Lines.lineAngle(entity.x + x, entity.y + y, Mathf.angle(x, y), (fin * 20 + 1f) * scl); }); Draw.color(); Draw.mixcol(Color.white, fract); - Draw.rect(reg, entity.getX(), entity.getY(), reg.width * Draw.scl * scl, reg.height * Draw.scl * scl, fract * 135f); + Draw.rect(reg, entity.x, entity.y, reg.width * Draw.scl * scl, reg.height * Draw.scl * scl, fract * 135f); Draw.reset(); } diff --git a/gradle.properties b/gradle.properties index 581d1f703c..3700022ccb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=78fdeeda71a4bb2d46e81d936beccf8727d95388 +archash=f89e6a465fe9d139bd192960c2ebdff33c2af86a From 95c04eb0859b0aca213b6e9fa1e14c25f3709314 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 13 Jan 2021 17:09:18 -0500 Subject: [PATCH 051/426] Minor sector damage calculation changes --- core/src/mindustry/maps/SectorDamage.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/maps/SectorDamage.java b/core/src/mindustry/maps/SectorDamage.java index 28d9846d1d..7bac886a65 100644 --- a/core/src/mindustry/maps/SectorDamage.java +++ b/core/src/mindustry/maps/SectorDamage.java @@ -363,13 +363,11 @@ public class SectorDamage{ info.waveDpsBase = reg.intercept; info.waveDpsSlope = reg.slope; - //enemy units like to aim for a lot of non-essential things, so increase resulting health slightly - info.sumHealth = sumHealth * 1.05f; - //players tend to have longer range units/turrets, so assume DPS is higher - info.sumDps = sumDps * 1.05f; + info.sumHealth = sumHealth * 0.9f; + info.sumDps = sumDps; info.sumRps = sumRps; - float cmult = 1.5f; + float cmult = 1.6f; info.curEnemyDps = curEnemyDps*cmult; info.curEnemyHealth = curEnemyHealth*cmult; @@ -524,7 +522,7 @@ public class SectorDamage{ static float cost(Tile tile){ return 1f + (tile.block().isStatic() && tile.solid() ? 200f : 0f) + - (tile.build != null ? tile.build.health / 40f : 0f) + + (tile.build != null ? tile.build.health / (tile.build.block.size * tile.build.block.size) / 20f : 0f) + (tile.floor().isLiquid ? 10f : 0f); } } From 32070a37f789af599ad60cf0cb9b2aad0678d408 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 14 Jan 2021 11:26:16 -0500 Subject: [PATCH 052/426] Fixed #4325 --- .../world/blocks/distribution/MassDriver.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/world/blocks/distribution/MassDriver.java b/core/src/mindustry/world/blocks/distribution/MassDriver.java index eb3409b1cd..67c4c23191 100644 --- a/core/src/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/mindustry/world/blocks/distribution/MassDriver.java @@ -175,11 +175,14 @@ public class MassDriver extends Block{ Angles.near(rotation, targetRotation, 2f) && Angles.near(other.rotation, targetRotation + 180f, 2f)){ //actually fire fire(other); - //remove waiting shooters, it's done firing - other.waitingShooters.remove(tile); - //set both states to idle + float timeToArrive = Math.min(bulletLifetime, dst(other) / bulletSpeed); + Time.run(timeToArrive, () -> { + //remove waiting shooters, it's done firing + other.waitingShooters.remove(tile); + other.state = DriverState.idle; + }); + //driver is immediately idle state = DriverState.idle; - other.state = DriverState.idle; } } } From 81ce3a28a19adaaf457a626d713fdc68e80b442e Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 14 Jan 2021 13:46:27 -0500 Subject: [PATCH 053/426] More distinct plastanium sprite --- .../sprites/items/item-plastanium.png | Bin 481 -> 324 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/core/assets-raw/sprites/items/item-plastanium.png b/core/assets-raw/sprites/items/item-plastanium.png index f6ddf438fcc193d44271685c06fdc6996dfae12a..be27bcfe12ba25cd0dfaba8a15975e21af4a5848 100644 GIT binary patch delta 285 zcmaFJe1vI&K|RAiPZ!6Kh}O4LHu4@a5OC!`*1*T5BBeDgq3=!O4dvn#PAw@Ft``Zs zD<-UY^5*yd+p>SOHr9TR(>b2Df8NZfihZ*8U;eHuo>b-Onq1M#5<8)Jwa}F${(Vt7 zXV1L(xXVlE!y%zR(ymGC4((myl;N8pX)5);NpidJQO~ERBRk*Jvv94STEHGz(R(Dt zp>?&;h4=$1t%@@_V&0u!CiHUi_1kwF!-NEFv@duuy$rQs)>T;~_fT=oM2D<}`yD1a zWZ&stA#e3v@5b8cp&#B|I4&NzmW5fLOG8M=h(ABbz6 zZ@lD|n(MX%^Ag9GFC#hw8g%_7Zcjea*rvWVB|T^V`Ny5%jQ=788LpI`WlLYJe%J2r zjMZx97Dm>`+0E-7zsNr2!I0UdzSaKwDXs%=?xin!{5idzZ4X1e-sin@o&Ub(K6tI+ z*50#smQBCT8Y#Zvdh;qqCI!#k+zWVF7Lv!0uhBC%F!AtC6kXaDz%Vg2 zL7#(f#m;3j8y5%&74uG5Ke_&az$McXwzignv#PEZEG?;hasQ7;3kV%bUuXU5{f}RX z%a~85t(*1cYt5GZw{QN*E$Uo-(vso0?FDsVyW(J$2j7xzaVu$`3VX(|;bM)za?yMK z+c=MWFLX)ha}E&J*&|fVQW&M^r_H1oc_uaQU7eL(F>`@}tU|=+WiIk+vI=WVo;`cV zxQwml)76&DdFzD}HZHno__oXbY>TO&Ve-GHSJeH>ek{@RVr^w$U|{fc^>bP0l+XkK DduPSe From 593a7b060c6fea9360fb1790ffb4b0fd471c2c04 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 10:04:56 -0500 Subject: [PATCH 054/426] Fixed #4334 --- core/src/mindustry/world/blocks/distribution/Sorter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/distribution/Sorter.java b/core/src/mindustry/world/blocks/distribution/Sorter.java index f15c561c04..39805330cd 100644 --- a/core/src/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/mindustry/world/blocks/distribution/Sorter.java @@ -33,7 +33,11 @@ public class Sorter extends Block{ @Override public void drawRequestConfig(BuildPlan req, Eachable list){ - drawRequestConfigCenter(req, req.config, "center"); + if(req.config == null){ + Draw.rect("cross", req.drawx(), req.drawy()); + }else{ + drawRequestConfigCenter(req, req.config, "center"); + } } @Override From 956f4659c7ee54f8915370428e1069f2518cfe1f Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Fri, 15 Jan 2021 07:13:41 -0800 Subject: [PATCH 055/426] Sound stuff (#4332) --- core/src/mindustry/entities/bullet/BulletType.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 53aad2f052..318fbd6f04 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -34,6 +34,10 @@ public abstract class BulletType extends Content{ public Effect smokeEffect = Fx.shootSmallSmoke; /** Sound made when hitting something or getting removed.*/ public Sound hitSound = Sounds.none; + /** Pitch of the sound made when hitting something*/ + public float hitSoundPitch = 1; + /** Volume of the sound made when hitting something*/ + public float hitSoundVolume = 1; /** Extra inaccuracy when firing. */ public float inaccuracy = 0f; /** How many bullets get created per ammo item/liquid. */ @@ -186,7 +190,7 @@ public abstract class BulletType extends Content{ public void hit(Bullet b, float x, float y){ hitEffect.at(x, y, b.rotation(), hitColor); - hitSound.at(b); + hitSound.at(x, y, hitSoundPitch, hitSoundVolume); Effect.shake(hitShake, hitShake, b); From a342a7d6386fab60cbfa4ea4d7bb0aab68ae371a Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 11:16:08 -0500 Subject: [PATCH 056/426] Cleanup & bugfixes --- core/src/mindustry/core/Logic.java | 7 ----- core/src/mindustry/logic/LExecutor.java | 12 ++++----- core/src/mindustry/maps/SectorDamage.java | 31 ++++++++++------------- gradle.properties | 2 +- 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 6e7ba9b957..6263782b51 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -81,13 +81,6 @@ public class Logic implements ApplicationListener{ state.wavetime = state.rules.waveSpacing; SectorDamage.applyCalculatedDamage(); - - //make sure damaged buildings are counted - for(Tile tile : world.tiles){ - if(tile.build != null && tile.build.damaged()){ - indexer.notifyTileDamaged(tile.build); - } - } } //reset values diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 45c28bb75a..ffbee6cdf3 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -569,7 +569,7 @@ public class LExecutor{ int address = exec.numi(position); Building from = exec.building(target); - if(from instanceof MemoryBuild mem){ + if(from instanceof MemoryBuild mem && from.team == exec.team){ exec.setnum(output, address < 0 || address >= mem.memory.length ? 0 : mem.memory[address]); } @@ -593,7 +593,7 @@ public class LExecutor{ int address = exec.numi(position); Building from = exec.building(target); - if(from instanceof MemoryBuild mem){ + if(from instanceof MemoryBuild mem && from.team == exec.team){ if(address >= 0 && address < mem.memory.length){ mem.memory[address] = exec.num(value); @@ -620,7 +620,7 @@ public class LExecutor{ Object target = exec.obj(from); Object sense = exec.obj(type); - //TODO should remote enemy buildings be senseable? + //note that remote units/buildings can be sensed as well if(target instanceof Senseable se){ if(sense instanceof Content){ exec.setnum(to, se.sense(((Content)sense))); @@ -857,8 +857,7 @@ public class LExecutor{ //graphics on headless servers are useless. if(Vars.headless) return; - Building build = exec.building(target); - if(build instanceof LogicDisplayBuild d){ + if(exec.building(target) instanceof LogicDisplayBuild d && d.team == exec.team){ if(d.commands.size + exec.graphicsBuffer.size < maxDisplayBuffer){ for(int i = 0; i < exec.graphicsBuffer.size; i++){ d.commands.addLast(exec.graphicsBuffer.items[i]); @@ -920,8 +919,7 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - Building build = exec.building(target); - if(build instanceof MessageBuild d){ + if(exec.building(target) instanceof MessageBuild d && d.team == exec.team){ d.message.setLength(0); d.message.append(exec.textBuffer, 0, Math.min(exec.textBuffer.length(), maxTextBuffer)); diff --git a/core/src/mindustry/maps/SectorDamage.java b/core/src/mindustry/maps/SectorDamage.java index 7bac886a65..1c0df9f233 100644 --- a/core/src/mindustry/maps/SectorDamage.java +++ b/core/src/mindustry/maps/SectorDamage.java @@ -24,7 +24,7 @@ public class SectorDamage{ public static final int maxRetWave = 40, maxWavesSimulated = 50; //direct damage is for testing only - private static final boolean direct = false, rubble = true; + private static final boolean rubble = true; /** @return calculated capture progress of the enemy */ public static float getDamage(SectorInfo info){ @@ -225,7 +225,6 @@ public class SectorDamage{ //create sparse tile array for fast range query int sparseSkip = 5, sparseSkip2 = 3; - //TODO if this is slow, use a quadtree Seq sparse = new Seq<>(path.size / sparseSkip + 1); Seq sparse2 = new Seq<>(path.size / sparseSkip2 + 1); @@ -485,23 +484,21 @@ public class SectorDamage{ if(other.build != null && other.team() != state.rules.waveTeam){ resultDamage -= other.build.health(); - if(direct){ - other.build.damage(currDamage); - }else{ //indirect damage happens at game load time - other.build.health -= currDamage; - //don't kill the core! - if(other.block() instanceof CoreBlock) other.build.health = Math.max(other.build.health, 1f); + other.build.health -= currDamage; + //don't kill the core! + if(other.block() instanceof CoreBlock) other.build.health = Math.max(other.build.health, 1f); - //remove the block when destroyed - if(other.build.health < 0){ - //rubble - if(rubble && !other.floor().solid && !other.floor().isLiquid && Mathf.chance(0.4)){ - Effect.rubble(other.build.x, other.build.y, other.block().size); - } - - other.build.addPlan(false); - other.remove(); + //remove the block when destroyed + if(other.build.health < 0){ + //rubble + if(rubble && !other.floor().solid && !other.floor().isLiquid && Mathf.chance(0.4)){ + Effect.rubble(other.build.x, other.build.y, other.block().size); } + + other.build.addPlan(false); + other.remove(); + }else{ + indexer.notifyTileDamaged(other.build); } }else if(other.solid() && !other.synthetic()){ //skip damage propagation through solid blocks diff --git a/gradle.properties b/gradle.properties index 3700022ccb..caeb2227d2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=f89e6a465fe9d139bd192960c2ebdff33c2af86a +archash=25dcd2f7664f3c5a669447fdf8dffaea7e65fe0d From 136c8cfcd2deead51826e4c7462e33873ff61e38 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 11:34:33 -0500 Subject: [PATCH 057/426] Cleanup + Generic cross rendering --- core/src/mindustry/input/DesktopInput.java | 8 ++++++-- .../ui/fragments/PlacementFragment.java | 2 +- core/src/mindustry/world/Block.java | 18 +++++++++++++----- .../world/blocks/distribution/ItemBridge.java | 2 -- .../world/blocks/distribution/Sorter.java | 6 +----- .../world/blocks/sandbox/ItemSource.java | 2 +- .../world/blocks/sandbox/LiquidSource.java | 2 +- 7 files changed, 23 insertions(+), 17 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 801ffdbbd8..5c82bd67a3 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -3,6 +3,7 @@ package mindustry.input; import arc.*; import arc.Graphics.*; import arc.Graphics.Cursor.*; +import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; @@ -160,14 +161,17 @@ public class DesktopInput extends InputHandler{ drawArrow(block, cursorX, cursorY, rotation); } Draw.color(); + boolean valid = validPlace(cursorX, cursorY, block, rotation); drawRequest(cursorX, cursorY, block, rotation); - block.drawPlace(cursorX, cursorY, rotation, validPlace(cursorX, cursorY, block, rotation)); + block.drawPlace(cursorX, cursorY, rotation, valid); - if(block.saveConfig && block.lastConfig != null){ + if(block.saveConfig){ + Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f)); brequest.set(cursorX, cursorY, rotation, block); brequest.config = block.lastConfig; block.drawRequestConfig(brequest, allRequests()); brequest.config = null; + Draw.reset(); } } } diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index 7bb3e6be3c..018b577954 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -99,7 +99,7 @@ public class PlacementFragment extends Fragment{ if(Core.input.keyTap(Binding.pick) && player.isBuilder()){ //mouse eyedropper select Building tile = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); - Block tryRecipe = tile == null ? null : tile.block instanceof ConstructBlock ? ((ConstructBuild)tile).cblock : tile.block; + Block tryRecipe = tile == null ? null : tile instanceof ConstructBuild c ? c.cblock : tile.block; Object tryConfig = tile == null ? null : tile.config(); for(BuildPlan req : player.unit().plans()){ diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index c7e9d73b33..6c9628c95b 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -426,9 +426,7 @@ public class Block extends UnlockableContent{ TextureRegion reg = getRequestRegion(req, list); Draw.rect(reg, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90); - if(req.config != null){ - drawRequestConfig(req, list); - } + drawRequestConfig(req, list); } public TextureRegion getRequestRegion(BuildPlan req, Eachable list){ @@ -439,8 +437,14 @@ public class Block extends UnlockableContent{ } - public void drawRequestConfigCenter(BuildPlan req, Object content, String region){ - Color color = content instanceof Item ? ((Item)content).color : content instanceof Liquid ? ((Liquid)content).color : null; + public void drawRequestConfigCenter(BuildPlan req, Object content, String region, boolean cross){ + if(content == null){ + if(cross){ + Draw.rect("cross", req.drawx(), req.drawy()); + } + return; + } + Color color = content instanceof Item i ? i.color : content instanceof Liquid l ? l.color : null; if(color == null) return; Draw.color(color); @@ -448,6 +452,10 @@ public class Block extends UnlockableContent{ Draw.color(); } + public void drawRequestConfigCenter(BuildPlan req, Object content, String region){ + drawRequestConfigCenter(req, content, region, false); + } + public void drawRequestConfigTop(BuildPlan req, Eachable list){ } diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 2ab0c9b047..605d74f880 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -176,8 +176,6 @@ public class ItemBridge extends Block{ public void playerPlaced(Object config){ super.playerPlaced(config); - if(config != null) return; - Tile link = findLink(tile.x, tile.y); if(linkValid(tile, link) && !proximity.contains(link.build)){ link.build.configure(tile.pos()); diff --git a/core/src/mindustry/world/blocks/distribution/Sorter.java b/core/src/mindustry/world/blocks/distribution/Sorter.java index 39805330cd..b76037ee3d 100644 --- a/core/src/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/mindustry/world/blocks/distribution/Sorter.java @@ -33,11 +33,7 @@ public class Sorter extends Block{ @Override public void drawRequestConfig(BuildPlan req, Eachable list){ - if(req.config == null){ - Draw.rect("cross", req.drawx(), req.drawy()); - }else{ - drawRequestConfigCenter(req, req.config, "center"); - } + drawRequestConfigCenter(req, req.config, "center", true); } @Override diff --git a/core/src/mindustry/world/blocks/sandbox/ItemSource.java b/core/src/mindustry/world/blocks/sandbox/ItemSource.java index fb28247758..aee34a9446 100644 --- a/core/src/mindustry/world/blocks/sandbox/ItemSource.java +++ b/core/src/mindustry/world/blocks/sandbox/ItemSource.java @@ -37,7 +37,7 @@ public class ItemSource extends Block{ @Override public void drawRequestConfig(BuildPlan req, Eachable list){ - drawRequestConfigCenter(req, req.config, "center"); + drawRequestConfigCenter(req, req.config, "center", true); } @Override diff --git a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java index 25d84598bf..7f029299c3 100644 --- a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java +++ b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java @@ -41,7 +41,7 @@ public class LiquidSource extends Block{ @Override public void drawRequestConfig(BuildPlan req, Eachable list){ - drawRequestConfigCenter(req, req.config, "center"); + drawRequestConfigCenter(req, req.config, "center", true); } public class LiquidSourceBuild extends Building{ From 6ec76409ef90d334bc6a17fa09bc35c121cb7c29 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 12:38:42 -0500 Subject: [PATCH 058/426] Fixed #4335 --- .../world/blocks/distribution/StackConveyor.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/distribution/StackConveyor.java b/core/src/mindustry/world/blocks/distribution/StackConveyor.java index 41b0736181..d68365a4d3 100644 --- a/core/src/mindustry/world/blocks/distribution/StackConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/StackConveyor.java @@ -267,6 +267,12 @@ public class StackConveyor extends Block implements Autotiler{ link = -1; } + @Override + public int acceptStack(Item item, int amount, Teamc source){ + if(items.any() && !items.has(item)) return 0; + return super.acceptStack(item, amount, source); + } + @Override public void handleItem(Building source, Item item){ if(items.empty()) poofIn(); @@ -301,7 +307,7 @@ public class StackConveyor extends Block implements Autotiler{ if(this == source) return true; // player threw items if(cooldown > recharge - 1f) return false; // still cooling down return !((state != stateLoad) // not a loading dock - || (items.total() > 0 && !items.has(item)) // incompatible items + || (items.any() && !items.has(item)) // incompatible items || (items.total() >= getMaximumAccepted(item)) // filled to capacity || (front() == source)); } From 650d47991e71f3fef8fa5e938e0dd712890fc8c0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 12:43:37 -0500 Subject: [PATCH 059/426] Formatting --- core/src/mindustry/ai/BaseAI.java | 3 ++- .../blocks/distribution/StackConveyor.java | 26 +++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/core/src/mindustry/ai/BaseAI.java b/core/src/mindustry/ai/BaseAI.java index 85e6656d28..6a1e43b172 100644 --- a/core/src/mindustry/ai/BaseAI.java +++ b/core/src/mindustry/ai/BaseAI.java @@ -265,6 +265,7 @@ public class BaseAI{ if(spawn == null) return; for(int wx = lastX; wx <= lastX + lastW; wx++){ + outer: for(int wy = lastY; wy <= lastY + lastH; wy++){ Tile tile = world.tile(wx, wy); @@ -279,7 +280,7 @@ public class BaseAI{ Tile o = world.tile(tile.x + p.x, tile.y + p.y); if(o != null && (o.block() instanceof PayloadAcceptor || o.block() instanceof PayloadConveyor)){ - break; + continue outer; } if(o != null && o.team() == data.team && !(o.block() instanceof Wall)){ diff --git a/core/src/mindustry/world/blocks/distribution/StackConveyor.java b/core/src/mindustry/world/blocks/distribution/StackConveyor.java index d68365a4d3..ceb9339635 100644 --- a/core/src/mindustry/world/blocks/distribution/StackConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/StackConveyor.java @@ -201,21 +201,21 @@ public class StackConveyor extends Block implements Autotiler{ @Override public void updateTile(){ - // reel in crater + //reel in crater if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed * edelta(), 0f, recharge); - // indicates empty state + //indicates empty state if(link == -1) return; - // crater needs to be centered + //crater needs to be centered if(cooldown > 0f) return; - // get current item + //get current item if(lastItem == null || !items.has(lastItem)){ lastItem = items.first(); } - // do not continue if disabled, will still allow one to be reeled in to prevent visual stacking + //do not continue if disabled, will still allow one to be reeled in to prevent visual stacking if(!enabled) return; if(state == stateUnload){ //unload @@ -225,12 +225,12 @@ public class StackConveyor extends Block implements Autotiler{ }else{ //transfer if(state != stateLoad || (items.total() >= getMaximumAccepted(lastItem))){ if(front() instanceof StackConveyorBuild e && e.team == team){ - // sleep if its occupied + //sleep if its occupied if(e.link == -1){ e.items.add(items); e.lastItem = lastItem; e.link = tile.pos(); - // ▲ to | from ▼ + //▲ to | from ▼ link = -1; items.clear(); @@ -254,7 +254,7 @@ public class StackConveyor extends Block implements Autotiler{ @Override public boolean shouldAmbientSound(){ - return false; // has no moving parts; + return false; //has no moving parts; } protected void poofIn(){ @@ -304,11 +304,11 @@ public class StackConveyor extends Block implements Autotiler{ @Override public boolean acceptItem(Building source, Item item){ - if(this == source) return true; // player threw items - if(cooldown > recharge - 1f) return false; // still cooling down - return !((state != stateLoad) // not a loading dock - || (items.any() && !items.has(item)) // incompatible items - || (items.total() >= getMaximumAccepted(item)) // filled to capacity + if(this == source) return true; //player threw items + if(cooldown > recharge - 1f) return false; //still cooling down + return !((state != stateLoad) //not a loading dock + || (items.any() && !items.has(item)) //incompatible items + || (items.total() >= getMaximumAccepted(item)) //filled to capacity || (front() == source)); } From 718a40d742717c68447d604b7493aa11f27b8773 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 16:04:26 -0500 Subject: [PATCH 060/426] More pattern matching --- core/src/mindustry/entities/comp/BuildingComp.java | 2 +- core/src/mindustry/world/blocks/ConstructBlock.java | 2 +- .../mindustry/world/blocks/distribution/StackConveyor.java | 4 ++-- core/src/mindustry/world/blocks/power/PowerNode.java | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 2067c328db..1fa2d7c372 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -906,7 +906,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, tempTiles.clear(); Geometry.circle(tileX(), tileY(), range, (x, y) -> { Building other = world.build(x, y); - if(other != null && other.block instanceof PowerNode && ((PowerNode)other.block).linkValid(other, self()) && !PowerNode.insulated(other, self()) + if(other != null && other.block instanceof PowerNode node && node.linkValid(other, self()) && !PowerNode.insulated(other, self()) && !other.proximity().contains(this.self()) && !(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){ tempTiles.add(other.tile); diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index f2ebd161dd..85ca209ab6 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -63,7 +63,7 @@ public class ConstructBlock extends Block{ if(tile == null) return; float healthf = tile.build == null ? 1f : tile.build.healthf(); - Seq prev = tile.build instanceof ConstructBuild ? ((ConstructBuild)tile.build).prevBuild : null; + Seq prev = tile.build instanceof ConstructBuild co ? co.prevBuild : null; tile.setBlock(block, team, rotation); diff --git a/core/src/mindustry/world/blocks/distribution/StackConveyor.java b/core/src/mindustry/world/blocks/distribution/StackConveyor.java index ceb9339635..b279f09b9d 100644 --- a/core/src/mindustry/world/blocks/distribution/StackConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/StackConveyor.java @@ -92,8 +92,8 @@ public class StackConveyor extends Block implements Autotiler{ @Override public boolean rotatedOutput(int x, int y){ Building tile = world.build(x, y); - if(tile instanceof StackConveyorBuild){ - return ((StackConveyorBuild)tile).state != stateUnload; + if(tile instanceof StackConveyorBuild s){ + return s.state != stateUnload; } return super.rotatedOutput(x, y); } diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 43c292e5b0..9982c1d324 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -246,9 +246,9 @@ public class PowerNode extends PowerBlock{ public boolean linkValid(Building tile, Building link, boolean checkMaxNodes){ if(tile == link || link == null || !link.block.hasPower || tile.team != link.team) return false; - if(overlaps(tile, link, laserRange * tilesize) || (link.block instanceof PowerNode && overlaps(link, tile, ((PowerNode)link.block).laserRange * tilesize))){ - if(checkMaxNodes && link.block instanceof PowerNode){ - return link.power.links.size < ((PowerNode)link.block).maxNodes || link.power.links.contains(tile.pos()); + if(overlaps(tile, link, laserRange * tilesize) || (link.block instanceof PowerNode node && overlaps(link, tile, node.laserRange * tilesize))){ + if(checkMaxNodes && link.block instanceof PowerNode node){ + return link.power.links.size < node.maxNodes || link.power.links.contains(tile.pos()); } return true; } From 2d3a9b605aab36554866bfcc7796996c81c07c12 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 17:09:12 -0500 Subject: [PATCH 061/426] Fixed #4337 / Fixed #4336 --- core/src/mindustry/maps/Map.java | 4 ++-- core/src/mindustry/world/blocks/storage/CoreBlock.java | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/maps/Map.java b/core/src/mindustry/maps/Map.java index 1f9ab65cdd..f1cc24d5f4 100644 --- a/core/src/mindustry/maps/Map.java +++ b/core/src/mindustry/maps/Map.java @@ -62,7 +62,7 @@ public class Map implements Comparable, Publishable{ } public int getHightScore(){ - return Core.settings.getInt("hiscore" + file.nameWithoutExtension(), 0); + return Core.settings.getInt("hiscore" + file.nameWithoutExtension() + tags.get("steamid", ""), 0); } public Texture safeTexture(){ @@ -78,7 +78,7 @@ public class Map implements Comparable, Publishable{ } public void setHighScore(int score){ - Core.settings.put("hiscore" + file.nameWithoutExtension(), score); + Core.settings.put("hiscore" + file.nameWithoutExtension() + tags.get("steamid", ""), score); } /** Returns the result of applying this map's rules to the specified gamemode.*/ diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index da2ac30b8f..7e271d798c 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -34,8 +34,6 @@ public class CoreBlock extends StorageBlock{ public final int timerResupply = timers++; - public int launchRange = 1; - public int ammoAmount = 5; public float resupplyRate = 10f; public float resupplyRange = 60f; @@ -114,7 +112,7 @@ public class CoreBlock extends StorageBlock{ if(tile == null) return false; CoreBuild core = team.core(); //must have all requirements - if(core == null || (!state.rules.infiniteResources && !core.items.has(requirements))) return false; + if(core == null || (!state.rules.infiniteResources && !core.items.has(requirements, state.rules.buildCostMultiplier))) return false; return tile.block() instanceof CoreBlock && size > tile.block().size; } From f3b1ef02e3a495bc84fac8f821ef96a96f99c81f Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Fri, 15 Jan 2021 23:09:39 +0100 Subject: [PATCH 062/426] Scale impact reactor warmup time with boost (#4317) --- core/src/mindustry/world/blocks/power/ImpactReactor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index 156e5c13ce..da7bcdabc7 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -72,7 +72,7 @@ public class ImpactReactor extends PowerGenerator{ if(consValid() && power.status >= 0.99f){ boolean prevOut = getPowerProduction() <= consumes.getPower().requestedPower(this); - warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed); + warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed * timeScale()); if(Mathf.equal(warmup, 1f, 0.001f)){ warmup = 1f; } From 02ef633529f93785bc3ee9f49d620a816680c0a8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 15 Jan 2021 17:10:38 -0500 Subject: [PATCH 063/426] Removed redundant parens --- core/src/mindustry/world/blocks/distribution/Conveyor.java | 2 +- core/src/mindustry/world/blocks/power/ImpactReactor.java | 6 +++--- core/src/mindustry/world/blocks/power/NuclearReactor.java | 2 +- core/src/mindustry/world/blocks/production/Drill.java | 2 +- core/src/mindustry/world/blocks/storage/Unloader.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index f21f4fbad2..7fb01d9be0 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -114,7 +114,7 @@ public class Conveyor extends Block implements Autotiler{ @Override public void draw(){ - int frame = enabled && clogHeat <= 0.5f ? (int)(((Time.time * speed * 8f * timeScale())) % 4) : 0; + int frame = enabled && clogHeat <= 0.5f ? (int)(((Time.time * speed * 8f * timeScale)) % 4) : 0; //draw extra conveyors facing this one for non-square tiling purposes Draw.z(Layer.blockUnder); diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index da7bcdabc7..22c95a9089 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -45,7 +45,7 @@ public class ImpactReactor extends PowerGenerator{ bars.add("poweroutput", (GeneratorBuild entity) -> new Bar(() -> Core.bundle.format("bar.poweroutput", - Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale(), 1)), + Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale, 1)), () -> Pal.powerBar, () -> entity.productionEfficiency)); } @@ -72,7 +72,7 @@ public class ImpactReactor extends PowerGenerator{ if(consValid() && power.status >= 0.99f){ boolean prevOut = getPowerProduction() <= consumes.getPower().requestedPower(this); - warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed * timeScale()); + warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed * timeScale); if(Mathf.equal(warmup, 1f, 0.001f)){ warmup = 1f; } @@ -81,7 +81,7 @@ public class ImpactReactor extends PowerGenerator{ Events.fire(Trigger.impactPower); } - if(timer(timerUse, itemDuration / timeScale())){ + if(timer(timerUse, itemDuration / timeScale)){ consume(); } }else{ diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index bbde62b3e7..7dd8be9f07 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -81,7 +81,7 @@ public class NuclearReactor extends PowerGenerator{ if(fuel > 0 && enabled){ heat += fullness * heating * Math.min(delta(), 4f); - if(timer(timerFuel, itemDuration / timeScale())){ + if(timer(timerFuel, itemDuration / timeScale)){ consume(); } }else{ diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index 6d4e0c8708..373d5bb9de 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -90,7 +90,7 @@ public class Drill extends Block{ super.setBars(); bars.add("drillspeed", (DrillBuild e) -> - new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastDrillSpeed * 60 * e.timeScale(), 2)), () -> Pal.ammo, () -> e.warmup)); + new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastDrillSpeed * 60 * e.timeScale, 2)), () -> Pal.ammo, () -> e.warmup)); } public Item getDrop(Tile tile){ diff --git a/core/src/mindustry/world/blocks/storage/Unloader.java b/core/src/mindustry/world/blocks/storage/Unloader.java index e040153828..a2fa940da9 100644 --- a/core/src/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/mindustry/world/blocks/storage/Unloader.java @@ -52,7 +52,7 @@ public class Unloader extends Block{ @Override public void updateTile(){ - if(timer(timerUnload, speed / timeScale())){ + if(timer(timerUnload, speed / timeScale)){ if(rotations == null || rotations.length != proximity.size){ rotations = new int[proximity.size]; } From f9adcfeed11fbedc22b5ecef37cbc8447a192120 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 17 Jan 2021 09:21:11 -0500 Subject: [PATCH 064/426] Ground units: Avoid stepping onto dangerous/deep floor --- core/src/mindustry/ai/Pathfinder.java | 2 +- core/src/mindustry/world/Tile.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/ai/Pathfinder.java b/core/src/mindustry/ai/Pathfinder.java index 8c9a9cda6d..b957d61e53 100644 --- a/core/src/mindustry/ai/Pathfinder.java +++ b/core/src/mindustry/ai/Pathfinder.java @@ -292,7 +292,7 @@ public class Pathfinder implements Runnable{ } } - if(current == null || tl == impassable) return tile; + if(current == null || tl == impassable || (path.cost == costTypes.items[costGround] && current.dangerous() && !tile.dangerous())) return tile; return current; } diff --git a/core/src/mindustry/world/Tile.java b/core/src/mindustry/world/Tile.java index d4556fd60f..e5fb9cbc0d 100644 --- a/core/src/mindustry/world/Tile.java +++ b/core/src/mindustry/world/Tile.java @@ -378,6 +378,11 @@ public class Tile implements Position, QuadTreeObject, Displayable{ return block.destructible || block.breakable || block.update; } + /** @return whether the floor on this tile deals damage or can be drowned on. */ + public boolean dangerous(){ + return !block.solid && (floor.isDeep() || floor.damageTaken > 0); + } + /** * Iterates through the list of all tiles linked to this multiblock, or just itself if it's not a multiblock. * The result contains all linked tiles, including this tile itself. From 634d9d1a40d553e0f90bdd3ade9ff43b87c1c7b7 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 17 Jan 2021 15:31:22 -0500 Subject: [PATCH 065/426] Fixed #4357 / Fixed #4349 / Fixed #4345 / Fixed #4343 --- core/src/mindustry/entities/bullet/SapBulletType.java | 2 +- core/src/mindustry/world/blocks/campaign/LaunchPad.java | 5 +++++ core/src/mindustry/world/blocks/defense/Door.java | 8 ++++---- .../mindustry/world/blocks/distribution/ItemBridge.java | 2 ++ core/src/mindustry/world/blocks/storage/CoreBlock.java | 1 + 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/entities/bullet/SapBulletType.java b/core/src/mindustry/entities/bullet/SapBulletType.java index dbd30b77a8..b86476a9d7 100644 --- a/core/src/mindustry/entities/bullet/SapBulletType.java +++ b/core/src/mindustry/entities/bullet/SapBulletType.java @@ -19,7 +19,7 @@ public class SapBulletType extends BulletType{ public SapBulletType(){ speed = 0.0001f; despawnEffect = Fx.none; - pierce = false; + pierce = true; collides = false; hitSize = 0f; hittable = false; diff --git a/core/src/mindustry/world/blocks/campaign/LaunchPad.java b/core/src/mindustry/world/blocks/campaign/LaunchPad.java index 838efde720..f8f3ce53b0 100644 --- a/core/src/mindustry/world/blocks/campaign/LaunchPad.java +++ b/core/src/mindustry/world/blocks/campaign/LaunchPad.java @@ -76,6 +76,11 @@ public class LaunchPad extends Block{ return power != null && (block.consumes.has(ConsumeType.power) && !block.consumes.getPower().buffered) ? power.status : 1f; } + @Override + public boolean shouldConsume(){ + return true; + } + @Override public void draw(){ super.draw(); diff --git a/core/src/mindustry/world/blocks/defense/Door.java b/core/src/mindustry/world/blocks/defense/Door.java index 3546831ac8..f17ca43946 100644 --- a/core/src/mindustry/world/blocks/defense/Door.java +++ b/core/src/mindustry/world/blocks/defense/Door.java @@ -69,8 +69,8 @@ public class Door extends Wall{ super.onProximityRemoved(); for(Building b : proximity){ - if(b instanceof DoorBuild){ - ((DoorBuild)b).updateChained(); + if(b instanceof DoorBuild d){ + d.updateChained(); } } } @@ -113,8 +113,8 @@ public class Door extends Wall{ this.chained = set; for(Building b : proximity){ - if(b instanceof DoorBuild){ - ((DoorBuild)b).flow(set); + if(b instanceof DoorBuild d){ + d.flow(set); } } } diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 605d74f880..2ab0c9b047 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -176,6 +176,8 @@ public class ItemBridge extends Block{ public void playerPlaced(Object config){ super.playerPlaced(config); + if(config != null) return; + Tile link = findLink(tile.x, tile.y); if(linkValid(tile, link) && !proximity.contains(link.build)){ link.build.configure(tile.pos()); diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 7e271d798c..8767554939 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -384,6 +384,7 @@ public class CoreBlock extends StorageBlock{ }else if(state.rules.coreIncinerates && items.get(item) >= storageCapacity && !noEffect){ //create item incineration effect at random intervals incinerateEffect(this, source); + noEffect = false; } } } From 32a1d91faf502bcfbfc171a16327f1d49fda3a2c Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sun, 17 Jan 2021 21:33:19 +0100 Subject: [PATCH 066/426] Use Player.deathDelay + 1 instead of magic number (#4344) --- core/src/mindustry/input/InputHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 7bc5fe5e80..4a5c8fe18b 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -343,7 +343,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } player.clearUnit(); - player.deathTimer = 61f; + player.deathTimer = Player.deathDelay + 1f; build.requestSpawn(player); }else if(unit == null){ //just clear the unit (is this used?) player.clearUnit(); @@ -369,7 +369,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Fx.spawn.at(player); player.clearUnit(); - player.deathTimer = 61f; //for instant respawn + player.deathTimer = Player.deathDelay + 1f; //for instant respawn } @Remote(targets = Loc.both, called = Loc.server, forward = true) From 6a63956b7128425c032b3fe715e3865d7ec0422c Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 17 Jan 2021 15:54:43 -0500 Subject: [PATCH 067/426] Anuken/Mindustry-Suggestions/issues/1808 / Less fire in rain --- core/src/mindustry/Vars.java | 4 ++-- core/src/mindustry/entities/comp/FireComp.java | 7 +++++-- core/src/mindustry/game/SectorInfo.java | 2 ++ core/src/mindustry/game/Universe.java | 11 +++++++++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index d8928a434e..b0db5ef272 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -92,8 +92,8 @@ public class Vars implements Loadable{ public static final float turnDuration = 2 * Time.toMinutes; /** chance of an invasion per turn, 1 = 100% */ public static final float baseInvasionChance = 1f / 100f; - /** how many turns have to pass before invasions start */ - public static final int invasionGracePeriod = 20; + /** how many minutes have to pass before invasions in a *captured* sector start */ + public static final float invasionGracePeriod = 20; /** min armor fraction damage; e.g. 0.05 = at least 5% damage */ public static final float minArmorDamage = 0.1f; /** launch animation duration */ diff --git a/core/src/mindustry/entities/comp/FireComp.java b/core/src/mindustry/entities/comp/FireComp.java index 7981e061b6..89710ebdf1 100644 --- a/core/src/mindustry/entities/comp/FireComp.java +++ b/core/src/mindustry/entities/comp/FireComp.java @@ -10,6 +10,7 @@ import mindustry.entities.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.world.*; +import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -38,13 +39,15 @@ abstract class FireComp implements Timedc, Posc, Firec, Syncc{ control.sound.loop(Sounds.fire, this, 0.07f); } - time = Mathf.clamp(time + Time.delta, 0, lifetime()); + //faster updates -> disappears more quickly + float speedMultiplier = 1f + Math.max(state.envAttrs.get(Attribute.water) * 10f, 0); + time = Mathf.clamp(time + Time.delta * speedMultiplier, 0, lifetime); if(Vars.net.client()){ return; } - if(time >= lifetime() || tile == null){ + if(time >= lifetime || tile == null){ remove(); return; } diff --git a/core/src/mindustry/game/SectorInfo.java b/core/src/mindustry/game/SectorInfo.java index 6a15c50e96..f49225d403 100644 --- a/core/src/mindustry/game/SectorInfo.java +++ b/core/src/mindustry/game/SectorInfo.java @@ -63,6 +63,8 @@ public class SectorInfo{ public int spawnPosition; /** How long the player has been playing elsewhere. */ public float secondsPassed; + /** How many minutes this sector has been captured. */ + public float minutesCaptured; /** Display name. */ public @Nullable String name; /** Displayed icon. */ diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index c8c3702a17..d602f1ec15 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -148,6 +148,13 @@ public class Universe{ for(Sector sector : planet.sectors){ if(sector.hasSave() && sector.hasBase()){ + //if it is being attacked, capture time is 0; otherwise, increment the timer + if(sector.isAttacked()){ + sector.info.minutesCaptured = 0; + }else{ + sector.info.minutesCaptured += turnDuration / 60 / 60; + } + //increment seconds passed for this sector by the time that just passed with this turn if(!sector.isBeingPlayed()){ @@ -216,11 +223,11 @@ public class Universe{ } //queue random invasions - if(!sector.isAttacked() && turn > invasionGracePeriod && sector.info.hasSpawns){ + if(!sector.isAttacked() && sector.info.minutesCaptured > invasionGracePeriod && sector.info.hasSpawns){ int count = sector.near().count(Sector::hasEnemyBase); //invasion chance depends on # of nearby bases - if(count > 0 && Mathf.chance(baseInvasionChance * (0.75f + (count - 1) * 0.3f))){ + if(count > 0 && Mathf.chance(baseInvasionChance * (0.8f + (count - 1) * 0.3f))){ int waveMax = Math.max(sector.info.winWave, sector.isBeingPlayed() ? state.wave : sector.info.wave + sector.info.wavesPassed) + Mathf.random(2, 4) * 5; //assign invasion-related things From 83a4f56679697dcf188c5dbf94d25ac793de6508 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 18 Jan 2021 17:23:16 -0500 Subject: [PATCH 068/426] Fixed #4368 --- core/src/mindustry/world/consumers/ConsumeLiquidFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java index 268cdfaf54..f7a3f99639 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -25,10 +25,10 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{ } @Override - public void build(Building tile, Table table){ + public void build(Building build, Table table){ Seq list = content.liquids().select(l -> !l.isHidden() && filter.get(l)); MultiReqImage image = new MultiReqImage(); - list.each(liquid -> image.add(new ReqImage(liquid.icon(Cicon.medium), () -> tile.liquids != null && tile.liquids.get(liquid) >= use(tile)))); + list.each(liquid -> image.add(new ReqImage(liquid.icon(Cicon.medium), () -> build.liquids != null && build.liquids.get(liquid) >= Math.max(use(build), amount * build.delta())))); table.add(image).size(8 * 4); } From 18a382b07abd9817863e2ec893b1715cb6bf72ba Mon Sep 17 00:00:00 2001 From: genNAowl <68400583+genNAowl@users.noreply.github.com> Date: Mon, 18 Jan 2021 14:34:17 -0800 Subject: [PATCH 069/426] Draw Conveyor Items under Blocks (#4372) * Draw Conveyor Items under Blocks * Remove new layer in favor of subtraction Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com> --- core/src/mindustry/world/blocks/distribution/Conveyor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index 7fb01d9be0..4e59952084 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -127,11 +127,11 @@ public class Conveyor extends Block implements Autotiler{ } } - Draw.z(Layer.block); + Draw.z(Layer.block - 0.2f); Draw.rect(regions[blendbits][frame], x, y, tilesize * blendsclx, tilesize * blendscly, rotation * 90); - Draw.z(Layer.blockOver); + Draw.z(Layer.block - 0.1f); for(int i = 0; i < len; i++){ Item item = ids[i]; From 2da128678a4eaf40e79e21f48c4e0780c5a08af2 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Mon, 18 Jan 2021 14:44:01 -0800 Subject: [PATCH 070/426] Always allow zoom while controlling unit that can't build (#4371) --- core/src/mindustry/input/DesktopInput.java | 2 +- core/src/mindustry/input/MobileInput.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 5c82bd67a3..06e980f7d3 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -251,7 +251,7 @@ public class DesktopInput extends InputHandler{ //zoom camera if((!Core.scene.hasScroll() || Core.input.keyDown(Binding.diagonal_placement)) && !ui.chatfrag.shown() && Math.abs(Core.input.axisTap(Binding.zoom)) > 0 - && !Core.input.keyDown(Binding.rotateplaced) && (Core.input.keyDown(Binding.diagonal_placement) || ((!isPlacing() || !block.rotate) && selectRequests.isEmpty()))){ + && !Core.input.keyDown(Binding.rotateplaced) && (Core.input.keyDown(Binding.diagonal_placement) || ((!player.isBuilder() || !isPlacing() || !block.rotate) && selectRequests.isEmpty()))){ renderer.scaleCamera(Core.input.axisTap(Binding.zoom)); } diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index fb9fdbf86b..2ad24c1e9a 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -652,7 +652,7 @@ public class MobileInput extends InputHandler implements GestureListener{ } //zoom camera - if(Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && !Core.input.keyDown(Binding.rotateplaced) && (Core.input.keyDown(Binding.diagonal_placement) || ((!isPlacing() || !block.rotate) && selectRequests.isEmpty()))){ + if(Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && !Core.input.keyDown(Binding.rotateplaced) && (Core.input.keyDown(Binding.diagonal_placement) || ((!player.isBuilder() || !isPlacing() || !block.rotate) && selectRequests.isEmpty()))){ renderer.scaleCamera(Core.input.axisTap(Binding.zoom)); } From f91910e84f7adb8c4866140ed7001af136ccf678 Mon Sep 17 00:00:00 2001 From: Sunny Kim <58885089+sk7725@users.noreply.github.com> Date: Tue, 19 Jan 2021 07:45:45 +0900 Subject: [PATCH 071/426] conductsTo() returning whether to conduct itself to adjacent builds (#4354) * conductsTo * insulated block no longer conducts * moved both checks to be symmetrical --- core/src/mindustry/entities/comp/BuildingComp.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 1fa2d7c372..f4758c427d 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -778,6 +778,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, } power.links.clear(); } + + public boolean conductsTo(Building other){ + return !block.insulated; + } public Seq getPowerConnections(Seq out){ out.clear(); @@ -786,7 +790,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, for(Building other : proximity){ if(other != null && other.power != null && !(block.consumesPower && other.block.consumesPower && !block.outputsPower && !other.block.outputsPower) - && !power.links.contains(other.pos())){ + && conductsTo(other) && other.conductsTo(self()) && !power.links.contains(other.pos())){ out.add(other); } } From 82f8e78ec88de06135d3522be9a7f1efe8bd5f82 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 18 Jan 2021 18:04:16 -0500 Subject: [PATCH 072/426] Fixed various rounding errors in database --- core/src/mindustry/ui/LiquidDisplay.java | 4 ++-- core/src/mindustry/world/meta/values/AmmoListValue.java | 4 ++-- core/src/mindustry/world/meta/values/BoosterListValue.java | 2 +- core/src/mindustry/world/meta/values/WeaponListValue.java | 2 +- gradle.properties | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/ui/LiquidDisplay.java b/core/src/mindustry/ui/LiquidDisplay.java index c2d71fee25..0a3d7b1716 100644 --- a/core/src/mindustry/ui/LiquidDisplay.java +++ b/core/src/mindustry/ui/LiquidDisplay.java @@ -23,10 +23,10 @@ public class LiquidDisplay extends Table{ if(amount != 0){ Table t = new Table().left().bottom(); - t.add(Strings.autoFixed(amount, 1)).style(Styles.outlineLabel); + t.add(Strings.autoFixed(amount, 2)).style(Styles.outlineLabel); add(t); } - }}).size(8 * 4).padRight(3 + (amount != 0 && Strings.autoFixed(amount, 1).length() > 2 ? 8 : 0)); + }}).size(8 * 4).padRight(3 + (amount != 0 && Strings.autoFixed(amount, 2).length() > 2 ? 8 : 0)); if(perSecond){ add(StatUnit.perSecond.localized()).padLeft(2).padRight(5).color(Color.lightGray).style(Styles.outlineLabel); diff --git a/core/src/mindustry/world/meta/values/AmmoListValue.java b/core/src/mindustry/world/meta/values/AmmoListValue.java index 16c759f110..15db897384 100644 --- a/core/src/mindustry/world/meta/values/AmmoListValue.java +++ b/core/src/mindustry/world/meta/values/AmmoListValue.java @@ -59,11 +59,11 @@ public class AmmoListValue implements StatValue{ } if(!Mathf.equal(type.reloadMultiplier, 1f)){ - sep(bt, Core.bundle.format("bullet.reload", Strings.fixed(type.reloadMultiplier, 1))); + sep(bt, Core.bundle.format("bullet.reload", Strings.autoFixed(type.reloadMultiplier, 2))); } if(type.knockback > 0){ - sep(bt, Core.bundle.format("bullet.knockback", Strings.fixed(type.knockback, 1))); + sep(bt, Core.bundle.format("bullet.knockback", Strings.autoFixed(type.knockback, 2))); } if(type.healPercent > 0f){ diff --git a/core/src/mindustry/world/meta/values/BoosterListValue.java b/core/src/mindustry/world/meta/values/BoosterListValue.java index 8d3315adaa..6f08fc9eac 100644 --- a/core/src/mindustry/world/meta/values/BoosterListValue.java +++ b/core/src/mindustry/world/meta/values/BoosterListValue.java @@ -40,7 +40,7 @@ public class BoosterListValue implements StatValue{ float reloadRate = (baseReload ? 1f : 0f) + maxUsed * multiplier * liquid.heatCapacity; float standardReload = baseReload ? reload : reload / (maxUsed * multiplier * 0.4f); float result = standardReload / (reload / reloadRate); - bt.add(Core.bundle.format("bullet.reload", Strings.fixed(result, 1))); + bt.add(Core.bundle.format("bullet.reload", Strings.autoFixed(result, 2))); }).left().padTop(-9); c.row(); } diff --git a/core/src/mindustry/world/meta/values/WeaponListValue.java b/core/src/mindustry/world/meta/values/WeaponListValue.java index 706077b967..6833837f5c 100644 --- a/core/src/mindustry/world/meta/values/WeaponListValue.java +++ b/core/src/mindustry/world/meta/values/WeaponListValue.java @@ -39,7 +39,7 @@ public class WeaponListValue implements StatValue{ if(weapon.inaccuracy > 0){ sep(w, "[lightgray]" + Stat.inaccuracy.localized() + ": [white]" + (int)weapon.inaccuracy + " " + StatUnit.degrees.localized()); } - sep(w, "[lightgray]" + Stat.reload.localized() + ": " + (weapon.mirror ? "2x " : "") + "[white]" + Strings.autoFixed(60f / weapon.reload * weapon.shots, 1)); + sep(w, "[lightgray]" + Stat.reload.localized() + ": " + (weapon.mirror ? "2x " : "") + "[white]" + Strings.autoFixed(60f / weapon.reload * weapon.shots, 2)); var bullet = new AmmoListValue(OrderedMap.of(unit, weapon.bullet)); bullet.display(w); diff --git a/gradle.properties b/gradle.properties index caeb2227d2..9088d4b5c8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=25dcd2f7664f3c5a669447fdf8dffaea7e65fe0d +archash=08046a31abc93a2628d02e402e98100f2842c72f From 26ad53ec50f04c4c6fe60e0988108a3461b2b553 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Mon, 18 Jan 2021 16:42:47 -0800 Subject: [PATCH 073/426] Tweak highlight on plastanium sprite (#4373) --- .../sprites/items/item-plastanium.png | Bin 324 -> 320 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/core/assets-raw/sprites/items/item-plastanium.png b/core/assets-raw/sprites/items/item-plastanium.png index be27bcfe12ba25cd0dfaba8a15975e21af4a5848..eb5b69d374262a0e69bcc6ea8c7a8c43e5ed299d 100644 GIT binary patch delta 294 zcmX@Ybbx7say=uvr;B4qMC;ordwCBz@VN0NJFv3~@rrsIxPNnaGtn}lsf(?X$tr?b zMP*6wqs@P7_wn6vIXU-lT#fyw&xVQ81-stGKmA=+x*#ji)49Tp$xq{9_sw6Q_t@)i zVKIqpu5X??!>B;lOEEuBQt@)s!9?+v7cJI|Ka1TC$@FY9Qmzk_b+~4zys*yYp=9Sp z&4h=}GsL3aelSc?u~7_tP*ZI(@xp_s+^x*IDvL~4dtV4Tv?}#oqnJ<}Z@F-qiqg)7 z!3R8Cim!C9urGTRyCL#i@Q1wX{S{YN&zS1)U>SpQE)^-QX$gIA z8gD2Ur*LXXsc^kW;9W6c&6793|KFDVqqVX2dz{YkwEgpDMpf*Sz5nueUGbzUPuJv% zUY6Ji&8vm3B=PTy$~k-H&Bt9{LLUwZ{gHM}T6bvg5~mE`3`x^^srOBi+l7yMK0O`T z`G$pS{nP^X$co-0DGsfxg)YP&P-#`1$r1DJ{4$}Jo3G!#+ZZM!Xrq0>i|J*k4YRJw zBDsf(YbH8mE!^)g(INXz_X>Hd?|L`ZP7nR??!s~Lz_l#Q`dk`9IyNE+Dk2st0h2m} z4kj|XGBpM>^{{X)XBFUNQ`Y00q7tz~=Ygljhx#*T>|Tg3-g?hYHJX8efx*+&&t;uc GLK6Vy4SvZ0 From 0061690631f89a28b671e6c614aca07d58d0e14e Mon Sep 17 00:00:00 2001 From: alex <67626131+alexpvpmindustry@users.noreply.github.com> Date: Tue, 19 Jan 2021 08:50:40 +0800 Subject: [PATCH 074/426] Update servers_v6.json (#4342) Adding a fast paced hex for V6. --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index 6b1e4bb38c..a542eba109 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -49,7 +49,7 @@ }, { "name": "ALEX", - "address": ["alexmindustryhub.ddns.net:6568", "alexmindustry.ddns.net:6568", "alexmindustry.ddns.net:6569", "alexmindustryattac.ddns.net:25800","alexmindustryturbo.ddns.net:25854"] + "address": ["alexmindustryhub.ddns.net:6568", "alexmindustry.ddns.net:6568", "alexmindustry.ddns.net:6569", "alexmindustryattac.ddns.net:25800","alexmindustryturbo.ddns.net:25854","alexmindustryhex.ddns.net:25587"] }, { "name": "Minty [subzero]", From 25b22b4f9324afec37096e00322ebf745f41d68d Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 18 Jan 2021 20:17:59 -0500 Subject: [PATCH 075/426] Duplicate IP prevention / Removed overflow inventories --- core/src/mindustry/core/NetServer.java | 2 +- .../mindustry/entities/comp/PlayerComp.java | 4 + core/src/mindustry/ui/dialogs/MapsDialog.java | 1 - .../world/blocks/distribution/Conveyor.java | 6 ++ .../blocks/distribution/OverflowGate.java | 84 +++++-------------- .../world/blocks/distribution/Sorter.java | 5 +- 6 files changed, 31 insertions(+), 71 deletions(-) diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index da801cc454..6a0f2f6bdc 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -182,7 +182,7 @@ public class NetServer implements ApplicationListener{ return; } - if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid))){ + if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid) || player.ip().equals(con.address))){ con.kick(KickReason.idInUse); return; } diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index aababe65e3..914c074d4d 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -197,6 +197,10 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra return unit.isNull() || !unit.isValid(); } + String ip(){ + return con == null ? "localhost" : con.address; + } + String uuid(){ return con == null ? "[LOCAL]" : con.uuid; } diff --git a/core/src/mindustry/ui/dialogs/MapsDialog.java b/core/src/mindustry/ui/dialogs/MapsDialog.java index 605a0bec1c..e0783b7965 100644 --- a/core/src/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/mindustry/ui/dialogs/MapsDialog.java @@ -72,7 +72,6 @@ public class MapsDialog extends BaseDialog{ Map map = MapIO.createMap(file, true); - //when you attempt to import a save, it will have no name, so generate one String name = map.tags.get("name", () -> { String result = "unknown"; diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index 4e59952084..9db976e8a5 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -145,6 +145,12 @@ public class Conveyor extends Block implements Autotiler{ } } + @Override + public void drawCracks(){ + Draw.z(Layer.block - 0.15f); + super.drawCracks(); + } + @Override public void overwrote(Seq builds){ if(builds.first() instanceof ConveyorBuild build){ diff --git a/core/src/mindustry/world/blocks/distribution/OverflowGate.java b/core/src/mindustry/world/blocks/distribution/OverflowGate.java index 1b38cff775..0422c8f583 100644 --- a/core/src/mindustry/world/blocks/distribution/OverflowGate.java +++ b/core/src/mindustry/world/blocks/distribution/OverflowGate.java @@ -8,8 +8,6 @@ import mindustry.type.*; import mindustry.world.*; import mindustry.world.meta.*; -import static mindustry.Vars.*; - public class OverflowGate extends Block{ public float speed = 1f; public boolean invert = false; @@ -23,7 +21,7 @@ public class OverflowGate extends Block{ instantTransfer = true; unloadable = false; canOverdrive = false; - itemCapacity = 1; + itemCapacity = 0; } @Override @@ -32,73 +30,35 @@ public class OverflowGate extends Block{ } public class OverflowGateBuild extends Building{ - public Item lastItem; - public Tile lastInput; - public float time; - - @Override - public int acceptStack(Item item, int amount, Teamc source){ - return 0; - } - - @Override - public int removeStack(Item item, int amount){ - int result = super.removeStack(item, amount); - if(result != 0 && item == lastItem){ - lastItem = null; - } - return result; - } - - @Override - public void updateTile(){ - if(lastItem == null && items.total() > 0){ - items.clear(); - } - - if(lastItem != null){ - if(lastInput == null){ - lastItem = null; - return; - } - - time += 1f / speed * Time.delta; - Building target = getTileTarget(lastItem, lastInput, false); - - if(target != null && (time >= 1f)){ - getTileTarget(lastItem, lastInput, true); - target.handleItem(this, lastItem); - items.remove(lastItem, 1); - lastItem = null; - } - } - } @Override public boolean acceptItem(Building source, Item item){ - return team == source.team && lastItem == null && items.total() == 0; + Building to = getTileTarget(item, source, false); + + return to != null && to.acceptItem(this, item) && to.team == team; } @Override public void handleItem(Building source, Item item){ - items.add(item, 1); - lastItem = item; - time = 0f; - lastInput = source.tile(); + Building target = getTileTarget(item, source, true); + + if(target != null) target.handleItem(this, item); } - public @Nullable Building getTileTarget(Item item, Tile src, boolean flip){ - int from = relativeToEdge(src); + public @Nullable Building getTileTarget(Item item, Building src, boolean flip){ + int from = relativeToEdge(src.tile); if(from == -1) return null; Building to = nearby((from + 2) % 4); - boolean canForward = to != null && to.acceptItem(this, item) && to.team == team && !(to.block instanceof OverflowGate); - boolean inv = invert == enabled; + boolean + fromInst = src.block.instantTransfer, + canForward = to != null && to.acceptItem(this, item) && to.team == team && !(fromInst && to.block.instantTransfer), + inv = invert == enabled; if(!canForward || inv){ Building a = nearby(Mathf.mod(from - 1, 4)); Building b = nearby(Mathf.mod(from + 1, 4)); - boolean ac = a != null && a.acceptItem(this, item) && !(a.block instanceof OverflowGate) && a.team == team; - boolean bc = b != null && b.acceptItem(this, item) && !(b.block instanceof OverflowGate) && b.team == team; + boolean ac = a != null && a.acceptItem(this, item) && !(fromInst && a.block.instantTransfer) && a.team == team; + boolean bc = b != null && b.acceptItem(this, item) && !(fromInst && b.block.instantTransfer) && b.team == team; if(!ac && !bc){ return inv && canForward ? to : null; @@ -124,14 +84,7 @@ public class OverflowGate extends Block{ @Override public byte version(){ - return 3; - } - - @Override - public void write(Writes write){ - super.write(write); - - write.i(lastInput == null ? -1 : lastInput.pos()); + return 4; } @Override @@ -141,9 +94,10 @@ public class OverflowGate extends Block{ if(revision == 1){ new DirectionalItemBuffer(25).read(read); }else if(revision == 3){ - lastInput = world.tile(read.i()); - lastItem = items.first(); + read.i(); } + + items.clear(); } } } diff --git a/core/src/mindustry/world/blocks/distribution/Sorter.java b/core/src/mindustry/world/blocks/distribution/Sorter.java index b76037ee3d..3fe8653f06 100644 --- a/core/src/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/mindustry/world/blocks/distribution/Sorter.java @@ -81,13 +81,10 @@ public class Sorter extends Block{ @Override public void handleItem(Building source, Item item){ - Building to = getTileTarget(item, source, true); - - to.handleItem(this, item); + getTileTarget(item, source, true).handleItem(this, item); } public boolean isSame(Building other){ - // comment code below to allow sorter/gate chaining return other != null && other.block.instantTransfer; } From d06a74e7a224444a4b96e1140c211de03b59e0cc Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 19 Jan 2021 09:58:41 -0500 Subject: [PATCH 076/426] Fixed #4376 --- .../mindustry/world/blocks/distribution/OverflowGate.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/blocks/distribution/OverflowGate.java b/core/src/mindustry/world/blocks/distribution/OverflowGate.java index 0422c8f583..f6c431cb31 100644 --- a/core/src/mindustry/world/blocks/distribution/OverflowGate.java +++ b/core/src/mindustry/world/blocks/distribution/OverflowGate.java @@ -51,14 +51,14 @@ public class OverflowGate extends Block{ Building to = nearby((from + 2) % 4); boolean fromInst = src.block.instantTransfer, - canForward = to != null && to.acceptItem(this, item) && to.team == team && !(fromInst && to.block.instantTransfer), + canForward = to != null && to.team == team && !(fromInst && to.block.instantTransfer) && to.acceptItem(this, item), inv = invert == enabled; if(!canForward || inv){ Building a = nearby(Mathf.mod(from - 1, 4)); Building b = nearby(Mathf.mod(from + 1, 4)); - boolean ac = a != null && a.acceptItem(this, item) && !(fromInst && a.block.instantTransfer) && a.team == team; - boolean bc = b != null && b.acceptItem(this, item) && !(fromInst && b.block.instantTransfer) && b.team == team; + boolean ac = a != null && !(fromInst && a.block.instantTransfer) && a.team == team && a.acceptItem(this, item); + boolean bc = b != null && !(fromInst && b.block.instantTransfer) && b.team == team && b.acceptItem(this, item); if(!ac && !bc){ return inv && canForward ? to : null; From ead0158ef918c36dc572ca32a0de54d81b956980 Mon Sep 17 00:00:00 2001 From: RayanZ22 <70777952+RayanZ22@users.noreply.github.com> Date: Tue, 19 Jan 2021 12:17:08 -0300 Subject: [PATCH 077/426] Update bundle_pt_BR.properties (#3612) update --- core/assets/bundles/bundle_pt_BR.properties | 200 ++++++++++---------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index 0e597d2159..06c293844d 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -341,7 +341,7 @@ waves.waves = Horda(s) waves.perspawn = por spawn waves.shields = Escudo/Horda waves.to = para -waves.guardian = Guardian +waves.guardian = Guardião waves.preview = Pré-visualizar waves.edit = Editar... waves.copy = Copiar para área de transferência @@ -419,9 +419,9 @@ toolmode.drawteams.description = Muda o time do qual o bloco pertence. filters.empty = [lightgray]Sem filtro! Adicione um usando o botão abaixo. filter.distort = Distorcedor filter.noise = Geração aleatória -filter.enemyspawn = Enemy Spawn Select -filter.spawnpath = Path To Spawn -filter.corespawn = Core Select +filter.enemyspawn = Seleção de Spawn do Inimigo +filter.spawnpath = Caminho para o Spawn +filter.corespawn = Seleção de Núcleo filter.median = Medio filter.oremedian = Minério mediano filter.blend = Misturar @@ -475,18 +475,18 @@ locked = Trancado complete = [lightgray]Completo: requirement.wave = Alcançar a Horda {0} em {1} requirement.core = Destruir o núcleo inimigo em {0} -requirement.research = Research {0} +requirement.research = Pesquise {0} requirement.capture = Capture {0} bestwave = [lightgray]Melhor: {0} -launch.text = Launch -research.multiplayer = Only the host can research items. +launch.text = Lançar +research.multiplayer = Apenas o host pode pesquisar itens. uncover = Descobrir configure = Configurar carregamento -loadout = Loadout -resources = Resources +loadout = Carregamento +resources = Recursos bannedblocks = Blocos Banidos addall = Adicionar Todos -launch.destination = Destination: {0} +launch.destination = Destino: {0} configure.invalid = A quantidade deve ser um número entre 0 e {0}. zone.unlocked = [lightgray]{0} Desbloqueado. zone.requirement.complete = Horda {0} alcançada:\n{1} Requerimentos da zona alcançada. @@ -508,49 +508,49 @@ error.io = Erro I/O de internet. error.any = Erro de rede desconhecido. error.bloom = Falha ao inicializar bloom.\nSeu dispositivo talvez não o suporte. -weather.rain.name = Rain -weather.snow.name = Snow -weather.sandstorm.name = Sandstorm -weather.sporestorm.name = Sporestorm -weather.fog.name = Fog +weather.rain.name = Chuva +weather.snow.name = Neve +weather.sandstorm.name = Tempestade de Areia +weather.sporestorm.name = Tempestade de Esporos +weather.fog.name = Névoa -sectors.unexplored = [lightgray]Unexplored -sectors.resources = Resources: -sectors.production = Production: -sectors.stored = Stored: -sectors.resume = Resume -sectors.launch = Launch -sectors.select = Select +sectors.unexplored = [lightgray]Inexplorado +sectors.resources = Recursos: +sectors.production = Produção: +sectors.stored = Armazenado: +sectors.resume = Continuar +sectors.launch = Lançar +sectors.select = Selecione sectors.nonelaunch = [lightgray]none (sun) -sectors.rename = Rename Sector -sector.missingresources = [scarlet]Insufficient Core Resources +sectors.rename = Renomear Setor +sector.missingresources = [scarlet]Recursos Insuficientes no Núcleo planet.serpulo.name = Serpulo -planet.sun.name = Sun +planet.sun.name = Sol -sector.groundZero.name = Ground Zero -sector.craters.name = The Craters -sector.frozenForest.name = Frozen Forest -sector.ruinousShores.name = Ruinous Shores -sector.stainedMountains.name = Stained Mountains -sector.desolateRift.name = Desolate Rift -sector.nuclearComplex.name = Nuclear Production Complex -sector.overgrowth.name = Overgrowth -sector.tarFields.name = Tar Fields -sector.saltFlats.name = Salt Flats -sector.fungalPass.name = Fungal Pass +sector.groundZero.name = Marco Zero +sector.craters.name = As Crateras +sector.frozenForest.name = Floresta Congelada +sector.ruinousShores.name = Costas Ruinosas +sector.stainedMountains.name = Montanhas Manchadas +sector.desolateRift.name = Fenda Desolada +sector.nuclearComplex.name = Complexo de Prodção Nuclear +sector.overgrowth.name = Supercrescimento +sector.tarFields.name = Campos de Piche +sector.saltFlats.name = Planícies de Sal +sector.fungalPass.name = Passagem Fúngica -sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. -sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. -sector.saltFlats.description = On the outskirts of the desert lie the Salt Flats. Few resources can be found in this location.\n\nThe enemy has erected a resource storage complex here. Eradicate their core. Leave nothing standing. -sector.craters.description = Water has accumulated in this crater, relic of the old wars. Reclaim the area. Collect sand. Smelt metaglass. Pump water to cool turrets and drills. -sector.ruinousShores.description = Past the wastes, is the shoreline. Once, this location housed a coastal defense array. Not much of it remains. Only the most basic defense structures have remained unscathed, everything else reduced to scrap.\nContinue the expansion outwards. Rediscover the technology. -sector.stainedMountains.description = Further inland lie the mountains, yet untainted by spores.\nExtract the abundant titanium in this area. Learn how to use it.\n\nThe enemy presence is greater here. Do not give them time to send their strongest units. -sector.overgrowth.description = This area is overgrown, closer to the source of the spores.\nThe enemy has established an outpost here. Build Titan units. Destroy it. Reclaim that which was lost. -sector.tarFields.description = The outskirts of an oil production zone, between the mountains and desert. One of the few areas with usable tar reserves.\nAlthough abandoned, this area has some dangerous enemy forces nearby. Do not underestimate them.\n\n[lightgray]Research oil processing technology if possible. -sector.desolateRift.description = An extremely dangerous zone. Plentiful resources, but little space. High risk of destruction. Leave as soon as possible. Do not be fooled by the long spacing between enemy attacks. -sector.nuclearComplex.description = A former facility for the production and processing of thorium, reduced to ruins.\n[lightgray]Research the thorium and its many uses.\n\nThe enemy is present here in great numbers, constantly scouting for attackers. -sector.fungalPass.description = A transition area between high mountains and lower, spore-ridden lands. A small enemy reconnaissance base is located here.\nDestroy it.\nUse Dagger and Crawler units. Take out the two cores. +sector.groundZero.description = Um lugar bom para recomeçar. Baixa ameaça inimiga. Poucos recursos.\nConsiga o máximo possível de chumbo e cobre.\nContinue. +sector.frozenForest.description = Mesmo aqui, perto das montanhas, os esporos se espalharam. As temperaturas baixas não conseguirão contê-los para sempre.\n\nComeçe a aventura com energia. Construa geradores a combustão. Aprenda a usar reparadores. +sector.saltFlats.description = Nos arredores do deserto ficam as planícies de sal. Muitos recursos podem ser encontrados nesse local.\n\nO inimigo construiu um complexo de armazenamento de recursos aqui. Destrua o núcleo deles. Não deixe nada sobrando. +sector.craters.description = A água se acumulou nessa cratera, relíquias de guerras antigas. Re-conquiste a área. Colete areia. Faça metavidro. Use a água para melhorar suas brocas e torretas. +sector.ruinousShores.description = Passando o terreno desolado, está localizada a costa. Antigamente, este local abrigava uma rede de defesa costeira. Não restou muita coisa. Apenas as estruturas de defesas básicas permaneceram ilesas, o resto foi reduzido a sucata.\nContinue expandindo seus territórios, re-descubra a tecnologia. +sector.stainedMountains.description = Mais para o interior estão as montanhas, ainda não contaminadas pelos esporos.\nExtraia o titânio que é abundante nessa área. Aprenda a usá-lo.\n\nA presença inimiga é maior aqui. Não dê tempo a eles de trazerem fortes unidades. +sector.overgrowth.description = Essa área coberta por vegetação, próxima ao local de origem dos esporos.\nO inimigo estabeleceu um posto de controle aqui. Faça unidades Titan. Destrua eles. Recupere o que foi perdido. +sector.tarFields.description = Nos arredores de uma zone de produção de petróleo, entre as montanhas e o deserto. Uma das poucas áreas com reservas de piche utilizáveis.\nMesmo abandonada, essa área tem forças inimigas por perto. Não subestime-os.\n\n[lightgray]Pesquise a tecnologia de processamento de petróleo se possível. +sector.desolateRift.description = Uma zona extremamente perigosa. Uma zona com recursos abundantes, mas pouco espaço. Grande risco de destruição. Saia o quanto antes. Não se deixe levar pelo tempo entre os ataques inimigos. +sector.nuclearComplex.description = Uma antiga instalação de produção e processamento de tório, reduzida a ruínas.\n[lightgray]Pesquise sobre o tório e seu vários usos.\n\nO inimigo está presente aqui em grande número, constantemente procurando por atacantes. +sector.fungalPass.description = Uma área de transição entre altas montanhas e terras baixas, repletas de esporos. Uma pequena base de reconhecimento inimiga está aqui.\nDestrua o núcleo. settings.language = Idioma settings.data = Dados do jogo @@ -564,30 +564,30 @@ settings.graphics = Gráficos settings.cleardata = Apagar dados settings.clear.confirm = Certeza que quer limpar a os dados?\nOque é feito não pode ser desfeito! settings.clearall.confirm = [scarlet]Aviso![]\nIsso vai limpar todo os arquivos, incluindo jogos salvos, mapas, teclas personalizadas e desbloqueados.\nQuando apertar 'ok' todos os arquivos serão apagados e o jogo irá sair automaticamente. -settings.clearsaves.confirm = Are you sure you want to clear all your saves? -settings.clearsaves = Clear Saves -settings.clearresearch = Clear Research -settings.clearresearch.confirm = Are you sure you want to clear all of your campaign research? -settings.clearcampaignsaves = Clear Campaign Saves -settings.clearcampaignsaves.confirm = Are you sure you want to clear all of your campaign saves? +settings.clearsaves.confirm = Você tem certeza que quer apagar todos os seus saves? +settings.clearsaves = Apagar Saves +settings.clearresearch = Apagar Pesquisas +settings.clearresearch.confirm = Você tem certeza que quer apagar todas as suas pesquisas da campanha? +settings.clearcampaignsaves = Apagar Saves da Campanha +settings.clearcampaignsaves.confirm = Você tem certeza que quer apagar todos os seus saves da campanha? paused = Pausado clear = Limpo banned = [scarlet]BANIDO -unplaceable.sectorcaptured = [scarlet]Requires captured sector +unplaceable.sectorcaptured = [scarlet]Requer captura de setor yes = Sim no = Não info.title = [accent]Informação error.title = [crimson]Ocorreu um Erro. error.crashtitle = Ocorreu um Erro -unit.nobuild = [scarlet]Unit can't build -lastaccessed = [lightgray]Last Accessed: {0} +unit.nobuild = [scarlet]Unidades não podem construir +lastaccessed = [lightgray]Último Acesso: {0} block.unknown = [lightgray]??? stat.input = Entrada stat.output = Saída stat.booster = Apoio stat.tiles = Required Tiles -stat.affinities = Affinities +stat.affinities = Afinidades stat.powercapacity = Capacidade de Energia stat.powershot = Energia/tiro stat.damage = Dano @@ -597,16 +597,16 @@ stat.itemsmoved = Velocidade de movimento stat.launchtime = Tempo entre Disparos. stat.shootrange = Alcance stat.size = Tamanho -stat.displaysize = Display Size +stat.displaysize = Tamanho do Display stat.liquidcapacity = Capacidade de Líquido stat.powerrange = Alcance da Energia -stat.linkrange = Link Range -stat.instructions = Instructions +stat.linkrange = Alcance do Link +stat.instructions = Instruções stat.powerconnections = Conexões Máximas stat.poweruse = Uso de energia stat.powerdamage = Dano/Poder stat.itemcapacity = Capacidade de Itens -stat.memorycapacity = Memory Capacity +stat.memorycapacity = Capacidade de Memória stat.basepowergeneration = Geração de poder base stat.productiontime = Tempo de produção stat.repairtime = Tempo de reparo total do bloco @@ -624,34 +624,34 @@ stat.inaccuracy = Imprecisão stat.shots = Tiros stat.reload = Tempo de recarga stat.ammo = Munição -stat.shieldhealth = Shield Health +stat.shieldhealth = Vida do Escudo stat.cooldowntime = Tempo de espera -stat.explosiveness = Explosiveness -stat.basedeflectchance = Base Deflect Chance +stat.explosiveness = Explosividade +stat.basedeflectchance = Chance Base de Esquiva stat.lightningchance = Lightning Chance -stat.lightningdamage = Lightning Damage -stat.flammability = Flammability -stat.radioactivity = Radioactivity -stat.heatcapacity = HeatCapacity -stat.viscosity = Viscosity -stat.temperature = Temperature -stat.speed = Speed -stat.buildspeed = Build Speed -stat.minespeed = Mine Speed -stat.minetier = Mine Tier -stat.payloadcapacity = Payload Capacity -stat.commandlimit = Command Limit -stat.abilities = Abilities +stat.lightningdamage = Dano por Raio +stat.flammability = Inflamabilidade +stat.radioactivity = Radioatividade +stat.heatcapacity = Capacidade de Aquecimento +stat.viscosity = Viscosidade +stat.temperature = Temperatura +stat.speed = Velocidade +stat.buildspeed = Velocidade de Construção +stat.minespeed = Velocidade de Mineração +stat.minetier = Nível de Mineração +stat.payloadcapacity = Capacidade de Carga +stat.commandlimit = Limite de Comando +stat.abilities = Habilidades -ability.forcefield = Force Field -ability.repairfield = Repair Field +ability.forcefield = Campo de Força +ability.repairfield = Campo de Reparação ability.statusfield = Status Field -ability.unitspawn = {0} Factory -ability.shieldregenfield = Shield Regen Field +ability.unitspawn = {0} Fábrica +ability.shieldregenfield = Raio de Regeneração do Escudo bar.drilltierreq = Broca melhor necessária. -bar.noresources = Missing Resources -bar.corereq = Core Base Required +bar.noresources = Recursos Insuficientes +bar.corereq = Base do Núcleo Necessária bar.drillspeed = Velocidade da Broca: {0}/s bar.pumpspeed = Velocidade da Bomba: {0}/s bar.efficiency = Eficiência: {0}% @@ -659,7 +659,7 @@ bar.powerbalance = Energia: {0} bar.powerstored = Armazenada: {0}/{1} bar.poweramount = Energia: {0} bar.poweroutput = Saída de energia: {0} -bar.powerlines = Connections: {0}/{1} +bar.powerlines = Conexões: {0}/{1} bar.items = Itens: {0} bar.capacity = Capacidade: {0} bar.unitcap = {0} {1}/{2} @@ -669,7 +669,7 @@ bar.heat = Aquecer bar.power = Poder bar.progress = Progresso da construção bar.input = Entrada -bar.output = Sainda +bar.output = Saída units.processorcontrol = [lightgray]Processor Controlled @@ -680,15 +680,15 @@ bullet.homing = [stat]Guiado bullet.shock = [stat]Choque bullet.frag = [stat]Fragmentação bullet.knockback = [stat]{0}[lightgray]Impulso -bullet.pierce = [stat]{0}[lightgray]x pierce -bullet.infinitepierce = [stat]pierce +bullet.pierce = [stat]{0}[lightgray]x perfuração +bullet.infinitepierce = [stat]perfuração bullet.freezing = [stat]Congelamento bullet.tarred = [stat]Grudento bullet.multiplier = [stat]{0}[lightgray]x multiplicador de munição bullet.reload = [stat]{0}[lightgray]x cadência de tiro unit.blocks = Blocos -unit.blockssquared = blocks² +unit.blockssquared = Blocos² unit.powersecond = unidades de energia por segundo unit.liquidsecond = líquido segundo unit.itemssecond = itens por segundo @@ -711,19 +711,19 @@ category.power = Energia category.liquids = Líquidos category.items = Itens category.crafting = Entrada/Saída -category.function = Function +category.function = Função category.optional = Melhoras opcionais setting.landscape.name = Travar panorama setting.shadows.name = Sombras setting.blockreplace.name = Sugestões automáticas de blocos setting.linear.name = Filtragem linear setting.hints.name = Dicas -setting.flow.name = Display Resource Flow Rate[scarlet] (experimental) +setting.flow.name = Mostrar Fluxo de Recursos[scarlet] (experimental) setting.buildautopause.name = Pausar construções automaticamente setting.animatedwater.name = Água animada setting.animatedshields.name = Escudos animados setting.antialias.name = Filtro suavizante[lightgray] (reinicialização requerida)[] -setting.playerindicators.name = Player Indicators +setting.playerindicators.name = Indicador de Jogadores setting.indicators.name = Indicador de aliados/inimigos setting.autotarget.name = Alvo automatico setting.keyboard.name = Controles de mouse e teclado @@ -756,7 +756,7 @@ setting.smoothcamera.name = Suavizar movimentos da câmera setting.vsync.name = VSync setting.pixelate.name = Pixelizado [lightgray](Pode diminuir a performace) setting.minimap.name = Mostrar minimapa -setting.coreitems.name = Display Core Items (WIP) +setting.coreitems.name = Mostrar Itens no Núcleo (WIP) setting.position.name = Mostrar a posição do Jogador setting.musicvol.name = Volume da Música setting.atmosphere.name = Mostrar a atmosfera do planeta @@ -767,7 +767,7 @@ setting.mutesound.name = Desligar Som setting.crashreport.name = Enviar denúncias anônimas de erros setting.savecreate.name = Criar salvamentos automaticamente setting.publichost.name = Visibilidade do jogo público -setting.playerlimit.name = Player Limit +setting.playerlimit.name = Limites de Player setting.chatopacity.name = Opacidade do chat setting.lasersopacity.name = Opacidade do laser setting.bridgeopacity.name = Opacidade da ponte @@ -861,14 +861,14 @@ mode.custom = Regras personalizadas rules.infiniteresources = Recursos infinitos rules.reactorexplosions = Reatores explodem -rules.schematic = Schematics Allowed +rules.schematic = Permitir Esquemas rules.wavetimer = Tempo de horda rules.waves = Hordas rules.attack = Modo de ataque rules.buildai = Habilitar construção da IA rules.enemyCheat = Recursos de IA Infinitos rules.blockhealthmultiplier = Multiplicador de vida do bloco -rules.blockdamagemultiplier = Block Damage Multiplier +rules.blockdamagemultiplier = Multiplicador de dano do bloco rules.unitbuildspeedmultiplier = Multiplicador de velocidade de criação de unidade rules.unithealthmultiplier = Multiplicador de vida de unidade rules.unitdamagemultiplier = Multiplicador de dano de Unidade @@ -887,7 +887,7 @@ rules.title.unit = Unidades rules.title.experimental = Experimental rules.title.environment = Ambiente rules.lighting = Iluminação -rules.enemyLights = Enemy Lights +rules.enemyLights = Iluminação Inimiga rules.fire = Fogo rules.explosions = Dano de explosão de unidades/blocos rules.ambientlight = Luz ambiente @@ -966,9 +966,9 @@ block.salt.name = Sal block.salt-wall.name = Parede de Sal block.pebbles.name = Pedrinhas block.tendrils.name = Gavinhas -block.sand-wall.name = Sand Wall +block.sand-wall.name = Muro de Areia block.spore-pine.name = Pinheiro de esporo -block.spore-wall.name = Spore Wall +block.spore-wall.name = Muro de Esporos block.boulder.name = Rochedo block.snow-boulder.name = Monte de neve block.snow-pine.name = Pinheiro com neve @@ -1105,7 +1105,7 @@ block.wave.name = Onda block.tsunami.name = Tsunami block.swarmer.name = Enxame block.salvo.name = Salvo -block.ripple.name = Morteiro +block.ripple.name = Ondulação block.phase-conveyor.name = Transportador de Fase block.bridge-conveyor.name = Esteira-Ponte block.plastanium-compressor.name = Compressor de Plastânio @@ -1168,7 +1168,7 @@ block.hyper-processor.name = Hiper Processador block.logic-display.name = Monitor Lógico block.large-logic-display.name = Monitor lógico grande block.memory-cell.name = Célula de Memória -block.memory-bank.name = Memory Bank +block.memory-bank.name = Banco de Memória team.blue.name = Azul team.crux.name = Vermelho From 50aab01a2ea9331a7bd14989d3bf5659cee67aa3 Mon Sep 17 00:00:00 2001 From: reNemesic <64527076+reNemesic@users.noreply.github.com> Date: Tue, 19 Jan 2021 16:21:34 +0100 Subject: [PATCH 078/426] Perfecting of bundle_pt-BR [Finished] (#3863) * Update bundle_pt_BR.properties Added sector description [not finished] * Update 2 Finished first translation of sector descriptions (fixes and did the last one) Added some translations for not done entries. * Upgrade #3 Started fixing consistency issues Redid sector descriptions Translated last untranslated elements Co-authored-by: Anuken --- core/assets/bundles/bundle_pt_BR.properties | 141 ++++++++++---------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index 06c293844d..9ecb99f248 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -34,7 +34,7 @@ load.scripts = Scripts be.update = Uma nova versão beta está disponível: be.update.confirm = Baixar e reiniciar o jogo agora? be.updating = Atualizando... -be.ignore = Ignore +be.ignore = Ignorar be.noupdates = Nenhuma atualização encontrada. be.check = Cheque por atualizações @@ -50,7 +50,7 @@ schematic.browseworkshop = Navegar pela oficina schematic.copy = Copiar para a área de transferência schematic.copy.import = Importar da área de transferência schematic.shareworkshop = Compartilhar na Oficina -schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Virar o Esquema +schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Virar o esquema schematic.saved = Esquema salvo. schematic.delete.confirm = Esse esquema será apagado. Tem certeza? schematic.rename = Renomear esquema @@ -71,7 +71,7 @@ map.delete = Certeza que quer deletar o mapa "[accent]{0}[]"? level.highscore = Melhor\npontuação: [accent] {0} level.select = Seleção de fase level.mode = Modo de jogo: -coreattack = < O núcleo está sobre ataque! > +coreattack = < O núcleo está sob ataque! > nearpoint = [[ [scarlet]SAIA DO PONTO DE SPAWN IMEDIATAMENTE[] ]\nANIQUILAÇÃO IMINENTE database = Banco de dados savegame = Salvar jogo @@ -100,7 +100,7 @@ committingchanges = Enviando mudanças done = Feito feature.unsupported = Seu dispositivo não suporta essa função. -mods.alphainfo = Tenha em mente que os mods estão em alpha, e[scarlet] talvez eles contenham erros e instabilidades[].\nReporte quaisquer problemas no Discord ou GitHub do Mindustry. +mods.alphainfo = Lembre-se que o sistema de mods está em alpha, e[scarlet] que eles talvez contenham erros e instabilidades[].\nReporte quaisquer problemas no Discord ou GitHub do Mindustry. mods = Mods mods.none = [lightgray]Nenhum mod encontrado! mods.guide = Guia de mods @@ -133,7 +133,7 @@ mod.remove.confirm = Este mod será deletado. mod.author = [lightgray]Autor:[] {0} mod.missing = Esse jogo salvo foi criado antes de você atualizar ou desinstalar um mod. Pode ocorrer uma corrupção no salvamento. Você tem certeza que quer carregar?\n[lightgray]Mods:\n{0} mod.preview.missing = Antes de publicar esse mod na oficina, você deve adicionar uma imagem de pré-visualização.\nColoque uma imagem com o nome[accent] preview.png[] na pasta do mod e tente novamente. -mod.folder.missing = Somente mods no formato de pasta serão publicados na oficina.\nPara converter qualquer Mod em uma pasta, Simplesmente descompacte seu arquivo numa pasta e delete a compactação antiga, então reinicie seu jogo ou recarregue os mods. +mod.folder.missing = Somente mods no formato de pasta serão publicados na oficina.\nPara converter qualquer Mod em uma pasta, simplesmente descompacte seu arquivo numa pasta e delete o arquivo ZIP antigo, então reinicie seu jogo ou recarregue os mods. mod.scripts.disable = Seu dispositivo não suporta mods com scripts. Você precisa desabilitar esses mods para conseguir jogar. about.button = Sobre @@ -168,11 +168,11 @@ server.kicked.nameInUse = Este nome já está sendo usado\nneste servidor. server.kicked.nameEmpty = Você deve ter pelo menos uma letra ou número no nome. server.kicked.idInUse = Você ja está neste servidor! Conectar com duas contas não é permitido. server.kicked.customClient = Este servidor não suporta versões customizadas. Baixe a versão original. -server.kicked.gameover = Fim de jogo! +server.kicked.gameover = Fim do jogo! server.kicked.serverRestarting = O servidor esta reiniciando. server.versions = Sua versão:[accent] {0}[]\nVersão do servidor:[accent] {1}[] -host.info = O botão de [accent]Hospedar[] hospeda um servidor no Host[scarlet]6567[] e [scarlet]6568.[]\nQualquer um no [lightgray]Wi-fi ou internet local[] pode ver este servidor na lista de servidores.\n\nSe você quer poder entrar em qualquer servidor em seu ip, [accent]port forwarding[] é requerido.\n\n[lightgray]Nota: Se alguém esta com problemas em conectar no seu servidor lan, Tenha certeza que deixou mindustry Acessar sua internet local nas configurações de firewall -join.info = Aqui, você pode entar em um [accent]IP de servidor[] para conectar, ou descobrir [accent]servidores[] da rede local.\nAmbos os servidores LAN e WAN são suportados.\n\n[lightgray]Nota: Não há uma lista de servidores automáticos; Se você quer conectar ao IP de alguém, você precisa pedir o IP ao anfitrião. +host.info = O botão de [accent]Hospedar[] hospeda um servidor no Host[scarlet]6567[] e [scarlet]6568.[]\nQualquer um no [lightgray]Wi-fi ou internet local[] pode ver este servidor na lista de servidores.\n\nSe você quiser poder entrar em qualquer servidor em seu ip, [accent]port forwarding[] é necessário.\n\n[lightgray]Nota: Se alguém está com problemas em conectar no seu servidor lan, tenha certeza que mindustry tem acesso a sua internet local nas configurações do seu firewall +join.info = Aqui, você pode entar em um [accent]IP de servidor[] para conectar, ou descobrir [accent]servidores[] da rede local.\nAmbos os servidores LAN e WAN são suportados.\n\n[lightgray]Nota: Não há uma lista de servidores automáticos; Se você quiser se conectar ao IP de alguém, você precisa pedir o IP ao anfitrião. hostserver = Hospedar servidor invitefriends = Convidar amigos hostserver.mobile = Hospedar\nJogo @@ -272,7 +272,7 @@ data.import = Importar dados data.openfolder = Abrir pasta de dados data.exported = Dados exportados. data.invalid = Estes dados de jogo não são válidos. -data.import.confirm = Importar dados externos irá deletar[scarlet] todos[] os seus dados atuais.\n[accent]Isso não pode ser desfeito![]\n\nQuando sua data é importada, seu jogo ira sair imediatamente. +data.import.confirm = Importar dados externos irá deletar[scarlet] todos[] os seus dados atuais.\n[accent]Isso não pode ser desfeito![]\n\nQuando seus dados serão importados, seu jogo irá sair imediatamente. quit.confirm = Você tem certeza que quer sair? quit.confirm.tutorial = Você tem certeza que você sabe o que você esta fazendo?\nO tutorial pode ser refeito nas [accent] Configurações->Jogo->Refazer Tutorial.[] loading = [accent]Carregando... @@ -298,7 +298,7 @@ saveimage = Salvar\nimagem unknown = Desconhecido custom = Customizado builtin = Padrão -map.delete.confirm = Certeza que quer deletar este mapa? Isto não pode ser desfeito! +map.delete.confirm = Certeza que quer deletar este mapa? Isto não pode ser anulado! map.random = [accent]Mapa aleatório map.nospawn = Este mapa não possui nenhum núcleo para o jogador nascer! Adicione um núcleo[accent] amarelo[] para este mapa no editor. map.nospawn.pvp = Esse mapa não tem núcleos inimigos para os jogadores nascerem! Adicione[scarlet] núcleos vermelhos[] no mapa no editor. @@ -324,7 +324,7 @@ editor.oregen.info = Geração de minério: editor.mapinfo = Informação do mapa editor.author = Autor: editor.description = Descrição: -editor.nodescription = Um mapa deve ter uma descrição de no mínimo 4 caracteres antes de ser publicado. +editor.nodescription = Um mapa deve ter uma descrição de ao mínimo 4 caracteres antes de ser publicado. editor.waves = Hordas: editor.rules = Regras: editor.generation = Geração: @@ -500,7 +500,7 @@ boss.health = Vida do Chefão connectfail = [crimson]Falha ao entrar no servidor: [accent]{0} error.unreachable = Servidor fora de alcance. error.invalidaddress = Endereço inválido. -error.timedout = Desconectado!\nTenha certeza que o anfitrião tenha feito redirecionamento de portas e que o endereço esteja correto! +error.timedout = Desconectado!\nTenha certeza que o anfitrião tenha feito o port forwarding e que o endereço esteja correto! error.mismatch = Erro de pacote:\nPossivel incompatibilidade com a versão do cliente/servidor.\nTenha certeza que você e o anfitrião tenham a última versão! error.alreadyconnected = Já conectado. error.mapnotfound = Arquivo de mapa não encontrado! @@ -521,7 +521,7 @@ sectors.stored = Armazenado: sectors.resume = Continuar sectors.launch = Lançar sectors.select = Selecione -sectors.nonelaunch = [lightgray]none (sun) +sectors.nonelaunch = [lightgray]nenhum (sun) sectors.rename = Renomear Setor sector.missingresources = [scarlet]Recursos Insuficientes no Núcleo @@ -604,7 +604,7 @@ stat.linkrange = Alcance do Link stat.instructions = Instruções stat.powerconnections = Conexões Máximas stat.poweruse = Uso de energia -stat.powerdamage = Dano/Poder +stat.powerdamage = Dano / Poder stat.itemcapacity = Capacidade de Itens stat.memorycapacity = Capacidade de Memória stat.basepowergeneration = Geração de poder base @@ -624,6 +624,7 @@ stat.inaccuracy = Imprecisão stat.shots = Tiros stat.reload = Tempo de recarga stat.ammo = Munição + stat.shieldhealth = Vida do Escudo stat.cooldowntime = Tempo de espera stat.explosiveness = Explosividade @@ -701,7 +702,7 @@ unit.persecond = por segundo unit.perminute = /min unit.timesspeed = x Velocidade unit.percent = % -unit.shieldhealth = shield health +unit.shieldhealth = Saúde do escudo unit.items = itens unit.thousands = k unit.millions = m @@ -773,12 +774,12 @@ setting.lasersopacity.name = Opacidade do laser setting.bridgeopacity.name = Opacidade da ponte setting.playerchat.name = Mostrar chat em jogo public.confirm = Você quer fazer sua partida pública?\n[accent]Qualquer um será capaz de entrar na sua partida.\n[lightgray]Isso pode ser mudado depois em Configurações->Jogo->Visibilidade da partida pública. -public.beta = Note que as versões beta do jogo não podem fazer salas publicas. +public.beta = Note que as versões beta do jogo não podem fazer salas públicas. uiscale.reset = A escala da interface foi mudada.\nPressione "OK" para confirmar esta escala.\n[scarlet]Revertendo e saindo em[accent] {0}[] segundos... uiscale.cancel = Cancelar e sair setting.bloom.name = Bloom keybind.title = Refazer teclas -keybinds.mobile = [scarlet]A maior parte das teclas aqui não são funcionais em dispositivos móveis. Apenas movimento básico é suportado. +keybinds.mobile = [scarlet]A maior parte das teclas aqui não são funcionais em dispositivos móveis. É unicamente suportado movimento básico. category.general.name = Geral category.view.name = Ver category.multiplayer.name = Multijogador @@ -786,7 +787,7 @@ category.blocks.name = Selecionar bloco command.attack = Atacar command.rally = Reunir command.retreat = Recuar -command.idle = Ausente +command.idle = Parado placement.blockselectkeys = \n[lightgray]Tecla: [{0}, keybind.respawn.name = Reaparecer keybind.control.name = Controlar unidade @@ -795,7 +796,7 @@ keybind.press = Pressione uma tecla... keybind.press.axis = Pressione um eixo ou tecla... keybind.screenshot.name = Captura do mapa keybind.toggle_power_lines.name = Mudar lasers -keybind.toggle_block_status.name = Mostrar a propriedade dos blocos +keybind.toggle_block_status.name = Mostrar as propriedades dos blocos keybind.move_x.name = Mover no eixo x keybind.move_y.name = Mover no eixo Y keybind.mouse_move.name = Seguir o Cursor @@ -854,7 +855,7 @@ mode.sandbox.name = Criativo mode.sandbox.description = Recursos infinitos e sem tempo para ataques. mode.editor.name = Editor mode.pvp.name = JxJ -mode.pvp.description = Lutar contra outros jogadores locais. +mode.pvp.description = Luta contra outros jogadores locais. mode.attack.name = Ataque mode.attack.description = Sem hordas, com o objetivo de destruir a base inimiga. mode.custom = Regras personalizadas @@ -872,7 +873,7 @@ rules.blockdamagemultiplier = Multiplicador de dano do bloco rules.unitbuildspeedmultiplier = Multiplicador de velocidade de criação de unidade rules.unithealthmultiplier = Multiplicador de vida de unidade rules.unitdamagemultiplier = Multiplicador de dano de Unidade -rules.enemycorebuildradius = Raio de "Não-criação" de core inimigo:[lightgray] (blocos) +rules.enemycorebuildradius = Raio de "não-criação" de core inimigo:[lightgray] (blocos) rules.wavespacing = Espaço de tempo entre hordas:[lightgray] (seg) rules.buildcostmultiplier = Multiplicador de custo de construção rules.buildspeedmultiplier = Multiplicador de velocidade de construção @@ -909,10 +910,10 @@ item.thorium.name = Tório item.silicon.name = Sílicio item.plastanium.name = Plastânio item.phase-fabric.name = Tecido de fase -item.surge-alloy.name = Liga de surto -item.spore-pod.name = Cápsula de esporos +item.surge-alloy.name = Liga de súrgio +item.spore-pod.name = Pedaço de esporo item.sand.name = Areia -item.blast-compound.name = Composto de explosão +item.blast-compound.name = Composto Explosivo item.pyratite.name = Piratita item.metaglass.name = Metavidro item.scrap.name = Sucata @@ -934,7 +935,7 @@ unit.arkyid.name = Arkyid unit.toxopid.name = Toxopid unit.flare.name = Flare unit.horizon.name = Horizon -unit.zenith.name = Zenith +unit.zenith.name = Zênite unit.antumbra.name = Antumbra unit.eclipse.name = Eclipse unit.mono.name = Mono @@ -950,7 +951,7 @@ unit.omura.name = Omura unit.alpha.name = Alpha unit.beta.name = Beta unit.gamma.name = Gamma -unit.scepter.name = Scepter +unit.scepter.name = Sceptro unit.reign.name = Reign unit.vela.name = Vela unit.corvus.name = Corvus @@ -963,7 +964,7 @@ block.grass.name = Grama block.slag.name = Escória block.space.name = Space block.salt.name = Sal -block.salt-wall.name = Parede de Sal +block.salt-wall.name = Parede de sal block.pebbles.name = Pedrinhas block.tendrils.name = Gavinhas block.sand-wall.name = Muro de Areia @@ -993,8 +994,8 @@ block.core-foundation.name = Fundação do núcleo block.core-nucleus.name = Centro do núcleo block.deepwater.name = Água profunda block.water.name = Água -block.tainted-water.name = Água contaminada -block.darksand-tainted-water.name = Água contaminada sobre areia escura +block.tainted-water.name = Água tinta +block.darksand-tainted-water.name = Água tinta sobre areia escura block.tar.name = Piche block.stone.name = Pedra block.sand.name = Areia @@ -1064,7 +1065,7 @@ block.sorter.name = Ordenador block.inverted-sorter.name = Ordenador invertido block.message.name = Mensagem block.illuminator.name = Iluminador -block.illuminator.description = Uma pequena, compacta e configurável fonte de luz. Precisa de energia para funcionar. +block.illuminator.description = Uma fonte de luz pequena, configurável e compacta. Precisa de energia para funcionar. block.overflow-gate.name = Portão de Fluxo block.underflow-gate.name = Portão de Fluxo invertido block.silicon-smelter.name = Fundidora de silicio @@ -1075,10 +1076,10 @@ block.melter.name = Aparelho de fusão block.incinerator.name = Incinerador block.spore-press.name = Prensa de Esporo block.separator.name = Separador -block.coal-centrifuge.name = Centrífuga de Carvão +block.coal-centrifuge.name = Centrífugador de Carvão block.power-node.name = Célula de energia block.power-node-large.name = Célula de energia grande -block.surge-tower.name = Torre de surto +block.surge-tower.name = Torre de súrgio block.diode.name = Diodo block.battery.name = Bateria block.battery-large.name = Bateria grande @@ -1198,7 +1199,7 @@ tutorial.withdraw = Em algumas situações é necessário pegar itens diretament tutorial.deposit = Deposite itens em blocos arrastando da sua nave até o bloco.\n\n[accent]Deposite seu cobre de volta no núcleo.[] tutorial.waves = O[lightgray] inimigo[] se aproxima.\n\nDefenda seu núcleo por 2 hordas. Construa mais torretas. tutorial.waves.mobile = O[lightgray] inimigo[] se aproxima.\n\nDefenda seu núcleo por 2 hordas. Seu drone vai atirar nos inimigos automaticamente.\nConstrua mais torretas e brocas. Minere mais cobre. -tutorial.launch = Quando você atinge uma horda específica, Você é capaz de[accent] lançar o núcleo[], deixando suas defesas para trás e[accent] obtendo todos os recursos em seu núcleo.[]\nEstes recursos podem ser usados para pesquisar novas tecnologias.\n\n[accent]Pressione o botão lançar. +tutorial.launch = Quando você atinge uma horda específica, você é capaz de[accent] lançar o núcleo[], deixando suas defesas para trás e[accent] obtendo todos os recursos em seu núcleo.[]\nEstes recursos podem ser usados para pesquisar novas tecnologias.\n\n[accent]Pressione o botão lançar. item.copper.description = O material mais básico. Usado em todos os tipos de blocos. item.lead.description = Material de começo basico. usado extensivamente em blocos de transporte de líquidos e eletrônicos. @@ -1221,10 +1222,10 @@ liquid.slag.description = Vários metais derretidos misturados juntos. Pode ser liquid.oil.description = Um líquido usado na produção de materias avançados. Pode ser convertido em carvão como combustível, ou pulverizado e incendiado como arma. liquid.cryofluid.description = A maneira mais eficiente de resfriar qualquer coisa, até seu corpo quando está calor, mas não faça isto. -block.message.description = Armazena uma mensagem. Usado para comunicação entre aliados. +block.message.description = Mostra uma mensagem. Usado para comunicação entre aliados. block.graphite-press.description = Comprime pedaços de carvão em lâminas de grafite puro. block.multi-press.description = Uma versão melhorada da prensa de grafite. Usa água e energia para processar carvão rápida e eficientemente. -block.silicon-smelter.description = Reduz areia a silicio usando carvão puro. Produz silício. +block.silicon-smelter.description = Reduz areia a silício usando carvão puro. Produz silício. block.kiln.description = Derrete chumbo e areia no composto conhecido como metavidro. Requer pequenas quantidades de energia. block.plastanium-compressor.description = Produz plastânio usando petróleo e titânio. block.phase-weaver.description = Produz tecido de fase usando tório radioativo e areia. Requer massivas quantidades de energia para funcionar. @@ -1238,14 +1239,14 @@ block.spore-press.description = Comprime cápsulas de esporos em petróleo. block.pulverizer.description = Esmaga sucata em areia. Util quando esta em falta de areia natural. block.coal-centrifuge.description = Solidifica petróleo em carvão. block.incinerator.description = Se livra de itens em excesso ou liquidos. -block.power-void.description = Destroi qualquer energia que entre dentro. Apenas caixa de areia. -block.power-source.description = Infinitivamente da energia. Apenas caixa de areia. -block.item-source.description = Infinivamente da itens. Apenas caixa de areia. -block.item-void.description = Destroi qualquer item que entre sem requerir energia. Apenas caixa de areia. -block.liquid-source.description = Infinitivamente da Liquidos. Apenas caixa de areia. -block.liquid-void.description = Remove todos os líquidos. Apenas sandbox. -block.copper-wall.description = Um bloco defensivo e barato.\nUtil para proteger o núcleo e torretas no começo. -block.copper-wall-large.description = Um bloco defensivo e barato.\nUtil para proteger o núcleo e torretas no começo.\nOcupa múltiplos blocos. +block.power-void.description = Destroi qualquer energia que entra dentro. Apenas no modo sandbox. +block.power-source.description = Infinitivamente da energia. Apenas no modo sandbox. +block.item-source.description = Infinitamente dá itens. Apenas caixa de areia. +block.item-void.description = Destroi qualquer item que entre sem requerir energia. Apenas no modo sandbox. +block.liquid-source.description = Infinitivamente dá Liquidos. Apenas no modo sanbox. +block.liquid-void.description = Destroi qualquer líquidos que entrar dentro. Apenas no modo sandbox. +block.copper-wall.description = Um bloco defensivo barato.\nUtil para proteger o núcleo e torretas no começo. +block.copper-wall-large.description = Um bloco defensivo barato.\nUtil para proteger o núcleo e torretas no começo.\nOcupa múltiplos blocos. block.titanium-wall.description = Um bloco defensivo moderadamente forte.\nProvidencia defesa moderada contra inimigos. block.titanium-wall-large.description = Um bloco defensivo moderadamente forte.\nProvidencia defesa moderada contra inimigos.\nOcupa múltiplos blocos. block.plastanium-wall.description = Um tipo especial de muro que absorve arcos elétricos e bloqueia conexões automáticas de células de energia. @@ -1253,30 +1254,30 @@ block.plastanium-wall-large.description = Um tipo especial de muro que absorve a block.thorium-wall.description = Um bloco defensivo forte.\nBoa proteção contra inimigos. block.thorium-wall-large.description = Um bloco defensivo forte.\nBoa proteção contra inimigos.\nOcupa múltiplos blocos. block.phase-wall.description = Um muro revestido com um composto especial baseado em tecido de fase. Desvia a maioria das balas no impacto. -block.phase-wall-large.description = Um muro revestido com um composto especial baseado em tecido de fase. Desvia a maioria das balas no impacto.\nOcupa múltiplos blocos. -block.surge-wall.description = Um bloco defensivo extremamente durável.\nSe carrega com eletricidade no contato com as balas, soltando-s aleatoriamente. -block.surge-wall-large.description = Um bloco defensivo extremamente durável.\nSe carrega com eletricidade no contato com as balas, soltando-s aleatoriamente.\nOcupa multiplos blocos. +block.phase-wall-large.description = Um muro revestido com um composto especial baseado em tecido de fase. Desvia a maioria das balas ao impacto.\nOcupa múltiplos blocos. +block.surge-wall.description = Um bloco defensivo extremamente durável.\nSe carrega com eletricidade no contato com as balas, soltando-as aleatoriamente. +block.surge-wall-large.description = Um bloco defensivo extremamente durável.\nSe carrega com eletricidade no contato com as balas, soltando-as aleatoriamente.\nOcupa multiplos blocos. block.door.description = Uma pequeda porta. Pode ser aberta e fechada ao tocar. block.door-large.description = Uma grande porta. Pode ser aberta e fechada ao tocar.\nOcupa múltiplos blocos. -block.mender.description = Periodicamente repara blocos vizinhos. Mantem as defesas reparadas em e entre ondas.\nPode usar silício para aumentar o alcance e a eficiência. -block.mend-projector.description = Uma versão melhorada do reparador. Repara blocos vizinhos.\nPode usar tecido de fase para aumentar o alcance e a eficiência. -block.overdrive-projector.description = Aumenta a velocidade de construções vizinhas.\nPode usar tecido de fase para aumentar o alcance e a eficiência. -block.force-projector.description = Cria um campo de força hexagonal ao redor de si, protegendo construções e unidades.\nSuperaquece se suportar muito dano. Pode usar líquidos para evitar superaquecimento. Pode-se usar tecido de fase para aumentar o tamanho do escudo. +block.mender.description = Periodicamente repara blocos vizinhos. Mantem as defesas reparadas em e entre ondas.\nPode usar silício para aumentar o alcance e a eficácia. +block.mend-projector.description = Uma versão melhorada do reparador. Repara blocos vizinhos.\nPode usar tecido de fase para aumentar o alcance e a eficácia. +block.overdrive-projector.description = Aumenta a velocidade de construções vizinhas.\nPode usar tecido de fase para aumentar o alcance e a eficácia. +block.force-projector.description = Cria um campo de força hexagonal ao redor de si, protegendo construções e unidades.\nAquece demais se o escudo tomar dano. Pode usar líquidos para evitar superaquecimento. Pode-se usar tecido de fase para aumentar o tamanho do escudo. block.shock-mine.description = Danifica inimigos em cima da mina. Quase invisivel ao inimigo. block.conveyor.description = Bloco de transporte de item basico. Move os itens a frente e os deposita automaticamente em torretas ou construtores. Rotacionável. block.titanium-conveyor.description = Bloco de transporte de item avançado. Move itens mais rapidos que esteiras padrões. -block.plastanium-conveyor.description = Moves items in batches.\nAccepts items at the back, and unloads them in three directions at the front. -block.junction.description = Funciona como uma ponte Para duas esteiras que estejam se cruzando. Util em situações que tenha duas esteiras diferentes carregando materiais diferentes para lugares diferentes. +block.plastanium-conveyor.description = Move os itens por grupos.\nRecebe os itens por trás, e despeja eles nas três outras direções. +block.junction.description = Funciona como uma ponte para duas esteiras que estejam se cruzando. Util em situações que tenha duas esteiras separadas carregando materiais diferentes para lugares diferentes. block.bridge-conveyor.description = Bloco de transporte de itens avancado. Possibilita o transporte de itens acima de 3 blocos de construção ou paredes. block.phase-conveyor.description = Bloco de transporte de item avançado. Usa energia para teleportar itens a uma esteira de fase sobre uma severa distancia. block.sorter.description = Filtra itens passando o selecionado para frente e os outros para os lados. block.inverted-sorter.description = Filtra os itens como um ordenador normal, porém, os itens escolhidos sairão pelas laterais. -block.router.description = Aceita itens de uma direção e os divide em 3 direções igualmente. Util para espalhar materiais da fonte para multiplos alvos. -block.distributor.description = Um roteador avançado que espalhas os itens em 7 outras direções igualmente. -block.overflow-gate.description = Uma combinação de roteador e divisor Que apenas manda para a esquerda e Direita se a frente estiver bloqueada. +block.router.description = Aceita itens de uma direção e os divide em 3 direções igualmente. Util para espalhar materiais de uma fonte para multiplos alvos. +block.distributor.description = Um roteador avançado que espalhas os itens em 7 direções igualmente. +block.overflow-gate.description = Uma combinação de roteador e divisor que apenas manda para a esquerda e direita se a frente estiver bloqueada. block.underflow-gate.description = O oposto de um portão de sobrecarga. Manda pra frente se a esquerda e a direita estiverem bloqueadas. block.mass-driver.description = Bloco de transporte de itens supremo. Coleta itens severos e atira eles em outro mass driver de uma longa distancia. -block.mechanical-pump.description = Uma bomba barata com baixa saída de líquidos, mas sem consumo de energia. +block.mechanical-pump.description = Uma bomba barata com baixa saída de líquidos, sem consumo de energia. block.rotary-pump.description = Uma bomba avançada. Bombeia mais líquido, mas requer energia. block.thermal-pump.description = A bomba final. block.conduit.description = Bloco básico de transporte de líquidos. Move líquidos para a frente. Usado em conjunto com bombas e outros canos. @@ -1290,38 +1291,38 @@ block.phase-conduit.description = Bloco avancado de transporte de liquido. Usa e block.power-node.description = Transmite energia para células conectadas. A célula vai receber energia ou alimentar qualquer bloco adjacente. block.power-node-large.description = Uma célula de energia avançada com maior alcance e mais conexões. block.surge-tower.description = Uma célula de energia com um extremo alcance mas com menos conexões disponíveis. -block.diode.description = A energia de baterias pode fluir através desse bloco em apenas uma direção, mas apenas se o outro lado possuir menos energia armazenada. +block.diode.description = A energia de baterias pode fluir através desse bloco em apenas uma direção, mas sómente se o outro lado possuir menos energia armazenada. block.battery.description = Armazena energia em tempos de energia excedente. Libera energia em tempos de déficit. block.battery-large.description = Guarda muito mais energia que uma bateria comum. block.combustion-generator.description = Gera energia queimando materiais inflamáveis, como carvão. block.thermal-generator.description = Gera energia quando colocado em lugares quentes. block.steam-generator.description = Mais eficiente que o gerador à combustão, mas requer água adicional para a geração de vapor. -block.differential-generator.description = Gera grandes quantidades de energia. Utiliza a diferença de temperatura entre o Fluido Criogênico e a Piratita. -block.rtg-generator.description = Um Gerador termoelétrico de radioisótopos que não precisa de refriamento mas dá muito menos energia que o reator de tório. +block.differential-generator.description = Gera grandes quantidades de energia. Utiliza a diferença de temperatura entre o fluido friogênico e a piratita. +block.rtg-generator.description = Um Gerador termoelétrico de radioisótopos que não precisa de resfriamento mas dá muito menos energia que o reator de tório. block.solar-panel.description = Gera pequenas quantidades de energia do sol. block.solar-panel-large.description = Uma versão significantemente mais eficiente que o painel solar padrão. -block.thorium-reactor.description = Gera altas quantidades de energia do torio radioativo. Requer resfriamento constante. Vai explodir violentamente Se resfriamento insuficiente for fornecido. +block.thorium-reactor.description = Gera altas quantidades de energia pelo tório radioativo. Requer resfriamento constante. Explodirá violentamente se o resfriamento for insuficiente. block.impact-reactor.description = Um gerador avançado, capaz de criar quantidades enormes de energia em seu poder total. Requer uma entrada significativa de energia ao iniciar. -block.mechanical-drill.description = Uma broca barata. Quando colocado em blocos apropriados, retira itens em um ritmo lento e indefinitavamente. -block.pneumatic-drill.description = Uma broca improvisada que é mais rápida e capaz de processar materiais mais duros usando a pressão do ar -block.laser-drill.description = Possibilita a mineração ainda mais rapida usando tecnologia a laser, Mas requer poder adcionalmente torio radioativo pode ser recuperado com essa mineradora +block.mechanical-drill.description = Uma broca barata. Quando colocado nos blocos apropriados, retira itens em um ritmo lento, eternamente. +block.pneumatic-drill.description = Uma broca improvisada que é mais rápida e capaz de extrair materiais mais duros usando a pressão do ar. +block.laser-drill.description = Possibilita mineração ainda mais rapida usando tecnologia a laser, mas requer poder adicionalmente. Tório pode ser recuperado com essa mineradora. block.blast-drill.description = A melhor mineradora. Requer muita energia. -block.water-extractor.description = Extrai água subterrânea. Usado em locais sem água superficial disponível. +block.water-extractor.description = Extrai água subterrânea. Usado em locais sem água disponível na superficie. block.cultivator.description = Cultiva pequenas concentrações de esporos na atmosfera em cápsulas prontas. block.oil-extractor.description = Usa altas quantidades de energia para extrair petróleo da areia. Use quando não tiver fontes de petróleo por perto. block.core-shard.description = A primeira iteração do núcleo. Uma vez destruído, todo o contato com a região é perdido. Não deixe isso acontecer. -block.core-foundation.description = A segunda versão do núcleo. Mais bem armadurado. Armazena mais recursos. -block.core-nucleus.description = A terceira e ultima iteração do núcleo. Extremamente bem armadurada. Guarda quantidades massivas de recursos. -block.vault.description = Carrega uma alta quantidade de itens. Usado para criar fontes Quando não tem uma necessidade constante de materiais. Um[lightgray] Descarregador[] pode ser usado para recuperar esses itens do container. -block.container.description = Carrega uma baixa quantidade de itens. Usado para criar fontes Quando não tem uma necessidade constante de materiais. Um[lightgray] Descarregador[] pode ser usado para recuperar esses itens do container. +block.core-foundation.description = A segunda versão do núcleo. Armadurado melhor. Armazena mais recursos. +block.core-nucleus.description = A terceira e última versão do núcleo. Extremamente bem armadurada. Guarda quantidades massivas de recursos. +block.vault.description = Carrega uma alta quantidade de itens. Usado para criar fontes quando não há uma entrada constante de materiais. Um[lightgray] descarregador[] pode ser usado para recuperar esses itens do container. +block.container.description = Guarda uma pequena quantidade de itens. Usado para criar fontes quando não há uma entrada constante de materiais. Um[lightgray] descarregador[] pode ser usado para recuperar esses itens do container. block.unloader.description = Descarrega itens de um container, Descarrega em uma esteira ou diretamente em um bloco adjacente. O tipo de item que pode ser descarregado pode ser mudado clicando no descarregador. block.launch-pad.description = Lança montes de itens sem qualquer necessidade de um lançamento de núcleo. block.launch-pad-large.description = Uma versão melhorada da plataforma de lançamento. Guarda mais itens. Lança mais frequentemente. block.duo.description = Uma pequena torre de baixo custo. Útil contra unidades terrestres. block.scatter.description = Uma torre antiaérea essencial para a defesa. Dispara vários tiros aglomerados de chumbo, sucata ou metavidro. -block.scorch.description = Uma torre que queima qualquer unidade que estiver próxima. Altamente efetivo se for a queima-roupa. +block.scorch.description = Uma torre que queima qualquer unidade que estiver próxima. Altamente efetivo se for de perto. block.hail.description = Uma pequena torre de artilharia com grande alcance. -block.wave.description = Uma torre de tamanho médio. Lança jatos de líquidos nos seus inimigos. Automaticamente apaga incêndios se for abastecido com água ou crio fluido. +block.wave.description = Uma torre de tamanho médio. Lança jatos de líquidos nos seus inimigos. Automaticamente apaga incêndios se for abastecido com água ou fluido criogênico. block.lancer.description = Uma torre laser anti-terrestre média. Carrega e dispara poderosos feixes de energia. block.arc.description = Uma pequena torre elétrica com curto alcance. Dispara arcos de eletricidade nos seus inimigos. block.swarmer.description = Uma torre de mísseis de tamanho médio. Ataca ambos terrestre e aéreo disparando misseis teleguiados. From 68f19fdbcfed0ec4206ede9fa06043a63751bb0a Mon Sep 17 00:00:00 2001 From: Rodrigo <60452545+rodrigolitzius@users.noreply.github.com> Date: Tue, 19 Jan 2021 12:22:11 -0300 Subject: [PATCH 079/426] Update bundle_pt_BR.properties (#4352) Fixed a dumb error --- core/assets/bundles/bundle_pt_BR.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index 9ecb99f248..4317aeb6f1 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -1144,7 +1144,7 @@ block.rtg-generator.name = Gerador GTR block.spectre.name = Espectro block.meltdown.name = Fusão block.foreshadow.name = Foreshadow -block.container.name = Contâiner +block.container.name = Contêiner block.launch-pad.name = Plataforma de lançamento block.launch-pad-large.name = Plataforma de lançamento grande block.segment.name = Segmento From 774be56bde8c21eee6cb7946d5eb8a95377ec3e2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 19 Jan 2021 10:46:33 -0500 Subject: [PATCH 080/426] #4379 --- tests/src/test/java/ApplicationTests.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index a142826e26..d19b617aae 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -5,6 +5,8 @@ import arc.math.*; import arc.math.geom.*; import arc.struct.*; import arc.util.*; +import arc.util.serialization.*; +import arc.util.serialization.JsonValue.*; import mindustry.*; import mindustry.content.*; import mindustry.core.*; @@ -94,6 +96,21 @@ public class ApplicationTests{ state.set(State.menu); } + @Test + void serverListJson(){ + String[] files = {"servers.json", "servers_be.json", "servers_v6.json"}; + + for(String file : files){ + try{ + String str = Core.files.absolute("./../../" + file).readString(); + assertEquals(ValueType.array, new JsonReader().parse(str).type()); + assertTrue(Jval.read(str).isArray()); + }catch(Exception e){ + fail("Failed to parse " + file, e); + } + } + } + @Test void initialization(){ assertNotNull(logic); From 01b24959c88ccaaf4541aeac8abe90c270d3c30f Mon Sep 17 00:00:00 2001 From: Rodrigo <60452545+rodrigolitzius@users.noreply.github.com> Date: Tue, 19 Jan 2021 15:53:56 -0300 Subject: [PATCH 081/426] Typo (#3947) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Í --- core/assets/bundles/bundle_pt_BR.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index 4317aeb6f1..82c7401fcd 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -907,7 +907,7 @@ item.coal.name = Carvão item.graphite.name = Grafite item.titanium.name = Titânio item.thorium.name = Tório -item.silicon.name = Sílicio +item.silicon.name = Silício item.plastanium.name = Plastânio item.phase-fabric.name = Tecido de fase item.surge-alloy.name = Liga de súrgio @@ -1068,7 +1068,7 @@ block.illuminator.name = Iluminador block.illuminator.description = Uma fonte de luz pequena, configurável e compacta. Precisa de energia para funcionar. block.overflow-gate.name = Portão de Fluxo block.underflow-gate.name = Portão de Fluxo invertido -block.silicon-smelter.name = Fundidora de silicio +block.silicon-smelter.name = Fundidora de silício block.phase-weaver.name = Palheta de fase block.pulverizer.name = Pulverizador block.cryofluid-mixer.name = Misturador de Crio Fluido @@ -1229,7 +1229,7 @@ block.silicon-smelter.description = Reduz areia a silício usando carvão puro. block.kiln.description = Derrete chumbo e areia no composto conhecido como metavidro. Requer pequenas quantidades de energia. block.plastanium-compressor.description = Produz plastânio usando petróleo e titânio. block.phase-weaver.description = Produz tecido de fase usando tório radioativo e areia. Requer massivas quantidades de energia para funcionar. -block.alloy-smelter.description = Combina titânio, chumbo, silicio e cobre para produzir liga de surto. +block.alloy-smelter.description = Combina titânio, chumbo, silício e cobre para produzir liga de surto. block.cryofluid-mixer.description = Mistura água e pó fino de titânio para produzir criofluido. Essencial para o uso do reator a tório. block.blast-mixer.description = Quebra e mistura aglomerados de esporos com piratita para produzir composto de explosão. block.pyratite-mixer.description = Mistura carvão, chumbo e areia em piratita altamente inflamável. From 3972e34ddee9bbe818b0be108e884f87b9ec40e8 Mon Sep 17 00:00:00 2001 From: itcannotbe <45280919+itcannotbe@users.noreply.github.com> Date: Wed, 20 Jan 2021 03:37:40 +0800 Subject: [PATCH 082/426] Update bundle.properties (#4375) Remove flowgate limitation in block description. --- core/assets/bundles/bundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 57d9fa6755..f1f22de6dc 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1383,8 +1383,8 @@ block.inverted-sorter.description = Similar to a standard sorter, but outputs se block.router.description = Distributes input items to 3 output directions equally. block.router.details = A necessary evil. Using next to production inputs is not advised, as they will get clogged by output. block.distributor.description = Distributes input items to 7 output directions equally. -block.overflow-gate.description = Only outputs items to the left and right if the front path is blocked. Cannot be used next to other gates. -block.underflow-gate.description = Opposite of an overflow gate. Outputs to the front if the left and right paths are blocked. Cannot be used next to other gates. +block.overflow-gate.description = Only outputs items to the left and right if the front path is blocked. +block.underflow-gate.description = Opposite of an overflow gate. Outputs to the front if the left and right paths are blocked. block.mass-driver.description = Long-range item transport structure. Collects batches of items and shoots them to other mass drivers. block.mechanical-pump.description = Pumps and outputs liquids. Does not require power. block.rotary-pump.description = Pumps and outputs liquids. Requires power. From cd81482b6b666e7a299bf1ffe6f0c11cfc8b030c Mon Sep 17 00:00:00 2001 From: Loumardes <40787527+Loumardes@users.noreply.github.com> Date: Tue, 19 Jan 2021 20:38:11 +0100 Subject: [PATCH 083/426] untranslated mods notification strings (#4347) --- core/assets/bundles/bundle_fr.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index 79de4a4865..c3de632bbd 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -113,7 +113,7 @@ mods.guide = Guide de Modding mods.report = Signaler un Bug mods.openfolder = Ouvrir le dossier des mods mods.reload = Rafraichir -mods.reloadexit = The game will now exit, to reload mods. +mods.reloadexit = Le jeu va maintenant se fermer, pour recharger les mods. mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Activé mod.disabled = [scarlet]Désactivé @@ -133,7 +133,7 @@ mod.reloadrequired = [scarlet]Rechargement requis mod.import = Importer un mod mod.import.file = Importer un fichier mod.import.github = Importer un mod GitHub -mod.jarwarn = [scarlet]JAR mods are inherently unsafe.[]\nMake sure you're importing this mod from a trustworthy source! +mod.jarwarn = [scarlet]Les mods JAR sont fondamentalement peu sûrs.[]\nSoyez certain que vous importez celui ci d'une source de confiance! mod.item.remove = Cet objet fait partie du mod[accent] '{0}'[]. Pour le supprimer, désinstallez le mod en question. mod.remove.confirm = Ce mod sera supprimé. mod.author = [lightgray]Auteur:[] {0} From 4fc805abbfb5a139271bb7a85dd77e0edbd49998 Mon Sep 17 00:00:00 2001 From: Loumardes <40787527+Loumardes@users.noreply.github.com> Date: Tue, 19 Jan 2021 20:38:18 +0100 Subject: [PATCH 084/426] launch core translated to "Lancement du noyau" (#4348) --- core/assets/bundles/bundle_fr.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index c3de632bbd..593320f7e4 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -146,7 +146,7 @@ about.button = À propos name = Nom: noname = Commencez par choisir un[accent] nom de joueur[]. planetmap = Planet Map -launchcore = Launch Core +launchcore = Lancement du Noyau filename = Nom du fichier: unlocked = Nouveau bloc débloqué! completed = [accent]Complété From e3f388692ff88bce899a8ce995872c7dd5a5273f Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 19 Jan 2021 15:13:41 -0500 Subject: [PATCH 085/426] Misc cleanup & fixes --- core/assets/scripts/base.js | 35 +++++++++---------- core/assets/scripts/global.js | 35 +++++++++---------- core/src/mindustry/core/Renderer.java | 3 +- .../src/mindustry/graphics/BlockRenderer.java | 4 +-- core/src/mindustry/graphics/Drawf.java | 16 +++++++++ core/src/mindustry/input/MobileInput.java | 8 +---- core/src/mindustry/mod/Scripts.java | 4 +++ .../world/blocks/payloads/Payload.java | 5 +++ .../world/blocks/payloads/UnitPayload.java | 7 +++- .../blocks/production/PayloadAcceptor.java | 16 +++++---- .../world/blocks/units/Reconstructor.java | 5 ++- 11 files changed, 78 insertions(+), 60 deletions(-) diff --git a/core/assets/scripts/base.js b/core/assets/scripts/base.js index 368ebff42d..d97e6aa8f2 100755 --- a/core/assets/scripts/base.js +++ b/core/assets/scripts/base.js @@ -1,9 +1,10 @@ "use strict"; -function log(context, obj){ - Vars.mods.scripts.log(context, String(obj)) -} +let scriptName = "base.js" +let modName = "none" +const log = (context, obj) => Vars.mods.scripts.log(context, String(obj)) +const print = text => log(modName + "/" + scriptName, text) const readString = path => Vars.mods.scripts.readString(path) const readBytes = path => Vars.mods.scripts.readBytes(path) const loadMusic = path => Vars.mods.scripts.loadMusic(path) @@ -13,11 +14,20 @@ const readFile = (purpose, ext, cons) => Vars.mods.scripts.readFile(purpose, ext const readBinFile = (purpose, ext, cons) => Vars.mods.scripts.readBinFile(purpose, ext, cons); const writeFile = (purpose, ext, str) => Vars.mods.scripts.writeFile(purpose, ext, str); const writeBinFile = (purpose, ext, bytes) => Vars.mods.scripts.writeBinFile(purpose, ext, bytes); +const newFloats = cap => Vars.mods.getScripts().newFloats(cap); -let scriptName = "base.js" -let modName = "none" +//these are not strictly necessary, but are kept for edge cases +const run = method => new java.lang.Runnable(){run: method} +const boolf = method => new Boolf(){get: method} +const boolp = method => new Boolp(){get: method} +const floatf = method => new Floatf(){get: method} +const floatp = method => new Floatp(){get: method} +const cons = method => new Cons(){get: method} +const prov = method => new Prov(){get: method} +const func = method => new Func(){get: method} -const print = text => log(modName + "/" + scriptName, text); +const newEffect = (lifetime, renderer) => new Effect.Effect(lifetime, new Effect.EffectRenderer({render: renderer})) +Call = Packages.mindustry.gen.Call //js 'extend(Base, ..., {})' = java 'new Base(...) {}' function extend(/*Base, ..., def*/){ @@ -39,16 +49,3 @@ function extend(/*Base, ..., def*/){ //For backwards compatibility, use extend instead const extendContent = extend; - -//these are not strictly necessary, but are kept for edge cases -const run = method => new java.lang.Runnable(){run: method} -const boolf = method => new Boolf(){get: method} -const boolp = method => new Boolp(){get: method} -const floatf = method => new Floatf(){get: method} -const floatp = method => new Floatp(){get: method} -const cons = method => new Cons(){get: method} -const prov = method => new Prov(){get: method} -const func = method => new Func(){get: method} - -const newEffect = (lifetime, renderer) => new Effect.Effect(lifetime, new Effect.EffectRenderer({render: renderer})) -Call = Packages.mindustry.gen.Call diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index 92a7fd5562..4e40e985f7 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -2,10 +2,11 @@ "use strict"; -function log(context, obj){ - Vars.mods.scripts.log(context, String(obj)) -} +let scriptName = "base.js" +let modName = "none" +const log = (context, obj) => Vars.mods.scripts.log(context, String(obj)) +const print = text => log(modName + "/" + scriptName, text) const readString = path => Vars.mods.scripts.readString(path) const readBytes = path => Vars.mods.scripts.readBytes(path) const loadMusic = path => Vars.mods.scripts.loadMusic(path) @@ -15,11 +16,20 @@ const readFile = (purpose, ext, cons) => Vars.mods.scripts.readFile(purpose, ext const readBinFile = (purpose, ext, cons) => Vars.mods.scripts.readBinFile(purpose, ext, cons); const writeFile = (purpose, ext, str) => Vars.mods.scripts.writeFile(purpose, ext, str); const writeBinFile = (purpose, ext, bytes) => Vars.mods.scripts.writeBinFile(purpose, ext, bytes); +const newFloats = cap => Vars.mods.getScripts().newFloats(cap); -let scriptName = "base.js" -let modName = "none" +//these are not strictly necessary, but are kept for edge cases +const run = method => new java.lang.Runnable(){run: method} +const boolf = method => new Boolf(){get: method} +const boolp = method => new Boolp(){get: method} +const floatf = method => new Floatf(){get: method} +const floatp = method => new Floatp(){get: method} +const cons = method => new Cons(){get: method} +const prov = method => new Prov(){get: method} +const func = method => new Func(){get: method} -const print = text => log(modName + "/" + scriptName, text); +const newEffect = (lifetime, renderer) => new Effect.Effect(lifetime, new Effect.EffectRenderer({render: renderer})) +Call = Packages.mindustry.gen.Call //js 'extend(Base, ..., {})' = java 'new Base(...) {}' function extend(/*Base, ..., def*/){ @@ -42,19 +52,6 @@ function extend(/*Base, ..., def*/){ //For backwards compatibility, use extend instead const extendContent = extend; -//these are not strictly necessary, but are kept for edge cases -const run = method => new java.lang.Runnable(){run: method} -const boolf = method => new Boolf(){get: method} -const boolp = method => new Boolp(){get: method} -const floatf = method => new Floatf(){get: method} -const floatp = method => new Floatp(){get: method} -const cons = method => new Cons(){get: method} -const prov = method => new Prov(){get: method} -const func = method => new Func(){get: method} - -const newEffect = (lifetime, renderer) => new Effect.Effect(lifetime, new Effect.EffectRenderer({render: renderer})) -Call = Packages.mindustry.gen.Call - importPackage(Packages.arc) importPackage(Packages.arc.func) importPackage(Packages.arc.graphics) diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 7b812f03f9..0e0ac343d4 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -33,7 +33,7 @@ public class Renderer implements ApplicationListener{ public @Nullable Bloom bloom; public FrameBuffer effectBuffer = new FrameBuffer(); - public boolean animateShields, drawWeather = true; + public boolean animateShields, drawWeather = true, drawStatus; /** minZoom = zooming out, maxZoom = zooming in */ public float minZoom = 1.5f, maxZoom = 6f; @@ -81,6 +81,7 @@ public class Renderer implements ApplicationListener{ laserOpacity = settings.getInt("lasersopacity") / 100f; bridgeOpacity = settings.getInt("bridgeopacity") / 100f; animateShields = settings.getBool("animatedshields"); + drawStatus = Core.settings.getBool("blockstatus"); if(landTime > 0){ landTime -= Time.delta; diff --git a/core/src/mindustry/graphics/BlockRenderer.java b/core/src/mindustry/graphics/BlockRenderer.java index 651e1d01d7..072b6e1a98 100644 --- a/core/src/mindustry/graphics/BlockRenderer.java +++ b/core/src/mindustry/graphics/BlockRenderer.java @@ -39,7 +39,6 @@ public class BlockRenderer implements Disposable{ private Seq outArray2 = new Seq<>(); private Seq shadowEvents = new Seq<>(); private IntSet procEntities = new IntSet(), procLinks = new IntSet(), procLights = new IntSet(); - private boolean displayStatus = false; public BlockRenderer(){ @@ -177,7 +176,6 @@ public class BlockRenderer implements Disposable{ /** Process all blocks to draw. */ public void processBlocks(){ - displayStatus = Core.settings.getBool("blockstatus"); int avgx = (int)(camera.position.x / tilesize); int avgy = (int)(camera.position.y / tilesize); @@ -275,7 +273,7 @@ public class BlockRenderer implements Disposable{ Draw.z(Layer.block); } - if(displayStatus && block.consumes.any()){ + if(renderer.drawStatus && block.consumes.any()){ entity.drawStatus(); } } diff --git a/core/src/mindustry/graphics/Drawf.java b/core/src/mindustry/graphics/Drawf.java index b8d1f1e522..83d9065281 100644 --- a/core/src/mindustry/graphics/Drawf.java +++ b/core/src/mindustry/graphics/Drawf.java @@ -17,6 +17,22 @@ import static mindustry.Vars.*; public class Drawf{ + public static void target(float x, float y, float rad, Color color){ + target(x, y, rad, 1, color); + } + + public static void target(float x, float y, float rad, float alpha, Color color){ + Lines.stroke(3f); + Draw.color(Pal.gray, alpha); + Lines.poly(x, y, 4, rad, Time.time * 1.5f); + Lines.spikes(x, y, 3f/7f * rad, 6f/7f * rad, 4, Time.time * 1.5f); + Lines.stroke(1f); + Draw.color(color, alpha); + Lines.poly(x, y, 4, rad, Time.time * 1.5f); + Lines.spikes(x, y, 3f/7f * rad, 6f/7f * rad, 4, Time.time * 1.5f); + Draw.reset(); + } + public static float text(){ float z = Draw.z(); if(renderer.pixelator.enabled()){ diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 2ad24c1e9a..a1ca88635a 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -374,13 +374,7 @@ public class MobileInput extends InputHandler implements GestureListener{ crosshairScale = Mathf.lerpDelta(crosshairScale, 1f, 0.2f); - Draw.color(Pal.remove); - Lines.stroke(1f); - - float radius = Interp.swingIn.apply(crosshairScale); - - Lines.poly(target.getX(), target.getY(), 4, 7f * radius, Time.time * 1.5f); - Lines.spikes(target.getX(), target.getY(), 3f * radius, 6f * radius, 4, Time.time * 1.5f); + Drawf.target(target.getX(), target.getY(), 7f * Interp.swingIn.apply(crosshairScale), Pal.remove); } Draw.reset(); diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index 6ae9631da1..d1faa3433c 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -80,6 +80,10 @@ public class Scripts implements Disposable{ //region utility mod functions + public float[] newFloats(int capacity){ + return new float[capacity]; + } + public String readString(String path){ return Vars.tree.get(path, true).readString(); } diff --git a/core/src/mindustry/world/blocks/payloads/Payload.java b/core/src/mindustry/world/blocks/payloads/Payload.java index 851678094e..afce4b0da4 100644 --- a/core/src/mindustry/world/blocks/payloads/Payload.java +++ b/core/src/mindustry/world/blocks/payloads/Payload.java @@ -32,6 +32,11 @@ public interface Payload{ return size() / tilesize <= s; } + /** @return rotation of this payload. */ + default float rotation(){ + return 0f; + } + /** writes the payload for saving. */ void write(Writes write); diff --git a/core/src/mindustry/world/blocks/payloads/UnitPayload.java b/core/src/mindustry/world/blocks/payloads/UnitPayload.java index cb04b5f36d..c1b5b8a014 100644 --- a/core/src/mindustry/world/blocks/payloads/UnitPayload.java +++ b/core/src/mindustry/world/blocks/payloads/UnitPayload.java @@ -35,7 +35,12 @@ public class UnitPayload implements Payload{ @Override public void set(float x, float y, float rotation){ unit.set(x, y); - unit.rotation(rotation); + unit.rotation = rotation; + } + + @Override + public float rotation(){ + return unit.rotation; } @Override diff --git a/core/src/mindustry/world/blocks/production/PayloadAcceptor.java b/core/src/mindustry/world/blocks/production/PayloadAcceptor.java index 2851d4c27f..df21f8ad6f 100644 --- a/core/src/mindustry/world/blocks/production/PayloadAcceptor.java +++ b/core/src/mindustry/world/blocks/production/PayloadAcceptor.java @@ -14,7 +14,7 @@ import mindustry.world.blocks.payloads.*; import static mindustry.Vars.*; public class PayloadAcceptor extends Block{ - public float payloadSpeed = 0.5f; + public float payloadSpeed = 0.5f, payloadRotateSpeed = 5f; public @Load(value = "@-top", fallback = "factory-top-@size") TextureRegion topRegion; public @Load(value = "@-out", fallback = "factory-out-@size") TextureRegion outRegion; @@ -66,7 +66,7 @@ public class PayloadAcceptor extends Block{ public void handlePayload(Building source, Payload payload){ this.payload = (T)payload; this.payVector.set(source).sub(this).clamp(-size * tilesize / 2f, -size * tilesize / 2f, size * tilesize / 2f, size * tilesize / 2f); - this.payRotation = source.angleTo(this); + this.payRotation = payload.rotation(); updatePayload(); } @@ -115,7 +115,7 @@ public class PayloadAcceptor extends Block{ updatePayload(); - payRotation = Mathf.slerpDelta(payRotation, rotate ? rotdeg() : 90f, 0.3f); + payRotation = Angles.moveToward(payRotation, rotate ? rotdeg() : 90f, payloadRotateSpeed * edelta()); payVector.approach(Vec2.ZERO, payloadSpeed * delta()); return hasArrived(); @@ -126,10 +126,12 @@ public class PayloadAcceptor extends Block{ updatePayload(); - payVector.trns(rotdeg(), payVector.len() + delta() * payloadSpeed); - payRotation = rotdeg(); + Vec2 dest = Tmp.v1.trns(rotdeg(), size* tilesize/2f); - if(payVector.len() >= size * tilesize/2f){ + payRotation = Angles.moveToward(payRotation, rotdeg(), payloadRotateSpeed * edelta()); + payVector.approach(dest, payloadSpeed * delta()); + + if(payVector.within(dest, 0.001f)){ payVector.clamp(-size * tilesize / 2f, -size * tilesize / 2f, size * tilesize / 2f, size * tilesize / 2f); Building front = front(); @@ -155,7 +157,7 @@ public class PayloadAcceptor extends Block{ public void drawPayload(){ if(payload != null){ - payload.set(x + payVector.x, y + payVector.y, payRotation); + updatePayload(); Draw.z(Layer.blockOver); payload.draw(); diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index 849e999059..1521511c15 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -142,13 +142,12 @@ public class Reconstructor extends UnitBlock{ if(constructing() && hasArrived()){ Draw.draw(Layer.blockOver, () -> { Draw.alpha(1f - progress/ constructTime); - Draw.rect(payload.unit.type.icon(Cicon.full), x, y, rotdeg() - 90); + Draw.rect(payload.unit.type.icon(Cicon.full), x, y, payload.rotation() - 90); Draw.reset(); - Drawf.construct(this, upgrade(payload.unit.type), rotdeg() - 90f, progress / constructTime, speedScl, time); + Drawf.construct(this, upgrade(payload.unit.type), payload.rotation() - 90f, progress / constructTime, speedScl, time); }); }else{ Draw.z(Layer.blockOver); - payRotation = rotdeg(); drawPayload(); } From ca62d2aa070bf6783ba3d576f02b6e2cec0aae7a Mon Sep 17 00:00:00 2001 From: Phinner <62483793+Phinner@users.noreply.github.com> Date: Tue, 19 Jan 2021 21:18:38 +0100 Subject: [PATCH 086/426] Rework and Update of the french bundles (Steam and bundle_fr) (#4350) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Complete rework of bundle_fr # Complete rework of bundle_fr ## Overview Hello players. I made a pull in [Mindustry-Suggestions](https://github.com/Anuken/Mindustry-Suggestions/issues/1743) about merging bundle_fr and bundle_fr_be. The cat told he was unable to do that because: > I don't understand either language, so I would be unable to merge the two bundles with any degree of accuracy. This is best discussed and implemented by other speakers of the language(s). So I decided to do that with the help of senri on discord and Voila. There is the updated version of the french bundle for Belgians, Frenchs, Quebecois and everyone else who speaks or learns french ! ## Changes There are the words I changed that you may argue about: ``` FPS -> IPS Raccourci clavier -> Touches Foreshadow -> Présage Mace -> Titan Scepter -> Destructeur Reign -> Eradicateur Lancier -> Perforateur (Its just an idea) Chat -> Tchat Minuterie -> Compte à rebours (Makes more sense for the waves i think) Minimap -> Mini-carte Supporté -> Pas pris en charge (For errors, makes more sense) Hébergeur -> Hôte (the shorter the better) Foreuse à vérin -> foreuse pneumatique (I don't think being super precise might help normal players) Onde -> Vague Percussion -> Percuteur (C'est un nom qui percute !) - Deleted the (e) until the file is reviewed by more people - Made the whole file more coherent, I mean there were upper/lower case letters where it shouldn't be. - Added translations for V6 content like logic blocks, sector description, turrets, units... - Some more stuff I may have forgotten ``` ## Lines to verify in priority There are the lines I was strugulling with ``` 16, 23, 27, 37, 100, 109, 128, 129, 140, 153, 159, 189, 204, 229, 251, 282, 291, 321, 341, 421, 468, 482, 515, 536, [598 -> 613], 703, 705, 715, 751, 777, 1254, 1402 ``` ## conclusion Like I said, I merged fr and fr_be, taking the best translations one by one and translating the missing lines. That would be cool if you look quickly in the file and find some errors I could have made. Thank you for reading and I wish you a good day, or night... * Hotfix * Updated steam translations Updated the achievements and Added the new ones. The only problem I had is the "NEW_ACHIEVEMENT_26_1_DESC", I think there's better translation for that but I'm unable to figure it out for some reasons. Co-authored-by: Anuken --- core/assets/bundles/bundle_fr.properties | 1304 +++++++++------- core/assets/bundles/bundle_fr_BE.properties | 1335 ----------------- .../metadata/steam/french/achievements.vdf | 58 +- .../steam/french/short-description.txt | 2 +- 4 files changed, 768 insertions(+), 1931 deletions(-) delete mode 100644 core/assets/bundles/bundle_fr_BE.properties diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index 593320f7e4..ab44ee3d80 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -1,29 +1,32 @@ -credits.text = Créé par [royal]Anuken[] - [sky]anukendev@gmail.com[]\n\n[gray] +credits.text = Créé par [royal]Anuken[] - [sky]anukendev@gmail.com[] credits = Crédits contributors = Traducteurs et contributeurs -discord = Rejoignez le Discord de Mindustry -link.discord.description = Le discord officiel de Mindustry! -link.reddit.description = Le subreddit de Mindustry +discord = Rejoignez le Discord de Mindustry ! +link.discord.description = Discord officiel de Mindustry +link.reddit.description = Subreddit de Mindustry link.github.description = Code source du jeu link.changelog.description = Liste des mises à jour -link.dev-builds.description = Versions instables du jeu -link.trello.description = Trello officiel pour les ajouts futurs -link.itch.io.description = Page itch.io avec lien de téléchargement pour PC -link.google-play.description = Google Play Store -link.f-droid.description = Catalogue F-Droid -link.wiki.description = Le wiki officiel de Mindustry -link.suggestions.description = Suggérer de nouvelles fonctionnalités -linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copiée dans votre presse-papier. -screenshot = Capture d'écran sauvegardée à {0} -screenshot.invalid = La carte est trop large, il n'y a potentiellement pas assez de mémoire pour la capture d'écran. -gameover = Game over -gameover.pvp = L'équipe [accent] {0}[] a gagné ! +link.dev-builds.description = Versions expérimentale du jeu +link.trello.description = Trello officiel pour les nouvelles fonctionalités planifiées +link.itch.io.description = Page itch.io avec les différentes versions du jeu. +link.google-play.description = Page Google Play du jeu +link.f-droid.description = Page F-Droid du jeu +link.wiki.description = Wiki officiel de Mindustry +link.suggestions.description = Suggérez de nouvelles fonctionallités +link.bug.description = Vous avez trouvé un bug? Reportez le ici +linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre presse-papier. +screenshot = Capture d'écran sauvegardée dans {0} +screenshot.invalid = Carte trop grande, potentiellement pas assez de mémoire pour la capture d'écran. +gameover = Partie terminée +gameover.disconnect = Déconnecté +gameover.pvp = L'équipe[accent] {0}[] a gagnée! +gameover.waiting = [accent]Attente de la nouvelle carte... highscore = [accent]Nouveau meilleur score! copied = Copié. -indev.popup = [accent]v6[] is currently in [accent]alpha[].\n[lightgray]This means:[]\n[scarlet]- The campaign is completely unfinished[]\n- Content is missing\n - Most [scarlet]Unit AI[] does not work properly\n- Many units are unfinished\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[]. -indev.notready = This part of the game isn't ready yet +indev.notready = Cette partie du jeu n'est pas encore prête +indev.campaign = [accent]Félicitations! Vous avez atteint la fin de la campagne![]\n\nC'est ici que le contenu actuel s'arrête. Le voyage interplanétaire sera ajouté dans de futures mises à jour. -load.sound = Sons +load.sound = Son load.map = Cartes load.image = Images load.content = Contenu @@ -31,38 +34,38 @@ load.system = Système load.mod = Mods load.scripts = Scripts -be.update = Une nouvelle version en développement est disponible: -be.update.confirm = Télécharger et Redémarrer le jeu maintenenant ? +be.update = Une nouvelle version expérimentale est disponible: +be.update.confirm = Télécharger et Redémarrer le jeu maintenenant? be.updating = Mise à jour en cours... be.ignore = Ignorer be.noupdates = Aucune mise à jour trouvée. -be.check = Vérifiez les mises à jour +be.check = Chercher des mises à jour -mod.featured.title = Explorateur de mods -mod.featured.dialog.title = Explorateur de Mods +mod.featured.dialog.title = Navigateur de Mods (WIP) mods.browser.selected = Mod sélectionné -mods.browser.add = Installer le mod -mods.github.open = Ouvrir au Github +mods.browser.add = Installer +mods.github.open = Voir schematic = Schéma -schematic.add = Sauvegarder le schéma... +schematic.add = Enregistrer le Schéma... schematics = Schémas -schematic.replace = Un schéma avec ce nom existe déjà. Le remplacer? +schematic.replace = Un schéma avec ce nom existe déjà. Voulez-vous le remplacer ? schematic.exists = Un schéma avec ce nom existe déjà. schematic.import = Importer un schéma... schematic.exportfile = Exporter le fichier schematic.importfile = Importer un fichier schematic.browseworkshop = Consulter le Steam Workshop -schematic.copy = Copier au presse-papier -schematic.copy.import = Importer du presse-papier +schematic.copy = Copier dans le presse-papier +schematic.copy.import = Importer depuis presse-papier schematic.shareworkshop = Partager sur le Steam Workshop schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Retourner le schéma -schematic.saved = Schéma sauvegardé. +schematic.saved = Schéma enregistré. schematic.delete.confirm = Ce schéma sera supprimé définitivement. -schematic.rename = Renommer le schéma +schematic.rename = Renommer le Schéma schematic.info = {0}x{1}, {2} blocs -schematic.disabled = [scarlet]Schematics disabled[]\nYou are not allowed to use schematics on this [accent]map[] or [accent]server. +schematic.disabled = [scarlet] Schémas désactivés![]\nVous n'êtes pas autorisés à utiliser des schémas sur cette [accent]cartemap[] ou ce [accent]serveur. +stats = Stats stat.wave = Vagues vaincues:[accent] {0} stat.enemiesDestroyed = Ennemis détruits:[accent] {0} stat.built = Bâtiments construits:[accent] {0} @@ -72,26 +75,27 @@ stat.delivered = Ressources transférées: stat.playtime = Temps de jeu:[accent] {0} stat.rank = Rang Final: [accent]{0} -globalitems = [accent]Global Items -map.delete = Êtes-vous certain(e) de vouloir supprimer la carte "[accent]{0}[]"? +globalitems = [accent]Ressources globales +map.delete = Êtes-vous sûr de vouloir supprimer cette carte ?"[accent]{0}[]"? level.highscore = Meilleur score: [accent]{0} level.select = Sélection du niveau level.mode = Mode de jeu: -coreattack = [scarlet]< Le noyau est attaquée! > +coreattack = [scarlet]< Le Noyau est attaqué! > nearpoint = [[ [scarlet]QUITTEZ LE POINT D'APPARITION ENNEMI IMMÉDIATEMENT[] ]\nannihilation imminente database = Base de données savegame = Sauvegarder la partie loadgame = Charger la partie -joingame = Rejoindre une partie -customgame = Partie customisée +joingame = Rejoindre la partie +customgame = Partie personnalisée newgame = Nouvelle partie -none = -minimap = Minimap +none = +none.found = [lightgray] +minimap = Mini-carte position = Position close = Fermer website = Site Web quit = Quitter -save.quit = Sauvegarder\net Quitter +save.quit = Sauvegarder & Quitter maps = Cartes maps.browse = Parcourir les cartes continue = Continuer @@ -104,24 +108,24 @@ uploadingcontent = Publication du contenu uploadingpreviewfile = Publication du fichier d'aperçu committingchanges = Validation des modifications done = Fait -feature.unsupported = Votre appareil ne supporte pas cette fonctionnalité. +feature.unsupported = Votre appareil ne prend pas en charge cette fonctionnalité. -mods.alphainfo = Gardez à l'esprit que les mods sont en alpha et[scarlet] peuvent être très buggés[].\nMerci de signaler les problèmes que vous rencontrez via le GitHub ou le Discord Mindustry. +mods.alphainfo = Gardez à l'esprit que les mods sont en alpha et[scarlet] qu'ils peuvent être très buggés[].\nMerci de signaler les problèmes que vous rencontrez via le GitHub de Mindustry. mods = Mods -mods.none = [lightgray]Aucun mod trouvé! +mods.none = [lightgray]Aucun Mod trouvé! mods.guide = Guide de Modding mods.report = Signaler un Bug -mods.openfolder = Ouvrir le dossier des mods -mods.reload = Rafraichir -mods.reloadexit = Le jeu va maintenant se fermer, pour recharger les mods. +mods.openfolder = Ouvrir le Dossier +mods.reload = Relancer +mods.reloadexit = Le jeu va se fermer pour relancer les mods. mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Activé mod.disabled = [scarlet]Désactivé mod.disable = Désactiver mod.content = Contenu: mod.delete.error = Impossible de supprimer le mod. Le fichier est probablement en cours d'utilisation. -mod.requiresversion = [scarlet]Version du jeu requise : [accent]{0} -mod.outdated = [scarlet]Not compatible with V6 (no minGameVersion: 105) +mod.requiresversion = [scarlet]Version minimale du jeu requise : [accent]{0} +mod.outdated = [scarlet]non compatible avec la V6 (no minGameVersion: 105) mod.missingdependencies = [scarlet]Dépendances manquantes: {0} mod.erroredcontent = [scarlet]Erreurs de contenu mod.errors = Des erreurs se sont produites lors du chargement du contenu. @@ -129,34 +133,38 @@ mod.noerrorplay = [scarlet]Vous avez des mods avec des erreurs.[] Désactivez le mod.nowdisabled = [scarlet]Le mod '{0}' a des dépendances manquantes:[accent] {1}\n[lightgray]Ces mods doivent d'abord être téléchargés.\nCe mod sera automatiquement désactivé. mod.enable = Activer mod.requiresrestart = Le jeu va maintenant se fermer pour appliquer les modifications du mod. -mod.reloadrequired = [scarlet]Rechargement requis +mod.reloadrequired = [scarlet]Redémarrage requis mod.import = Importer un mod mod.import.file = Importer un fichier -mod.import.github = Importer un mod GitHub -mod.jarwarn = [scarlet]Les mods JAR sont fondamentalement peu sûrs.[]\nSoyez certain que vous importez celui ci d'une source de confiance! +mod.import.github = Importer un mod depuis GitHub +mod.jarwarn = [scarlet]Les mods JAR sont par nature peu sûrs.[]\nFaites en sorte d'Importer ce mod depuis une source digne de confiance. mod.item.remove = Cet objet fait partie du mod[accent] '{0}'[]. Pour le supprimer, désinstallez le mod en question. mod.remove.confirm = Ce mod sera supprimé. mod.author = [lightgray]Auteur:[] {0} -mod.missing = Cette sauvegarde contient des mods que vous avez récemment mis à jour ou que vous avez désinstallés. Votre sauvegarde risque d'être corrompue. Êtes-vous sûr(e) de vouloir l'importer?\n[lightgray]Mods:\n{0} +mod.missing = Cette sauvegarde contient des mods que vous avez récemment mis à jour ou que vous avez désinstallés. Votre sauvegarde risque d'être corrompue. Êtes-vous sûr de vouloir l'importer?\n[lightgray]Mods:\n{0} mod.preview.missing = Avant de publier ce mod dans le Steam Workshop, vous devez ajouter une image servant d'aperçu.\nPlacez une image nommée[accent] preview.png[] dans le dossier du mod et réessayez. -mod.folder.missing = Seuls les mods sous forme de dossiers peuvent être publiés sur le Steam Workshop.\nPour convertir n'importe quel mod en un dossier, dézippez-le tout simplement dans un dossier et supprimez l'ancien zip, puis redémarrez votre jeu ou rechargez vos mods. -mod.scripts.disable = Votre appareil ne supporte pas les mods avec des scripts. Vous devez désactiver ces mods pour jouer. +mod.folder.missing = Seuls les mods sous forme de dossiers peuvent être publiés sur le Steam Workshop.\nPour convertir n'importe quel mod en un dossier, décompressez-le tout simplement dans un dossier et supprimez l'ancien zip, puis redémarrez votre jeu ou rechargez vos mods. +mod.scripts.disable = Votre appareil ne prend pas an charge les mods avec des scripts. Vous devez désactiver ces mods pour pouvoir jouer. about.button = À propos name = Nom: -noname = Commencez par choisir un[accent] nom de joueur[]. -planetmap = Planet Map -launchcore = Lancement du Noyau +noname = Commencez par choisir un[accent] pseudo[]. +planetmap = Carte de la planète +launchcore = Lancer le Noyau filename = Nom du fichier: -unlocked = Nouveau bloc débloqué! +unlocked = Nouveau contenu débloqué! +available = Nouvelle recherche disponible! completed = [accent]Complété techtree = Arbre technologique +research.legacy = Données de recherche de la [accent]5.0[] trouvées.\nVoulez-vous [accent]charger les données[] ou [accent]les ignorer[] et recommencer la recherche dans la nouvelle campagne? (recommandé) +research.load = Chargement +research.discard = Ignorer research.list = [lightgray]Recherche: research = Rechercher -researched = [lightgray]{0} recherché(e). -research.progress = {0}% complete -players = {0} joueurs en ligne -players.single = {0} joueur en ligne +researched = [lightgray]{0} recherché. +research.progress = {0}% complété +players = {0} joueurs +players.single = {0} joueur players.search = Recherche players.notfound = [gray]Aucun joueur trouvé server.closing = [accent]Fermeture du serveur... @@ -168,113 +176,123 @@ server.kicked.clientOutdated = Client obsolète! Mettez votre jeu à jour! server.kicked.serverOutdated = Serveur obsolète! Demandez à l'hôte de le mettre à jour! server.kicked.banned = Vous avez été banni de ce serveur. server.kicked.typeMismatch = Ce serveur n'est pas compatible avec votre version du jeu. -server.kicked.playerLimit = Ce serveur est plein. Veuillez attendre qu'une place se libère. -server.kicked.recentKick = Vous avez été expulsé récemment.\nAttendez avant de vous connecter à nouveau. +server.kicked.playerLimit = Ce serveur est complet. Attendez qu'une place se libére. +server.kicked.recentKick = Vous avez été expulsé récemment.\nAttendez avant de vous reconnecter. server.kicked.nameInUse = Il y a déjà quelqu'un avec\nce nom sur ce serveur. server.kicked.nameEmpty = Votre nom est invalide. -server.kicked.idInUse = Vous êtes déjà sur ce serveur! Se connecter avec deux comptes n'est pas permis. +server.kicked.idInUse = Vous êtes déjà sur ce serveur! Se connecter avec deux comptes n'est pas permis! server.kicked.customClient = Ce serveur ne supporte pas les versions personnalisées (Custom builds). Téléchargez une version officielle. -server.kicked.gameover = Game over! +server.kicked.gameover = Partie terminée! server.kicked.serverRestarting = Le serveur est en train de redémarrer. server.versions = Votre version:[accent] {0}[]\nVersion du serveur:[accent] {1}[] -host.info = Le bouton [accent]Héberger[] héberge un serveur sur le port [scarlet]6567[]. \nN'importe qui sur le même [lightgray]wifi ou réseau local []devrait voir votre serveur sur sa liste de serveurs.\n\nSi vous voulez que les gens puissent s'y connecter de partout à l'aide de votre IP, [accent]le transfert de port (port forwarding)[] est requis.\n\n[lightgray]Note: Si quelqu'un a des problèmes de connexion à votre partie LAN, vérifiez que vous avez autorisé l'accès à Mindustry sur votre réseau local dans les paramètres de votre pare-feu. -join.info = Ici, vous pouvez entrer [accent]l'adresse IP d'un serveur []pour s'y connecter, ou découvrir un serveur en [accent]réseau local[].\nLe multijoueur en LAN ainsi qu'en WAN est supporté.\n\n[lightgray]Note: Il n'y a pas de liste de serveurs globaux automatiques; Si vous voulez vous connecter à quelqu'un par IP, il faudra d'abord demander à l'hébergeur leur IP. -hostserver = Héberger une partie +host.info = Le bouton [accent]héberger[] héberge un serveur sur le port [scarlet]6567[].\nN'importe qui sur le même [lightgray]réseau wifi ou local[] devrait pouvoir voir votre serveur dans sa liste de serveurs.\n\nSi vous voulez que les gens puissent se connecter de n'importe où grâce à l'IP, [accent]une ouverture des ports[] est requise.\n\n[lightgray]Note: Si quelqu'un éprouve des difficultés à se connecter à votre partie LAN, assurez-vous que vous avez autorisé Mindustry à accéder à votre réseau local dans les paramètres de votre pare-feu. +join.info = Ici, vous pouvez entrer l'[accent]IP d'un serveur[] pour vous y connecter, ou découvrir les serveurs sur votre [accent]réseau local[] ou les serveurs [accent]globaux[].\nLes parties multijoueur LAN et WAN sont toutes deux supportées.\n\n[lightgray]Note: Si vous voulez vous connecter à un serveur par IP, vous devrez demander l'IP à l'hébergeur. Celle-ci peut-être trouvée en recherchant "Mon IP" sur un moteur de recherche depuis son appareil. +hostserver = Héberger une partie multijoueur invitefriends = Inviter des Amis hostserver.mobile = Héberger\nune partie host = Héberger -hosting = [accent]Préparation du serveur... +hosting = [accent]Ouverture du serveur... hosts.refresh = Actualiser hosts.discovering = Recherche de jeux en LAN hosts.discovering.any = Recherche de parties server.refreshing = Actualisation du serveur -hosts.none = [lightgray]Aucun jeu en LAN trouvé! +hosts.none = [lightgray]Aucune partie en LAN trouvée! host.invalid = [scarlet]Impossible de se connecter à l'hôte. servers.local = Serveurs locaux servers.remote = Serveurs distants -servers.global = Serveurs officiels +servers.global = Serveurs communautaires + +servers.disclaimer = Les serveurs communautaires ne sont [accent]pas[] gérés ou controllés par le développeur.\n\nCes serveurs peuvent contenir du contenu qui ne convient pas à tout les âges. +servers.showhidden = Montrer les serveurs cachés +server.shown = Montré +server.hidden = Caché trace = Suivre le joueur trace.playername = Nom du joueur : [accent]{0} trace.ip = IP: [accent]{0} -trace.id = ID Unique : [accent]{0} -trace.mobile = Client mobile: [accent]{0} +trace.id = ID Unique: [accent]{0} +trace.mobile = Client Mobile: [accent]{0} trace.modclient = Client personnalisé: [accent]{0} invalidid = ID du client invalide! Veuillez soumettre un rapport d'erreur. -server.bans = Joueurs Bannis +server.bans = Bans server.bans.none = Aucun joueur banni trouvé! -server.admins = Administrateurs +server.admins = Admins server.admins.none = Aucun administrateur trouvé! server.add = Ajouter un serveur -server.delete = Êtes-vous sûr de vouloir supprimer ce serveur ? +server.delete = Êtes-vous sûr de vouloir supprimer ce serveur? server.edit = Modifier le serveur -server.outdated = [crimson]Serveur obsolète![] -server.outdated.client = [crimson]Client obsolète![] -server.version = [lightgray]Version: {0} {1} +server.outdated = [scarlet]Serveur obsolète![] +server.outdated.client = [scarlet]Client obsolète![] +server.version = [gray]Version: {0} {1} server.custombuild = [accent]Version personnalisée -confirmban = Souhaitez-vous vraiment bannir ce joueur? -confirmkick = Souhaitez-vous vraiment expulser ce joueur? -confirmvotekick = Voulez-vous vraiment voter l'expulsion de ce joueur? -confirmunban = Souhaitez-vous vraiment réintégrer ce joueur ? -confirmadmin = Souhaitez-vous vraiment rendre ce joueur administrateur? -confirmunadmin = Souhaitez-vous vraiment enlever le statut d'administrateur à ce joueur? +confirmban = Êtes-vous sûr de vouloir bannir "{0}[white]"? +confirmkick = Êtes-vous sûr de vouloir expulser "{0}[white]"? +confirmvotekick = Êtes-vous sûr de vouloir voter "{0}[white]"? +confirmunban = Êtes-vous sûr de vouloir annuler le ban de ce joueur? +confirmadmin = Êtes-vous sûr de vouloir faire de "{0}[white]" un administrateur? +confirmunadmin = Êtes-vous sûr de vouloir supprimer le statut d'administrateur de "{0}[white]"? joingame.title = Rejoindre une partie joingame.ip = IP: disconnect = Déconnecté. -disconnect.error = Erreur de connexion. -disconnect.closed = Connexion fermée. +disconnect.error = Un problème est survenu lors de la connection. +disconnect.closed = Connection fermée. disconnect.timeout = Délai de connexion expiré. disconnect.data = Les données du monde n'ont pas pu être chargées! cantconnect = Impossible de rejoindre ([accent]{0}[]). connecting = [accent]Connexion... -connecting.data = [accent]Chargement de la partie... +reconnecting = [accent]Reconnexion... +connecting.data = [accent]Chargement des données du monde... server.port = Port: server.addressinuse = Adresse déjà utilisée! server.invalidport = Numéro de port invalide! -server.error = [crimson]Erreur d'hébergement: [accent]{0} +server.error = [scarlet]Erreur lors de l'hébergement du serveur. save.new = Nouvelle sauvegarde -save.overwrite = Êtes-vous sûr de vouloir\n écraser cette sauvegarde ? +save.overwrite = Êtes-vous sûr de vouloir\nécraser cette sauvegarde ? overwrite = Écraser -save.none = Aucune sauvegarde trouvée ! +save.none = Aucune sauvegarde trouvée! savefail = Échec de la sauvegarde! -save.delete.confirm = Êtes-vous sûr(e) de vouloir supprimer cette sauvegarde? +save.delete.confirm = Êtes-vous sûr de vouloir supprimer cette sauvegarde? save.delete = Supprimer -save.export = Exporter une\nsauvegarde +save.export = Exporter une sauvegarde save.import.invalid = [accent]Cette sauvegarde est invalide! -save.import.fail = [crimson]Échec d'importation: [accent]{0} -save.export.fail = [crimson]Échec d'exportation: [accent]{0} +save.import.fail = [crimson]L'importation de la sauvegarde\na échouée: [accent]{0} +save.export.fail = [crimson]L'exportation de la sauvegarde\na échouée: [accent]{0} save.import = Importer une sauvegarde save.newslot = Nom de la sauvegarde: save.rename = Renommer save.rename.text = Nouveau nom: -selectslot = Choisissez une sauvegarde. +selectslot = Sélectionnez une sauvegarde. slot = [accent]Emplacement {0} editmessage = Modifier le Message -save.corrupted = [accent]Sauvegarde corrompue ou invalide!\nSi vous venez de mettre à jour votre jeu, c'est probablement dû à un changement du format de sauvegarde et [scarlet]pas[] à un bug. +save.corrupted = Fichier de sauvegarde corrompu ou invalide! empty = on = Activé off = Désactivé save.autosave = Sauvegarde automatique: {0} save.map = Carte: {0} save.wave = Vague {0} -save.mode = Mode de jeu: {0} +save.mode = Mode de jeu : {0} save.date = Dernière sauvegarde: {0} save.playtime = Temps de jeu: {0} warning = Avertissement. confirm = Confirmer delete = Supprimer view.workshop = Voir dans le Steam Workshop -workshop.listing = Éditer le listing du Steam Workshop +workshop.listing = Éditer la liste du Steam Workshop ok = OK open = Ouvrir -customize = Personnaliser les règles +customize = Personnaliser cancel = Annuler openlink = Ouvrir le lien copylink = Copier le lien back = Retour +max = Max +crash.export = Exporter les rapports de bugs +crash.none = Aucun rapport de bug trouvé. +crash.exported = Rapports de bugs exportés. data.export = Exporter les données -data.import = Importer les données +data.import = Importer des données data.openfolder = Ouvrir le dossier de données data.exported = Données exportées. data.invalid = Ce ne sont pas des données de jeu valides. @@ -284,11 +302,12 @@ quit.confirm.tutorial = Êtes-vous sur de ce que vous faites?\nLe tutoriel peut loading = [accent]Chargement... reloading = [accent]Rechargement des Mods... saving = [accent]Sauvegarde... -respawn = [accent][[{0}][] pour réapparaitre dans le noyau +respawn = [accent][[{0}][] pour réapparaître dans le Noyau cancelbuilding = [accent][[{0}][] pour effacer le plan -selectschematic = [accent][[{0}][] pour sélectionner et copier +selectschematic = [accent][[{0}][] pour sélectionner+copier pausebuilding = [accent][[{0}][] pour mettre la construction en pause resumebuilding = [scarlet][[{0}][] pour reprendre la construction +showui = Interface cachée.\nPressez [accent][[{0}][] pour montrer l'interface. wave = [accent]Vague {0} wave.cap = [accent]Vague {0}/{1} wave.waiting = [lightgray]Vague dans {0} @@ -296,38 +315,40 @@ wave.waveInProgress = [lightgray]Vague en cours waiting = [lightgray]En attente... waiting.players = En attente de joueurs... wave.enemies = [lightgray]{0} Ennemis restants +wave.enemycores = [accent]{0}[lightgray] Noyaux ennemis +wave.enemycore = [accent]{0}[lightgray] Noyau ennemi wave.enemy = [lightgray]{0} Ennemi restant -wave.guardianwarn = Gardien à l'approche dans [accent]{0}[] vagues. -wave.guardianwarn.one = Gardien à l'approche dans [accent]{0}[] vague. +wave.guardianwarn = Arrivée du Gardien dans [accent]{0}[] vagues. +wave.guardianwarn.one = Arrivée du Gardien dans [accent]{0}[] vague. loadimage = Charger l'image saveimage = Sauvegarder l'image unknown = Inconnu custom = Personnalisé -builtin = Intégré -map.delete.confirm = Voulez-vous vraiment supprimer cette carte? Il n'y aura plus de retour en arrière! +builtin = Pré-fait +map.delete.confirm = Voulez-vous vraiment supprimer cette carte? Il n'y aura pas de retour en arrière! map.random = [accent]Carte aléatoire -map.nospawn = Cette carte n'a pas de base pour qu'un joueur puisse y apparaître! Ajoutez une base[accent] orange[] sur cette carte dans l'éditeur. +map.nospawn = Cette carte ne possède pas de base pour que le joueur puisse apparaître! Ajouter un [royalNoyau orange[] sur cette carte dans l'éditeur. map.nospawn.pvp = Cette carte n'a pas de base ennemie pour qu'un joueur ennemi puisse y apparaître! Ajoutez au moins une base [scarlet] non-orange[] dans l'éditeur. map.nospawn.attack = Cette carte n'a aucune base ennemie à attaquer! Veuillez ajouter une base[scarlet] rouge[] sur cette carte dans l'éditeur. map.invalid = Erreur lors du chargement de la carte: carte corrompue ou invalide. workshop.update = Mettre à jour workshop.error = Erreur lors de la récupération des détails du Steam Workshop: {0} -map.publish.confirm = Êtes-vous sûr(e) de vouloir publier cette carte?\n\n[lightgray]Assurez-vous d’accepter d’abord les CGU du Steam Workshop, sinon vos cartes ne seront pas affichées! +map.publish.confirm = Êtes-vous sûr de vouloir publier cette carte?\n\n[lightgray]Assurez-vous d’accepter d’abord les CGU du Steam Workshop, sinon vos cartes ne seront pas affichées! workshop.menu = Sélectionnez ce que vous souhaitez faire avec cet élément. workshop.info = Infos sur l'élément changelog = Journal des changements (optionnel): eula = CGU de Steam -missing = Cet élément a été supprimé ou déplacé.\n[lightgray]Le listing du Steam Workshop a maintenant été automatiquement dissocié. +missing = Cet élément a été supprimé ou déplacé.\n[lightgray]La liste du Steam Workshop a maintenant été automatiquement dissociée. publishing = [accent]Publication... -publish.confirm = Êtes-vous sûr de vouloir publier ceci ?\n\n[lightgray]Assurez-vous d'être d'abord d'accord avec les CGU du workshop, sinon vos éléments n'apparaîtront pas ! +publish.confirm = Êtes-vous sûr de vouloir publier ceci ?\n\n[lightgray]Assurez-vous d'avoir accepté les CGU du workshop, sinon vos éléments n'apparaîtront pas! publish.error = Erreur de publication de l'élément: {0} -steam.error = Échec d'initialisation des services Steam.\nError: {0} +steam.error = Échec d'initialisation des services Steam.\nErreur: {0} editor.brush = Pinceau editor.openin = Ouvrir dans l'éditeur editor.oregen = Génération de minerais editor.oregen.info = Génération de minerais: -editor.mapinfo = Infos Carte +editor.mapinfo = Infos de la Carte editor.author = Auteur: editor.description = Description: editor.nodescription = Une carte doit avoir une description d'au moins 4 caractères pour pouvoir être publiée. @@ -341,7 +362,6 @@ editor.center = Centrer workshop = Steam Workshop waves.title = Vagues waves.remove = Supprimer -waves.never = waves.every = tous les waves.waves = vague(s) waves.perspawn = par apparition @@ -356,48 +376,49 @@ waves.invalid = Vagues invalides dans le presse-papiers. waves.copied = Vagues copiées waves.none = Aucun ennemi défini.\nNotez que les vagues vides seront automatiquement remplacées par une vague générée par défaut. -wavemode.counts = counts -wavemode.totals = totals -wavemode.health = health +#these are intentionally in lower case +wavemode.counts = compte +wavemode.totals = totaux +wavemode.health = vie editor.default = [lightgray] details = Détails... edit = Modifier... editor.name = Nom: -editor.spawn = Créer l'unité +editor.spawn = Ajouter une unité editor.removeunit = Retirer l'unité -editor.teams = Équipe +editor.teams = Équipes editor.errorload = Erreur lors du chargement du fichier:\n[accent]{0} editor.errorsave = Erreur lors de la sauvegarde du fichier:\n[accent]{0} editor.errorimage = Ceci est une image, et non une carte.\n\nSi vous voulez importer une carte provenant de la version 3.5 (build 40), utilisez le bouton 'importer une carte obsolète (image)' dans l'éditeur. -editor.errorlegacy = Cette carte est trop ancienne, et utilise un format de carte qui n'est plus supporté. +editor.errorlegacy = Cette carte est trop ancienne et utilise un format de carte qui n'est plus pris en charge. editor.errornot = Ceci n'est pas un fichier de carte. -editor.errorheader = Le fichier de carte est invalide ou corrompu. +editor.errorheader = Ce fichier de carte est invalide ou corrompu. editor.errorname = La carte n'a pas de nom. Essayez-vous de charger une sauvegarde? editor.update = Mettre à jour -editor.randomize = Rendre aléatoire +editor.randomize = Randomiser editor.apply = Appliquer editor.generate = Générer editor.resize = Redimensionner editor.loadmap = Charger la carte editor.savemap = Sauvegarder la carte editor.saved = Sauvegardé! -editor.save.noname = Votre carte n'a pas de nom! Ajoutez un nom dans le menu 'info de la carte'. -editor.save.overwrite = Votre carte écrase une carte du jeu de base! Choisissez un nom différent dans le menu 'info de la carte' . -editor.import.exists = [scarlet]Importation impossible :[] '{0}' est le nom d'une carte du jeu de base! -editor.import = Importation... +editor.save.noname = Votre carte n'a pas de nom! Ajoutez un nom dans le menu 'Infos de la Carte' +editor.save.overwrite = Votre carte écrase une carte de base du jeu! Choisissez un nom différent dans le menu 'Infos de la Carte'. +editor.import.exists = [scarlet]Importation impossible :[] '{0}' est le nom d'une carte de base du jeu! +editor.import = Importer editor.importmap = Importer une carte -editor.importmap.description = Importer une carte existante +editor.importmap.description = Importer une carte déjà existante editor.importfile = Importer un fichier editor.importfile.description = Importer une carte externe -editor.importimage = Importer une carte obsolète +editor.importimage = Importer une carte (image) editor.importimage.description = Importer une carte externe (image) -editor.export = Exporter... +editor.export = Exporter editor.exportfile = Exporter un fichier editor.exportfile.description = Exporter un fichier de carte editor.exportimage = Exporter l'image du terrain -editor.exportimage.description = Exporter une image de la carte -editor.loadimage = Importer le terrain +editor.exportimage.description = Exporter une image de la carte avec du terrain seulement +editor.loadimage = Importer un terrain editor.saveimage = Exporter le terrain editor.unsaved = [scarlet]Vous n'avez pas sauvegardé vos modifications![] Voulez-vous vraiment quitter ? editor.resizemap = Redimensionner\nla carte @@ -408,15 +429,15 @@ editor.exists = Une carte avec ce nom existe déjà. editor.selectmap = Sélectionnez une carte: toolmode.replace = Remplacer -toolmode.replace.description = Dessiner seulement sur les blocs solides. +toolmode.replace.description = Dessine seulement sur les blocs solides. toolmode.replaceall = Tout Remplacer toolmode.replaceall.description = Remplace tous les blocs de la carte. toolmode.orthogonal = Orthogonal toolmode.orthogonal.description = Dessine seulement des lignes orthogonales. toolmode.square = Carré toolmode.square.description = Pinceau carré. -toolmode.eraseores = Effacer les minéraux -toolmode.eraseores.description = Efface seulement les minéraux. +toolmode.eraseores = Effacer les minerais +toolmode.eraseores.description = Efface seulement les minerais. toolmode.fillteams = Remplir les équipes toolmode.fillteams.description = Remplit les équipes au lieu des blocs. toolmode.drawteams = Dessiner les équipes @@ -425,39 +446,39 @@ toolmode.drawteams.description = Dessine les équipes au lieu de blocs. filters.empty = [lightgray]Aucun filtre! Ajoutez-en un avec les boutons ci-dessous. filter.distort = Déformation filter.noise = Bruit -filter.enemyspawn = Zone d'apparition enemi -filter.spawnpath = Path To Spawn -filter.corespawn = Zone d'apparition du noyau +filter.enemyspawn = Zone d'apparition enemie +filter.spawnpath = Chemin vers la zone d'apparition +filter.corespawn = Zone d'apparition du Noyau filter.median = Médian filter.oremedian = Minerai Médian filter.blend = Fusion -filter.defaultores = Minerai par défaut +filter.defaultores = Minerais par défaut filter.ore = Minerai -filter.rivernoise = Bruit des rivières +filter.rivernoise = Bruit de rivière filter.mirror = Miroir filter.clear = Effacer filter.option.ignore = Ignorer filter.scatter = Disperser filter.terrain = Terrain -filter.option.scale = Gamme +filter.option.scale = Échelle filter.option.chance = Chance filter.option.mag = Magnitude filter.option.threshold = Seuil -filter.option.circle-scale = Gamme du cercle +filter.option.circle-scale = Échelle circulaire filter.option.octaves = Octaves -filter.option.falloff = Diminution +filter.option.falloff = Détachemment filter.option.angle = Angle filter.option.amount = Quantité filter.option.block = Bloc filter.option.floor = Sol -filter.option.flooronto = Sol en question +filter.option.flooronto = Sol ciblé filter.option.target = Cible filter.option.wall = Mur filter.option.ore = Minerai filter.option.floor2 = Sol secondaire filter.option.threshold2 = Seuil secondaire filter.option.radius = Rayon -filter.option.percentile = Centile +filter.option.percentile = Pourcentage width = Largeur: height = Hauteur: @@ -466,9 +487,11 @@ play = Jouer campaign = Campagne load = Charger save = Sauvegarder -fps = FPS: {0} +fps = IPS: {0} ping = Ping: {0}ms -language.restart = Veuillez redémarrer votre jeu pour que le changement de langue prenne effet. +memory = Mem: {0}mb +memory2 = Mem:\n {0}mb +\n {1}mb +language.restart = Veuillez redémarrez votre jeu pour que le changement de langage prenne effet. settings = Paramètres tutorial = Tutoriel tutorial.retake = Refaire le Tutoriel @@ -481,59 +504,80 @@ locked = Verrouillé complete = [lightgray]Compléter: requirement.wave = Vague {0} dans {1} requirement.core = Détruire le Noyau ennemi dans {0} -requirement.research = Research {0} -requirement.capture = Capture {0} -bestwave = [lightgray]Meilleur: {0} -launch.text = Launch -research.multiplayer = Only the host can research items. +requirement.research = Recherchez {0} +requirement.produce = Produisez {0} +requirement.capture = Capturez {0} +launch.text = Décoller +research.multiplayer = Seul l'hôte peut rechercher des objets. +map.multiplayer = Seul l'hôte peut voir les secteurs. uncover = Découvrir -configure = Modifier les ressources à emporter -loadout = Loadout -resources = Resources -bannedblocks = Blocs Bannis -addall = Ajouter TOUS +configure = Modifier le chargement + +loadout = Chargement +resources = Ressources +bannedblocks = Blocs bannis +addall = Ajouter TOUT +launch.from = Décollage depuis: [accent]{0} launch.destination = Destination: {0} -configure.invalid = Le montant doit être un nombre compris entre 0 et {0}. -zone.unlocked = [lightgray]{0} débloquée. -zone.requirement.complete = Exigences pour {0} complétées:[lightgray]\n{1} -zone.resources = [lightgray]Ressources détectées: -zone.objective = [lightgray]Objectif: [accent]{0} -zone.objective.survival = Survivre -zone.objective.attack = Détruire le noyau ennemi -add = Ajouter... -boss.health = Santé du Boss +configure.invalid = La quantité doit être un nombre compris entre 0 et {0}. +add = Ajouter +boss.health = Santé du Gardien -connectfail = [crimson]Échec de la connexion au serveur :\n\n[accent]{0} -error.unreachable = Serveur injoignable.\nL'adresse IP est-elle correcte? +connectfail = [scarlet]Échec de la connexion au serveur:\n\n[accent]{0} +error.unreachable = Serveur inaccessible.\nEst-ce que l'adresse est écrite correctement? error.invalidaddress = Adresse invalide. -error.timedout = Délai de connexion expiré!\nAssurez-vous que l'hôte a autorisé l'accès au port (port forwarding) et que l'adresse est correcte! -error.mismatch = Erreur de paquet:\nPossible différence de version entre le client et le serveur .\nVérifiez que vous et l'hôte avez la version de Mindustry la plus récente! -error.alreadyconnected = Déjà connecté(e). -error.mapnotfound = Carte introuvable! +error.timedout = Expiration du délai!\nAssurez-vous que l'ouverture des port est configurée chez l'hôte et que l'adresse est correcte! +error.mismatch = Erreur de paquet:\nPossible incompatibilité de version client/serveur.\nAssurez-vous que l'hôte et vous disposez de la dernière version de Mindustry! +error.alreadyconnected = Déjà connecté. +error.mapnotfound = Fichier de carte introuvable ! error.io = Erreur de Réseau (I/O) -error.any = Erreur réseau inconnue -error.bloom = Échec de l'initialisation du flou lumineux.\nVotre appareil peut ne pas le supporter. +error.any = Erreur de réseau inconnue. +error.bloom = Échec de l'initialisation du flou lumineux.\nIl se peut que votre appareil ne le prenne pas en charge. -weather.rain.name = Rain -weather.snow.name = Snow -weather.sandstorm.name = Sandstorm -weather.sporestorm.name = Sporestorm -weather.fog.name = Fog +weather.rain.name = Pluie +weather.snow.name = Neige +weather.sandstorm.name = Tempête de sable +weather.sporestorm.name = Tempête de spores +weather.fog.name = Brouillard -sectors.unexplored = [lightgray]Unexplored -sectors.resources = Resources: +sectors.unexplored = [lightgray]Inexploré +sectors.resources = Ressources: sectors.production = Production: -sectors.stored = Stored: -sectors.resume = Resume -sectors.launch = Launch -sectors.select = Select -sectors.nonelaunch = [lightgray]none (sun) -sectors.rename = Rename Sector -sector.missingresources = [scarlet]Insufficient Core Resources +sectors.export = Exporté: +sectors.time = Temps de jeu: +sectors.threat = Menace: +sectors.wave = Vague: +sectors.stored = Stocké: +sectors.resume = Reprendre +sectors.launch = Décoller +sectors.select = Sélectionner +sectors.nonelaunch = [lightgray]Vide (soleil) +sectors.rename = Renommer le secteur +sectors.enemybase = [scarlet]Base ennemie +sectors.vulnerable = [scarlet]Vulnérable +sectors.underattack = [scarlet]Attaque en cours! [accent]{0}% endommagé +sectors.survives = [accent]Survécu à {0} vagues +sectors.go = Aller +sector.curcapture = Secteur capturé +sector.curlost = Secteur perdu +sector.missingresources = [scarlet]Ressources du Noyau insuffisantes +sector.attacked = Secteur [accent]{0}[white] attaqué! +sector.lost = Secteur [accent]{0}[white] perdu! +#note: the missing space in the line below is intentional +sector.captured = Sector [accent]{0}[white]capturé! + +threat.low = Faible +threat.medium = Normale +threat.high = Grande +threat.extreme = Extrême +threat.eradication = Éradication + +planets = Planètes planet.serpulo.name = Serpulo -planet.sun.name = Sun +planet.sun.name = Soleil +sector.impact0078.name = Impact 0078 sector.groundZero.name = Ground Zero sector.craters.name = The Craters sector.frozenForest.name = Frozen Forest @@ -545,20 +589,29 @@ sector.overgrowth.name = Overgrowth sector.tarFields.name = Tar Fields sector.saltFlats.name = Salt Flats sector.fungalPass.name = Fungal Pass +sector.biomassFacility.name = Biomass Synthesis Facility +sector.windsweptIslands.name = Windswept Islands +sector.extractionOutpost.name = Extraction Outpost +sector.planetaryTerminal.name = Planetary Launch Terminal -sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. -sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. -sector.saltFlats.description = On the outskirts of the desert lie the Salt Flats. Few resources can be found in this location.\n\nThe enemy has erected a resource storage complex here. Eradicate their core. Leave nothing standing. -sector.craters.description = Water has accumulated in this crater, relic of the old wars. Reclaim the area. Collect sand. Smelt metaglass. Pump water to cool turrets and drills. -sector.ruinousShores.description = Past the wastes, is the shoreline. Once, this location housed a coastal defense array. Not much of it remains. Only the most basic defense structures have remained unscathed, everything else reduced to scrap.\nContinue the expansion outwards. Rediscover the technology. -sector.stainedMountains.description = Further inland lie the mountains, yet untainted by spores.\nExtract the abundant titanium in this area. Learn how to use it.\n\nThe enemy presence is greater here. Do not give them time to send their strongest units. -sector.overgrowth.description = This area is overgrown, closer to the source of the spores.\nThe enemy has established an outpost here. Build Titan units. Destroy it. Reclaim that which was lost. -sector.tarFields.description = The outskirts of an oil production zone, between the mountains and desert. One of the few areas with usable tar reserves.\nAlthough abandoned, this area has some dangerous enemy forces nearby. Do not underestimate them.\n\n[lightgray]Research oil processing technology if possible. -sector.desolateRift.description = An extremely dangerous zone. Plentiful resources, but little space. High risk of destruction. Leave as soon as possible. Do not be fooled by the long spacing between enemy attacks. -sector.nuclearComplex.description = A former facility for the production and processing of thorium, reduced to ruins.\n[lightgray]Research the thorium and its many uses.\n\nThe enemy is present here in great numbers, constantly scouting for attackers. -sector.fungalPass.description = A transition area between high mountains and lower, spore-ridden lands. A small enemy reconnaissance base is located here.\nDestroy it.\nUse Dagger and Crawler units. Take out the two cores. +sector.groundZero.description = Un endroit optimal pour commencer. Avec une menace ennemie faible et le peu de ressources disponibles, rassemblez autant de cuivre et de plomb que possible pour continuer votre exploration. +sector.frozenForest.description = Même ici, près des montagnes, les spores se sont propagées. Les températures glaciales ne pourront pas les contenir indéfiniment.\n\nCommencez votre production d'énergie en construisant des générateurs à combustion et apprennez à utiliser les bâtiments de soin. +sector.saltFlats.description = À la périphérie du désert se trouvent les déserts de sel. Peu de ressources s'y trouvent.\n\nLà-bas, l'ennemi a construit un complexe de stockage de ressource. Détruisez leur Noyau et ne laissez rien debout. +sector.craters.description = Ce cratère est une relique d'anciennes guerres. De l'eau s'est accumulée au fond. Prenez le contrôle de la zone.\nCollectez du Sable et faites fondre du Verre trempé. Pompez de l'eau pour refroidir vos tourelles et vos foreuses. +sector.ruinousShores.description = Au-delà des déchets, se trouve le littoral. Autrefois, cet endroit abritait un réseau de défense côtière, mais il n’en reste pas grand-chose. Seules quelques structures de défense basiques sont restées intactes, tout le reste a été réduit en ferraille.\nContinuez votre exploration en redécouvrant la technologie. +sector.stainedMountains.description = Plus loin, à l’intérieur des terres, se trouvent des montagnes qui n'ont pas touchées par les spores.\nExploitez le Titane présent en abondance dans cette zone et apprenez comment l'utiliser.\n\nLa présence ennemie est bien plus grande ici. Ne leur donnez pas le temps d’envoyer leurs unités les plus fortes. +sector.overgrowth.description = Étant plus proche de la source des spores, cette zone a été complètement envahie.\nL'ennemi y a établi un avant-poste. Formez des Titans et détruisez-le. +sector.tarFields.description = La périphérie d’une zone de production de pétrole, situé entre les montagnes et le désert. L’une des rares avec des réserves de goudron utilisables.\nBien qu’abandonnée, cette zone a quelques forces ennemies dangereuses à proximité. Ne les sous-estimez pas!\n\n[lightgray]Recherchez la technologie de traitement de pétrole si possible. +sector.desolateRift.description = Une zone extrêmement dangereuse. Des ressources abondantes, mais peu d’espace. Un risque élevé de destruction donc partez dès que possible! Ne vous laissez surtout pas berner par le long temps d'attente entre les vagues ennemies. Vous risquerez de le regretter. +sector.nuclearComplex.description = Une ancienne installation de production et de traitement de thorium, réduite en ruines.\n[lightgray]Faites des recherches sur le thorium et ses nombreuses utilisations.\n\nL’ennemi est présent ici en grand nombre, recherchant constamment des attaquants. +sector.fungalPass.description = Une zone de transition entre les hautes montagnes et les terres plus basses, infestées de spores. Une petite base de reconnaissance ennemie se trouve ici.\nDétruisez les 2 Noyaux ennemis en utilisant des Poingnards et des Rampeurs. +sector.biomassFacility.description = L’origine des spores. Il s’agit de l’installation dans laquelle elles ont été étudiées et initialement produites.\nRecherchez la technologie présente sur les lieux et cultivez des spores pour la production de carburant et de plastique.\n\n[lightgray]Lors de la destruction de cette installation, les spores ont été libérées. Rien dans l’écosystème local ne pouvait concurrencer un organisme aussi envahissant. +sector.windsweptIslands.description = Au delà du rivage se trouve cette chaîne d’îles reculées. Les registres montrent qu’il y avait autrefois des usines de [accent]Plastanium[].\n\nDéfendez-vous contre les unités navales ennemies, établissez-y une base et faites des recherches sur ces usines. +sector.extractionOutpost.description = Un avant-poste éloigné, construit par l’ennemi dans le but de transférer des ressources vers d’autres secteurs.\n\nCette technologie de transport inter-secteur est essentielle pour de nouvelles conquêtes. Détruisez la base et recherchez leurs Rampes de lancement. +sector.impact0078.description = Ici reposent les vestiges d'un vaisseau de transport interstellaire, premier à être rentré dans ce système.\n\nRécuperez et recherchez autant de technologies que possible dans cette épave. +sector.planetaryTerminal.description = La cible finale.\n\nCette base côtière contient une structure capable de lancer des Noyaux sur les planètes voisines. Elle est extrêmement bien gardée.\n\nProduisez des unités navales, éliminez l’ennemi le plus rapidement possible et recherchez la structure de lancement. -settings.language = Langue +settings.language = Language settings.data = Données du Jeu settings.reset = Valeurs par Défaut settings.rebind = Réattribuer @@ -568,34 +621,34 @@ settings.game = Jeu settings.sound = Son settings.graphics = Graphismes settings.cleardata = Effacer les données du jeu... -settings.clear.confirm = Êtes-vous sûr d'effacer ces données ?\nAucun retour en arrière n'est possible! -settings.clearall.confirm = [scarlet]ATTENTION![]\nCette action effacera toutes les données, y compris les sauvegardes, les cartes, la progression et la configuration des touches.\nUne fois que vous aurez pressé 'OK' le jeu effacera TOUTES les données et se fermera. -settings.clearsaves.confirm = Are you sure you want to clear all your saves? -settings.clearsaves = Clear Saves -settings.clearresearch = Clear Research -settings.clearresearch.confirm = Are you sure you want to clear all of your campaign research? -settings.clearcampaignsaves = Clear Campaign Saves -settings.clearcampaignsaves.confirm = Are you sure you want to clear all of your campaign saves? +settings.clear.confirm = Êtes-vous sûr de vouloir effacer ces données?\nAucun retour en arrière n'est possible! +settings.clearall.confirm = [scarlet]ATTENTION![]\nCette action effacera toutes les données, y compris les sauvegardes, les cartes, la progression et la configuration des touches.\nUne fois que vous aurez pressé 'OK', le jeu effacera TOUTES les données et se fermera. +settings.clearsaves.confirm = Êtes-vous sûr de vouloir supprimer toutes vos sauvegardes? +settings.clearsaves = Supprimer les Sauvegardes +settings.clearresearch = Supprimer la Recherche +settings.clearresearch.confirm = Êtes-vous sûr de vouloir supprimer toutes les recherches de la campagne? +settings.clearcampaignsaves = Supprimer la Campagne +settings.clearcampaignsaves.confirm = Êtes-vous sûr de vouloir supprimer toutes les sauvegardes de la campagne? paused = [accent]< Pause > clear = Effacer banned = [scarlet]Bannis -unplaceable.sectorcaptured = [scarlet]Nécessite la capture du secteur yes = Oui no = Non info.title = Info -error.title = [crimson]Une erreur s'est produite +error.title = [scarlet]Une erreur s'est produite error.crashtitle = Une erreur s'est produite unit.nobuild = [scarlet]Cette unité ne peut construire -lastaccessed = [lightgray]Last Accessed: {0} +lastaccessed = [lightgray]Dernier accès: {0} block.unknown = [lightgray]??? -stat.input = Entrée -stat.output = Sortie -stat.booster = Booster -stat.tiles = Pré-requis +stat.description = But +stat.input = Ressource(s) requise(s) +stat.output = Ressource(s) produite(s) +stat.booster = Boosteur +stat.tiles = Sol requis stat.affinities = Affinités stat.powercapacity = Capacité d'énergie -stat.powershot = Énergie/Tir +stat.powershot = Unités d'énergie/Tir stat.damage = Dégâts stat.targetsair = Cibles Aériennes stat.targetsground = Cibles Terrestres @@ -603,141 +656,153 @@ stat.itemsmoved = Vitesse de Déplacement stat.launchtime = Temps entre chaque lancement stat.shootrange = Portée de tir stat.size = Taille -stat.displaysize = Display Size +stat.displaysize = Résolution stat.liquidcapacity = Capacité liquide stat.powerrange = Portée électrique -stat.linkrange = Link Range +stat.linkrange = Portée des liens stat.instructions = Instructions stat.powerconnections = Nombre maximal de connections stat.poweruse = Énergie utilisée -stat.powerdamage = Dégâts d'énergie +stat.powerdamage = Unités d'énergie/Dégat stat.itemcapacity = Stockage -stat.memorycapacity = Memory Capacity -stat.basepowergeneration = Production d'énergie +stat.memorycapacity = Mémoire +stat.basepowergeneration = Production d'énergie de Base stat.productiontime = Durée de production -stat.repairtime = Durée de réparation complète du Bloc +stat.repairtime = Durée de la réparation complète d'un Bloc +stat.weapons = Armes +stat.bullet = Balles stat.speedincrease = Accélération stat.range = Portée stat.drilltier = Forable -stat.drillspeed = Vitesse de forage de base -stat.boosteffect = Effet du Boost -stat.maxunits = Unités actives max +stat.drillspeed = Vitesse de forage de Base +stat.boosteffect = Effet(s) du Boost +stat.maxunits = Max d'Unités Actives stat.health = Santé stat.buildtime = Durée de construction -stat.maxconsecutive = Max Consecutive +stat.maxconsecutive = Max Consécutif stat.buildcost = Coût de construction -stat.inaccuracy = Imprécision +stat.inaccuracy = Précision stat.shots = Tirs stat.reload = Tirs/Seconde stat.ammo = Munitions -stat.shieldhealth = Shield Health -stat.cooldowntime = Cooldown Time -stat.explosiveness = Explosiveness -stat.basedeflectchance = Base Deflect Chance -stat.lightningchance = Lightning Chance -stat.lightningdamage = Lightning Damage -stat.flammability = Flammability -stat.radioactivity = Radioactivity -stat.heatcapacity = HeatCapacity -stat.viscosity = Viscosity -stat.temperature = Temperature -stat.speed = Speed -stat.buildspeed = Build Speed -stat.minespeed = Mine Speed -stat.minetier = Mine Tier -stat.payloadcapacity = Payload Capacity -stat.commandlimit = Command Limit -stat.abilities = Abilities +stat.shieldhealth = Santé du bouclier +stat.cooldowntime = Temps de refroidissement +stat.explosiveness = Explosivité +stat.basedeflectchance = Chance de Détournement de Base +stat.lightningchance = Chance d'Éclairs +stat.lightningdamage = Dégats des Éclairs +stat.flammability = Inflammabilité +stat.radioactivity = Radioactivité +stat.heatcapacity = Capacité Thermique +stat.viscosity = Viscosité +stat.temperature = Température +stat.speed = Vitesse +stat.buildspeed = Vitesse de construction +stat.minespeed = Vitesse de minage +stat.minetier = Niveau de minage +stat.payloadcapacity = Capacité de chargement +stat.commandlimit = Limite de contrôle +stat.abilities = Abilités +stat.canboost = Boost +stat.flying = Unité volante +stat.ammouse = Utilisation de munitions -ability.forcefield = Force Field -ability.repairfield = Repair Field -ability.statusfield = Status Field -ability.unitspawn = {0} Factory -ability.shieldregenfield = Shield Regen Field +ability.forcefield = Champ de Force +ability.repairfield = Champ de Réparation +ability.statusfield = Champ de statut +ability.unitspawn = Usine de {0} +ability.shieldregenfield = Champ de regénération de bouclier +ability.movelightning = Déplacement éclair bar.drilltierreq = Meilleure Foreuse Requise -bar.noresources = Missing Resources -bar.corereq = Core Base Required +bar.noresources = Ressources manquantes +bar.corereq = Noyau de base requis bar.drillspeed = Vitesse de Forage: {0}/s bar.pumpspeed = Vitesse de Pompage: {0}/s bar.efficiency = Efficacité: {0}% +bar.boost = Boost: {0}% bar.powerbalance = Énergie: {0}/s -bar.powerstored = En stock: {0}/{1} +bar.powerstored = Réserves d'Énergie: {0}/{1} bar.poweramount = Énergie: {0} bar.poweroutput = Énergie Produite: {0} bar.powerlines = Connections: {0}/{1} bar.items = Objets: {0} bar.capacity = Capacité: {0} bar.unitcap = {0} {1}/{2} -bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[unit disabled] -bar.liquid = Liquide +bar.liquid = Liquides bar.heat = Chaleur bar.power = Énergie -bar.progress = Progression de la construction +bar.progress = Construction en cours bar.input = Entrée bar.output = Sortie -units.processorcontrol = [lightgray]Processor Controlled +units.processorcontrol = [lightgray]Contrôlée par un processeur bullet.damage = [stat]{0}[lightgray] dégâts bullet.splashdamage = [stat]{0}[lightgray] dégâts de zone ~[stat] {1}[lightgray] blocs bullet.incendiary = [stat]incendiaire +bullet.sapping = [stat]vol de vie bullet.homing = [stat]autoguidé bullet.shock = [stat]choc électrique -bullet.frag = [stat]explosif +bullet.frag = [stat]fragmentation +bullet.buildingdamage = [stat]{0}%[lightgray] des dégâts aux bâtiments bullet.knockback = [stat]{0}[lightgray] recul -bullet.pierce = [stat]{0}[lightgray]x pierce -bullet.infinitepierce = [stat]pierce +bullet.pierce = [stat]{0}[lightgray]x perforant +bullet.infinitepierce = [stat]perforant +bullet.healpercent = [stat]{0}[lightgray]% soins bullet.freezing = [stat]gel bullet.tarred = [stat]goudronné bullet.multiplier = [stat]{0}[lightgray]x multiplicateur de munitions bullet.reload = [stat]{0}[lightgray]x vitesse de tir unit.blocks = blocs -unit.blockssquared = blocks² -unit.powersecond = énergie/seconde -unit.liquidsecond = unité de liquide/seconde +unit.blockssquared = blocs² +unit.powersecond = unités d'énergie/seconde +unit.liquidsecond = Unités de liquide/seconde unit.itemssecond = objets/seconde -unit.liquidunits = unité de liquide -unit.powerunits = unité d'énergie +unit.liquidunits = unités de liquide +unit.powerunits = unités d'énergie unit.degrees = degrés unit.seconds = secondes -unit.minutes = mins +unit.minutes = minutes unit.persecond = /sec unit.perminute = /min unit.timesspeed = x vitesse unit.percent = % -unit.shieldhealth = shield health +unit.shieldhealth = santé du bouclier unit.items = objets unit.thousands = k -unit.millions = M -unit.billions = b +unit.millions = mil +unit.billions = Md +unit.pershot = /tirs +category.purpose = But category.general = Général category.power = Énergie category.liquids = Liquides category.items = Objets category.crafting = Fabrication -category.function = Function -category.optional = Améliorations optionnelles -setting.landscape.name = Verrouiller en rotation paysage +category.function = Fonction +category.optional = Améliorations facultatives +setting.landscape.name = Verrouiller la rotation en mode paysage setting.shadows.name = Ombres -setting.blockreplace.name = Suggestions Automatiques de Blocs -setting.linear.name = Filtrage Linéaire +setting.blockreplace.name = Suggestion automatique des Blocs +setting.linear.name = Filtrage linéaire setting.hints.name = Astuces -setting.flow.name = Afficher le Débit des Ressources -setting.buildautopause.name = Confirmation avant la construction -setting.animatedwater.name = Eau animée +setting.flow.name = Afficher le Débit des ressources +setting.backgroundpause.name = Pause en Arrière-plan +setting.buildautopause.name = Confirmation avant construction +setting.animatedwater.name = Surfaces Animées setting.animatedshields.name = Boucliers Animés setting.antialias.name = Anticrénelage[lightgray] (redémarrage du jeu nécessaire)[] -setting.playerindicators.name = Indicateurs des Joueurs -setting.indicators.name = Indicateurs des Ennemis +setting.playerindicators.name = Indicateurs alliés +setting.indicators.name = Indicateurs ennemis setting.autotarget.name = Visée automatique setting.keyboard.name = Contrôles Souris+Clavier setting.touchscreen.name = Commandes d'écran tactile -setting.fpscap.name = FPS Max -setting.fpscap.none = Aucun -setting.fpscap.text = {0} FPS -setting.uiscale.name = Échelle de l'interface[lightgray] (redémarrage du jeu nécessaire)[] +setting.fpscap.name = Max IPS +setting.fpscap.none = Illimité +setting.fpscap.text = {0} IPS +Échelle de l'interface[lightgray] (redémarrage du jeu nécessaire)[] setting.swapdiagonal.name = Autoriser le placement en diagonale setting.difficulty.training = Entraînement setting.difficulty.easy = Facile @@ -747,65 +812,66 @@ setting.difficulty.insane = Extrême setting.difficulty.name = Difficulté: setting.screenshake.name = Tremblement de l'Écran setting.effects.name = Afficher les Effets -setting.destroyedblocks.name = Afficher les Blocs Détruits +setting.destroyedblocks.name = Afficher les Blocs détruits setting.blockstatus.name = Afficher le Statut des Blocs -setting.conveyorpathfinding.name = Auto-placement Intelligent des Convoyeurs +setting.conveyorpathfinding.name = Placement intelligent des Convoyeurs setting.sensitivity.name = Sensibilité de la manette -setting.saveinterval.name = Intervalle des Sauvegardes Automatiques +setting.saveinterval.name = Intervalle des Sauvegardes automatiques setting.seconds = {0} secondes -setting.blockselecttimeout.name = Délai d'Attente de Sélection de Bloc setting.milliseconds = {0} millisecondes setting.fullscreen.name = Plein Écran -setting.borderlesswindow.name = Fenêtre sans bords (Borderless)[lightgray] (peut nécessiter le redémarrage du jeu) -setting.fps.name = Afficher FPS et Ping +setting.borderlesswindow.name = Fenêtre sans bords[lightgray] (peut nécessiter le redémarrage du jeu) +setting.fps.name = Afficher IPS et Ping setting.smoothcamera.name = Lissage de la Caméra -setting.vsync.name = VSync -setting.pixelate.name = Pixeliser[lightgray] (désactive les animations) -setting.minimap.name = Afficher la Minimap -setting.coreitems.name = Display Core Items (WIP) +setting.vsync.name = Synchronisation Verticale +setting.pixelate.name = Pixeliser +setting.minimap.name = Afficher la Mini-carte +setting.coreitems.name = Afficher les objets du Noyau setting.position.name = Afficher la position du joueur -setting.musicvol.name = Volume Musique -setting.atmosphere.name = Son atmosphérique de la planète +setting.musicvol.name = Volume de la Musique +setting.atmosphere.name = Montrer l'Atmosphère de la planète setting.ambientvol.name = Volume Ambiant setting.mutemusic.name = Couper la Musique -setting.sfxvol.name = Volume des Effets Spéciaux -setting.mutesound.name = Couper le son des Effets Spéciaux -setting.crashreport.name = Envoyer des Rapports de Crash anonymes +setting.sfxvol.name = Volume des Sons et Effets +setting.mutesound.name = Couper les Sons et Effets +setting.crashreport.name = Envoyer des Rapports de crash anonymes setting.savecreate.name = Sauvegardes Automatiques -setting.publichost.name = Visibilité de la Partie Publique +setting.publichost.name = Visibilité de la Partie publique setting.playerlimit.name = Limite de Joueurs setting.chatopacity.name = Opacité du Chat -setting.lasersopacity.name = Opacité des Connections Laser +setting.lasersopacity.name = Opacité des Connections laser setting.bridgeopacity.name = Opacité des ponts setting.playerchat.name = Montrer les bulles de discussion des joueurs -public.confirm = Voulez-vous rendre votre partie publique?\n[accent]N'importe qui pourrait rejoindre vos parties.\n[lightgray]Ce paramètre peut être changé plus tard dans Paramètres->Jeu->Visibilité de la Partie Publique -public.beta = Notez que les versions bêta du jeu ne peuvent pas créer des salons publics. -uiscale.reset = L'échelle de l'interface a été modifiée.\nAppuyez sur "OK" pour confirmer.\n[scarlet]Rétablissement des paramètres d'avant et fermeture dans [accent] {0}[]... +setting.showweather.name = Montrer les Effets météos +public.confirm = Voulez-vous rendre votre partie publique?\n[accent]N'importe qui pourra rejoindre vos parties.\n[lightgray]Ce paramètre peut être changé plus tard dans Paramètres->Jeu->Visibilité de la Partie Publique +public.confirm.really = Si vous voulez jouer avec des amis, utilisez [green]Inviter un Ami[] Au lieu [scarlet]d'un Serveur Public[]!\nÊtes-vous sûrs de vouloir rendre votre partie [scarlet]publique[]? +public.beta = Notez que les versions bêta du jeu ne peuvent pas créer de salons publics. +uiscale.reset = L'échelle de l'interface a été modifiée.\nAppuyez sur "OK" pour confirmer.\n[scarlet]Rétablissement des anciens paramètres et fermeture du jeu dans [accent] {0}[] secondes... uiscale.cancel = Annuler & Quitter setting.bloom.name = Flou lumineux -keybind.title = Raccourcis Clavier -keybinds.mobile = [scarlet]La plupart des raccourcis clavier ne sont pas fonctionnels sur mobile. Seuls les mouvements basiques sont supportés. +keybind.title = Paramètres des Touches du Clavier +keybinds.mobile = [scarlet]La plupart des touches de clavier ne sont pas fonctionnelles sur mobile. Seuls les mouvements basiques sont supportés. category.general.name = Général category.view.name = Voir category.multiplayer.name = Multijoueur -category.blocks.name = Block Select -command.attack = Attaque -command.rally = Rassembler +category.blocks.name = Sélection des blocs +command.attack = Attaquer +command.rally = Rallier command.retreat = Retraite -command.idle = Idle -placement.blockselectkeys = \n[lightgray]Touche: [{0}, -keybind.respawn.name = Réapparaitre +command.idle = Pause +placement.blockselectkeys = \n[lightgray]Raccourci: [{0}, +keybind.respawn.name = Réapparaître keybind.control.name = Controler une Unité -keybind.clear_building.name = Effacer les constructions -keybind.press = Appuyez sur une touche... -keybind.press.axis = Appuyez sur un axe ou une touche... -keybind.screenshot.name = Capture d'écran +keybind.clear_building.name = Réinitialiser les constructions +keybind.press = Pressez une touche... +keybind.press.axis = Pressez un axe ou une touche... +keybind.screenshot.name = Capture d'écran de la carte keybind.toggle_power_lines.name = Montrer/Cacher les Connections d'Énergie -keybind.toggle_block_status.name = Montrer/Cacher les Status des Blocs -keybind.move_x.name = Mouvement X -keybind.move_y.name = Mouvement Y -keybind.mouse_move.name = Suivre la Souris -keybind.pan.name = Pan View +keybind.toggle_block_status.name = Montrer/Cacher le Statut des Blocs +keybind.move_x.name = Mouvement axe X +keybind.move_y.name = Mouvement axe Y +keybind.mouse_move.name = Suivre la souris +keybind.pan.name = Vue Panoramique keybind.boost.name = Boost keybind.schematic_select.name = Sélectionner une Région keybind.schematic_menu.name = Menu des schémas @@ -813,10 +879,10 @@ keybind.schematic_flip_x.name = Retourner le schéma sur l'axe des X keybind.schematic_flip_y.name = Retourner le schéma sur l'axe des Y keybind.category_prev.name = Catégorie Précédente keybind.category_next.name = Catégorie Suivante -keybind.block_select_left.name = Sélectionner Bloc de Gauche -keybind.block_select_right.name = Sélectionner Bloc de Droite -keybind.block_select_up.name = Sélectionner Bloc en Haut -keybind.block_select_down.name = Sélectionner Bloc en Bas +keybind.block_select_left.name = Sélectionner le Bloc de Gauche +keybind.block_select_right.name = Sélectionner le Bloc de Droite +keybind.block_select_up.name = Sélectionner le Bloc en Haut +keybind.block_select_down.name = Sélectionner le Bloc en Bas keybind.block_select_01.name = Sélectionner Catégorie/Bloc 1 keybind.block_select_02.name = Sélectionner Catégorie/Bloc 2 keybind.block_select_03.name = Sélectionner Catégorie/Bloc 3 @@ -833,59 +899,63 @@ keybind.diagonal_placement.name = Placement en diagonale keybind.pick.name = Choisir un bloc keybind.break_block.name = Supprimer un bloc keybind.deselect.name = Désélectionner -keybind.pickupCargo.name = Pickup Cargo -keybind.dropCargo.name = Drop Cargo -keybind.command.name = Command +keybind.pickupCargo.name = Prendre un Chargement +keybind.dropCargo.name = Lacher un Chargement +keybind.command.name = Commander keybind.shoot.name = Tirer -keybind.zoom.name = Zoomer +keybind.zoom.name = Zoom keybind.menu.name = Menu keybind.pause.name = Pause -keybind.pause_building.name = Pauser/Reprendre la construction -keybind.minimap.name = Minimap -keybind.chat.name = Chat -keybind.player_list.name = Liste des Joueurs +keybind.pause_building.name = Pauser/Reprendre la Construction +keybind.minimap.name = Mini-carte +keybind.planet_map.name = Carte de la Planète +keybind.research.name = Recherche +keybind.chat.name = Tchat +keybind.player_list.name = Liste des joueurs keybind.console.name = Console keybind.rotate.name = Tourner -keybind.rotateplaced.name = Tourner un bloc existant (maintenir) +keybind.rotateplaced.name = Tourner un Bloc existant (maintenir) keybind.toggle_menus.name = Cacher/Afficher les Menus -keybind.chat_history_prev.name = Remonter l'Historique du Chat -keybind.chat_history_next.name = Descendre l'Historique du Chat -keybind.chat_scroll.name = Défilement du Chat -keybind.drop_unit.name = Larguer l'unité -keybind.zoom_minimap.name = Zoom Minimap +keybind.chat_history_prev.name = Remonter l'Historique du Tchat +keybind.chat_history_next.name = Descendre l'Historique du Tchat +keybind.chat_scroll.name = Défilement du Tchat +keybind.chat_mode.name = Changer le mode du Tchat +keybind.drop_unit.name = Larguer une unité +keybind.zoom_minimap.name = Zoomer la Mini-carte mode.help.title = Description des modes de jeu mode.survival.name = Survie -mode.survival.description = Le mode normal. Ressources limitées et vagues d'Ennemis automatiques.\n[gray]Nécessite un point d'apparition ennemi pour y jouer. -mode.sandbox.name = Bac à sable -mode.sandbox.description = Ressources infinies et pas de minuterie pour les vagues. +mode.survival.description = Le mode normal. Ressources limitées et vagues automatiques.\n[gray]Requiert des points d'apparition ennemis pour pouvoir jouer à ce mode. +mode.sandbox.name = Bac à Sable +mode.sandbox.description = Ressources infinies et pas de compte à rebours pour les vagues. mode.editor.name = Éditeur -mode.pvp.name = PvP -mode.pvp.description = Battez-vous contre d'autres joueurs en local.\n[gray]Requiert aux moins 2 noyaux de couleurs différentes dans la carte pour y jouer. +mode.pvp.name = JcJ +mode.pvp.description = Lutter contre d'autres joueurs pour gagner!\n[gray]Requiert au moins 2 Noyaux de couleurs différentes pour pouvoir jouer à ce mode. mode.attack.name = Attaque -mode.attack.description = Pas de vagues, le but étant de détruire la base ennemie.\n[gray]Requiert un noyau rouge dans la map pour y jouer. -mode.custom = Règles personnalisées +mode.attack.description = Pas forcément de vagues, le but étant de détruire la base ennemie.\n[gray]Requiert un Noyau rouge pour jouer à ce mode. +mode.custom = Règles Personnalisées -rules.infiniteresources = Ressources infinies +rules.infiniteresources = Ressources Infinies rules.reactorexplosions = Explosion des Réacteurs -rules.schematic = Schematics Allowed -rules.wavetimer = Minuterie pour les vagues +rules.coreincinerates = Incinération des surplus du Noyau +rules.schematic = Schémas autorisés +rules.wavetimer = Compte à rebours des vagues rules.waves = Vagues rules.attack = Mode « Attaque » -rules.buildai = AI Building +rules.buildai = Constructions de l'IA rules.enemyCheat = Ressources infinies pour l'IA (équipe rouge) rules.blockhealthmultiplier = Multiplicateur de Santé des Blocs rules.blockdamagemultiplier = Multiplicateur de Dégât des Blocs -rules.unitbuildspeedmultiplier = Multiplicateur de Vitesse de Construction d'Unités +rules.unitbuildspeedmultiplier = Multiplicateur de Vitesse de Construction des Unités rules.unithealthmultiplier = Multiplicateur de Santé des Unités rules.unitdamagemultiplier = Multiplicateur de Dégât des Unités -rules.enemycorebuildradius = Périmètre de non-construction autour du noyau ennemi:[lightgray] (blocs) -rules.wavespacing = Espacement des vagues:[lightgray] (sec) +rules.enemycorebuildradius = Périmètre de Non-Construction autour du Noyau ennemi:[lightgray] (blocs) +rules.wavespacing = Temps entre les Vagues:[lightgray] (sec) rules.buildcostmultiplier = Multiplicateur du prix de construction rules.buildspeedmultiplier = Multiplicateur du temps de construction rules.deconstructrefundmultiplier = Multiplicateur du remboursement lors de la déconstruction -rules.waitForWaveToEnd = Les Vagues Attendent la Mort des Ennemis -rules.dropzoneradius = Rayon d'Apparition des Ennemis:[lightgray] (tuiles) -rules.unitammo = Les Unités Nécessitent des Munitions +rules.waitForWaveToEnd = Les Vagues attendent la mort des ennemis +rules.dropzoneradius = Rayon d'Apparition des ennemis:[lightgray] (tuiles) +rules.unitammo = Les Unités nécessitent des munitions rules.title.waves = Vagues rules.title.resourcesbuilding = Ressources & Construction rules.title.enemy = Ennemis @@ -893,18 +963,20 @@ rules.title.unit = Unités rules.title.experimental = Expérimental rules.title.environment = Environment rules.lighting = Éclairage -rules.enemyLights = Enemy Lights -rules.fire = Fire -rules.explosions = Block/Unit Explosion Damage +rules.enemyLights = Éclairage ennemi +rules.fire = Feu +rules.explosions = Dégâts d'explosion des Blocs/Unités rules.ambientlight = Éclairage Ambiant -rules.weather = Weather -rules.weather.frequency = Frequency: -rules.weather.duration = Duration: +rules.weather = Météo +rules.weather.frequency = Fréquence: +rules.weather.always = Permanent +rules.weather.duration = Durée: content.item.name = Objets content.liquid.name = Liquides content.unit.name = Unités content.block.name = Blocs +content.sector.name = Secteurs item.copper.name = Cuivre item.lead.name = Plomb @@ -916,7 +988,7 @@ item.silicon.name = Silicium item.plastanium.name = Plastanium item.phase-fabric.name = Tissu Phasé item.surge-alloy.name = Alliage Superchargé -item.spore-pod.name = Glande de Spore +item.spore-pod.name = Bulbe Sporifère item.sand.name = Sable item.blast-compound.name = Mélange Explosif item.pyratite.name = Pyratite @@ -928,7 +1000,7 @@ liquid.oil.name = Pétrole liquid.cryofluid.name = Liquide Cryogénique unit.dagger.name = Poignard -unit.mace.name = Mace +unit.mace.name = Titan unit.fortress.name = Forteresse unit.nova.name = Nova unit.pulsar.name = Pulsar @@ -942,7 +1014,7 @@ unit.flare.name = Flare unit.horizon.name = Horizon unit.zenith.name = Zenith unit.antumbra.name = Antumbra -unit.eclipse.name = Eclipse +unit.eclipse.name = Éclipse unit.mono.name = Mono unit.poly.name = Poly unit.mega.name = Mega @@ -956,89 +1028,90 @@ unit.omura.name = Omura unit.alpha.name = Alpha unit.beta.name = Beta unit.gamma.name = Gamma -unit.scepter.name = Scepter -unit.reign.name = Reign +unit.scepter.name = Destructeur +unit.reign.name = Éradicateur unit.vela.name = Vela unit.corvus.name = Corvus -block.resupply-point.name = Resupply Point +block.resupply-point.name = Point de Rechargement block.parallax.name = Parallax block.cliff.name = Falaise block.sand-boulder.name = Bloc de Sable +block.basalt-boulder.name = Rocher de Basalte block.grass.name = Herbe block.slag.name = Scories -block.space.name = Space +block.space.name = Espace block.salt.name = Sel -block.salt-wall.name = Salt Wall +block.salt-wall.name = Mur de Sel block.pebbles.name = Cailloux block.tendrils.name = Vrilles -block.sand-wall.name = Sand Wall +block.sand-wall.name = Mur de Sable block.spore-pine.name = Pin Sporeux -block.spore-wall.name = Spore Wall -block.boulder.name = Boulder -block.snow-boulder.name = Snow Boulder +block.spore-wall.name = Mur de Spores +block.boulder.name = Rocher +block.snow-boulder.name = Bloc de Neige block.snow-pine.name = Pin enneigé block.shale.name = Schiste block.shale-boulder.name = Blocs de Schiste block.moss.name = Mousse block.shrubs.name = Arbustes -block.spore-moss.name = Mousse Sporeuse -block.shale-wall.name = Shale Wall +block.spore-moss.name = Mousse Sporifère +block.shale-wall.name = Mur de Schiste block.scrap-wall.name = Mur de Ferraille block.scrap-wall-large.name = Grand Mur de Ferraille block.scrap-wall-huge.name = Énorme Mur de Ferraille block.scrap-wall-gigantic.name = Gigantesque Mur de Ferraille block.thruster.name = Propulseur -block.kiln.name = Four +block.kiln.name = Four à Verre block.graphite-press.name = Presse à Graphite block.multi-press.name = Multi-Presse -block.constructing = {0}\n[lightgray](En Construction) +block.constructing = {0} [lightgray](En Construction) block.spawn.name = Point d'Apparition Ennemi -block.core-shard.name = Noyau: Tesson +block.core-shard.name = Noyau: Fragment block.core-foundation.name = Noyau: Fondation block.core-nucleus.name = Noyau: Épicentre block.deepwater.name = Eau profonde block.water.name = Eau block.tainted-water.name = Eau Contaminée -block.darksand-tainted-water.name = Eau Contaminée avec fond de Sable Sombre +block.darksand-tainted-water.name = Eau Contaminée avec fond de Sable sombre block.tar.name = Goudron block.stone.name = Roche block.sand.name = Sable -block.darksand.name = Sable Sombre +block.darksand.name = Sable sombre block.ice.name = Glace block.snow.name = Neige block.craters.name = Cratères block.sand-water.name = Eau avec fond de Sable -block.darksand-water.name = Eau avec fond de Sable Sombre -block.char.name = Cendre +block.darksand-water.name = Eau avec fond de Sable sombre +block.char.name = Cendres block.dacite.name = Dacite -block.dacite-wall.name = Dacite Wall -block.dacite-boulder.name = Dacite Boulder +block.dacite-wall.name = Mur de Dacite +block.dacite-boulder.name = Rocher de Dacite block.ice-snow.name = Neige et Glace -block.stone-wall.name = Stone Wall -block.ice-wall.name = Ice Wall -block.snow-wall.name = Snow Wall -block.dune-wall.name = Dune Wall +block.stone-wall.name = Mur de Pierre +block.ice-wall.name = Mur de Glace +block.snow-wall.name = Mur de Neige +block.dune-wall.name = Mur de Sable sombre block.pine.name = Pin -block.dirt.name = Dirt -block.dirt-wall.name = Dirt Wall -block.mud.name = Mud +block.dirt.name = Terre +block.dirt-wall.name = Mur de Terre +block.mud.name = Boue block.white-tree-dead.name = Arbre Blanc Mort block.white-tree.name = Arbre Blanc -block.spore-cluster.name = Grappe de Spores -block.metal-floor.name = Plancher Métallique 1 -block.metal-floor-2.name = Plancher Métallique 2 -block.metal-floor-3.name = Plancher Métallique 3 -block.metal-floor-5.name = Plancher Métallique 4 -block.metal-floor-damaged.name = Plancher Métallique Endommagé -block.dark-panel-1.name = Panneau Sombre 1 -block.dark-panel-2.name = Panneau Sombre 2 -block.dark-panel-3.name = Panneau Sombre 3 -block.dark-panel-4.name = Panneau Sombre 4 -block.dark-panel-5.name = Panneau Sombre 5 -block.dark-panel-6.name = Panneau Sombre 6 -block.dark-metal.name = Métal Sombre -block.basalt.name = Basalt +block.spore-cluster.name = Grappes de Spores +block.metal-floor.name = Sol métallique +block.metal-floor-2.name = Sol métallique 2 +block.metal-floor-3.name = Sol métallique 3 +block.metal-floor-5.name = Sol métallique 5 +block.metal-floor-damaged.name = Sol métallique endommagé +block.dark-panel-1.name = Panneau sombre 1 +block.dark-panel-2.name = Panneau sombre 2 +block.dark-panel-3.name = Panneau sombre 3 +block.dark-panel-4.name = Panneau sombre 4 +block.dark-panel-5.name = Panneau sombre 5 +block.dark-panel-6.name = Panneau sombre 6 +block.dark-metal.name = Métal sombre +block.basalt.name = Basalte block.hotrock.name = Roches Chaudes block.magmarock.name = Roches Magmatiques block.copper-wall.name = Mur de Cuivre @@ -1057,12 +1130,11 @@ block.duo.name = Duo block.scorch.name = Brûleur block.scatter.name = Disperseur block.hail.name = Grêle -block.lancer.name = Lancier +block.lancer.name = Perforateur block.conveyor.name = Convoyeur block.titanium-conveyor.name = Convoyeur en Titane block.plastanium-conveyor.name = Convoyeur en Plastanium block.armored-conveyor.name = Convoyeur Cuirassé -block.armored-conveyor.description = Déplace les objets à la même vitesse que les convoyeurs en titane, mais est plus résistant. Seulement d'autres convoyeurs peuvent faire entrer des ressources par ses côtés. block.junction.name = Jonction block.router.name = Routeur block.distributor.name = Distributeur @@ -1070,7 +1142,6 @@ block.sorter.name = Trieur block.inverted-sorter.name = Trieur Inversé block.message.name = Message block.illuminator.name = Illuminateur -block.illuminator.description = Une petite source lumineuse compacte et configurable. Nécessite de l'énergie pour fonctionner. block.overflow-gate.name = Barrière de Débordement block.underflow-gate.name = Barrière de Refoulement block.silicon-smelter.name = Fonderie de Silicium @@ -1079,7 +1150,7 @@ block.pulverizer.name = Pulvérisateur block.cryofluid-mixer.name = Refroidisseur block.melter.name = Four à Fusion block.incinerator.name = Incinérateur -block.spore-press.name = Presse à Spore +block.spore-press.name = Presse à Spores block.separator.name = Séparateur block.coal-centrifuge.name = Centrifugeuse à Charbon block.power-node.name = Transmetteur Énergétique @@ -1093,7 +1164,7 @@ block.steam-generator.name = Générateur à Turbine block.differential-generator.name = Générateur Différentiel block.impact-reactor.name = Réacteur à Impact block.mechanical-drill.name = Foreuse Mécanique -block.pneumatic-drill.name = Foreuse à Vérin +block.pneumatic-drill.name = Foreuse Pneumatique block.laser-drill.name = Foreuse Laser block.water-extractor.name = Extracteur d'Eau block.cultivator.name = Cultivateur @@ -1107,15 +1178,15 @@ block.power-void.name = Absorbeur Énergétique block.power-source.name = Source d'Énergie block.unloader.name = Déchargeur block.vault.name = Coffre-Fort -block.wave.name = Onde +block.wave.name = Vague block.tsunami.name = Tsunami -block.swarmer.name = Nuée +block.swarmer.name = Essaim block.salvo.name = Salve -block.ripple.name = Percussion +block.ripple.name = Percuteur block.phase-conveyor.name = Convoyeur Phasé block.bridge-conveyor.name = Pont block.plastanium-compressor.name = Compresseur de Plastanium -block.pyratite-mixer.name = Mixeur de Pyratite +block.pyratite-mixer.name = Mixeur à Pyratite block.blast-mixer.name = Mixeur à Explosion block.solar-panel.name = Panneau Solaire block.solar-panel-large.name = Grand Panneau Solaire @@ -1124,218 +1195,313 @@ block.repair-point.name = Point de Réparation block.pulse-conduit.name = Conduit à Impulsion block.plated-conduit.name = Conduit Plaqué block.phase-conduit.name = Conduit Phasé -block.liquid-router.name = Routeur de Liquide -block.liquid-tank.name = Réservoir à Liquide -block.liquid-junction.name = Jonction à Liquide -block.bridge-conduit.name = Conduit Surélevé +block.liquid-router.name = Routeur de Liquides +block.liquid-tank.name = Réservoir à Liquides +block.liquid-junction.name = Jonction à Liquides +block.bridge-conduit.name = Pont à Liquide block.rotary-pump.name = Pompe Rotative block.thorium-reactor.name = Réacteur à Thorium -block.mass-driver.name = Catapulte Électromagnétique -block.blast-drill.name = Foreuse à Explosion -block.thermal-pump.name = Pompe Thermique -block.thermal-generator.name = Générateur Thermique +block.mass-driver.name = Transporteur de masse +block.blast-drill.name = Foreuse à explosion +block.thermal-pump.name = Pompe thermique +block.thermal-generator.name = Générateur thermique block.alloy-smelter.name = Fonderie d'Alliage Superchargé -block.mender.name = Réparateur -block.mend-projector.name = Projecteur Soignant +block.mender.name = Gardien +block.mend-projector.name = Projecteur soignant block.surge-wall.name = Mur Superchargé -block.surge-wall-large.name = Grand Mur Superchargé +block.surge-wall-large.name = Grand mur Superchargé block.cyclone.name = Cyclone -block.fuse.name = Fusible -block.shock-mine.name = Mine -block.overdrive-projector.name = Projecteur Surmultiplicateur -block.force-projector.name = Champ de Force +block.fuse.name = Fuse +block.shock-mine.name = Mine terrestre +block.overdrive-projector.name = Projecteur Accélérant +block.force-projector.name = Projecteur de Champ de force block.arc.name = Arc -block.rtg-generator.name = Générateur G.T.R. +block.rtg-generator.name = G.T.R block.spectre.name = Spectre -block.meltdown.name = Fusion -block.foreshadow.name = Foreshadow +block.meltdown.name = Meltdown +block.foreshadow.name = Présage block.container.name = Conteneur -block.launch-pad.name = Plateforme de Lancement -block.launch-pad-large.name = Grande Plateforme de Lancement -block.segment.name = Diviseur -block.command-center.name = Command Center -block.ground-factory.name = Usine d'Unité Terrestre -block.air-factory.name = Usine d'Unité Aérienne -block.naval-factory.name = Usine d'Unité Navale +block.launch-pad.name = Rampe de lancement +block.launch-pad-large.name = Grande rampe de lancement +block.segment.name = Diviseur +block.command-center.name = Centre de Commande +block.ground-factory.name = Usine d'Unités Terrestres +block.air-factory.name = Usine d'Unités Aériennes +block.naval-factory.name = Usine d'Unités Navales block.additive-reconstructor.name = Reconstructeur Additif block.multiplicative-reconstructor.name = Reconstructeur Multiplicatif block.exponential-reconstructor.name = Reconstructeur Exponentiel block.tetrative-reconstructor.name = Reconstructeur Tétratif block.payload-conveyor.name = Convoyeur de Masse -block.payload-router.name = Routeur de Charge Utile -block.disassembler.name = Disassembler -block.silicon-crucible.name = Creuset de Silicium -block.overdrive-dome.name = Overdrive Dome +block.payload-router.name = Routeur de Masse +block.disassembler.name = Désasembleur +block.silicon-crucible.name = Grande Fonderie de Silicium +block.overdrive-dome.name = Dome Accélérant +#experimental, may be removed +block.block-forge.name = Forgeur de Blocs +block.block-loader.name = Chargeur de Blocs +block.block-unloader.name = Déchargeur de Blocs +block.interplanetary-accelerator.name = Accélérateur Interplanétaire -block.switch.name = Switch -block.micro-processor.name = Micro Processor -block.logic-processor.name = Logic Processor -block.hyper-processor.name = Hyper Processor -block.logic-display.name = Logic Display -block.large-logic-display.name = Large Logic Display -block.memory-cell.name = Memory Cell -block.memory-bank.name = Memory Bank +block.switch.name = Interrupteur +block.micro-processor.name = Micro Processeur +block.logic-processor.name = Processeur +block.hyper-processor.name = Hyper Processeur +block.logic-display.name = Écran +block.large-logic-display.name = Grand Écran +block.memory-cell.name = Bloc de mémoire +block.memory-bank.name = Banque de mémoire team.blue.name = bleu team.crux.name = rouge -team.sharded.name = jaune +team.sharded.name = orange team.orange.name = orange -team.derelict.name = abandonné +team.derelict.name = derelict team.green.name = vert -team.purple.name = violet +team.purple.name = mauve -tutorial.next = [lightgray] -tutorial.intro = Bienvenue sur le [scarlet]Tutoriel de Mindustry![]\nUtilisez [accent][[ZQSD ou WASD][] pour vous déplacer.\nFaites [accent]rouler[] la molette de la souris pour zoomer et dézoomer.\nCommencez en minant du [accent]cuivre[]. Pour cela, allez près de votre noyau, puis faites un clic gauche sur un minerai de cuivre.\n\n[accent]{0}/{1} cuivre -tutorial.intro.mobile = Bienvenue sur le [scarlet]Tutoriel de Mindustry![]\nBalayez l'écran pour vous déplacer.\n[accent] Pincez avec deux doigts [] pour zoomer et dézoomer.\nCommencez en[accent] minant du cuivre[]. Pour cela, allez près de votre noyau, puis appuyez sur un minerai de cuivre.\n\n[accent]{0}/{1} cuivre -tutorial.drill = Miner manuellement est inefficace.\nLes [accent]foreuses []peuvent miner pour vous.\nCliquez sur l'onglet des foreuses en bas à droite.\nSélectionnez la [accent]foreuse mécanique[]. Placez-la ensuite sur des minerais de cuivre avec un clic-gauche.\nVous pouvez aussi sélectionner la foreuse en appuyant sur [accent][[2][] et [accent][[1][] rapidement, peu importe l'onglet ouvert.\n[accent]Faites un clic-droit[] pour arrêter la construction. -tutorial.drill.mobile = Miner manuellement est inefficace.\n[accent]Les foreuses []peuvent miner pour vous.\nAppuyez sur l'onglet des foreuses en bas à droite.\nSélectionnez la [accent]foreuse mécanique[].\nPlacez-la sur des minerais de cuivre en appuyant dessus, puis en touchant la[accent] coche[] pour confirmer votre placement.\nAppuyez sur le [accent]bouton X[] pour annuler le placement. -tutorial.blockinfo = Chaque bloc a des statistiques différentes. Chaque foreuse ne peut miner que certains minerais.\nPour vérifier les informations et les statistiques d'un bloc, appuyez sur le [accent]bouton "?" tout en le sélectionnant dans le menu de construction.[]\n\n[accent]Maintenant, essayez d'accéder aux statistiques de la foreuse mécanique.[] -tutorial.conveyor = [accent]Les convoyeurs[] sont utilisés pour transporter des objets au noyau.\nFaites une ligne de convoyeurs de la foreuse jusqu'au noyau.\n[accent]Maintenez votre souris pour les placer en ligne.[]\nGardez la touche[accent] CTRL[] enfoncée pour pouvoir les placer en diagonale.\n\nPlacez 2 convoyeurs en ligne, puis livrez un minerai au noyau. -tutorial.conveyor.mobile = [accent]Les convoyeurs[] sont utilisés pour transporter des objets au noyau.\nFaites une ligne de convoyeurs de la foreuse jusqu'au noyau.\n[accent] Maintenez votre doigt enfoncé[] et déplacez-le pour former une ligne.\n\nPlacez 2 convoyeurs en ligne, puis livrez un minerai au noyau. -tutorial.turret = Une fois qu'une ressource entre dans votre noyau, elle peut être utilisée pour la construction.\nGardez à l'esprit que certaines ressources ne peuvent pas être utilisées pour la construction.\nCes ressources, telles que[accent] le charbon[],[accent] le sable[] ou[accent] la ferraille[], ne peuvent pas entrer dans votre noyau.\nDes structures défensives doivent être construites pour repousser l'[lightgray] ennemi[].\nConstruisez une [accent]tourelle Duo[] près de votre noyau. -tutorial.drillturret = Les tourelles Duo ont besoin de[accent] munitions en cuivre []pour tirer.\nPlacez une foreuse près de la tourelle.\nÀ l'aide de convoyeurs, alimentez la tourelle en cuivre.\n\n[accent]Munitions livrées: 0/1 -tutorial.pause = Pendant les batailles, vous pouvez mettre [accent]le jeu en pause.[]\nVous pouvez planifier la construction de bâtiments tout en étant en pause.\n\n[accent]Appuyez sur la barre espace pour mettre en pause. -tutorial.pause.mobile = Pendant les batailles, vous pouvez mettre [accent]le jeu en pause.[]\nVous pouvez planifier la construction de bâtiments tout en étant en pause.\n\n[accent]Appuyez sur ce bouton en haut à gauche pour mettre en pause. -tutorial.unpause = Maintenant, appuyez à nouveau sur espace pour reprendre. -tutorial.unpause.mobile = Appuyez à nouveau dessus pour reprendre. -tutorial.breaking = Les blocs ou bâtiments doivent souvent être détruits.\n[accent]Gardez enfoncé le bouton droit de votre souris[] pour détruire tous les blocs en une sélection.[]\n\n[accent]Détruisez tous les blocs de ferraille situés à la gauche de votre noyau à l'aide de la sélection de zone. -tutorial.breaking.mobile = Les blocs ou bâtiments doivent souvent être détruits.\n[accent]Sélectionnez le mode de déconstruction[], puis appuyez sur un bloc pour commencer à le détruire.\nDétruisez une zone en maintenant votre doigt appuyé pendant quelques secondes[] et en le déplaçant dans une direction.\nAppuyez sur le bouton coche pour confirmer.\n\n[accent]Détruisez tous les blocs de ferraille situés à la gauche de votre noyau à l'aide de la sélection de zone. -tutorial.withdraw = Dans certaines situations, il est nécessaire de prendre des ressources directement à partir des bâtiments.\nPour faire cela, [accent]appuyez sur un bloc[] qui contient des ressources, puis [accent]appuyez sur une ressource[] dans son inventaire.\nPlusieurs objets d'une même ressource peuvent être retirées en [accent]appuyant pendant quelques secondes[].\n\n[accent]Retirez du cuivre du noyau.[] -tutorial.deposit = Vous pouvez déposer des ressources dans des bâtiments en les faisant glisser de votre vaisseau vers le bâtiment de destination.\n\n[accent]Déposez le cuivre récupéré précédemment dans le noyau.[] -tutorial.waves = L'[lightgray] ennemi[] approche.\n\nDéfendez le noyau pendant 2 vagues.[accent] Cliquez[] pour tirer.\nConstruisez plus de tourelles et de foreuses. Minez plus de cuivre. -tutorial.waves.mobile = L'[lightgray] ennemi[] approche.\n\nDéfendez le noyau pendant 2 vagues. Votre vaisseau tirera automatiquement sur les ennemis.\nConstruisez plus de tourelles et de foreuses. Minez plus de cuivre. -tutorial.launch = Une fois que vous aurez atteint une vague spécifique, vous aurez la possibilité de[accent] faire décoller le noyau[], abandonnant vos défenses, mais [accent]sécurisant toutes les ressources stockées dans votre noyau.[]\nCes ressources peuvent ensuite être utilisées pour rechercher de nouvelles technologies.\n\n[accent]Appuyez sur le bouton de lancement. +hint.skip = Passer +hint.desktopMove = Utilisez [accent][[ZQSD][] pour bouger. +hint.zoom = [accent]Scroller[] pour zoomer et dézoomer. +hint.mine = Bougez vers le \uf8c4 minerai de cuivre et [accent]cliquez[] dessus mour le miner manuellement. +hint.desktopShoot = [accent][[Clic-gauche][] pour tirer. +hint.depositItems = Pour déposer des ressources dans le Noyau, déplacez-les depuis votre vaisseau, vers ce dernier. +hint.respawn = Pour réapparaître en tant que vaisseau, presser [accent][[V][]. +hint.respawn.mobile = Vous avez pris le contrôle d'une unité/structure. Pour réapparaître en tant que vaisseau, [accent]touchez l'avatar en haut à gauche.[] +hint.desktopPause = Pressez [accent][[Espace][] pour pauser et reprendre le jeu. +hint.placeDrill = Sélectionnez l'onglet \ue85e [accent]Foreuses[] dans le menu en bas à droite, sélectionnez une \uf870 [accent]Foreuse[] et cliquez sur un filon de cuivre pour la placer. +hint.placeDrill.mobile = Sélectionnez l'onglet \ue85e [accent]Foreuses[] dans le menu en bas à droite, sélectionnez une \uf870 [accent]Foreuse Méchanique[] et touchez un filon de cuivre pour la placer.\n\nPressez le \ue800 [accent]V[] en bas à droite pour confirmer. +hint.placeConveyor = Les Convoyeurs transportent les ressources des foreuses, vers d'autres blocs. Sélectionnez un \uf896 [accent]Convoyeur[] dans l'onglet \ue814 [accent]Distribution[].\n\nCliquez et maintenez pour placer plusieurs convoyeurs.\n[accent]Scrollez[] pour les faire pivoter. +hint.placeConveyor.mobile = Les Convoyeurs transportent les ressources des foreuses, vers d'autres blocs. Sélectionnez un \uf896 [accent]Convoyeur[] dans l'onglet \ue814 [accent]Distribution[].\n\nMaintenez votre doigt et déplacez-le pour placer plusieurs convoyeurs. +hint.placeTurret = Placez des \uf861 [accent]Tourelles[] pour défendre votre base contre les ennemis.\n\nLes Tourelles nécessitent des munitions (dans ce cas, du \uf838Cuivre).\nUtilisez les convoyeurs et les foreuses pour les ravitailler. +hint.breaking = Maintenez [accent]Clic-droit[] pour détruire des blocs. +hint.breaking.mobile = Activez le \ue817 [accent]marteau[] en bas à droite Touchez pour détruire des blocs.\n\nRetenez votre doigt pendant une seconde et déplacez-le pour détruire les blocs dans la zone de sélection. +hint.research = Utilisez le bouton \ue875 [accent]Recherche[] pour rechercher de nouvelles technologies. +hint.research.mobile = Utilisez le bouton \ue875 [accent]Recherche[] dans le \ue88c [accent]Menu[] pour rechercher de nouvelles technologies. +hint.unitControl = Retenez [accent][[Ctrl-gauche][] et [accent]cliquez[] Pour contrôler une tourelle ou une unité alliée. +hint.unitControl.mobile = [accent][[Tapez][] 2 fois une tourelle ou une unité alliée pour la controler. +hint.launch = Une fois que vous avez collecté assez de ressources, vous pouvez [accent]Lancer[] votre Noyau en sélectionnant un secteur depuis la \ue827 [accent]Carte[] en bas à droite. +hint.launch.mobile = Une fois que vous avez collecté assez de ressources, vous pouvez [accent]Lancer[] votre Noyau en sélectionnant un secteur depuis la \ue827 [accent]Carte[] dans le \ue88c [accent]Menu[]. +hint.schematicSelect = Retenez [accent][[F][] pour sélectionner des blocs dans une zone afin de les copier et les coller.\n\n[accent][[Clic du milieu][] pour copier un seule type de bloc. +hint.conveyorPathfind = Retenez [accent][[Ctrl-gauche][] pendant que vous placez des convoyeurs, afin de générer un chemin automatiquement. +hint.conveyorPathfind.mobile = Activez le mode \ue844 [accent]Diagonale[] et déplacez des convoyeurs, afin de générer un chemin automatiquement. +hint.boost = Retenez [accent][[Maj-gauche][] pour voler au-dessus des obstacles avec votre unité actuelle.\n\nSeules quelques unités terrestres peuvent voler. +hint.command = Pressez [accent][[G][] pour commander les unités proches d'un [accent]type similaire[] et bouger une formation.\n\nSeules les unités terrestres peuvent controller d'autres unités terrestres. +hint.command.mobile = [accent][[Tapez][] 2 fois votre unité pour commander les unités proches d'un [accent]type similaire[] et bouger une formation. +hint.payloadPickup = Pressez [accent][[[] pour transporter des blocs ou des unités. +hint.payloadPickup.mobile = [accent]Tapez et retenez[] votre doigt pour transporter des blocs ou des unités. +hint.payloadDrop = Pressez [accent]][] pour larguer votre chargement. +hint.payloadDrop.mobile = [accent]Tapez et retenez[] votre doigt pour larguer votre chargement. +hint.waveFire = [accent]Les tourelles à liquides[] approvisionnées en eau en tant que munition, vont automatiquement éteindre les incendies proches. +hint.generator = \uf879 Les [accent]Générateurs à combustion[] brûlent du Charbon et transmettent de l'énergie aux blocs adjacents.\n\nLa transmission d'énergie peut être étendue avec des \uf87f [accent]Transmetteurs Énergétiques[]. +hint.guardian = Les [accent]Gardiens[] sont protégés par un bouclier. Les munitions faibles telles que le [accent]Cuivre[] et le [accent]Plomb[] ne seront [scarlet]pas efficaces[].\n\nUtilisez des tourelles de plus haut niveau, ou de meilleures munitions comme le \uf835 [accent]Graphite[] avec un \uf861Duo/\uf859Salve pour pouvoir tuer le gardien. +hint.coreUpgrade = Les Noyaux peuvent être améliorés [accent]en plaçant un Noyau de plus haut niveau sur eux[].\n\nPlacez un  Noyau [accent]Fondation[] sur le  Noyau [accent]Fragment[]. Soyez sûrs que rien n'obstrue la construction. +hint.presetLaunch = Les [accent]secteurs[] gris, tels que [accent]Frozen Forest[], peuvent être lançés de n'importe où. Ils ne requièrent pas la capture d'un secteur adjacent.\n\n[accent]Il y a beaucoup de secteurs[] comme celui-ci, qui sont [accent]optionels[]. +hint.coreIncinerate = Lorsqu'un Noyau est remplit d'une ressource en particulier, le surplus qui rentrera dans celui-ci sera [accent]incinéré[]. +hint.coopCampaign = Quand vous jouez en [accent]campagne multi-joueur[], les ressources produites dans le secteur dans lequel vous jouez sera aussi envoyé [accent]dans vos secteurs[].\n\nLes recherches faites par l'hôte sont aussi partagées. -item.copper.description = Le matériau structurel de base. Utilisation très répandue dans tous les types de blocs. +item.copper.description = Le matériau structurel de base. Utilisation très répandue dans tous les types de blocs et en tant que munition. +item.copper.details = Le cuivre est un matériau anormalement abondant sur Serpulo. Il est structurellement faible à moins d'être renforcé. item.lead.description = Un matériau de départ. Utilisation très répandue en électronique et dans les blocs de transport de liquides. +item.lead.details = Dense et inerte, il est beaucoup utilisé dans les batteries.\nNote: Probablement toxique pour les formes de vie biologiques. Mais ce n'est pas comme s’il en restait beaucoup ici. item.metaglass.description = Un composé de verre super-résistant. Utilisation très répandue pour le transport et le stockage de liquides. -item.graphite.description = Du carbone minéralisé utilisé pour les munitions et l’isolation électrique. -item.sand.description = Un matériau commun largement utilisé dans la fonte, à la fois dans l'alliage et comme un flux. -item.coal.description = De la matière végétale fossilisée, formée bien avant l’ensemencement de ce monde. Utilisation très répandue pour la production de carburant et de ressources. -item.titanium.description = Un métal rare et super-léger largement utilisé dans le transport de liquides, dans les foreuses de hauts niveaux et dans l'aviation. -item.thorium.description = Un métal dense et radioactif utilisé comme support structurel et comme carburant nucléaire. -item.scrap.description = Un mix de métaux provenant des restes de vieilles structures et d'unités. Contient des traces de nombreux métaux différents. +item.graphite.description = Du carbone minéralisé utilisé pour les munitions et dans les composants électriques. +item.sand.description = Un matériau commun, largement utilisé pour la fabrication de matériaux raffinés. +item.coal.description = Un carburant commun et facile à obtenir. +item.coal.details = De la matière végétale fossilisée, formée bien avant l’ensemencement de ce monde. Utilisation très répandue pour la production de carburant et de ressources. +item.titanium.description = Un métal rare et super-léger, largement utilisé dans le transport de liquides, dans les foreuses de haut niveau et dans l'aviation. +item.thorium.description = Un métal dense et radioactif, utilisé comme support structurel et comme carburant nucléaire. +item.scrap.description = Il est utilisé dans les fours à fusion et les pulvériseurs, pour être raffiné en d'autres matériauxs. +item.scrap.details = Un mix de métaux provenant des restes de vieilles structures et d'unités. Contient des traces de nombreux métaux différents. item.silicon.description = Un matériau semi-conducteur extrêmement pratique utilisé dans les panneaux solaires, dans les munitions autoguidées et dans beaucoup d'autres composants électroniques complexes. -item.plastanium.description = Un matériau léger et ductile utilisé dans l'aviation avancée et dans les munitions à fragmentation. -item.phase-fabric.description = Une substance au poids quasiment inexistant utilisée pour l'électronique avancée et la technologie auto-réparatrice. -item.surge-alloy.description = Un alliage avancé avec des propriétés électriques uniques. -item.spore-pod.description = Une glande de spores synthétisées à partir de concentrations atmosphériques à des fins industrielles et utilisé pour la conversion en pétrole, en explosifs et en carburant. -item.blast-compound.description = Un composé instable synthétisé à partir de glandes de spores ou bien d'autres composés volatils et utilisé dans les bombes ainsi que dans les autres explosifs. Bien qu'il puisse être utilisé comme carburant, ce n'est pas conseillé. -item.pyratite.description = Une substance extrêmement inflammable utilisée dans les armes incendiaires. +item.plastanium.description = Un matériau léger et ductile, utilisé dans l'isolation, la fabrication d'unités avancées et dans les munitions à fragmentation. +item.phase-fabric.description = Une substance au poids quasiment inexistant, utilisée pour l'électronique avancée et la technologie auto-réparatrice. +item.surge-alloy.description = Un alliage avancé aux propriétés électriques uniques, utilisé dans l'armement avancé. +item.spore-pod.description = Les bulbes sporifères sont utilisés pour l'obtention d'huile, d'explosifs et de carburants. +item.spore-pod.details = Les spores dont des formes de vies synthetiques, émettant des gaz qui sont toxiques pour les autres formes de vie biologiques. Elles sont extrêmement invasives et Très inflammables dans certaines conditions. +item.blast-compound.description = Un matériau utilisé dans les bombes et les munitions explosives. +item.pyratite.description = Une substance extrêmement inflammable utilisée dans les armes incendiaires et comme combustible pour les générateurs. + liquid.water.description = Le liquide le plus utile. Couramment utilisé pour le refroidissement et le traitement des déchets. liquid.slag.description = Différents types de métaux en fusion mélangés. Peut être séparé en ses minéraux constitutifs ou tout simplement pulvérisé sur les unités ennemies. liquid.oil.description = Un liquide utilisé dans la production de matériaux avancés. Peut être transformé en charbon ou pulvérisé sur les ennemis, puis enflammé. liquid.cryofluid.description = Un liquide inerte, non corrosif, créé à partir d’eau et de titane. Possède une capacité d'absorption de chaleur extrêmement élevée. Largement utilisé comme liquide de refroidissement. -block.message.description = Enregistre un message. Utilisé pour la communication entre alliés. -block.graphite-press.description = Compresse des morceaux de charbon en feuilles de graphite pur. -block.multi-press.description = Une version améliorée de la presse à graphite. Utilise de l'eau et de l'électricité pour traiter le charbon rapidement et efficacement. -block.silicon-smelter.description = Réduit le sable avec du charbon pur. Produit du silicium. -block.kiln.description = Fait fondre le sable et le plomb en verre trempé. Nécessite une petite quantité d'énergie. +block.resupply-point.description = Approvisionne les unités proches en munitions. Pas compatible avec celles qui ont besoin d'énergie pour tirer. +block.illuminator.description = Une petite source lumineuse compacte et configurable. Nécessite de l'énergie pour fonctionner. +block.armored-conveyor.description = Déplace les objets à la même vitesse que les convoyeurs en titane, mais est plus résistant. Seulement d'autres convoyeurs peuvent faire entrer des ressources par ses côtés. +block.message.description = Enregistre un message. Utilisé pour la communication entre alliés. Le message contenu peut être modifié par un processeur logique. +block.graphite-press.description = Compresse le charbon en graphite. +block.multi-press.description = Une version améliorée de la presse à graphite, utilisant de l'eau et de l'électricité pour traiter le charbon plus rapidement et plus efficacement. +block.silicon-smelter.description = Raffine du silicium avec du sable et du charbon. +block.kiln.description = Fait fondre le sable et le plomb en verre trempé. block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane. -block.phase-weaver.description = Produit du tissu phasé à partir de thoriums et de grandes quantités de sable. Nécessite une quantité massive d'énergie pour fonctionner. +block.phase-weaver.description = Synthétise du tissu phasé à partir de thorium et de grandes quantités de sable. Nécessite une quantité massive d'énergie pour fonctionner. block.alloy-smelter.description = Produit un alliage superchargé à l'aide de titane, de plomb, de silicium et de cuivre. -block.cryofluid-mixer.description = Mélange de l’eau et de la fine poudre de titane pour former du liquide cryogénique. Indispensable lors de l'utilisation de réacteurs aux thoriums. -block.blast-mixer.description = Écrase et mélange les amas de spores avec de la pyratite pour produire un mélange explosif. -block.pyratite-mixer.description = Mélange le charbon, le plomb et le sable en pyratite hautement inflammable. -block.melter.description = Fait fondre la ferraille en scories pour un traitement ultérieur ou une utilisation dans les tourelles « Onde ». +block.cryofluid-mixer.description = Mélange de l’eau et de la poudre fine de titane pour former du liquide cryogénique. Indispensable lors de l'utilisation de réacteurs à thorium. +block.blast-mixer.description = Écrase et mélange des amas de spores avec de la pyratite pour produire un mélange explosif. +block.pyratite-mixer.description = Mélange du charbon, du plomb et du sable en pyratite hautement inflammable. +block.melter.description = Fait fondre la ferraille en scories. block.separator.description = Expose la scorie à de l'eau sous pression afin d'obtenir les différents minéraux qu'elle contient. -block.spore-press.description = Compresse les glandes de spore sous une pression extrême pour synthétiser du pétrole. +block.spore-press.description = Compresse des spores pour synthétiser du pétrole. block.pulverizer.description = Écrase la ferraille pour en faire du sable. Utile quand il y a un manque de sable naturel. block.coal-centrifuge.description = Solidifie le pétrole en blocs de charbon. -block.incinerator.description = Permet de se débarrasser de n'importe quel objet ou liquide en excès. +block.incinerator.description = Incinère ou vaporise n'importe quel objet ou liquide qu'il reçoit. block.power-void.description = Absorbe toute l'énergie qui va à l'intérieur. Bac à sable uniquement. block.power-source.description = Produit de l'énergie à l'infini. Bac à sable uniquement. -block.item-source.description = Produit des objets à l'infini. Bac à sable uniquement . +block.item-source.description = Produit des objets à l'infini. Bac à sable uniquement. block.item-void.description = Désintègre n'importe quel objet qui va à l'intérieur. Bac à sable uniquement. block.liquid-source.description = Source de liquide infinie. Bac à sable uniquement. block.liquid-void.description = Détruit n'importe quel liquide. Bac à sable uniquement. block.copper-wall.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles lors des premières vagues. -block.copper-wall-large.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles lors des premières vagues.\n2 x 2. -block.titanium-wall.description = Un bloc défensif standard.\nProcure une protection modérée contre les ennemis. -block.titanium-wall-large.description = Un bloc défensif standard.\nProcure une protection modérée contre les ennemis.\n2 x 2. -block.plastanium-wall.description = Un mur spécial qui absorbe les arcs électriques et bloque les connections automatiques des transmetteurs énergétiques. -block.plastanium-wall-large.description = Un mur spécial qui absorbe les arcs électriques et bloque les connections automatiques des transmetteurs énergétiques.\n2 x 2. -block.thorium-wall.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis. -block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les ennemis.\n2 x 2. -block.phase-wall.description = Moins puissant qu'un mur en Thorium mais dévie les balles, sauf si elles sont trop puissantes. -block.phase-wall-large.description = Moins puissant qu'un mur en Thorium mais dévie les balles, sauf si elles sont trop puissantes.\n2 x 2. -block.surge-wall.description = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis . -block.surge-wall-large.description = Le plus puissant bloc défensif .\nA une faible chance de créer des éclairs vers les ennemis .\n2 x 2. -block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte les ennemis peuvent tirer et passer à travers. -block.door-large.description = Une large porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte les ennemis peuvent tirer et passer à travers.\n2 x 2. -block.mender.description = Soigne périodiquement les bâtiments autour de lui. Permet de garder les défenses en bon état entre les vagues ennemies.\nPeut utiliser du Silicium pour booster la portée et l'efficacié. -block.mend-projector.description = Une version améliorée du Réparateur. Soigne périodiquement les bâtiments autour de lui.\nPeut utiliser du tissu phasé pour booster la portée et l'efficacié. -block.overdrive-projector.description = Accélère le fonctionnement des bâtiments autour de lui, notamment les foreuses et les convoyeurs.\nPeut utiliser du tissu phasé pour booster la portée et l'efficacié. -block.force-projector.description = Crée un champ de force hexagonal autour de lui qui protège des dégâts les bâtiments et les unités à l'intérieur.\nSurchauffe si trop de dégâts sont reçus. Peut utiliser du liquide cryogénique pour éviter la surchauffe. Peut utiliser du tissu phasé pour booster la taille du bouclier. -block.shock-mine.description = Blesse les ennemis qui marchent dessus. Quasiment invisible pour l'ennemi. +block.copper-wall-large.description = Un bloc défensif à faible coût.\nUtile pour protéger la base et les tourelles lors des premières vagues. +block.titanium-wall.description = Un bloc défensif standard.\nProcure une protection modérée contre les attaques ennemies. +block.titanium-wall-large.description = Un bloc défensif standard.\nProcure une protection modérée contre les attaques ennemies. +block.plastanium-wall.description = Un mur spécial qui peut absorber les arcs électriques et bloquer les connections automatiques des transmetteurs énergétiques. +block.plastanium-wall-large.description = Un mur spécial qui absorber les arcs électriques et bloquer les connections automatiques des transmetteurs énergétiques. +block.thorium-wall.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les attaques ennemies. +block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les attaques ennemies. +block.phase-wall.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes. +block.phase-wall-large.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes. +block.surge-wall.description = Le plus puissant bloc défensif.\nA une faible chance de créer des éclairs vers les ennemis. +block.surge-wall-large.description = Le plus puissant bloc défensif.\nA une faible chance de créer des éclairs vers les ennemis. +block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers. +block.door-large.description = Une grande porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers. +block.mender.description = Soigne périodiquement les bâtiments autour de lui, ce qui permet de remettre les défenses en bon état entre les vagues ennemies.\nPeut utiliser du silicium pour booster la portée et l'efficacité. +block.mend-projector.description = Une version améliorée du Gardien. Soigne périodiquement les bâtiments autour de lui.\nPeut utiliser du tissu phasé pour booster la portée et l'efficacité. +block.overdrive-projector.description = Accélère le fonctionnement des bâtiments autour de lui, notamment les foreuses et les convoyeurs.\nPeut utiliser du tissu phasé pour booster la portée et l'efficacité. +block.force-projector.description = Crée un champ de force hexagonal autour de lui, qui protège des dégâts les bâtiments et les unités à l'intérieur.\nSurchauffe si trop de dégâts sont reçus. De l'eau ou du liquide cryogénique peuvent être utilisés pour ralentir la surchauffe et/ou accélérer le refroidissement. Peut utiliser du tissu phasé pour booster la taille du bouclier. +block.shock-mine.description = Blesse les ennemis qui marchent dessus. block.conveyor.description = Convoyeur basique servant à transporter des objets. Les objets déplacés en avant sont automatiquement déposés dans les tourelles ou les bâtiments. Peut être tourné. -block.titanium-conveyor.description = Convoyeur avancé. Déplace les objets plus rapidement que les convoyeurs standard. -block.plastanium-conveyor.description = Moves items in batches.\nAccepts items at the back, and unloads them in three directions at the front. +block.titanium-conveyor.description = Convoyeur avancé. Déplace les objets plus rapidement que les convoyeurs standards. +block.plastanium-conveyor.description = Convoyeur transportant les ressources par paquets. Accepte les ressources par derrière et les déchargent par 3 directions à l'avant. Pour une efficacité maximale, utilisez plusieurs points de chargement et de déchargement pour une même ligne. block.junction.description = Agit comme un pont pour deux lignes de convoyeurs se croisant. Utile lorsque deux lignes de convoyeurs différentes déplacent différents matériaux à différents endroits. -block.bridge-conveyor.description = Bloc de transport avancé permettant de traverser jusqu'à 3 blocs de n'importe quel terrain ou bâtiment. -block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un convoyeur phasé connecté jusqu'à une longue distance. +block.bridge-conveyor.description = Bloc de transport avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment. +block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un autre convoyeur phasé. Possède une longue portée. block.sorter.description = Trie les ressources. Si une ressource correspond à la sélection, elle peut passer tout droit. Autrement, elle est distribuée vers la gauche ou la droite. -block.inverted-sorter.description = Trie les ressources comme un trieur standard, mais ceux correspondant à la sélection sont envoyés sur les côtés. Le reste est envoyé tout droit. -block.router.description = Accepte les objets depuis une ou plusieurs directions et les renvoie dans n'importe quelle direction. Utile pour séparer une chaîne de convoyeurs en plusieurs. -block.distributor.description = Un routeur avancé qui répartit équitablement les objets entre au plus 7 directions différentes.\n2x2 -block.overflow-gate.description = Bloc envoyant les ressources à gauche et à droite si le chemin de devant est bloqué. -block.underflow-gate.description = Le contraire d'une barrière de débordement.\nEnvoie les ressources vers l'avant si les chemins de gauche et de droite sont bloqués. -block.mass-driver.description = Le moyen de transport de resources ultime. Collecte plusieurs ressources puis les envoie à une autre catapulte sur une longue distance. Nécessite de l'énergie pour fonctionner. -block.mechanical-pump.description = Une pompe de faible prix pompant lentement, mais ne consommant pas d'énergie. -block.rotary-pump.description = Une pompe avancée plus rapide mais utilisant de l'énergie.\n2x2 -block.thermal-pump.description = La pompe ultime.\n3x3 -block.conduit.description = Bloc de transport de liquide de base. Fait avancer les liquides. Utilisé avec des pompes et autres conduits. +block.inverted-sorter.description = Trie les ressources comme un trieur standard, mais celles qui correspondent à la sélection sont envoyées sur les côtés. Le reste est envoyé tout droit. +block.router.description = Accepte les objets depuis une ou plusieurs directions et les renvoie équitablement dans n'importe quelle direction. Utile pour séparer une chaîne de convoyeurs en plusieurs. +block.router.details = Un mal nécessaire... Utiliser un routeur à côté d'une usine est très déconseillé, car ceux-ci peuvent être bloqués par les matériaux produits par celle-ci. +block.distributor.description = Un routeur avancé qui répartit équitablement les objets jusqu'à 7 directions différentes. +block.overflow-gate.description = Bloc envoyant les ressources à gauche et à droite si le chemin de devant est bloqué. Ne peut pas être utilisée si elle est à côté d'une autre barrière. +block.underflow-gate.description = Le contraire d'une barrière de débordement. Envoie les ressources vers l'avant si les chemins de gauche et de droite sont bloqués. Ne peut pas être utilisée si elle est à côté d'une autre barrière. +block.mass-driver.description = Le moyen de transport de ressources ultime! Cette structure collecte des lots de ressources et les envoie à un autre transporteur de masse, sur une longue distance. Nécessite de l'énergie pour fonctionner. +block.mechanical-pump.description = Une pompe basique et bon marché qui pompe lentement des liquides. Elle ne consomme pas d'énergie. +block.rotary-pump.description = Une pompe avancée, plus rapide, mais utilisant de l'énergie. +block.thermal-pump.description = La pompe ultime. +block.conduit.description = Bloc de transport de liquide de base, faisant avancer les liquides. Utilisé avec des pompes et autres conduits. block.pulse-conduit.description = Conduit avancé permettant le transport de liquide. Transporte les liquides plus rapidement et en stocke plus que les conduits standards. -block.plated-conduit.description = Déplace les liquides au même rythme que les conduits à impulsion, mais est renforcé. N'accepte pas de liquides provenant des côtés par autre chose que des conduits.\nFuit moins. -block.liquid-router.description = Accepte les liquides depuis une direction et les rejette de tous les côtés équitablement. Peut aussi stocker une certaine quantité de liquide. Utile pour envoyer un liquide à plusieurs endroits. -block.liquid-tank.description = Stocke une grande quantité de liquide. Utile pour réguler la sortie quand la demande est inconstante ou comme sécurité pour refroidir des bâtiments importants. -block.liquid-junction.description = Agit comme une jonction pour deux conduits se croisant. Utile si deux conduits amènent différents liquides à différents endroits. -block.bridge-conduit.description = Bloc de transport de liquide avancé. Permet le transport de liquides à travers 3 blocs de n'importe quel terrain ou bâtiment au plus. +block.plated-conduit.description = Déplace les liquides au même rythme que les conduits à impulsion, mais est renforcé et empêche les fuites en cas de rupture. N'accepte pas les liquides provenant des côtés, seuls les autres conduits peuvent le faire. +block.liquid-router.description = Accepte les liquides depuis une direction et les distribue jusqu'à 3 directions équitablement. Utile pour envoyer un liquide à plusieurs endroits. Peut aussi stocker une certaine quantité de liquide. +block.liquid-tank.description = Stocke une grande quantité de liquide et peut les distribuer dans tous les côtés, un peu comme un routeur liquide.\nUtile pour réguler la sortie quand la demande en liquide si elle est inconstante ou comme sécurité pour refroidir des bâtiments importants. +block.liquid-junction.description = Agit comme un pont pour deux conduits se croisant. Utile si deux conduits amènent différents liquides à différents endroits. +block.bridge-conduit.description = Bloc de transport de liquide avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment. block.phase-conduit.description = Conduit très avancé permettant le transport de liquide. Utilise de l'énergie pour téléporter les liquides à un autre conduit phasé sur une longue distance. -block.power-node.description = Transmet l'énergie aux transmetteurs énergétiques connectés. Le transmetteur recevra de l'énergie ou la transmettra à n'importe quel bâtiment adjacent, mais la connexion peut être activé/désactivé manuellement -block.power-node-large.description = Possède un rayon plus grand que le transmetteur énergétique standard, connectant d'autant plus de consommateurs ou transmetteurs d'énergie. +block.power-node.description = Transmet de l'énergie aux autres transmetteurs énergétiques connectés. Le transmetteur recevra de l'énergie ou la transmettra à n'importe quel bâtiment adjacent. La connexion peut être activée/désactivée manuellement. +block.power-node-large.description = Ce transmetteur possède un rayon plus grand que le transmetteur énergétique standard. Il peut aussi accepter plus de connexions. block.surge-tower.description = Un transmetteur énergétique de très grande portée mais avec moins de connections disponibles. -block.diode.description = L'énergie ne peut circuler à travers ce bloc que dans un sens, et uniquement si l’autre côté présente moins d’énergie en stock. +block.diode.description = L'énergie ne circule que dans un sens à travers ce bloc, et uniquement si l’autre côté présente moins d’énergie en stock. Idéal pour protéger les lieux de production d'énergie. block.battery.description = Stocke le surplus d'énergie et le redistribue en cas de besoin. -block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale. +block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale. block.combustion-generator.description = Génère de l'énergie en brûlant du charbon ou d'autres matériaux inflammables. block.thermal-generator.description = Génère une grande quantité d'énergie à partir de zones de chaleur. block.steam-generator.description = Plus efficace qu'un générateur à combustion, mais requiert de l'eau. block.differential-generator.description = Génère de grandes quantités d'énergie en utilisant la différence de température entre le liquide cryogénique et la pyratite brûlante. -block.rtg-generator.description = Un générateur thermo-électrique à radioisotope qui ne demande pas de refroidissement mais produit moins d'énergie qu'un réacteur à Thorium. +block.rtg-generator.description = Un générateur thermo-électrique à radioisotope qui ne demande pas de refroidissement, mais produit moins d'énergie qu'un réacteur à Thorium. block.solar-panel.description = Génère une faible quantité d'énergie grâce aux rayons du soleil. block.solar-panel-large.description = Génère bien plus d'énergie qu'un panneau solaire standard, mais est aussi bien plus cher à construire. block.thorium-reactor.description = Génère énormément d'énergie à l'aide de la radioactivité du thorium. Requiert néanmoins un refroidissement constant. Explosera violemment en cas de surchauffe. -block.impact-reactor.description = Un générateur avancé, capable de produire une quantité d'énergie gigantesque lorsqu'il atteint son efficacité maximale. Nécessite une quantité significative d'énergie pour lancer le générateur. -block.mechanical-drill.description = Une foreuse de faible coût. Si elle est placée sur un endroit approprié, produit des matériaux lentement à l'infini. -block.pneumatic-drill.description = Une foreuse améliorée plus rapide et capable de forer des matériaux plus durs comme le titane grâce à l'usage de vérins à air comprimé. -block.laser-drill.description = Permet de forer bien plus vite grâce à la technologie laser, mais requiert de l'énergie . Permet de miner le Thorium, un matériau radioactif. -block.blast-drill.description = La Foreuse ultime . Demande une grande quantité d'énergie. -block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'eau à proximité. -block.cultivator.description = Cultive le sol avec de l'eau afin d'obtenir de la biomasse. -block.oil-extractor.description = Utilise une grande quantité d'énergie afin d'extraire du pétrole à partir de sable. Utile quand il n'y a pas de lacs de pétrole à proximité. -block.core-shard.description = La première version du noyau. Une fois détruite tout contact avec la région est perdu. Ne laissez pas cela se produire. -block.core-foundation.description = La deuxième version du noyau. Meilleur blindage. Stocke plus de ressources. -block.core-nucleus.description = La troisième et dernière version du noyau. Extrêmement bien blindée. Stocke des quantités importantes de ressources. -block.vault.description = Stocke un grand nombre d'objets. Utile pour réguler le flux d'objets quand la demande de matériaux est inconstante. Un [lightgray] déchargeur[] peut être utilisé pour récupérer des objets depuis le coffre-fort. -block.container.description = Stocke un petit nombre d'objets. Utile pour réguler le flux d'objets quand la demande de matériaux est inconstante. Un [lightgray] déchargeur[] peut être utilisé pour récupérer des objets depuis le conteneur. -block.unloader.description = Décharge des objets depuis des conteneurs, coffres-forts ou d'un noyau sur un convoyeur ou directement dans un bloc adjacent. Le type d'objet peut être changé en appuyant sur le déchargeur. -block.launch-pad.description = Permet de transférer des ressources sans attendre le lancement du noyau. -block.launch-pad-large.description = Une version améliorée de la plateforme de lancement. Stocke plus de ressources et les envoie plus fréquemment. +block.impact-reactor.description = Ce réacteur est capable de produire de gigantesques quantités d'énergie lorsqu'il atteint son efficacité maximale. Nécessite une quantité significative d'énergie pour pouvoir le démarrer. +block.mechanical-drill.description = Une foreuse basique. Si elle est placée sur un endroit approprié, elle produira des matériaux lentement et indéfiniment. +block.pneumatic-drill.description = Une foreuse améliorée, plus rapide et capable de forer des minerais plus durs comme le titane. +block.laser-drill.description = Permet de forer bien plus vite grâce à la technologie laser, mais requiert de l'énergie pour fonctionner. Permet de miner du Thorium, un matériau radioactif. +block.blast-drill.description = La Foreuse ultime. Demande une grande quantité d'énergie pour fonctionner. +block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'étendue d'eau à proximité. +block.cultivator.description = Cultive une petite quantité de spores atmosphériques afin de former des bulbes sporifères. +block.cultivator.details = Technologie de récupération. Utilisée pour produire des quantités massives de biomasse aussi efficacement que possible. Probablement l’incubateur initial des spores qui couvrent maintenant Serpulo. +block.oil-extractor.description = Utilise de grandes quantités d'énergie pour extraire le pétrole du sable. Utilisez-le lorsqu'il n'y a pas de source directe de pétrole à proximité. +block.core-shard.description = Le coeur de votre base. Une fois détruit, le secteur est perdu. Ne laissez pas cela arriver. +block.core-shard.details = La première version du Noyau. Il est compact, doté d'un module d'auto-réplication et est équippé de propulseurs de lancement à usage unique. Equipped with single-use launch thrusters. Ceux-ci n'ont pas été conçus pour le voyage interplanétaire. +block.core-foundation.description = Le coeur de votre base. Cette version améliorée possède un meilleur blindage et stocke plus de ressources qu'un Noyau fragment. +block.core-foundation.details = La seconde version. +block.core-nucleus.description = Le coeur de votre base. Ce Noyau est extrêmement bien blindé et stocke des quantités massives de ressources. +block.core-nucleus.details = La version finale. +block.vault.description = Stocke un grand nombre d'objets de chaque type. Utilisez un déchargeur pour les récupérer.\nUtile pour réguler le flux d'objets quand la demande de matériaux est inconstante. +block.container.description = Stocke un petit nombre d'objets de chaque type. Utilisez un déchargeur pour les récupérer.\nUtile pour réguler le flux d'objets quand la demande de matériaux est inconstante. +block.unloader.description = Permet de décharger l'objet choisi, depuis les blocs adjacents. +block.launch-pad.description = Permet de transférer des ressources vers les secteurs sélectionnés. block.duo.description = Une petite tourelle à faible coût. Fonctionne bien contre les ennemis terrestres. block.scatter.description = Une tourelle anti-aérienne essentielle. Mitraille les ennemis de débris de plomb, de ferraille ou de verre trempé. block.scorch.description = Brûle les ennemis terrestres près de lui. Très efficace à courte portée. -block.hail.description = Une petite tourelle d'artillerie. Efficace à longue portée. -block.wave.description = Une tourelle de taille moyenne tirant rapidement des jets de liquide. Peut éteindre les incendies si elle est alimentée en eau. +block.hail.description = Une petite tourelle d'artillerie visant les ennemis terrestres. Efficace à longue portée. +block.wave.description = Une tourelle de taille moyenne tirant un jet de liquide. Peut éteindre les incendies automatiquement si elle est alimentée en eau. block.lancer.description = Une tourelle de taille moyenne chargeant et tirant de puissants lasers aux ennemis terrestres. -block.arc.description = Une petite tourelle de petite portée tirant des arcs électriques sur les ennemis. -block.swarmer.description = Une tourelle de taille moyenne attaquant les ennemis terrestres et aériens à l'aide de missiles autoguidés. +block.arc.description = Une petite tourelle tirant des arcs électriques sur les ennemis. +block.swarmer.description = Une tourelle de taille moyenne attaquant les ennemis terrestres et aériens à l'aide de missiles autoguidés. Consomme beaucoup de munitions. block.salvo.description = Une version plus grande et améliorée de la tourelle Duo. Tire par salves. block.fuse.description = Une tourelle de grande taille et de petite portée. Elle perce les lignées ennemis avec ses trois tirs de sharpnel. -block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs salves simultanément sur de très longues distances. -block.cyclone.description = Une grande tourelle qui tire rapidement des débris explosifs aux ennemis terrestres et aériens. -block.spectre.description = Une tourelle massive à double cannon et qui tire de puissantes balles perce-blindages simultanément. +block.ripple.description = Lance des amas d’obus sur les ennemis terrestres sur de très longues distances. +block.cyclone.description = Une grande tourelle qui tire rapidement des balles explosives aux ennemis proches. +block.spectre.description = Une tourelle massive à double cannon qui tire de puissantes balles perçantes. block.meltdown.description = Une tourelle massive chargeant et tirant de puissants rayons lasers. Nécessite un liquide de refroidissement. +block.foreshadow.description = Une tourelle massive tirant une puissante balle sur une cible, sur de très longues distances. Elle vise les unités ayant le plus de santé en priorité. block.repair-point.description = Soigne en permanence l'unité endommagée la plus proche à proximité. -block.segment.description = Endommage et détruit les tirs ennemis. Cependant, les lasers ne peuvent pas être ciblés. +block.segment.description = Endommage et détruit les tirs ennemis. Les lasers ne peuvent pas être ciblés. +block.parallax.description = Tire un rayon tracteur qui attire les ennemis volants, infligeant aussi des dégâts. +block.tsunami.description = Tire un puissant jet de liquide aux ennemis. Peut éteindre les incendies automatiquement si elle est alimentée en eau. +block.silicon-crucible.description = Raffine du silicium avec du sable et du charbon en utilisant de la pyratite comme source de chaleur additionelle. Cette usine est plus efficace dans les endroits chauds. +block.disassembler.description = Cette verion avancée du séparateur peut produire du thorium. +block.overdrive-dome.description = Accélère le fonctionnement des bâtiments autour de lui. Requiert du silicium et du tissu phasé pour fonctionner. +block.payload-conveyor.description = Ce grand convoyeur peut déplacer de gros chargements, comme des unité depuis leurs usines ou bien des conteneurs. +block.payload-router.description = Distribue les chargements qui entrent dans 3 directions différentes. +block.command-center.description = Contrôle le comportement des unités avec plusieurs commandes différentes. +block.ground-factory.description = Produit des unités terrestres. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées. +block.air-factory.description = Produit des unités aériennes. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées. +block.naval-factory.description = Produit des unités navales. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées. +block.additive-reconstructor.description = Améliore les unités entrantes au second niveau. +block.multiplicative-reconstructor.description = Améliore les unités entrantes au troisième niveau. +block.exponential-reconstructor.description = Améliore les unités entrantes au quatrième niveau. +block.tetrative-reconstructor.description = Améliore les unités entrantes au cinquième niveau. +block.switch.description = Un interupteur pouvant être activé/désactivé. Le statut peut être lu et controllé avec des processeurs logiques. +block.micro-processor.description = Exécute une séquence d'instructions en bloucle. Peut être utilisé pour controller des unités ou des bâtiments. +block.logic-processor.description = Exécute une séquence d'instructions en bloucle. Peut être utilisé pour controller des unités ou des bâtiments. Plus rapide qu'un micro processeur. +block.hyper-processor.description = Exécute une séquence d'instructions en bloucle. Peut être utilisé pour controller des unités ou des bâtiments. Plus rapide qu'un processeur. +block.memory-cell.description = Stocke des informations pour un processeur logique. +block.memory-bank.description = Stocke des informations pour un processeur logique. Possède une plus grande capacité. +block.logic-display.description = Affiche des images à partir des instructions d'un processeur logique. +block.large-logic-display.description = Affiche des images à partir des instructions d'un processeur logique. Possède une plus grande résolution qu'un écran. +block.interplanetary-accelerator.description = Un énorme canon électromagnétique à rails. Accélère les Noyaux pour qu'ils échappent à la gravité de leur planète et leur permettre un déploiement interplanétaire. + +unit.dagger.description = Tire des balles normales aux ennemis proches. +unit.mace.description = Tire des jets de flammes aux ennemis proches. +unit.fortress.description = Tire des balles d’artillerie à longue portée, sur des cibles terrestres. +unit.scepter.description = Tire un barrage de balles superchargées aux ennemis proches. +unit.reign.description = Tire un barrage de grosses balles perçantes aux ennemis proches. +unit.nova.description = Tire des balles laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler. +unit.pulsar.description = Tire des arcs électriques qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler. +unit.quasar.description = Tire des faisceaux laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler et est dotée d'un champ de force. +unit.vela.description = Tire un rayon laser continu qui inflige des dégâts aux ennemis, cause des incendies aux structures ennemies et répare les structures alliées. Est capable de voler. +unit.corvus.description = Tire un rayon laser massif qui inflige des dégâts aux ennemis et répare les structures alliées. Peut marcher sur de la plupart des terrains. +unit.crawler.description = Court vers un ennemi proche pour s'auto-détruire, causant une large explosion. +unit.atrax.description = Tire des orbes débilitants de scories sur des cibles terrestres. Peut marcher sur de la plupart des terrains. +unit.spiroct.description = Tire des faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur de la plupart des terrains. +unit.arkyid.description = Tire de larges faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur de la plupart des terrains. +unit.toxopid.description = Tire de larges obus électriques et des lasers perçants aux ennemis proches. Peut marcher sur de la plupart des terrains. +unit.flare.description = Tire des balles normales cibles terrestres. +unit.horizon.description = Largue des bombes sur des cibles terrestres. +unit.zenith.description = Tire des salves de missiles sur les ennemis proches. +unit.antumbra.description = Tire un barrage de balles aux ennemis proches. +unit.eclipse.description = Tire 2 lasers perçants et un barrage de balles explosives aux ennemis proches. +unit.mono.description = Mine automatiquement du cuivre et du plomb et le dépose dans un Noyau proche. +unit.poly.description = Reconstruit automatiquement les structures détruites (sauf les réacteurs au thorium) et assiste les autres unités lorsqu'elles construisent. +unit.mega.description = Répare automatiquement les structures endommagées. Capable de transporter des blocs et de petites unités terrestres. +unit.quad.description = Largue de grosses bombes sur des cibles terrestres, réparant les structures alliées et infligeant des dégâts aux ennemis. Capable de transporter des blocs et des unités terrestres de taille moyenne. +unit.oct.description = Protège les alliés proches avec son champ de force auto-regénérant. Capable de transporter des blocs et de grosses unités terrestres. +unit.risso.description = Tire un barrage de missiles et de balles aux ennemis proches. +unit.minke.description = Tire des obus et des balles normales aux ennemis proches. +unit.bryde.description = Tire des obus d'artillerie à longue portée et des missiles aux ennemis proches. +unit.sei.description = Tire un barrage de missiles et de balles perçantes aux ennemis proches. +unit.omura.description = Tire avec un canon à rails à longue portée, une puissante balle perçante aux ennemis proches. Possède une usine à flares. +unit.alpha.description = Défend le Noyau fragment contre les ennemis. Peut construire des structures. +unit.beta.description = Défend le Noyau fondation contre les ennemis. Peut construire des structures. +unit.gamma.description = Défend le Noyau épicentre contre les ennemis. Peut construire des structures. diff --git a/core/assets/bundles/bundle_fr_BE.properties b/core/assets/bundles/bundle_fr_BE.properties deleted file mode 100644 index 8975031cb6..0000000000 --- a/core/assets/bundles/bundle_fr_BE.properties +++ /dev/null @@ -1,1335 +0,0 @@ -credits.text = Créé par [royal]Anuken[] - [sky]anukendev@gmail.com[] -credits = Crédits -contributors = Traducteurs et contributeurs -discord = Rejoignez le discord de Mindustry ! -link.discord.description = Le discord officiel de Mindustry -link.reddit.description = Le subreddit de Mindustry -link.github.description = Code source du jeu -link.changelog.description = Liste des mises à jour -link.dev-builds.description = Versions instables de développement -link.trello.description = Trello officiel pour les fonctionnalités planifiées. -link.itch.io.description = Site itch.io avec les versions téléchargeables pour ordinateur. -link.google-play.description = Page Google Play du jeu -link.f-droid.description = F-Droid catalogue listing -link.wiki.description = Wiki officiel de Mindustry -link.suggestions.description = Suggérer des nouvelles fonctionallitées -linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre presse-papier. -screenshot = Capture d'écran enregistrée sur {0} -screenshot.invalid = Carte trop grande, potentiellement pas assez de mémoire pour la capture d'écran. -gameover = Le base a été détruite. -gameover.pvp = L'équipe[accent] {0}[] a gagnée ! -highscore = [accent]Nouveau meilleur score ! -copied = Copié. -indev.popup = [accent]La v6[] est actuellement en [accent]alpha[].\n[lightgray]Cela signifie :[]\n[scarlet]- La campagne est totalement incomplète[]\n- Il manque du contenu\n - La plupart des [scarlet]IA d'unités[] ne fonctionne pas correctement\n- De nombreuses unités ne sont pas terminées\n- Tout ce que vous voyez est susceptible d'être modifié ou supprimé.\n\nMerci de rapporter les bugs/crash sur [accent]Github[]. -indev.notready = Cette partie du jeu n'est pas encore prête - -load.sound = Son -load.map = Maps -load.image = Images -load.content = Contenu -load.system = Système -load.mod = Mods -load.scripts = Scripts - -be.update = Une nouvelle version est disponible: -be.update.confirm = Voulez vous la télécharger et recommencer maintenant ? -be.updating = En train de mettre à jour... -be.ignore = Ignorer -be.noupdates = Aucune mise à jour n'as été trouvée. -be.check = Chercher des mises à jour - -schematic = Schéma -schematic.add = Enregistrer Schéma... -schematics = Schémas -schematic.replace = Un schéma avec ce nom existe déjà. Voulez vous le remplacer ? -schematic.exists = Un schéma avec ce nom existe déjà. -schematic.import = Importer le Schéma... -schematic.exportfile = Exporter Dossier -schematic.importfile = Importer Dossier -schematic.browseworkshop = Parcourir l'Atelier -schematic.copy = Copier dans le presse-papier -schematic.copy.import = Importer du presse-papier -schematic.shareworkshop = Partager sur l'Atelier -schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Retourner Schéma -schematic.saved = Schéma enregistré. -schematic.delete.confirm = Ce Schéma sera définitivement supprimé. -schematic.rename = Renommer Schéma -schematic.info = {0}x{1}, {2} blocks -schematic.disabled = [scarlet] Schémas désactivés ![]\nVous n'êtes pas autorisés à utiliser des schémas sur cette [accent]map[] ou ce [accent]serveur. - -stat.wave = Vagues vaincues:[accent] {0} -stat.enemiesDestroyed = Ennemies détruits:[accent] {0} -stat.built = Bâtiments construits:[accent] {0} -stat.destroyed = Bâtiments détruits:[accent] {0} -stat.deconstructed = Bâtiments déconstruits:[accent] {0} -stat.delivered = Ressources transférées: -stat.playtime = Temps Joué:[accent] {0} -stat.rank = Rang Final: [accent]{0} - -globalitems = [accent]Global Items -map.delete = Êtes-vous sûr de vouloir supprimer cette carte ?"[accent]{0}[]"? -level.highscore = Meilleur score: [accent]{0} -level.select = Sélection de niveau -level.mode = Mode de jeu: -coreattack = -nearpoint = [[ [scarlet]QUITTEZ LE POINT D'APPARITION ENNEMI IMMÉDIATEMENT[] ]\nextermination imminente -database = Base de données -savegame = Sauvegarder la partie -loadgame = Charger la partie -joingame = Rejoindre la partie -customgame = Partie personnalisée -newgame = Nouvelle partie -none = -minimap = Minimap -position = Position -close = Fermer -website = Site Web -quit = Quitter -save.quit = Save & Quit -maps = Cartes -maps.browse = Feuilleter les maps -continue = Continuer -maps.none = [lightgray]Aucune carte trouvée! -invalid = Invalide -pickcolor = Choisir Couleur -preparingconfig = Préparation Configuration -preparingcontent = Préparation Contenu -uploadingcontent = Télécharger Contenu -uploadingpreviewfile = Télécharger Aperçu de Dossier -committingchanges = Commettre Changements -done = Fini -feature.unsupported = Votre appareil ne prend pas en charge cette fonctionnalité. - -mods.alphainfo = Tenez en compte que les mods sont en version alpha et [scarlet] qu'ils peuvent avoir des bugs[].\nVeuillez signaler tout les problèmes que vous encontrez sur le Github de Mindustry ou sur Discord. -mods = Mods -mods.none = [lightgray]Aucun Mod trouvé ! -mods.guide = Guide de Modding -mods.report = Signaler un Bug -mods.openfolder = Ouvrir Dossier Mod -mods.reload = Relancer -mods.reloadexit = Le jeu va quitter pour relancer les mods. -mod.display = [gray]Mod:[orange] {0} -mod.enabled = [lightgray]Activé -mod.disabled = [scarlet]Désactivé -mod.disable = Désactive -mod.content = Contenu: -mod.delete.error = Unable to delete mod. File may be in use. -mod.requiresversion = [scarlet]Requires min game version: [accent]{0} -mod.outdated = [scarlet]Not compatible with V6 (no minGameVersion: 105) -mod.missingdependencies = [scarlet]Missing dependencies: {0} -mod.erroredcontent = [scarlet]Content Errors -mod.errors = Errors have occurred loading content. -mod.noerrorplay = [scarlet]You have mods with errors.[] Either disable the affected mods or fix the errors before playing. -mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled. -mod.enable = Enable -mod.requiresrestart = The game will now close to apply the mod changes. -mod.reloadrequired = [scarlet]Reload Required -mod.import = Import Mod -mod.import.file = Import File -mod.import.github = Import GitHub Mod -mod.jarwarn = [scarlet]JAR mods are inherently unsafe.[]\nMake sure you're importing this mod from a trustworthy source! -mod.item.remove = This item is part of the[accent] '{0}'[] mod. To remove it, uninstall that mod. -mod.remove.confirm = This mod will be deleted. -mod.author = [lightgray]Author:[] {0} -mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0} -mod.preview.missing = Before publishing this mod in the workshop, you must add an image preview.\nPlace an image named[accent] preview.png[] into the mod's folder and try again. -mod.folder.missing = Only mods in folder form can be published on the workshop.\nTo convert any mod into a folder, simply unzip its file into a folder and delete the old zip, then restart your game or reload your mods. -mod.scripts.disable = Your device does not support mods with scripts. You must disable these mods to play the game. - -about.button = À propos -name = Nom: -noname = Choisissez d'abord [accent]un pseudo[]. -planetmap = Planet Map -launchcore = Launch Core -filename = Nom du fichier: -unlocked = Nouveau bloc debloqué! -completed = [accent]Terminé -techtree = Arbre technologique -research.list = [lightgray]Recherche: -research = Recherche -researched = [lightgray]{0} recherché. -research.progress = {0}% complete -players = {0} joueurs -players.single = {0} joueur -players.search = search -players.notfound = [gray]no players found -server.closing = [accent]Fermeture du serveur ... -server.kicked.kick = Vous avez été expulsé du serveur ! -server.kicked.whitelist = You are not whitelisted here. -server.kicked.serverClose = Serveur fermé. -server.kicked.vote = Vous avez été expulsé par vote. Au revoir. -server.kicked.clientOutdated = Client dépassé! Mettez à jour votre jeu ! -server.kicked.serverOutdated = Serveur dépassé! Demandez à l'hôte de le mettre à jour ! -server.kicked.banned = Vous êtes banni de ce serveur. -server.kicked.typeMismatch = This server is not compatible with your build type. -server.kicked.playerLimit = Ce serveur est complet. Attendez qu'une place ce libére. -server.kicked.recentKick = Vous avez été expulsé récemment.\nAttendez avant de vous connecter à nouveau. -server.kicked.nameInUse = Il y a déjà quelqu'un avec ce nom\nsur ce serveur. -server.kicked.nameEmpty = Votre nom doit contenir au moins une lettre ou un chiffre. -server.kicked.idInUse = Vous êtes déjà sur ce serveur ! Se connecter avec deux comptes n'est pas permis ! -server.kicked.customClient = Ce serveur ne supporte pas les versions personnalisées (Custom builds). Télécharger une version officielle. -server.kicked.gameover = Vous avez perdu ! -server.kicked.serverRestarting = Le serveur est entrain de redémarrer. -server.versions = Votre version:[accent] {0}[]\nVersion du serveur:[accent] {1}[] -host.info = Le bouton [accent]héberger[] héberge un serveur sur les ports [scarlet]6567[] et [scarlet]6568.[]\nN'importe qui sur le même [lightgray]réseau wifi ou local[] devrait pouvoir voir votre serveur dans sa liste de serveurs.\n\nSi vous voulez que les gens puissent se connecter de n'importe où grâce à l'IP, [accent]rediriger les ports[] est requis.\n\n[lightgray]Note:Si quelqu'un éprouve des difficultés à se connecter à votre partie LAN, assurez-vous que vous avez autorisé Mindustry à accéder à votre réseau local dans les paramètres de votre pare-feu. -join.info = Ici, vous pouvez entrer l' [accent]IP d'un serveur[] pour s'y connecter, ou découvrir les serveurs[accent]sur votre réseau local[] pour s'y connecter.\nLes parties multijoueur LAN et WAN sont toutes deux supportées.\n\n[lightgray]Note: Aucune liste globale des serveurs n'est génerée automatiquement: si vous voulez vous connecter à un serveur par IP, vous devrez demander l'IP à l'hébergeur. -hostserver = Héberger un serveur -invitefriends = Inviter des amis -hostserver.mobile = Héberger\nune partie -host = Héberger -hosting = [accent]Ouverture du serveur ... -hosts.refresh = Actualiser -hosts.discovering = Recherche de parties en LAN -hosts.discovering.any = Découverte des jeux -server.refreshing = Actualisation du serveur -hosts.none = [lightgray]Aucun jeu en LAN trouvé ! -host.invalid = [scarlet]Impossible de se\nconnecter à l'hôte. - -servers.local = Serveurs Locaux -servers.remote = Serveurs Distants -servers.global = Serveurs Communautaires - -trace = Suivre le joueur -trace.playername = Nom du joueur: [accent]{0} -trace.ip = IP: [accent]{0} -trace.id = ID Unique: [accent]{0} -trace.mobile = Client Mobile: [accent]{0} -trace.modclient = Client personnalisé: [accent]{0} -invalidid = ID client invalide ! Soumettre un rapport de bug -server.bans = Banni -server.bans.none = Aucun joueur banni trouvé ! -server.admins = Administrateurs -server.admins.none = Aucun administrateur trouvé ! -server.add = Ajouter un serveur -server.delete = Êtes-vous sûr de vouloir supprimer ce serveur ? -server.edit = Modifier le serveur -server.outdated = [crimson]Serveur obsolète ![] -server.outdated.client = [crimson]Client obsolète ![] -server.version = [lightgray]Version: {0} {1} -server.custombuild = [accent]Version personnalisée -confirmban = Êtes-vous sûr de vouloir bannir ce joueur ? -confirmkick = Êtes-vous sûr de vouloir expulser ce joueur ? -confirmvotekick = Êtes-vous sûr de vouloir voter que ce joueur soit banni ? -confirmunban = Êtes-vous sûr de vouloir annuler le ban de ce joueur ? -confirmadmin = Êtes-vous sûr de vouloir faire de ce joueur un administrateur ? -confirmunadmin = Êtes-vous sûr de vouloir supprimer le statut d'administrateur de ce joueur ? -joingame.title = Rejoindre une partie -joingame.ip = IP: -disconnect = Déconnecté. -disconnect.error = Un problème est survenu lors de la connection. -disconnect.closed = Connection fermée. -disconnect.timeout = Timed out. -disconnect.data = Les données du monde n'ont pas pu être chargées ! -cantconnect = Impossible de rejoindre le jeu ([accent]{0}[]). -connecting = [accent]Connexion... -connecting.data = [accent]Chargement des données du monde... -server.port = Port: -server.addressinuse = Adresse déjà utilisée ! -server.invalidport = Numéro de port incorrect ! -server.error = [crimson]Erreur lors de l'hébergement du serveur: [accent]{0} -save.new = Nouvelle sauvegarde -save.overwrite = Êtes-vous sûr de vouloir\nrecouvrir cette sauvegarde ? -overwrite = Recouvrir -save.none = Aucune sauvegarde trouvée ! -savefail = Échec de la sauvegarde ! -save.delete.confirm = Êtes-vous sûr de supprimer cette sauvegarde ? -save.delete = Supprimer -save.export = Exporter une\nSauvegarde -save.import.invalid = [accent]Cette sauvegarde est invalide! -save.import.fail = [crimson]L'importation de la sauvegarde\na échouée: [accent]{0} -save.export.fail = [crimson]L'exportation de la sauvegarde\na échouée: [accent]{0} -save.import = Importer une sauvegarde -save.newslot = Nom de la sauvegarde: -save.rename = Renommer -save.rename.text = Nouveau nom: -selectslot = Sélectionnez une sauvegarde. -slot = [accent]Emplacement {0} -editmessage = Modifier le Message -save.corrupted = [accent]Fichier de sauvegarde corrompu ou invalide!\nSi vous venez de mettre à jour votre jeu, c'est probablement dû à un changement du format de sauvegarde et [scarlet]non[] un bug. -empty = -on = Allumer -off = Éteint -save.autosave = Sauvegarde automatique {0} -save.map = Carte: {0} -save.wave = Vague {0} -save.mode = Mode de jeu {0} -save.date = Dernière sauvegarde: {0} -save.playtime = Temps de jeu: {0} -warning = Avertissement. -confirm = Confirmer -delete = Supprimer -view.workshop = View In Workshop -workshop.listing = Edit Workshop Listing -ok = OK -open = Ouvrir -customize = Personnaliser -cancel = Annuler -openlink = Ouvrir le lien -copylink = Copier le lien -back = Retour -data.export = Export Data -data.import = Import Data -data.openfolder = Open Data Folder -data.exported = Data exported. -data.invalid = Ceci ne sont pas des données de jeu valide. -data.import.confirm = Importing external data will erase[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately. -quit.confirm = Êtes-vous sûr de vouloir quitter? -quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[] -loading = [accent]Chargement... -reloading = [accent]Reloading Mods... -saving = [accent]Sauvegarde... -respawn = [accent][[{0}][] to respawn in core -cancelbuilding = [accent][[{0}][] to clear plan -selectschematic = [accent][[{0}][] to select+copy -pausebuilding = [accent][[{0}][] to pause building -resumebuilding = [scarlet][[{0}][] to resume building -wave = [accent]Vague {0} -wave.cap = [accent]Wave {0}/{1} -wave.waiting = [lightgray]Prochaine vague dans {0} -wave.waveInProgress = [lightgray]Vague en cours -waiting = [lightgray]En attente... -waiting.players = En attente de joueurs ... -wave.enemies = [lightgray]{0} Ennemis restants -wave.enemy = [lightgray]{0} Ennemi restant -wave.guardianwarn = Guardian approaching in [accent]{0}[] waves. -wave.guardianwarn.one = Guardian approaching in [accent]{0}[] wave. -loadimage = Charger l'image -saveimage = Sauvegarder l'image -unknown = Inconnu -custom = Personnalisé -builtin = Pré-fait -map.delete.confirm = Êtes-vous sûr de vouloir effacer cette carte ? Cette action est irréversible ! -map.random = [accent]Carte aléatoire -map.nospawn = Cette carte ne possède pas de base pour que le joueur puisse apparaître !Ajouter un [royal]base bleue[] sur cette carte dans l'éditeur. -map.nospawn.pvp = Cette carte ne contient aucune base ennemi dans lequel le joueur apparaît!\nAjoutez des bases [scarlet]rouge[] à cette carte dans l'éditeur. -map.nospawn.attack = Cette carte ne contient aucune base ennemi à attaquer! Ajoutez des bases [scarlet]rouge[] à cette carte dans l'éditeur. -map.invalid = Erreur lors du chargement de la carte: carte corrompue ou invalide. -workshop.update = Update Item -workshop.error = Error fetching workshop details: {0} -map.publish.confirm = Are you sure you want to publish this map?\n\n[lightgray]Make sure you agree to the Workshop EULA first, or your maps will not show up! -workshop.menu = Select what you would like to do with this item. -workshop.info = Item Info -changelog = Changelog (optional): -eula = Steam EULA -missing = This item has been deleted or moved.\n[lightgray]The workshop listing has now been automatically un-linked. -publishing = [accent]Publishing... -publish.confirm = Are you sure you want to publish this?\n\n[lightgray]Make sure you agree to the Workshop EULA first, or your items will not show up! -publish.error = Error publishing item: {0} -steam.error = Failed to initialize Steam services.\nError: {0} - -editor.brush = Pinceau -editor.openin = Ouvrir dans l'éditeur -editor.oregen = Génération des minerais -editor.oregen.info = Génération de minerais: -editor.mapinfo = Infos sur la carte -editor.author = Auteur: -editor.description = Description: -editor.nodescription = A map must have a description of at least 4 characters before being published. -editor.waves = Vagues: -editor.rules = Règles: -editor.generation = Generation: -editor.ingame = Modifier en jeu -editor.publish.workshop = Publish On Workshop -editor.newmap = Nouvelle carte -editor.center = Center -workshop = Workshop -waves.title = Vagues -waves.remove = Retirer -waves.never = -waves.every = tous les -waves.waves = vague(s) -waves.perspawn = par apparition -waves.shields = shields/wave -waves.to = à -waves.guardian = Guardian -waves.preview = Prévisualiser -waves.edit = Modifier... -waves.copy = Copier dans le Presse-papiers -waves.load = Coller depuis le Presse-papiers -waves.invalid = Vagues invalides dans le Presse-papiers. -waves.copied = Vagues copiées. -waves.none = Aucun ennemi défini.\nNotez que les dispositions vides seront automatiquement remplacées par la dispositions par défaut. - -wavemode.counts = counts -wavemode.totals = totals -wavemode.health = health - -editor.default = [lightgray] -details = Details... -edit = Modifier... -editor.name = Nom: -editor.spawn = Ajouter une unité -editor.removeunit = Retirer l'unité -editor.teams = Équipes -editor.errorload = Erreur lors du chargement du fichier:\n[accent]{0} -editor.errorsave = Erreur lors de la sauvegarde du fichier:\n[accent]{0} -editor.errorimage = C’est une image, pas une carte.\n\nSi vous souhaitez importer une carte 3.5/build 40, utilisez le bouton "Importer une carte héritée" dans l’éditeur. -editor.errorlegacy = Cette carte est trop ancienne et utilise un format de carte qui n'est plus pris en charge. -editor.errornot = Ce n'est pas un fichier de carte. -editor.errorheader = Ce fichier de carte n'est pas valide ou corrompu. -editor.errorname = La carte n'a pas de nom ! -editor.update = Mettre à jour -editor.randomize = Randomiser -editor.apply = Appliquer -editor.generate = Générer -editor.resize = Redimensionner -editor.loadmap = Charger une carte -editor.savemap = Sauvegarder une carte -editor.saved = Sauvegardé ! -editor.save.noname = Votre carte ne possède pas de nom ! Ajouter en un dans le menu 'Infos sur la carte'. -editor.save.overwrite = Une carte posséde déjà ce nom ! Choisissez un nom différent dans le menu 'Infos sur la carte'. -editor.import.exists = [scarlet]Importation impossible :[] Une carte nommé '{0}' existe déjà! -editor.import = Importation... -editor.importmap = Importer une carte -editor.importmap.description = Importer une carte déjà existante -editor.importfile = Importer un fichier -editor.importfile.description = Importer une carte à partir d'un fichier externe -editor.importimage = Importer la carte existante -editor.importimage.description = Importer une image de terrain à partir d'un fichier externe -editor.export = Exportation en cours... -editor.exportfile = Exporter un fichier -editor.exportfile.description = Exporter une carte -editor.exportimage = Exporter l'image du terrain -editor.exportimage.description = Exporter la carte sous forme d'image -editor.loadimage = Importer le terrain -editor.saveimage = Exportr le terrain -editor.unsaved = [scarlet] Vous avez des changements non sauvegardés ![] Êtes-vous sûr de vouloir quitter ? -editor.resizemap = Redimensionner\nla carte -editor.mapname = Nom de la carte: -editor.overwrite = [accent]Attention!\nCela écrasera une carte existante. -editor.overwrite.confirm = [scarlet]Attention ![] Une carte avec ce nom existe déjà. Êtes-vous sûr de vouloir la réécrire? -editor.exists = A map with this name already exists. -editor.selectmap = Sélectionnez une carte à charger: - -toolmode.replace = Remplacer -toolmode.replace.description = Dessine uniquement sur des blocs pleins. -toolmode.replaceall = Remplacer tout -toolmode.replaceall.description = Remplacez tous les blocs de la carte. -toolmode.orthogonal = Orthogonale -toolmode.orthogonal.description = Dessine uniquement des lignes orthogonales. -toolmode.square = Carré -toolmode.square.description = Pinceau carré. -toolmode.eraseores = Effacer les minerais -toolmode.eraseores.description = N'effacez que les minerais. -toolmode.fillteams = Remplir les équipes -toolmode.fillteams.description = Remplissez les équipes au lieu de blocs. -toolmode.drawteams = Tirage au sort des équipes -toolmode.drawteams.description = Dessinez des équipes au lieu de blocs. - -filters.empty = [lightgray]Aucun filtre! Ajoutez-en un avec les boutons ci-dessous. -filter.distort = Déformation -filter.noise = Bruit -filter.enemyspawn = Enemy Spawn Select -filter.spawnpath = Path To Spawn -filter.corespawn = Core Select -filter.median = Median -filter.oremedian = Ore Median -filter.blend = Mélange -filter.defaultores = Minerais par défaut -filter.ore = Minerai -filter.rivernoise = Bruit des rivières -filter.mirror = Miroir -filter.clear = Nettoyer -filter.option.ignore = Ignorer -filter.scatter = Dispersement -filter.terrain = Terrain -filter.option.scale = Échelle -filter.option.chance = Chance -filter.option.mag = Magnitude -filter.option.threshold = Seuil -filter.option.circle-scale = Échelle du cercle -filter.option.octaves = Octaves -filter.option.falloff = Diminution -filter.option.angle = Angle -filter.option.amount = Amount -filter.option.block = Bloc -filter.option.floor = Sol -filter.option.flooronto = Sible au sol -filter.option.target = Target -filter.option.wall = Mur -filter.option.ore = Minerai -filter.option.floor2 = Sol secondaire -filter.option.threshold2 = Seuil secondaire -filter.option.radius = Rayon -filter.option.percentile = Centile - -width = Largeur: -height = Hauteur: -menu = Menu -play = Jouer -campaign = Campagne -load = Charger -save = Sauvegarder -fps = FPS: {0} -ping = Ping: {0}ms -language.restart = Veuillez redémarrez votre jeu pour le changement de langage prenne effet. -settings = Paramètres -tutorial = Tutoriel -tutorial.retake = Re-Take Tutorial -editor = Éditeur -mapeditor = Éditeur de carte - -abandon = Abandonner -abandon.text = Cette zone et toutes ses ressources seront perdues. -locked = Verrouillé -complete = [lightgray]Compléter: -requirement.wave = Reach Wave {0} in {1} -requirement.core = Destroy Enemy Core in {0} -requirement.research = Research {0} -requirement.capture = Capture {0} -bestwave = [lightgray]Meilleur: {0} -launch.text = Launch -research.multiplayer = Only the host can research items. -uncover = Découvrir -configure = Configurer le transfert des ressources. -loadout = Loadout -resources = Resources -bannedblocks = Banned Blocks -addall = Add All -launch.destination = Destination: {0} -configure.invalid = Amount must be a number between 0 and {0}. -zone.unlocked = [lightgray]{0} Débloquée. -zone.requirement.complete = Vague {0} atteinte:\n{1} Exigences de la zone complétées -zone.resources = Ressources détectées: -zone.objective = [lightgray]Objective: [accent]{0} -zone.objective.survival = Survive -zone.objective.attack = Détruire la base ennemi -add = Ajouter... -boss.health = Vie du BOSS - -connectfail = [crimson]Échec de la connexion au serveur: [accent]{0} -error.unreachable = Serveur inaccessible. -error.invalidaddress = Adresse invalide. -error.timedout = Expiration du délai !\nAssurez-vous que la redirection de port est configurée sur l'hôte et que l'adresse est correcte ! -error.mismatch = Erreur de paquet:\nPossible d'incompatibilité de version client/serveur.\nAssurez-vous que l'hôte et vous disposez de la dernière version de Mindustry ! -error.alreadyconnected = Déjà connecté. -error.mapnotfound = Fichier de carte introuvable ! -error.io = Network I/O error. -error.any = Erreur réseau inconnue. -error.bloom = Échec d'initialisation du flou lumineux.\nVotre appareil peut ne pas le supporter. - -weather.rain.name = Pluie -weather.snow.name = Neige -weather.sandstorm.name = Tempête de sable -weather.sporestorm.name = Tempête de spores -weather.fog.name = Brouillard - -sectors.unexplored = [lightgray] Inexploré -sectors.resources = Resources: -sectors.production = Production: -sectors.stored = Stored: -sectors.resume = Resume -sectors.launch = Launch -sectors.select = Select -sectors.nonelaunch = [lightgray]none (sun) -sectors.rename = Rename Sector -sector.missingresources = [scarlet]Ressources du noyau insuffisantes - -planet.serpulo.name = Serpulo -planet.sun.name = Soleil - -sector.groundZero.name = Ground Zero -sector.craters.name = The Craters -sector.frozenForest.name = Frozen Forest -sector.ruinousShores.name = Ruinous Shores -sector.stainedMountains.name = Stained Mountains -sector.desolateRift.name = Desolate Rift -sector.nuclearComplex.name = Nuclear Production Complex -sector.overgrowth.name = Overgrowth -sector.tarFields.name = Tar Fields -sector.saltFlats.name = Salt Flats -sector.fungalPass.name = Fungal Pass - -sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. -sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. -sector.saltFlats.description = On the outskirts of the desert lie the Salt Flats. Few resources can be found in this location.\n\nThe enemy has erected a resource storage complex here. Eradicate their core. Leave nothing standing. -sector.craters.description = Water has accumulated in this crater, relic of the old wars. Reclaim the area. Collect sand. Smelt metaglass. Pump water to cool turrets and drills. -sector.ruinousShores.description = Past the wastes, is the shoreline. Once, this location housed a coastal defense array. Not much of it remains. Only the most basic defense structures have remained unscathed, everything else reduced to scrap.\nContinue the expansion outwards. Rediscover the technology. -sector.stainedMountains.description = Further inland lie the mountains, yet untainted by spores.\nExtract the abundant titanium in this area. Learn how to use it.\n\nThe enemy presence is greater here. Do not give them time to send their strongest units. -sector.overgrowth.description = This area is overgrown, closer to the source of the spores.\nThe enemy has established an outpost here. Build Titan units. Destroy it. Reclaim that which was lost. -sector.tarFields.description = The outskirts of an oil production zone, between the mountains and desert. One of the few areas with usable tar reserves.\nAlthough abandoned, this area has some dangerous enemy forces nearby. Do not underestimate them.\n\n[lightgray]Research oil processing technology if possible. -sector.desolateRift.description = An extremely dangerous zone. Plentiful resources, but little space. High risk of destruction. Leave as soon as possible. Do not be fooled by the long spacing between enemy attacks. -sector.nuclearComplex.description = A former facility for the production and processing of thorium, reduced to ruins.\n[lightgray]Research the thorium and its many uses.\n\nThe enemy is present here in great numbers, constantly scouting for attackers. -sector.fungalPass.description = A transition area between high mountains and lower, spore-ridden lands. A small enemy reconnaissance base is located here.\nDestroy it.\nUse Dagger and Crawler units. Take out the two cores. - -settings.language = Langue -settings.data = Données du jeu -settings.reset = Valeur par défaut. -settings.rebind = Réatttribuer -settings.resetKey = Reset -settings.controls = Contrôles -settings.game = Jeu -settings.sound = Son -settings.graphics = Graphiques -settings.cleardata = Effacer les données du jeu... -settings.clear.confirm = Êtes-vous sûr d'effacer ces données ?\n[scarlet]Ceci est irréversible -settings.clearall.confirm = [scarlet]ATTENTION![]\nCet action effacera toutes les données , incluant les sauvegarges, les cartes, les déblocages et la configuration des touches.\nUne fois que vous aurez pressé 'Ok' le jeu effacera toutes les données et se fermera. -settings.clearsaves.confirm = Are you sure you want to clear all your saves? -settings.clearsaves = Clear Saves -settings.clearresearch = Clear Research -settings.clearresearch.confirm = Are you sure you want to clear all of your campaign research? -settings.clearcampaignsaves = Clear Campaign Saves -settings.clearcampaignsaves.confirm = Are you sure you want to clear all of your campaign saves? -paused = En pause -clear = Clear -banned = [scarlet]Banned -unplaceable.sectorcaptured = [scarlet]Requires captured sector -yes = Oui -no = Non -info.title = Info -error.title = [crimson]Une erreur s'est produite -error.crashtitle = Une erreur s'est produite -unit.nobuild = [scarlet]Unit can't build -lastaccessed = [lightgray]Last Accessed: {0} -block.unknown = [lightgray]Inconnu - -stat.input = Ressource(s) requise(s) -stat.output = Ressource(s) produite(s) -stat.booster = Booster -stat.tiles = Required Tiles -stat.affinities = Affinities -stat.powercapacity = Capacité d'énergie -stat.powershot = Énergie/Tir -stat.damage = Damage -stat.targetsair = Cible les unités aériennes -stat.targetsground = Cible les unités terrestres -stat.itemsmoved = Vitesse de déplacement -stat.launchtime = Temps entre chaque lancement -stat.shootrange = Portée -stat.size = Taille -stat.displaysize = Display Size -stat.liquidcapacity = Capacité en liquide -stat.powerrange = Distance de transmission -stat.linkrange = Link Range -stat.instructions = Instructions -stat.powerconnections = Max Connections -stat.poweruse = Énergie utilisée -stat.powerdamage = Énergie/Dégâts -stat.itemcapacity = Stockage -stat.memorycapacity = Memory Capacity -stat.basepowergeneration = Production d'énergie de base -stat.productiontime = Temps de production -stat.repairtime = Temps pour la réparation totale du bloc -stat.speedincrease = Augmentation de la vitesse -stat.range = Portée -stat.drilltier = Forable -stat.drillspeed = Vitesse de forage de base -stat.boosteffect = Effet boostant -stat.maxunits = Maximum d'unitée active -stat.health = Santé -stat.buildtime = Temps de construction -stat.maxconsecutive = Max Consecutive -stat.buildcost = Coût de construction -stat.inaccuracy = Précision -stat.shots = Tirs -stat.reload = Tirs/Seconde -stat.ammo = Munition -stat.shieldhealth = Shield Health -stat.cooldowntime = Cooldown Time -stat.explosiveness = Explosiveness -stat.basedeflectchance = Base Deflect Chance -stat.lightningchance = Lightning Chance -stat.lightningdamage = Lightning Damage -stat.flammability = Flammability -stat.radioactivity = Radioactivity -stat.heatcapacity = HeatCapacity -stat.viscosity = Viscosity -stat.temperature = Temperature -stat.speed = Speed -stat.buildspeed = Build Speed -stat.minespeed = Mine Speed -stat.minetier = Mine Tier -stat.payloadcapacity = Payload Capacity -stat.commandlimit = Command Limit -stat.abilities = Abilities - -ability.forcefield = Force Field -ability.repairfield = Repair Field -ability.statusfield = Status Field -ability.unitspawn = {0} Factory -ability.shieldregenfield = Shield Regen Field - -bar.drilltierreq = Better Drill Required -bar.noresources = Missing Resources -bar.corereq = Core Base Required -bar.drillspeed = Vitesse de forage: {0}/s -bar.pumpspeed = Pump Speed: {0}/s -bar.efficiency = Efficacité: {0}% -bar.powerbalance = Énergie: {0} -bar.powerstored = Stored: {0}/{1} -bar.poweramount = Énergie: {0} -bar.poweroutput = Énergie en sortie: {0} -bar.powerlines = Connections: {0}/{1} -bar.items = Objets: {0} -bar.capacity = Capacity: {0} -bar.unitcap = {0} {1}/{2} -bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[unit disabled] -bar.liquid = Liquide -bar.heat = Chaleur -bar.power = Énergie -bar.progress = Progression de la construction -bar.input = Input -bar.output = Output - -units.processorcontrol = [lightgray]Processor Controlled - -bullet.damage = [stat]{0}[lightgray] dégats -bullet.splashdamage = [stat]{0}[lightgray] dgt zone ~[stat] {1}[lightgray] tuiles -bullet.incendiary = [stat]incendiaire -bullet.homing = [stat]autoguidage -bullet.shock = [stat]choc -bullet.frag = [stat]frag -bullet.knockback = [stat]{0}[lightgray]recul -bullet.pierce = [stat]{0}[lightgray]x pierce -bullet.infinitepierce = [stat]pierce -bullet.freezing = [stat]gel -bullet.tarred = [stat]goudronné -bullet.multiplier = [stat]{0}[lightgray]x multiplicateur de munitions -bullet.reload = [stat]{0}[lightgray]x vitesse de rechargement - -unit.blocks = Blocs -unit.blockssquared = blocks² -unit.powersecond = Énergie/seconde -unit.liquidsecond = Liquides/seconde -unit.itemssecond = Objets/seconde -unit.liquidunits = Unité de liquide -unit.powerunits = Unité d'énergie -unit.degrees = degrés -unit.seconds = secondes -unit.minutes = mins -unit.persecond = /sec -unit.perminute = /min -unit.timesspeed = x vitesse -unit.percent = % -unit.shieldhealth = shield health -unit.items = Objets -unit.thousands = k -unit.millions = mil -unit.billions = b -category.general = Général -category.power = Énergie -category.liquids = Liquides -category.items = Objets -category.crafting = Fabrication -category.function = Function -category.optional = Améliorations facultatives -setting.landscape.name = Verrouiller la rotation en mode paysage -setting.shadows.name = Ombres -setting.blockreplace.name = Automatic Block Suggestions -setting.linear.name = Filtrage linéaire -setting.hints.name = Hints -setting.flow.name = Display Resource Flow Rate[scarlet] (experimental) -setting.buildautopause.name = Auto-Pause Building -setting.animatedwater.name = Eau animée -setting.animatedshields.name = Boucliers Animés -setting.antialias.name = Antialias[lightgray] (demande le redémarrage de l'appareil)[] -setting.playerindicators.name = Player Indicators -setting.indicators.name = Indicateurs d'alliés -setting.autotarget.name = Visée automatique -setting.keyboard.name = Contrôles Souris + Clavier -setting.touchscreen.name = Touchscreen Controls -setting.fpscap.name = Max FPS -setting.fpscap.none = Vide -setting.fpscap.text = {0} FPS -setting.uiscale.name = Mise à l'échelle de l'interface[lightgray] (nécessite un redémarrage)[] -setting.swapdiagonal.name = Autoriser le placement des blocs en diagonal -setting.difficulty.training = Entraînement -setting.difficulty.easy = Facile -setting.difficulty.normal = Normal -setting.difficulty.hard = Difficile -setting.difficulty.insane = Êxtreme -setting.difficulty.name = Difficulté: -setting.screenshake.name = Tremblement d'écran -setting.effects.name = Montrer les effets -setting.destroyedblocks.name = Display Destroyed Blocks -setting.blockstatus.name = Display Block Status -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding -setting.sensitivity.name = Contôle de la sensibilité -setting.saveinterval.name = Intervalle des sauvegardes auto -setting.seconds = {0} Secondes -setting.blockselecttimeout.name = Block Select Timeout -setting.milliseconds = {0} milliseconds -setting.fullscreen.name = Plein écran -setting.borderlesswindow.name = Fenêtre sans bordure[lightgray] (peut nécessiter un redémarrage) -setting.fps.name = Afficher FPS -setting.smoothcamera.name = Smooth Camera -setting.vsync.name = VSync -setting.pixelate.name = Pixélisé [lightgray](peut diminuer les performances)[] -setting.minimap.name = Montrer la minimap -setting.coreitems.name = Display Core Items (WIP) -setting.position.name = Show Player Position -setting.musicvol.name = Volume de la musique -setting.atmosphere.name = Show Planet Atmosphere -setting.ambientvol.name = Ambient Volume -setting.mutemusic.name = Couper la musique -setting.sfxvol.name = Volume des SFX -setting.mutesound.name = Couper les SFX -setting.crashreport.name = Envoyer des rapports d'incident anonymement. -setting.savecreate.name = Auto-Create Saves -setting.publichost.name = Public Game Visibility -setting.playerlimit.name = Player Limit -setting.chatopacity.name = Opacité du tchat -setting.lasersopacity.name = Power Laser Opacity -setting.bridgeopacity.name = Bridge Opacity -setting.playerchat.name = Afficher le tchat en jeu -public.confirm = Do you want to make your game public?\n[accent]Anyone will be able to join your games.\n[lightgray]This can be changed later in Settings->Game->Public Game Visibility. -public.beta = Note that beta versions of the game cannot make public lobbies. -uiscale.reset = L'échelle de l'interface a été modifiée.\nAppuyez sur "OK" pour confirmer cette échelle.\n[scarlet]Revenir et sortir en[accent] {0}[] réglages... -uiscale.cancel = Annuler et quitter -setting.bloom.name = Flou lumineux -keybind.title = Paramétrer les touches -keybinds.mobile = [scarlet]La plupart des raccourcis clavier ne sont pas fonctionnelles sur les appareils mobiles. Seul le mouvement de base est pris en charge. -category.general.name = Général -category.view.name = Voir -category.multiplayer.name = Multijoueur -category.blocks.name = Block Select -command.attack = Attaquer -command.rally = Rally -command.retreat = Retraite -command.idle = Idle -placement.blockselectkeys = \n[lightgray]Key: [{0}, -keybind.respawn.name = Respawn -keybind.control.name = Control Unit -keybind.clear_building.name = Clear Building -keybind.press = Appuyez sur une touche ... -keybind.press.axis = Appuyez sur un axe ou une touche... -keybind.screenshot.name = Map Screenshot -keybind.toggle_power_lines.name = Toggle Power Lasers -keybind.toggle_block_status.name = Toggle Block Statuses -keybind.move_x.name = Mouvement X -keybind.move_y.name = Mouvement Y -keybind.mouse_move.name = Follow Mouse -keybind.pan.name = Pan View -keybind.boost.name = Boost -keybind.schematic_select.name = Select Region -keybind.schematic_menu.name = Schematic Menu -keybind.schematic_flip_x.name = Flip Schematic X -keybind.schematic_flip_y.name = Flip Schematic Y -keybind.category_prev.name = Previous Category -keybind.category_next.name = Next Category -keybind.block_select_left.name = Block Select Left -keybind.block_select_right.name = Block Select Right -keybind.block_select_up.name = Block Select Up -keybind.block_select_down.name = Block Select Down -keybind.block_select_01.name = Category/Block Select 1 -keybind.block_select_02.name = Category/Block Select 2 -keybind.block_select_03.name = Category/Block Select 3 -keybind.block_select_04.name = Category/Block Select 4 -keybind.block_select_05.name = Category/Block Select 5 -keybind.block_select_06.name = Category/Block Select 6 -keybind.block_select_07.name = Category/Block Select 7 -keybind.block_select_08.name = Category/Block Select 8 -keybind.block_select_09.name = Category/Block Select 9 -keybind.block_select_10.name = Category/Block Select 10 -keybind.fullscreen.name = Basculer en plein écran -keybind.select.name = Sélectionner/Tirer -keybind.diagonal_placement.name = Placement en diagonal -keybind.pick.name = Choisir un bloc -keybind.break_block.name = Supprimer un bloc -keybind.deselect.name = Déselectionner -keybind.pickupCargo.name = Pickup Cargo -keybind.dropCargo.name = Drop Cargo -keybind.command.name = Command -keybind.shoot.name = Tirer -keybind.zoom.name = Zoom -keybind.menu.name = Menu -keybind.pause.name = Pause -keybind.pause_building.name = Pause/Resume Building -keybind.minimap.name = Mini-Map -keybind.chat.name = Tchat -keybind.player_list.name = Liste des joueurs -keybind.console.name = Console -keybind.rotate.name = Tourner -keybind.rotateplaced.name = Rotate Existing (Hold) -keybind.toggle_menus.name = Montrer/Cacher les menus -keybind.chat_history_prev.name = Reculer dans l'historique du tchat -keybind.chat_history_next.name = Suite de l'historique du tchat -keybind.chat_scroll.name = Faire défiler le tchat -keybind.drop_unit.name = Larguer une unité -keybind.zoom_minimap.name = Zoomer la minimap -mode.help.title = Description des modes de jeu -mode.survival.name = Survival -mode.survival.description = Le mode normal. Ressources limitées et vagues automatiques. -mode.sandbox.name = Bac à sable -mode.sandbox.description = Ressources infinies et pas de compte à rebours pour les vagues. -mode.editor.name = Editor -mode.pvp.name = PvP -mode.pvp.description = Lutter contre d'autres joueurs pour gagner ! -mode.attack.name = Attaque -mode.attack.description = Pas de vagues, le but est de détruire la base ennemie. -mode.custom = Règles personnalisées - -rules.infiniteresources = Ressources infinies -rules.reactorexplosions = Reactor Explosions -rules.schematic = Schematics Allowed -rules.wavetimer = Temps de vague -rules.waves = Vague -rules.attack = Mode attaque -rules.buildai = AI Building -rules.enemyCheat = Ressources infinies pour l'IA -rules.blockhealthmultiplier = Block Health Multiplier -rules.blockdamagemultiplier = Block Damage Multiplier -rules.unitbuildspeedmultiplier = Multiplicateur de vitesse de création d'unités -rules.unithealthmultiplier = Multiplicateur de la santé des unités -rules.unitdamagemultiplier = Multiplicateur de dégât des unités -rules.enemycorebuildradius = Rayon de non-construction autour de la base ennemi:[lightgray] (tuiles) -rules.wavespacing = Espacement des vagues:[lightgray] (sec) -rules.buildcostmultiplier = Multiplicateur de coût de construction -rules.buildspeedmultiplier = Multiplicateur de vitesse de construction -rules.deconstructrefundmultiplier = Deconstruct Refund Multiplier -rules.waitForWaveToEnd = Les vagues attendent les ennemis -rules.dropzoneradius = Rayon de la zone de largage:[lightgray] (tuiles) -rules.unitammo = Units Require Ammo -rules.title.waves = Vagues -rules.title.resourcesbuilding = Ressources & Bâtiment -rules.title.enemy = Ennemis -rules.title.unit = Unités -rules.title.experimental = Experimental -rules.title.environment = Environment -rules.lighting = Lighting -rules.enemyLights = Enemy Lights -rules.fire = Fire -rules.explosions = Block/Unit Explosion Damage -rules.ambientlight = Ambient Light -rules.weather = Weather -rules.weather.frequency = Frequency: -rules.weather.duration = Duration: - -content.item.name = Objets -content.liquid.name = Liquides -content.unit.name = Unités -content.block.name = Blocs - -item.copper.name = Cuivre -item.lead.name = Plomb -item.coal.name = Charbon -item.graphite.name = Graphite -item.titanium.name = Titane -item.thorium.name = Thorium -item.silicon.name = Silicium -item.plastanium.name = Plastanium -item.phase-fabric.name = Phase Fabric -item.surge-alloy.name = Alliage superchargé -item.spore-pod.name = Bulbe sporifère -item.sand.name = Sable -item.blast-compound.name = Mélange explosif -item.pyratite.name = Pyratite -item.metaglass.name = Métaverre -item.scrap.name = Ferraille -liquid.water.name = Eau -liquid.slag.name = Scorie -liquid.oil.name = Pétrole -liquid.cryofluid.name = Liquide Cryogénique - -unit.dagger.name = Poignard -unit.mace.name = Mace -unit.fortress.name = Forteresse -unit.nova.name = Nova -unit.pulsar.name = Pulsar -unit.quasar.name = Quasar -unit.crawler.name = Rampeur -unit.atrax.name = Atrax -unit.spiroct.name = Spiroct -unit.arkyid.name = Arkyid -unit.toxopid.name = Toxopid -unit.flare.name = Flare -unit.horizon.name = Horizon -unit.zenith.name = Zenith -unit.antumbra.name = Antumbra -unit.eclipse.name = Eclipse -unit.mono.name = Mono -unit.poly.name = Poly -unit.mega.name = Mega -unit.quad.name = Quad -unit.oct.name = Oct -unit.risso.name = Risso -unit.minke.name = Minke -unit.bryde.name = Bryde -unit.sei.name = Sei -unit.omura.name = Omura -unit.alpha.name = Alpha -unit.beta.name = Beta -unit.gamma.name = Gamma -unit.scepter.name = Scepter -unit.reign.name = Reign -unit.vela.name = Vela -unit.corvus.name = Corvus - -block.resupply-point.name = Point de rechargement -block.parallax.name = Parallax -block.cliff.name = Falaise -block.sand-boulder.name = Sable rocheux -block.grass.name = Herbe -block.slag.name = Scories -block.space.name = Space -block.salt.name = Sel -block.salt-wall.name = Mur de sel -block.pebbles.name = Cailloux -block.tendrils.name = Vrilles -block.sand-wall.name = Mur de sable -block.spore-pine.name = Pin sporifère -block.spore-wall.name = Spore Wall -block.boulder.name = Boulder -block.snow-boulder.name = Snow Boulder -block.snow-pine.name = Snow Pine -block.shale.name = Schiste -block.shale-boulder.name = Rocher de schiste -block.moss.name = Mousse -block.shrubs.name = Arbustes -block.spore-moss.name = Mousse sporifère -block.shale-wall.name = Shale Wall -block.scrap-wall.name = Mur de ferraille -block.scrap-wall-large.name = Grand mur de ferraille -block.scrap-wall-huge.name = Enorme mur de ferraille -block.scrap-wall-gigantic.name = Gigantesque mur de ferraille -block.thruster.name = Propulseur -block.kiln.name = Four -block.graphite-press.name = Presse à graphite -block.multi-press.name = Multi-Presse -block.constructing = {0}\n[lightgray](En construction) -block.spawn.name = Générateur d'ennemis -block.core-shard.name = Core: Shard -block.core-foundation.name = Core: Fondation -block.core-nucleus.name = Core: Nucleus -block.deepwater.name = Eau profonde -block.water.name = Eau -block.tainted-water.name = Eau contaminée -block.darksand-tainted-water.name = Eau contaminée par le sable noir -block.tar.name = Pétrole -block.stone.name = Pierre -block.sand.name = Sable -block.darksand.name = Sable noire -block.ice.name = Glace -block.snow.name = Neige -block.craters.name = Cratères -block.sand-water.name = Eau (sable) -block.darksand-water.name = Eau (sable noir) -block.char.name = Carboniser -block.dacite.name = Dacite -block.dacite-wall.name = Dacite Wall -block.dacite-boulder.name = Dacite Boulder -block.ice-snow.name = Neige glacée -block.stone-wall.name = Stone Wall -block.ice-wall.name = Ice Wall -block.snow-wall.name = Snow Wall -block.dune-wall.name = Dune Wall -block.pine.name = Pin -block.dirt.name = Dirt -block.dirt-wall.name = Dirt Wall -block.mud.name = Mud -block.white-tree-dead.name = Arbre blanc mort -block.white-tree.name = Arbre blanc -block.spore-cluster.name = Grappe de spores -block.metal-floor.name = Sol métallique -block.metal-floor-2.name = Sol métallique 2 -block.metal-floor-3.name = Sol métallique 3 -block.metal-floor-5.name = Sol métallique 5 -block.metal-floor-damaged.name = Sol métallique endommagé -block.dark-panel-1.name = Panneau noir 1 -block.dark-panel-2.name = Panneau noir 2 -block.dark-panel-3.name = Panneau noir 3 -block.dark-panel-4.name = Panneau noir 4 -block.dark-panel-5.name = Panneau noir 5 -block.dark-panel-6.name = Panneau noir 6 -block.dark-metal.name = Métal noir -block.basalt.name = Basalt -block.hotrock.name = Roche chaude -block.magmarock.name = Roche de magma -block.copper-wall.name = Mur de cuivre -block.copper-wall-large.name = Grand mur de cuivre -block.titanium-wall.name = Mur de titane -block.titanium-wall-large.name = Grand mur de titane -block.plastanium-wall.name = Plastanium Wall -block.plastanium-wall-large.name = Large Plastanium Wall -block.phase-wall.name = Mur phasé -block.phase-wall-large.name = Grand mur phasé -block.thorium-wall.name = Mur en thorium -block.thorium-wall-large.name = Grand mur en thorium -block.door.name = Porte -block.door-large.name = Grande porte -block.duo.name = Duo -block.scorch.name = Brûleur -block.scatter.name = Disperseur -block.hail.name = Grêle -block.lancer.name = Lancier -block.conveyor.name = Convoyeur -block.titanium-conveyor.name = Convoyeur en titane -block.plastanium-conveyor.name = Convoyeur en plastanium -block.armored-conveyor.name = Convoyeur cuirassé -block.armored-conveyor.description = Moves items at the same speed as titanium conveyors, but possesses more armor. Does not accept inputs from the sides from anything but other conveyors. -block.junction.name = Jonction -block.router.name = Routeur -block.distributor.name = [accent]Distributeur[] -block.sorter.name = Trieur -block.inverted-sorter.name = Trieur inversé -block.message.name = Message -block.illuminator.name = Illuminator -block.illuminator.description = A small, compact, configurable light source. Requires power to function. -block.overflow-gate.name = Barrière de Débordement -block.underflow-gate.name = Barrière de Refoulement -block.silicon-smelter.name = Fonderie de silicium -block.phase-weaver.name = Tisseur à phase -block.pulverizer.name = Pulvérisateur -block.cryofluid-mixer.name = Refroidisseur -block.melter.name = Four à Fusion -block.incinerator.name = Incinérateur -block.spore-press.name = Presse à spores -block.separator.name = Séparateur -block.coal-centrifuge.name = Centrifugeuse à charbon -block.power-node.name = Transmetteur énergétique -block.power-node-large.name = Grand transmetteur énergétique -block.surge-tower.name = Tour de surtension -block.diode.name = Diode de batterie -block.battery.name = Batterie -block.battery-large.name = Grande batterie -block.combustion-generator.name = Générateur à combustion -block.steam-generator.name = Générateur à turbine -block.differential-generator.name = Générateur différentiel -block.impact-reactor.name = Réacteur à impact -block.mechanical-drill.name = Foreuse mécanique -block.pneumatic-drill.name = Foreuse à vérins -block.laser-drill.name = Foreuse Laser -block.water-extractor.name = Extracteur d'eau -block.cultivator.name = Cultivateur -block.conduit.name = Conduit -block.mechanical-pump.name = Pompe Mécanique -block.item-source.name = Source d'objets -block.item-void.name = Destructeur d'objets -block.liquid-source.name = Source de liquide -block.liquid-void.name = Vaporisateur -block.power-void.name = Absorbeur énergétique -block.power-source.name = Puissance infinie -block.unloader.name = Déchargeur -block.vault.name = Coffre-Fort -block.wave.name = Vague -block.tsunami.name = Tsunami -block.swarmer.name = Essaim -block.salvo.name = Salve -block.ripple.name = Percussion -block.phase-conveyor.name = Convoyeur phasé -block.bridge-conveyor.name = Pont -block.plastanium-compressor.name = Compresseur de plastanium -block.pyratite-mixer.name = Mixeur à pyratite -block.blast-mixer.name = Mixeur à explosion -block.solar-panel.name = Panneau solaire -block.solar-panel-large.name = Grand panneau solaire -block.oil-extractor.name = Extracteur de pétrole -block.repair-point.name = Point de Réparation -block.pulse-conduit.name = Conduit à Impulsion -block.plated-conduit.name = Plated Conduit -block.phase-conduit.name = Conduit à Phase -block.liquid-router.name = Routeur de Liquide -block.liquid-tank.name = Réservoir de Liquide -block.liquid-junction.name = Jonction à Liquide -block.bridge-conduit.name = Pont à liquide -block.rotary-pump.name = Pompe Rotative -block.thorium-reactor.name = Réacteur à Thorium -block.mass-driver.name = Transporteur de masse -block.blast-drill.name = Foreuse à explosion -block.thermal-pump.name = Pompe thermique -block.thermal-generator.name = Générateur thermique -block.alloy-smelter.name = Fonderie d'alliage superchargé -block.mender.name = Gardien -block.mend-projector.name = Projecteur soignant -block.surge-wall.name = Mur superchargé -block.surge-wall-large.name = Grand mur superchargé -block.cyclone.name = Cyclone -block.fuse.name = Fuse -block.shock-mine.name = Mines terrestre -block.overdrive-projector.name = Projecteur accélérant -block.force-projector.name = Projecteur de champ de force -block.arc.name = Arc -block.rtg-generator.name = G.T.R. -block.spectre.name = Spectre -block.meltdown.name = Meltdown -block.foreshadow.name = Foreshadow -block.container.name = Conteneur -block.launch-pad.name = Rampe de lancement -block.launch-pad-large.name = Grande rampe de lancement -block.segment.name = Segment -block.command-center.name = Command Center -block.ground-factory.name = Ground Factory -block.air-factory.name = Air Factory -block.naval-factory.name = Naval Factory -block.additive-reconstructor.name = Additive Reconstructor -block.multiplicative-reconstructor.name = Multiplicative Reconstructor -block.exponential-reconstructor.name = Exponential Reconstructor -block.tetrative-reconstructor.name = Tetrative Reconstructor -block.payload-conveyor.name = Mass Conveyor -block.payload-router.name = Payload Router -block.disassembler.name = Disassembler -block.silicon-crucible.name = Silicon Crucible -block.overdrive-dome.name = Overdrive Dome - -block.switch.name = Switch -block.micro-processor.name = Micro Processor -block.logic-processor.name = Logic Processor -block.hyper-processor.name = Hyper Processor -block.logic-display.name = Logic Display -block.large-logic-display.name = Large Logic Display -block.memory-cell.name = Memory Cell -block.memory-bank.name = Memory Bank - -team.blue.name = Bleu -team.crux.name = red -team.sharded.name = orange -team.orange.name = Orange -team.derelict.name = derelict -team.green.name = Vert -team.purple.name = Violet - -tutorial.next = [lightgray] -tutorial.intro = Vous êtes entré dans le[scarlet] Tutoriel de Mindustry.[]\nCommencez par[accent] miner du cuivre[]. Appuyez ou cliquez sur une veine de minerai de cuivre près de votre base pour commencer à miner.\n\n[accent]{0}/{1} cuivre -tutorial.intro.mobile = You have entered the[scarlet] Mindustry Tutorial.[]\nSwipe the screen to move.\n[accent]Pinch with 2 fingers [] to zoom in and out.\nBegin by[accent] mining copper[]. Move close to it, then tap a copper ore vein near your core to do this.\n\n[accent]{0}/{1} copper -tutorial.drill = Le minage manuel est inefficace.\n[accent]Des foreuses[]peuvent miner automatiquement.\nPlacez-en une sur un filon de cuivre. -tutorial.drill.mobile = Le minage manuel est inefficace.\n[accent]Des foreuses[]peuvent miner automatiquement.\nAppuyez sur l'onglet de forage en bas à droite.\nSélectionnez la[accent] perceuse mécanique[].\nPlacez-la sur une veine de cuivre, puis appuyez sur la[accent] coche(V)[] ci-dessous pour confirmer votre sélection.\nAppuyez sur le [accent] bouton X[]pour annuler le placement. -tutorial.blockinfo = Chaque bloc a des statistiques différentes. Chaque foreuse ne peut extraire que certains minerais.\nPour vérifier les informations et les statistiques d'un bloc,[accent] tapez sur le "?" tout en le sélectionnant dans le menu de compilation.[]\n\n[accent]Accédez aux statistiques de la foreuse mécanique maintenant.[] -tutorial.conveyor = [accent]Convoyeurs[] sont utilisés pour transporter des articles à la base.\nFaire une ligne de convoyeurs de la foreuse à la base.\n[accent]Maintenez le clique droit de la souris pour placer dans une ligne.[]\nMaintenir[accent] CTRL[] en sélectionnant une ligne à placer en diagonale.\n\n[accent]Placez 2 convoyeurs avec l'outil ligne, puis livrez un article dans la base. -tutorial.conveyor.mobile = [accent]Convoyeurs[] sont utilisés pour transporter des articles à la base.\nFaire une ligne de convoyeurs de la foreuse à la base.\n[accent] Placez dans une ligne en maintenant votre doigt appuyé pendant quelques secondes[] et en le faisant glisser dans une direction.\n\n[accent]Placez 2 convoyeurs avec l'outil ligne, puis livrez un article dans la base. -tutorial.turret = Des constructions défensives doivent être construites pour repousser [lightgray]les ennemis[].Construisez une tourelle "duo" près de votre base. -tutorial.drillturret = Les tourelles "Duo" ont besoin de [accent]munitions en cuivre[] pour tirer.\nPlacez une foreuse à côté de la tourelle pour l'approvisionner avec du cuivre. -tutorial.pause = Pendant le combat, vous pouvez[accent] mettre le jeu en pause.[]\nVous pouvez construire des bâtiments pendant que le jeu est en pause.\n\n[accent]Appuyez sur espace pour mettre le jeu en pause. -tutorial.pause.mobile = Pendant le combat, vous pouvez[accent] mettre le jeu en pause.[]\nVous pouvez construire des bâtiments pendant que le jeu est en pause.\n\n[accent]Appuyez sur le bouton en haut à gauche pour mettre le jeu en pause. -tutorial.unpause = Appuyez de nouveau sur espace pour reprendre le cour du jeu -tutorial.unpause.mobile = Appuyez de nouveau sur cette touche pour reprendre le cour du jeu -tutorial.breaking = Les blocs doivent souvent être détruits.\n[accent]Maintenez le bouton droit de la souris enfoncé.[] pour détruire tous les blocs sélectionnés.[]\n\n[accent]Détruisez tous les blocs de ferraille à gauche de votre base à l'aide de la sélection de zone. -tutorial.breaking.mobile = Les blocs doivent souvent être détruits.\n[accent]Sélectionnez le mode de déconstruction[], puis appuyez sur un bloc pour commencer à le casser.\nDétruisez une zone en maintenant votre doigt enfoncé pendant quelques secondes[] et glisser dans une direction.\nAppuyez sur la coche(V) pour confirmer.\n\n[accent]Détruisez tous les blocs de ferraille à gauche de votre base à l'aide de la sélection de zone. -tutorial.withdraw = Dans certaines situations, il est nécessaire de prendre des articles directement des blocs..\nPour faire ça, [accent]tapez sur un bloc[] avec des articles à l'intérieur, alors [accent]appuyez sur l'élément[] dans l'inventaire.\nPlusieurs éléments peuvent être retirés en [accent]tapotant et en maintenant enfoncée la touche[].\n\n[accent]Retirez un peu de cuivre de votre base.[] -tutorial.deposit = Déposez les éléments dans des blocs en les faisant glisser de votre vaisseau vers un module de stockage.\n\n[accent]Déposez votre cuivre dans la base.[] -tutorial.waves = Les [lightgray]ennemies[] approchent.\n\nDéfendez votre base durant 2 vagues.\nConstruisez plus de tourelles et de foreuses. Minez plus de cuivre. -tutorial.waves.mobile = [lightgray]Les ennemies approchent[].\n\nDéfendez votre base durant 2 vagues. Votre vaisseau tirera automatiquement sur les ennemis.\nConstruisez plus de tourelles et de foreuses. Minez plus de cuivre. -tutorial.launch = Une fois que vous atteignez une vague spécifique, vous êtes en mesure de[accent] lancer votre base[], laissant vos défenses derrière vous et[accent] en obtenant toutes les ressources de votre base.[]\nCes ressources peuvent ensuite servir à la recherche de nouvelles technologies.\n\n[accent]Appuyez sur le bouton de lancement. - -item.copper.description = Un matériau de construction utile. Utilisé intensivement dans tout les blocs. -item.lead.description = Un matériau de départ. Utilisé intensivement en électronique et pour le transport de blocs. -item.metaglass.description = Un composé de verre très résistant. Utilisation intensive pour la distribution et le stockage de liquides. -item.graphite.description = Carbone minéralisé, utilisé pour les munitions et l’isolation électrique. -item.sand.description = Un matériau commun utilisé largement dans la fonte, à la fois dans l'alliage et comme un flux. -item.coal.description = Un carburant commun et facile à obtenir. -item.titanium.description = Un métal rare super-léger largement utilisé dans le transport de liquides et d'objets ainsi que dans les foreuses de haut-niveau et l'aviation -item.thorium.description = Un métal dense, et radioactif utilisé comme support structurel et comme carburant nucléaire. -item.scrap.description = Restes de vieilles structures et unités. Contient des traces de nombreux métaux différents. -item.silicon.description = Un matériau semi-conducteur extrêmement utile, avec des utilisations dans les panneaux solaires et beaucoup d'autre composants électroniques complexes. -item.plastanium.description = Un matériau léger et docile utilisé dans l'aviation avancée et dans les munitions à fragmentation. -item.phase-fabric.description = Une substance presque en apesanteur utilisée dans l'électronique de pointe et la technologie autoréparable. -item.surge-alloy.description = Un alliage avancé aux propriétés électriques uniques. -item.spore-pod.description = Utilisé pour l'obtention d'huile, d'explosifs et de carburants -item.blast-compound.description = Un composé volatile utilisé dans les bombes et les explosifs. Bien qu'il puisse être utilisé comme carburant, ce n'est pas conseillé. -item.pyratite.description = Une substance extrêmement inflammable utilisée dans les armes incendiaires. -liquid.water.description = Couramment utilisé pour les machines de refroidissement et le traitement des déchets. -liquid.slag.description = Différents types de métaux en fusion mélangés. Peut être séparé en ses minéraux constitutifs ou pulvérisé sur les unités ennemies comme une arme. -liquid.oil.description = Peut être brûlé, explosé ou utilisé comme liquide de refroidissement. -liquid.cryofluid.description = Le liquide de refroidissement le plus efficace. - -block.message.description = Stores a message. Used for communication between allies. -block.graphite-press.description = Compresse des morceaux de charbon en feuilles de graphite. -block.multi-press.description = Une version améliorée de la presse à graphite. Utilise de l'eau et de l'électricité pour traiter le charbon rapidement et efficacement. -block.silicon-smelter.description = Réduit le sable avec du coke* très pur afin de produire du silicium. (*Coke produit à partir de charbon:REF) -block.kiln.description = Fait fondre le sable et le plomb en métaverre. Nécessite de petites quantités d'énergie. -block.plastanium-compressor.description = Produit du plastanium à partir de pétrole et de titane. -block.phase-weaver.description = Produit un tissu de phase à partir de thorium radioactif et de grandes quantités de sable. -block.alloy-smelter.description = Produit un alliage de surtension à partir de titane, plomb, silicium et cuivre. -block.cryofluid-mixer.description = L'eau et le titane combinés forment un fluide cryo beaucoup plus efficace pour le refroidissement. -block.blast-mixer.description = Utilise du pétrole pour transformer la pyratite en un composé explosif moins inflammable mais plus explosif. -block.pyratite-mixer.description = Mélange le charbon, le plomb et le sable en pyratite hautement inflammable. -block.melter.description = Chauffe la pierre à des températures très élevées pour obtenir de la lave. -block.separator.description = Exposer la pierre à la pression de l'eau afin d'obtenir différents minéraux contenus dans la pierre. -block.spore-press.description = Comprime les gousses de spores en huile. -block.pulverizer.description = Brise la pierre en sable. Utile en cas de manque de sable naturel. -block.coal-centrifuge.description = Solidifie le pétrole en morceaux de charbon. -block.incinerator.description = Se débarrasse de tout article ou liquide en excès. -block.power-void.description = Annule toute l'énergie qui y est introduite. Bac à sable seulement. -block.power-source.description = Débit infini d'énergie. Bac à sable seulement. -block.item-source.description = Sort infiniment les articles. Bac à sable seulement. -block.item-void.description = Détruit tous les objets qui y entrent sans utiliser d'énergie. Bac à sable seulement. -block.liquid-source.description = Débit infini de liquides. Bac à sable seulement. -block.liquid-void.description = Removes any liquids. Sandbox only. -block.copper-wall.description = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues. -block.copper-wall-large.description = Un bloc défensif bon marché.\nUtile pour protéger le noyau et les tourelles lors des premières vagues.\nS'étend sur plusieurs tuiles. -block.titanium-wall.description = Un bloc défensif modérément fort.\nFournit une protection modérée contre les ennemis. -block.titanium-wall-large.description = Un bloc défensif modérément fort.\nFournit une protection modérée contre les ennemis.\nS'étend sur plusieurs tuiles. -block.plastanium-wall.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections. -block.plastanium-wall-large.description = A special type of wall that absorbs electric arcs and blocks automatic power node connections.\nSpans multiple tiles. -block.thorium-wall.description = Un puissant bloc défensif.\nBonne protection contre les ennemis. -block.thorium-wall-large.description = Un puissant bloc défensif.\nBonne protection contre les ennemis.\nS'étend sur plusieurs tuiles. -block.phase-wall.description = Pas aussi fort qu'un mur de thorium, mais détournera les balles à moins qu'elles ne soient trop puissantes. -block.phase-wall-large.description = Pas aussi fort qu'un mur de thorium, mais détournera les balles à moins qu'elles ne soient trop puissantes.\nS'étend sur plusieurs tuiles. -block.surge-wall.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant. -block.surge-wall-large.description = Le bloc défensif le plus puissant.\nPeu de chances de déclencher des éclairs en direction de l'attaquant.\nS'étend sur plusieurs tuiles. -block.door.description = Une petite porte qui peut être ouverte et fermée en cliquant dessus.\nSi elle est ouverte, les ennemis peuvent tirer et se déplacer. -block.door-large.description = Une grande porte qui peut être ouverte et fermée en cliquant dessus.\nSi elle est ouverte, les ennemis peuvent tirer et se déplacer.\nS'étend sur plusieurs tuiles. -block.mender.description = Répare périodiquement des blocs à proximité. Garder les défenses réparées entre les vagues.\nUtilise éventuellement du silicium pour augmenter la portée et l'efficacité. -block.mend-projector.description = Guérit périodiquement les bâtiments situés à proximité. -block.overdrive-projector.description = Augmente la vitesse des bâtiments à proximité, comme les foreuses et les convoyeurs. -block.force-projector.description = Crée un champ de force hexagonal autour de lui-même, protégeant les bâtiments et les unités internes des dommages causés par les balles. -block.shock-mine.description = Endommage les ennemis qui marchent sur la mine. Presque invisible à l'ennemi. -block.conveyor.description = Bloc de transport d'articles standard.\nDéplace les objets et les déposes automatiquement dans des tourelles ou des usines. Rotatif. -block.titanium-conveyor.description = Bloc de transport d'articles avancé.\nDéplace les articles plus rapidement que les convoyeurs standard. -block.plastanium-conveyor.description = Moves items in batches.\nAccepts items at the back, and unloads them in three directions at the front. -block.junction.description = Agit comme un pont pour deux bandes transporteuses qui se croisent.\nUtile dans les situations avec deux convoyeurs différents transportant des matériaux différents à des endroits différents. -block.bridge-conveyor.description = Bloc de transport d'articles avancé. Permet de transporter des objets sur plus de 3 tuiles de n'importe quel terrain ou bâtiment. -block.phase-conveyor.description = Bloc de transport d'articles avancé.\nUtilise le pouvoir de téléporter des articles vers un convoyeur de phase connecté sur plusieurs carreaux. -block.sorter.description = Trie les articles. Si un article correspond à la sélection, il peut passer. Autrement, l'article est distribué vers la gauche ou la droite. -block.inverted-sorter.description = Processes items like a standard sorter, but outputs selected items to the sides instead. -block.router.description = Accepte les éléments d'une direction et les envoie dans 3 autres directions de manière égale. Utile pour séparer les matériaux d'une source en plusieurs cibles. -block.distributor.description = Un routeur avancé qui divise les articles en 7 autres directions de manière égale. [scarlet]Seule et unique ![] -block.overflow-gate.description = C'est la combinaison entre un routeur et un diviseur qui peut seulement distribuer à gauche et à droite si le chemin de devant est bloqué. -block.underflow-gate.description = Le contraire d'une barrière de débordement.\nEnvoie les ressources vers l'avant si les chemins de gauche et de droite sont bloqués. -block.mass-driver.description = Bloc de transport d'articles ultime.\nRecueille plusieurs objets et les envoie ensuite à un autre pilote de masse sur une longue distance. -block.mechanical-pump.description = Une pompe bon marché avec un débit lent, mais aucune consommation d'énergie. -block.rotary-pump.description = Une pompe avancée qui double la vitesse en utilisant l’énergie. -block.thermal-pump.description = La pompe ultime. Trois fois plus rapide qu'une pompe mécanique et la seule pompe capable de récupérer de la lave. -block.conduit.description = Bloc de transport liquide de base. Fonctionne comme un convoyeur, mais avec des liquides. Utilisation optimale avec des extracteurs, des pompes ou d’autres conduits. -block.pulse-conduit.description = Bloc de transport de liquide avancé. Transporte les liquides plus rapidement et stocke plus que des conduits standard. -block.plated-conduit.description = Moves liquids at the same rate as pulse conduits, but possesses more armor. Does not accept fluids from the sides by anything other than conduits.\nLeaks less. -block.liquid-router.description = Accepte les liquides d'une direction et les envoie dans 3 autres directions de manière égale. Peut également stocker une certaine quantité de liquide. Utile pour séparer les liquides d'une source à plusieurs cibles. -block.liquid-tank.description = Stocke une grande quantité de liquides. Utilisez-le pour créer des tampons en cas de demande non constante de matériaux ou comme protection pour le refroidissement des blocs vitaux. -block.liquid-junction.description = Agit comme un pont pour deux conduits de croisement. Utile dans les situations avec deux conduits différents transportant des liquides différents à des endroits différents. -block.bridge-conduit.description = Bloc de transport de liquide avancé. Permet de transporter des liquides jusqu'à 3 tuiles de n'importe quel terrain ou bâtiment. -block.phase-conduit.description = Bloc de transport de liquide avancé. Utilise le pouvoir de téléporter des liquides vers un conduit de phase connecté sur plusieurs carreaux. -block.power-node.description = Transmet la puissance à des noeuds connectés. Il est possible de connecter jusqu'à quatre sources d'alimentation, puits ou nœuds.\nLe nœud recevra de l’alimentation ou fournira l’alimentation à tous les blocs adjacents. -block.power-node-large.description = Son rayon d'action est supérieur à celui du nœud d'alimentation et peut être connecté à six sources d'alimentation, puits ou nœuds au maximum. -block.surge-tower.description = Un nœud d'alimentation extrêmement longue portée avec moins de connexions disponibles. -block.diode.description = Battery power can flow through this block in only one direction, but only if the other side has less power stored. -block.battery.description = Stocke l’énergie chaque fois qu’il ya abondance et en cas de pénurie, tant qu’il reste de la capacité. -block.battery-large.description = Stocke beaucoup plus d'énergie qu'une batterie ordinaire. -block.combustion-generator.description = Génère de l'énergie en brûlant du pétrole ou des matériaux inflammables. -block.thermal-generator.description = Génère une grande quantité d'énergie grâce à la lave. -block.steam-generator.description = Plus efficace qu'un générateur de combustion, mais nécessite de l'eau supplémentaire. -block.differential-generator.description = Génère de grandes quantités d'énergie. Utilise la différence de température entre le cryofluide et la pyratite en combustion. -block.rtg-generator.description = Générateur thermoélectrique à radio-isotopes ne nécessitant pas de refroidissement mais fournissant moins d'énergie qu'un réacteur à thorium. -block.solar-panel.description = Fournit une petite quantité d'énergie grâce au soleil. -block.solar-panel-large.description = Fournit une bien meilleure alimentation qu'un panneau solaire standard, mais coûte également beaucoup plus cher à construire. -block.thorium-reactor.description = Génère d'énormes quantités d'énergie à partir de thorium hautement radioactif. Nécessite un refroidissement constant.\nExplose violemment si des quantités insuffisantes de liquide de refroidissement ne sont pas fournies. -block.impact-reactor.description = Un groupe électrogène avancé, capable de générer d’énormes quantités d’énergie avec une efficacité maximale.\nNécessite une entrée de puissance significative pour relancer le processus. -block.mechanical-drill.description = Un extracteur bon marché. Lorsqu'il est placé sur des carreaux appropriés, les objets sortent à un rythme lent et indéfiniment. -block.pneumatic-drill.description = Un extracteur améliorée, plus rapide et capable de traiter des matériaux plus durs en utilisant la pression atmosphérique. -block.laser-drill.description = Permet de forer encore plus rapidement grâce à la technologie laser, mais nécessite de l'énergie. De plus, le thorium radioactif peut être récupéré avec cet extracteur. -block.blast-drill.description = L'extracteur ultime. Nécessite de grandes quantités d'énergie. -block.water-extractor.description = Extrait l'eau du sol. Utilisez-le quand il n'y a pas de lac à proximité. -block.cultivator.description = Cultiver le sol avec de l'eau afin d'obtenir du biomatter. -block.oil-extractor.description = Utilise de grandes quantités d'énergie pour extraire le pétrole du sable. Utilisez-le lorsqu'il n'y a pas de source directe de pétrole à proximité. -block.core-shard.description = La première version de la base centrale. Une fois détruit, tout contact avec la région est perdu. Ne laissez pas cela arriver. -block.core-foundation.description = La deuxième version de la base centrale. Mieux blindé. Stocke plus de ressources. -block.core-nucleus.description = La troisième et dernière version de la base centrale. Extrêmement bien blindé. Stocke des quantités massives de ressources. -block.vault.description = Stocke une grande quantité d'objets. Utilisez-le pour créer des tampons lorsqu'il existe une demande non constante de matériaux. [lightgray]Un déchargeur[] peut être utilisé pour récupérer des éléments du coffre-fort. -block.container.description = Stocke une petite quantité d'objets. Utilisez-le pour créer des tampons lorsqu'il existe une demande non constante de matériaux. [lightgray]Un déchargeur[] peut être utilisé pour récupérer des éléments du conteneur. -block.unloader.description = Décharge des articles d'un conteneur, d'une chambre forte ou d'un noyau sur un convoyeur ou directement dans un bloc adjacent.\nLe type d'élément à décharger peut être modifié en tapotant sur le déchargeur. -block.launch-pad.description = Lance des lots d'articles sans qu'il soit nécessaire de procéder à un lancement de base. Inachevé. -block.launch-pad-large.description = Une version améliorée de la rampe de lancement. Stocke plus d'articles. Lancements plus fréquemment. -block.duo.description = Une petite tourelle pas chère. -block.scatter.description = Une tourelle anti-air de taille moyenne. Pulvérise des amas de plomb ou de ferraille sur les unités ennemies. -block.scorch.description = Brûle les ennemis au sol les plus proches. Très efficace à courte portée. -block.hail.description = Une petite tourelle d'artillerie. -block.wave.description = Une tourelle de taille moyenne à tir rapide qui tire des bulles de liquide. -block.lancer.description = Une tourelle de taille moyenne qui tire des faisceaux d’électricité chargés. -block.arc.description = Une petite tourelle qui tire de l'électricité dans un arc au hasard vers l'ennemi. -block.swarmer.description = Une tourelle de taille moyenne qui tire des missiles éclatés. -block.salvo.description = Une tourelle de taille moyenne qui tire des coups de salves. -block.fuse.description = Une grande tourelle qui tire de puissants faisceaux à courte portée. -block.ripple.description = Une grande tourelle d'artillerie qui tire plusieurs coups simultanément. -block.cyclone.description = Une grande tourelle à tir rapide. -block.spectre.description = Une grande tourelle qui tire deux balles puissantes à la fois. -block.meltdown.description = Une grande tourelle qui tire de puissants faisceaux à longue portée. -block.repair-point.description = Soigne en permanence l'unité endommagée la plus proche à proximité. -block.segment.description = Damages and destroys incoming projectiles. Laser projectiles are not targeted. diff --git a/fastlane/metadata/steam/french/achievements.vdf b/fastlane/metadata/steam/french/achievements.vdf index 316945c53c..79305dbebb 100644 --- a/fastlane/metadata/steam/french/achievements.vdf +++ b/fastlane/metadata/steam/french/achievements.vdf @@ -3,16 +3,12 @@ "Language" "french" "Tokens" { - "NEW_ACHIEVEMENT_20_0_NAME" "Certifié" - "NEW_ACHIEVEMENT_20_0_DESC" "Terminer le tutoriel." "NEW_ACHIEVEMENT_20_1_NAME" "Bagarreur" "NEW_ACHIEVEMENT_20_1_DESC" "Détruire 1 000 unités ennemies." "NEW_ACHIEVEMENT_20_2_NAME" "Purge" "NEW_ACHIEVEMENT_20_2_DESC" "Détruire 100 000 unités ennemies." - "NEW_ACHIEVEMENT_20_3_NAME" "Transport Atmosphérique" - "NEW_ACHIEVEMENT_20_3_DESC" "Transférer 10 000 ressources." "NEW_ACHIEVEMENT_20_5_NAME" "Livraison Sans Fin" - "NEW_ACHIEVEMENT_20_5_DESC" "Transférer 1 000 000 ressources." + "NEW_ACHIEVEMENT_20_5_DESC" "Transférer 100 000 ressources." "NEW_ACHIEVEMENT_20_6_NAME" "Conquérant" "NEW_ACHIEVEMENT_20_6_DESC" "Remporter 10 matchs en mode Attaque." "NEW_ACHIEVEMENT_20_7_NAME" "Champion" @@ -23,16 +19,12 @@ "NEW_ACHIEVEMENT_20_9_DESC" "Lancer votre Noyau dans une zone 30 fois." "NEW_ACHIEVEMENT_20_10_NAME" "Tenace" "NEW_ACHIEVEMENT_20_10_DESC" "Survivre 100 vagues." - "NEW_ACHIEVEMENT_20_11_NAME" "Invaincu" - "NEW_ACHIEVEMENT_20_11_DESC" "Survivre 500 vagues." "NEW_ACHIEVEMENT_20_12_NAME" "Chercheur" "NEW_ACHIEVEMENT_20_12_DESC" "Rechercher toutes les technologies." - "NEW_ACHIEVEMENT_20_13_NAME" "Transformiste" - "NEW_ACHIEVEMENT_20_13_DESC" "Débloquer et utiliser tous les Méchas du jeu." "NEW_ACHIEVEMENT_20_14_NAME" "Surcharge" "NEW_ACHIEVEMENT_20_14_DESC" "Toucher un ennemi couvert d'eau avec un tir électrique." "NEW_ACHIEVEMENT_20_15_NAME" "Déflexion" - "NEW_ACHIEVEMENT_20_15_DESC" "Détruire une unité avec la reflexion de son propre tir." + "NEW_ACHIEVEMENT_20_15_DESC" "Détruire une unité avec la reflexion de ses propres balles." "NEW_ACHIEVEMENT_20_17_NAME" "Une Grave Erreur" "NEW_ACHIEVEMENT_20_17_DESC" "Rechercher le Routeur." "NEW_ACHIEVEMENT_20_18_NAME" "Créer" @@ -42,7 +34,7 @@ "NEW_ACHIEVEMENT_20_20_NAME" "Un Désastre Spectaculaire" "NEW_ACHIEVEMENT_20_20_DESC" "Provoquer l'explosion d'un Réacteur à Thorium en le faisant surchauffer." "NEW_ACHIEVEMENT_20_21_NAME" "Cartographe" - "NEW_ACHIEVEMENT_20_21_DESC" "Éditer une nouvelle carte 10 fois." + "NEW_ACHIEVEMENT_20_21_DESC" "Créer une nouvelle carte 10 fois." "NEW_ACHIEVEMENT_20_22_NAME" "Navigateur" "NEW_ACHIEVEMENT_20_22_DESC" "Télécharger une carte sur le Workshop." "NEW_ACHIEVEMENT_20_23_NAME" "Créateur" @@ -51,8 +43,6 @@ "NEW_ACHIEVEMENT_20_24_DESC" "Vaincre un boss." "NEW_ACHIEVEMENT_20_25_NAME" "Explorateur" "NEW_ACHIEVEMENT_20_25_DESC" "Débloquer toutes les zones de la campagne." - "NEW_ACHIEVEMENT_20_26_NAME" "Complétionniste" - "NEW_ACHIEVEMENT_20_26_DESC" "Atteindre la vague requise pour débloquer la configuration des ressources sur chaque zones." "NEW_ACHIEVEMENT_20_29_NAME" "Matériau II" "NEW_ACHIEVEMENT_20_29_DESC" "Débloquer le Thorium." "NEW_ACHIEVEMENT_20_31_NAME" "Matériau I" @@ -60,35 +50,29 @@ "NEW_ACHIEVEMENT_21_0_NAME" "Kamikaze" "NEW_ACHIEVEMENT_21_0_DESC" "Remplir votre Mécha de matériaux explosifs et mourir en créant une explosion." "NEW_ACHIEVEMENT_21_1_NAME" "Le Commencement" - "NEW_ACHIEVEMENT_21_1_DESC" "Construire une Usine de Méchas Poignards." + "NEW_ACHIEVEMENT_21_1_DESC" "Construire une Usine d'unités terrestres'." "NEW_ACHIEVEMENT_21_2_NAME" "Attaque Directe " "NEW_ACHIEVEMENT_21_2_DESC" "Utiliser la commande Attaque du Centre de Commandement." "NEW_ACHIEVEMENT_21_3_NAME" "Horde" "NEW_ACHIEVEMENT_21_3_DESC" "Avoir 100 unités actives en même temps." "NEW_ACHIEVEMENT_21_4_NAME" "Fidèles" - "NEW_ACHIEVEMENT_21_4_DESC" "Avoir 10 Drones Fantômes actifs en même temps." - "NEW_ACHIEVEMENT_21_5_NAME" "Armée Instable" - "NEW_ACHIEVEMENT_21_5_DESC" "Avoir 50 Rampeurs actifs en même temps." + "NEW_ACHIEVEMENT_21_4_DESC" "Avoir 10 Megas actifs en même temps." + "NEW_ACHIEVEMENT_21_5_NAME" "Roboticien" + "NEW_ACHIEVEMENT_21_5_DESC" "Construire chaque type d'unité." "NEW_ACHIEVEMENT_21_6_NAME" "Légions" "NEW_ACHIEVEMENT_21_6_DESC" "Construire 1000 unités total." - "NEW_ACHIEVEMENT_21_7_NAME" "Super" - "NEW_ACHIEVEMENT_21_7_DESC" "Atteindre le rang S dans n'importe quelle zone." - "NEW_ACHIEVEMENT_21_8_NAME" "Super Super" - "NEW_ACHIEVEMENT_21_8_DESC" "Atteindre le rang SS dans n'importe quelle zone" "NEW_ACHIEVEMENT_21_9_NAME" "Tu Aurais Dû Écouter" "NEW_ACHIEVEMENT_21_9_DESC" "Mourir dans la zone d'exclusion du point d'apparition ennemi." - "NEW_ACHIEVEMENT_21_10_NAME" "Il Suffit De Sprinter..." + "NEW_ACHIEVEMENT_21_10_NAME" "Il y a des unités navales pour ça..." "NEW_ACHIEVEMENT_21_10_DESC" "Réussir à couler." "NEW_ACHIEVEMENT_21_11_NAME" "Collectionneur" "NEW_ACHIEVEMENT_21_11_DESC" "Remplir le Noyau au maximum de sa capacité avec tous les types de matériaux." "NEW_ACHIEVEMENT_21_12_NAME" "Foule" "NEW_ACHIEVEMENT_21_12_DESC" "Héberger un serveur avec 10 joueurs connectés." - "NEW_ACHIEVEMENT_21_13_NAME" "Invulnerable" - "NEW_ACHIEVEMENT_21_13_DESC" "Construire les tourelles Fusion et Spectre." + "NEW_ACHIEVEMENT_21_13_NAME" "Invulnérable" + "NEW_ACHIEVEMENT_21_13_DESC" "Construire le Meltdown, le Spectre et le Présage." "NEW_ACHIEVEMENT_21_14_NAME" "Décollage" "NEW_ACHIEVEMENT_21_14_DESC" "Utiliser la Plateforme de Lancement." - "NEW_ACHIEVEMENT_21_15_NAME" "Complaisance" - "NEW_ACHIEVEMENT_21_15_DESC" "Passer le lancement deux fois, puis se faire anéantir par l'ennemi." "NEW_ACHIEVEMENT_21_16_NAME" "Hérésie" "NEW_ACHIEVEMENT_21_16_DESC" "Construire deux routeurs côte à côte." "NEW_ACHIEVEMENT_21_17_NAME" "Gardien Solitaire" @@ -105,5 +89,27 @@ "NEW_ACHIEVEMENT_21_22_DESC" "Démarrer une zone en emportant 10 000 ressources ou plus." "NEW_ACHIEVEMENT_21_23_NAME" "Allumage" "NEW_ACHIEVEMENT_21_23_DESC" "Lancer un Réacteur à Impact." + "NEW_ACHIEVEMENT_21_24_NAME" "Accélération" + "NEW_ACHIEVEMENT_21_24_DESC" "Activater l'Accélérateur Interplanétaire." + "NEW_ACHIEVEMENT_21_25_NAME" "La Spirale" + "NEW_ACHIEVEMENT_21_25_DESC" "Round and round it goes..." + "NEW_ACHIEVEMENT_21_26_NAME" "Escalade" + "NEW_ACHIEVEMENT_21_26_DESC" "Construire une unité de niveau 5." + "NEW_ACHIEVEMENT_21_27_NAME" "Architecte" + "NEW_ACHIEVEMENT_21_27_DESC" "Créer 20 schémas." + "NEW_ACHIEVEMENT_21_28_NAME" "Domination Globale" + "NEW_ACHIEVEMENT_21_28_DESC" "Capturer tous les secteurs de Serpulo." + "NEW_ACHIEVEMENT_21_29_NAME" "Transport Aérien" + "NEW_ACHIEVEMENT_21_29_DESC" "Transporter une unité de niveau 5 avec un Oct." + "NEW_ACHIEVEMENT_21_30_NAME" "La Forme de vie Suprême" + "NEW_ACHIEVEMENT_21_30_DESC" "Rejoignez-les." + "NEW_ACHIEVEMENT_21_31_NAME" "Production I" + "NEW_ACHIEVEMENT_21_31_DESC" "Atteindre 5 000 objets/min de production totale dans la campagne." + "NEW_ACHIEVEMENT_26_0_NAME" "Production II" + "NEW_ACHIEVEMENT_26_0_DESC" "Atteindre 50,000 items/min de production totale dans la campagne." + "NEW_ACHIEVEMENT_26_1_NAME" "Victoire Assurée" + "NEW_ACHIEVEMENT_26_1_DESC" "Capturer un secteur pendant que vous jouez dans un autre." + "NEW_ACHIEVEMENT_26_2_NAME" "Petit Empire" + "NEW_ACHIEVEMENT_26_2_DESC" "Contrôller 10 secteurs à la fois." } } diff --git a/fastlane/metadata/steam/french/short-description.txt b/fastlane/metadata/steam/french/short-description.txt index 1198f34de7..e8deb5ded0 100644 --- a/fastlane/metadata/steam/french/short-description.txt +++ b/fastlane/metadata/steam/french/short-description.txt @@ -1 +1 @@ -Un tower-defense ouvert axé sur la gestion des ressources. +Un tower-defense ouvert, axé sur la gestion des ressources. From ae921bf266f5b616b19a9b6685dcbcd7302e1e6d Mon Sep 17 00:00:00 2001 From: ZirKNkium611 <76028150+ZirKNkium611@users.noreply.github.com> Date: Tue, 19 Jan 2021 14:22:47 -0600 Subject: [PATCH 087/426] Update bundle_es.properties (#4027) * Update bundle_es.properties correcting and improving some translations * Update bundle_es.properties correcting team names --- core/assets/bundles/bundle_es.properties | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index 60e9538f1a..6f62033ba2 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -24,7 +24,7 @@ gameover.waiting = [accent]Esperando el próximo mapa... highscore = [accent]¡Nuevo récord de puntuación! copied = Copiado indev.notready = Esta parte del juego no esta lista aún. -indev.campaign = [accent]Has llegado al final de la campaña![]\n\nEsto es todo lo lejos que puedes llegar por ahora.\nLos viajes interplanetarios se añadirán en futuras actualizaciones. +indev.campaign = [accent]Has llegado al final de la campaña![]\n\nEsto es lo más lejos que puedes llegar por ahora.\nLos viajes interplanetarios se añadirán en futuras actualizaciones. load.sound = Sonidos load.map = Mapas @@ -570,7 +570,7 @@ threat.low = Baja threat.medium = Media threat.high = Alta threat.extreme = Extrema -threat.eradication = Exterminio +threat.eradication = Erradicación planets = Planetas @@ -585,7 +585,7 @@ sector.ruinousShores.name = Costas Ruinosas sector.stainedMountains.name = Montañas manchadas sector.desolateRift.name = Grieta desolada sector.nuclearComplex.name = Complejo de producción nuclear -sector.overgrowth.name = Crecimiento excesivo +sector.overgrowth.name = Sobrecrecimiento sector.tarFields.name = Campos de alquitrán sector.saltFlats.name = Llanuras de sal sector.fungalPass.name = Paso de hongos @@ -594,13 +594,13 @@ sector.windsweptIslands.name = Islas Windswept sector.extractionOutpost.name = Puesto de avanzada de Extracción sector.planetaryTerminal.name = Terminal de Lanzamiento Interplanetario -sector.groundZero.description = La ubicación adecuada para empezar una vez más. Baja amenaza enemiga. Pocos recursos.\nReúna la mayor cantidad de plomo y cobre posible y sigue adelante. +sector.groundZero.description = La ubicación adecuada para empezar una vez más. Amenaza enemiga baja. Pocos recursos.\nReúna la mayor cantidad de plomo y cobre posible y sigue adelante. sector.frozenForest.description = Incluso aquí, más cerca de las montañas, las esporas se han extendido. Las gélidas temperaturas no las contendrán para siempre.\n\nAprende a usar la energía. Construye generadores de combustión. Aprende a usar reparadores. sector.saltFlats.description = En las afueras del desierto se encuentran las Salinas. No hay muchos recursos en esta ubicación.\n\nEl enemigo ha creado un complejo de almacenamiento de recursos aquí. Erradica su núcleo. No dejes nada en pie. sector.craters.description = El agua se ha acumulado en este cráter, reliquia de las viejas guerras. Recupera la zona. Recoge arena. Funde Metacristal. Bombea agua para enfriar torretas y taladros. sector.ruinousShores.description = Más allá de los páramos, se encuentra la costa. Una vez, esta ubicación albergó una serie de defensa costera. No queda mucho. Solo las estructuras de defensa más básicas han quedado ilesas, todo lo demás está reducido a chatarra.\nContinúa la expansión. Redescubre la tecnología. sector.stainedMountains.description = Más adentro se encuentran las montañas, aún intactas por las esporas.\nExtrae el abundante titanio de esta zona. Aprende a usarlo.\n\nLa presencia enemiga es mayor aquí. No les des tiempo para enviar sus unidades más fuertes. -sector.overgrowth.description = El área está cubierta de maleza, más cerca de la fuente de las esporas.\nEl enemigo ha establecido un puesto de avanzada aquí. Construye unidades Titán. Destruyelo. Recupera lo que se perdió. +sector.overgrowth.description = El área está cubierta de maleza, más cerca de la fuente de las esporas.\nEl enemigo ha establecido un puesto de avanzada aquí. Construye unidades Mace. Destruyelo. Recupera lo que se perdió. sector.tarFields.description = Las afueras de una zona de producción de petróleo, entre la montaña y el desierto. Una de las pocas áreas con reservas de alquitrán utilizables.\nAunque está abandonada, esta zona tiene algunas fuerzas enemigas peligrosas cerca. No los subestimes.\n\n[lightgray]Investiga la tecnología de procesamiento de petróleo si es posible. sector.desolateRift.description = Una zona extremadamente peligrosa. Recursos abundantes, pero poco espacio. Alto riesgo de destrucción. Abandona el lugar lo antes posible. No te dejes engañar por el intervalo entre los ataques enemigos. sector.nuclearComplex.description = Antigua instalación de producción y procesamiento de torio, reducida a ruinas.\n[lightgray] Investiga el torio y sus múltiples usos.\n\nEl enemigo está presente aquí,superando en número a sus atacantes. @@ -706,11 +706,11 @@ stat.abilities = Habilidades stat.canboost = Tiene Propulsores stat.flying = Aéreo -ability.forcefield = Zona de Escudo -ability.repairfield = Zona de Reparación -ability.statusfield = Zona de Estado +ability.forcefield = Campo de Fuerza +ability.repairfield = Campo de Reparación +ability.statusfield = Campo de Estado ability.unitspawn = {0} Fábrica de Drones -ability.shieldregenfield = Regeneración de Escudos +ability.shieldregenfield = Campo de Regeneración de Escudos ability.movelightning = Movimiento Relámpago bar.drilltierreq = Requiere un taladro mejor @@ -735,7 +735,7 @@ bar.progress = Progreso de construcción bar.input = Entrada bar.output = Salida -units.processorcontrol = [lightgray]Procesador Controlado +units.processorcontrol = [lightgray]Controlado por Procesador bullet.damage = [stat]{0}[lightgray] Daño bullet.splashdamage = [stat]{0}[lightgray] daño de área ~[stat] {1}[lightgray] casillas @@ -796,7 +796,7 @@ setting.indicators.name = Indicadores de Enemigos setting.autotarget.name = Auto-Apuntado setting.keyboard.name = Controles de Ratón+Teclado setting.touchscreen.name = Controles Táctiles -setting.fpscap.name = Máximos FPS +setting.fpscap.name = FPS Maxímos setting.fpscap.none = Nada setting.fpscap.text = {0} FPS setting.uiscale.name = Escala de Interfaz[lightgray] (necesita reiniciar)[] @@ -823,7 +823,7 @@ setting.smoothcamera.name = Movimiento de cámara suave setting.vsync.name = VSync (Limita los fps a los Hz de tu pantalla) setting.pixelate.name = Pixelar setting.minimap.name = Mostrar Minimapa -setting.coreitems.name = Mostrar elementos en el nucleo (WIP) +setting.coreitems.name = Mostrar Objetos en el nucleo (WIP) setting.position.name = Mostrar indicadores de posición de jugadores. setting.musicvol.name = Volumen de la Música setting.atmosphere.name = Mostrar Atmósfera del planeta @@ -852,7 +852,7 @@ category.view.name = Visión category.multiplayer.name = Multijugador category.blocks.name = Seleccionar bloques command.attack = Atacar -command.rally = Patrullar +command.rally = Reunirse command.retreat = Retirarse command.idle = Esperar placement.blockselectkeys = \n[lightgray]Códigos: [{0}, @@ -1232,7 +1232,7 @@ block.disassembler.name = Desensamblador block.silicon-crucible.name = Crisol de silicio block.overdrive-dome.name = Campo de Aceleración #experimental, puede ser eliminado -block.block-forge.name = Fundidor de Bloques +block.block-forge.name = Forja de Bloques block.block-loader.name = Cargador de Bloques block.block-unloader.name = Descargador de Bloques block.interplanetary-accelerator.name = Acelerador Interplanetario @@ -1247,10 +1247,10 @@ block.memory-cell.name = Unidad de memoria block.memory-bank.name = Servidor de memoria team.blue.name = azul -team.crux.name = rojo -team.sharded.name = naranja +team.crux.name = crux +team.sharded.name = sharded team.orange.name = naranja -team.derelict.name = abandonado +team.derelict.name = delerict team.green.name = verde team.purple.name = morado @@ -1269,7 +1269,7 @@ hint.placeConveyor = Las cintas transportadoras pueden sacar objetos de los tala hint.placeConveyor.mobile = Las cintas transportadoras pueden mover objetos de los taladros hasta otros bloques. Selecciona un \uf896 [accent]Transportador[] de la pestaña \ue814 [accent]Distribución[].\n\nMantén el dedo un segundo y arrastra para crear múltiples cintas transportadoras. hint.placeTurret = Construye \uf861 [accent]Torretas[] para defender tu base de los enemigos.\n\nLas torretas necesitan munición - en este caso, \uf838cobre.\nUsa cintas transportadoras y taladros para abastecerlas con cobre. hint.breaking = Pulsa [accent]Clic-derecho[] y arrastra para destruir bloques. -hint.breaking.mobile = Activa el botón con el \ue817 [accent]martillo[] situado abajo a la derecha y selecciona bloque para eliminarlos.\n\nMantén el dedo un segundo y arrastra para eliminar bloques directamente en esa selección. +hint.breaking.mobile = Activa el botón con el \ue817 [accent]martillo[] situado abajo a la derecha y selecciona bloques para eliminarlos.\n\nMantén el dedo un segundo y arrastra para eliminar bloques directamente en esa selección. hint.research = Usa el botón \ue875 [accent]Investigación[] para acceder al menú de descubrimientos tecnológicos. hint.research.mobile = Usa el botón \ue875 [accent]Investigación[] para acceder al menú de descubrimientos tecnológicos. hint.unitControl = Mantén [accent][[L-ctrl][] y [accent]haz clic[] sobre unidades o torretas aliadas para controlarlas manualmente. @@ -1286,7 +1286,7 @@ hint.payloadPickup = Pulsa [accent][[[] para recoger bloques pequeños o unidade hint.payloadPickup.mobile = [accent]Mantén[] sobre un bloque pequeño o unidad para recogerlo. hint.payloadDrop = Pulsa [accent]][] para soltar la carga. hint.payloadDrop.mobile = [accent]Mantén[] sobre un lugar vacío para soltar la carga. -hint.waveFire = Cuando las torretas [accent]Wave[] usan agua como munición, apagarán fuego e incendios cercanos automáticamente. +hint.waveFire = Cuando las torretas [accent]Wave[] usen agua como munición, apagarán fuego e incendios cercanos automáticamente. hint.generator = Los \uf879[accent]Generadores de combustión[] querman carbón para transmitir energía a bloques adyacentes.\n\nEl alcance de transmisión de energía se puede extender usando \uf87f[accent]Nodos de energía[]. hint.guardian = Los [accent]Guardianes[] poseen una robusta armadura. Municiones débiles como el [accent]Cobre[] o el [accent]Plomo[] no son [scarlet]effectivas[] contra él.\n\nUsa torretas de mayor categoría o por ejemplo, munición de \uf835[accent]Grafito[] \uf861Duo/\uf859 en torretas Salvo para derribar a los Guardianes. hint.coreUpgrade = Los núcleos se pueden mejorar [accent]construyendo núcleos de mayor calidad encima[].\n\nColoca un  núcleo [accent]Foundation[] sobre el  núcleo [accent]Shard[]. Asegúrate de que no hay obstáculos cerca. @@ -1294,7 +1294,7 @@ hint.presetLaunch = Las zonas de aterrizaje de los [accent]sectores grises[], co hint.coreIncinerate = Tras completar la capacidad máxima de almacenamiento en el núcleo para un tipo de objeto, cualquier recurso adicional de ese tipo que reciba el núcleo será [accent]incinerado[]. hint.coopCampaign = Sí estás jugando el modo [accent]campaña en multijugador[], los objetos producidos en el mapa actual también se enviarán [accent]a los sectores locales de cada jugador[].\n\nCualquier nueva investigación tecnológica realizada por el anfitrión también se desbloqueará para los demás jugadores. -item.copper.description = Un práctico material de estructura. Usado en todo tipo de bloques. +item.copper.description = Un práctico material para construcción. Usado en todo tipo de bloques y munición. item.copper.details = Cobre. Metal anormalmente abundante en Serpulo. Estructuralmente débil a menos que sea reforzado. item.lead.description = Un material básico. Usado en electrónicos y transferencia de líquidos. item.lead.details = Denso. Inerte. Extensamente usado en baterías.\nNota: Suele ser tóxico para la mayoría de formas de vida biológicas. Aunque ya no quedan muchas de esas por aquí. @@ -1445,7 +1445,7 @@ block.parallax.description = Dispara un rayo tractor que atrae enemigos aéreos, block.tsunami.description = Dispara poderosos torrentes de líquido a los enemigos. También apaga fuegos automáticamente si se lo abastece con agua. block.silicon-crucible.description = Refina silicio a partir de arena y carbón, usando pirotita como una fuente de calor adicional. Es más eficiente en lugares cálidos. block.disassembler.description = Separa magma cantidades moderadas de componentes minerales exóticos con baja eficiencia. Puede producir Torio. -block.overdrive-dome.description = Incrementa la velocidad de estructuras cercanas. Requiere Tejido de Fase, y Silicio para operar. +block.overdrive-dome.description = Incrementa la velocidad de estructuras cercanas. Requiere Tejido de Fase y Silicio para operar. block.payload-conveyor.description = Mueve tanto grandes cargas, como unidades recién ensambladas de sus fábricas. block.payload-router.description = Divide las cargas entrantes en 3 direcciones de salida. block.command-center.description = Controla el comportamiento de las unidades con diferentes órdenes. @@ -1479,7 +1479,7 @@ unit.corvus.description = Dispara poderosos láseres que dañan enemigos, y repa unit.crawler.description = Corre hacia enemigos y se autodestruye, provocando una gran explosión. unit.atrax.description = Dispara orbes de magma debilitantes a enemigos terrestres. Puede pisar sobre la mayoría de terreno. unit.spiroct.description = Dispara láseres que debilitan al enemigo, reparándose en el proceso. Puede pisar sobre la mayoría de terreno. -unit.arkyid.description = Dispara grandes rayos láser que debilitan al enemigo, repairing itself in the process. Puede pisar sobre la mayoría de terreno. +unit.arkyid.description = Dispara grandes rayos láser que debilitan al enemigo, reparándose en el proceso. Puede pisar sobre la mayoría de terreno. unit.toxopid.description = Dispara grandes fragmentos electrizados y láseres perforantes. Puede pisar sobre la mayoría de terreno. unit.flare.description = Dispara proyectiles básicos a enemigos cercanos. unit.horizon.description = Suelta fragmentos explosivos sobre objetivos terrestres. From 7e104879262494107d3858e4b555aebbe5b2b507 Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Tue, 19 Jan 2021 23:24:59 +0300 Subject: [PATCH 088/426] [Bundle][RU] actual L10n (#4173) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 1 line changed - noname * 1 line changed - hint.placeTurret * 3 new lines - servers.disclaimer - hint.coreUpgrade - hint.presetLaunch ---- NOTE from Felix Corvus (@Remint32) This commit and PR are the last ones I made to the repository. I want to sincerely thank the people I worked with to enhance the game and translate it into Russian. I want to thank you separately: Prosta4ok_ua (@Prosta4okua), Vanguard (@XEN0PHIL), BasedUser (@BasedUser), Summet (@summetdev), Anuke (@Anuken), The_Slaylord (@TheSlaylord), Lonely_Ymomfe (@ymomfe), and XZimur (@XZimur) * 5 changed lines; 2 new lines Changed: globalitems sector.extractionOutpost.description hint.launch hint.launch.mobile hint.presetLaunch New: hint.coreIncinerate hint.coopCampaign * 2 changed line hint.coopCampaign item.spore-pod.details - В споровом стручке всё же множественное число в описании, говорится про сами споры. THEY EMIT - они выделяют, IT EMITS - он выделяет. * 2 changed lines hint.coreIncinerate block.interplanetary-accelerator.description * 3 new line; 1 changed line New: setting.showweather.name link.bug.description rules.weather.always Changed: keybinds.mobile * 4 new lines; 1 changed line; 1 deleted line New: public.confirm.really bullet.buildingdamage stat.ammouse unit.pershot Changed: bullet.knockback Deleted: bar.limitreached * Update bundle_ru.properties падежи * Update bundle_ru.properties мелочи * 1 changed line stat.ammouse * 1 new line none.found * 6 changed; 1 deleted Changed: mod.featured.dialog.title mods.browser.add mods.github.open mod.import.github mod.jarwarn mods.guide Deleted: mod.featured.title * 2 changed lines link.bug.description mod.scripts.disable * Update achievements.vdf * Update description.txt * 1 changed line item.thorium.description * 1 new line rules.coreincinerates * 1 new line bar.boost * 1 new line max * Update bundle_ru.properties * Update bundle_ru.properties * rip v3.5 maps * Update bundle_ru.properties * Update bundle_ru.properties Co-authored-by: Felix Corvus Co-authored-by: Vanguard <55051135+XEN0PHIL@users.noreply.github.com> Co-authored-by: Prosta4okua <31485341+Prosta4okua@users.noreply.github.com> --- core/assets/bundles/bundle_ru.properties | 30 ++++----- .../metadata/steam/russian/achievements.vdf | 58 ++++++++++-------- .../metadata/steam/russian/description.txt | 61 ++++++++++--------- 3 files changed, 81 insertions(+), 68 deletions(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 3a4afc4188..45753b9a9e 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -13,7 +13,7 @@ link.google-play.description = Скачать для Android с Google Play link.f-droid.description = Скачать для Android с F-Droid link.wiki.description = Официальная вики link.suggestions.description = Предложить новые возможности -link.bug.description = Нашли одну? Доложите о ней здесь +link.bug.description = Нашли ошибку? Доложите о ней здесь linkfail = Не удалось открыть ссылку!\nURL-адрес был скопирован в буфер обмена. screenshot = Скриншот сохранён в {0} screenshot.invalid = Карта слишком большая, возможно, не хватает памяти для скриншота. @@ -41,11 +41,10 @@ be.ignore = Игнорировать be.noupdates = Обновления не найдены. be.check = Проверить обновления -mod.featured.title = Обозреватель модов -mod.featured.dialog.title = Обозреватель модов +mod.featured.dialog.title = Браузер модификаций mods.browser.selected = Выбранный мод -mods.browser.add = Установить мод -mods.github.open = Открыть GitHub страницу +mods.browser.add = Скачать +mods.github.open = Открыть schematic = Схема schematic.add = Сохранить схему… @@ -64,7 +63,7 @@ schematic.saved = Схема сохранена. schematic.delete.confirm = Эта схема будет поджарена Испепелителем. schematic.rename = Переименовать схему schematic.info = {0}x{1}, {2} блоков -schematic.disabled = [scarlet]Схемы отключены[]\nНа этой [accent]карте[] или [accent]сервере запрещено использование схем. +schematic.disabled = [scarlet]Схемы отключены[]\nНа этой [accent]карте[] или [accent]сервере[] запрещено использование схем. stats = Статистика stat.wave = Волн отражено:[accent] {0} @@ -90,6 +89,7 @@ joingame = Сетевая игра customgame = Пользовательская игра newgame = Новая игра none = <ничего> +none.found = [lightgray]<ничего не найдено> minimap = Мини-карта position = Координаты close = Закрыть @@ -113,7 +113,7 @@ feature.unsupported = Ваше устройство не поддерживае mods.alphainfo = Имейте в виду, что модификации находятся в альфа-версии и [scarlet]могут содержать много ошибок[]. Докладывайте о любых проблемах, которые вы найдете в Mindustry Github. mods = Модификации mods.none = [lightgray]Модификации не найдены! -mods.guide = Руководство по модам +mods.guide = Руководство по модификациям mods.report = Доложить об ошибке mods.openfolder = Открыть папку с модификациями mods.reload = Перезагрузить @@ -136,15 +136,15 @@ mod.requiresrestart = Теперь игра закроется, чтобы пр mod.reloadrequired = [scarlet]Необходим перезапуск mod.import = Импортировать модификацию mod.import.file = Импортировать файл -mod.import.github = Импортировать мод с GitHub -mod.jarwarn = [scarlet]JAR-модификации по сути не безопасны.[]\nУбедитесь, что вы импортируете этот мод из надежного источника! +mod.import.github = Импортировать модификацию с GitHub +mod.jarwarn = [scarlet]JAR-модификации по сути не безопасны.[]\nУбедитесь, что вы импортируете эту модификацию из надёжного источника! mod.item.remove = Этот предмет является частью модификации [accent]«{0}[accent]»[white]. Чтобы удалить его, удалите саму модификацию. mod.remove.confirm = Эта модификация будет удалена. mod.author = [lightgray]Автор(ы):[] {0} mod.missing = В этом сохранении есть следы модификации, которая отсутствует или установлена её обновлённая версия. Может произойти повреждение сохранения. Вы уверены, что хотите загрузить его?\n[lightgray]Модификации:\n{0} mod.preview.missing = Перед публикацией этой модификации в Мастерской, вы должны добавить изображение предпросмотра.\nРазместите изображение с именем[accent] preview.png[] в папке модификации и попробуйте снова. mod.folder.missing = Модификации могут быть опубликованы в Мастерской только в виде папки.\nЧтобы конвертировать любой мод в папку, просто извлеките его из архива и удалите старый архив .zip, затем перезапустите игру или перезагрузите модификации. -mod.scripts.disable = Ваше устройство не поддерживает модификации со скриптами. Отключите такие моды, чтобы играть. +mod.scripts.disable = Ваше устройство не поддерживает модификации со скриптами. Отключите такие модификации, чтобы играть. about.button = Об игре name = Имя: @@ -287,6 +287,7 @@ cancel = Отмена openlink = Открыть ссылку copylink = Скопировать ссылку back = Назад +max = Заполнить полностью crash.export = Экспорт отчёта об ошибках crash.none = Отчёты об ошибках не найдены. crash.exported = Отчёты об ошибках экспортированы. @@ -361,12 +362,11 @@ editor.center = Центрировать workshop = Мастерская waves.title = Волны waves.remove = Удалить -waves.never = ∞ waves.every = каждый waves.waves = волна(ы) waves.perspawn = за появление waves.shields = ед. щита/волну -waves.to = к +waves.to = до waves.guardian = Страж waves.preview = Предварительный просмотр waves.edit = Редактировать… @@ -390,7 +390,7 @@ editor.removeunit = Удалить боевую единицу editor.teams = Команды editor.errorload = Ошибка загрузки файла. editor.errorsave = Ошибка сохранения файла. -editor.errorimage = Это изображение, а не карта.\n\nЕсли вы хотите импортировать карту версии 3.5/40 сборки, то используйте кнопку [accent][Импортировать устаревшую карту][] в редакторе. +editor.errorimage = Это изображение, а не карта. editor.errorlegacy = Эта карта слишком старая и использует устаревший формат карты, который больше не поддерживается. editor.errornot = Это не файл карты. editor.errorheader = Этот файл карты недействителен или повреждён. @@ -720,6 +720,7 @@ bar.corereq = Требуется основа ядра bar.drillspeed = Скорость бурения: {0}/с bar.pumpspeed = Скорость выкачивания: {0}/с bar.efficiency = Эффективность: {0}% +bar.boost = Ускорение: {0}% bar.powerbalance = Энергия: {0}/с bar.powerstored = Накоплено: {0}/{1} bar.poweramount = Энергия: {0} @@ -935,6 +936,7 @@ mode.custom = Пользовательские правила rules.infiniteresources = Бесконечные ресурсы (Игрок) rules.reactorexplosions = Взрывы реакторов +rules.coreincinerates = Ядро сжигает избыток ресурсов rules.schematic = Схемы разрешены rules.wavetimer = Интервал волн rules.waves = Волны @@ -1308,7 +1310,7 @@ item.sand.description = Используется в производстве д item.coal.description = Используется как топливо и в производстве обработанных материалов. item.coal.details = Похоже, что это окаменевшее растительное вещество, образовавшееся задолго до Посева. item.titanium.description = Широко используется в транспортировке жидкостей, бурах и авиации. -item.thorium.description = Используется в прочных постройках и как ядерного топлива. +item.thorium.description = Используется в прочных постройках и как ядерное топливо. item.scrap.description = Используется в плавильнях и измельчителях для получения других материалов. item.scrap.details = Остатки старых построек и единиц. item.silicon.description = Используется в солнечных панелях, сложной электронике и самонаводящихся боеприпасах для турелей. diff --git a/fastlane/metadata/steam/russian/achievements.vdf b/fastlane/metadata/steam/russian/achievements.vdf index 628e39b9a5..f7f62840f0 100644 --- a/fastlane/metadata/steam/russian/achievements.vdf +++ b/fastlane/metadata/steam/russian/achievements.vdf @@ -3,14 +3,10 @@ "Language" "russian" "Tokens" { - "NEW_ACHIEVEMENT_20_0_NAME" "Проверен" - "NEW_ACHIEVEMENT_20_0_DESC" "Пройдите обучение." "NEW_ACHIEVEMENT_20_1_NAME" "Утилизатор" "NEW_ACHIEVEMENT_20_1_DESC" "Уничтожьте 1000 вражеских единиц." "NEW_ACHIEVEMENT_20_2_NAME" "Зачистка" "NEW_ACHIEVEMENT_20_2_DESC" "Уничтожьте 100,000 вражеских единиц." - "NEW_ACHIEVEMENT_20_3_NAME" "Воздушная доставка" - "NEW_ACHIEVEMENT_20_3_DESC" "Запустите в целом 10,000 предметов." "NEW_ACHIEVEMENT_20_5_NAME" "Налаженное снабжение" "NEW_ACHIEVEMENT_20_5_DESC" "Запустите 1,000,000 предметов." "NEW_ACHIEVEMENT_20_6_NAME" "Завоеватель" @@ -23,23 +19,19 @@ "NEW_ACHIEVEMENT_20_9_DESC" "Совершите 30 посадок ядра на поверхность." "NEW_ACHIEVEMENT_20_10_NAME" "Упорный" "NEW_ACHIEVEMENT_20_10_DESC" "Выживите 100 волн." - "NEW_ACHIEVEMENT_20_11_NAME" "Непобежденный" - "NEW_ACHIEVEMENT_20_11_DESC" "Выживите 500 волн." "NEW_ACHIEVEMENT_20_12_NAME" "Исследователь" "NEW_ACHIEVEMENT_20_12_DESC" "Исследуйте всё." - "NEW_ACHIEVEMENT_20_13_NAME" "Оборотень" - "NEW_ACHIEVEMENT_20_13_DESC" "Разблокируйте и трансформируйтесь во всех мехов в игре." "NEW_ACHIEVEMENT_20_14_NAME" "Перегрузка" "NEW_ACHIEVEMENT_20_14_DESC" "Поразите покрытого водой врага электричеством." "NEW_ACHIEVEMENT_20_15_NAME" "Отражение" "NEW_ACHIEVEMENT_20_15_DESC" "Уничтожьте единицу при помощи её же отражённого снаряда." - "NEW_ACHIEVEMENT_20_17_NAME" "Гробовая ошибка" + "NEW_ACHIEVEMENT_20_17_NAME" "Серьёзная ошибка" "NEW_ACHIEVEMENT_20_17_DESC" "Исследуйте маршрутизатор." "NEW_ACHIEVEMENT_20_18_NAME" "Создайте" "NEW_ACHIEVEMENT_20_18_DESC" "Разместите 10,000 блоков." "NEW_ACHIEVEMENT_20_19_NAME" "Снесите" "NEW_ACHIEVEMENT_20_19_DESC" "Уничтожьте 1,000 вражеских блоков." - "NEW_ACHIEVEMENT_20_20_NAME" "Неожиданная катастрофа" + "NEW_ACHIEVEMENT_20_20_NAME" "Зрелищная катастрофа" "NEW_ACHIEVEMENT_20_20_DESC" "Допустите взрыв ториевого реактора из-за перегрева." "NEW_ACHIEVEMENT_20_21_NAME" "Картограф" "NEW_ACHIEVEMENT_20_21_DESC" "Создайте 10 новых карт." @@ -51,44 +43,36 @@ "NEW_ACHIEVEMENT_20_24_DESC" "Уничтожьте босса." "NEW_ACHIEVEMENT_20_25_NAME" "Открыватель" "NEW_ACHIEVEMENT_20_25_DESC" "Разблокируйте все зоны в режиме кампании." - "NEW_ACHIEVEMENT_20_26_NAME" "Завершитель" - "NEW_ACHIEVEMENT_20_26_DESC" "Достигните необходимой волны для разблокирования конфигурации во всех зонах." "NEW_ACHIEVEMENT_20_29_NAME" "Материал II" "NEW_ACHIEVEMENT_20_29_DESC" "Разблокируйте торий." "NEW_ACHIEVEMENT_20_31_NAME" "Материал I" "NEW_ACHIEVEMENT_20_31_DESC" "Разблокируйте титан." "NEW_ACHIEVEMENT_21_0_NAME" "Камикадзе" - "NEW_ACHIEVEMENT_21_0_DESC" "Заполните Ваш мех взрывчатым веществом и умрите, создав взрыв." + "NEW_ACHIEVEMENT_21_0_DESC" "Заполните ваш мех взрывчатым веществом и умрите." "NEW_ACHIEVEMENT_21_1_NAME" "Начинается" - "NEW_ACHIEVEMENT_21_1_DESC" "Создайте завод «Кинжалов»." + "NEW_ACHIEVEMENT_21_1_DESC" "Постройте фабрику наземных единиц." "NEW_ACHIEVEMENT_21_2_NAME" "Прямое нападение" "NEW_ACHIEVEMENT_21_2_DESC" "Выберите команду «атака», используя командный центр." "NEW_ACHIEVEMENT_21_3_NAME" "Рой" "NEW_ACHIEVEMENT_21_3_DESC" "Имейте одновременно 100 активных единиц." "NEW_ACHIEVEMENT_21_4_NAME" "Стая" - "NEW_ACHIEVEMENT_21_4_DESC" "Имейте одновременно 10 активных дронов «Фантом»." - "NEW_ACHIEVEMENT_21_5_NAME" "Взрывная армия" - "NEW_ACHIEVEMENT_21_5_DESC" "Имейте одновременно 50 активных ботов «Ползун»." + "NEW_ACHIEVEMENT_21_4_DESC" "Имейте одновременно 10 активных дронов «Поли»." + "NEW_ACHIEVEMENT_21_5_NAME" "Робототехник" + "NEW_ACHIEVEMENT_21_5_DESC" "Постройте все виды единиц." "NEW_ACHIEVEMENT_21_6_NAME" "Легионы" "NEW_ACHIEVEMENT_21_6_DESC" "Постройте в целом 1000 единиц." - "NEW_ACHIEVEMENT_21_7_NAME" "Super" - "NEW_ACHIEVEMENT_21_7_DESC" "Получите ранг «S» в любой зоне." - "NEW_ACHIEVEMENT_21_8_NAME" "Super Super" - "NEW_ACHIEVEMENT_21_8_DESC" "Получите ранг «SS» в любой зоне." "NEW_ACHIEVEMENT_21_9_NAME" "Тебе следовало послушаться" "NEW_ACHIEVEMENT_21_9_DESC" "Умрите в зоне высадки врагов." - "NEW_ACHIEVEMENT_21_10_NAME" "Просто нажми Shift" - "NEW_ACHIEVEMENT_21_10_DESC" "Каким-то образом, утоните." + "NEW_ACHIEVEMENT_21_10_NAME" "Для этого есть морские единицы" + "NEW_ACHIEVEMENT_21_10_DESC" "Утоните." "NEW_ACHIEVEMENT_21_11_NAME" "Собиратель" "NEW_ACHIEVEMENT_21_11_DESC" "Полностью заполните ядро всеми видами ресурсов." "NEW_ACHIEVEMENT_21_12_NAME" "Толпа" "NEW_ACHIEVEMENT_21_12_DESC" "Создайте сервер, на котором будет 10 игроков." "NEW_ACHIEVEMENT_21_13_NAME" "Неуязвимый" - "NEW_ACHIEVEMENT_21_13_DESC" "Постройте Испепелитель и Спектр." + "NEW_ACHIEVEMENT_21_13_DESC" "Постройте Испепелитель, Спектр и Знамение." "NEW_ACHIEVEMENT_21_14_NAME" "Взлет" "NEW_ACHIEVEMENT_21_14_DESC" "Используйте стартовую площадку." - "NEW_ACHIEVEMENT_21_15_NAME" "Самодовольство" - "NEW_ACHIEVEMENT_21_15_DESC" "Дважды пропустите запуск и допустите уничтожение ядра врагом." "NEW_ACHIEVEMENT_21_16_NAME" "Ересь" "NEW_ACHIEVEMENT_21_16_DESC" "Постройте два маршрутизатора рядом друг с другом." "NEW_ACHIEVEMENT_21_17_NAME" "Одинокий страж" @@ -105,5 +89,27 @@ "NEW_ACHIEVEMENT_21_22_DESC" "Запустите ядро в зону с 10,000 или более предметами." "NEW_ACHIEVEMENT_21_23_NAME" "Зажигание" "NEW_ACHIEVEMENT_21_23_DESC" "Запустите импульсный реактор." + "NEW_ACHIEVEMENT_21_24_NAME" "Ускорение" + "NEW_ACHIEVEMENT_21_24_DESC" "Активируйте межпланетный ускоритель." + "NEW_ACHIEVEMENT_21_25_NAME" "Спираль" + "NEW_ACHIEVEMENT_21_25_DESC" "Всё ходит и ходит кругом..." + "NEW_ACHIEVEMENT_21_26_NAME" "Новый уровень" + "NEW_ACHIEVEMENT_21_26_DESC" "Постройте единицу 5 уровня." + "NEW_ACHIEVEMENT_21_27_NAME" "Архитектор" + "NEW_ACHIEVEMENT_21_27_DESC" "Создайте 20 схем." + "NEW_ACHIEVEMENT_21_28_NAME" "Мировое господство" + "NEW_ACHIEVEMENT_21_28_DESC" "Захватите все секторы на Серпуло." + "NEW_ACHIEVEMENT_21_29_NAME" "Авиаперевозка" + "NEW_ACHIEVEMENT_21_29_DESC" "Поднимите единицу 5 уровня на борт Окта." + "NEW_ACHIEVEMENT_21_30_NAME" "Совершенная форма" + "NEW_ACHIEVEMENT_21_30_DESC" "Присоединитесь к ним." + "NEW_ACHIEVEMENT_21_31_NAME" "Производство I" + "NEW_ACHIEVEMENT_21_31_DESC" "Достигните общей скорости производства в 5,000 предметов/мин в кампании." + "NEW_ACHIEVEMENT_26_0_NAME" "Производство II" + "NEW_ACHIEVEMENT_26_0_DESC" "Достигните общей скорости производства в 50,000 предметов/мин в кампании." + "NEW_ACHIEVEMENT_26_1_NAME" "Уверенная победа" + "NEW_ACHIEVEMENT_26_1_DESC" "Захватите сектор во время игры на другом секторе." + "NEW_ACHIEVEMENT_26_2_NAME" "Небольшая империя" + "NEW_ACHIEVEMENT_26_2_DESC" "Контролируйте 10 секторов одновременно." } } diff --git a/fastlane/metadata/steam/russian/description.txt b/fastlane/metadata/steam/russian/description.txt index 6fae321743..e706aaa32a 100644 --- a/fastlane/metadata/steam/russian/description.txt +++ b/fastlane/metadata/steam/russian/description.txt @@ -1,46 +1,51 @@ -Создавайте продуманные цепочки поставок конвейерными лентами для подачи боеприпасов в ваши башни, производите материалы для строительства и защищайте свои сооружения от волн врагов. Играйте с друзьями в платформонезависимые многопользовательские кооперативные матчи или бросайте им вызов в командных PvP-матчах. - [img]{STEAM_APP_IMAGE}/extras/ezgif-4-0e70c282f775.gif[/img] [h2]Игровой процесс[/h2] [list] -[*] Создавайте буры и конвейеры для перемещения ресурсов в ваше ядро. -[*] Используйте производящие блоки для создания передовых материалов. +[*] Создавайте сложные цепочки поставок из конвейеров для подачи боеприпасов в турели и производства материалов для строительства +[*] Используйте производственные блоки для создания разнообразных передовых материалов +[*] Защищайте свои постройки от волн врагов +[*] Играйте со своими друзьями в платформонезависимых многопользовательских кооперативных играх или бросьте им вызов в командных PvP матчах [*] Создавайте дронов для автоматической добычи ресурсов, помощи в строительстве и защиты вашей базы. -[*] Доставляйте жидкости и боритесь с очагами огня. -[*] Ускоряйте производство, дополнительно поставляя охлаждающую жидкость и смазку в ваши защитные и производственные блоки. +[*] Доставляйте жидкости и справляйтесь с постоянными трудностями, такими как пожары или вражеские рейды с воздуха +[*] Производите разнообразные единицы для автоматического управления вашей базой или штурма вражеских баз [/list] -[h2]Кампания[/h2] +[img]{STEAM_APP_IMAGE}/extras/ezgif-1-8679abe089cd.gif[/img] +[h2]Кампания[/h2] + [list] -[*] Продвигайтесь через 12 переигрываемых встроенных зон со случайными точками возрождения -[*] Собирайте и запускайте ресурсы -[*] Исследуйте новые блоки для поддержания прогресса -[*] Настраивайте выгружаемые ресурсы для каждой зоны -[*] Разнообразие целей и задач миссий -[*] Приглашайте друзей для совместного прохождения миссий +[*] Завоюйте планету Серпуло, продвигаясь через более чем 250 процедурно сгенерированных секторов и 16 сделанных вручную карт +[*] Захватывайте территорию и стройте заводы для производства ресурсов, пока вы играете на других секторах +[*] Защищайте ваши секторы от периодических вторжений +[*] Координируйте распределение ресурсов между секторами при помощи пусковых площадок +[*] Исследуйте новые блоки, чтобы поддерживать прогрессию +[*] Приглашайте ваших друзей для совместного прохождения миссий [*] Больше 120 функциональных блоков для освоения -[*] 19 различных типов дронов, мехов и кораблей -[*] Больше 50 достижений для прохождения +[*] 33 различных видов дронов, мехов и кораблей +[*] Больше 50 достижений для выполнения [/list] [h2][h2]Игровые режимы[/h2][/h2] -[*] [b]Выживание[/b]: Стройте турели, чтобы защищаться от врагов в стиле башенной защиты. Продержитесь как можно дольше, при желании запустив своё ядро, чтобы использовать собранные ресурсы для исследований. Подготовьте свою базу для периодических атак воздушными боссами. -[*] [b]Атака[/b]: Стройте заводы боевых единиц, чтобы уничтожить вражеские ядра, одновременно защищая свою базу от волн вражеских единиц. Создайте множество различных вспомогательных и наступательных боевых единиц, которые помогут вам в ваших целях. -[*] [b]PvP[/b]: До 4 различных команд для соревнования с другими игроками на уничтожение ядер друг друга. Создавайте отряды или атакуйте другие базы напрямую своими мехами. -[*] [b]Песочница[/b]: Играйте с бесконечными ресурсами без вражеской угрозы. Используйте специфичные для песочницы блоки-источники предметов и жидкостей для проверки эффективности построек, а также вызывайте волны врагов по запросу. +[list] +[*] [b]Выживание[/b]: Стройте турели, чтобы защищаться от врагов в стиле башенной защиты. Продержитесь как можно дольше, при желании запустив своё ядро, чтобы использовать собранные ресурсы для исследований. Подготовьте свою базу к периодическим атакам воздушных боссов. +[*] [b]Атака[/b]: Стройте фабрики боевых единиц, чтобы уничтожить вражеские ядра, одновременно защищая свою базу от волн вражеских единиц. Создайте множество различных вспомогательных и наступательных боевых единиц, которые помогут вам в ваших целях. При желании, вы можете включить ИИ, который строит оборонительные сооружения как дополнительное испытание. +[*] [b]PvP[/b]: До 4 различных команд для соревнования с другими игроками на уничтожение ядер друг друга. Создавайте боевые единицы или атакуйте другие базы напрямую своими мехами. +[*] [b]Песочница[/b]: Играйте с бесконечными ресурсами без вражеской угрозы. Используйте специфичные для песочницы блоки-источники предметов и жидкостей для проверки дизайнов, а также вызывайте волны врагов по запросу. [/list] +[img]{STEAM_APP_IMAGE}/extras/2020-11-30_10-46-02.gif[/img] + [h2]Пользовательские игры & платформонезависимый мультиплеер[/h2] [list] -[*] 12 встроенных карт для игры, в дополнение к кампании. -[*] Играйте в кооперативном режиме, PvP или песочницу. -[*] Присоединитесь к общедоступному серверу или пригласите друзей в свою игровую сессию. -[*] Настриваемые игровые правила: Изменяйте стоимость блоков, характеристики врагов, стартовые ресурсы, задержки между волнами и другое. +[*] 16 встроенных карт для пользовательских игр в дополнение к кампании +[*] Играйте в кооперативном режиме, PvP или песочнице +[*] Присоединитесь к общедоступному серверу или пригласите друзей в свою приватную сессию +[*] Настриваемые игровые правила: Изменяйте стоимость блоков, характеристики врагов, начальные ресурсы, задержки между волнами и другое [*] Смешанные игровые матчи: Совмещайте PvP и PvE режимы на одной карте. [/list] @@ -48,13 +53,13 @@ [list] [*] Создавайте ландшафт с помощью визуального редактора -[*] Изменяйте и просматривайте постройки так же как в игре +[*] Изменяйте и просматривайте постройки во время игры [*] Настраиваемые режимы инструментов — измените способ работы каждого инструмента -[*] Мощная система генерации карт, с большим количеством различных типов фильтров для процедурных манипуляций над местностью -[*] Применяйте шум, искажение, сглаживание, эрозию, симметрию, рудную генерацию и случайный ландшафт к вашим картам +[*] Мощная система генерации карт с большим количеством различных типов фильтров для процедурных манипуляций над местностью +[*] Применяйте шум, искажение, сглаживание, эрозию, симметрию, генерацию руд и случайный ландшафт к вашим картам [*] Настраивайте случайную генерацию руд, а также размещение рек и ресурсов [*] Настраиваемые шаблоны вражеских волн -[*] Делитесь выложенными картами в Мастерской Steam +[*] Делитесь картами в Мастерской Steam [*] Настраивайте изначальные правила карты -[*] Используйте больше 75 различных блоков окружения +[*] Используйте больше 80 различных блоков окружения [/list] From eb75cd5ae8a3939a965acc8e05d1c31f0934d3a3 Mon Sep 17 00:00:00 2001 From: CPXMC <62936489+CPXMC@users.noreply.github.com> Date: Wed, 20 Jan 2021 04:26:12 +0800 Subject: [PATCH 089/426] Update contributors (#3766) Co-authored-by: Anuken --- core/assets/contributors | 1 + 1 file changed, 1 insertion(+) diff --git a/core/assets/contributors b/core/assets/contributors index 59f40b3ef2..2b55988f2c 100644 --- a/core/assets/contributors +++ b/core/assets/contributors @@ -113,3 +113,4 @@ younggam simba-fs RedRadiation Marko Zajc +CPX MC From c026d44cd3ef28d1f474592d29c7014a32675a37 Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Tue, 19 Jan 2021 22:26:36 +0200 Subject: [PATCH 090/426] [Bundle][RO] Translation update (#4192) * [Bundle][RO] Translation update This PR was tested in-game and is _**ready to merge at any time**_ (unless marked as draft). Changelog: - ~~New strings/changes up to commit~~ TBA - Sector description improvements - Typo fixes & various other improvements * Update bundle_ro.properties * Max * repeated typo typo typo * Welcome to 2020 when maps are no longer images * forget your position in the 20s --- core/assets/bundles/bundle_ro.properties | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index 103b173a72..bacebda5f8 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -288,6 +288,7 @@ cancel = Anulare openlink = Deschide Linkul copylink = Copiază Linkul back = Înapoi +max = Maximum crash.export = Exportă Crash Logs crash.none = Nu s-au găsit crash logs. crash.exported = Crash logs exportate. @@ -362,7 +363,6 @@ editor.center = Centrează workshop = Workshop waves.title = Valuri waves.remove = Elimină -waves.never = waves.every = la fiecare waves.waves = val(uri) waves.perspawn = per apariție @@ -393,7 +393,7 @@ editor.errorload = Eroare la încărcarea fișierului. memory = Mem: {0}mb memory2 = Mem:\n {0}mb +\n {1}mb editor.errorsave = Eroare la salvarea fișierului. -editor.errorimage = Aceasta este o imagine, nu o hartă.\n\nDacă vrei să imporți o hartă din versiunile 3.5/build 40, folosește butonul 'Importă Hartă Veche' din editor. +editor.errorimage = Aceasta este o imagine, nu o hartă. editor.errorlegacy = Hartă aceasta este prea veche, și folosește un format învechit care nu mai este suportat. editor.errornot = Acesta nu este un fișier cu o hartă. editor.errorheader = Acest fișier de hartă este invalid sau corupf. @@ -599,17 +599,17 @@ sector.groundZero.description = Locația optimă pt a începe încă odată. Ris sector.frozenForest.description = Chiar și aici, aproape de munți, sporii s-au împrăștiat. Temperaturile reci nu-i pot reține la infinit.\n\nÎncepe călătoria către electricitate. Construiește generatoare de combustie. Învață să folosești reparatoare. sector.saltFlats.description = La periferia deșertului stau Podișurile Saline. Puține resurse pot fi găsite în această locație.\n\nInamicul a ridicat un complex de depozitare aici. Distruge-le nucleul. Nu lăsa nimic în urmă. sector.craters.description = Apa s-a acumulat în acest crater, rămășiță a vechilor războaie. Cucerește din nou zona. Adună nisip. Toarnă-l în metasticlă. Pompează apă pt a răci armele și burghiele. -sector.ruinousShores.description = După deșerturi vine țărmul. Odată, locația aceasta a avut un sistem de apărare de coastă. N-a rămas mult din el. Doar structurile de apărare cele mai simple au rămas în picioare, restul fiind redus la fier vechi.\nContinuă expansiunea înspre exterior. Redescoperă tehnologia. -sector.stainedMountains.description = Mai spre mijlocul continentului sunt munții, încă neatinși de spori.\nExtrage abundentele resurse de titan din zonă. Învață cum să-l folosești.\n\nPrezența inamicului e mai mare aici. Nu le da timp să-și trimită cele mai puternice unități. +sector.ruinousShores.description = După deșerturi vine țărmul. Odată, locația aceasta avea un sistem de apărare de coastă. N-a rămas mult din el. Doar structurile de apărare cele mai simple au rămas în picioare, restul fiind redus la fier vechi.\nContinuă expansiunea înspre exterior. Redescoperă tehnologia. +sector.stainedMountains.description = Mai spre mijlocul continentului sunt munții, încă neatinși de spori.\nExtrage abundentele resurse de titan din zonă. Învață cum să-l folosești.\n\nPrezența inamicului e mai mare aici. Nu le da timp să trimită cele mai puternice unități. sector.overgrowth.description = Această zonă este plină de buruieni, mai aproape de sursa sporilor.\nInamicul și-a stabilit un avanpost aici. Construiește unități Mace. Distruge-l. -sector.tarFields.description = O zonă aflată la periferia unui complex de producție petrolieră, între munți și deșert. Una din puținele zone cu resurse utilizabile de țiței.\nDeși abandonată, în apropierea zonei se află de forțe inamice periculoase. Nu le subestima.\n\n[lightgray]Cercetează tehnologie de procesare a petrolului pe cât posibil. +sector.tarFields.description = O zonă aflată la periferia unui complex de producție petrolieră, între munți și deșert. Una din puținele zone cu resurse utilizabile de țiței.\nDeși abandonată, în apropierea zonei se află forțe inamice periculoase. Nu le subestima.\n\n[lightgray]Cercetează tehnologia de procesare a petrolului pe cât posibil. sector.desolateRift.description = O zonă extrem de periculoasă. Multe resurse, dar puțin spațiu. Mare risc de distrugere. Pleacă curând, cât mai curând. Nu te lăsa păcălit de pauzele mari dintre atacurile inamice. sector.nuclearComplex.description = O fostă facilitate pt producerea și procesarea de toriu, redusă la ruine.\n[lightgray]Cercetează toriul și multele sale utilizări.\n\nInamicul e prezent aici în mari numere, căutând constant atacatori. sector.fungalPass.description = O zonă de tranziție dintre munții înalți și zonele joase, pline cu spori. O mică bază de recunoaștere a inamicului este localizată aici.\nDistruge-o.\nFolosește unități Dagger și Crawler. Distruge cele 2 nuclee. sector.biomassFacility.description = Originea sporilor. Aceasta este facilitatea în care au fost cercetați și produși inițial.\nCercetează tehnologia ce poate fi găsită aici. Cultivă spori pt producția de combustibil și mase plastice.\n\n[lightgray]Când facilitatea a decăzut, sporii au fost eliberați. Nimic din din ecosistemul local nu a putut concura cu un organism atât de invaziv. sector.windsweptIslands.description = Acest arhipelag izolat se află mai departe, după țărm. Datele arată că odată aveau structuri care produceau [accent]Plastaniu[].\n\nApără-te de unitățile navale ale inamicului. Construiește o bază pe insule. Cercetează fabricile necesare. sector.extractionOutpost.description = Un avanpost izolat, construit de inamic cu scopul de a lansa resurse către alte sectoare.\n\nTehnologia de transport intersectorial este esențială pt cuceririle ce urmează. Distruge baza. Cercetează platformele lor de lansare. -sector.impact0078.description = Aici se află rămășițele primei nave de transport interstelar care a intrat în acest sistem stelar.\n\nSalvează cât mai mult posibil din epavă. Cercetează orice tehnologie intactă. +sector.impact0078.description = Aici se află rămășițele primei nave de transport interstelar care a intrat în acest sistem stelar.\n\nSalvează cât de mult posibil din epavă. Cercetează orice tehnologie intactă. sector.planetaryTerminal.description = Ținta finală.\n\nAceastă bază de coastă conține o structură capabilă să lanseze nuclee către alte planete locale. Este extrem de bine păzită.\n\nProdu unități navale. Elimină inamicul cât de rapid se poate. Cercetează structura de lansare. settings.language = Limbă @@ -721,6 +721,7 @@ bar.corereq = Plasare pe Nucleu Necesară bar.drillspeed = Viteză Minare: {0}/s bar.pumpspeed = Viteză Pompare: {0}/s bar.efficiency = Eficiență: {0}% +bar.boost = Efect Grăbire: {0}% bar.powerbalance = Electricitate: {0}/s bar.powerstored = Stocată: {0}/{1} bar.poweramount = Electricitate: {0} @@ -936,6 +937,7 @@ mode.custom = Reguli Personalizate rules.infiniteresources = Resurse Infinite rules.reactorexplosions = Reactoarele Explodează +rules.coreincinerates = Nucleul Incinerează Resursele în Plus rules.schematic = Se Pot Folosi Scheme rules.wavetimer = Valuri pe Timp rules.waves = Valuri @@ -1456,10 +1458,10 @@ block.command-center.description = Controlează comportamentul unităților mili block.ground-factory.description = Produce unități de artilerie. Unitățile produse pot fi folosite direct sau mutate în reconstructoare pt îmbunătățiri. block.air-factory.description = Produce unități aeriene. Unitățile produse pot fi folosite direct sau mutate în reconstructoare pt îmbunătățiri. block.naval-factory.description = Produce unități navale. Unitățile produse pot fi folosite direct sau mutate în reconstructoare pt îmbunătățiri. -block.additive-reconstructor.description = Îmbunătățește unitățile primite, tranformându-le în unități de nivel doi. -block.multiplicative-reconstructor.description = Îmbunătățește unitățile primite, tranformându-le în unități de nivel trei. -block.exponential-reconstructor.description = Îmbunătățește unitățile primite, tranformându-le în unități de nivel patru. -block.tetrative-reconstructor.description =Îmbunătățește unitățile primite, tranformându-le în unități de ltimă generație: nivelul cinci. +block.additive-reconstructor.description = Îmbunătățește unitățile primite, transformându-le în unități de nivel doi. +block.multiplicative-reconstructor.description = Îmbunătățește unitățile primite, transformându-le în unități de nivel trei. +block.exponential-reconstructor.description = Îmbunătățește unitățile primite, transformându-le în unități de nivel patru. +block.tetrative-reconstructor.description = Îmbunătățește unitățile primite, transformându-le în unități de ltimă generație: nivelul cinci. block.switch.description = Un întrerupător. Poate fi pornit sau oprit. Statusul său poate fi citit și controlat de procesoarele logice. block.micro-processor.description = Rulează într-o buclă continuă o secvență de instrucțiuni logice. Poate fi folosit pt a controla unități și diverse clădiri. block.logic-processor.description = Rulează într-o buclă continuă o secvență de instrucțiuni logice. Poate fi folosit pt a controla unități și diverse clădiri. Mai rapid decât microprocesorul. From b9b8fc66b1cc88f81253b9bc739d4566bd6f33fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Ga=C5=A1par=C3=ADk?= Date: Tue, 19 Jan 2021 21:28:23 +0100 Subject: [PATCH 091/426] Czech translation - ongoing effort (#3841) --- core/assets/bundles/bundle_cs.properties | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_cs.properties b/core/assets/bundles/bundle_cs.properties index 58942b40e3..f727c74fc6 100644 --- a/core/assets/bundles/bundle_cs.properties +++ b/core/assets/bundles/bundle_cs.properties @@ -194,6 +194,7 @@ servers.local = Místní servery servers.remote = Vzdálené servery servers.global = Komunitní servery +servers.disclaimer = Komunitní servery [accent]nejsou[] vlastněny ani kontrolovány vývojářem této hry.\n\nServery mohou obsahovat obsah vytvořený uživateli, který může na některé uživatele působit nepatřičně či nevhodně. servers.showhidden = Zobraz skryté servery server.shown = Zobrazené server.hidden = Skryté @@ -1278,6 +1279,10 @@ hint.payloadDrop.mobile = [accent]Ťupni a drž[] na prázdném místě pro polo hint.waveFire = [accent]Naplň[] věže vodou místo munice pro automatické hašení okolních požárů. hint.generator = \uf879 [accent]Spalovací generátory[] pálí uhlí a přenášení energii do sousedících bloků.\n\nPřenos energie na delší vzdálenost se provádí pomocí \uf87f [accent]Energetických uzlů[]. hint.guardian = Jednotky [accent]Strážce[] jsou obrněné. Měkká munice, jako je například [accent]měď[] a [accent]olovo[] je [scarlet]neefektivní[].\n\nPoužij vylepšené věže nebo \uf835 [accent]grafitovou[] munici pro \uf861 Střílnu Duo/\uf859 Salvu, abys Strážce sejmul. +hint.coreUpgrade = Jádro může být vylepšeno [accent]překrytím jádrem vyšší úrovně[].\n\nUmísti jádro typu [accent]Základ[] přes jádro typu [accent]Odštěpek[]. Ujisti se, že v okolí nejsou žádné překážky. +hint.presetLaunch = Na šedé [accent]sektory v přistávací zóně[], jako je například [accent]Zamrzlý les[], se lze vyslat kdykoli. Nevyžadují polapení okolního teritoria.\n\n[accent]Číslované sektory[], jako je tento, jsou [accent]volitelné[]. +hint.coreIncinerate = Poté, co je kapacita jádra určité položky naplněna, jakékoliv další stejné přijaté položky budou [accent]zničeny[]. +hint.coopCampaign = Když hraješ [accent]kooperativní kampaň[], položky, které jsou vyrobeny v této mapě, budou též zaslány [accent]do Tvých místních sektorů[].\n\nJakýkoliv vývoj dosažený hostitelem se též přenáší. item.copper.description = Používá se ve všech typech bloků a munice. item.copper.details = Měď. Nezvykle nadpočetný kov na Serpulu. Konstrukčně slabý, pokud není rafinovaná. @@ -1471,7 +1476,7 @@ unit.zenith.description = Střílí salvy raket na všechny blízké nepřátele unit.antumbra.description = Střílí palbu střel na všechny blízké nepřátele. unit.eclipse.description = Vystřelí dva pronikavé lasery a záplavu protivzdušných střel na všechny blízké nepřátele. unit.mono.description = Samočinně těží měď a olovo a ukládá je do jádra. -unit.poly.description = Samočinně obnovuje poškozené konstrukce a pomáhá ostatním jednotkám při stavbě. +unit.poly.description = Samočinně obnovuje zničené konstrukce a pomáhá ostatním jednotkám při stavbě. unit.mega.description = Samočinně opravuje poškozené konstrukce. Je schopný přenést bloky a malé pozemní jednotky. unit.quad.description = Pouští velké bomby na pozemní cíle, opravuje spojenecké konstrukce a poškozuje nepřátele. Je schopen přenést středně velké pozemní jednotky. unit.oct.description = Chrání blízké spojence pomocí regeneračního štítu. Je schopen přenést většinu pozemních jednotek. From 52e47a28c4914337455599f878444206e3b76946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=BA=E6=A2=B0=E5=B8=88?= <57534147+jixishi@users.noreply.github.com> Date: Wed, 20 Jan 2021 04:36:27 +0800 Subject: [PATCH 092/426] Update servers_v6.json (#4132) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加两个中国地区服务器,主要为挑战性地图。 Add two China region servers, mainly for challenging maps. --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index a542eba109..173aba03e7 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -15,6 +15,10 @@ "name": "C.A.M.S.", "address": ["routerchain.ddns.net", "pandorum.su:8000"] }, + { + "name": "BE6.RUN", + "address": ["be6.run", "mindustrycn.top"] + }, { "name": "io", "address": ["mindustry.io", "mindustry.io:1000", "mindustry.io:2000", "mindustry.io:3000", "mindustry.io:4000"] From da8ea843972cd92bd0350df60d425fe4cffb815c Mon Sep 17 00:00:00 2001 From: VozDuh <61590217+Voz-Duh@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:42:33 +0300 Subject: [PATCH 093/426] New Unit Select (#3672) * New Unit Select * Fix * Facepalm * Code Fix * Texture Fix --- core/assets-raw/sprites/effects/select-arrow.png | Bin 0 -> 765 bytes core/src/mindustry/graphics/OverlayRenderer.java | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 core/assets-raw/sprites/effects/select-arrow.png diff --git a/core/assets-raw/sprites/effects/select-arrow.png b/core/assets-raw/sprites/effects/select-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..023cf217480a505241a4d88dddf71baae66aa377 GIT binary patch literal 765 zcmeAS@N?(olHy`uVBq!ia0y~yU^ofF9Lx+14ErRWnKLjjFct^7J29*~C-ahlfq^C6 z(btiIVPik{pF~y$1_sUmpAc6D28RFt|1&T!6d!9YWME)mE(!7r{{Nrh`YB#VkeULI z$YKTtzC$3)D5~Mrz`($i=jq}YQW5v|{K-;gLmrmE(?8kYde40`(Sn;%?C&pjhLYOa z|Kge-Jv;rqYJwh37Mefh$C4xJs&+IG+NM(}dvjyU%l$bKhd$l^rk(gh{`S-jzt`XO zno*muStv~Y=IWMy4UU}N?tfHyWG_wMP<$rt&>7(;s%vZx#~wNnd_^_K=6KAZBa@G) z>e!r)K6K#n7S%V_=c5ko;a;M;X7{1ULp!{usOIcG7IA1xcZ;gd?o;81Hk>X|eY5La z*r7GjDXMFB9S%LTB05AhXV>wNLrZ46sOs!G9eilPZ4=cuJI@Cln!~Q5x~B3_;Gr4r zBC0u+#{v#bX=hQ@sm!Y7be4;bJJk0)Y`Q^m(^1tmGZJ$-m6t_C9cr@-n`V$WsZ~{H zMrtf4^RmdWL;oworhcefXTKhu}<{PL)vL+^KnP5Dr@iB+{`-rD^w$1iW4{-J!| zJE41G8F~-1Tki?Yo0g&bFunJjP@Gt%&co!X`-J4CWokc+pSw=zo@kcV!|0{+gyv1n z(tH@cwofQdG+X0g@YY{Ka#OYSANucoC3Me3L+_z?`z@h)TQqbZy7!+FiZjvFdFVWS zmyp~RP3?zu^H&L-Gxs{l@mzXoO3UZoAfrP+-83a1)-0aVQ?M`4%gy4xhN|+M{3(+J fk(A}et(VsmlVV)CWm!D~0|SGntDnm{r-UW|g*#Bd literal 0 HcmV?d00001 diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 2f5ea104c7..2b1dc76ef7 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -16,6 +16,7 @@ import mindustry.world.*; import static mindustry.Vars.*; public class OverlayRenderer{ + private static final TextureRegion arrowRegion = Core.atlas.find("select-arrow"); private static final float indicatorLength = 14f; private static final float spawnerMargin = tilesize*11f; private static final Rect rect = new Rect(); @@ -88,8 +89,12 @@ public class OverlayRenderer{ Draw.rect(select.type.icon(Cicon.full), select.x(), select.y(), select.rotation() - 90); } - Lines.stroke(unitFade); - Lines.square(select.x, select.y, select.hitSize() * 1.5f, Time.time * 2f); + + for(int i = 0; i < 4; i++){ + float rot = i * 90f + 45f + (-Time.time / 3f) % 360f; + float length = select.hitSize() * 1.5f + (unitFade * 2.5f); + Draw.rect(arrowRegion, select.x + Angles.trnsx(rot, length), select.y + Angles.trnsy(rot, length), length / 1.9f, length / 1.9f, rot - 135f); + } Draw.reset(); } From f812460164ce8e3136984850d5f7779321c48ee3 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 19 Jan 2021 15:49:30 -0500 Subject: [PATCH 094/426] New unit select fixes --- .../assets-raw/sprites/effects/select-arrow.png | Bin 765 -> 310 bytes .../src/mindustry/graphics/OverlayRenderer.java | 8 ++++---- core/src/mindustry/input/DesktopInput.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/assets-raw/sprites/effects/select-arrow.png b/core/assets-raw/sprites/effects/select-arrow.png index 023cf217480a505241a4d88dddf71baae66aa377..41c2608d8b95e40b9d7575465466dc9102f96347 100644 GIT binary patch delta 281 zcmey%x{XP%Gr-TCmrII^fq{Y7)59f*fq@|fggKZQ7#Q4bQqve17#NF#+?^QKos)Sv z(N4YojHioZNJit^vnP2EJMb_&X#W+TJ74~zoYGNIf#%BxV&=0=7gqP1V^R3%NGFVO zvU}2wx!#KuJKI#GCS`bl7*D=iOtk4^KKc2Adb9Jq9==i|ny4UU}N?tfHyWG_wMP<$rt&>7(;s%vZx#~wNnd_^_K=6KAZBa@G) z>e!r)K6K#n7S%V_=c5ko;a;M;X7{1ULp!{usOIcG7IA1xcZ;gd?o;81Hk>X|eY5La z*r7GjDXMFB9S%LTB05AhXV>wNLrZ46sOs!G9eilPZ4=cuJI@Cln!~Q5x~B3_;Gr4r zBC0u+#{v#bX=hQ@sm!Y7be4;bJJk0)Y`Q^m(^1tmGZJ$-m6t_C9cr@-n`V$WsZ~{H zMrtf4^RmdWL;oworhcefXTKhu}<{PL)vL+^KnP5Dr@iB+{`-rD^w$1iW4{-J!| zJE41G8F~-1Tki?Yo0g&bFunJjP@Gt%&co!X`-J4CWokc+pSw=zo@kcV!|0{+gyv1n z(tH@cwofQdG+X0g@YY{Ka#OYSANucoC3Me3L+_z?`z@h)TQqbZy7!+FiZjvFdFVWS zmyp~RP3?zu^H&L-Gxs{l@mzXoO3UZoAfrP+-83a1)-0aVQ?M`4%gy4xhN|+M{3(+J fk(A}et(VsmlVV)CWm!D~0|SGntDnm{r-UW|g*#Bd diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 2b1dc76ef7..fc1ff87726 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -16,10 +16,10 @@ import mindustry.world.*; import static mindustry.Vars.*; public class OverlayRenderer{ - private static final TextureRegion arrowRegion = Core.atlas.find("select-arrow"); private static final float indicatorLength = 14f; private static final float spawnerMargin = tilesize*11f; private static final Rect rect = new Rect(); + private float buildFade, unitFade; private Unit lastSelect; @@ -89,12 +89,12 @@ public class OverlayRenderer{ Draw.rect(select.type.icon(Cicon.full), select.x(), select.y(), select.rotation() - 90); } - for(int i = 0; i < 4; i++){ - float rot = i * 90f + 45f + (-Time.time / 3f) % 360f; + float rot = i * 90f + 45f + (-Time.time / 1.5f) % 360f; float length = select.hitSize() * 1.5f + (unitFade * 2.5f); - Draw.rect(arrowRegion, select.x + Angles.trnsx(rot, length), select.y + Angles.trnsy(rot, length), length / 1.9f, length / 1.9f, rot - 135f); + Draw.rect("select-arrow", select.x + Angles.trnsx(rot, length), select.y + Angles.trnsy(rot, length), length / 1.9f, length / 1.9f, rot - 135f); } + Draw.reset(); } diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 06e980f7d3..203108f036 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -374,7 +374,7 @@ public class DesktopInput extends InputHandler{ int cursorY = tileY(Core.input.mouseY()); int rawCursorX = World.toTile(Core.input.mouseWorld().x), rawCursorY = World.toTile(Core.input.mouseWorld().y); - // automatically pause building if the current build queue is empty + //automatically pause building if the current build queue is empty if(Core.settings.getBool("buildautopause") && isBuilding && !player.unit().isBuilding()){ isBuilding = false; buildWasAutoPaused = true; From 27d9718d4f88c24f27fd0e4c417e5b3f24c09288 Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+sharlotte-mobile@users.noreply.github.com> Date: Wed, 20 Jan 2021 06:05:17 +0900 Subject: [PATCH 095/426] update KO bundle + android (#4285) * Update bundle_ko.properties * oops! * changelog update * Update full_description.txt * oh god, i forgot this again again... sorry * Update bundle_ko.properties --- core/assets/bundles/bundle_ko.properties | 50 ++++++++++--------- .../android/ko-KR/changelogs/29798.txt | 6 +++ .../android/ko-KR/full_description.txt | 14 +++--- 3 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 fastlane/metadata/android/ko-KR/changelogs/29798.txt diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 6bba05f072..cb15a9e49c 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -81,7 +81,7 @@ level.highscore = 최고 점수: [accent]{0} level.select = 맵 선택 level.mode = 게임 모드: coreattack = < 코어가 공격을 받고 있습니다! > -nearpoint = [[ [scarlet]즉시 적 소환구역에서 떠나십시오[] ]\n단계가 시작하는 순간 인근 건물들과 유닛들이 전멸됩니다! +nearpoint = [[ [scarlet]즉시 적 소환구역에서 떠나십시오[] ]\n단계가 시작하는 순간 인근 건물들과 유닛들이 전멸합니다! database = 코어 데이터베이스 savegame = 게임 저장 loadgame = 게임 불러오기 @@ -126,7 +126,7 @@ mod.content = 콘텐츠: mod.delete.error = 모드를 삭제할 수 없습니다. 파일이 사용 중일 수 있습니다. mod.requiresversion = [scarlet]필요한 최소 게임 버전: [accent]{0} mod.outdated = [scarlet]V6 버전과 호환되지 않음 (minGameVersion이 105 이하인 모드는 사용할 수 없습니다.) -mod.missingdependencies = [scarlet]누락된 요구 모드: {0} +mod.missingdependencies = [scarlet]누락된 필요 모드: {0} mod.erroredcontent = [scarlet]콘텐츠 오류 mod.errors = 콘텐츠를 불러오는 중에 오류가 발생함. mod.noerrorplay = [scarlet]오류가 있는 모드가 있습니다.[] 영향을 받는 모드를 비활성화하거나 플레이하기 전에 오류를 수정하세요. @@ -137,11 +137,11 @@ mod.reloadrequired = [scarlet]재시작 필요 mod.import = 모드 가져오기 mod.import.file = 파일 가져오기 mod.import.github = Github 에서 모드 가져오기 -mod.jarwarn = [scarlet]JAR 모드는 안전하지 않습니다.[]\n신뢰할 수 있는 소스에서 얻은 모드만을 사용해야 합니다! +mod.jarwarn = [scarlet]JAR 모드는 안전하지 않습니다.[]\n신뢰할 수 있는 모드 개발자에게서 얻은 모드만을 사용해야 합니다! mod.item.remove = 이 자원은[accent] '{0}' 모드의 일부입니다. 이를 제거하려면 해당 모드를 제거하세요. mod.remove.confirm = 이 모드가 삭제될 것입니다. mod.author = [lightgray]제작자:[] {0} -mod.missing = 이 저장 파일에는 최근에 업데이트되었거나 현재 기기에 설치되지 않은 모드가 포함되어 있습니다. 저장 파일이 손상될 수 있습니다. 정말로 불러오시겠습니까?\n[lighthray]모드들:\n{0} +mod.missing = 이 저장 파일에는 최근에 업데이트되었거나 현재 기기에 설치되지 않은 모드가 포함되어 있습니다. 저장 파일이 손상될 수 있습니다. 정말로 불러오시겠습니까?\n[lightgray]모드들:\n{0} mod.preview.missing = 창작마당에 모드를 올리기 전에 미리 보기 이미지를 추가해야 합니다.\n[accent]preview.png[] 라는 이름의 미리 보기 이미지를 모드 폴더에 넣고 다시 시도하세요. mod.folder.missing = 창작마당에는 폴더 형태의 모드만 게시할 수 있습니다.\n모드를 폴더 형태로 바꾸려면 모드 파일을 모드 폴더에 압축을 풀고 이전 모드 파일을 삭제 후, 게임을 재시작하거나 모드를 다시 불러오십시오. mod.scripts.disable = 이 기기는 스크립트가 있는 모드를 지원하지 않습니다. 게임을 플레이하려면 이 모드를 비활성화해야 합니다. @@ -287,6 +287,7 @@ cancel = 취소 openlink = 링크 열기 copylink = 링크 복사 back = 뒤로가기 +max = 최대 crash.export = 오류 로그 내보내기 crash.none = 오류 로그가 발견되지 않았습니다. crash.exported = 오류 로그가 추출되었습니다. @@ -361,7 +362,6 @@ editor.center = 중앙 workshop = 창작마당 waves.title = 단계 waves.remove = 삭제 -waves.never = 여기까지 유닛 생성 waves.every = 매 waves.waves = 단계마다 waves.perspawn = 마리씩 생성됨 @@ -390,7 +390,7 @@ editor.removeunit = 유닛 삭제 editor.teams = 팀 editor.errorload = 파일을 불러오지 못했습니다. editor.errorsave = 파일을 저장하지 못했습니다. -editor.errorimage = 이것은 맵이 아니라 사진입니다.\n\n3.5/build 40 맵을 가져올려면 편집기에서 '예전 맵 가져오기' 버튼을 사용하세요. +editor.errorimage = 이것은 맵이 아니라 사진입니다. editor.errorlegacy = 이 맵은 너무 오래되어 더 이상 지원되지 않는 구형 맵 형식을 사용합니다. editor.errornot = 맵 파일이 아닙니다. editor.errorheader = 이 맵 파일은 유효하지 않거나 손상되었습니다. @@ -720,6 +720,7 @@ bar.corereq = 코어 필요 bar.drillspeed = 드릴 속도: {0}/s bar.pumpspeed = 펌프 속도: {0}/s bar.efficiency = 효율: {0}% +bar.boost = 가속: {0}% bar.powerbalance = 전력: {0}/s bar.powerstored = 저장량: {0}/{1} bar.poweramount = 전력: {0} @@ -871,7 +872,7 @@ keybind.move_x.name = X축 이동 keybind.move_y.name = Y축 이동 keybind.mouse_move.name = 커서를 따라서 이동 keybind.pan.name = 펜 보기 -keybind.boost.name = 부스트 +keybind.boost.name = 비행 keybind.schematic_select.name = 영역 설정 keybind.schematic_menu.name = 설계도 메뉴 keybind.schematic_flip_x.name = 설계도 X축 뒤집기 @@ -935,6 +936,7 @@ mode.custom = 사용자 정의 규칙 rules.infiniteresources = 무한 자원 rules.reactorexplosions = 원자로 폭발 허용 +rules.coreincinerates = 코어 방화 비허용 rules.schematic = 설계도 허용 rules.wavetimer = 시간 제한이 있는 단계 rules.waves = 일반 단계 @@ -961,13 +963,13 @@ rules.title.unit = 유닛 rules.title.experimental = 실험적인 기능 rules.title.environment = 환경 rules.lighting = 조명 -rules.enemyLights = 상대에게 조명 +rules.enemyLights = 상대에게 조명 표시 rules.fire = 방화 rules.explosions = 블록/유닛 폭발 데미지 -rules.ambientlight = 자연 조명 +rules.ambientlight = 자연 조명 표시 rules.weather = 날씨 rules.weather.frequency = 빈도: -rules.weather.always = 항상 +rules.weather.always = 항상 rules.weather.duration = 지속 시간: content.item.name = 자원 @@ -1154,7 +1156,7 @@ block.coal-centrifuge.name = 석탄 정제기 block.power-node.name = 전력 노드 block.power-node-large.name = 대형 전력 노드 block.surge-tower.name = 설금 타워 -block.diode.name = 전력 비교기 +block.diode.name = 다이오드 block.battery.name = 배터리 block.battery-large.name = 대형 배터리 block.combustion-generator.name = 화력 발전기 @@ -1263,17 +1265,17 @@ hint.desktopMove = [accent][[WASD][] 키를 이용해 자신의 유닛을 조종 hint.zoom = [accent]마우스 스크롤[]를 사용해 확대 또는 축소가 가능합니다. hint.mine = \uf8c4 주변의 구리광석을 수동으로 채굴하려면 광석을 [accent]누르십시오[]. (추가설명)마우스가 있을 경우 마우스 오른쪽 클릭을 하면 채굴 중단이 가능합니다. hint.desktopShoot = [accent][[마우스 왼클릭][]으로 발사할수 있습니다. -hint.depositItems = 아이템을 코어로 옮기려면, 당신의 기체의 아이템을 코어로 끌어놓으세요. +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 = 컨베이어는 아이템을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n클릭하거나 드래그로 다수의 컨베이어를 설치할 수 있습니다.\n클릭하고 놓지 않은채로 마우스 [accent]휠을 돌리면 돌아갑니다. -hint.placeConveyor.mobile = 컨베이어는 아이템을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n여러개의 컨베이어를 놓으려면 손가락으로 누른채로 끌어서 설치 범위를 지정하십시오. +hint.placeConveyor = 컨베이어는 자원을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n클릭하거나 드래그로 다수의 컨베이어를 설치할 수 있습니다.\n클릭하고 놓지 않은채로 마우스 [accent]휠을 돌리면 돌아갑니다. +hint.placeConveyor.mobile = 컨베이어는 자원을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n여러개의 컨베이어를 놓으려면 손가락으로 누른채로 끌어서 설치 범위를 지정하십시오. hint.placeTurret = 적에게서 당신의 기지를 막아내려면 \uf861 [accent]포탑[]를 설치하십시오.\n\n포탑 탄약 필요 - 지금은 \uf838 구리가 필요합니다.\n컨베이어를 사용해 드릴에 구리를 공급하십시오. hint.breaking = 블록을 부수려면 [accent]오른클릭[]이나 드래그를 하십시오. -hint.breaking.mobile = 블럭을 부수려면 오른쪽 아래의 \ue817 [accent]망치[]를 눌러 해체 모드를 활성화 하십시오.\n\n손가락으로 누른채로 끌어서 해체 범위를 지정하십시오. +hint.breaking.mobile = 블록을 부수려면 오른쪽 아래의 \ue817 [accent]망치[]를 눌러 해체 모드를 활성화 하십시오.\n\n손가락으로 누른채로 끌어서 해체 범위를 지정하십시오. hint.research = 새 기술을 연구하려면 \ue875 [accent]연구[]버튼을 누르십시오. hint.research.mobile = 새 기술을 연구하려면 \ue88c [accent]메뉴[] 아래의 \ue875 [accent]연구[]버튼을 누르십시오. hint.unitControl = 아군 유닛과 포탑을 조종하려면 [accent][[왼쪽 ctrl][]을 누른채로 [accent]클릭[] 하십시오. @@ -1286,8 +1288,8 @@ hint.conveyorPathfind.mobile = \ue844 [accent]diagonal mode[]를 활성화하고 hint.boost = 당신의 유닛과 같이 장애물을 넘어가려면 [accent][[L-Shift][]을 누르고 이동하십시오. \n\n 적은 수의 지상 유닛만 날 수 있습니다. hint.command = 주변의 아군 유닛을 데리고 다니려면 비슷한 단계의 유닛 무리 주변에서 [accent][[G][]를 누르십시오. \n\n 지상 유닛을 데리고 다니기 위해서는 먼저 다른 지상 유닛을 조종하고 있어야 합니다. hint.command.mobile = 아군 유닛을 데리고 다니려면 비슷한 단계의 유닛 무리 주변에서 [accent]빠르게 두번 누르십시오[]. -hint.payloadPickup = 작은 블럭이나 유닛을 집으려면 [accent][[[]를 누르십시오. -hint.payloadPickup.mobile = 작은 블럭이나 유닛을 집으려면 [accent]잠깐 누르십시오[]. +hint.payloadPickup = 작은 블록이나 유닛을 집으려면 [accent][[[]를 누르십시오. +hint.payloadPickup.mobile = 작은 블록이나 유닛을 집으려면 [accent]잠깐 누르십시오[]. hint.payloadDrop = 다시 내려놓으려면 [accent]][]를 누르십시오. hint.payloadDrop.mobile = 다시 내려놓으려면 빈 공간에서 [accent]화면을 잠깐 누르십시오[]. hint.waveFire = [accent]Wave[]포탑에 탄약으로 물을 넣으면 주변의 불을 자동으로 꺼줍니다. @@ -1295,11 +1297,11 @@ hint.generator = \uf879 [accent]화력 발전기[]는 석탄을 태워서 주변 hint.guardian = [accent]수호자[] 유닛들은 방어력을 가집니다. [accent]구리[]와 [accent]납[]같은 약한 탄약으로는 [scarlet]아무런 효과도 없습니다[].\n\n그런 수호자를 없애려면 높은 단계의 포탑 또는 \uf835 [accent]흑연[]을 탄약으로 넣은 \uf861듀오/\uf859살보를 사용하십시오. hint.coreUpgrade = 코어는 [accent]상위 코어를 위에 설치함[]으로써 업그레이드할 수 있습니다.\n\n [accent]기반[] 코어를  [accent]조각[] 코어 위에 설치하십시오. 주변에 장애물이 없는지도 확인하십시오. hint.presetLaunch = [accent]얼어붙은 숲[]과 같은 회색[accent]캠페인 지역[]은 어디에서나 출격해서 올 수 있습니다. 주변 지역을 점령하지 않아도 됩니다.\n\n이와 같은 [accent]네임드 지역[]들은 [accent]선택적[]입니다. -hint.coreIncinerate = 코어가 아이템으로 가득 찬 후에 받는 모든 아이템들은 [accent]소각[]될 것입니다. -hint.coopCampaign = [accent]협동 캠페인[]을 할 떄, 현재 맵에서 생산된 아이템들은 [accent]당신의 캠페인 지역으로[]도 보내집니다.\n\n호스트가 새로 해금한 모든 것들도 가져갑니다. +hint.coreIncinerate = 코어가 자원으로 가득 찬 후에 받는 모든 자원들은 [accent]소각[]될 것입니다. +hint.coopCampaign = [accent]협동 캠페인[]을 할 떄, 현재 맵에서 생산된 자원들은 [accent]당신의 캠페인 지역으로[]도 보내집니다.\n\n호스트가 새로 해금한 모든 것들도 가져갑니다. item.copper.description = 가장 기본적인 건설 재료. 모든 유형의 블록에서 광범위하게 사용됩니다. -item.copper.details = 평범한 구리. 세르플로에 비정상적으로 많이 분포되어 있습니다. 별다른 보강재 없이는 구조적 문제 때문에 내구성이 비교적 약합니다. +item.copper.details = 평범한 구리. 세르플로에 비정상적으로 많이 분포합니다. 별다른 보강재 없이는 구조적 문제 때문에 내구성이 비교적 약합니다. item.lead.description = 기본 초반 재료. 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. item.lead.details = 밀도가 높으며 반응성이 적은 자원. 배터리에 주로 사용됩니다. item.metaglass.description = 초강력 방탄유리. 액체 분배 및 저장에 광범위하게 사용됩니다. @@ -1325,8 +1327,8 @@ liquid.slag.description = 다양한 종류의 금속들이 함께 섞여 녹아 liquid.oil.description = 고급 재료 생산에 사용되는 액체. 석탄으로 전환하거나 무기로 뿌려서 불을 지를 수 있습니다. liquid.cryofluid.description = 물과 티타늄으로 만든 비 부식성 액체. 열 용량이 매우 높으며 냉각수로 광범위하게 사용됩니다. -block.resupply-point.description = 주변 유닛들에게 구리 탄약을 보급합니다. 베터리 전력이 필요한 유닛들은 호환되지 않습니다. -block.armored-conveyor.description = 앞으로 아이템들을 운반합니다. 측면에서 아이템들을 받아들이지 않습니다. +block.resupply-point.description = 주변 유닛들에게 구리 탄약을 보급합니다. 배터리 전력이 필요한 유닛들은 호환되지 않습니다. +block.armored-conveyor.description = 앞으로 자원들을 운반합니다. 측면에서 자원들을 받아들이지 않습니다. block.illuminator.description = 발광합니다. block.message.description = 아군 간의 소통을 위한 메시지를 저장합니다. block.graphite-press.description = 석탄을 흑연으로 압축합니다. @@ -1409,7 +1411,7 @@ block.rtg-generator.description = 간단하고 안정적인 발전기. 붕괴하 block.solar-panel.description = 태양으로부터 소량의 전력을 생성합니다. block.solar-panel-large.description = 표준 태양 전지판보다 훨씬 더 효율적인 버전. block.thorium-reactor.description = 토륨으로부터 상당한 양의 전력을 생산합니다. 지속적인 냉각이 필요하며, 충분한 양의 냉각수가 공급되지 않으면 크게 폭발합니다. 전력 출력은 토륨의 양에 따라 달라집니다. -block.impact-reactor.description = 최고 효율로 대량의 전력을 생산할 수 있는 고급 발전기. 프로세스를 시작하려면 상당한 전력 공급이 필요합니다. +block.impact-reactor.description = 최고 효율로 대량의 전력을 생산할 수 있는 고급 발전기. 가동을 시작하려면 상당한 전력 공급이 필요합니다. block.mechanical-drill.description = 가격이 싼 드릴. 적절한 타일에 설치하면 자원을 천천히 느린 속도로 출력합니다. 기본 자원만 채굴할 수 있습니다. block.pneumatic-drill.description = 티타늄을 캘 수 있는 향상된 드릴. 기계식 드릴보다 더 빠른 속도로 채굴합니다. block.laser-drill.description = 레이저 기술을 통해 더욱 빠르게 채광할 수 있지만, 전력이 필요합니다. 토륨 채굴 가능. @@ -1444,7 +1446,7 @@ block.spectre.description = 공중 및 지상 목표물에게 큰 관통 철갑 block.meltdown.description = 주변 적에게 지속적인 레이저 빔을 충전하여 발사합니다. 냉각 액체가 있어야 작동합니다. block.foreshadow.description = 장거리에 걸친 거대한 단일 목표 저격탄을 발사합니다. block.repair-point.description = 인근에 가장 가까운 유닛을 지속적으로 치료합니다. -block.segment.description = 날아오는 발사체를 요격합니다. 큰 발사체에겐 조준되지 않습니다. +block.segment.description = 날아오는 발사체를 요격합니다. 큰 발사체에겐 조준하지 않습니다. block.parallax.description = 공중 목표물을 끌어오는 견인 광선을 발사하며, 견인 과정에서 데미지를 줍니다. block.tsunami.description = 적에게 강력한 액체 줄기를 발사합니다. 물이 공급되면 자동으로 주변의 화재를 진압합니다. block.silicon-crucible.description = 추가적으로 파이라타이트를 사용하여 더 높은 온도에서 석탄과 모래를 제련합니다. 뜨거운 곳에서 더 효율적입니다. diff --git a/fastlane/metadata/android/ko-KR/changelogs/29798.txt b/fastlane/metadata/android/ko-KR/changelogs/29798.txt new file mode 100644 index 0000000000..f7a3f9e5ef --- /dev/null +++ b/fastlane/metadata/android/ko-KR/changelogs/29798.txt @@ -0,0 +1,6 @@ +[대부분의 변경점이 생략되었습니다. 모든 변경점을 볼려면 Github를 보십시오.] +- 다양한 마이너 버그들 고침 +- 전력 공급기의 출력을 또다시 증가 +- 건설 광선 비주얼 향상 +- 인접한 전력 노드나 배터리로 맵의 성능 향상 +- 에디터에서 날씨 비활성화 \ No newline at end of file diff --git a/fastlane/metadata/android/ko-KR/full_description.txt b/fastlane/metadata/android/ko-KR/full_description.txt index dee45ee1dd..eed0e57123 100644 --- a/fastlane/metadata/android/ko-KR/full_description.txt +++ b/fastlane/metadata/android/ko-KR/full_description.txt @@ -1,13 +1,13 @@ -정교한 컨베이어 벨트 공급망을 만들어 포탑에 탄약을 공급하고 건물에 사용할 재료를 생산하여 적의 공격으로부터 기지를 방어하십시오. 크로스 플렛폼 멀티플레이어에서 친구와 함께 협동 대형 혹은 어려운 맵에서 협동전을 하거나, 팀 pvp를 통해 실력을 자랑해 보세요. +정교한 컨베이어 벨트 공급망을 만들어 포탑에 탄약을 공급하고 건물에 사용할 재료를 생산하여 적의 공격으로부터 기지를 방어하십시오. 크로스 플렛폼 멀티플레이어에서 친구와 함께 협동 대형 혹은 어려운 맵에서 협동전을 하거나, 팀 pvp를 통해 실력을 자랑해보세요. 포함된 특징들 : -- 16개의 기본 맵들 +- 24개의 기본 내장 맵들 - 해금 가능 지역과 테크 트리로 구성된 캠페인 -- 당신을 파괴하기 위한 강력한 보스 -- 전력, 액체, 자원 수송 시스템 -- 33가지의 각기 다른 드론, 유닛, 배들 -- 120종류가 넘는 블럭들 -- 80가지가 넘는 환경 타일 및 블럭들 +- 당신을 파괴하기 위한 4개의 강력한 단계 보스 +- 전력, 액체 그리고 자원 수송 시스템 +- 19가지의 각기 다른 드론, 유닛, 배! +- 120가지가 넘는 테크놀로지 블록들 +- 75가지가 넘는 환경 블록들 - 로컬 네트워크 또는 전용 서버를 통한 크로스 플랫폼 멀티플레이어 - 사용자 정의 게임 규칙 : 블록 가격, 적 스텟 변경, 시작 자원, 단계 대기시간 그 이상을 변경해보세요. - 맵에 광물, 지형, 장식을 랜덤으로 생성하고, 대칭을 추가해보세요. From 32d1d7264c43d1e6fce9c4d7c94774b14d421a66 Mon Sep 17 00:00:00 2001 From: Vajda Simon <75036456+VajdaSimon@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:08:22 +0100 Subject: [PATCH 096/426] bundle_hu.properties (#4181) Okay, so a lot of little ones go big. --- core/assets/bundles/bundle_hu.properties | 112 +++++++++++------------ 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/core/assets/bundles/bundle_hu.properties b/core/assets/bundles/bundle_hu.properties index 200f3e1530..57d4ad79e8 100644 --- a/core/assets/bundles/bundle_hu.properties +++ b/core/assets/bundles/bundle_hu.properties @@ -87,7 +87,7 @@ database = Mag adatbázis savegame = Játék mentése loadgame = Játék betöltése joingame = Csatlakozás játékhoz -customgame = Custom Game +customgame = Egyedi játék newgame = Új játék none = minimap = Minimap @@ -307,8 +307,8 @@ selectschematic = Használd a(z) [accent][[{0}][] gombot, hogy kijelölj és má pausebuilding = Használd a(z) [accent][[{0}][] gombot, hogy megállítsd az építkezést. resumebuilding = Használd a(z) [scarlet][[{0}][] gombot, hogy folytasd az építkezést. showui = A kezelőfelület elrejtve.\nNyomja meg a(z) [accent][[{0}][] gombot a megjelenítéséhez. -wave = [accent]Hullám {0} -wave.cap = [accent]Hullám {0}/{1} +wave = [accent]{0}. Hullám +wave.cap = [accent]{0}/{1}. Hullám wave.waiting = [lightgray]Következő hullám {0} wave.waveInProgress = [lightgray]Hullám folyamatban waiting = [lightgray]Várakozás... @@ -782,7 +782,7 @@ category.items = Items category.crafting = Input/Output category.function = Function category.optional = Optional Enhancements -setting.landscape.name = Lock Landscape +setting.landscape.name = Fekvő mód zárolása setting.shadows.name = Árnyékok setting.blockreplace.name = Automatikus blokk javaslatok setting.linear.name = Lineáris szűrés @@ -793,17 +793,17 @@ setting.buildautopause.name = Automatikus szünet építéskor setting.animatedwater.name = Animált víz setting.animatedshields.name = Animált pajzsok setting.antialias.name = Antialias[lightgray] (újra kell indítani)[] -setting.playerindicators.name = Player Indicators -setting.indicators.name = Enemy Indicators -setting.autotarget.name = Auto-Target -setting.keyboard.name = Mouse+Keyboard Controls -setting.touchscreen.name = Touchscreen Controls +setting.playerindicators.name = Játékos mutató +setting.indicators.name = Ellenség mutató +setting.autotarget.name = Automatikus lövés +setting.keyboard.name = Irányítás egérrel és billentyűzettel +setting.touchscreen.name = Irányítás érintőképernyővel setting.fpscap.name = Max FPS -setting.fpscap.none = None +setting.fpscap.none = Nincs setting.fpscap.text = {0} FPS setting.uiscale.name = UI Scaling[lightgray] (restart required)[] setting.swapdiagonal.name = Always Diagonal Placement -setting.difficulty.training = Training +setting.difficulty.training = Kiképzés setting.difficulty.easy = Könnyű setting.difficulty.normal = közepes setting.difficulty.hard = Nehéz @@ -812,42 +812,42 @@ setting.difficulty.name = Nehézség: setting.screenshake.name = Screen Shake setting.effects.name = Display Effects setting.destroyedblocks.name = Display Destroyed Blocks -setting.blockstatus.name = Display Block Status +setting.blockstatus.name = Blokk állapotának megjelenítése setting.conveyorpathfinding.name = Conveyor Placement Pathfinding setting.sensitivity.name = Controller Sensitivity setting.saveinterval.name = Save Interval -setting.seconds = {0} seconds -setting.milliseconds = {0} milliseconds -setting.fullscreen.name = Fullscreen -setting.borderlesswindow.name = Borderless Window[lightgray] (restart may be required) -setting.fps.name = Show FPS & Ping -setting.smoothcamera.name = Smooth Camera +setting.seconds = {0} másodperc +setting.milliseconds = {0} ezredmásodperc +setting.fullscreen.name = Teljesképernyő +setting.borderlesswindow.name = Keret nélküli ablak[lightgray] (újraindításra lehet szükség) +setting.fps.name = FPS és Ping mutatása +setting.smoothcamera.name = Sima kamera setting.vsync.name = VSync -setting.pixelate.name = Pixelate -setting.minimap.name = Show Minimap -setting.coreitems.name = Display Core Items -setting.position.name = Show Player Position -setting.musicvol.name = Music Volume -setting.atmosphere.name = Show Planet Atmosphere -setting.ambientvol.name = Ambient Volume -setting.mutemusic.name = Mute Music -setting.sfxvol.name = SFX Volume -setting.mutesound.name = Mute Sound +setting.pixelate.name = Pixeles +setting.minimap.name = Minimap +setting.coreitems.name = Az alapvető elemek megjelenítése +setting.position.name = A játékos pozíciójának megjelenítése +setting.musicvol.name = Zene hangerő +setting.atmosphere.name = Bolygó atmoszféra +setting.ambientvol.name = Környezeti hangerő +setting.mutemusic.name = Néma zene +setting.sfxvol.name = SFX hangerő +setting.mutesound.name = Néma hang setting.crashreport.name = Send Anonymous Crash Reports -setting.savecreate.name = Auto-Create Saves +setting.savecreate.name = Automatikus mentés setting.publichost.name = Public Game Visibility -setting.playerlimit.name = Player Limit -setting.chatopacity.name = Chat Opacity +setting.playerlimit.name = Játékos limit +setting.chatopacity.name = Chat átlátszatlanság setting.lasersopacity.name = Power Laser Opacity -setting.bridgeopacity.name = Bridge Opacity -setting.playerchat.name = Display Player Bubble Chat -setting.showweather.name = Show Weather Graphics +setting.bridgeopacity.name = Híd átlátszatlanság +setting.playerchat.name = A játékos buborékos csevegésének megjelenítése +setting.showweather.name = Időjárás grafika megjelenítése public.confirm = Do you want to make your game public?\n[accent]Anyone will be able to join your games.\n[lightgray]This can be changed later in Settings->Game->Public Game Visibility. public.confirm.really = If you want to play with friends, use [green]Invite Friend[] instead of a [scarlet]Public server[]!\nAre you sure you want to make your game [scarlet]public[]? public.beta = Note that beta versions of the game cannot make public lobbies. uiscale.reset = UI scale has been changed.\nPress "OK" to confirm this scale.\n[scarlet]Reverting and exiting in[accent] {0}[] seconds... -uiscale.cancel = Cancel & Exit -setting.bloom.name = Bloom +uiscale.cancel = Mégse és Kilépés +setting.bloom.name = Virágzás keybind.title = Rebind Keys keybinds.mobile = [scarlet]Most keybinds here are not functional on mobile. Only basic movement is supported. category.general.name = General @@ -967,14 +967,14 @@ rules.explosions = Block/Unit Explosion Damage rules.ambientlight = Ambient Light rules.weather = Weather rules.weather.frequency = Frequency: -rules.weather.always = Always +rules.weather.always = Mindig rules.weather.duration = Duration: -content.item.name = Items -content.liquid.name = Liquids -content.unit.name = Units -content.block.name = Blocks -content.sector.name = Sectors +content.item.name = Itemek +content.liquid.name = Folyadékok +content.unit.name = Egységek +content.block.name = Blokkok +content.sector.name = Szektor item.copper.name = Copper item.lead.name = Lead @@ -1250,21 +1250,21 @@ block.large-logic-display.name = Large Logic Display block.memory-cell.name = Memory Cell block.memory-bank.name = Memory Bank -team.blue.name = blue -team.crux.name = red -team.sharded.name = orange -team.orange.name = orange -team.derelict.name = derelict -team.green.name = green -team.purple.name = purple +team.blue.name = kék +team.crux.name = piros +team.sharded.name = narancssárga +team.orange.name = narancssárga +team.derelict.name = elhagyott +team.green.name = zöld +team.purple.name = lila -hint.skip = Skip -hint.desktopMove = Use [accent][[WASD][] to move. -hint.zoom = [accent]Scroll[] to zoom in or out. -hint.mine = Move near the \uf8c4 copper ore and [accent]tap[] it to mine manually. -hint.desktopShoot = [accent][[Left-click][] to shoot. -hint.depositItems = To transfer items, drag from your ship to the core. -hint.respawn = To respawn as a ship, press [accent][[V][]. +hint.skip = Átugrás +hint.desktopMove = Használd a [accent][[WASD][] gombokat a mozgáshoz. +hint.zoom = Használd a [accent]görgőt[] a zoomhoz.. +hint.mine = Mozogjon a \uf8c4 copper közelében, és [accent]érintse meg[] a kézi bányászathoz. +hint.desktopShoot = Használja a [accent]bal egér gombot[] a lövéshez. +hint.depositItems = Az átviteléhez húzzaaz itemeket a hajóról a magra. +hint.respawn = Ha újból hajóvá akar válni, nyomja meg a [accent][[V][] gombot. hint.respawn.mobile = You have switched control to a unit/structure. To respawn as a ship, [accent]tap the avatar in the top left.[] hint.desktopPause = Press [accent][[Space][] to pause and unpause the game. hint.placeDrill = Select the \ue85e [accent]Drill[] tab in the menu at the bottom right, then select a \uf870 [accent]Drill[] and click on a copper patch to place it. From e3ccde31d81771b800c3896a8c02ee00c4757f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Wed, 20 Jan 2021 06:21:41 +0800 Subject: [PATCH 097/426] removed "never", minor updates (#4363) --- core/assets/bundles/bundle_zh_TW.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 780df32819..f3b19078cb 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -362,7 +362,6 @@ editor.center = 中心 workshop = 工作坊 waves.title = 波次 waves.remove = 移除 -waves.never = 〈永遠〉 waves.every = 每 waves.waves = 波次 waves.perspawn = 每次生成 @@ -391,7 +390,7 @@ editor.removeunit = 移除單位 editor.teams = 隊伍 editor.errorload = 載入檔案時發生問題。 editor.errorsave = 儲存檔案時發生問題。 -editor.errorimage = 這是圖片檔,而非地圖。不要試圖修改副檔名讓它可以使用。\n\n如果要匯入地形圖片檔,請使用編輯器中的「匯入地形圖片檔」按鈕。 +editor.errorimage = 這是圖片檔,而非地圖。 editor.errorlegacy = 此地圖太舊,並使用不支援的舊地圖格式。 editor.errornot = 這不是地圖檔。 editor.errorheader = 此地圖檔無效或已損毀。 From b86201ea9b37dd27245c7aa0f6fe852664bd36aa Mon Sep 17 00:00:00 2001 From: Esculap <77432194+EsculapWasTaken@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:23:44 +0100 Subject: [PATCH 098/426] Update bundle_pl.properties (#4326) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translated some tiles (not translated yet): Dacite => Dacyt Dacite Wall => Dacytowa Ściana Dacite Boulder => Dacytowy Głaz Stone Wall => Kamienna Ściana Ice Wall => Lodowa Ściana Snow Wall => Śnieżna Ściana Dune Wall => Wydmowa Ściana Dirt => Ziemia Dirt Wall => Ziemna Ściana Mud => Błoto Basalt => Bazalt --- core/assets/bundles/bundle_pl.properties | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index aa26f651db..276cdb89ea 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -1078,18 +1078,18 @@ block.craters.name = Kratery block.sand-water.name = Woda z Piaskiem block.darksand-water.name = Woda z Ciemnym Piaskiem block.char.name = Popiół -block.dacite.name = Dacite -block.dacite-wall.name = Dacite Wall -block.dacite-boulder.name = Dacite Boulder +block.dacite.name = Dacyt +block.dacite-wall.name = Dacytowa Ściana +block.dacite-boulder.name = Dacytowy Głaz block.ice-snow.name = Lodowy Śnieg -block.stone-wall.name = Stone Wall -block.ice-wall.name = Ice Wall -block.snow-wall.name = Snow Wall -block.dune-wall.name = Dune Wall +block.stone-wall.name = Kamienna Ściana +block.ice-wall.name = Lodowa Ściana +block.snow-wall.name = Śnieżna Ściana +block.dune-wall.name = Wydmowa Ściana block.pine.name = Sosna -block.dirt.name = Dirt -block.dirt-wall.name = Dirt Wall -block.mud.name = Mud +block.dirt.name = Ziemia +block.dirt-wall.name = Ziemna Ściana +block.mud.name = Błoto block.white-tree-dead.name = Białe Martwe Drzewo block.white-tree.name = Białe Drzewo block.spore-cluster.name = Skupisko Zarodników @@ -1105,7 +1105,7 @@ block.dark-panel-4.name = Ciemny Panel 4 block.dark-panel-5.name = Ciemny Panel 5 block.dark-panel-6.name = Ciemny Panel 6 block.dark-metal.name = Ciemny Metal -block.basalt.name = Basalt +block.basalt.name = Bazalt block.hotrock.name = Gorący Kamień block.magmarock.name = Skała magmowa block.copper-wall.name = Miedziana Ściana From 775ebd6e942b5d22102e92e1669b58a67b6ba8f8 Mon Sep 17 00:00:00 2001 From: Thomas Widyantoko <40286070+DaGamerFiles@users.noreply.github.com> Date: Wed, 20 Jan 2021 05:24:03 +0700 Subject: [PATCH 099/426] more in_ID translation (#4286) * more in_ID translation fixes, addition, etc * changes to in_ID translated rules.coreincinerates and removed waves.never to match up with the original bundle file --- core/assets/bundles/bundle_in_ID.properties | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties index 7c82ca930e..60eca12c70 100644 --- a/core/assets/bundles/bundle_in_ID.properties +++ b/core/assets/bundles/bundle_in_ID.properties @@ -287,9 +287,10 @@ cancel = Batal openlink = Buka Tautan copylink = Salin Tautan back = Kembali -crash.export = Export Crash Logs -crash.none = No crash logs found. -crash.exported = Crash logs exported. +max = Maks +crash.export = Ekspor Crash Log +crash.none = Tidak ada crash log ditemukan. +crash.exported = Crash log diekspor. data.export = Ekspor Data data.import = Impor Data data.openfolder = Buka Folder Data @@ -361,7 +362,6 @@ editor.center = Pusat workshop = Workshop waves.title = Gelombang waves.remove = Hapus -waves.never = waves.every = setiap waves.waves = gelombang waves.perspawn = per muncul @@ -720,6 +720,7 @@ bar.corereq = Memerlukan Inti Dasar bar.drillspeed = Kecepatan Bor: {0}/s bar.pumpspeed = Kecepatan Pompa: {0}/s bar.efficiency = Daya Guna: {0}% +bar.boost = Percepatan: {0}% bar.powerbalance = Tenaga: {0}/s bar.powerstored = Disimpan: {0}/{1} bar.poweramount = Tenaga: {0} @@ -918,6 +919,7 @@ keybind.toggle_menus.name = Muncul Tidaknya Menu keybind.chat_history_prev.name = Sejarah Pesan Sebelumnya keybind.chat_history_next.name = Sejarah Pesan Setelahnya keybind.chat_scroll.name = Scroll Pesan +keybind.chat_mode.name = Ubah Mode Pesan keybind.drop_unit.name = Jatuhkan Unit keybind.zoom_minimap.name = Perbesar Peta Kecil mode.help.title = Deskripsi mode @@ -925,7 +927,7 @@ mode.survival.name = Bertahan Hidup mode.survival.description = Mode normal. Sumber daya terbatas dan gelombang otomatis. mode.sandbox.name = Mode Sandbox/Bebas mode.sandbox.description = Sumber daya tak terbatas dan tidak ada gelombang otomatis. -mode.editor.name = Sunting +mode.editor.name = Penyunting mode.pvp.name = PvP mode.pvp.description = Melawan pemain lain. Membutuhkan setidaknya 2 inti berbeda warna didalam peta untuk main. mode.attack.name = Penyerangan @@ -934,6 +936,7 @@ mode.custom = Pengaturan Modifikasi rules.infiniteresources = Sumber Daya Tak Terbatas rules.reactorexplosions = Ledakan Reaktor +rules.coreincinerates = Penghangusan Luapan Inti rules.schematic = Skema Diperbolehkan rules.wavetimer = Pengaturan Waktu Gelombang rules.waves = Gelombang @@ -1219,6 +1222,7 @@ block.meltdown.name = Meltdown block.foreshadow.name = Foreshadow block.container.name = Kontainer block.launch-pad.name = Alas Peluncur +block.launch-pad-large.name = Alas Peluncur Besar block.segment.name = Segment block.command-center.name = Pusat Perintah block.ground-factory.name = Pabrik Unit Darat From e9abe273c7dec5b71ff2379cab38940bccd64d59 Mon Sep 17 00:00:00 2001 From: rnarko <1793030+loa-in-@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:30:30 +0100 Subject: [PATCH 100/426] Update Polish translation to fix eye-hurting typos (#4310) --- core/assets/bundles/bundle_pl.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 276cdb89ea..a7eda43fd6 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -1272,9 +1272,9 @@ hint.breaking = Użyj [accent]Prawego przycisku myszy[] i przeciągnij by zniszc hint.breaking.mobile = Aktywuj \ue817 [accent]ikonę młota[] w dolnym prawym rogu by zniszczyć bloki.\n\nPrzytrymaj swój palec i przeciągij by wybrać wiele bloków do zniszczenia. hint.research = Klikij przycisk \ue875 [accent]Badań[] by odkrwyać nowe technologie. hint.research.mobile = Użyj przycisku \ue875 [accent]Badań[] w \ue88c [accent]Menu[] by odkrwyać nowe technologie. -hint.unitControl = Przytrzymaj [accent][[Lewy CTRL][] i [accent]kliknij[] to control by kontrolować sojusznicze jednostki i działka. +hint.unitControl = Przytrzymaj [accent][[Lewy CTRL][] i [accent]kliknij[] by kontrolować sojusznicze jednostki i działka. hint.unitControl.mobile = [accent][Kliknij dwukrotnie[] by kontrolować sojusznicze jednostki i działka. -hint.launch = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] wybierając \ue827 [accent]Mape[] w dolnym prawym rogu. +hint.launch = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] wybierając \ue827 [accent]Mapę[] w dolnym prawym rogu. hint.launch.mobile = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] do pobliskich sektorów klikając w \ue827 [accent]Mape[] w \ue88c [accent]Menu[]. hint.schematicSelect = Przytrzymaj [accent][[F][] by kopiować i wkleić bloki.\n\n[accent][[Środkowy przycisk myszy][] kopiuje pojedyńczy blok. hint.conveyorPathfind = Przeciągij i przytrzymaj [accent][[Lewy CTRL][] w trakcie budowania przenośników by wygenerować ścieżkę. @@ -1287,12 +1287,12 @@ hint.payloadPickup.mobile = [accent]Kliknij i przytrzymaj[] mały blok by go pod hint.payloadDrop = Kliknij [accent]][] by opuścić podniesoiny towar. hint.payloadDrop.mobile = [accent]Kliknij i przytrzymaj[] w puste miejsce by opuścić podniesoiny towar. hint.waveFire = [accent]Strumień[] wypełniony wodą będzie gasić pobiskie pożary. -hint.generator = \uf879 [accent]Generatory Spalinowe[] spalają węgiel i przekuzują moc do pobliskich bloków.\n\nMożesz powiększyć odległość transmitowanej mocy używająć \uf87f [accent]Węzeły Prądu[]. +hint.generator = \uf879 [accent]Generatory Spalinowe[] spalają węgiel i przekuzują moc do pobliskich bloków.\n\nMożesz powiększyć odległość transmitowanej mocy używająć \uf87f [accent]Węzły Prądu[]. hint.guardian = Jednostki [accent]Strażnicze[] są uzbrojone. Słaba amunicja - taka jak [accent]Miedź[] oraz [accent]Ołów[] [scarlet]nie jest efektywna[].\n\nUżyj lepszych działek takich jak \uf835 [accent]Naładowane Grafitem[] \uf861Duo/\uf859Salwa by pozbyć się strażników. hint.coreUpgrade = Rdzenie mogą być ulepszone poprzez [accent]płożenie na nich rdzeń wyższego poziomu[].\n\nPołóż  rdzeń [accent]Fundacji[] na  rdzeń:[accent]Odłamek[] core. Żadna przeszkoda ani blok nie może stać na miejscu rdzenia. hint.presetLaunch = Szare [accent]sektory[], takie jak [accent]Zamrożony Las[], to sektory do których możesz dotrzeć z każdego miejsca. Nie wymagają podbicia pobliskiego terenu.\n\n[accent]Ponumerowane sektory[], takie jak ten, [accent]są dodatkowe[]. hint.coreIncinerate = Jak rdzeń zostanie w pełni wypełniony danym przedmiotem, reszta przedmiotów tego typu zostanie [accent]spalona[]. -hint.coopCampaign = Gdy grasz [accent]kooperacyjną kampanie[], przedmioty które są produkowane na mapie trafią także [accent]dotwoich lokalnych sektorów[].\n\nWszelkie nowe badania przeprowadzone przez hosta są również przenoszone. +hint.coopCampaign = Gdy grasz [accent]kooperacyjną kampanię[], przedmioty które są produkowane na mapie trafią także [accent]do twoich lokalnych sektorów[].\n\nWszelkie nowe badania przeprowadzone przez hosta są również przenoszone. item.copper.description = Przydatny materiał budowlany. Szeroko używany w prawie każdej konstrukcji. item.copper.details = Miedź. Nienormalnie obfity metal na Serpulo. Strukturalnie słaba, chyba że zostanie wzmocniona. From 0be39d43a23f48d560a92fad5f1ee3b1809b3e31 Mon Sep 17 00:00:00 2001 From: Molovtov <76136198+Molovtov@users.noreply.github.com> Date: Wed, 20 Jan 2021 05:30:40 +0700 Subject: [PATCH 101/426] better_thai_translate.properties (#4314) * better_thai_translate.properties Better thai translate but not done yet,by the red(need more blins) * Better_thai_properties Better thai by thai people,by the red(need more blins) --- core/assets/bundles/bundle_th.properties | 100 +++++++++++------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/core/assets/bundles/bundle_th.properties b/core/assets/bundles/bundle_th.properties index 930887461d..01b8310b19 100644 --- a/core/assets/bundles/bundle_th.properties +++ b/core/assets/bundles/bundle_th.properties @@ -331,7 +331,7 @@ editor.generation = การเกิด: editor.ingame = แก้ไขในเกม editor.publish.workshop = เผยแพร่บน Workshop editor.newmap = แมพใหม่ -editor.center = Center +editor.center = ศูนย์กลางแมพ workshop = Workshop waves.title = Waves waves.remove = ลบ @@ -352,7 +352,7 @@ waves.none = ไม่ได้กำหนดศัตรู\nwave layouts เ wavemode.counts = จำนวน wavemode.totals = ทั้งหมด -wavemode.health = health +wavemode.health = เลือด editor.default = [lightgray]<ค่าเริ่่มต้น> details = รสยละเอียด... @@ -512,7 +512,7 @@ weather.rain.name = ฝน weather.snow.name = หิมะ weather.sandstorm.name = พายุทราย weather.sporestorm.name = พายุสปอร์ -weather.fog.name = Fog +weather.fog.name = หมอก sectors.unexplored = [lightgray]ยังไม่ได้สำรวจ sectors.resources = ทรัพยากร: @@ -523,7 +523,7 @@ sectors.launch = ส่ง sectors.select = เลือก sectors.nonelaunch = [lightgray]none (sun) sectors.rename = Rename Sector -sector.missingresources = [scarlet]Insufficient Core Resources +sector.missingresources = [scarlet]สิ่งของทำ core ไม่ครบ planet.serpulo.name = Serpulo planet.sun.name = Sun @@ -566,10 +566,10 @@ settings.clear.confirm = คุณแน่ใจหรือว่าจะเ settings.clearall.confirm = [scarlet]คำเตือน![]\nการกระทำนี้จะลบข้อมูลทั้งหมด นั้นรวมไปถึงเซฟ, แมพ, สิ่งที่ปลดล็อคแล้วและ keybinds.\nเมื่อคุณกด 'โอเค' เกมจะลบข้อมูลทุกอย่างและออกโดยอัตโนมัติ settings.clearsaves.confirm = คุณแน่ใจหรือว่าคุณต้องการเคลียร์เซฟทั้งหมด? settings.clearsaves = เคลียร์เซฟ -settings.clearresearch = Clear Research -settings.clearresearch.confirm = Are you sure you want to clear all of your campaign research? -settings.clearcampaignsaves = Clear Campaign Saves -settings.clearcampaignsaves.confirm = Are you sure you want to clear all of your campaign saves? +settings.clearresearch = ลบการ Research +settings.clearresearch.confirm = แน่ใจที่จะลบการ Research หรือไม่? +settings.clearcampaignsaves = ลบเซฟ Campaign +settings.clearcampaignsaves.confirm = แน่ใจที่จะลบเซฟ Campaign หรือไม่? paused = [accent]< หยุดชั่วคราว > clear = เคลียร์ banned = [scarlet]แบน @@ -580,14 +580,14 @@ info.title = ข้อมูล error.title = [crimson]มีบางอย่างผิดพลาดเกิดขึ้น error.crashtitle = มีบางอย่างผิดพลาดเกิดขึ้น unit.nobuild = [scarlet]ยูนิตไม่สามารถสร้างได้ -lastaccessed = [lightgray]Last Accessed: {0} +lastaccessed = [lightgray]:คนที่แตะเป็นคนสุดท้าย {0} block.unknown = [lightgray]??? stat.input = นำเข้า stat.output = ส่งออก stat.booster = บูสเตอร์ stat.tiles = ต้องการ Tiles -stat.affinities = Affinities +stat.affinities = affinities stat.powercapacity = ความจุพลังงาน stat.powershot = หน่วยพลังงาน/นัด stat.damage = ดาเมจ @@ -600,13 +600,13 @@ stat.size = ขนาด stat.displaysize = ขนาดที่โชว์ stat.liquidcapacity = จุของเหลว stat.powerrange = ระยะพลังงาน -stat.linkrange = Link Range +stat.linkrange = ระยะการเชื่อมต่อ stat.instructions = คำแนะนำ stat.powerconnections = จำนวนการเชื่อมต่อสูงสุด stat.poweruse = ใช้พลังงาน stat.powerdamage = หน่วยพลังงาน/ดาเมจ stat.itemcapacity = จุไอเท็ม -stat.memorycapacity = Memory Capacity +stat.memorycapacity = ความจุหน่วยความจำ stat.basepowergeneration = กำเนิดพลังงานพื้นฐาน stat.productiontime = เวลาที่ใช้ในการผลิต stat.repairtime = เวลาที่ใช้ในการซ่อมแซมให้สมบูรณ์ @@ -626,28 +626,28 @@ stat.reload = นัด/วินาที stat.ammo = กระสุน stat.shieldhealth = เลือดของเกราะ stat.cooldowntime = เวลา Cooldown -stat.explosiveness = Explosiveness -stat.basedeflectchance = Base Deflect Chance -stat.lightningchance = Lightning Chance -stat.lightningdamage = Lightning Damage -stat.flammability = Flammability -stat.radioactivity = Radioactivity -stat.heatcapacity = HeatCapacity +stat.explosiveness = ความแรงของระเบิด +stat.basedeflectchance = โอกาสกระสุนกระเด็นกลับ +stat.lightningchance = โอกาสที่จะเกิดสายฟ้า +stat.lightningdamage = ความแรงของสายฟ้า +stat.flammability = ความไวไฟ +stat.radioactivity = ความแรงของรังสี +stat.heatcapacity = ความจุความร้อน stat.viscosity = Viscosity -stat.temperature = Temperature -stat.speed = Speed -stat.buildspeed = Build Speed -stat.minespeed = Mine Speed -stat.minetier = Mine Tier -stat.payloadcapacity = Payload Capacity -stat.commandlimit = Command Limit -stat.abilities = Abilities +stat.temperature = อุณหภูมิ +stat.speed = ความไว +stat.buildspeed = ความไวในการก่อสร้าง +stat.minespeed = ความไวในการขุด +stat.minetier = ความแรงของเลเซอร์ขุด +stat.payloadcapacity = ความจุการขนของ +stat.commandlimit = จำนวน Unit ที่สามารถสูงสุด +stat.abilities = ทักษะ -ability.forcefield = Force Field -ability.repairfield = Repair Field -ability.statusfield = Status Field -ability.unitspawn = {0} Factory -ability.shieldregenfield = Shield Regen Field +ability.forcefield = สนามพลัง +ability.repairfield = รักษา Unit รอบข้าง +ability.statusfield = บัฟ Unit รอบข้าง +ability.unitspawn = โรงงานทำ {0} +ability.shieldregenfield = บัฟโล่รอบข้าง bar.drilltierreq = จำเป็นต้องใช้เครื่องขุดที่ดีกว่า bar.noresources = ทรัพยากรหาย @@ -671,7 +671,7 @@ bar.progress = ความคืบหน้าในการสร้าง bar.input = นำเข้า bar.output = ส่งออก -units.processorcontrol = [lightgray]Processor Controlled +units.processorcontrol = [lightgray]ถูก Processor ควบคุม bullet.damage = [stat]{0}[lightgray] ดาเมจ bullet.splashdamage = [stat]{0}[lightgray] ดาเมจกระจาย ~[stat] {1}[lightgray] ช่อง @@ -680,8 +680,8 @@ bullet.homing = [stat]ติดตาม bullet.shock = [stat]ช็อค bullet.frag = [stat]แตกออก bullet.knockback = [stat]{0}[lightgray] ดันกลับ -bullet.pierce = [stat]{0}[lightgray]x pierce -bullet.infinitepierce = [stat]pierce +bullet.pierce = [stat]{0}[lightgray]x ทะลุ +bullet.infinitepierce = [stat]ทะลุ bullet.freezing = [stat]แช่แข็ง bullet.tarred = [stat]เปื้อนน้ำมัน bullet.multiplier = [stat]{0}[lightgray]x จำนวนกระสุนต่อ 1 ไอเท็ม @@ -696,9 +696,9 @@ unit.liquidunits = หน่วยของเหลว unit.powerunits = หน่วยพลังงาน unit.degrees = องศา unit.seconds = วินาที -unit.minutes = mins +unit.minutes = นาที unit.persecond = /วินาที -unit.perminute = /min +unit.perminute = /ต่อนาที unit.timesspeed = เท่าเร็วขึ้น unit.percent = % unit.shieldhealth = เลือดเกราะ @@ -729,7 +729,7 @@ setting.autotarget.name = เล็งเป้าอัตโนมัติ setting.keyboard.name = การควบคุมแบบ เม้าส์+คีย์บอร์ด setting.touchscreen.name = การควบคุมแบบหน้าจอสัมผัส setting.fpscap.name = FPS -setting.fpscap.none = ไม่มี +setting.fpscap.none = ∞ setting.fpscap.text = {0} FPS setting.uiscale.name = ขนาด UI[lightgray] (จำเป็นต้องรีสตาร์ท)[] setting.swapdiagonal.name = การวางเป็นเส้นทแยงเสมอ @@ -803,8 +803,8 @@ keybind.pan.name = แพนวิว keybind.boost.name = บูสต์ keybind.schematic_select.name = เลือกภูมิภาค keybind.schematic_menu.name = เมนู Schematic -keybind.schematic_flip_x.name = กลับ Schematic ในแกน X -keybind.schematic_flip_y.name = กลับ Schematic ในแกน Y +keybind.schematic_flip_x.name = กลับแผนผังแกน X +keybind.schematic_flip_y.name = กลับแผนผังแกน Y keybind.category_prev.name = หมวดหมู่ก่อนหน้า keybind.category_next.name = หมวดหมู่ถ้ดไป keybind.block_select_left.name = เลือกบล็อค ซ้าย @@ -821,7 +821,7 @@ keybind.block_select_07.name = หมวดหมู่/เลือกบล็ keybind.block_select_08.name = หมวดหมู่/เลือกบล็อค 8 keybind.block_select_09.name = หมวดหมู่/เลือกบล็อค 9 keybind.block_select_10.name = หมวดหมู่/เลือกบล็อค 10 -keybind.fullscreen.name = เปิด/ปิด Fullscreen +keybind.fullscreen.name = เปิด/ปิด เต็มจอ keybind.select.name = เลือก/ยิง keybind.diagonal_placement.name = วางเป็นแนวทแยง keybind.pick.name = เลือกบล็อค @@ -861,7 +861,7 @@ mode.custom = กฎแบบกำหนดเอง rules.infiniteresources = ทรัพยากรไม่จำกัด rules.reactorexplosions = การระเบิดของ -rules.schematic = Schematics Allowed +rules.schematic = อนุญาตแผนผัง rules.wavetimer = ตัวนับเวลาปล่อยคลื่น(รอบ) rules.waves = คลื่น(รอบ) rules.attack = โหมดการโจมตี @@ -884,10 +884,10 @@ rules.title.waves = คลื่น(รอบ) rules.title.resourcesbuilding = ทรัพยากรและสิ่งก่อสร้าง rules.title.enemy = ศัตรู rules.title.unit = ยูนิต -rules.title.experimental = Experimental +rules.title.experimental = ทดลอง rules.title.environment = สิ่งแวดล้อม rules.lighting = แสง -rules.enemyLights = Enemy Lights +rules.enemyLights = ไฟศัตรู rules.fire = ไฟ rules.explosions = ดาเมจบล็อค/ยูนิตระเบิด rules.ambientlight = แสงจากแวดล้อม @@ -960,8 +960,8 @@ block.parallax.name = พาราแล็ซ block.cliff.name = หน้าผ่า block.sand-boulder.name = ก้อนหินทราย block.grass.name = หญ้า -block.slag.name = Slag -block.space.name = Space +block.slag.name = กากแร่ +block.space.name = อวกาศ block.salt.name = เกลือ block.salt-wall.name = กำแพงเกลือ block.pebbles.name = ก้อนกรวด @@ -1007,7 +1007,7 @@ block.darksand-water.name = น้ำบนทรายดำ block.char.name = ถ่าน block.dacite.name = ดาไซต์ block.dacite-wall.name = กำแพงดาไซต์ -block.dacite-boulder.name = Dacite Boulder +block.dacite-boulder.name = โขดหินดาไซต์ block.ice-snow.name = น้ำแข็งหิมะ block.stone-wall.name = กำแพงหิน block.ice-wall.name = กำแพงน้ำแข็ง @@ -1102,7 +1102,7 @@ block.power-source.name = จุดกำเนิดพลังงาน block.unloader.name = ตัวถ่ายไอเทม block.vault.name = ตู้นิรภัย block.wave.name = เวฟ -block.tsunami.name = Tsunami +block.tsunami.name = สึนามิ block.swarmer.name = สวอร์มเมอร์ block.salvo.name = ซัลโว block.ripple.name = ริปเปิล @@ -1142,11 +1142,11 @@ block.arc.name = อาร์ค block.rtg-generator.name = เครื่องกำเนิดไฟฟ้า RTG block.spectre.name = สเปคเตอร์ block.meltdown.name = เมลท์ดาวน์ -block.foreshadow.name = Foreshadow +block.foreshadow.name = ฟอร์ชาโดว์ block.container.name = ตู้เก็บของ block.launch-pad.name = ฐานส่งของ block.launch-pad-large.name = ฐานส่งของขนาดใหญ่ -block.segment.name = Segment +block.segment.name = เซ็กเมนต์ block.command-center.name = ศูนย์ควบคุม block.ground-factory.name = โรงงานภาคพื้นดิน block.air-factory.name = โรงงานภาคอากาศ From 88086f5ba9f3875324dcb8dd91279da7b6f36490 Mon Sep 17 00:00:00 2001 From: Arnyyx <74717260+Arnyyx@users.noreply.github.com> Date: Wed, 20 Jan 2021 05:32:15 +0700 Subject: [PATCH 102/426] Update bundle_vi.properties (#4333) --- core/assets/bundles/bundle_vi.properties | 114 +++++++++++------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/core/assets/bundles/bundle_vi.properties b/core/assets/bundles/bundle_vi.properties index d45c16a170..cc33ff9bee 100644 --- a/core/assets/bundles/bundle_vi.properties +++ b/core/assets/bundles/bundle_vi.properties @@ -83,13 +83,13 @@ joingame = Tham gia trò chơi customgame = Tùy chỉnh newgame = Trò chơi mới none = -minimap = Bản đồ mini +minimap = Bản đồ nhỏ position = Vị trí close = Đóng website = Website quit = Thoát save.quit = Lưu & Thoát -maps = Maps +maps = Bản đồ maps.browse = Duyệt bản đồ continue = Tiếp tục maps.none = [lightgray]Không có bản đồ nào được tìm thấy! @@ -971,19 +971,19 @@ item.graphite.name = Than chì item.titanium.name = Titan item.thorium.name = Thorium item.silicon.name = Silicon -item.plastanium.name = Plastanium +item.plastanium.name = Nhựa item.phase-fabric.name = Phase Fabric -item.surge-alloy.name = Surge Alloy +item.surge-alloy.name = Hợp kim item.spore-pod.name = Vỏ bào tử item.sand.name = Cát item.blast-compound.name = Chất nổ -item.pyratite.name = Pyratite -item.metaglass.name = Metaglass +item.pyratite.name = Tiền chất nổ +item.metaglass.name = Thuỷ tinh item.scrap.name = Phế liệu liquid.water.name = Nước liquid.slag.name = Xỉ nóng chảy liquid.oil.name = Dầu -liquid.cryofluid.name = Cryofluid +liquid.cryofluid.name = Chất làm lạnh #Why we should translate this ??? unit.dagger.name = Dagger @@ -1050,8 +1050,8 @@ block.scrap-wall-huge.name = Tường phế liệu khổng lồ block.scrap-wall-gigantic.name = Tường phế liệu siêu khổng lồ block.thruster.name = Thruster block.kiln.name = Lò nung -block.graphite-press.name = Máy nén thang chì -block.multi-press.name = Máy nén thang chì lớn +block.graphite-press.name = Máy nén than chì +block.multi-press.name = Máy nén than chì lớn block.constructing = {0} [lightgray](Đang xây dựng) block.spawn.name = Khu vực tạo ra kẻ địch block.core-shard.name = Căn cứ: Cơ sở @@ -1120,21 +1120,21 @@ block.hail.name = Hail block.lancer.name = Lancer block.conveyor.name = Băng chuyền block.titanium-conveyor.name = Băng chuyền titan -block.plastanium-conveyor.name = Băng chuyền Plastanium -block.armored-conveyor.name = Băng chuyền bọc thép +block.plastanium-conveyor.name = Băng chuyền nhựa +block.armored-conveyor.name = Băng chuyền bọc giáp block.junction.name = Junction -block.router.name = Router -block.distributor.name = Distributor -block.sorter.name = Sorter -block.inverted-sorter.name = Sorter ngược +block.router.name = Bộ định tuyến +block.distributor.name = Bộ phân phát +block.sorter.name = Bộ lọc +block.inverted-sorter.name = Bộ lọc ngược block.message.name = Thông điệp block.illuminator.name = Đèn -block.overflow-gate.name = Overflow Gate -block.underflow-gate.name = Underflow Gate +block.overflow-gate.name = Cổng tràn +block.underflow-gate.name = Cổng tràn ngược block.silicon-smelter.name = Máy nấu silicon block.phase-weaver.name = Máy tạo Phase block.pulverizer.name = Máy nghiền -block.cryofluid-mixer.name = Máy trộn Cryofluid +block.cryofluid-mixer.name = Máy sản xuất chất làm mát block.melter.name = Máy nung chảy block.incinerator.name = Máy phân hủy block.spore-press.name = Máy nén bào tử @@ -1142,7 +1142,7 @@ block.separator.name = Máy phân tách block.coal-centrifuge.name = Máy tạo than block.power-node.name = Chốt điện block.power-node-large.name = Chốt điện lớn -block.surge-tower.name = Tháp Surge +block.surge-tower.name = Tháp điện block.diode.name = Diode pin block.battery.name = Pin block.battery-large.name = Pin lớn @@ -1151,7 +1151,7 @@ block.steam-generator.name = Máy phát điện hơi nước block.differential-generator.name = Máy phát điện vi sai block.impact-reactor.name = Lò phản ứng nhiệt hạch block.mechanical-drill.name = Máy khoan cơ khí -block.pneumatic-drill.name = Khoan khí nén +block.pneumatic-drill.name = Máy khoan khí nén block.laser-drill.name = Máy khoan laser block.water-extractor.name = Máy khoan nước block.cultivator.name = Máy nuôi cấy bào tử @@ -1163,8 +1163,8 @@ block.liquid-source.name = Nguồn chất lỏng block.liquid-void.name = Hủy chất lỏng block.power-void.name = Hủy năng lượng block.power-source.name = Vô hạn năng lượng -block.unloader.name = Unloader -block.vault.name = Vault +block.unloader.name = Điểm dỡ hàng +block.vault.name = Nhà kho block.wave.name = Wave block.tsunami.name = Tsunami block.swarmer.name = Swarmer @@ -1172,31 +1172,31 @@ block.salvo.name = Salvo block.ripple.name = Ripple block.phase-conveyor.name = Phase Conveyor block.bridge-conveyor.name = Bridge Conveyor -block.plastanium-compressor.name = Máy nén Plastanium -block.pyratite-mixer.name = Máy trộn Pyratite +block.plastanium-compressor.name = Máy sản xuất nhựa +block.pyratite-mixer.name = Máy trộn tiền chất nổ block.blast-mixer.name = Máy trộn chất nổ block.solar-panel.name = Pin mặt trời block.solar-panel-large.name = Pin mặt trời lớn block.oil-extractor.name = Máy khoan dầu block.repair-point.name = Điểm sửa chữa block.pulse-conduit.name = Ống dẫn titan -block.plated-conduit.name = Ống dẫn bọc thép +block.plated-conduit.name = Ống dẫn bọc giáp block.phase-conduit.name = Ống dẫn Phase -block.liquid-router.name = Liquid Router +block.liquid-router.name = Bộ định tuyến chất lỏng block.liquid-tank.name = Thùng chất lỏng block.liquid-junction.name = Liquid Junction block.bridge-conduit.name = Bridge Conduit block.rotary-pump.name = Bơm điện block.thorium-reactor.name = Lò phản ứng Thorium -block.mass-driver.name = Mass Driver -block.blast-drill.name = Máy khoang thủy lực +block.mass-driver.name = Máy phóng điện từ +block.blast-drill.name = Máy khoan thủy lực block.thermal-pump.name = Bơm nhiệt block.thermal-generator.name = Máy phát nhiệt điện block.alloy-smelter.name = Lò luyện hợp kim block.mender.name = Máy sửa chữa block.mend-projector.name = Máy sửa lớn -block.surge-wall.name = Tường Surge -block.surge-wall-large.name = Tường Surge lớn +block.surge-wall.name = Tường hợp kim +block.surge-wall-large.name = Tường hợp kim lớn block.cyclone.name = Cyclone block.fuse.name = Fuse block.shock-mine.name = Mìn gây sốc @@ -1220,7 +1220,7 @@ block.multiplicative-reconstructor.name = Máy nâng cấp quân đội cấp 3 block.exponential-reconstructor.name = Máy nâng cấp quân đội cấp 4 block.tetrative-reconstructor.name = Máy nâng cấp quân đội cấp 5 block.payload-conveyor.name = Băng chuyền khối hàng -block.payload-router.name = Payload Router +block.payload-router.name = Bộ định tuyến khối hàng block.disassembler.name = Máy phân tách lớn block.silicon-crucible.name = Máy nấu Silicon lớn block.overdrive-dome.name = Máy tăng tốc lớn @@ -1234,8 +1234,8 @@ block.switch.name = Công tắc block.micro-processor.name = Bộ xử lí mini block.logic-processor.name = Bộ xử lý block.hyper-processor.name = Bộ xử lý lớn -block.logic-display.name = Màng hình -block.large-logic-display.name = Màng hình lớn +block.logic-display.name = Màn hình +block.large-logic-display.name = Màn hình lớn block.memory-cell.name = Bộ nhớ block.memory-bank.name = Bộ nhớ lớn @@ -1307,41 +1307,41 @@ item.pyratite.description = Dùng trong vũ khí gây cháy và máy phát đi liquid.water.description = Dùng để làm mát máy móc và xử lý chất thải. liquid.slag.description = Dùng để tách các kim loại, hoặc phun vào kẻ thù như một loại vũ khí. -liquid.oil.description = Dùng trong sản xuất vật liệu tiên tiến và làm đạn gây cháycháy. +liquid.oil.description = Dùng trong sản xuất vật liệu tiên tiến và làm đạn gây cháy. liquid.cryofluid.description = Dùng làm chất làm mát trong lò phản ứng, súng và nhà máy. block.resupply-point.description = Cung cấp đạn đồng cho các quân lính ở gần. Không tương thích với quân lính sử dụng điện. -block.armored-conveyor.description = Vận chuyển vật phẩm về phía . Không nhận đầu vào từ phía bên. +block.armored-conveyor.description = Vận chuyển vật phẩm về phía. Không nhận đầu vào từ phía bên. block.illuminator.description = Phát sáng. block.message.description = Lưu trữ tin nhắn giao tiếp giữa đồng đội. block.graphite-press.description = Nén than thành than chì. block.multi-press.description = Nén than thành than chì. Cần nước làm chất làm mát. block.silicon-smelter.description = Tinh chế silicon từ cát và than. -block.kiln.description = Nấu chảy cát và chì thành metaglass. -block.plastanium-compressor.description = Sản xuất plastanium từ dầu và titan. +block.kiln.description = Nấu chảy cát và chì thành thuỷ tinh. +block.plastanium-compressor.description = Sản xuất nhựa từ dầu và titan. block.phase-weaver.description = Tổng hợp phase fabric từ thorium và cát. -block.alloy-smelter.description = Trộn titan, chì, silicon và đồng thành hợp kim surge. -block.cryofluid-mixer.description = Trộn nước và bột titan để sản xuất cryofluid. -block.blast-mixer.description = Tạo ra hợp chất nổ từ pyratite và vỏ bào tử. -block.pyratite-mixer.description = Trộn than, chì và cát thành pyratite. +block.alloy-smelter.description = Trộn titan, chì, silicon và đồng thành hợp kim. +block.cryofluid-mixer.description = Trộn nước và bột titan để sản xuất chất làm mát. +block.blast-mixer.description = Tạo ra hợp chất nổ từ tiền chất nổ và vỏ bào tử. +block.pyratite-mixer.description = Trộn than, chì và cát thành tiền chất nổ. block.melter.description = Nung phế liệu thành xỉ. block.separator.description = Tách xỉ thành các thành phần khoáng của nó. block.spore-press.description = Nén vỏ bào tử thành dầu. block.pulverizer.description = Nghiền phế liệu thành cát. block.coal-centrifuge.description = Biến dầu thành than. block.incinerator.description = Tiêu hủy bất kỳ vật phẩm hoặc chất lỏng nào mà nó nhận được. -block.power-void.description = Hủy tất cả năng lượng nhận được. Chỉ có trong chế độ Sandbox. -block.power-source.description = Tạo ra năng lượng mãi mãi. Chỉ có trong chế độ Sandbox. -block.item-source.description = Tạo ra vật phẩm mãi mãi. Chỉ có trong chế độ Sandbox. -block.item-void.description = Hủy mọi vật phẩm. Chỉ có trong chế độ Sandbox. -block.liquid-source.description = Tạo ra chất lỏng mãi mãi. Chỉ có trong chế độ Sandbox. -block.liquid-void.description = Loại bỏ mọi chất lỏng. Chỉ có trong chế độ Sandbox. +block.power-void.description = Hủy tất cả năng lượng nhận được. Chỉ có trong chế độ tự do. +block.power-source.description = Tạo ra năng lượng mãi mãi. Chỉ có trong chế độ tự do. +block.item-source.description = Tạo ra vật phẩm mãi mãi. Chỉ có trong chế độ tự do. +block.item-void.description = Hủy mọi vật phẩm. Chỉ có trong chế độ tự do. +block.liquid-source.description = Tạo ra chất lỏng mãi mãi. Chỉ có trong chế độ tự do. +block.liquid-void.description = Loại bỏ mọi chất lỏng. Chỉ có trong chế độ tự do. block.copper-wall.description = Bảo vệ các công trình khỏi đạn của kẻ thù. block.copper-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù. block.titanium-wall.description = Bảo vệ các công trình khỏi đạn của kẻ thù. block.titanium-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù. -block.plastanium-wall.description = Bảo vệ công trình khỏi đạn của kẻ thù. Hấp thụ tia laser và tia điện. Chặn kết nối nguồn tự động. -block.plastanium-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù. Hấp thụ tia laser và tia điện. Chặn kết nối nguồn tự động. +block.plastanium-wall.description = Bảo vệ công trình khỏi đạn của kẻ thù. Hấp thụ tia laser và tia điện. Chặn kết nối điện tự động. +block.plastanium-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù. Hấp thụ tia laser và tia điện. Chặn kết nối điện tự động. block.thorium-wall.description = Bảo vệ công trình khỏi đạn của kẻ thù. block.thorium-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù. block.phase-wall.description = Bảo vệ công trình khỏi đạn của kẻ thù, phản hầu hết đạn khi va chạm. @@ -1405,22 +1405,22 @@ block.cultivator.details = Công nghệ được phục hồi. Được sử d block.oil-extractor.description = Sử dụng lượng năng lượng năng lớn, sử dụng cát và nước để khoan dầu. block.core-shard.description = Trung tâm của căn cứ. Sau khi bị phá hủy, khu vực này sẽ bị mất. block.core-shard.details = Lần thử đầu tiên. Gọn nhẹ. Tự thay thế. Được trang bị tên lửa đẩy dùng một lần. Không được thiết kế để di chuyển giữa các hành tinh. -block.core-foundation.description = Core of the base. Well armored. Stores more resources than a Shard. +block.core-foundation.description = Trung tâm của căn cứ. Được bọc giáp. Stores more resources than a Shard. block.core-foundation.details = The second iteration. block.core-nucleus.description = Lõi của căn cứ. Bọc giáp chắc chắn. Lưu trữ lượng lớn tài nguyên. -block.core-nucleus.details = Lần thử thứ ba và lần thử cuối. -block.vault.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với Unloader. -block.container.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với Unloader. +block.core-nucleus.details = Lần thử thứ ba và lần thử cuối. +block.vault.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng. +block.container.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng. block.unloader.description = Lấy các vật phẩm được chọn từ các ô gần đó. block.launch-pad.description = Phóng lô vật phẩm vào phân vùng. block.duo.description = Bắn xen kẽ đạn vào kẻ địch. -block.scatter.description = Bắn chì, phế liệu hoặc metaglass vào máy bay địch. +block.scatter.description = Bắn chì, phế liệu hoặc thuỷ tinh vào kẻ địch trên không. block.scorch.description = Đốt mọi kẻ địch trên mặt đất. Hiệu quả cao ở tầm gần. block.hail.description = Phóng đạn nhỏ vào kẻ địch trên mặt đất ở tầm xa. block.wave.description = Phóng một tia chất lỏng vào kẻ địch. Tự chữa cháy nếu được cung cấp nước. block.lancer.description = Tích tụ và phóng tia năng lượng mạnh vào kẻ địch trên mặt đất. block.arc.description = Phóng tia điện vào kẻ địch trên mặt đất. -block.swarmer.description = Bắn tên lửa homing vào kẻ địch. +block.swarmer.description = Bắn tên lửa truy đuổi vào kẻ địch. block.salvo.description = Bắn đạn salvo vào kẻ địch. block.fuse.description = Bắn ba đạn xuyên giáp tầm gần vào kẻ địch. block.ripple.description = Bắn cụm đạn vào kẻ địch trên mặt đất ở tầm xa. @@ -1432,7 +1432,7 @@ block.repair-point.description = Liên tục sửa chữa robot ở gần trong block.segment.description = Gây hư hại và phá hủy đạn đến. Ngoại trừ tia laser. block.parallax.description = Bắn một tia kéo máy bay địch và làm hư hỏng nó trong quá trình kéo. block.tsunami.description = Phóng một tia chất lỏng mạnh vào kẻ địch. Tự chữa cháy nếu được cung cấp nước. -block.silicon-crucible.description = Tinh chế silicon từ cát và than, sử dụng pyratite làm nguồn nhiệt phụ. Có hiệu quả cao hơn khi ở nơi nóng. +block.silicon-crucible.description = Tinh chế silicon từ cát và than, sử dụng tiền chất nổ làm nguồn nhiệt phụ. Có hiệu quả cao hơn khi ở nơi nóng. block.disassembler.description = Tách xỉ thành các kim loại khác nhau với hiệu suất thấp. Có thể sản xuất thorium. block.overdrive-dome.description = Tăng tốc độ làm việc của các công trình lân cận. Sử dụng phase fabric and silicon để hoạt động. block.payload-conveyor.description = Di chuyển những khối hàng lớn, chẳng hạn như các quân lính từ nhà máy. @@ -1484,7 +1484,7 @@ unit.risso.description = Bắn chùm tên lửa và đạn lên kẻ địch t unit.minke.description = Bắn đạn và đạn thường lên kẻ địch tầm gần trên mặt đất. unit.bryde.description = Bắn đạn tầm xa và tên lửa vào kẻ địch. unit.sei.description = Bắn chùm tên lửa và đạn xuyên giáp vào kẻ địch. -unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào kẻ địch. Tạo nên robot báo hiệu. +unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào kẻ địch. Tạo nên drone báo hiệu. unit.alpha.description = Bảo vệ căn cứ cơ sở khỏi kẻ thù. Có thể xây dựng. unit.beta.description = Bảo vệ căn cứ trụ sở khỏi kẻ thù. Có thể xây dựng. unit.gamma.description = Bảo vệ căn cứ trung tâm khỏi kẻ thù. Có thể xây dựng. From 532a4bc140e24926b8c85de3e372c7d18a4d7e6d Mon Sep 17 00:00:00 2001 From: Nikolass1000 <68129216+Nikolass1000@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:33:42 +0100 Subject: [PATCH 103/426] Update bundle_pl.properties (#4377) --- core/assets/bundles/bundle_pl.properties | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index a7eda43fd6..936f17e760 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -41,7 +41,6 @@ be.ignore = Zignoruj be.noupdates = Nie znaleziono aktualizacji. be.check = Sprawdź aktualizacje -mod.featured.title = Wyszukiwarka Modów mod.featured.dialog.title = Wyszukiwarka Modów mods.browser.selected = Wybrany Mod mods.browser.add = Zainstaluj Moda @@ -90,6 +89,7 @@ joingame = Dołącz Do Gry customgame = Własna Gra newgame = Nowa Gra none = +none.found = [lightgray]<żaden znaleziony> minimap = Minimapa position = Pozycja close = Zamknij @@ -110,7 +110,6 @@ committingchanges = Zatwierdzanie Zmian done = Gotowe feature.unsupported = Twoje urządzenie nie wspiera tej funkcji. - mods.alphainfo = Pamiętaj, że mody są wersji alpha, i[scarlet] mogą być pełne błędów[].\nZgłaszaj wszystkie znalezione problemy na Mindustry GitHub lub Discord. mods = Mody mods.none = [lightgray]Nie znaleziono modów! @@ -288,6 +287,7 @@ cancel = Anuluj openlink = Otwórz Link copylink = Kopiuj Link back = Wróć +max = Max crash.export = Eksportuj logi błędów. crash.none = Nie znaleziono logów błędów. crash.exported = Logi zostały przeniesione. @@ -362,7 +362,6 @@ editor.center = Center workshop = Warsztat waves.title = Fale waves.remove = Usuń -waves.never = waves.every = co waves.waves = fal(e) waves.perspawn = co pojawienie @@ -706,6 +705,7 @@ stat.commandlimit = Limit Jednostek Zarządanych stat.abilities = Umiejętności stat.canboost = Może przyspieszyć stat.flying = Latanie +stat.ammouse = Zużycie Amunicji ability.forcefield = Pole Mocy ability.repairfield = Pole Naprawy @@ -720,6 +720,7 @@ bar.corereq = Wymagany Rdzeń bar.drillspeed = Prędkość wiertła: {0}/s bar.pumpspeed = Prędkość pompy: {0}/s bar.efficiency = Efektywność: {0}% +bar.boost = Przyspieszenie: {0}% bar.powerbalance = Moc: {0} bar.powerstored = Zmagazynowano: {0}/{1} bar.poweramount = Moc: {0} @@ -728,7 +729,6 @@ bar.powerlines = Połączenia: {0}/{1} bar.items = Przedmiotów: {0} bar.capacity = Pojemność: {0} bar.unitcap = {0} {1}/{2} -bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[unit disabled] bar.liquid = Płyn bar.heat = Ciepło bar.power = Prąd @@ -745,6 +745,7 @@ bullet.sapping = [stat]wyczerpujący bullet.homing = [stat]naprowadzający bullet.shock = [stat]piorunowy bullet.frag = [stat]fragmentacyjny +bullet.buildingdamage = [stat]{0}%[lightgray] obrażeń budynkom bullet.knockback = [stat]{0}[lightgray] odrzut bullet.pierce = [stat]{0}[lightgray]x przebicia bullet.infinitepierce = [stat]przebijający @@ -773,6 +774,7 @@ unit.items = przedmioty unit.thousands = tys. unit.millions = mln unit.billions = b +unit.pershot = /szczał category.purpose = Opis category.general = Główne category.power = Prąd @@ -842,6 +844,7 @@ setting.bridgeopacity.name = Przezroczystość mostów setting.playerchat.name = Wyświetlaj czat w grze setting.showweather.name = Pokaż pogodę public.confirm = Czy chcesz ustawić swoją grę jako publiczną?\n[accent]Każdy będzie mógł dołączyć do Twojej gry.\n[lightgray]Można to później zmienić w Ustawienia->Gra->Widoczność Gry Publicznej. +public.confirm.really = Jeśli chcesz grać z przyjaciółmi, użyj [green]Zaproś Przyjaciela[] zamiast [scarlet]Punliczny serwer[]!\nJesteś pewny że chcesz rozpocząć grę [scarlet]publiczą[]? public.beta = Wersje beta gry nie mogą tworzyć publicznych pokoi. uiscale.reset = Skala interfejsu uległa zmianie.\nNaciśnij "OK" by potwierdzić zmiany.\n[scarlet]Cofanie zmian i wyjście z gry za[accent] {0}[] uiscale.cancel = Anuluj i Wyjdź @@ -916,6 +919,7 @@ keybind.toggle_menus.name = Zmiana widoczności menu keybind.chat_history_prev.name = Przewiń wiadomości w górę keybind.chat_history_next.name = Przewiń wiadomości w dół keybind.chat_scroll.name = Przewijaj Wiadomości +keybind.chat_mode.name = Zmień tryb czatu keybind.drop_unit.name = Wyrzucanie przedmiot keybind.zoom_minimap.name = Powiększenie mapy mode.help.title = Opis trybów @@ -932,6 +936,7 @@ mode.custom = Własny Tryb rules.infiniteresources = Nieskończone Zasoby rules.reactorexplosions = Eksplozje Reaktorów +rules.coreincinerates = Rdzeń Spala Przepełnienie rules.schematic = Schematy Są Dozwolone rules.wavetimer = Zegar Fal rules.waves = Fale @@ -964,6 +969,7 @@ rules.explosions = Uszkodzenia Wybuchu Klocka/Jednostki rules.ambientlight = Otaczające Światło rules.weather = Pogoda rules.weather.frequency = Częstotliwość: +rules.weather.always = Zawsze rules.weather.duration = Czas trwania: content.item.name = Przedmioty From c53a6a7c04a8da80f0cd21de4812154ba8e14bcf Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Tue, 19 Jan 2021 14:46:02 -0800 Subject: [PATCH 104/426] hitColor colored beam effects. (#3471) * hitColor colored beam effects. * Same with lasers * fix --- core/src/mindustry/content/Fx.java | 20 +++++++++++++++++++ .../bullet/ContinuousLaserBulletType.java | 2 +- .../entities/bullet/LaserBulletType.java | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index 7edc5d5cc3..b2f21d732d 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -418,6 +418,16 @@ public class Fx{ Fill.circle(e.x + x, e.y + y, e.fout() * 2f); }); }), + + hitLaserBlast = new Effect(12, e -> { + color(e.color); + stroke(e.fout() * 1.5f); + + randLenVectors(e.id, 8, e.finpow() * 17f, e.rotation, 360f, (x, y) -> { + float ang = Mathf.angle(x, y); + lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f); + }); + }), hitLancer = new Effect(12, e -> { color(Color.white); @@ -429,6 +439,16 @@ public class Fx{ }); }), + hitBeam = new Effect(12, e -> { + color(e.color); + stroke(e.fout() * 2f); + + randLenVectors(e.id, 6, e.finpow() * 18f, e.rotation, 360f, (x, y) -> { + float ang = Mathf.angle(x, y); + lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f); + }); + }), + hitMeltdown = new Effect(12, e -> { color(Pal.meltdownHit); stroke(e.fout() * 2f); diff --git a/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java b/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java index 9edcdb0a5c..43113a0a99 100644 --- a/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java +++ b/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java @@ -25,7 +25,7 @@ public class ContinuousLaserBulletType extends BulletType{ public ContinuousLaserBulletType(float damage){ super(0.001f, damage); - hitEffect = Fx.hitMeltdown; + hitEffect = Fx.hitBeam; despawnEffect = Fx.none; hitSize = 4; drawSize = 420f; diff --git a/core/src/mindustry/entities/bullet/LaserBulletType.java b/core/src/mindustry/entities/bullet/LaserBulletType.java index ab6cd9dce1..1a9a92a139 100644 --- a/core/src/mindustry/entities/bullet/LaserBulletType.java +++ b/core/src/mindustry/entities/bullet/LaserBulletType.java @@ -23,7 +23,8 @@ public class LaserBulletType extends BulletType{ public LaserBulletType(float damage){ super(0.01f, damage); - hitEffect = Fx.hitLancer; + hitEffect = Fx.hitLaserBlast; + hitColor = colors[2]; despawnEffect = Fx.none; shootEffect = Fx.hitLancer; smokeEffect = Fx.none; From 632887ddd23493cbd06028b865f13089a5c3f409 Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Wed, 20 Jan 2021 01:39:09 +0200 Subject: [PATCH 105/426] [Metadata] Android desc = Steam desc (#4370) Features: - Kept the first 2 sentences intact. This means that roughly same text is displayed before clicking 'Read more'. 'Features include:' has been dropped for 'Gameplay Features', for Steam similarity. - Steam-like formatting. I noticed that

doesn't seem to do anything. Despite that, I've seen Gameloft using it. For something bigger, I'd recommend . - Updated blocks count. There's over 130 blocks. I triple checked. - The old description still had 4 unique bosses. RIP. - Steam Workshop & achievements and Android don't mix up. - Checked against the character limit. It has less than 4000. - Only cat-approved text. --- .../android/en-US/full_description.txt | 63 +++++++++++++++---- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 51d9d7b4b3..2a979effdc 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1,14 +1,53 @@ Create elaborate supply chains of conveyor belts to feed ammo into your turrets, produce materials to use for building, and defend your structures from waves of enemies. Play with your friends in cross-platform multiplayer co-op games, or challenge them in team-based PvP matches. -Features include: -- 24 built-in maps -- A campaign, complete with a tech tree and unlockable areas -- 4 powerful wave bosses to defeat -- Energy, liquid and item transportation systems -- 19 different types of drones, mechs and ships -- 120+ technology blocks to master -- 75+ different environmental blocks -- Cross-platform multiplayer via local networks or dedicated servers -- Custom game rules: Change block costs, enemy stats, starting items, wave timing and more -- A powerful editor, with tools to randomly generate ores, terrain, decoration and apply symmetry to maps -- Customizable map wave layouts + +

Gameplay Features

+ +- Use production blocks to create a wide variety of advanced materials +- Defend your structures from waves of enemies +- Play with your friends in cross-platform multiplayer co-op games, or challenge them in team-based PvP matches +- Distribute liquids and fight constant challenges, like outbreaks of fire or enemy flier raids +- Get the most out of your production by supplying optional coolant and lubricant +- Produce a wide variety of units for automatic management of your base or assault on enemy bases + + +

Campaign

+ +- Conquer the planet Serpulo as you advance through 250+ procedurally generated sectors and 16 hand-made maps +- Capture territory and set up factories to produce resources while you play other sectors +- Defend your sectors from periodic invasions +- Coordinate resource distribution between sectors via launch pads +- Research new blocks to fuel progress +- Invite your friends to complete missions together +- 130+ technology blocks to master +- 33 different types of drones, mechs and ships + + +

Gamemodes

+ +- Survival: Build turrets to defend from enemies in tower-defense based gameplay. Survive as long as possible, optionally launching your core to use your collected resources for research. Prepare your base for intermittent attacks from airborne bosses. +- Attack: Build factories for units to destroy the enemy cores, while simultaneously defending your base from waves of enemy units. Create a variety of different types of support and offensive unit to assist you in your goals. Optionally enable an AI that builds defensive structures to an extra challenge. +- PvP: Compete with other players on up to 4 different teams to destroy each other's cores. Create units, or attack other bases directly with your mechs. +- Sandbox: Play around with infinite resources and no enemy threat. Use sandbox-specific item and liquid source blocks to test out designs, and spawn in enemies on request. + + +

Custom Games & Cross-Platform Multiplayer

+ +- 16 built in maps for custom games, in addition to campaign +- Play co-op, PvP or sandbox +- Join a public dedicated server, or invite friends to your own private session +- Customizable game rules: Change block costs, enemy stats, starting items, wave timing and more +- Mix & match gamemodes: Combine PvP and PvE gamemodes together + + +

Custom Map Editor

+ +- Paint terrain with an editor UI +- Edit and preview structures in-game +- Configurable tool modes: Change how each tool functions +- Powerful map generation system, with many different types of filters for procedural manipulation of terrain +- Apply noise, distortion, smoothing, erosion, symmetry, ore generation and random terrain to your maps +- Randomize and configure ore generation, as well as placement of river and resource tiles +- Configure enemy wave layouts +- Customize base map rules +- Use 80+ different environmental blocks From e816f6110de6ec9638b5a6be8a9710bdc49f5f4d Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Wed, 20 Jan 2021 01:50:49 +0200 Subject: [PATCH 106/426] [Fastlane][RO] Steam Translation (#3958) * Create short-description.txt * Add files via upload * incomplete * Update achievements.vdf * finished * import commit 032 b254 * [Steam] Update counts Co-authored-by: Anuken --- .../android/en-US/full_description.txt | 1 - .../metadata/steam/english/description.txt | 4 +- .../metadata/steam/romanian/achievements.vdf | 115 ++++++++++++++++++ .../metadata/steam/romanian/description.txt | 65 ++++++++++ .../steam/romanian/short-description.txt | 1 + 5 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 fastlane/metadata/steam/romanian/achievements.vdf create mode 100644 fastlane/metadata/steam/romanian/description.txt create mode 100644 fastlane/metadata/steam/romanian/short-description.txt diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 2a979effdc..e4dcd33cc2 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1,6 +1,5 @@ Create elaborate supply chains of conveyor belts to feed ammo into your turrets, produce materials to use for building, and defend your structures from waves of enemies. Play with your friends in cross-platform multiplayer co-op games, or challenge them in team-based PvP matches. -

Gameplay Features

- Use production blocks to create a wide variety of advanced materials diff --git a/fastlane/metadata/steam/english/description.txt b/fastlane/metadata/steam/english/description.txt index 9f5ea15047..3192f255cb 100644 --- a/fastlane/metadata/steam/english/description.txt +++ b/fastlane/metadata/steam/english/description.txt @@ -23,7 +23,7 @@ [*] Coordinate resource distribution between sectors via launch pads [*] Research new blocks to fuel progress [*] Invite your friends to complete missions together -[*] 120+ technology blocks to master +[*] 130+ technology blocks to master [*] 33 different types of drones, mechs and ships [*] 50+ achievements to complete [/list] @@ -42,7 +42,7 @@ [h2]Custom Games & Cross-Platform Multiplayer[/h2] [list] -[*] 16 built in maps for custom games, in addition to campaign +[*] 18 built in maps for custom games, in addition to campaign [*] Play co-op, PvP or sandbox [*] Join a public dedicated server, or invite friends to your own private session [*] Customizable game rules: Change block costs, enemy stats, starting items, wave timing and more diff --git a/fastlane/metadata/steam/romanian/achievements.vdf b/fastlane/metadata/steam/romanian/achievements.vdf new file mode 100644 index 0000000000..375daf425c --- /dev/null +++ b/fastlane/metadata/steam/romanian/achievements.vdf @@ -0,0 +1,115 @@ +"lang" +{ + "Language" "romanian" + "Tokens" + { + "NEW_ACHIEVEMENT_20_1_NAME" "Fier Vechi" + "NEW_ACHIEVEMENT_20_1_DESC" "Distruge 1000 unități inamice." + "NEW_ACHIEVEMENT_20_2_NAME" "Curățenie" + "NEW_ACHIEVEMENT_20_2_DESC" "Distruge 100,000 unități inamice." + "NEW_ACHIEVEMENT_20_5_NAME" "Livrând la Nesfârșit" + "NEW_ACHIEVEMENT_20_5_DESC" "Lansează 100,000 materiale în total." + "NEW_ACHIEVEMENT_20_6_NAME" "Cuceritor" + "NEW_ACHIEVEMENT_20_6_DESC" "Câștigă 10 jocuri în modul atac." + "NEW_ACHIEVEMENT_20_7_NAME" "Campion" + "NEW_ACHIEVEMENT_20_7_DESC" "Câștigă 10 jocuri PvP multiplayer." + "NEW_ACHIEVEMENT_20_8_NAME" "Blitz" + "NEW_ACHIEVEMENT_20_8_DESC" "Distruge nucleul inamic dintr-o zonă de atac în 5 sau mai puține valuri." + "NEW_ACHIEVEMENT_20_9_NAME" "Ploaie de Nuclee" + "NEW_ACHIEVEMENT_20_9_DESC" "Lansează nuclee de 30 de ori." + "NEW_ACHIEVEMENT_20_10_NAME" "Tenace" + "NEW_ACHIEVEMENT_20_10_DESC" "Supraviețuiește 100 de valuri." + "NEW_ACHIEVEMENT_20_12_NAME" "Cercetător" + "NEW_ACHIEVEMENT_20_12_DESC" "Cercetează totul." + "NEW_ACHIEVEMENT_20_14_NAME" "Scurtcircuit" + "NEW_ACHIEVEMENT_20_14_DESC" "Lovește un inamic ud cu electricitate." + "NEW_ACHIEVEMENT_20_15_NAME" "Reflexie" + "NEW_ACHIEVEMENT_20_15_DESC" "Distruge o unitate cu propriul glonț reflectat." + "NEW_ACHIEVEMENT_20_17_NAME" "O greșeală Gravă" + "NEW_ACHIEVEMENT_20_17_DESC" "Cercetează Routerul." + "NEW_ACHIEVEMENT_20_18_NAME" "Crează" + "NEW_ACHIEVEMENT_20_18_DESC" "Construiește 10,000 de blocuri." + "NEW_ACHIEVEMENT_20_19_NAME" "Rade" + "NEW_ACHIEVEMENT_20_19_DESC" "Distruge 1,000 blocuri inamice." + "NEW_ACHIEVEMENT_20_20_NAME" "Un Dezastru Spectaculos" + "NEW_ACHIEVEMENT_20_20_DESC" "Cauzează explozia unui Reactor de Toriu supraîncălzit." + "NEW_ACHIEVEMENT_20_21_NAME" "Geograf" + "NEW_ACHIEVEMENT_20_21_DESC" "Crează 10 noi hărți." + "NEW_ACHIEVEMENT_20_22_NAME" "Browser" + "NEW_ACHIEVEMENT_20_22_DESC" "Descarcă o hartă de pe Workshop." + "NEW_ACHIEVEMENT_20_23_NAME" "Creator" + "NEW_ACHIEVEMENT_20_23_DESC" "Publică o hartă pe Workshop." + "NEW_ACHIEVEMENT_20_24_NAME" "Ucigaș" + "NEW_ACHIEVEMENT_20_24_DESC" "Distruge un gardian." + "NEW_ACHIEVEMENT_20_25_NAME" "Explorator" + "NEW_ACHIEVEMENT_20_25_DESC" "Deblochează toate zonele din campanie." + "NEW_ACHIEVEMENT_20_29_NAME" "Materia II" + "NEW_ACHIEVEMENT_20_29_DESC" "Deblozhează Toriul." + "NEW_ACHIEVEMENT_20_31_NAME" "Materia I" + "NEW_ACHIEVEMENT_20_31_DESC" "Deblochează Titaniul." + "NEW_ACHIEVEMENT_21_0_NAME" "Kamikaze" + "NEW_ACHIEVEMENT_21_0_DESC" "Controlează o unitate plină cu materiale explozive și mori." + "NEW_ACHIEVEMENT_21_1_NAME" "Începe" + "NEW_ACHIEVEMENT_21_1_DESC" "Construiește o fabrică de unități de artilerie." + "NEW_ACHIEVEMENT_21_2_NAME" "Asalt Direct" + "NEW_ACHIEVEMENT_21_2_DESC" "Trimite comanda Atac unităților aliate folosind centrul de comandă." + "NEW_ACHIEVEMENT_21_3_NAME" "Armate" + "NEW_ACHIEVEMENT_21_3_DESC" "100 unități active deodată." + "NEW_ACHIEVEMENT_21_4_NAME" "Stoluri" + "NEW_ACHIEVEMENT_21_4_DESC" "10 unități Poly active deodată." + "NEW_ACHIEVEMENT_21_5_NAME" "Robotician" + "NEW_ACHIEVEMENT_21_5_DESC" "Construiește fiecare tip de unitate." + "NEW_ACHIEVEMENT_21_6_NAME" "Legiuni" + "NEW_ACHIEVEMENT_21_6_DESC" "Construiește 1000 uunități în total." + "NEW_ACHIEVEMENT_21_9_NAME" "Trebuia să Asculți" + "NEW_ACHIEVEMENT_21_9_DESC" "Mori în zona de lansare a inamicului." + "NEW_ACHIEVEMENT_21_10_NAME" "Există Unități Navale pt Asta" + "NEW_ACHIEVEMENT_21_10_DESC" "Îneacă-te." + "NEW_ACHIEVEMENT_21_11_NAME" "Colector" + "NEW_ACHIEVEMENT_21_11_DESC" "Umple nucleul la capacitate maximă cu toate tipurile de materiale." + "NEW_ACHIEVEMENT_21_12_NAME" "Mulțime" + "NEW_ACHIEVEMENT_21_12_DESC" "Găzduieș e un server cu 10 jucători." + "NEW_ACHIEVEMENT_21_13_NAME" "Invulnerabil" + "NEW_ACHIEVEMENT_21_13_DESC" "Construiește arme Meltdown, Spectre și Foreshadow." + "NEW_ACHIEVEMENT_21_14_NAME" "Decolare" + "NEW_ACHIEVEMENT_21_14_DESC" "Folosește Platforma de Lansare." + "NEW_ACHIEVEMENT_21_16_NAME" "Erezie" + "NEW_ACHIEVEMENT_21_16_DESC" "Construieste 2 routere unul lângă altul." + "NEW_ACHIEVEMENT_21_17_NAME" "Gardianul Singuratic" + "NEW_ACHIEVEMENT_21_17_DESC" "0 valuri fără să fi construit blocuri." + "NEW_ACHIEVEMENT_21_18_NAME" "Incinerare" + "NEW_ACHIEVEMENT_21_18_DESC" "Folosește Piratită în orice armă." + "NEW_ACHIEVEMENT_21_19_NAME" "Eficiență" + "NEW_ACHIEVEMENT_21_19_DESC" "Răcește o armă cu apă sau criofluid." + "NEW_ACHIEVEMENT_21_20_NAME" "Modul Classic" + "NEW_ACHIEVEMENT_21_20_DESC" "Activează pixelarea." + "NEW_ACHIEVEMENT_21_21_NAME" "Savant" + "NEW_ACHIEVEMENT_21_21_DESC" "Descide Wikiul din joc." + "NEW_ACHIEVEMENT_21_22_NAME" "Avans" + "NEW_ACHIEVEMENT_21_22_DESC" "Lansează într-o zonă cu peste 10,000 de materiale configurate." + "NEW_ACHIEVEMENT_21_23_NAME" "Aprinderea" + "NEW_ACHIEVEMENT_21_23_DESC" "Pornește un Reactor de Impact." + "NEW_ACHIEVEMENT_21_24_NAME" "Accelerare" + "NEW_ACHIEVEMENT_21_24_DESC" "Activează Acceleratorul Interplanetar." + "NEW_ACHIEVEMENT_21_25_NAME" "Spirala" + "NEW_ACHIEVEMENT_21_25_DESC" "Se învârte și se învârte..." + "NEW_ACHIEVEMENT_21_26_NAME" "Ascensiune" + "NEW_ACHIEVEMENT_21_26_DESC" "Construiește o unitate de Nivelul 5." + "NEW_ACHIEVEMENT_21_27_NAME" "Arhitect" + "NEW_ACHIEVEMENT_21_27_DESC" "Crează 20 de scheme." + "NEW_ACHIEVEMENT_21_28_NAME" "La Scară Globală" + "NEW_ACHIEVEMENT_21_28_DESC" "Capturează fiecare sector de pe Serpulo." + "NEW_ACHIEVEMENT_21_29_NAME" "Transport Aerian" + "NEW_ACHIEVEMENT_21_29_DESC" "Ridică o unitate de Nivel 5 cu un transportator Oct." + "NEW_ACHIEVEMENT_21_30_NAME" "Forma Supremă" + "NEW_ACHIEVEMENT_21_30_DESC" "Alătură-te lor." + "NEW_ACHIEVEMENT_21_31_NAME" "Producție I" + "NEW_ACHIEVEMENT_21_31_DESC" "Produ cel puțin 5,000 de materiale/min în total în campanie." + "NEW_ACHIEVEMENT_26_0_NAME" "Producție II" + "NEW_ACHIEVEMENT_26_0_DESC" "Produ cel puțin 50,000 items/min de materiale/min în total în campanie." + "NEW_ACHIEVEMENT_26_1_NAME" "Victorie Asigurată" + "NEW_ACHIEVEMENT_26_1_DESC" "Capturează un sector în timp ce joci în alt sector." + "NEW_ACHIEVEMENT_26_2_NAME" "Micul Imperiu" + "NEW_ACHIEVEMENT_26_2_DESC" "Controlează 10 sectoare deodată." + } +} diff --git a/fastlane/metadata/steam/romanian/description.txt b/fastlane/metadata/steam/romanian/description.txt new file mode 100644 index 0000000000..8575fee3f9 --- /dev/null +++ b/fastlane/metadata/steam/romanian/description.txt @@ -0,0 +1,65 @@ +[img]{STEAM_APP_IMAGE}/extras/ezgif-4-0e70c282f775.gif[/img] + +[h2]Gameplay[/h2] + +[list] +[*] Create elaborate supply chains of conveyor belts to feed ammo into your turrets and produce materials to use for building +[*] Use production blocks to create a wide variety of advanced materials +[*] Defend your structures from waves of enemies +[*] Play with your friends in cross-platform multiplayer co-op games, or challenge them in team-based PvP matches +[*] Distribute liquids and fight constant challenges, like outbreaks of fire or enemy flier raids +[*] Get the most out of your production by supplying optional coolant and lubricant +[*] Produce a wide variety of units for automatic management of your base or assault on enemy bases +[/list] + +[img]{STEAM_APP_IMAGE}/extras/ezgif-1-8679abe089cd.gif[/img] + +[h2]Campaign[/h2] + +[list] +[*] Conquer the planet Serpulo as you advance through 250+ procedurally generated sectors and 16 hand-made maps +[*] Capture territory and set up factories to produce resources while you play other sectors +[*] Defend your sectors from periodic invasions +[*] Coordinate resource distribution between sectors via launch pads +[*] Research new blocks to fuel progress +[*] Invite your friends to complete missions together +[*] 120+ technology blocks to master +[*] 33 different types of drones, mechs and ships +[*] 50+ achievements to complete +[/list] + +[h2][h2]Gamemodes[/h2][/h2] + +[list] +[*] [b]Survival[/b]: Build turrets to defend from enemies in tower-defense based gameplay. Survive as long as possible, optionally launching your core to use your collected resources for research. Prepare your base for intermittent attacks from airborne bosses. +[*] [b]Attack[/b]: Build factories for units to destroy the enemy cores, while simultaneously defending your base from waves of enemy units. Create a variety of different types of support and offensive unit to assist you in your goals. Optionally enable an AI that builds defensive structures to an extra challenge. +[*] [b]PvP[/b]: Compete with other players on up to 4 different teams to destroy each other's cores. Create units, or attack other bases directly with your mechs. +[*] [b]Sandbox[/b]: Play around with infinite resources and no enemy threat. Use sandbox-specific item and liquid source blocks to test out designs, and spawn in enemies on request. +[/list] + +[img]{STEAM_APP_IMAGE}/extras/2020-11-30_10-46-02.gif[/img] + +[h2]Custom Games & Cross-Platform Multiplayer[/h2] + +[list] +[*] 16 built in maps for custom games, in addition to campaign +[*] Play co-op, PvP or sandbox +[*] Join a public dedicated server, or invite friends to your own private session +[*] Customizable game rules: Change block costs, enemy stats, starting items, wave timing and more +[*] Mix & match gamemodes: Combine PvP and PvE gamemodes together +[/list] + +[h2]Custom Map Editor[/h2] + +[list] +[*] Paint terrain with an editor UI +[*] Edit and preview structures in-game +[*] Configurable tool modes: Change how each tool functions +[*] Powerful map generation system, with many different types of filters for procedural manipulation of terrain +[*] Apply noise, distortion, smoothing, erosion, symmetry, ore generation and random terrain to your maps +[*] Randomize and configure ore generation, as well as placement of river and resource tiles +[*] Configure enemy wave layouts +[*] Share exported maps on the Steam Workshop +[*] Customize base map rules +[*] Use 80+ different environmental blocks +[/list] \ No newline at end of file diff --git a/fastlane/metadata/steam/romanian/short-description.txt b/fastlane/metadata/steam/romanian/short-description.txt new file mode 100644 index 0000000000..1d5eae544e --- /dev/null +++ b/fastlane/metadata/steam/romanian/short-description.txt @@ -0,0 +1 @@ +An open-ended tower-defense game with a focus on resource management. From 18fe2a1737c3e030307662dcae9079708311991c Mon Sep 17 00:00:00 2001 From: end <72604018+laok233@users.noreply.github.com> Date: Wed, 20 Jan 2021 00:52:09 +0100 Subject: [PATCH 107/426] Update achievements.vdf (#4358) --- .../metadata/steam/italian/achievements.vdf | 68 ++++++++++--------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/fastlane/metadata/steam/italian/achievements.vdf b/fastlane/metadata/steam/italian/achievements.vdf index dc2a1f78d3..931c91e464 100644 --- a/fastlane/metadata/steam/italian/achievements.vdf +++ b/fastlane/metadata/steam/italian/achievements.vdf @@ -3,14 +3,10 @@ "Language" "italian" "Tokens" { - "NEW_ACHIEVEMENT_20_0_NAME" "Utente abilitato" - "NEW_ACHIEVEMENT_20_0_DESC" "Completa il tutorial." "NEW_ACHIEVEMENT_20_1_NAME" "Attaccabrighe" "NEW_ACHIEVEMENT_20_1_DESC" "Distruggi 1000 unità nemiche." "NEW_ACHIEVEMENT_20_2_NAME" "Epurazione" "NEW_ACHIEVEMENT_20_2_DESC" "Distruggi 100,000 unità nemiche." - "NEW_ACHIEVEMENT_20_3_NAME" "Trasporto Atmosferico" - "NEW_ACHIEVEMENT_20_3_DESC" "Lancia 10,000 oggetti." "NEW_ACHIEVEMENT_20_5_NAME" "Spedizioni senza fine" "NEW_ACHIEVEMENT_20_5_DESC" "Lancia 1,000,000 di oggetti." "NEW_ACHIEVEMENT_20_6_NAME" "Conquistatore" @@ -20,19 +16,15 @@ "NEW_ACHIEVEMENT_20_8_NAME" "Blitz" "NEW_ACHIEVEMENT_20_8_DESC" "Distruggi il nucleo nemico in una zona d'attacco in 5 ondate o meno." "NEW_ACHIEVEMENT_20_9_NAME" "Pioggia di Nuclei" - "NEW_ACHIEVEMENT_20_9_DESC" "Lancia il tuo nucleo in una zona 30 volte" + "NEW_ACHIEVEMENT_20_9_DESC" "Lancia il tuo nucleo 30 volte" "NEW_ACHIEVEMENT_20_10_NAME" "Tenace" "NEW_ACHIEVEMENT_20_10_DESC" "Sopravvivi a 100 ondate." - "NEW_ACHIEVEMENT_20_11_NAME" "Imbattuto" - "NEW_ACHIEVEMENT_20_11_DESC" "Sopravvivi a 500 ondate." "NEW_ACHIEVEMENT_20_12_NAME" "Ricercatore" "NEW_ACHIEVEMENT_20_12_DESC" "Ricerca tutto." - "NEW_ACHIEVEMENT_20_13_NAME" "Mutaforma" - "NEW_ACHIEVEMENT_20_13_DESC" "Sblocca tutti i mech e trasformati in ogniuno di essi." "NEW_ACHIEVEMENT_20_14_NAME" "Sovraccarico" "NEW_ACHIEVEMENT_20_14_DESC" "Colpisci un nemico ricoperto d'acqua con l'elettricità." "NEW_ACHIEVEMENT_20_15_NAME" "Deviazione" - "NEW_ACHIEVEMENT_20_15_DESC" "Distruggi un nemico con un suo colpo riflesso." + "NEW_ACHIEVEMENT_20_15_DESC" "Distruggi un'unità con un suo colpo riflesso." "NEW_ACHIEVEMENT_20_17_NAME" "Un grave errore" "NEW_ACHIEVEMENT_20_17_DESC" "Ricerca il distributore." "NEW_ACHIEVEMENT_20_18_NAME" "Costruttore" @@ -51,44 +43,36 @@ "NEW_ACHIEVEMENT_20_24_DESC" "Sconfiggi un boss." "NEW_ACHIEVEMENT_20_25_NAME" "Esploratore" "NEW_ACHIEVEMENT_20_25_DESC" "Sblocca tutte le zone della campagna." - "NEW_ACHIEVEMENT_20_26_NAME" "Completista" - "NEW_ACHIEVEMENT_20_26_DESC" "Sblocca l'equipaggiamento personalizzato in tutte le zone." "NEW_ACHIEVEMENT_20_29_NAME" "Materiale II" "NEW_ACHIEVEMENT_20_29_DESC" "Sblocca il Torio." "NEW_ACHIEVEMENT_20_31_NAME" "Materiale I" "NEW_ACHIEVEMENT_20_31_DESC" "Sblocca il Titanio." "NEW_ACHIEVEMENT_21_0_NAME" "Kamikaze" - "NEW_ACHIEVEMENT_21_0_DESC" "Riempi il tuo mech di esplosivi e muori, creando un esplosione." - "NEW_ACHIEVEMENT_21_1_NAME" "Ha inizio" - "NEW_ACHIEVEMENT_21_1_DESC" "Costruisci una fabbrica di droni pugnalatori." + "NEW_ACHIEVEMENT_21_0_DESC" "Riempi il tuo mech di esplosivi e muori." + "NEW_ACHIEVEMENT_21_1_NAME" "Inizia" + "NEW_ACHIEVEMENT_21_1_DESC" "Costruisci una fabbrica terrestre" "NEW_ACHIEVEMENT_21_2_NAME" "Assalto Diretto" "NEW_ACHIEVEMENT_21_2_DESC" "Emetti un ordine di attacco usando il centro di comando." "NEW_ACHIEVEMENT_21_3_NAME" "Orda" "NEW_ACHIEVEMENT_21_3_DESC" "Possiedi 100 unità attive contemporaneamente." "NEW_ACHIEVEMENT_21_4_NAME" "Stormo" - "NEW_ACHIEVEMENT_21_4_DESC" "Possiedi 10 Droni Fantasma attivi contemporaneamente." - "NEW_ACHIEVEMENT_21_5_NAME" "Esercito Esplosivo" - "NEW_ACHIEVEMENT_21_5_DESC" "Possiedi 50 Strisciatori attivi contemporaneamente." + "NEW_ACHIEVEMENT_21_4_DESC" "Possiedi 10 Costruttori attivi contemporaneamente." + "NEW_ACHIEVEMENT_21_5_NAME" "Roboticista" + "NEW_ACHIEVEMENT_21_5_DESC" "Costruisci tutti tipi di unità." "NEW_ACHIEVEMENT_21_6_NAME" "Legione" - "NEW_ACHIEVEMENT_21_6_DESC" "Costruisci 1000 unità." - "NEW_ACHIEVEMENT_21_7_NAME" "Super" - "NEW_ACHIEVEMENT_21_7_DESC" "Ottieni la valutazione S in una zona qualsiasi." - "NEW_ACHIEVEMENT_21_8_NAME" "Super Super" - "NEW_ACHIEVEMENT_21_8_DESC" "Ottieni la valutazione SS in una zona qualsiasi." + "NEW_ACHIEVEMENT_21_6_DESC" "Costruisci 1000 unità in totale." "NEW_ACHIEVEMENT_21_9_NAME" "Avresti dovusto ascoltare" "NEW_ACHIEVEMENT_21_9_DESC" "Muori nella zona di esclusione dell'atterraggio nemico." - "NEW_ACHIEVEMENT_21_10_NAME" "Premi Shift" - "NEW_ACHIEVEMENT_21_10_DESC" "Annega, in qualche modo." + "NEW_ACHIEVEMENT_21_10_NAME" "Ci sono unità navali per quello" + "NEW_ACHIEVEMENT_21_10_DESC" "Annega." "NEW_ACHIEVEMENT_21_11_NAME" "Collezionista" "NEW_ACHIEVEMENT_21_11_DESC" "Riempi il nucleo alla capacità massima con ogni tipo di materiale." "NEW_ACHIEVEMENT_21_12_NAME" "Folla" "NEW_ACHIEVEMENT_21_12_DESC" "Ospita un server con 10 giocatori." - "NEW_ACHIEVEMENT_21_13_NAME" "Invincibile" - "NEW_ACHIEVEMENT_21_13_DESC" "Costruisci le torrette Fusione e Spettro." + "NEW_ACHIEVEMENT_21_13_NAME" "Invulnerabile" + "NEW_ACHIEVEMENT_21_13_DESC" "Costruisci le torrette Fusione, Spettro e Tenebra." "NEW_ACHIEVEMENT_21_14_NAME" "Ascesa" - "NEW_ACHIEVEMENT_21_14_DESC" "Usa l'ascensore spaziale." - "NEW_ACHIEVEMENT_21_15_NAME" "Autocompiacimento" - "NEW_ACHIEVEMENT_21_15_DESC" "Salta il decollo due volte e perdi il nucleo per mano nemica." + "NEW_ACHIEVEMENT_21_14_DESC" "Usa l'Ascensore Spaziale." "NEW_ACHIEVEMENT_21_16_NAME" "Eresia" "NEW_ACHIEVEMENT_21_16_DESC" "Costruisci due distributori uno affianco all'altro." "NEW_ACHIEVEMENT_21_17_NAME" "Guardiano Solitario" @@ -100,10 +84,32 @@ "NEW_ACHIEVEMENT_21_20_NAME" "Modalità Classica" "NEW_ACHIEVEMENT_21_20_DESC" "Abilita la pixelazione." "NEW_ACHIEVEMENT_21_21_NAME" "Alunno" - "NEW_ACHIEVEMENT_21_21_DESC" "Apri la wiki dal gioco." + "NEW_ACHIEVEMENT_21_21_DESC" "Apri la Wiki dal gioco." "NEW_ACHIEVEMENT_21_22_NAME" "Vantaggio" "NEW_ACHIEVEMENT_21_22_DESC" "Lanciati in una zona con 10,000 o più oggetti nell'equipaggiamento." "NEW_ACHIEVEMENT_21_23_NAME" "Avviamento" "NEW_ACHIEVEMENT_21_23_DESC" "Avvia un Reattore ad Impatto." + "NEW_ACHIEVEMENT_21_24_NAME" "Accelerazione" + "NEW_ACHIEVEMENT_21_24_DESC" "Attiva l'Acceleratore Interplanetario." + "NEW_ACHIEVEMENT_21_25_NAME" "La spirale" + "NEW_ACHIEVEMENT_21_25_DESC" "Gira e rigira va..." + "NEW_ACHIEVEMENT_21_26_NAME" "Escalazione" + "NEW_ACHIEVEMENT_21_26_DESC" "Costruisci un'unità di livello 5" + "NEW_ACHIEVEMENT_21_27_NAME" "Architetto" + "NEW_ACHIEVEMENT_21_27_DESC" "Crea 20 schematiche." + "NEW_ACHIEVEMENT_21_28_NAME" "Dominazione Globale" + "NEW_ACHIEVEMENT_21_28_DESC" "Cattura tutti settori su Serpulo." + "NEW_ACHIEVEMENT_21_29_NAME" "Ascensore Aereo" + "NEW_ACHIEVEMENT_21_29_DESC" "Prendi un'unità T5 sul payload di un Curatore." + "NEW_ACHIEVEMENT_21_30_NAME" "La forma finale" + "NEW_ACHIEVEMENT_21_30_DESC" "Unisci a loro." + "NEW_ACHIEVEMENT_21_31_NAME" "Produzione I" + "NEW_ACHIEVEMENT_21_31_DESC" "Raggiungi 5,000 oggetti/min di produzione totale in campagna." + "NEW_ACHIEVEMENT_26_0_NAME" "Produzione II" + "NEW_ACHIEVEMENT_26_0_DESC" "Raggiungi 50,000 oggetti/min di produzione totale in campaigna." + "NEW_ACHIEVEMENT_26_1_NAME" "Vittoria Assicurata" + "NEW_ACHIEVEMENT_26_1_DESC" "Cattura un settore mentre giochi su un settore differente." + "NEW_ACHIEVEMENT_26_2_NAME" "Piccolo Impero" + "NEW_ACHIEVEMENT_26_2_DESC" "Controlla 10 settori contemporaneamente." } } From 77f31fd86ccfdcc853a6f1b2945a5f93fe14abb3 Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Tue, 19 Jan 2021 16:20:25 -0800 Subject: [PATCH 108/426] Movement Lightning Ability Improvements (#3901) * Movement Lightning Ability Improvements * `Core.atlas.find` Might not always be avalable * Default is null * Fix --- .../abilities/MoveLightningAbility.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/entities/abilities/MoveLightningAbility.java b/core/src/mindustry/entities/abilities/MoveLightningAbility.java index 17d3eaa23a..d03f08b01a 100644 --- a/core/src/mindustry/entities/abilities/MoveLightningAbility.java +++ b/core/src/mindustry/entities/abilities/MoveLightningAbility.java @@ -1,12 +1,15 @@ package mindustry.entities.abilities; +import arc.*; import arc.graphics.*; +import arc.graphics.g2d.*; import arc.math.*; import arc.util.*; import arc.audio.*; import mindustry.content.*; import mindustry.entities.*; import mindustry.gen.*; +import mindustry.graphics.*; public class MoveLightningAbility extends Ability{ //Lightning damage @@ -19,16 +22,32 @@ public class MoveLightningAbility extends Ability{ public float minSpeed = 0.8f, maxSpeed = 1.2f; //Lightning color public Color color = Color.valueOf("a9d8ff"); + //Shifts where the lightning spawns along the Y axis + public float offset = 0f; + //Jittering heat sprite like the shield on v5 Javelin + public String heatRegion = "error"; public Effect shootEffect = Fx.sparkShoot; public Sound shootSound = Sounds.spark; MoveLightningAbility(){} - public MoveLightningAbility(float damage, int length, float chance, float minSpeed, float maxSpeed, Color color){ + public MoveLightningAbility(float damage, int length, float chance, float offset, float minSpeed, float maxSpeed, Color color, String heatRegion){ this.damage = damage; this.length = length; this.chance = chance; + this.offset = offset; + this.minSpeed = minSpeed; + this.maxSpeed = maxSpeed; + this.color = color; + this.heatRegion = heatRegion; + } + + public MoveLightningAbility(float damage, int length, float chance, float offset, float minSpeed, float maxSpeed, Color color){ + this.damage = damage; + this.length = length; + this.chance = chance; + this.offset = offset; this.minSpeed = minSpeed; this.maxSpeed = maxSpeed; this.color = color; @@ -38,9 +57,23 @@ public class MoveLightningAbility extends Ability{ public void update(Unit unit){ float scl = Mathf.clamp((unit.vel().len() - minSpeed) / (maxSpeed - minSpeed)); if(Mathf.chance(Time.delta * chance * scl)){ - shootEffect.at(unit.x, unit.y, unit.rotation, color); - Lightning.create(unit.team, color, damage, unit.x + unit.vel.x, unit.y + unit.vel.y, unit.rotation, length); + float x = unit.x + Angles.trnsx(unit.rotation, offset, 0), y = unit.y + Angles.trnsy(unit.rotation, offset, 0); + shootEffect.at(x, y, unit.rotation, color); + Lightning.create(unit.team, color, damage, x + unit.vel.x, y + unit.vel.y, unit.rotation, length); shootSound.at(unit); } } + + @Override + public void draw(Unit unit){ + float scl = Mathf.clamp((unit.vel().len() - minSpeed) / (maxSpeed - minSpeed)); + TextureRegion region = Core.atlas.find(heatRegion); + if(Core.atlas.isFound(region) && scl > 0.00001f){ + Draw.color(color); + Draw.alpha(scl / 2f); + Draw.blend(Blending.additive); + Draw.rect(region, unit.x + Mathf.range(scl / 2f), unit.y + Mathf.range(scl / 2f), unit.rotation - 90); + Draw.blend(); + } + } } From fa8d43bbc9f9eddaea4b6469e20c5003f3073658 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 19 Jan 2021 19:55:21 -0500 Subject: [PATCH 109/426] Misc cleanup --- core/assets-raw/sprites/units/vanguard-cell.png | Bin 611 -> 0 bytes core/assets-raw/sprites/units/vanguard.png | Bin 1290 -> 0 bytes core/src/mindustry/content/Blocks.java | 1 + core/src/mindustry/content/Bullets.java | 10 +++++----- .../mindustry/entities/bullet/BulletType.java | 3 +-- core/src/mindustry/graphics/OverlayRenderer.java | 2 +- .../world/blocks/experimental/BlockForge.java | 9 +++++++++ 7 files changed, 17 insertions(+), 8 deletions(-) delete mode 100644 core/assets-raw/sprites/units/vanguard-cell.png delete mode 100644 core/assets-raw/sprites/units/vanguard.png diff --git a/core/assets-raw/sprites/units/vanguard-cell.png b/core/assets-raw/sprites/units/vanguard-cell.png deleted file mode 100644 index 4366b2167b0e3e7259edb97f81f1340fbba5a701..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F|M2mv-m%Sl&i}Rib#=~BhWQ>gr+F@`-BXx% zZwv3a-$xR|ri4B!ezd|Gu1BAwpF2%vohNB_d1d7zgN+d{5|%bcUcAz=yhC}_ zvfzCa3L~HHIU1=Q9{GCSpVotO_H8;-I!oCjLC|}Gf|H}D>Xbxfx7B`Kts-xa+x|K1 zyWd5xHAdB-NM`{PZ_#D`f9(5rZ~Zh`I4{V6uVlZ)x#JoaHglU~^?j~=W6>*o;6G2y z%iQ{V5ur*P{6rJ@-l(7#L=Gx;TbpG`_v& z$km`A(E2dFWU}AGzvA;2ZN9OJW1_;$>D~YGRXH9@t1EIcfI#qXSZ}Lud3q<-z1Zf_@!5U{*WWN}Tz}y} zj){RZ@0M>tZQtA?)h=+q;?Vb8y>wMgWAvWJYk%+mKYLH(G)tAE>_f(ceauX*s(tI` RPgn@D*3;F`Wt~$(696WX7n}e9 diff --git a/core/assets-raw/sprites/units/vanguard.png b/core/assets-raw/sprites/units/vanguard.png deleted file mode 100644 index feacbacc6eb7dee74207517f22a3ded34fb94278..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1290 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F^X_+~x z3=A3*YbV-z9Cna78XxScJC!d?pzuV%+$aIj!Yf)L3!PSoMwJ@u{K7rUL`74tuPOWB z!TzJGn!7iz<6GCH@PqNuqgP8_D5?Hiueqh;|M2mv-m%Sl&i}Rib#=~BhWQ>gr+F@`-BXx% zZwv3a-$xR|ri4B!ezd|Gu1BAwpF2%vohNB_d1d7zgN+d{5|%bcUcAz=yhC}_ zvfzCa3L~HHIU1=Q9{GCSpVotO_H8;-I!oCjLC|}Gf|H}D>Xbxfx7B`Kts-xa+x|K1 zyWd5xHAdB-NM`{PZ_#D`f9(5rZ~Zh`I4{V6uVlZ)x#JoaHglU~^?j~=W6>*o;6G2y z%iQ{V5ur*P{7L;x|uXU|@Fiba4#HXnY%K z+kM+Xpf)>bW=QzV2Zvg<1q-SRT%Aspyj)+l&gz}|4|R!f@vGP4pI@?wz16(nR4cde zALb@+?cOlSwP|VTsqqRA*xSCotJ$-B?$j{t2Tk01Kh{4yC;Gy$o{53S?QqcM+xg{u z4DXh0Pd|A(vO&GZe6Q)`?+cVN=IFgpIiS9D!=&#Ylr(mAcnD2+ZrS%@`!DBDtDj0S zOh`>;a0tv{V3==LpYx+osmdb3YVIt{nJiB#*@7 z=R)7Cm#rOK3&P`@TWeOWRsHU1{NSMAr>DZ(Oy}!)2nk%N-+BMtq9XQ?fH_A`eUsXTB_}7B1XBvKH zwY*L$DsDY_c4}5}R$eeCuiN2Y>W#|hw_4u55+kyz;rO4EA|A^6UnA3!45T($$8!Zb zxY}8@iha5?BhY1KX9BColkn4~T}hWcWFkAXR;=$oZF|#HaBb+iiO(lp7P_5Z{^QrT z>c9VQzvpMT@QS;34?|bM?bw^UJ}g~s$}INj$h5c1pB&z1+GZl082?32CHLBrBT|u> zIR;W?_cpF#V)?}9^YUlVgpNygS>6v;-3a6pS;TPgVqrO7;{>jA%e&^PG>Iz2DlUlI zlX~P@%Yp4GsY}ioxOyMhucUv(Lrig6far>K->)m^AK`MfcpJG`_t7mw75+c9A5`+r zNd+WLam*_W*Wz3utMch!eYlA9XGO{M^_?7+fdxz)1JZ8Zm{|S)^;|E51*w;RW*B^UTM{(SggMg8ji3Gd z<{zo0AD8$j-A{jiNAT|w?nze6>%3C7rQXu=<*H*H8XKb0vcx-~Ii}3NBrG|=br^9|#DNhSHo*&k`r2A)&@{BzZrh2cWJVY)k zfubqcV$PqLU;iauTNS!eXO*dQpx(31n`>X~ebB`BgZW7B=52uod8RQiFfe$!`njxg HN@xNA*STXt diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index ed8013c4d2..7bdce7d094 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1838,6 +1838,7 @@ public class Blocks implements ContentList{ shootType = new ContinuousLaserBulletType(70){{ length = 200f; hitEffect = Fx.hitMeltdown; + hitColor = Pal.meltdownHit; drawSize = 420f; incendChance = 0.4f; diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index dbed9cc7ac..2777ca1e2d 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -235,9 +235,9 @@ public class Bullets implements ContentList{ fragExplosive = new FlakBulletType(4f, 5){{ shootEffect = Fx.shootBig; - ammoMultiplier = 4f; - splashDamage = 18f; - splashDamageRadius = 55f; + ammoMultiplier = 5f; + splashDamage = 26f; + splashDamageRadius = 60f; collidesGround = true; status = StatusEffects.blasted; @@ -245,9 +245,9 @@ public class Bullets implements ContentList{ }}; fragSurge = new FlakBulletType(4.5f, 13){{ - ammoMultiplier = 4f; + ammoMultiplier = 5f; splashDamage = 50f; - splashDamageRadius = 40f; + splashDamageRadius = 38f; lightning = 2; lightningLength = 7; shootEffect = Fx.shootBig; diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 318fbd6f04..2844cb22d1 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -277,8 +277,7 @@ public abstract class BulletType extends Content{ } if(weaveMag > 0){ - 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); + b.vel.rotate(Mathf.sin(b.time + Mathf.PI * weaveScale/2f, weaveScale, weaveMag * (Mathf.randomSeed(b.id, 0, 1) == 1 ? -1 : 1)) * Time.delta); } if(trailChance > 0){ diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index fc1ff87726..d811af6fbc 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -90,7 +90,7 @@ public class OverlayRenderer{ } for(int i = 0; i < 4; i++){ - float rot = i * 90f + 45f + (-Time.time / 1.5f) % 360f; + float rot = i * 90f + 45f + (-Time.time) % 360f; float length = select.hitSize() * 1.5f + (unitFade * 2.5f); Draw.rect("select-arrow", select.x + Angles.trnsx(rot, length), select.y + Angles.trnsy(rot, length), length / 1.9f, length / 1.9f, rot - 135f); } diff --git a/core/src/mindustry/world/blocks/experimental/BlockForge.java b/core/src/mindustry/world/blocks/experimental/BlockForge.java index 83f9bc032a..506593db03 100644 --- a/core/src/mindustry/world/blocks/experimental/BlockForge.java +++ b/core/src/mindustry/world/blocks/experimental/BlockForge.java @@ -18,6 +18,7 @@ import mindustry.world.blocks.*; import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.production.*; import mindustry.world.consumers.*; +import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -56,6 +57,14 @@ public class BlockForge extends PayloadAcceptor{ bars.add("progress", (BlockForgeBuild entity) -> new Bar("bar.progress", Pal.ammo, () -> entity.recipe == null ? 0f : (entity.progress / entity.recipe.buildCost))); } + @Override + public void setStats(){ + super.setStats(); + + stats.add(Stat.output, "@x@ ~ @x@", minBlockSize, minBlockSize, maxBlockSize, maxBlockSize); + } + + @Override public void drawRequestRegion(BuildPlan req, Eachable list){ Draw.rect(region, req.drawx(), req.drawy()); From f64cb3ad9af8e46f6b3ca40d3bd32ea08f3bf8dd Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 09:11:32 -0500 Subject: [PATCH 110/426] Fixed #4385 --- core/src/mindustry/content/Blocks.java | 2 +- core/src/mindustry/entities/bullet/BulletType.java | 3 ++- core/src/mindustry/entities/comp/BulletComp.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 7bdce7d094..51dc090787 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1537,7 +1537,7 @@ public class Blocks implements ContentList{ shootSound = Sounds.laser; shootType = new LaserBulletType(140){{ - colors = new Color[]{Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white}; + colors = new Color[]{Pal.lancerLaser.cpy().a(0.4f), Pal.lancerLaser, Color.white}; hitEffect = Fx.hitLancer; despawnEffect = Fx.none; hitSize = 4; diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 2844cb22d1..f83ed10248 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -189,6 +189,7 @@ public abstract class BulletType extends Content{ } public void hit(Bullet b, float x, float y){ + b.hit = true; hitEffect.at(x, y, b.rotation(), hitColor); hitSound.at(x, y, hitSoundPitch, hitSoundVolume); @@ -245,7 +246,7 @@ public abstract class BulletType extends Content{ Effect.shake(despawnShake, despawnShake, b); - if(fragBullet != null || splashDamageRadius > 0 || lightning > 0){ + if(!b.hit && (fragBullet != null || splashDamageRadius > 0 || lightning > 0)){ hit(b); } } diff --git a/core/src/mindustry/entities/comp/BulletComp.java b/core/src/mindustry/entities/comp/BulletComp.java index a51a30dfd7..7f3d42d4e0 100644 --- a/core/src/mindustry/entities/comp/BulletComp.java +++ b/core/src/mindustry/entities/comp/BulletComp.java @@ -30,7 +30,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw Object data; BulletType type; float fdata; - transient boolean absorbed; + transient boolean absorbed, hit; @Override public void getCollisions(Cons consumer){ From d747b1d96a8f9dc143b3f2fafda24a293fd8807f Mon Sep 17 00:00:00 2001 From: rMuchan Date: Wed, 20 Jan 2021 22:18:13 +0800 Subject: [PATCH 111/426] update zh-cn translation (#4244) * update zh-cn translation * update zh-cn translation * add missing item --- core/assets/bundles/bundle_zh_CN.properties | 37 +++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index 4e5074ae4c..d27750e645 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -13,6 +13,7 @@ link.google-play.description = Google Play 页面 link.f-droid.description = F-Droid 页面 link.wiki.description = Mindustry 官方 Wiki link.suggestions.description = 提出新特性的建议 +link.bug.description = 发现了 Bug ?在这里报告 linkfail = 打开链接失败!\n网址已复制到您的剪贴板。 screenshot = 屏幕截图已保存到 {0} screenshot.invalid = 地图太大,可能没有足够的内存用于截图。 @@ -22,7 +23,6 @@ gameover.pvp = [accent] {0}[]队获胜! gameover.waiting = [accent]正在更换下一张地图... highscore = [accent]新纪录! copied = 已复制 -indev.popup = [accent]6.0[]仍在[accent]测试版[].\n[lightgray]这意味着:[]\n[scarlet]- 战役玩法完全没有完成[]\n- 很多内容还没有做完\n- 大多[scarlet]单位AI[]无法正确地运行\n- 单位系统完全没有完成\n- 一切您所看到的内容都可能会移除或调整。\n\n在[accent]Github[]提交错误报告。 indev.notready = 这部分玩法还未开发完成。 indev.campaign = [accent]恭喜!您已经到达战役模式的结尾![]\n\n这是目前内容的全部。 未来的更新中将添加行星际旅行。 @@ -41,6 +41,11 @@ be.ignore = 忽略 be.noupdates = 未发现更新。 be.check = 检测更新 +mod.featured.dialog.title = 模组浏览器 (尚未完成) +mods.browser.selected = 已选模组 +mods.browser.add=安装 +mods.github.open=查看 + schematic = 蓝图 schematic.add = 保存蓝图… schematics = 蓝图 @@ -84,6 +89,7 @@ joingame = 加入游戏 customgame = 自定义游戏 newgame = 新游戏 none = <无> +none.found = [lightgray]<未找到> minimap = 小地图 position = 位置 close = 关闭 @@ -147,8 +153,12 @@ planetmap = 行星地图 launchcore = 发射核心 filename = 文件名: unlocked = 解锁了新内容! +available = 可研究新科技! completed = [accent]己研究 techtree = 科技树 +research.legacy = 发现了 [accent]5.0[] 的研究数据。\n您想要[accent]加载数据[],还是[accent]丢弃数据[]并在新战役中重新研究(建议)? +research.load = 加载 +research.discard = 丢弃 research.list = [lightgray]研究: research = 研究 researched = [lightgray]{0}己研究。 @@ -193,6 +203,7 @@ servers.local = 本地服务器 servers.remote = 远程服务器 servers.global = 全球服务器 +servers.disclaimer=社区服务器[accent]不是[]由开发者拥有或管理。\n\n服务器中可能有其他玩家制作的不适当的内容。 servers.showhidden = 显示隐藏的服务器 server.shown = 显示 server.hidden = 隐藏 @@ -230,6 +241,7 @@ disconnect.timeout = 连接超时。 disconnect.data = 读取服务器数据失败! cantconnect = 无法加入([accent]{0}[])。 connecting = [accent]连接中… +reconnecting = [accent]重新连接中… connecting.data = [accent]加载中… server.port = 端口: server.addressinuse = 地址已在使用! @@ -593,6 +605,11 @@ sector.tarFields.description = 产油区边缘,位于山脉和沙漠之间。 sector.desolateRift.description = 非常危险的区域。这儿的资源丰富但空间很小。敌人十分危险。尽快离开,不要被敌人的攻击间隔太长所愚弄。 sector.nuclearComplex.description = 以前生产和加工钍的设施已变成废墟。\n[lightgray]研究钍及其多种用途。\n\n敌人在这里大量存在,不断消灭入侵者。 sector.fungalPass.description = 介于高山和低矮孢子丛生的土地之间的过渡地带。这里有一个小型的敌方侦察基地。\n侦察它。\n使用尖刀和爬行者单位来摧毁两个核心。 +sector.biomassFacility.description = 孢子的发源地。这里有最初研究和生产孢子的设施。\n研究这里的科技,培养孢子来制造燃料和聚合物。\n\n[lightgray]设施损毁后,孢子散播了出去,原生生态系统无法抵挡这种外来物种。 +sector.windsweptIslands.description = 海岸线之外坐落着这一串群岛。据记载这里曾有生产[accent]塑钢[]的建筑。\n\n抵御敌人的海军,在岛上建立基地,研究这些工厂。 +sector.extractionOutpost.description = 一座遥远的前哨,敌人为了向其他区域发射资源而建立。\n\n跨区域运输技术是征服这个星球不可或缺的技术。摧毁敌人基地,研究发射台。 +sector.impact0078.description = 这里有最初进入这个星系的星际运输船的遗迹。\n\n回收可以利用的资源,研究科技。 +sector.planetaryTerminal.description = 最终目标。\n\n这座滨海基地有一个可以将核心发射到其他行星的建筑,防卫森严。\n\n制造海军单位,尽快消灭敌人,研究发射建筑。 settings.language = 语言 settings.data = 游戏数据 @@ -688,6 +705,7 @@ stat.commandlimit = 指挥上限 stat.abilities = 能力 stat.canboost = 可助推 stat.flying = 可飞行 +stat.ammouse = 弹药消耗 ability.forcefield = 力墙场 ability.repairfield = 修复场 @@ -710,7 +728,6 @@ bar.powerlines = 链接: {0}/{1} bar.items = 物品:{0} bar.capacity = 容量:{0} bar.unitcap = {0} {1}/{2} -bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[已达单位上限] bar.liquid = 液体 bar.heat = 热量 bar.power = 电力 @@ -727,6 +744,7 @@ bullet.sapping = [stat] 削弱 bullet.homing = [stat] 追踪 bullet.shock = [stat] 电击 bullet.frag = [stat] 分裂 +bullet.buildingdamage = [stat]{0}%[lightgray] 对建筑伤害 bullet.knockback = [stat]{0}[lightgray] 击退 bullet.pierce = [stat]{0}[lightgray]x 穿透 bullet.infinitepierce = [stat] 穿透 @@ -755,6 +773,7 @@ unit.items = 物品 unit.thousands = K unit.millions = M unit.billions = B +unit.pershot = /发 category.purpose = 介绍 category.general = 普通 category.power = 能量 @@ -822,7 +841,9 @@ setting.chatopacity.name = 聊天界面不透明度 setting.lasersopacity.name = 能量激光不透明度 setting.bridgeopacity.name = 桥梁不透明度 setting.playerchat.name = 显示玩家聊天气泡 +setting.showweather.name = 显示天气效果 public.confirm = 确定使您的游戏公开可见?\n[accent]其他人将可以加入到您的游戏。\n[lightgray]您之后可以在 设置->游戏->游戏公开可见 更改。 +public.confirm.really = 如果您想与朋友游玩,可以使用[green]邀请朋友[]而不是[scarlet]公开游戏[]!\n您确定要使游戏[scarlet]公开可见[]吗? public.beta = 请注意,测试版的游戏不能公开可见。 uiscale.reset = UI 缩放比例已更改。\n按下“确定”来执行缩放比例的更改。\n[accent]{0}[]秒后[scarlet]将自动退出并还原设置。 uiscale.cancel = 取消并退出 @@ -897,6 +918,7 @@ keybind.toggle_menus.name = 显隐选项 keybind.chat_history_prev.name = 聊天记录向前 keybind.chat_history_next.name = 聊天记录向后 keybind.chat_scroll.name = 聊天记录滚动 +keybind.chat_mode.name = 切换聊天模式 keybind.drop_unit.name = 松开单位 keybind.zoom_minimap.name = 小地图缩放 mode.help.title = 模式说明 @@ -945,6 +967,7 @@ rules.explosions = 建筑/单位爆炸伤害 rules.ambientlight = 环境光 rules.weather = 气候 rules.weather.frequency = 频率: +rules.weather.always = 持续 rules.weather.duration = 时长: content.item.name = 物品 @@ -969,7 +992,6 @@ item.blast-compound.name = 爆炸混合物 item.pyratite.name = 硫 item.metaglass.name = 钢化玻璃 item.scrap.name = 废料 - liquid.water.name = 水 liquid.slag.name = 矿渣 liquid.oil.name = 石油 @@ -1271,11 +1293,15 @@ hint.payloadDrop.mobile = [accent]点住[]一个空的位置将有效载荷丢 hint.waveFire = [accent]波浪[]炮塔加水弹药会自动扑灭附近的火. hint.generator = \uf879 [accent]燃烧发电机[]燃烧煤炭并将电力传输到相邻方块.\n\n用\uf87f [accent]能量节点[]可以扩展电力传输范围. hint.guardian = [accent]Boss[]单位装甲厚重.[accent]铜[]和[accent]铅[]这类较弱的子弹对其[scarlet]作用不佳[].\n\n使用高级别炮塔或使用\uf835 [accent]石墨[]作为\uf861 双管炮及\uf859 齐射炮的弹药来消灭Boss. +hint.coreUpgrade = 核心可以通过[accent]在上面覆盖高等级核心[]进行升级。\n\n在[accent]初代核心[]上放置一个[accent]次代核心[]。确保周围没有障碍物。 +hint.presetLaunch = 灰色的[accent]降落地区[],如[accent]冰冻森林[],可以从任何区域发射,不需要占领附近的区块。\n\n[accent]数字编号的区域[],如这个,是[accent]可选的[]。 +hint.coreIncinerate = 核心存满一种物品后,再进入的同种物品会被[accent]摧毁[]。 +hint.coopCampaign = 游玩[accent]合作战役[]时,当前地图生产的资源也会被送入[accent]你本地的区域[]。\n\n新科技也会同步解锁。 item.copper.description = 用于所有类型的建筑和弹药。 item.copper.details = 铜。在塞普罗上的异常丰富的金属。不经加固,结构会较脆弱。 item.lead.description = 用于液体输送和电气结构。 -item.lead.details = 致密且呈惰性。广泛用于电池中。\n注意:可能对生物生命体有毒。虽说这里还有很多。 +item.lead.details = 致密且呈惰性。广泛用于电池中。\n注意:可能对生物生命体有毒。虽说这里已经没有多少生物了。 item.metaglass.description = 用于液体传输/储存结构。 item.graphite.description = 用于电子元件和炮塔弹药。 item.sand.description = 用于生产其他精炼材料。 @@ -1342,9 +1368,8 @@ block.door-large.description = 可以开关的墙。 block.mender.description = 定期修复附近的区块。\n可使用硅来提高范围和效率。 block.mend-projector.description = 修复其附近的区块。\n可使用相位物来提高射程和效率。 block.overdrive-projector.description = 提高附近建筑物的速度。\n可使用相位物来提高射程和效率。 -block.force-projector.description = 在自身周围创建一个六角形力场,使里面的建筑物和单位免受伤害。\n持续承受高伤害会导致过热,可以使用冷却液降温。相织物可用于增加护盾大小。 +block.force-projector.description = 在自身周围创建一个六角形力场,使里面的建筑物和单位免受伤害。\n持续承受高伤害会导致过热,可以使用冷却液降温。相位物可用于增加护盾大小。 block.shock-mine.description = 对踩到它的敌人释放电弧进行攻击。 -block.thermal-pump.description = 终级液泵。 block.conveyor.description = 将物品向前输送。 block.titanium-conveyor.description = 将物品向前输送。快于初级传送带。 block.plastanium-conveyor.description = 打包物品进行运输。\n在后方输入物品,在前方三个方向输出物品。需要多个装载和卸载点才能达到峰值载量。 From e326e3a27376ee076b4d1a2190635afe8f9ae3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Wed, 20 Jan 2021 22:22:49 +0800 Subject: [PATCH 112/426] Updated zh-TW Steam & Android (#4382) * removed "never", minor updates * steam description * translation moderation * removed weird syntax * Update full_description.txt * Update full_description.txt --- .../android/zh-TW/full_description.txt | 61 ++++++++++++++++--- .../steam/Traditional Chinese/description.txt | 18 +++--- .../metadata/steam/english/description.txt | 2 +- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/fastlane/metadata/android/zh-TW/full_description.txt b/fastlane/metadata/android/zh-TW/full_description.txt index 6a0092cdbf..a9e3f2a0c6 100644 --- a/fastlane/metadata/android/zh-TW/full_description.txt +++ b/fastlane/metadata/android/zh-TW/full_description.txt @@ -1,14 +1,55 @@ 建立精密的輸送帶供應鏈,提供砲塔彈藥,生產建築原料,保護您的建築物並抵禦入侵的敵人。在跨平臺的多人合作遊戲中和朋友一起玩,或在團隊 PvP 比賽中向他們挑戰。 -包含了以下特色: -- 24 張內建地圖 -- 有科技樹與可解鎖區域的戰役 -- 可擊敗 4 波強大的魔王 -- 能源、液體與物品運輸系統 -- 19 種不同類型的無人機、機甲與飛船 -- 研究 120 種以上的科技 -- 75 種以上不同的環境方塊 -- 透過區域網路或專用伺服器遊玩跨平臺多人遊戲 +

基本遊戲內容

+ +- 建造精密的供應系統裝填砲塔和生產建築所需的彈藥或原料。 +- 使用生產建築製作一系列的進階材料。 +- 抵禦敵人一波一波的攻擊。 +- 和朋友一同跨平台玩多人模式,或是邀請進行多人PvP。 +- 輸送液體應對不同的挑戰,像是突發的火災或敵軍空襲。 +- 利用冷卻液或催化劑提升砲塔與生產方塊的最高效率。 +- 生產各式各樣的機械兵器達到基地的自動化或侵襲敵方基地。 + + +

戰役模式

+ +- 探索並征服蕈孢星上250+個地區和16個手作地圖。 +- 佔領領地、建造工廠,在其他地區遊玩仍持續生產物資。 +- 抵禦敵方定時侵略,保衛領地。 +- 運用發射臺分配地區間的資源。 +- 研究新方塊推進進度。 +- 邀請好友一同完成任務。 +- 超過 130 種方塊供玩家使用、探索。 +- 33 種不同類型的無人機、機甲和船艦 +- 50+ 個成就可供解鎖 + + +

遊戲模式

+ +- 生存:建造砲塔來抵禦敵人入侵。生存愈久愈好,選擇發射您的核心並將您採集的資源用來研究新科技。為敵人頭目的到來做好準備。 +- 攻擊:建造工廠並生產部隊來摧毀敵人的核心,同時保護自己的基地不受敵方單位的攻擊。建立各種不同類型的支援與攻擊單位來協助實現您的目標。可選擇啟用自動建築防禦的AI增加難度。 +- 對戰:與最多四個不同團隊的玩家競爭摧毀其他人的核心。建立單位或直接用您的飛船攻擊其他人的基地。 +- 沙盒:在資源無限而且無敵人威脅下盡情遊玩。使用僅在沙盒模式中才有的無限物品與液體來源以測試設計,並根據需要生成敵人。 + + +

自訂遊戲與跨平臺多人遊戲

+ +- 除了戰役以外,還有 18 個內建地圖可用於自訂遊戲 +- 玩合作、PvP 或沙盒模式 +- 加入公開的專用伺服器,或邀請朋友加入您的私人伺服器 - 自訂遊戲規則:變更方塊花費、敵方屬性、起始物品、敵人來襲的間隔時間等 -- 強大的編輯器,有工具可將噪音、變形、平滑、腐蝕、對稱、礦物生成與隨機地形套用到您的地圖上 +- 混搭遊戲模式:結合 PvP 與 PvE 遊戲模式 + + +

自訂地圖編輯器

+ +- 使用編輯器來繪製地圖 +- 在遊戲中編輯並預覽建築 +- 可設定的工具模式:變更每個工具的功能 +- 強大的地圖生成系統,有許多不同類型的過濾器,可用於地形的可程式化處理 +- 將噪音、變形、平滑、腐蝕、對稱、礦物生成與隨機地形套用到您的地圖上 +- 隨機設定礦物生成,並放置河流與資源 - 設定敵人攻擊佈局 +- 在 Steam 工作坊上分享匯出的地圖 +- 自訂地圖的基礎規則 +- 使用 80 種以上不同的環境方塊 diff --git a/fastlane/metadata/steam/Traditional Chinese/description.txt b/fastlane/metadata/steam/Traditional Chinese/description.txt index 5a73494eec..35984e0d27 100644 --- a/fastlane/metadata/steam/Traditional Chinese/description.txt +++ b/fastlane/metadata/steam/Traditional Chinese/description.txt @@ -1,15 +1,15 @@ [img]{STEAM_APP_IMAGE}/extras/ezgif-4-0e70c282f775.gif[/img] -[h2]基本遊戲操作[/h2] +[h2]基本遊戲內容[/h2] [list] -[*] 建造精密的供應系統裝填砲塔和生產建造所需的材料。 -[*] 使用製造方塊製作一系列的進階原料。 +[*] 建造精密的供應系統裝填砲塔和生產建築所需的彈藥或原料。 +[*] 使用生產建築製作一系列的進階材料。 [*] 抵禦敵人一波一波的攻擊。 [*] 和朋友一同跨平台玩多人模式,或是邀請進行多人PvP。 [*] 輸送液體應對不同的挑戰,像是突發的火災或敵軍空襲。 -[*] 利用冷卻液或催化劑達成砲塔與生產方塊的最高效率。 -[*] 生產各式各樣的機械達到基地的自動化或侵襲敵方基地。 +[*] 利用冷卻液或催化劑提升砲塔與生產方塊的最高效率。 +[*] 生產各式各樣的機械兵器達到基地的自動化或侵襲敵方基地。 [/list] [img]{STEAM_APP_IMAGE}/extras/ezgif-1-8679abe089cd.gif[/img] @@ -18,12 +18,12 @@ [list] [*] 探索並征服蕈孢星上250+個地區和16個手作地圖。 -[*] 佔領領地、建造工廠,在其他星區遊玩仍持續生產物資。 +[*] 佔領領地、建造工廠,在其他地區遊玩仍持續生產物資。 [*] 抵禦敵方定時侵略,保衛領地。 [*] 運用發射臺分配地區間的資源。 [*] 研究新方塊推進進度。 [*] 邀請好友一同完成任務。 -[*] 超過 120 種方塊供玩家使用、探索。 +[*] 超過 130 種方塊供玩家使用、探索。 [*] 33 種不同類型的無人機、機甲和船艦 [*] 50+ 個成就可供解鎖 [/list] @@ -33,7 +33,7 @@ [list] [*] [b]生存[/b]:建造砲塔來抵禦敵人入侵。生存愈久愈好,選擇發射您的核心並將您採集的資源用來研究新科技。為敵人頭目的到來做好準備。 [*] [b]攻擊[/b]:建造工廠並生產部隊來摧毀敵人的核心,同時保護自己的基地不受敵方單位的攻擊。建立各種不同類型的支援與攻擊單位來協助實現您的目標。可選擇啟用自動建築防禦的AI增加難度。 -[*] [b]PvP[/b]:與最多四個不同團隊的玩家競爭摧毀其他人的核心。建立單位或直接用您的飛船攻擊其他人的基地。 +[*] [b]對戰[/b]:與最多四個不同團隊的玩家競爭摧毀其他人的核心。建立單位或直接用您的飛船攻擊其他人的基地。 [*] [b]沙盒[/b]:在資源無限而且無敵人威脅下盡情遊玩。使用僅在沙盒模式中才有的無限物品與液體來源以測試設計,並根據需要生成敵人。 [/list] @@ -42,7 +42,7 @@ [h2]自訂遊戲與跨平臺多人遊戲[/h2] [list] -[*] 除了戰役以外,還有 16 個內建地圖可用於自訂遊戲 +[*] 除了戰役以外,還有 18 個內建地圖可用於自訂遊戲 [*] 玩合作、PvP 或沙盒模式 [*] 加入公開的專用伺服器,或邀請朋友加入您的私人伺服器 [*] 自訂遊戲規則:變更方塊花費、敵方屬性、起始物品、敵人來襲的間隔時間等 diff --git a/fastlane/metadata/steam/english/description.txt b/fastlane/metadata/steam/english/description.txt index 3192f255cb..87a40a759e 100644 --- a/fastlane/metadata/steam/english/description.txt +++ b/fastlane/metadata/steam/english/description.txt @@ -28,7 +28,7 @@ [*] 50+ achievements to complete [/list] -[h2][h2]Gamemodes[/h2][/h2] +[h2]Gamemodes[/h2] [list] [*] [b]Survival[/b]: Build turrets to defend from enemies in tower-defense based gameplay. Survive as long as possible, optionally launching your core to use your collected resources for research. Prepare your base for intermittent attacks from airborne bosses. From 481e19b1ec3c3d82d7649e17d2d54e2904490965 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 10:51:01 -0500 Subject: [PATCH 113/426] Balancing to counteract double-splash-damage bug --- core/src/mindustry/content/Bullets.java | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index 2777ca1e2d..2792146ce9 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -155,7 +155,7 @@ public class Bullets implements ContentList{ width = 6f; height = 8f; hitEffect = Fx.flakExplosion; - splashDamage = 27f; + splashDamage = 27f * 1.5f; splashDamageRadius = 15f; }}; @@ -167,7 +167,7 @@ public class Bullets implements ContentList{ width = 6f; height = 8f; hitEffect = Fx.flakExplosion; - splashDamage = 22f; + splashDamage = 22f * 1.5f; splashDamageRadius = 24f; }}; @@ -179,10 +179,10 @@ public class Bullets implements ContentList{ width = 6f; height = 8f; hitEffect = Fx.flakExplosion; - splashDamage = 22f; + splashDamage = 22f * 1.5f; splashDamageRadius = 20f; fragBullet = flakGlassFrag; - fragBullets = 5; + fragBullets = 6; }}; fragGlassFrag = new BasicBulletType(3f, 5, "bullet"){{ @@ -212,19 +212,19 @@ public class Bullets implements ContentList{ width = 6f; height = 8f; hitEffect = Fx.flakExplosion; - splashDamage = 18f; + splashDamage = 18f * 1.5f; splashDamageRadius = 16f; fragBullet = fragGlassFrag; - fragBullets = 3; + fragBullets = 4; explodeRange = 20f; collidesGround = true; }}; fragPlastic = new FlakBulletType(4f, 6){{ splashDamageRadius = 40f; - splashDamage = 25f; + splashDamage = 25f * 1.5f; fragBullet = fragPlasticFrag; - fragBullets = 5; + fragBullets = 6; hitEffect = Fx.plasticExplosion; frontColor = Pal.plastaniumFront; backColor = Pal.plastaniumBack; @@ -236,7 +236,7 @@ public class Bullets implements ContentList{ fragExplosive = new FlakBulletType(4f, 5){{ shootEffect = Fx.shootBig; ammoMultiplier = 5f; - splashDamage = 26f; + splashDamage = 26f * 1.5f; splashDamageRadius = 60f; collidesGround = true; @@ -246,7 +246,7 @@ public class Bullets implements ContentList{ fragSurge = new FlakBulletType(4.5f, 13){{ ammoMultiplier = 5f; - splashDamage = 50f; + splashDamage = 50f * 1.5f; splashDamageRadius = 38f; lightning = 2; lightningLength = 7; @@ -261,7 +261,7 @@ public class Bullets implements ContentList{ shrinkY = 0f; drag = -0.01f; splashDamageRadius = 30f; - splashDamage = 30f; + splashDamage = 30f * 1.5f; ammoMultiplier = 4f; hitEffect = Fx.blastExplosion; despawnEffect = Fx.blastExplosion; @@ -279,7 +279,7 @@ public class Bullets implements ContentList{ drag = -0.01f; homingPower = 0.08f; splashDamageRadius = 20f; - splashDamage = 20f; + splashDamage = 20f * 1.5f; makeFire = true; hitEffect = Fx.blastExplosion; status = StatusEffects.burning; @@ -291,7 +291,7 @@ public class Bullets implements ContentList{ shrinkY = 0f; drag = -0.01f; splashDamageRadius = 25f; - splashDamage = 25f; + splashDamage = 25f * 1.5f; hitEffect = Fx.blastExplosion; despawnEffect = Fx.blastExplosion; lightningDamage = 10; From 770d8506c5022d942e32dfe3108ce586c7ffc6fd Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 12:31:35 -0500 Subject: [PATCH 114/426] MoveLightning ability bullet support --- core/src/mindustry/content/Blocks.java | 2 +- .../abilities/MoveLightningAbility.java | 32 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 51dc090787..4e6719473b 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1312,7 +1312,7 @@ public class Blocks implements ContentList{ }}; waterExtractor = new SolidPump("water-extractor"){{ - requirements(Category.production, with(Items.copper, 25, Items.graphite, 25, Items.lead, 20)); + requirements(Category.production, with(Items.copper, 30, Items.graphite, 30, Items.lead, 30)); result = Liquids.water; pumpAmount = 0.11f; size = 2; diff --git a/core/src/mindustry/entities/abilities/MoveLightningAbility.java b/core/src/mindustry/entities/abilities/MoveLightningAbility.java index d03f08b01a..4cc62b7172 100644 --- a/core/src/mindustry/entities/abilities/MoveLightningAbility.java +++ b/core/src/mindustry/entities/abilities/MoveLightningAbility.java @@ -1,31 +1,35 @@ package mindustry.entities.abilities; import arc.*; +import arc.audio.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; import arc.util.*; -import arc.audio.*; import mindustry.content.*; import mindustry.entities.*; +import mindustry.entities.bullet.*; import mindustry.gen.*; -import mindustry.graphics.*; public class MoveLightningAbility extends Ability{ - //Lightning damage + /** Lightning damage */ public float damage = 35f; - //Chance of firing every tick. Set >= 1 to always fire lightning every tick at max speed. + /** Chance of firing every tick. Set >= 1 to always fire lightning every tick at max speed. */ public float chance = 0.15f; - //Length of the lightning + /** Length of the lightning. <= 0 to disable */ public int length = 12; - //Speeds for when to start lightninging and when to stop getting faster + /** Speeds for when to start lightninging and when to stop getting faster */ public float minSpeed = 0.8f, maxSpeed = 1.2f; - //Lightning color + /** Lightning color */ public Color color = Color.valueOf("a9d8ff"); - //Shifts where the lightning spawns along the Y axis + /** Shifts where the lightning spawns along the Y axis */ public float offset = 0f; - //Jittering heat sprite like the shield on v5 Javelin + /** Jittering heat sprite like the shield on v5 Javelin */ public String heatRegion = "error"; + /** Bullet type that is fired. Can be null */ + public @Nullable BulletType bullet; + /** Bullet angle parameters */ + public float bulletAngle = 0f, bulletSpread = 0f; public Effect shootEffect = Fx.sparkShoot; public Sound shootSound = Sounds.spark; @@ -58,9 +62,17 @@ public class MoveLightningAbility extends Ability{ float scl = Mathf.clamp((unit.vel().len() - minSpeed) / (maxSpeed - minSpeed)); if(Mathf.chance(Time.delta * chance * scl)){ float x = unit.x + Angles.trnsx(unit.rotation, offset, 0), y = unit.y + Angles.trnsy(unit.rotation, offset, 0); + shootEffect.at(x, y, unit.rotation, color); - Lightning.create(unit.team, color, damage, x + unit.vel.x, y + unit.vel.y, unit.rotation, length); shootSound.at(unit); + + if(length > 0){ + Lightning.create(unit.team, color, damage, x + unit.vel.x, y + unit.vel.y, unit.rotation, length); + } + + if(bullet != null){ + bullet.create(unit, unit.team, x, y, unit.rotation + bulletAngle + Mathf.range(bulletSpread)); + } } } From ec73426bbcd4a097cd1cb3b28b4ef4aa98591660 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 13:52:14 -0500 Subject: [PATCH 115/426] Smaller 1x1 block status indicators --- core/src/mindustry/ai/BaseAI.java | 1 - core/src/mindustry/entities/comp/BuildingComp.java | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/ai/BaseAI.java b/core/src/mindustry/ai/BaseAI.java index 6a1e43b172..1a3fa81a80 100644 --- a/core/src/mindustry/ai/BaseAI.java +++ b/core/src/mindustry/ai/BaseAI.java @@ -285,7 +285,6 @@ public class BaseAI{ if(o != null && o.team() == data.team && !(o.block() instanceof Wall)){ any = true; - break; } } diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index f4758c427d..31a7ed8ce0 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -822,14 +822,15 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, public void drawStatus(){ if(block.enableDrawStatus && block.consumes.any()){ - float brcx = tile.drawx() + (block.size * tilesize / 2f) - (tilesize / 2f); - float brcy = tile.drawy() - (block.size * tilesize / 2f) + (tilesize / 2f); + float multiplier = block.size > 1 ? 1 : 0.64f; + float brcx = x + (block.size * tilesize / 2f) - (tilesize * multiplier / 2f); + float brcy = y - (block.size * tilesize / 2f) + (tilesize * multiplier / 2f); Draw.z(Layer.power + 1); Draw.color(Pal.gray); - Fill.square(brcx, brcy, 2.5f, 45); + Fill.square(brcx, brcy, 2.5f * multiplier, 45); Draw.color(status().color); - Fill.square(brcx, brcy, 1.5f, 45); + Fill.square(brcx, brcy, 1.5f * multiplier, 45); Draw.color(); } } From 1f2b331bf6ed1e1804c8129c156af9061775f9e2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 14:48:54 -0500 Subject: [PATCH 116/426] Possible Android mod extension fix --- core/src/mindustry/mod/Mods.java | 2 +- fastlane/metadata/android/en-US/changelogs/29801.txt | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/29801.txt diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 02bea3e464..22910afb1e 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -72,7 +72,7 @@ public class Mods implements Loadable{ /** Imports an external mod file.*/ public void importMod(Fi file) throws IOException{ - Fi dest = modDirectory.child(file.name()); + Fi dest = modDirectory.child(file.name() + (file.extension().isEmpty() ? ".zip" : "")); if(dest.exists()){ throw new IOException("A file with the same name already exists in the mod folder!"); } diff --git a/fastlane/metadata/android/en-US/changelogs/29801.txt b/fastlane/metadata/android/en-US/changelogs/29801.txt new file mode 100644 index 0000000000..945910092b --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29801.txt @@ -0,0 +1,9 @@ +[This is a truncated changelog, see Github for full notes] +As 6.0 is more or less stable now, updates have slowed down significantly. This is likely to be one of the last notable releases before 7.0. + +- Fixed same-line logic comments not parsing +- Fixed mass driver rotating before payload is received +- Fixed bullets dealing splash damage twice upon collision - splash damage of certain bullets has been increased to compensate + + + From 9b6c1252330a5ab1fa55f6f9d9a5df309c5030f3 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 16:38:46 -0500 Subject: [PATCH 117/426] UI.formatAmount for negative numbers --- core/src/mindustry/core/UI.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/core/UI.java b/core/src/mindustry/core/UI.java index 1eddb7b8fc..e22bc6817f 100644 --- a/core/src/mindustry/core/UI.java +++ b/core/src/mindustry/core/UI.java @@ -526,16 +526,15 @@ public class UI implements ApplicationListener, Loadable{ dialog.show(); } - //TODO move? - public static String formatAmount(int number){ - if(number >= 1_000_000_000){ + int mag = Math.abs(number); + if(mag >= 1_000_000_000){ return Strings.fixed(number / 1_000_000_000f, 1) + "[gray]" + Core.bundle.get("unit.billions") + "[]"; - }else if(number >= 1_000_000){ + }else if(mag >= 1_000_000){ return Strings.fixed(number / 1_000_000f, 1) + "[gray]" + Core.bundle.get("unit.millions") + "[]"; - }else if(number >= 10_000){ + }else if(mag >= 10_000){ return number / 1000 + "[gray]" + Core.bundle.get("unit.thousands") + "[]"; - }else if(number >= 1000){ + }else if(mag >= 1000){ return Strings.fixed(number / 1000f, 1) + "[gray]" + Core.bundle.get("unit.thousands") + "[]"; }else{ return number + ""; From 0cc9b0b0a3b7a30ae1dab30d3f194ac04f7152fc Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Jan 2021 16:44:04 -0500 Subject: [PATCH 118/426] Mod version parse fix --- core/src/mindustry/mod/Mods.java | 34 +++----------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 22910afb1e..e73dc85b9c 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -720,11 +720,7 @@ public class Mods implements Loadable{ public boolean isSupported(){ if(isOutdated()) return false; - int major = getMinMajor(), minor = getMinMinor(); - - if(Version.build <= 0) return true; - - return Version.build >= major && Version.revision >= minor; + return Version.isAtLeast(meta.minGameVersion); } /** @return whether this mod is outdated, e.g. not compatible with v6. */ @@ -734,33 +730,9 @@ public class Mods implements Loadable{ } public int getMinMajor(){ - int major = 0; - String ver = meta.minGameVersion == null ? "0" : meta.minGameVersion; - - if(ver.contains(".")){ - String[] split = ver.split("\\."); - if(split.length == 2){ - major = Strings.parseInt(split[0], 0); - } - }else{ - major = Strings.parseInt(ver, 0); - } - - return major; - } - - public int getMinMinor(){ - String ver = meta.minGameVersion == null ? "0" : meta.minGameVersion; - - if(ver.contains(".")){ - String[] split = ver.split("\\."); - if(split.length == 2){ - return Strings.parseInt(split[1], 0); - } - } - - return 0; + int dot = ver.indexOf("."); + return dot != -1 ? Strings.parseInt(ver.substring(0, dot), 0) : Strings.parseInt(ver, 0); } @Override From 75d2b0fb69317ab0197c72fdb137c7d7f1a32f27 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 08:48:36 -0500 Subject: [PATCH 119/426] Fixed #4393 / Fixed #4398 --- core/src/mindustry/core/NetServer.java | 2 +- core/src/mindustry/game/Gamemode.java | 1 - core/src/mindustry/game/Rules.java | 2 -- core/src/mindustry/ui/dialogs/CustomRulesDialog.java | 1 - core/src/mindustry/ui/dialogs/ModsDialog.java | 5 +++-- core/src/mindustry/world/blocks/defense/turrets/Turret.java | 2 +- core/src/mindustry/world/blocks/power/PowerGraph.java | 2 +- core/src/mindustry/world/blocks/power/PowerNode.java | 2 +- 8 files changed, 7 insertions(+), 10 deletions(-) diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 6a0f2f6bdc..da801cc454 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -182,7 +182,7 @@ public class NetServer implements ApplicationListener{ return; } - if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid) || player.ip().equals(con.address))){ + if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid))){ con.kick(KickReason.idInUse); return; } diff --git a/core/src/mindustry/game/Gamemode.java b/core/src/mindustry/game/Gamemode.java index f2bb95130a..e4c0d01c6c 100644 --- a/core/src/mindustry/game/Gamemode.java +++ b/core/src/mindustry/game/Gamemode.java @@ -31,7 +31,6 @@ public enum Gamemode{ rules.buildCostMultiplier = 1f; rules.buildSpeedMultiplier = 1f; rules.unitBuildSpeedMultiplier = 2f; - rules.unitHealthMultiplier = 3f; rules.attackMode = true; }, map -> map.teams.size > 1), editor(true, rules -> { diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index f9d594e83e..420840e7c0 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -46,8 +46,6 @@ public class Rules{ public boolean unitAmmo = false; /** How fast unit pads build units. */ public float unitBuildSpeedMultiplier = 1f; - /** How much health units start with. */ - public float unitHealthMultiplier = 1f; /** How much damage any other units deal. */ public float unitDamageMultiplier = 1f; /** How much health blocks start with. */ diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index 2e6d923063..b150b5fa9f 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -161,7 +161,6 @@ public class CustomRulesDialog extends BaseDialog{ title("@rules.title.unit"); check("@rules.unitammo", b -> rules.unitAmmo = b, () -> rules.unitAmmo); - number("@rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier); number("@rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0.001f, 50f); diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 998b401558..2ab1d7fd3d 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -221,13 +221,13 @@ public class ModsDialog extends BaseDialog{ sel.keyDown(KeyCode.escape, sel::hide); sel.keyDown(KeyCode.back, sel::hide); sel.show(); - }).width(480f).growX().left().fillY(); + }).width(460f).growX().left().fillY(); tablebrow.row(); } }); }; rebuildBrowser[0].run(); - }); + }).get().setScrollingDisabled(true, false); browser.addCloseButton(); browser.show(); }).margin(12f); @@ -241,6 +241,7 @@ public class ModsDialog extends BaseDialog{ if(!mobile){ buttons.button("@mods.openfolder", Icon.link, style, () -> Core.app.openFolder(modDirectory.absolutePath())).margin(margin); } + Styles.clearPartiali }).width(w); cont.row(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index ab320b7863..847ad58f7d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -111,7 +111,7 @@ public class Turret extends ReloadTurret{ super.setStats(); stats.add(Stat.inaccuracy, (int)inaccuracy, StatUnit.degrees); - stats.add(Stat.reload, 60f / reloadTime * (alternate ? 1 : shots), StatUnit.none); + stats.add(Stat.reload, 60f / (reloadTime + 1) * (alternate ? 1 : shots), StatUnit.none); stats.add(Stat.targetsAir, targetAir); stats.add(Stat.targetsGround, targetGround); if(ammoPerShot != 1) stats.add(Stat.ammoUse, ammoPerShot, StatUnit.perShot); diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index 03aa029f19..24873ecb14 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -224,7 +224,7 @@ public class PowerGraph{ lastPowerNeeded = powerNeeded; lastPowerProduced = powerProduced; - lastScaledPowerIn = powerProduced / Time.delta; + lastScaledPowerIn = (powerProduced + energyDelta) / Time.delta; lastScaledPowerOut = powerNeeded / Time.delta; lastCapacity = getTotalBatteryCapacity(); lastPowerStored = getBatteryStored(); diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 9982c1d324..c9f372a314 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -226,7 +226,7 @@ public class PowerNode extends PowerBlock{ for(Point2 point : (Point2[])req.config){ otherReq = null; list.each(other -> { - if((other.x == req.x + point.x && other.y == req.y + point.y) && other != req){ + if((other.x == req.x + point.x && other.y == req.y + point.y) && other != req && other.block != null && other.block.hasPower){ otherReq = other; } }); From d393230add77bc314e8ad2f53b746717a87060f6 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 08:50:25 -0500 Subject: [PATCH 120/426] . --- core/src/mindustry/ui/dialogs/ModsDialog.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 2ab1d7fd3d..a6434690cf 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -241,7 +241,6 @@ public class ModsDialog extends BaseDialog{ if(!mobile){ buttons.button("@mods.openfolder", Icon.link, style, () -> Core.app.openFolder(modDirectory.absolutePath())).margin(margin); } - Styles.clearPartiali }).width(w); cont.row(); From 65f97edbc51a2f2d260afe87a84698dfca33cfd4 Mon Sep 17 00:00:00 2001 From: Sunny Kim <58885089+sk7725@users.noreply.github.com> Date: Thu, 21 Jan 2021 22:51:43 +0900 Subject: [PATCH 121/426] Add search option for mod browser (#4391) * add search option * mods.browser.sortdate * mods.browser * Update bundle_ko.properties * oopsie * clearPartiali * half of my brain cells failed to boot --- core/assets/bundles/bundle.properties | 2 ++ core/assets/bundles/bundle_ko.properties | 2 ++ core/src/mindustry/ui/dialogs/ModsDialog.java | 14 +++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index f1f22de6dc..a71af9f728 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -45,6 +45,8 @@ mod.featured.dialog.title = Mod Browser (WIP) mods.browser.selected = Selected mod mods.browser.add = Install mods.github.open = View +mods.browser.sortdate = Sort by recent +mods.browser.sortstars = Sort by stars schematic = Schematic schematic.add = Save Schematic... diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index cb15a9e49c..aca4318573 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -45,6 +45,8 @@ mod.featured.dialog.title = 모드 탐색 (WIP) mods.browser.selected = 선택된 모드 mods.browser.add = 모드 설치 mods.github.open = 깃허브 사이트 열기 +mods.browser.sortdate = 최근 업데이트 +mods.browser.sortstars = 추천(스타) 수 schematic = 설계도 schematic.add = 설계도 저장하기 diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index a6434690cf..55cb26b629 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -8,6 +8,7 @@ import arc.graphics.*; import arc.graphics.g2d.*; import arc.input.*; import arc.scene.style.*; +import arc.scene.ui.*; import arc.scene.ui.TextButton.*; import arc.struct.*; import arc.util.*; @@ -31,6 +32,7 @@ import static mindustry.Vars.*; public class ModsDialog extends BaseDialog{ private String searchtxt = ""; private @Nullable Seq modList; + private boolean orderDate = true; public ModsDialog(){ super("@mods"); @@ -176,6 +178,10 @@ public class ModsDialog extends BaseDialog{ searchtxt = res; rebuildBrowser[0].run(); }).growX().get(); + table.button(Icon.list, Styles.clearPartiali, 32f, () -> { + orderDate = !orderDate; + rebuildBrowser[0].run(); + }).update(b -> b.getStyle().imageUp = (orderDate? Icon.list : Icon.star)).size(40f).get().addListener(new Tooltip(tip -> tip.label(() -> orderDate? "$mods.browser.sortdate" : "$mods.browser.sortstars").left())); }).fillX().padBottom(4); browser.cont.row(); @@ -186,8 +192,14 @@ public class ModsDialog extends BaseDialog{ tablebrow.clear(); tablebrow.add("@loading"); - getModList(listings -> { + getModList(rlistings -> { tablebrow.clear(); + + Seq listings = rlistings; + if(!orderDate){ + listings = rlistings.copy(); + listings.sort((m1, m2) -> Integer.compare(m2.stars, m1.stars)); + } for(ModListing mod : listings){ if(mod.hasJava || !searchtxt.isEmpty() && !mod.repo.toLowerCase().contains(searchtxt.toLowerCase()) || (Vars.ios && mod.hasScripts)) continue; From 3aee9bddd4ed23ab814e2d931f19555182af3918 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 08:54:14 -0500 Subject: [PATCH 122/426] Cleanup --- core/src/mindustry/ui/dialogs/ModsDialog.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 55cb26b629..6c0669582c 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -181,7 +181,8 @@ public class ModsDialog extends BaseDialog{ table.button(Icon.list, Styles.clearPartiali, 32f, () -> { orderDate = !orderDate; rebuildBrowser[0].run(); - }).update(b -> b.getStyle().imageUp = (orderDate? Icon.list : Icon.star)).size(40f).get().addListener(new Tooltip(tip -> tip.label(() -> orderDate? "$mods.browser.sortdate" : "$mods.browser.sortstars").left())); + }).update(b -> b.getStyle().imageUp = (orderDate ? Icon.list : Icon.star)).size(40f).get() + .addListener(new Tooltip(tip -> tip.label(() -> orderDate ? "@mods.browser.sortdate" : "@mods.browser.sortstars").left())); }).fillX().padBottom(4); browser.cont.row(); @@ -194,11 +195,11 @@ public class ModsDialog extends BaseDialog{ getModList(rlistings -> { tablebrow.clear(); - + Seq listings = rlistings; if(!orderDate){ listings = rlistings.copy(); - listings.sort((m1, m2) -> Integer.compare(m2.stars, m1.stars)); + listings.sortComparing(m1 -> -m1.stars); } for(ModListing mod : listings){ From 56b87a21418fd3490d6742de871bdd07058b9883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=82=A4=EC=97=90=EB=A5=B4?= <44261958+Kieaer@users.noreply.github.com> Date: Thu, 21 Jan 2021 23:13:07 +0900 Subject: [PATCH 123/426] Add kr server (#4378) * Add kr server * Update servers_v6.json Co-authored-by: Blockzilla101 <48705529+Blockzilla101@users.noreply.github.com> Co-authored-by: Blockzilla101 <48705529+Blockzilla101@users.noreply.github.com> --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index 173aba03e7..5959364a9d 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -62,5 +62,9 @@ { "name": "Minigames", "address": ["shizashizashiza.ml"] + }, + { + "name": "Korea", + "address": ["mindustry.kr"] } ] From 1fb608220fecf48437bb5c77311d303bc6855017 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Thu, 21 Jan 2021 15:30:25 +0100 Subject: [PATCH 124/426] Make impact reactor warmup sensable as heat (#4399) * Make impact reactor warmup sensable as heat * Update ImpactReactor.java --- core/src/mindustry/world/blocks/power/ImpactReactor.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index 22c95a9089..7ecffccd1c 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -12,6 +12,7 @@ import mindustry.entities.*; import mindustry.game.EventType.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.logic.*; import mindustry.ui.*; import mindustry.world.meta.*; @@ -121,6 +122,12 @@ public class ImpactReactor extends PowerGenerator{ public void drawLight(){ Drawf.light(team, x, y, (110f + Mathf.absin(5, 5f)) * warmup, Tmp.c1.set(plasma2).lerp(plasma1, Mathf.absin(7f, 0.2f)), 0.8f * warmup); } + + @Override + public double sense(LAccess sensor){ + if(sensor == LAccess.heat) return warmup; + return super.sense(sensor); + } @Override public void onDestroyed(){ From 988791f18df3561fe758029617a27990707e8492 Mon Sep 17 00:00:00 2001 From: genNAowl <68400583+genNAowl@users.noreply.github.com> Date: Thu, 21 Jan 2021 06:30:36 -0800 Subject: [PATCH 125/426] Let Logic set (and read) Illuminator Color (#4374) * illluminator color logic control * remove sense Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com> --- core/src/mindustry/logic/LAccess.java | 3 ++- core/src/mindustry/world/blocks/power/LightBlock.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index 0daf9ae83f..0c0597c6a1 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -44,7 +44,8 @@ public enum LAccess{ enabled("to"), //"to" is standard for single parameter access shoot("x", "y", "shoot"), shootp(true, "unit", "shoot"), - configure(true, 30, "to"); + configure(true, 30, "to"), + color("r", "g", "b"); public final String[] params; public final boolean isObj; diff --git a/core/src/mindustry/world/blocks/power/LightBlock.java b/core/src/mindustry/world/blocks/power/LightBlock.java index 6d55d0ac09..8f035689b9 100644 --- a/core/src/mindustry/world/blocks/power/LightBlock.java +++ b/core/src/mindustry/world/blocks/power/LightBlock.java @@ -9,6 +9,7 @@ import arc.util.io.*; import mindustry.annotations.Annotations.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.logic.*; import mindustry.world.*; import static mindustry.Vars.*; @@ -32,6 +33,15 @@ public class LightBlock extends Block{ public int color = Pal.accent.rgba(); public float smoothTime = 1f; + @Override + public void control(LAccess type, double p1, double p2, double p3, double p4){ + if(type == LAccess.color){ + color = Color.rgba8888((float)p1, (float)p2, (float)p3, 1f); + } + + super.control(type, p1, p2, p3, p4); + } + @Override public void draw(){ super.draw(); From 613b5a7703c1928c683077f00eee853b57b740bc Mon Sep 17 00:00:00 2001 From: Nikopol <53965568+KirillcraftEX@users.noreply.github.com> Date: Thu, 21 Jan 2021 19:54:24 +0400 Subject: [PATCH 126/426] Update servers_v6.json (#4401) --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index 5959364a9d..fcc68297ac 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -66,5 +66,9 @@ { "name": "Korea", "address": ["mindustry.kr"] + }, + { + "name": "NikoCHIO", + "address": ["nikochio.ddns.net"] } ] From a73165353fba19d3bd366df982433d4a939db748 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 14:45:43 -0500 Subject: [PATCH 127/426] Fixed #4402 --- core/src/mindustry/world/blocks/power/PowerNode.java | 9 ++++++--- fastlane/metadata/android/en-US/changelogs/29804.txt | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/29804.txt diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index c9f372a314..0457d16f79 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -221,12 +221,15 @@ public class PowerNode extends PowerBlock{ @Override public void drawRequestConfigTop(BuildPlan req, Eachable list){ - if(req.config instanceof Point2[]){ + if(req.config instanceof Point2[] ps){ setupColor(1f); - for(Point2 point : (Point2[])req.config){ + for(Point2 point : ps){ + int px = req.x + point.x, py = req.y + point.y; otherReq = null; list.each(other -> { - if((other.x == req.x + point.x && other.y == req.y + point.y) && other != req && other.block != null && other.block.hasPower){ + if(other.block != null + && (px >= other.x - ((other.block.size-1)/2) && py >= other.y - ((other.block.size-1)/2) && px <= other.x + other.block.size/2 && py <= other.y + other.block.size/2) + && other != req && other.block.hasPower){ otherReq = other; } }); diff --git a/fastlane/metadata/android/en-US/changelogs/29804.txt b/fastlane/metadata/android/en-US/changelogs/29804.txt new file mode 100644 index 0000000000..ef9e5b2b4f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29804.txt @@ -0,0 +1,6 @@ +[This is a truncated changelog, see Github for full notes] +- Fixed negative numbers not displaying properly in power nodes +- Fixed mod minVersion parsing +- Fixed mods disappearing after import [Android] +- Disabled duplicate IP prevention system +- Added mod browser sort order button From 027d080c55bb77204e049bec7421c582e626ecd0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 16:10:16 -0500 Subject: [PATCH 128/426] Fixed #4403 --- core/src/mindustry/world/consumers/ConsumeLiquid.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/world/consumers/ConsumeLiquid.java b/core/src/mindustry/world/consumers/ConsumeLiquid.java index 0834935198..9a0f637ecd 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquid.java @@ -41,7 +41,7 @@ public class ConsumeLiquid extends ConsumeLiquidBase{ @Override public boolean valid(Building entity){ - return entity != null && entity.liquids != null && entity.liquids.get(liquid) >= use(entity); + return entity != null && entity.liquids != null && entity.liquids.get(liquid) >= amount * entity.edelta(); } @Override From 457514a2c8099cab7f29b95bbdc6bcdbd1d6fd40 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 21:21:02 -0500 Subject: [PATCH 129/426] Fixed #4407 --- .../mindustry/entities/comp/CommanderComp.java | 1 + core/src/mindustry/logic/LAssembler.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/mindustry/entities/comp/CommanderComp.java b/core/src/mindustry/entities/comp/CommanderComp.java index 0ce8d60d10..2842e5cc9c 100644 --- a/core/src/mindustry/entities/comp/CommanderComp.java +++ b/core/src/mindustry/entities/comp/CommanderComp.java @@ -80,6 +80,7 @@ abstract class CommanderComp implements Entityc, Posc{ void command(Formation formation, Seq units){ clearCommand(); + units.shuffle(); float spacing = hitSize * 0.8f; minFormationSpeed = type.speed; diff --git a/core/src/mindustry/logic/LAssembler.java b/core/src/mindustry/logic/LAssembler.java index 8282e66ca6..95195cc3fe 100644 --- a/core/src/mindustry/logic/LAssembler.java +++ b/core/src/mindustry/logic/LAssembler.java @@ -61,9 +61,6 @@ public class LAssembler{ String[] lines = data.split("\n"); int index = 0; for(String line : lines){ - //comments - int commentIdx = line.indexOf('#'); - if(commentIdx != -1) line = line.substring(0, commentIdx).trim(); if(line.isEmpty()) continue; //remove trailing semicolons in case someone adds them in for no reason if(line.endsWith(";")) line = line.substring(0, line.length() - 1); @@ -83,7 +80,9 @@ public class LAssembler{ for(int i = 0; i < line.length() + 1; i++){ char c = i == line.length() ? ' ' : line.charAt(i); - if(c == '"'){ + if(c == '#' && !inString){ + break; + }else if(c == '"'){ inString = !inString; }else if(c == ' ' && !inString){ tokens.add(line.substring(lastIdx, Math.min(i, lastIdx + maxTokenLength))); @@ -96,6 +95,9 @@ public class LAssembler{ arr = new String[]{line}; } + //nothing found + if(arr.length == 0) continue; + String type = arr[0]; //legacy stuff @@ -131,10 +133,7 @@ public class LAssembler{ String first = arr[0]; if(customParsers.containsKey(first)){ statements.add(customParsers.get(first).get(arr)); - }else{ - //unparseable statement - statements.add(new InvalidStatement()); - } + } //unparseable statement, skip } }catch(Exception parseFailed){ parseFailed.printStackTrace(); From 792fdef95d03ab7caf211ff56199f99fbc90064a Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Jan 2021 21:25:04 -0500 Subject: [PATCH 130/426] Minor parse fix --- core/src/mindustry/logic/LAssembler.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/logic/LAssembler.java b/core/src/mindustry/logic/LAssembler.java index 95195cc3fe..48e59cf0c1 100644 --- a/core/src/mindustry/logic/LAssembler.java +++ b/core/src/mindustry/logic/LAssembler.java @@ -71,6 +71,7 @@ public class LAssembler{ try{ String[] arr; + if(line.startsWith("#")) continue; //yes, I am aware that this can be split with regex, but that's slow and even more incomprehensible if(line.contains(" ")){ @@ -133,7 +134,10 @@ public class LAssembler{ String first = arr[0]; if(customParsers.containsKey(first)){ statements.add(customParsers.get(first).get(arr)); - } //unparseable statement, skip + }else{ + //unparseable statement + statements.add(new InvalidStatement()); + } } }catch(Exception parseFailed){ parseFailed.printStackTrace(); From 8ca08a0f146f0c5b6f7a23409069df7f7b70bfb3 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Sat, 23 Jan 2021 07:28:26 -0800 Subject: [PATCH 131/426] Make schematics build insulated blocks first, power nodes last (#4414) * Make schematics build insulated blocks first, power nodes last * Add schematicPriority property to sort by * Assign schematicPriority of 10 to power diode --- core/src/mindustry/content/Blocks.java | 1 + core/src/mindustry/game/Schematics.java | 2 +- core/src/mindustry/world/Block.java | 2 ++ core/src/mindustry/world/blocks/power/PowerDiode.java | 1 + core/src/mindustry/world/blocks/power/PowerNode.java | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 4e6719473b..8f66b936ac 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -788,6 +788,7 @@ public class Blocks implements ContentList{ health = 130 * wallHealthMultiplier; insulated = true; absorbLasers = true; + schematicPriority = 10; }}; plastaniumWallLarge = new Wall("plastanium-wall-large"){{ diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index e60a1660fd..92179b7c9c 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -285,7 +285,7 @@ public class Schematics implements Loadable{ /** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */ public Seq toRequests(Schematic schem, int x, int y){ return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block, t.config).original(t.x, t.y, schem.width, schem.height)) - .removeAll(s -> (!s.block.isVisible() && !(s.block instanceof CoreBlock)) || !s.block.unlockedNow()); + .removeAll(s -> (!s.block.isVisible() && !(s.block instanceof CoreBlock)) || !s.block.unlockedNow()).sort(Structs.comparingInt(s -> -s.block.schematicPriority)); } /** @return all the valid loadouts for a specific core type. */ diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 6c9628c95b..22cb4772ee 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -145,6 +145,8 @@ public class Block extends UnlockableContent{ public boolean conveyorPlacement; /** Whether to swap the diagonal placement modes. */ public boolean swapDiagonalPlacement; + /** Build queue priority in schematics. */ + public int schematicPriority = 0; /** * The color of this block when displayed on the minimap or map preview. * Do not set manually! This is overridden when loading for most blocks. diff --git a/core/src/mindustry/world/blocks/power/PowerDiode.java b/core/src/mindustry/world/blocks/power/PowerDiode.java index 03892d1c54..6e2052250e 100644 --- a/core/src/mindustry/world/blocks/power/PowerDiode.java +++ b/core/src/mindustry/world/blocks/power/PowerDiode.java @@ -22,6 +22,7 @@ public class PowerDiode extends Block{ insulated = true; group = BlockGroup.power; noUpdateDisabled = true; + schematicPriority = 10; } @Override diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 0457d16f79..0c66eef09a 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -43,6 +43,7 @@ public class PowerNode extends PowerBlock{ outputsPower = false; canOverdrive = false; swapDiagonalPlacement = true; + schematicPriority = -10; drawDisabled = false; config(Integer.class, (entity, value) -> { From ad4650f408c48a065b258a813a0dd69516988209 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 23 Jan 2021 10:33:06 -0500 Subject: [PATCH 132/426] Fixed #4420 / Fixed #4418 / Fixed #4416 --- core/src/mindustry/entities/comp/UnitComp.java | 4 ++-- core/src/mindustry/type/UnitType.java | 1 + core/src/mindustry/world/blocks/distribution/Conveyor.java | 2 +- desktop/src/mindustry/desktop/DesktopLauncher.java | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 64a717d75e..7d8df00b89 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -53,7 +53,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I } public void approach(Vec2 vector){ - vel.approachDelta(vector, type.accel * realSpeed() * floorSpeedMultiplier()); + vel.approachDelta(vector, type.accel * realSpeed()); } public void aimLook(Position pos){ @@ -82,7 +82,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I /** @return speed with boost multipliers factored in. */ public float realSpeed(){ - return Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation) * speed(); + return Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation) * speed() * floorSpeedMultiplier(); } /** Iterates through this unit and everything it is controlling. */ diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 19a06c3196..d2b38efe2c 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -292,6 +292,7 @@ public class UnitType extends UnlockableContent{ if(maxRange < 0){ maxRange = 0f; + maxRange = Math.max(maxRange, range); for(Weapon weapon : weapons){ maxRange = Math.max(maxRange, weapon.bullet.range() + hitSize / 2f); diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index 9db976e8a5..8b0a7d45eb 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -83,7 +83,7 @@ public class Conveyor extends Block implements Autotiler{ @Override public Block getReplacement(BuildPlan req, Seq requests){ - Boolf cont = p -> requests.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && o.rotation == req.rotation && (req.block instanceof Conveyor || req.block instanceof Junction)); + Boolf cont = p -> requests.contains(o -> o.x == req.x + p.x && o.y == req.y + p.y && (req.block instanceof Conveyor || req.block instanceof Junction)); return cont.get(Geometry.d4(req.rotation)) && cont.get(Geometry.d4(req.rotation - 2)) && req.tile() != null && diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index 99120a74df..8b9d0a7487 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -109,7 +109,7 @@ public class DesktopLauncher extends ClientLauncher{ steamError = e; loadError = true; Log.err(e); - try(OutputStream s = new FileOutputStream(new File("steam-error-log-" + System.nanoTime() + ".txt"))){ + try(OutputStream s = new FileOutputStream("steam-error-log-" + System.nanoTime() + ".txt")){ String log = Strings.neatError(e); s.write(log.getBytes()); }catch(Exception e2){ From fc91b6b135c54851245d01e52a9283b32b732cfa Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Sat, 23 Jan 2021 12:29:36 -0800 Subject: [PATCH 133/426] Colored construct (#4417) --- core/src/mindustry/graphics/Drawf.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/graphics/Drawf.java b/core/src/mindustry/graphics/Drawf.java index 83d9065281..e38fa74c82 100644 --- a/core/src/mindustry/graphics/Drawf.java +++ b/core/src/mindustry/graphics/Drawf.java @@ -221,9 +221,13 @@ public class Drawf{ } public static void construct(float x, float y, TextureRegion region, float rotation, float progress, float speed, float time){ + construct(x, y, region, Pal.accent, rotation, progress, speed, time); + } + + public static void construct(float x, float y, TextureRegion region, Color color, float rotation, float progress, float speed, float time){ Shaders.build.region = region; Shaders.build.progress = progress; - Shaders.build.color.set(Pal.accent); + Shaders.build.color.set(color); Shaders.build.color.a = speed; Shaders.build.time = -time / 20f; @@ -235,9 +239,13 @@ public class Drawf{ } public static void construct(Building t, TextureRegion region, float rotation, float progress, float speed, float time){ + construct(t, region, Pal.accent, rotation, progress, speed, time); + } + + public static void construct(Building t, TextureRegion region, Color color, float rotation, float progress, float speed, float time){ Shaders.build.region = region; Shaders.build.progress = progress; - Shaders.build.color.set(Pal.accent); + Shaders.build.color.set(color); Shaders.build.color.a = speed; Shaders.build.time = -time / 20f; From 6b6d52e2fd36d6f6996e05f6ab2fe7bf0cb3ca9d Mon Sep 17 00:00:00 2001 From: _owler_#0954 <63801085+owler0954@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:22:44 +0300 Subject: [PATCH 134/426] Add new minigame (#4427) PvP version of tower defence --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index fcc68297ac..67d025e65c 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -61,7 +61,7 @@ }, { "name": "Minigames", - "address": ["shizashizashiza.ml"] + "address": ["shizashizashiza.ml", "shizashizashiza.ml:6568"] }, { "name": "Korea", From 623b7ada11003a4552c1d8a1acf52d486d459360 Mon Sep 17 00:00:00 2001 From: genNAowl <68400583+genNAowl@users.noreply.github.com> Date: Sun, 24 Jan 2021 06:23:12 -0800 Subject: [PATCH 135/426] Let Logic Sense Range (#4425) Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com> --- core/src/mindustry/entities/comp/BuildingComp.java | 1 + core/src/mindustry/entities/comp/UnitComp.java | 1 + core/src/mindustry/logic/LAccess.java | 1 + 3 files changed, 3 insertions(+) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 31a7ed8ce0..76824b6cc3 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1306,6 +1306,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case health -> health; case maxHealth -> maxHealth; case efficiency -> efficiency(); + case range -> this instanceof Ranged r ? r.range() / tilesize : 0; case rotation -> rotation; case totalItems -> items == null ? 0 : items.total(); case totalLiquids -> liquids == null ? 0 : liquids.total(); diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 7d8df00b89..753b03f248 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -130,6 +130,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case y -> World.conv(y); case team -> team.id; case shooting -> isShooting() ? 1 : 0; + case range -> range() / tilesize; case shootX -> World.conv(aimX()); case shootY -> World.conv(aimY()); case mining -> mining() ? 1 : 0; diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index 0c0597c6a1..6dcf46e140 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -26,6 +26,7 @@ public enum LAccess{ y, shootX, shootY, + range, shooting, mineX, mineY, From 18a3f8bb684976f53ac3516c70b6c61fe8984e36 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 24 Jan 2021 13:08:01 -0500 Subject: [PATCH 136/426] Fixed #4431 --- core/src/mindustry/core/NetServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index da801cc454..d358a3958d 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -155,7 +155,7 @@ public class NetServer implements ApplicationListener{ if(!extraMods.isEmpty()){ result.append("Unnecessary mods:[lightgray]\n").append("> ").append(extraMods.toString("\n> ")); } - con.kick(result.toString()); + con.kick(result.toString(), 0); } if(!admins.isWhitelisted(packet.uuid, packet.usid)){ From baedba0d5b4bf759a0177322d0380c1793aea7b6 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 24 Jan 2021 14:20:48 -0500 Subject: [PATCH 137/426] Mutual status effect transitions --- core/src/mindustry/content/StatusEffects.java | 10 +++++----- core/src/mindustry/entities/comp/StatusComp.java | 4 ++++ core/src/mindustry/type/StatusEffect.java | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/content/StatusEffects.java b/core/src/mindustry/content/StatusEffects.java index b20463a65f..e7c55055c2 100644 --- a/core/src/mindustry/content/StatusEffects.java +++ b/core/src/mindustry/content/StatusEffects.java @@ -21,7 +21,7 @@ public class StatusEffects implements ContentList{ 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; init(() -> { @@ -29,7 +29,7 @@ public class StatusEffects implements ContentList{ trans(tarred, ((unit, time, newTime, result) -> { unit.damagePierce(8f); Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f)); - result.set(this, Math.min(time + newTime, 300f)); + result.set(burning, Math.min(time + newTime, 300f)); })); }); }}; @@ -45,7 +45,7 @@ public class StatusEffects implements ContentList{ trans(blasted, ((unit, time, newTime, result) -> { unit.damagePierce(18f); - result.set(this, time); + result.set(freezing, time); })); }); }}; @@ -72,7 +72,7 @@ public class StatusEffects implements ContentList{ if(unit.team == state.rules.waveTeam){ Events.fire(Trigger.shock); } - result.set(this, time); + result.set(wet, time); })); opposite(burning); }); @@ -97,7 +97,7 @@ public class StatusEffects implements ContentList{ trans(tarred, ((unit, time, newTime, result) -> { unit.damagePierce(8f); Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f)); - result.set(this, Math.min(time + newTime, 200f)); + result.set(melting, Math.min(time + newTime, 200f)); })); }); }}; diff --git a/core/src/mindustry/entities/comp/StatusComp.java b/core/src/mindustry/entities/comp/StatusComp.java index c4ea7be07a..feda4c73e0 100644 --- a/core/src/mindustry/entities/comp/StatusComp.java +++ b/core/src/mindustry/entities/comp/StatusComp.java @@ -61,6 +61,10 @@ abstract class StatusComp implements Posc, Flyingc{ statuses.add(entry); } + void clearStatuses(){ + statuses.clear(); + } + /** Removes a status effect. */ void unapply(StatusEffect effect){ statuses.remove(e -> { diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index a02cb28978..d5b5489e02 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -63,6 +63,7 @@ public class StatusEffect extends MappableContent{ protected void trans(StatusEffect effect, TransitionHandler handler){ transitions.put(effect, handler); + effect.transitions.put(this, handler); } protected void opposite(StatusEffect... effect){ From 8b5cf5309a883527e9f5bb31cc449aeb0660a190 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 24 Jan 2021 15:22:41 -0500 Subject: [PATCH 138/426] Reactive effect flag --- core/src/mindustry/content/StatusEffects.java | 2 ++ core/src/mindustry/entities/comp/StatusComp.java | 10 ++++++---- core/src/mindustry/type/StatusEffect.java | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/content/StatusEffects.java b/core/src/mindustry/content/StatusEffects.java index e7c55055c2..fffdee4018 100644 --- a/core/src/mindustry/content/StatusEffects.java +++ b/core/src/mindustry/content/StatusEffects.java @@ -161,10 +161,12 @@ public class StatusEffects implements ContentList{ shocked = new StatusEffect("shocked"){{ color = Pal.lancerLaser; + reactive = true; }}; blasted = new StatusEffect("blasted"){{ color = Color.valueOf("ff795e"); + reactive = true; }}; corroded = new StatusEffect("corroded"){{ diff --git a/core/src/mindustry/entities/comp/StatusComp.java b/core/src/mindustry/entities/comp/StatusComp.java index feda4c73e0..744da3b386 100644 --- a/core/src/mindustry/entities/comp/StatusComp.java +++ b/core/src/mindustry/entities/comp/StatusComp.java @@ -55,10 +55,12 @@ abstract class StatusComp implements Posc, Flyingc{ } } - //otherwise, no opposites found, add direct effect - StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new); - entry.set(effect, duration); - statuses.add(entry); + if(!effect.reactive){ + //otherwise, no opposites found, add direct effect + StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new); + entry.set(effect, duration); + statuses.add(entry); + } } void clearStatuses(){ diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index d5b5489e02..19e0135960 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -25,6 +25,8 @@ public class StatusEffect extends MappableContent{ public float effectChance = 0.15f; /** If true, the effect never disappears. */ public boolean permanent; + /** If true, this effect will only react with other effects and cannot be applied. */ + public boolean reactive; /** Tint color of effect. */ public Color color = Color.white.cpy(); /** Effect that happens randomly on top of the affected unit. */ From 13896589c290e34420a7e4c31b33d1af3c4fe4d3 Mon Sep 17 00:00:00 2001 From: FrederickDoering Date: Sun, 24 Jan 2021 20:18:09 -0500 Subject: [PATCH 139/426] Made disabling payload conveyors output from routers more reliable. (#4433) Prevented reconstructors from being roughted to when disabled. Co-authored-by: frederick_efd --- .../world/blocks/distribution/PayloadConveyor.java | 8 +++----- core/src/mindustry/world/blocks/units/Reconstructor.java | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java b/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java index 122278238a..df51bef7ae 100644 --- a/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/PayloadConveyor.java @@ -217,11 +217,9 @@ public class PayloadConveyor extends Block{ @Override public boolean acceptPayload(Building source, Payload payload){ - if(source == this){ - return this.item == null && payload.fits(payloadLimit); - } - //accepting payloads from units isn't supported - return this.item == null && progress <= 5f && payload.fits(payloadLimit); + return this.item == null + && payload.fits(payloadLimit) + && (source == this || this.enabled && progress <= 5f); } @Override diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index 1521511c15..c0fe54d27b 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -106,6 +106,7 @@ public class Reconstructor extends UnitBlock{ @Override public boolean acceptPayload(Building source, Payload payload){ return this.payload == null + && this.enabled && relativeTo(source) != rotation && payload instanceof UnitPayload && hasUpgrade(((UnitPayload)payload).unit.type); From f16990edcbfc530d767b81c1cc81794aa917ecd7 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 24 Jan 2021 20:20:03 -0500 Subject: [PATCH 140/426] Reconstructors: Accept unit dropped payload when disabled --- core/src/mindustry/world/blocks/units/Reconstructor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index c0fe54d27b..c80cb35b83 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -106,10 +106,10 @@ public class Reconstructor extends UnitBlock{ @Override public boolean acceptPayload(Building source, Payload payload){ return this.payload == null - && this.enabled + && (this.enabled || source == this) && relativeTo(source) != rotation - && payload instanceof UnitPayload - && hasUpgrade(((UnitPayload)payload).unit.type); + && payload instanceof UnitPayload pay + && hasUpgrade(pay.unit.type); } @Override From 4630e5b3a457dc09659496c759098b2c469d05f4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 25 Jan 2021 10:28:36 -0500 Subject: [PATCH 141/426] Wave spawning improvements --- core/src/mindustry/ai/WaveSpawner.java | 13 +++++++------ core/src/mindustry/content/Fx.java | 20 +++++++++++++------- core/src/mindustry/core/Logic.java | 2 +- core/src/mindustry/input/DesktopInput.java | 1 - core/src/mindustry/logic/LExecutor.java | 1 + 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java index afc8ab30db..947e13b48b 100644 --- a/core/src/mindustry/ai/WaveSpawner.java +++ b/core/src/mindustry/ai/WaveSpawner.java @@ -13,7 +13,6 @@ import mindustry.entities.*; import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.gen.*; -import mindustry.type.*; import mindustry.world.*; import static mindustry.Vars.*; @@ -73,7 +72,7 @@ public class WaveSpawner{ for(int i = 0; i < spawned; i++){ Unit unit = group.createUnit(state.rules.waveTeam, state.wave - 1); unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); - unit.add(); + spawnEffect(unit); } }); }else{ @@ -178,8 +177,10 @@ public class WaveSpawner{ } private void spawnEffect(Unit unit){ - Call.spawnEffect(unit.x, unit.y, unit.type); - Time.run(30f, unit::add); + Call.spawnEffect(unit.x, unit.y, unit); + unit.rotation = unit.angleTo(world.width()/2f * tilesize, world.height()/2f * tilesize); + unit.apply(StatusEffects.unmoving, 30f); + unit.add(); } private interface SpawnConsumer{ @@ -187,8 +188,8 @@ public class WaveSpawner{ } @Remote(called = Loc.server, unreliable = true) - public static void spawnEffect(float x, float y, UnitType type){ - Fx.unitSpawn.at(x, y, 0f, type); + public static void spawnEffect(float x, float y, Unit u){ + Fx.unitSpawn.at(x, y, 0f, u); Time.run(30f, () -> Fx.spawn.at(x, y)); } diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index b2f21d732d..00b714c26b 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -26,17 +26,23 @@ public class Fx{ none = new Effect(0, 0f, e -> {}), unitSpawn = new Effect(30f, e -> { - if(!(e.data instanceof UnitType)) return; - - alpha(e.fin()); + if(!(e.data instanceof Unit unit)) return; float scl = 1f + e.fout() * 2f; - UnitType unit = e.data(); - TextureRegion region = unit.icon(Cicon.full); + TextureRegion region = unit.type.icon(Cicon.full); - rect(region, e.x, e.y, - region.width * Draw.scl * scl, region.height * Draw.scl * scl, 180f); + alpha(e.fout()); + mixcol(Color.white, e.fin()); + + rect(region, unit.x, unit.y, 180f); + + reset(); + + alpha(e.fin()); + + rect(region, unit.x, unit.y, + region.width * Draw.scl * scl, region.height * Draw.scl * scl, unit.rotation - 90); }), diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 6263782b51..aa6b19e2b5 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -200,7 +200,7 @@ public class Logic implements ApplicationListener{ } public void skipWave(){ - state.wavetime = 0; + runWave(); } public void runWave(){ diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 203108f036..592869b4d1 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -204,7 +204,6 @@ public class DesktopInput extends InputHandler{ if(input.keyDown(Binding.mouse_move)){ panCam = true; } - panning = false; Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(camSpeed)); }else if(!player.dead() && !panning){ diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index ffbee6cdf3..843d2600ab 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -888,6 +888,7 @@ public class LExecutor{ String strValue = v.objval == null ? "null" : v.objval instanceof String s ? s : + v.objval == Blocks.stoneWall ? "solid" : //special alias v.objval instanceof MappableContent content ? content.name : v.objval instanceof Content ? "[content]" : v.objval instanceof Building build ? build.block.name : From 5930e3c3501d6a4db78af836c36f71ddc598421c Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 25 Jan 2021 12:53:27 -0500 Subject: [PATCH 142/426] Cleanup --- core/src/mindustry/ai/WaveSpawner.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java index 947e13b48b..0bd5c7b35a 100644 --- a/core/src/mindustry/ai/WaveSpawner.java +++ b/core/src/mindustry/ai/WaveSpawner.java @@ -147,8 +147,7 @@ public class WaveSpawner{ private void eachFlyerSpawn(Floatc2 cons){ for(Tile tile : spawns){ - float angle = Angles.angle(world.width() / 2, world.height() / 2, tile.x, tile.y); - + float angle = Angles.angle(world.width() / 2f, world.height() / 2f, tile.x, tile.y); float trns = Math.max(world.width(), world.height()) * Mathf.sqrt2 * tilesize; float spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(angle, trns), -margin, world.width() * tilesize + margin); float spawnY = Mathf.clamp(world.height() * tilesize / 2f + Angles.trnsy(angle, trns), -margin, world.height() * tilesize + margin); From 5666fd49994e424ea0e0ea1b522d80ee77de58a6 Mon Sep 17 00:00:00 2001 From: Thomas Widyantoko <40286070+DaGamerFiles@users.noreply.github.com> Date: Tue, 26 Jan 2021 02:32:35 +0700 Subject: [PATCH 143/426] new update in_ID translation (#4437) yes --- core/assets/bundles/bundle_in_ID.properties | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties index 60eca12c70..e9a8d1382a 100644 --- a/core/assets/bundles/bundle_in_ID.properties +++ b/core/assets/bundles/bundle_in_ID.properties @@ -41,11 +41,12 @@ be.ignore = Abaikan be.noupdates = Tidak ada pembaruan yang ditemukan. be.check = Cek versi baru -mod.featured.title = Browser mod mod.featured.dialog.title = Browser Mod mods.browser.selected = Mod yang Dipilih mods.browser.add = Unduh Mod mods.github.open = Buka di GitHub +mods.browser.sortdate = Urut berdasarkan waktu +mods.browser.sortstars = Urut berdasarkan bintang schematic = Skema schematic.add = Menyimpan skema... @@ -90,6 +91,7 @@ joingame = Bermain Bersama customgame = Permainan Modifikasi newgame = Permainan Baru none = +none.found = [lightgray] minimap = Peta Kecil position = Posisi close = Tutup @@ -1383,7 +1385,7 @@ block.inverted-sorter.description = Sama seperti penyortir, melainkan mengeluark block.router.description = Menerima bahan dari satu arah dan mengeluarkannya ke 3 arah yang sama. Bisa juga menyimpan sejumlah bahan. Berguna untuk memisahkan bahan dari satu sumber ke target yang banyak. block.router.details = Bisa sangat menggangu. Jangan meletakannya disamping input produksi, karena bisa tersumbat oleh output. block.distributor.description = Pemisah canggih yang memisah item ke 7 arah berbeda bersamaan. -block.overflow-gate.description = Kombinasi antara pemisah dan penyortir yang hanya mengeluarkan item ke kiri dan/atau ke kanan jika bagian depan tertutup. +block.overflow-gate.description = Hanya mengeluarkan item ke kiri dan/atau ke kanan jika bagian depan tertutup. block.underflow-gate.description = Kebalikan dari gerbang luap. Mengeluarkan ke depan jika kanan dan kiri tertutup. block.mass-driver.description = Blok item transportasi tercanggih. Membawa beberapa item dan menembaknya ke penggerak massal lainnya dari arah yang jauh. block.mechanical-pump.description = Pompa murah dengan pengeluaran yang pelan, tetapi tidak mengkonsumsi tenaga. From b83c76f728ac1eeb84cc0a5e33cb1ce13ece7e9f Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 25 Jan 2021 16:16:38 -0500 Subject: [PATCH 144/426] Improved liquid bridge throughput --- core/src/mindustry/entities/comp/BuildingComp.java | 6 +++++- core/src/mindustry/world/blocks/liquid/LiquidBridge.java | 2 +- .../world/blocks/liquid/LiquidExtendingBridge.java | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 76824b6cc3..769530ce94 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -536,6 +536,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, } public void dumpLiquid(Liquid liquid){ + dumpLiquid(liquid, 2f); + } + + public void dumpLiquid(Liquid liquid, float scaling){ int dump = this.cdump; if(liquids.get(liquid) <= 0.0001f) return; @@ -551,7 +555,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, float ofract = other.liquids.get(liquid) / other.block.liquidCapacity; float fract = liquids.get(liquid) / block.liquidCapacity; - if(ofract < fract) transferLiquid(other, (fract - ofract) * block.liquidCapacity / 2f, liquid); + if(ofract < fract) transferLiquid(other, (fract - ofract) * block.liquidCapacity / scaling, liquid); } } diff --git a/core/src/mindustry/world/blocks/liquid/LiquidBridge.java b/core/src/mindustry/world/blocks/liquid/LiquidBridge.java index 59205c3c92..83b2fe3e1e 100644 --- a/core/src/mindustry/world/blocks/liquid/LiquidBridge.java +++ b/core/src/mindustry/world/blocks/liquid/LiquidBridge.java @@ -29,7 +29,7 @@ public class LiquidBridge extends ItemBridge{ Building other = world.build(link); if(other == null || !linkValid(tile, other.tile())){ - dumpLiquid(liquids.current()); + dumpLiquid(liquids.current(), 1f); }else{ ((ItemBridgeBuild)other).incoming.add(tile.pos()); diff --git a/core/src/mindustry/world/blocks/liquid/LiquidExtendingBridge.java b/core/src/mindustry/world/blocks/liquid/LiquidExtendingBridge.java index 76e4929b45..552c348891 100644 --- a/core/src/mindustry/world/blocks/liquid/LiquidExtendingBridge.java +++ b/core/src/mindustry/world/blocks/liquid/LiquidExtendingBridge.java @@ -28,7 +28,7 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{ Building other = world.build(link); if(other == null || !linkValid(tile, other.tile())){ - dumpLiquid(liquids.current()); + dumpLiquid(liquids.current(), 1f); }else{ ((ItemBridgeBuild)other).incoming.add(tile.pos()); From a13d51e09a612eb1fc713f3e02a766ebe41cae36 Mon Sep 17 00:00:00 2001 From: Sunny Kim <58885089+sk7725@users.noreply.github.com> Date: Tue, 26 Jan 2021 07:10:34 +0900 Subject: [PATCH 145/426] Charge stat for Item (#4392) * Stat.discharge, discharge * Update Items.java * item.discharge * full container = somewhat more than 4 full batteries * Stat.discharge * stat.discharge = Discharge * Update core/src/mindustry/type/Item.java Co-authored-by: Antsiferov Andrew * removed dis * oops * unit zap Co-authored-by: Antsiferov Andrew --- core/assets/bundles/bundle.properties | 1 + core/src/mindustry/content/Items.java | 1 + core/src/mindustry/entities/comp/BuildingComp.java | 1 + core/src/mindustry/entities/comp/UnitComp.java | 3 ++- core/src/mindustry/type/Item.java | 3 +++ core/src/mindustry/world/meta/Stat.java | 1 + 6 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index a71af9f728..e44236ac92 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -695,6 +695,7 @@ stat.lightningchance = Lightning Chance stat.lightningdamage = Lightning Damage stat.flammability = Flammability stat.radioactivity = Radioactivity +stat.charge = Charge stat.heatcapacity = Heat Capacity stat.viscosity = Viscosity stat.temperature = Temperature diff --git a/core/src/mindustry/content/Items.java b/core/src/mindustry/content/Items.java index 65c464a249..bd883c3ce9 100644 --- a/core/src/mindustry/content/Items.java +++ b/core/src/mindustry/content/Items.java @@ -74,6 +74,7 @@ public class Items implements ContentList{ surgeAlloy = new Item("surge-alloy", Color.valueOf("f3e979")){{ cost = 1.2f; + charge = 0.75f; }}; sporePod = new Item("spore-pod", Color.valueOf("7457ce")){{ diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 769530ce94..c2bb86dea9 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -983,6 +983,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, int amount = items.get(item); explosiveness += item.explosiveness * amount; flammability += item.flammability * amount; + power += item.charge * amount * 100f; } } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 753b03f248..69ffc86426 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -411,9 +411,10 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f; float flammability = item().flammability * stack().amount / 1.9f; + float power = item().charge * stack().amount * 160f; if(!spawnedByCore){ - Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team); + Damage.dynamicExplosion(x, y, flammability, explosiveness, power, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team); } float shake = hitSize / 3f; diff --git a/core/src/mindustry/type/Item.java b/core/src/mindustry/type/Item.java index 18cbdff886..24dd790d37 100644 --- a/core/src/mindustry/type/Item.java +++ b/core/src/mindustry/type/Item.java @@ -17,6 +17,8 @@ public class Item extends UnlockableContent{ public float flammability = 0f; /** how radioactive this item is. 0=none, 1=chernobyl ground zero */ public float radioactivity; + /** how electrically potent this item is. */ + public float charge = 0f; /** drill hardness of the item */ public int hardness = 0; /** @@ -41,6 +43,7 @@ public class Item extends UnlockableContent{ stats.addPercent(Stat.explosiveness, explosiveness); stats.addPercent(Stat.flammability, flammability); stats.addPercent(Stat.radioactivity, radioactivity); + stats.addPercent(Stat.charge, charge); } @Override diff --git a/core/src/mindustry/world/meta/Stat.java b/core/src/mindustry/world/meta/Stat.java index 1f9d1d0022..2a1b864c7c 100644 --- a/core/src/mindustry/world/meta/Stat.java +++ b/core/src/mindustry/world/meta/Stat.java @@ -15,6 +15,7 @@ public enum Stat{ explosiveness, flammability, radioactivity, + charge, heatCapacity, viscosity, temperature, From c6588659074949bef7ecd4a6e13ea773257114c1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 25 Jan 2021 17:21:12 -0500 Subject: [PATCH 146/426] Dynamic lightning damage tweaks --- core/src/mindustry/entities/Damage.java | 6 +++--- core/src/mindustry/entities/comp/UnitComp.java | 2 +- core/src/mindustry/logic/LogicDialog.java | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 9ddca6e986..e332af5a50 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -39,9 +39,9 @@ public class Damage{ /** Creates a dynamic explosion based on specified parameters. */ public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage, boolean fire, @Nullable Team ignoreTeam){ if(damage){ - for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){ - int branches = 5 + Mathf.clamp((int)(power / 30), 1, 20); - Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2))); + for(int i = 0; i < Mathf.clamp(power / 700, 0, 8); i++){ + int length = 5 + Mathf.clamp((int)(power / 500), 1, 20); + Time.run(i * 0.8f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), length + Mathf.range(2))); } if(fire){ diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 69ffc86426..8b0dbc67fe 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -411,7 +411,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f; float flammability = item().flammability * stack().amount / 1.9f; - float power = item().charge * stack().amount * 160f; + float power = item().charge * stack().amount * 150f; if(!spawnedByCore){ Damage.dynamicExplosion(x, y, flammability, explosiveness, power, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team); diff --git a/core/src/mindustry/logic/LogicDialog.java b/core/src/mindustry/logic/LogicDialog.java index dd12b9cca3..df37f8cb4b 100644 --- a/core/src/mindustry/logic/LogicDialog.java +++ b/core/src/mindustry/logic/LogicDialog.java @@ -35,6 +35,11 @@ public class LogicDialog extends BaseDialog{ p.table(Tex.button, t -> { TextButtonStyle style = Styles.cleart; t.defaults().size(280f, 60f).left(); + + t.button("@schematic.copy", Icon.copy, style, () -> { + dialog.hide(); + Core.app.setClipboardText(canvas.save()); + }).marginLeft(12f); t.row(); t.button("@schematic.copy.import", Icon.download, style, () -> { dialog.hide(); @@ -44,11 +49,6 @@ public class LogicDialog extends BaseDialog{ ui.showException(e); } }).marginLeft(12f).disabled(b -> Core.app.getClipboardText() == null); - t.row(); - t.button("@schematic.copy", Icon.copy, style, () -> { - dialog.hide(); - Core.app.setClipboardText(canvas.save()); - }).marginLeft(12f); }); }); From ccc59aa61be68264d3148ee13f52e78ea7076647 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 26 Jan 2021 10:37:36 -0500 Subject: [PATCH 147/426] Minor wave task tweaks --- core/src/mindustry/ai/WaveSpawner.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java index 0bd5c7b35a..6c542f5875 100644 --- a/core/src/mindustry/ai/WaveSpawner.java +++ b/core/src/mindustry/ai/WaveSpawner.java @@ -91,7 +91,7 @@ public class WaveSpawner{ } } - Time.runTask(121f, () -> spawning = false); + Time.run(121f, () -> spawning = false); } public void doShockwave(float x, float y){ @@ -166,6 +166,7 @@ public class WaveSpawner{ } private void reset(){ + spawning = false; spawns.clear(); for(Tile tile : world.tiles){ From 6969fbb1e7cef6a01ac984c9bba39b280dbcb86a Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 26 Jan 2021 17:31:36 +0100 Subject: [PATCH 148/426] Give tsunami the extinguisher flag as well (#4442) --- core/src/mindustry/content/Blocks.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 8f66b936ac..f9c48edcf0 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1662,6 +1662,7 @@ public class Blocks implements ContentList{ shootEffect = Fx.shootLiquid; range = 190f; health = 250 * size * size; + flags = EnumSet.of(BlockFlag.turret, BlockFlag.extinguisher); }}; fuse = new ItemTurret("fuse"){{ From 03b37235b31af69c55fd5c7955bb7250a5a9e8ea Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 26 Jan 2021 17:35:48 +0100 Subject: [PATCH 149/426] producer -> generator (#4441) --- core/src/mindustry/world/blocks/power/SolarGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/power/SolarGenerator.java b/core/src/mindustry/world/blocks/power/SolarGenerator.java index d5f37329ae..84e0b0ba81 100644 --- a/core/src/mindustry/world/blocks/power/SolarGenerator.java +++ b/core/src/mindustry/world/blocks/power/SolarGenerator.java @@ -10,7 +10,7 @@ public class SolarGenerator extends PowerGenerator{ public SolarGenerator(String name){ super(name); - //remove the BlockFlag.producer flag to make this a lower priority target than other generators. + //remove the BlockFlag.generator flag to make this a lower priority target than other generators. flags = EnumSet.of(); } From 47eea79b600bd5193da920cb9ff5c3e757aa98de Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 27 Jan 2021 11:49:04 -0500 Subject: [PATCH 150/426] Fixed #4453 / Fixed #4450 --- core/src/mindustry/ai/WaveSpawner.java | 8 +++++--- core/src/mindustry/content/Fx.java | 10 +++++----- core/src/mindustry/logic/LCanvas.java | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java index 6c542f5875..f5930ef7f2 100644 --- a/core/src/mindustry/ai/WaveSpawner.java +++ b/core/src/mindustry/ai/WaveSpawner.java @@ -13,6 +13,7 @@ import mindustry.entities.*; import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.gen.*; +import mindustry.type.*; import mindustry.world.*; import static mindustry.Vars.*; @@ -177,10 +178,11 @@ public class WaveSpawner{ } private void spawnEffect(Unit unit){ - Call.spawnEffect(unit.x, unit.y, unit); unit.rotation = unit.angleTo(world.width()/2f * tilesize, world.height()/2f * tilesize); unit.apply(StatusEffects.unmoving, 30f); unit.add(); + + Call.spawnEffect(unit.x, unit.y, unit.rotation, unit.type); } private interface SpawnConsumer{ @@ -188,8 +190,8 @@ public class WaveSpawner{ } @Remote(called = Loc.server, unreliable = true) - public static void spawnEffect(float x, float y, Unit u){ - Fx.unitSpawn.at(x, y, 0f, u); + public static void spawnEffect(float x, float y, float rotation, UnitType u){ + Fx.unitSpawn.at(x, y, rotation, u); Time.run(30f, () -> Fx.spawn.at(x, y)); } diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index 00b714c26b..d60dcaf74f 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -26,23 +26,23 @@ public class Fx{ none = new Effect(0, 0f, e -> {}), unitSpawn = new Effect(30f, e -> { - if(!(e.data instanceof Unit unit)) return; + if(!(e.data instanceof UnitType unit)) return; float scl = 1f + e.fout() * 2f; - TextureRegion region = unit.type.icon(Cicon.full); + TextureRegion region = unit.icon(Cicon.full); alpha(e.fout()); mixcol(Color.white, e.fin()); - rect(region, unit.x, unit.y, 180f); + rect(region, e.x, e.y, 180f); reset(); alpha(e.fin()); - rect(region, unit.x, unit.y, - region.width * Draw.scl * scl, region.height * Draw.scl * scl, unit.rotation - 90); + rect(region, e.x, e.y, + region.width * Draw.scl * scl, region.height * Draw.scl * scl, e.rotation - 90); }), diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 92c8f61d53..1beab892cd 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -283,13 +283,13 @@ public class LCanvas extends Table{ t.add().growX(); t.button(Icon.copy, Styles.logici, () -> { - }).padRight(6).get().tapped(this::copy); + }).size(24f).padRight(6).get().tapped(this::copy); t.button(Icon.cancel, Styles.logici, () -> { remove(); dragging = null; statements.layout(); - }); + }).size(24f); t.addListener(new InputListener(){ float lastx, lasty; From a667a94c8e0f7d3f79f70abc4e2b2767351d1ca3 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Wed, 27 Jan 2021 09:08:51 -0800 Subject: [PATCH 151/426] Draw plastanium conveyors on conveyors layer (#4446) --- .../world/blocks/distribution/StackConveyor.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/distribution/StackConveyor.java b/core/src/mindustry/world/blocks/distribution/StackConveyor.java index b279f09b9d..e44218feb4 100644 --- a/core/src/mindustry/world/blocks/distribution/StackConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/StackConveyor.java @@ -109,6 +109,8 @@ public class StackConveyor extends Block implements Autotiler{ @Override public void draw(){ + Draw.z(Layer.block - 0.2f); + Draw.rect(regions[state], x, y, rotdeg()); for(int i = 0; i < 4; i++){ @@ -117,7 +119,7 @@ public class StackConveyor extends Block implements Autotiler{ } } - Draw.z(Layer.blockOver); + Draw.z(Layer.block - 0.1f); Tile from = world.tile(link); @@ -145,6 +147,12 @@ public class StackConveyor extends Block implements Autotiler{ Draw.rect(lastItem.icon(Cicon.medium), Tmp.v1.x, Tmp.v1.y, size, size, 0); } + @Override + public void drawCracks(){ + Draw.z(Layer.block - 0.15f); + super.drawCracks(); + } + @Override public void onProximityUpdate(){ super.onProximityUpdate(); From 96ee32f8ed0aef773447b7394375807a7c3137a7 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Thu, 28 Jan 2021 15:06:30 +0100 Subject: [PATCH 152/426] Custom Game Underline 2: Electric Boogaloo (#4457) * Update CustomGameDialog.java * Remove .row() for consistensy --- core/src/mindustry/ui/dialogs/CustomGameDialog.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/mindustry/ui/dialogs/CustomGameDialog.java b/core/src/mindustry/ui/dialogs/CustomGameDialog.java index e23d8cca38..efe5a157ea 100644 --- a/core/src/mindustry/ui/dialogs/CustomGameDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomGameDialog.java @@ -25,8 +25,7 @@ public class CustomGameDialog extends BaseDialog{ void setup(){ clearChildren(); - add(titleTable); - row(); + add(titleTable).growX().row(); stack(cont, buttons).grow(); buttons.bottom(); cont.clear(); From 5a258d2830d8b27bf1dc5ce7ea32ff04a8569146 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 28 Jan 2021 10:23:02 -0500 Subject: [PATCH 153/426] Fixed #4461 --- core/src/mindustry/world/blocks/power/PowerGraph.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index 24873ecb14..abfdfbdaa3 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -291,15 +291,8 @@ public class PowerGraph{ } } - private void removeSingle(Building tile){ - all.remove(tile, true); - producers.remove(tile, true); - consumers.remove(tile, true); - batteries.remove(tile, true); - } - public void remove(Building tile){ - removeSingle(tile); + //begin by clearing the closed set closedSet.clear(); @@ -317,8 +310,6 @@ public class PowerGraph{ while(queue.size > 0){ //get child from queue Building child = queue.removeFirst(); - //remove it from this graph - removeSingle(child); //add it to the new branch graph graph.add(child); //go through connections From 7cdf7a21fef5f54234358a46d4307bf2eb204651 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 28 Jan 2021 12:07:50 -0500 Subject: [PATCH 154/426] Minor power graph optimizations --- .../src/mindustry/world/blocks/power/PowerGraph.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index abfdfbdaa3..6c179b4dc0 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -249,6 +249,8 @@ public class PowerGraph{ } public void addGraph(PowerGraph graph){ + if(graph == this) return; + for(Building tile : graph.all){ add(tile); } @@ -283,9 +285,8 @@ public class PowerGraph{ Building child = queue.removeFirst(); add(child); for(Building next : child.getPowerConnections(outArray2)){ - if(!closedSet.contains(next.pos())){ + if(closedSet.add(next.pos())){ queue.addLast(next); - closedSet.add(next.pos()); } } } @@ -293,9 +294,6 @@ public class PowerGraph{ public void remove(Building tile){ - //begin by clearing the closed set - closedSet.clear(); - //go through all the connections of this tile for(Building other : tile.getPowerConnections(outArray1)){ //a graph has already been assigned to this tile from a previous call, skip it @@ -316,9 +314,9 @@ public class PowerGraph{ for(Building next : child.getPowerConnections(outArray2)){ //make sure it hasn't looped back, and that the new graph being assigned hasn't already been assigned //also skip closed tiles - if(next != tile && next.power.graph != graph && !closedSet.contains(next.pos())){ + if(next != tile && next.power.graph != graph){ + graph.add(next); queue.addLast(next); - closedSet.add(next.pos()); } } } From d512aa5b2116326db9e1d5998b3aecf8b342aac0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 29 Jan 2021 09:32:29 -0500 Subject: [PATCH 155/426] Fixed #4463 --- core/src/mindustry/world/blocks/power/PowerGraph.java | 10 ++++++++++ tests/src/test/java/power/PowerTests.java | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index 6c179b4dc0..bc3b6e2fd8 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -292,6 +292,16 @@ public class PowerGraph{ } } + /** Used for unit tests only. */ + public void removeList(Building build){ + all.remove(build); + producers.remove(build); + consumers.remove(build); + batteries.remove(build); + } + + /** Note that this does not actually remove the building from the graph; + * it creates *new* graphs that contain the correct buildings. */ public void remove(Building tile){ //go through all the connections of this tile diff --git a/tests/src/test/java/power/PowerTests.java b/tests/src/test/java/power/PowerTests.java index af90f1d762..39e4b9b588 100644 --- a/tests/src/test/java/power/PowerTests.java +++ b/tests/src/test/java/power/PowerTests.java @@ -130,7 +130,7 @@ public class PowerTests extends PowerTestFixture{ assertEquals(1.0f, consumerTile.build.power.status, Mathf.FLOAT_ROUNDING_ERROR); - powerGraph.remove(producerTile.build); + powerGraph.removeList(producerTile.build); powerGraph.add(consumerTile.build); powerGraph.update(); From bc6db72df03d40bc7cd68f3080b3fef630f75d9e Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Fri, 29 Jan 2021 15:38:26 +0100 Subject: [PATCH 156/426] Make fillitems fill the core to the brim (#4462) Instead of just setting all items to the capacity of the first found core. --- server/src/mindustry/server/ServerControl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index 44f0603c5c..27b539c13a 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -502,7 +502,7 @@ public class ServerControl implements ApplicationListener{ } for(Item item : content.items()){ - state.teams.cores(team).first().items.set(item, state.teams.cores(team).first().block.itemCapacity); + state.teams.cores(team).first().items.set(item, state.teams.cores(team).first().storageCapacity); } info("Core filled."); From 022c76bf45e32d01e5e5da7eedc722287cf85b5b Mon Sep 17 00:00:00 2001 From: Vajda Simon <75036456+VajdaSimon@users.noreply.github.com> Date: Fri, 29 Jan 2021 15:40:07 +0100 Subject: [PATCH 157/426] bundle_hu.properties (#4464) They spoke on Discord because of an incorrect translation. --- core/assets/bundles/bundle_hu.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_hu.properties b/core/assets/bundles/bundle_hu.properties index 57d4ad79e8..1b32ac77da 100644 --- a/core/assets/bundles/bundle_hu.properties +++ b/core/assets/bundles/bundle_hu.properties @@ -308,7 +308,7 @@ pausebuilding = Használd a(z) [accent][[{0}][] gombot, hogy megállítsd az ép resumebuilding = Használd a(z) [scarlet][[{0}][] gombot, hogy folytasd az építkezést. showui = A kezelőfelület elrejtve.\nNyomja meg a(z) [accent][[{0}][] gombot a megjelenítéséhez. wave = [accent]{0}. Hullám -wave.cap = [accent]{0}/{1}. Hullám +wave.cap = [accent]{0}/{1} Hullám wave.waiting = [lightgray]Következő hullám {0} wave.waveInProgress = [lightgray]Hullám folyamatban waiting = [lightgray]Várakozás... @@ -316,7 +316,7 @@ waiting.players = Várakozás a játékosokra... wave.enemies = [lightgray]Fennmaradó ellenségek: {0} wave.enemycores = [accent]{0}[lightgray] Ellenséges magok wave.enemycore = [accent]{0}[lightgray] Ellenséges mag -wave.enemy = [lightgray]{0} Magmaradt ellenség +wave.enemy = [lightgray]{0} Megmaradt ellenség wave.guardianwarn = Az őrző [accent]{0}[] hullám múlva érkezik. wave.guardianwarn.one = Az őrző [accent]{0}[] hullám múlva érkezik. loadimage = Fénykép betöltése From 9142da2b70ae6a4769e53c16a62ef0ac695c014b Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 29 Jan 2021 12:02:31 -0500 Subject: [PATCH 158/426] Stop shooting upon crawler death --- core/src/mindustry/entities/EntityCollisions.java | 12 ++++-------- core/src/mindustry/input/InputHandler.java | 8 ++++++++ core/src/mindustry/mod/Scripts.java | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/core/src/mindustry/entities/EntityCollisions.java b/core/src/mindustry/entities/EntityCollisions.java index 3425314810..4787c833e7 100644 --- a/core/src/mindustry/entities/EntityCollisions.java +++ b/core/src/mindustry/entities/EntityCollisions.java @@ -190,14 +190,10 @@ public class EntityCollisions{ yInvExit = y2 - (y1 + h1); } - float xEntry, yEntry; - float xExit, yExit; - - xEntry = xInvEntry / vx1; - xExit = xInvExit / vx1; - - yEntry = yInvEntry / vy1; - yExit = yInvExit / vy1; + float xEntry = xInvEntry / vx1; + float xExit = xInvExit / vx1; + float yEntry = yInvEntry / vy1; + float yExit = yInvExit / vy1; float entryTime = Math.max(xEntry, yEntry); float exitTime = Math.min(xExit, yExit); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 4a5c8fe18b..638353b982 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -68,6 +68,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ public Seq lineRequests = new Seq<>(); public Seq selectRequests = new Seq<>(); + public InputHandler(){ + Events.on(UnitDestroyEvent.class, e -> { + if(e.unit != null && e.unit.isPlayer() && e.unit.getPlayer().isLocal() && e.unit.type.weapons.contains(w -> w.bullet.killShooter)){ + player.shooting = false; + } + }); + } + //methods to override @Remote(called = Loc.server, unreliable = true) diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index d1faa3433c..8ef5c8128e 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -23,7 +23,7 @@ import java.util.regex.*; public class Scripts implements Disposable{ private final Seq blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", "runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system", - ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org."); + ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.", "arc.net"); private final Seq whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor"); private final Context context; private final Scriptable scope; From 3d201f7042b462ec0d73a906295bf82df1213fbd Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 31 Jan 2021 15:51:42 -0500 Subject: [PATCH 159/426] Fixed #4474 / Fixed #4475 / Fixed #4476 / Fixed #4483 --- .../src/mindustry/editor/MapEditorDialog.java | 4 +- .../mindustry/editor/MapGenerateDialog.java | 38 ++++++++++--------- core/src/mindustry/game/Universe.java | 3 +- core/src/mindustry/type/UnitType.java | 4 ++ .../ui/dialogs/LaunchLoadoutDialog.java | 2 + 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/core/src/mindustry/editor/MapEditorDialog.java b/core/src/mindustry/editor/MapEditorDialog.java index 316d29f5e6..ba9fe16325 100644 --- a/core/src/mindustry/editor/MapEditorDialog.java +++ b/core/src/mindustry/editor/MapEditorDialog.java @@ -263,7 +263,9 @@ public class MapEditorDialog extends Dialog implements Disposable{ if(player.team().core() == null){ player.set(world.width() * tilesize/2f, world.height() * tilesize/2f); - player.unit(UnitTypes.alpha.spawn(player.team(), player.x, player.y)); + var unit = UnitTypes.alpha.spawn(player.team(), player.x, player.y); + unit.spawnedByCore = true; + player.unit(unit); } }); } diff --git a/core/src/mindustry/editor/MapGenerateDialog.java b/core/src/mindustry/editor/MapGenerateDialog.java index f6a87f77b1..0c4b553a87 100644 --- a/core/src/mindustry/editor/MapGenerateDialog.java +++ b/core/src/mindustry/editor/MapGenerateDialog.java @@ -285,30 +285,32 @@ public class MapGenerateDialog extends BaseDialog{ void showAdd(){ BaseDialog selection = new BaseDialog("@add"); - selection.setFillParent(false); - selection.cont.defaults().size(210f, 60f); - int i = 0; - for(Prov gen : filterTypes){ - GenerateFilter filter = gen.get(); + selection.cont.pane(p -> { + p.marginRight(14); + p.defaults().size(210f, 60f); + int i = 0; + for(Prov gen : filterTypes){ + GenerateFilter filter = gen.get(); - if((filter.isPost() && applied)) continue; + if((filter.isPost() && applied)) continue; - selection.cont.button(filter.name(), () -> { - filters.add(filter); + p.button(filter.name(), () -> { + filters.add(filter); + rebuildFilters(); + update(); + selection.hide(); + }); + if(++i % 2 == 0) p.row(); + } + + p.button("@filter.defaultores", () -> { + maps.addDefaultOres(filters); rebuildFilters(); update(); selection.hide(); }); - if(++i % 2 == 0) selection.cont.row(); - } - - selection.cont.button("@filter.defaultores", () -> { - maps.addDefaultOres(filters); - rebuildFilters(); - update(); - selection.hide(); - }); - + }).get().setScrollingDisabled(true, false); + F selection.addCloseButton(); selection.show(); } diff --git a/core/src/mindustry/game/Universe.java b/core/src/mindustry/game/Universe.java index d602f1ec15..2389b22f7d 100644 --- a/core/src/mindustry/game/Universe.java +++ b/core/src/mindustry/game/Universe.java @@ -123,6 +123,7 @@ public class Universe{ } /** @return the last selected loadout for this specific core type. */ + @Nullable public Schematic getLoadout(CoreBlock core){ //for tools - schem if(schematics == null) return Loadouts.basicShard; @@ -134,7 +135,7 @@ public class Universe{ Seq all = schematics.getLoadouts(core); Schematic schem = all.find(s -> s.file != null && s.file.nameWithoutExtension().equals(file)); - return schem == null ? all.first() : schem; + return schem == null ? all.any() ? all.first() : null : schem; } /** Runs possible events. Resets event counter. */ diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index d2b38efe2c..a72d4669e1 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -299,6 +299,10 @@ public class UnitType extends UnlockableContent{ } } + if(weapons.isEmpty()){ + range = maxRange = 0f; + } + if(mechStride < 0){ mechStride = 4f + (hitSize -8f)/2.1f; } diff --git a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java index 77ae944639..b9e05308e3 100644 --- a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java +++ b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java @@ -5,6 +5,7 @@ import arc.func.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; +import mindustry.content.*; import mindustry.ctype.*; import mindustry.game.*; import mindustry.gen.*; @@ -105,6 +106,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ int cols = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1); ButtonGroup

+ +- 생존: 포탑을 건설하고, 적의 공격을 방어하는 기본적인 타워디펜스 모드입니다. 더욱 길게 생존하여 연구하기 위한 자원을 모으고 출격하는 것도 가능합니다. 공중 보스의 기습 공격에 대비하세요. +- 공격: 공장을 건설하여 적의 코어를 파괴하기 위한 유닛들을 생산하고, 동시에 적의 유닛을 방어하기 위한 방어건물도 건설하세요. 다양한 지원 및 공격 유닛을 만들어서 목표를 달성하세요. 플레이어의 추가 공격을 막기 위한 방어선을 건설하는 적 AI를 선택적으로 활성화할 수 있습니다. +- PvP: 서로의 코어를 파괴하는 4개 이상의 다른 팀과의 경쟁 모드입니다. 유닛을 생성하거나, 당신의 기체로 적의 기지를 바로 공격하세요. +- 샌드박스: 적의 위협 없이 무한한 자원으로 플레이하세요. 디자인을 시험해보기 위해 무한 자원, 전기, 액체와 같은 샌드박스 전용 블록들을 사용해보거나, 원한다면 적을 생성해보세요. + + +

사용자 정의 게임 & 크로스플랫폼 멀티플레이어

+ +- 캠페인에 더하여 커스텀 게임을 위한 16개의 추가적인 맵들이 준비되어 있습니다. +- 협동, PvP 또는 샌드박스를 플레이해보세요! +- 유저들이 운영하는 공개되어있는 공용서버에 접속하거나, 당신만의 비공개서버를 만들고 친구들을 초대해보세요. +- 자유로운 게임 규칙: 블록의 재료 요구량 변경, 적의 능력 수치변경, 시작자원 변경, 단계 대기시간 변경 등 많은 것을 직접 설정할 수 있습니다. +- 게임모드 혼합!: PvP와 PvE를 합쳐 새로운 컨텐츠를 만들어보세요. + + +

사용자 정의 맵 에디터

+ +- 에디터 UI를 사용하여 지형을 그려보세요. +- 인-게임 에디터를 사용하여 맵 미리보기와 수정을 해보세요. +- 도구 모드 설정: 편집 도구의 모드를 바꿔보세요. +- 다양한 타입의 필터와 지형 생성 조건을 설정하고, 강력한 맵 생성 시스템을 사용하여 맵을 만들어보세요. +- 뿌리기, 왜곡, 매끄러움, 침식, 균형, 자원 생성 그리고 지형 무작위 생성 등을 당신의 맵에 적용해보세요. +- 강이나 자원 타일을 배치하는 것 뿐만이 아니라 광물 생성도 랜덤화 하거나, 설정해보세요. +- 적 단계 구성을 설정해보세요. - 맵 규칙을 마음대로 바꿔보세요. +- 80개 이상의 각기 다른 지형 블록들을 사용해보세요. diff --git a/fastlane/metadata/steam/korean/description.txt b/fastlane/metadata/steam/korean/description.txt index 349b368d2f..48aa54705b 100644 --- a/fastlane/metadata/steam/korean/description.txt +++ b/fastlane/metadata/steam/korean/description.txt @@ -17,7 +17,7 @@ [h2]캠페인[/h2] [list] -[*] 250개 이상의 자동으로 생성된 지역들과 16개의 수제 맵들을 지나 전진하면서 세르플로 행성을 정복하세요. +[*] 250개 이상의 자동으로 생성된 지역들과 16개의 내장 맵들을 지나 전진하면서 세르플로 행성을 정복하세요. [*] 지역을 점령하고 당신이 다른 지역에서 플레이하는 동안 자원을 만들도록 공장을 지으세요. [*] 주기적인 공격에게서 당신의 지역들을 지키세요. [*] 지역 자원 수송기를 통해 지역간 자원을 조직화하세요. @@ -52,7 +52,7 @@ [h2]사용자 정의 맵 에디터[/h2] [list] -[*] 에디터 ui를 사용하여 지형을 그려보세요. +[*] 에디터 UI를 사용하여 지형을 그려보세요. [*] 인-게임 에디터를 사용하여 맵 미리보기와 수정을 해보세요. [*] 도구 모드 설정: 편집 도구의 모드를 바꿔보세요. [*] 다양한 타입의 필터와 지형 생성 조건을 설정하고, 강력한 맵 생성 시스템을 사용하여 맵을 만들어보세요. From aef0faf79cff9ff2a62d34719118c5b681a487a6 Mon Sep 17 00:00:00 2001 From: Catchears <57631841+Catchears@users.noreply.github.com> Date: Thu, 11 Feb 2021 16:01:03 +0100 Subject: [PATCH 239/426] update german translation to include logic hints (#4654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update german bundle to "force projector heat issues" https://github.com/Anuken/Mindustry/commit/ea2b57ec4b4ef47847fca6870802655d18b1a8cd ea2b57ec4b4ef47847fca6870802655d18b1a8cd * Gebäude -> Block to prevent confusion --- core/assets/bundles/bundle_de.properties | 130 +++++++++++++++++++++-- 1 file changed, 124 insertions(+), 6 deletions(-) diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index 69d9555103..13c4725bee 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -71,9 +71,9 @@ schematic.disabled = [scarlet]Entwürfe deaktiviert[]\nAuf dieser [accent]Karte[ stats = Statistiken stat.wave = Wellen besiegt:[accent] {0} stat.enemiesDestroyed = Gegner zerstört:[accent] {0} -stat.built = Gebäude gebaut:[accent] {0} -stat.destroyed = Gebäude zerstört:[accent] {0} -stat.deconstructed = Gebäude abgebaut:[accent] {0} +stat.built = Blöcke gebaut:[accent] {0} +stat.destroyed = Blöcke zerstört:[accent] {0} +stat.deconstructed = Blöcke abgebaut:[accent] {0} stat.delivered = Übertragene Ressourcen: stat.playtime = Spielzeit:[accent] {0} stat.rank = Finaler Rang:[accent] {0} @@ -312,6 +312,7 @@ cancelbuilding = [accent][[{0}][] um den Plan zu leeren selectschematic = [accent][[{0}][] zum Auswählen+Kopieren pausebuilding = [accent][[{0}][] um das Bauen zu pausieren resumebuilding = [scarlet][[{0}][] um das Bauen fortzusetzen +enablebuilding = [scarlet][[{0}][] um zu bauen showui = Bedienflächen versteckt.\nDrücke [accent][[{0}][], um sie wieder anzuzeigen. wave = [accent]Welle {0} wave.cap = [accent]Welle {0}/{1} @@ -683,6 +684,7 @@ stat.drillspeed = Bohrgeschwindigkeit stat.boosteffect = Verstärkungseffekt stat.maxunits = Max. aktive Einheiten stat.health = Lebenspunkte +stat.armour = Panzer stat.buildtime = Baudauer stat.maxconsecutive = Max. Konsekutive stat.buildcost = Baukosten @@ -794,6 +796,7 @@ setting.shadows.name = Schatten setting.blockreplace.name = Automatische Blockvorschläge setting.linear.name = Lineare Filterung setting.hints.name = Tipps +setting.logichints.name = Logiktipps setting.flow.name = Ressourcen-Fluss anzeigen setting.backgroundpause.name = Im Hintergrund pausieren setting.buildautopause.name = Bauen automatisch pausieren @@ -963,7 +966,7 @@ rules.waitForWaveToEnd = Warten bis Welle endet rules.dropzoneradius = Drop-Zonen-Radius:[lightgray] (Kacheln) rules.unitammo = Einheiten benötigen Munition rules.title.waves = Wellen -rules.title.resourcesbuilding = Ressourcen & Gebäude +rules.title.resourcesbuilding = Ressourcen & Blöcke rules.title.enemy = Gegner rules.title.unit = Einheiten rules.title.experimental = Experimentell @@ -1318,7 +1321,7 @@ item.coal.details = Scheint versteinerte Pflanzenmasse zu sein, die sich schon l item.titanium.description = Wird im Flüssigkeitsbereich, im Bohrerbereich und für Flugzeuge vielfältig eingesetzt. item.thorium.description = Wird als festes Baumaterial oder radioaktiver Kraftstoff verwendet. item.scrap.description = Wird in Pulverisierer und Schmelzer zu anderen Materialien bearbeitet. -item.scrap.details = Übriggebliebene Reste alter Gebäude oder Einheiten. +item.scrap.details = Übriggebliebene Reste alter Blöcke oder Einheiten. item.silicon.description = Wird in Solarzellen, komplizierter Elektronik und als zielsuchende Munition verwendet. item.plastanium.description = Wird für fortgeschrittene Einheiten, Isolation und Munition eingesetzt. item.phase-fabric.description = Kann in Elektronik und selbstreparierende Blöcke verwendet werden. @@ -1510,4 +1513,119 @@ unit.sei.description = Schießt ein Sperrfeuer aus Raketen und durchdringende Ge unit.omura.description = Schießt eine Railgun mit hoher Reichweite, um Gegner zu zerstören. Stellt Flare-Einheiten her. unit.alpha.description = Beschützt den Scherbenkern vor Feinden. Baut Blöcke. unit.beta.description = Beschützt den Fundamentkern vor Feinden. Baut Blöcke. -unit.gamma.description = Beschützt den Nukleuskern vor Feinden. Baut Blöcke. \ No newline at end of file +unit.gamma.description = Beschützt den Nukleuskern vor Feinden. Baut Blöcke. + +lst.read = Liest einen Wert aus einer verbundenen Spiecherzelle. +lst.write = Schreibt eine Zahl in einer verbundene Speicherzelle. +lst.print = Fügt Text zum Textspeicher hinzu.\nZeigt nichts an, bis [accent]Print Flush[] verwendet wird. +lst.draw = Fügt eine [accent]Draw[]-Aufgabe zum Bildspeicher hinzu.\nZeigt nichts an, bis [accent]Draw Flush[] verwendet wird. +lst.drawflush = Druckt [accent]Draw[]-Aufgaben aus dem Bildspeicher auf einen Bildschirm. +lst.printflush = Druckt [accent]Print[]-Aufgaben aus dem Textspeicher auf einen Nachrichtenblock. +lst.getlink = Gibt ein verbundenen Block wieder. Fängt bei 0 an. +lst.control = Steuert einen Block. +lst.radar = Findet Einheiten. +lst.sensor = Gibt Daten über einen Block oder eine Einheit wieder. +lst.set = Setzt eine Variable fest. +lst.operation = Verändert eine Variable. +lst.end = Springt wieder nach oben. +lst.jump = Falls die Bedingung erfüllt ist, wird woanders weitergemacht. +lst.unitbind = Speichert eine Einheit einer Sorte als [accent]@unit[]. +lst.unitcontrol = Steuert [accent]@unit[]. +lst.unitradar = Findet Einheiten in der Nähe von [accent]@unit[]. +lst.unitlocate = Findet mit [accent]@unit[] bestimmte Positionen / Blöcke auf der ganzen Karte. + +lenum.type = Englischer Name eines Blocks / einer Einheit. Ein Verteiler gibt [accent]@router[] wieder.\nKein string. +lenum.shoot = Schießt auf eine Position. +lenum.shootp = Schießt auf eine Einheit / einen Block und sagt deren Position voraus. +lenum.configure = Blockkonfiguration, z.B. das ausgewählte Item in einem Sortierer. +lenum.enabled = Ob der Block an oder aus ist. +lenum.color = Illuminiererfarbe. + +lenum.always = Immer. +lenum.idiv = Division mit ganzen Zahlen. +lenum.div = Division.\nGibt bei Teilung durch null [accent]null[] zurück. +lenum.mod = Modulo. +lenum.equal = Prüft Gleichheit.\nNicht-"null" Objekte, die mit Zahlen verglichen werden, werden 1. +lenum.notequal = Prüft Ungleichheit. +lenum.strictequal = Prüft strenge Gleichheit.\nKann verwendet werden, um "null" zu finden. +lenum.shl = Bit-shift nacht links. +lenum.shr = Bit-shift nach rechts. +lenum.or = Bitwise ODER. +lenum.land = Logisches AND. +lenum.and = Bitwise UND. +lenum.not = Bitwise NOT. +lenum.xor = Bitwise XOR. + +lenum.min = Die Größte von zwei Zahlen. +lenum.max = Die Kleinste von zwei Zahlen. +lenum.angle = Angle of vector in degrees. +lenum.len = Length of vector. +lenum.sin = Sinus in Grad. +lenum.cos = Cosinus in Grad. +lenum.tan = Tangens in Grad. +lenum.rand = Zufällige Zahl zwischen [0, ). +lenum.log = Logarithmus (ln). +lenum.log10 = Logarithmus zur Basis 10. +lenum.noise = 2D rauschen. +lenum.abs = Betrag. +lenum.sqrt = Quadratwurzel. + +lenum.any = Irgendeine Einheit. +lenum.ally = Freundliche Einheit. +lenum.attacker = Einheit mit Waffe. +lenum.enemy = Gegnerische Einheit. +lenum.boss = Bosseinheit. +lenum.flying = Lufteinheit. +lenum.ground = Bodeneinheit. +lenum.player = Spielergesteuerte Einheit. + +lenum.ore = Erz. +lenum.damaged = Beschädigter, alliierter Block. +lenum.spawn = Gegnerischer Spawnpunkt.\nKann ein Kern oder eine Position sein. +lenum.building = Ein Block einer bestimmten Sorte. + +lenum.core = Irgendein Kern. +lenum.storage = Speicherblock, z.B. ein Tresor. + +sensor.in = Der Block / die Einheit. + +radar.from = Block zu benutzen. [accent]Sensor[]-Reichweite hängt von der Blockreichweite ab. +radar.target = Einheitenfilter. +radar.and = Weitere Filter. +radar.order = Sortierreihenfolge der Ergebnisse. 0 bedeutet rückwärts. +radar.sort = Sortiermethode der Ergebnisse. +radar.output = Variable für das Ergebnis. + +unitradar.target = Einheitenfilter. +unitradar.and = Weitere Filter. +unitradar.order = Sortierreihenfolge der Ergebnisse. 0 bedeutet rückwärts. +unitradar.sort = Sortiermethode der Ergebnisse. +unitradar.output = Variable für das Ergebnis. + +control.of = Block, der gesteuert werden soll. +control.unit = Zieleinheit / Zielblock. +control.shoot = Ob geschossen werden soll. + +unitlocate.enemy = Ob gegnerische Blöcke gesucht werden sollen. +unitlocate.found = Ob der Block gefunden wurde. +unitlocate.building = Variable für das Ergebnis. +unitlocate.outx = Variable für die X-Koordinate. +unitlocate.outy = Variable für die Y-Koordinate. +unitlocate.group = Gesuchter Blocktyp. + +lenum.stop = Bewegung / Abbau / Bau abbrechen. +lenum.move = Geht zu diese Position. +lenum.approach = Geht auf einen Punkt mit einem bestimmten Radius zu. +lenum.pathfind = Geht zum gegnerischen Spawnpunkt. +lenum.target = Schießt auf eine Position. +lenum.targetp = Schießt auf eine Einheit und sagt deren Position voraus. +lenum.itemdrop = Items abwerfen. +lenum.itemtake = Items aus einem Block nehmen. +lenum.paydrop = Lässt einen Block / eine Einheit wieder fallen. +lenum.paytake = Hebt einen Block / eine kleine Einheit auf. +lenum.flag = Zahl, mit der eine Einheit identifiziert werden kann. +lenum.mine = Erz von einer Position abbauen. +lenum.build = Einen Block bauen. +lenum.getblock = Gibt den Blocktyp an den Koordinaten zurück.\nEinheiten müssen nah genug dran sein.\nFeste nicht-Blöcke sind [accent]@solid[]. +lenum.within = Prüft, ob eine Einheit in einem Radius um einen Punkt ist. +lenum.boost = Aktiviert / deaktiviert den Boost. \ No newline at end of file From 27c8efc672fa91d6e885606466a17e5a8f9af5c8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 11 Feb 2021 10:12:07 -0500 Subject: [PATCH 240/426] Better targeting range calculation --- core/assets/bundles/bundle.properties | 1 + core/assets/maps/mudFlats.msav | Bin 28161 -> 28248 bytes core/src/mindustry/ai/BlockIndexer.java | 9 ++++----- core/src/mindustry/content/Blocks.java | 1 + core/src/mindustry/entities/Units.java | 7 ++++--- .../mindustry/entities/comp/BuildingComp.java | 7 ++++++- .../mindustry/entities/comp/HitboxComp.java | 7 ++++++- core/src/mindustry/entities/comp/Sized.java | 5 +++++ gradle.properties | 2 +- ios/robovm.xml | 1 - 10 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 core/src/mindustry/entities/comp/Sized.java diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index bcb64901f8..9b3a8136b5 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1563,6 +1563,7 @@ lenum.len = Length of vector. lenum.sin = Sine, in degrees. lenum.cos = Cosine, in degrees. lenum.tan = Tangent, in degrees. +#not a typo, look up 'range notation' lenum.rand = Random number in range [0, value). lenum.log = Natural logarithm (ln). lenum.log10 = Base 10 logarithm. diff --git a/core/assets/maps/mudFlats.msav b/core/assets/maps/mudFlats.msav index 1ba2e25cebe9b0156113552fa4253da48cf15071..adca422b83795cdeb581b64ca6a8ec805ea7ab72 100644 GIT binary patch delta 28191 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 r7g`+9cC|3&M{*Gb6hpJ&~4b+VJ` z^|Ti8-OE3k9^;-m-|_6tEf3`cmOjju)9BuBXyyL>-!g59cir!=%}S_^%ijLwr+8ao zf0Bf89iPOd3w!@no!b6Yf7`p`*S6c3_v|z+H&fmhlzC5V|C-uo*{^#}*Jk+LzBWsy zUgFuDsn2uVm;P+c|&U;RkD>dI`Sikgp?}bQ_dt2_+M_-rx(o*ouuIwi_3xC!Lq?eDfu8ZL9gBdaHl8WRk)&-muy&l)mue+J<+F^{SStx4$Y5 z>;E_P&U62$Z=av4FG{ysCekCX{PypEs}H+(r5`?(Z&l&vzy0F#WlLq(-oNzgNSDp` z#x+l0c-pRdeXag>z2&9-JoDB{t<8O~d6&NPeA7$oWX=CAKTuZ^yGFP6nSaLJ_PZ_F zM*O^wWxD^@o7CmH)mr?ufBB-4HR^b*L4Tn8nq-H_CmDsho%=LpSBF<0jFb0HzkFeS z7Vqw_s{apnJZE?FZ@#?map%ct_tZcA`JYpBC+yH(J3IdQ`lq56{W@)Wp7(J}Q^JKm zW#NAsmu{SDv)VHB^#9|RmRFvS`orIp{`HA=?ED)-XQI6S+a4}lHT43Af0vy3XWM^Yq_L$|u6@hZ_Yw1pj{h)Dm1c|mQ;yQA4>fZar+s_+-LX0UPyI~hoW*KeO7CxfwRms+?G5{! zuZNm1-Mi~c@3oA`{U4bZFF#bNFMLjYtJxCW$8+X!FZjCk)_1S{ncp_DTQAK|UhdAA zyEgN_(XMS3bKTAs%)NE*_solv@Ah1=t&GgD-T3YK`J?Zm4@UCr(htq-kzAX3?U(w0 zH-6dIry1vNTO+(`{fv697e6Wz;y+o*`Jdd7cH-2FnI8-1U)ucmN$tXisV`oZr2f(C z*y|_xuK(|aABJDWoem!}`R;b%!ksl&P3`x8+Vx@Lg&#{lT1G7WxbtF^yZ_?ch~zNw z-QjUHzAKj}ChseJ_%wKNrR60JHWR6~-$MIL_*4DYEx#x%v+DP*Zwt1l2}{+xUesQi z`210Dlk@AHUW~kVxvx$5cX7K*#QnP*8E3e7*JkTGm48h!S+8F8t#jQ~&AIU$^3(cc zjZO6Lny#_FVi~4+;j^2=cC{~S{``x1k+JVEM{V!t-D+#3mG`REG*3UOJ~2=7bGuV{ z;5==~wTV|I&)q4$M(jnn>x=EK^W84~-&p_Al;vN_?b?;Eza~2$EQnjN=|au+`I|rG zOl^87SHA9MasTR5^@o2*9ND(}?X9o1-!?w1So6AK-?qc+cW3QcXL;E2@YiP(_VrdS zYyG$D;mPBdH?{wpnRvGQnpxJ}`Nueo+bTU@i~s%Aw!S^m{7$>IYN?bz)2yuXXIZB2 zJ9=<__V)_vYfOmJe$!+n>d={9W?3JyCb%JYQ4g zEn+?EKVIEEb8P;~MAv^0E7YBq&&!n=Woc(> z^WGsYu(J$msR;x&CR7%!QXMX4ko2WCY_14j8ytbQNZtsvk5uBNAyNEO6 z*DT3PTkKrUCtUs&ayImK{f`{)7uj!%JmSB*zI?eV+wFYX4fpvs%HFg6TK;f>!-qk#7@T^{=>~Cm7akkO>`b##m z*Ogx9{a&77lW4!y&Exy|*Pge^Y+g$4(@i+^a>ewIYaZM+S~K|t>))rZQzN{WZ~1Do z!gA%u-#cH_GJf50W#Pzdw96q4Lgpx3I($y)iOh{u-Rj%FvtkXU?U%6uwp8rkNUT zSkZQKqlLKQ`TE1p|J+bocYWob<`cD_%MPC|RoR*QboSpVb_dh*yxv_n6=%QxmhiU6 zM;_hdGD|6`60wunyB71_b+?hd-T2#R?i2C9{QEWQrT#dtjefUpi69Ht~nI1 zP5vM(8vQ%1UFKZNiXg9?q@07BXMVKYzv6LqbvF^`(L&-50UuxU3-)FX*U;kjjbL*`giVfmr&NsFFzSvYp%C>KAuI)fn!_ncWzCq19?_0ewy%j?rQzgzU`KM#0NWgi#) z!{l>|^_2QADi04$EIi+}*1&hihmgg}>#v-P-EmL8|M8!VZ><}iEZU-Tj_ZLE^ZML_ z^`ANC?SF6gKEB)L_QY>9*1b_r@_qC2-}g(~v@aeKHoGMC!MHv8uWsmrYte<;`!?TJ z&pUp2t-;2Gs`|xs^CX|wzs~wExh!37NqPN}@*UX*m#b9g)z7^*^ObD=>z$(iTf5Zn zXPv*hq?Fb9Z}Hx870cSS>^}tfTKn%kSR-V8^Na1t`tbLh$Df~6?_R}U{_ue3O@oRh zk?F6`nt%NNS5Gd6%TDcn>vi*@lv7oo|M32~x^b=c{IyRza&v&t_&EIvjy32&0ojN4G#4Fl+#s_hWXX%Lxf8RM5mv!brX{1!lquUXx zX_7JPVr!eVx$pj|-`3{-&ieV0=PS>KoIV(?me%B3ySDJ-M_a?9FWmoPir1>&+5F|~ zaj}j3MU59!`~K@aEb32PXgDXE?@R0Hn+o4!58hq1r2w%-3YF1&yCTz>J-QxyOU%ri0o delta 27958 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 pred, boolean usePriority){ Building closest = null; float dst = 0; - float range2 = range * range; for(int rx = Math.max((int)((x - range) / tilesize / quadrantSize), 0); rx <= (int)((x + range) / tilesize / quadrantSize) && rx < quadWidth(); rx++){ for(int ry = Math.max((int)((y - range) / tilesize / quadrantSize), 0); ry <= (int)((y + range) / tilesize / quadrantSize) && ry < quadHeight(); ry++){ @@ -282,13 +281,13 @@ public class BlockIndexer{ if(e == null || e.team != team || !pred.get(e) || !e.block.targetable || e.team == Team.derelict) continue; - float ndst = e.dst2(x, y); - if(ndst < range2 && (closest == null || + float bdst = e.dst(x, y) - e.hitSize() / 2f; + if(bdst < range && (closest == null || //this one is closer, and it is at least of equal priority - (ndst < dst && (!usePriority || closest.block.priority.ordinal() <= e.block.priority.ordinal())) || + (bdst < dst && (!usePriority || closest.block.priority.ordinal() <= e.block.priority.ordinal())) || //priority is used, and new block has higher priority regardless of range (usePriority && closest.block.priority.ordinal() < e.block.priority.ordinal()))){ - dst = ndst; + dst = bdst; closest = e; } } diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index e73ffc89db..e9f8abf2a4 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -2047,6 +2047,7 @@ public class Blocks implements ContentList{ hasPower = true; consumes.power(10f); buildCostMultiplier = 0.5f; + health = size * size * 80; }}; //endregion campaign diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index cd602327a6..3d73faebd6 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -6,6 +6,7 @@ import arc.math.geom.*; import arc.struct.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; +import mindustry.entities.comp.*; import mindustry.game.*; import mindustry.game.Teams.*; import mindustry.gen.*; @@ -93,7 +94,7 @@ public class Units{ * @return whether the target is invalid */ public static boolean invalidateTarget(Posc target, Team team, float x, float y, float range){ - return target == null || (range != Float.MAX_VALUE && !target.within(x, y, range)) || (target instanceof Teamc && ((Teamc)target).team() == team) || (target instanceof Healthc && !((Healthc)target).isValid()); + return target == null || (range != Float.MAX_VALUE && !target.within(x, y, range + (target instanceof Sized hb ? hb.hitSize()/2f : 0f))) || (target instanceof Teamc t && t.team() == team) || (target instanceof Healthc h && !h.isValid()); } /** See {@link #invalidateTarget(Posc, Team, float, float, float)} */ @@ -217,7 +218,7 @@ public class Units{ cdist = 0f; nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> { - if(e.dead() || !predicate.get(e) || !e.within(x, y, range)) return; + if(e.dead() || !predicate.get(e) || !e.within(x, y, range + e.hitSize/2f)) return; float cost = sort.cost(e, x, y); if(result == null || cost < cdist){ @@ -292,7 +293,7 @@ public class Units{ /** Iterates over all units in a circle around this position. */ public static void nearby(Team team, float x, float y, float radius, Cons cons){ nearby(team, x - radius, y - radius, radius*2f, radius*2f, unit -> { - if(unit.within(x, y, radius)){ + if(unit.within(x, y, radius + unit.hitSize/2f)){ cons.get(unit); } }); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 747defe555..b368d060e0 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -43,7 +43,7 @@ import static mindustry.Vars.*; @EntityDef(value = {Buildingc.class}, isFinal = false, genio = false, serialize = false) @Component(base = true) -abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable, Senseable, Controllable{ +abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable, Senseable, Controllable, Sized{ //region vars and initialization static final float timeToSleep = 60f * 1, timeToUncontrol = 60f * 6; static final ObjectSet tmpTiles = new ObjectSet<>(); @@ -1277,6 +1277,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, return tile.build == self() && !dead(); } + @Override + public float hitSize(){ + return tile.block().size * tilesize; + } + @Replace @Override public void kill(){ diff --git a/core/src/mindustry/entities/comp/HitboxComp.java b/core/src/mindustry/entities/comp/HitboxComp.java index f44270ebed..82576686fe 100644 --- a/core/src/mindustry/entities/comp/HitboxComp.java +++ b/core/src/mindustry/entities/comp/HitboxComp.java @@ -8,7 +8,7 @@ import mindustry.annotations.Annotations.*; import mindustry.gen.*; @Component -abstract class HitboxComp implements Posc, QuadTreeObject{ +abstract class HitboxComp implements Posc, Sized, QuadTreeObject{ @Import float x, y; transient float lastX, lastY, deltaX, deltaY, hitSize; @@ -28,6 +28,11 @@ abstract class HitboxComp implements Posc, QuadTreeObject{ updateLastPosition(); } + @Override + public float hitSize(){ + return hitSize; + } + void getCollisions(Cons consumer){ } diff --git a/core/src/mindustry/entities/comp/Sized.java b/core/src/mindustry/entities/comp/Sized.java new file mode 100644 index 0000000000..5fd73efa42 --- /dev/null +++ b/core/src/mindustry/entities/comp/Sized.java @@ -0,0 +1,5 @@ +package mindustry.entities.comp; + +public interface Sized{ + float hitSize(); +} diff --git a/gradle.properties b/gradle.properties index fbe236418e..88888d07c9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=8b6d59e004463585b333c8cda9ea91dd66f3bcee +archash=5b04a94d53e279e3af3a2654978fff5ab16e7cb8 diff --git a/ios/robovm.xml b/ios/robovm.xml index e792b258a8..c82b246fad 100644 --- a/ios/robovm.xml +++ b/ios/robovm.xml @@ -2,7 +2,6 @@ ${app.executable} ${app.mainclass} ios - thumbv7 ios Info.plist.xml From 0350e6bbf4bf7bd7596322ba598d5dd1b989cc94 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 11 Feb 2021 12:03:11 -0500 Subject: [PATCH 241/426] Validate teams with power links --- core/src/mindustry/entities/comp/BuildingComp.java | 3 ++- .../world/blocks/defense/turrets/TractorBeamTurret.java | 2 +- core/src/mindustry/world/blocks/units/RepairPoint.java | 2 +- gradle.properties | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index b368d060e0..f270929f3a 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -792,6 +792,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, for(Building other : proximity){ if(other != null && other.power != null + && other.team == team && !(block.consumesPower && other.block.consumesPower && !block.outputsPower && !other.block.outputsPower) && conductsTo(other) && other.conductsTo(self()) && !power.links.contains(other.pos())){ out.add(other); @@ -800,7 +801,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, for(int i = 0; i < power.links.size; i++){ Tile link = world.tile(power.links.get(i)); - if(link != null && link.build != null && link.build.power != null) out.add(link.build); + if(link != null && link.build != null && link.build.power != null && link.build.team == team) out.add(link.build); } return out; } diff --git a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java index a56d648b3d..a7a94a4ad1 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/TractorBeamTurret.java @@ -98,7 +98,7 @@ public class TractorBeamTurret extends BaseTurret{ any = false; //look at target - if(target != null && target.within(this, range) && target.team() != team && target.checkTarget(targetAir, targetGround) && efficiency() > 0.02f){ + if(target != null && target.within(this, range + target.hitSize/2f) && target.team() != team && target.checkTarget(targetAir, targetGround) && efficiency() > 0.02f){ if(!headless){ control.sound.loop(shootSound, this, shootSoundVolume); } diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index 80664cbee3..72e0f506d2 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -95,7 +95,7 @@ public class RepairPoint extends Block{ @Override public void updateTile(){ boolean targetIsBeingRepaired = false; - if(target != null && (target.dead() || target.dst(tile) > repairRadius || target.health() >= target.maxHealth())){ + if(target != null && (target.dead() || target.dst(tile) - target.hitSize/2f > repairRadius || target.health() >= target.maxHealth())){ target = null; }else if(target != null && consValid()){ target.heal(repairSpeed * Time.delta * strength * efficiency()); diff --git a/gradle.properties b/gradle.properties index 88888d07c9..67ecd167b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=5b04a94d53e279e3af3a2654978fff5ab16e7cb8 +archash=d23d0f0b3625ab2d7d97e6c89a773ab6a4ad8434 From cd684996e137b570fc58bacf6349b7d404f35fb1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 11 Feb 2021 16:31:44 -0500 Subject: [PATCH 242/426] Cleanup & Steam crash fix --- core/src/mindustry/Vars.java | 10 +++++----- core/src/mindustry/editor/MapEditorDialog.java | 5 ++++- core/src/mindustry/ui/dialogs/JoinDialog.java | 2 +- core/src/mindustry/world/meta/PowerType.java | 7 ------- desktop/src/mindustry/desktop/DesktopLauncher.java | 1 + 5 files changed, 11 insertions(+), 14 deletions(-) delete mode 100644 core/src/mindustry/world/meta/PowerType.java diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 6126bb77a6..ec002b6325 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -38,6 +38,8 @@ public class Vars implements Loadable{ public static boolean loadedLogger = false, loadedFileLogger = false; /** Whether to enable various experimental features (e.g. cliffs) */ public static boolean experimental = false; + /** Name of current Steam player. */ + public static String steamPlayerName = ""; /** Maximum extra padding around deployment schematics. */ public static final int maxLoadoutSchematicPad = 5; /** Maximum schematic size.*/ @@ -54,16 +56,14 @@ public class Vars implements Loadable{ public static final String ghApi = "https://api.github.com"; /** URL for discord invite. */ public static final String discordURL = "https://discord.gg/mindustry"; - /** URL for sending crash reports to */ + /** URL for sending crash reports to. Currently offline. */ public static final String crashReportURL = "http://192.99.169.18/report"; /** URL the links to the wiki's modding guide.*/ public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/"; - /** URL to the JSON file containing all the global, public servers. Not queried in BE. */ - public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json"; /** URL to the JSON file containing all the BE servers. Only queried in BE. */ public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json"; - /** URL to the JSON file containing all the BE servers. Only queried in the V6 alpha (will be removed once it's out). */ - public static final String serverJsonV6URL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json"; + /** URL to the JSON file containing all the BE servers. */ + public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json"; /** URL of the github issue report template.*/ public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md"; /** list of built-in servers.*/ diff --git a/core/src/mindustry/editor/MapEditorDialog.java b/core/src/mindustry/editor/MapEditorDialog.java index ba9fe16325..747615a637 100644 --- a/core/src/mindustry/editor/MapEditorDialog.java +++ b/core/src/mindustry/editor/MapEditorDialog.java @@ -156,7 +156,10 @@ public class MapEditorDialog extends Dialog implements Disposable{ } platform.publish(map); - }).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.tags.containsKey("steamid") ? editor.tags.get("author").equals(player.name) ? "@workshop.listing" : "@view.workshop" : "@editor.publish.workshop")); + }).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> + b.setText(editor.tags.containsKey("steamid") ? + editor.tags.get("author").equals(steamPlayerName) ? "@workshop.listing" : "@view.workshop" : + "@editor.publish.workshop")); menu.cont.row(); } diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index 4f858a67ff..166b4c53a9 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -513,7 +513,7 @@ public class JoinDialog extends BaseDialog{ Core.settings.remove("server-list"); } - var url = becontrol.active() ? serverJsonBeURL : serverJsonV6URL; + var url = becontrol.active() ? serverJsonBeURL : serverJsonURL; Log.info("Fetching community servers at @", url); //get servers diff --git a/core/src/mindustry/world/meta/PowerType.java b/core/src/mindustry/world/meta/PowerType.java deleted file mode 100644 index 3f870ce85a..0000000000 --- a/core/src/mindustry/world/meta/PowerType.java +++ /dev/null @@ -1,7 +0,0 @@ -package mindustry.world.meta; - -public enum PowerType{ - consumer, - producer, - bridge -} diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index 8b9d0a7487..cf60813b7b 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -130,6 +130,7 @@ public class DesktopLauncher extends ClientLauncher{ player.name = SVars.net.friends.getPersonaName(); Core.settings.put("name", player.name); } + steamPlayerName = SVars.net.friends.getPersonaName(); //update callbacks Core.app.addListener(new ApplicationListener(){ @Override From 0cc64c6a8d80d1338e8bedb4133f5fe8fb9cb9de Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 08:41:36 -0500 Subject: [PATCH 243/426] Fixed #4658 --- core/src/mindustry/core/NetClient.java | 2 +- core/src/mindustry/core/NetServer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index 2b0e4322c0..d89b7f8481 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -481,7 +481,7 @@ public class NetClient implements ApplicationListener{ netClient.byteStream.setBytes(net.decompressSnapshot(coreData, coreDataLen)); DataInputStream input = netClient.dataStream; - byte cores = input.readByte(); + int cores = input.readInt(); for(int i = 0; i < cores; i++){ int pos = input.readInt(); Tile tile = world.tile(pos); diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 73fcf3b8e4..9ce38aa62a 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -852,7 +852,7 @@ public class NetServer implements ApplicationListener{ syncStream.reset(); int sum = state.teams.present.sum(t -> t.cores.size); - dataStream.writeByte(sum); + dataStream.writeInt(sum); for(TeamData data : state.teams.present){ for(CoreBuild entity : data.cores){ From 0fe158d080bf20a38e58b3b53a5720afb0c7b9a6 Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Fri, 12 Feb 2021 22:42:35 +0900 Subject: [PATCH 244/426] [KO] i got typo! (#4662) * [KO] i got typo! * typo --- core/assets/bundles/bundle_ko.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 87f11bc2cd..891249bb55 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -823,7 +823,7 @@ setting.screenshake.name = 화면 흔들림 setting.effects.name = 효과 표시 setting.destroyedblocks.name = 파괴된 블록 표시 setting.blockstatus.name = 블록 상태 표시 -setting.conveyorpathfinding.name = 컨베이어를 배치 길찾기 +setting.conveyorpathfinding.name = 컨베이어 배치 길찾기 setting.sensitivity.name = 컨트롤러 감도 setting.saveinterval.name = 저장 간격 setting.seconds = {0}초 @@ -1517,7 +1517,7 @@ unit.gamma.description = 적으로부터 코어: 핵심을 방어합니다. 구 lst.read = 연결된 메모리 셀에서 숫자 읽기 lst.write = 연결된 메모리 셀에 숫자 쓰기 -lst.print = 프린트 버퍼에 텍스트 추가하기\nD[accent]Print Flush[]가 사용되기 전까진 아무것도 보여주지 않습니다. +lst.print = 프린트 버퍼에 텍스트 추가하기\n[accent]Print Flush[]가 사용되기 전까진 아무것도 보여주지 않습니다. lst.draw = 드로잉 버퍼에 실행문 추가하기\n[accent]Draw Flush[]가 사용되기 전까진 아무것도 보여주지 않습니다. lst.drawflush = 대기중인 [accent]Draw[]실행문을 디스플레이에 출력하기 lst.printflush = 대기중인 [accent]Print[]실행문을 메시지 블록에 출력하기 From 0d084d380d648a939997a1efcfd288a5110527bd Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 08:56:40 -0500 Subject: [PATCH 245/426] Fixed map resize not preserving links --- core/src/mindustry/editor/MapEditor.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/editor/MapEditor.java b/core/src/mindustry/editor/MapEditor.java index c460d7c042..9b62ae40a6 100644 --- a/core/src/mindustry/editor/MapEditor.java +++ b/core/src/mindustry/editor/MapEditor.java @@ -8,6 +8,7 @@ import arc.math.geom.*; import arc.struct.*; import mindustry.content.*; import mindustry.editor.DrawOperation.*; +import mindustry.entities.units.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.io.*; @@ -259,7 +260,7 @@ public class MapEditor{ clearOp(); Tiles previous = world.tiles; - int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2; + int offsetX = (width() - width) / 2, offsetY = (height() - height) / 2; loading = true; Tiles tiles = world.resize(width, height); @@ -275,7 +276,17 @@ public class MapEditor{ if(tile.build != null && tile.isCenter()){ tile.build.x = x * tilesize + tile.block().offset; tile.build.y = y * tilesize + tile.block().offset; + + //shift links to account for map resize + Object config = tile.build.config(); + if(config != null){ + Object out = BuildPlan.pointConfig(tile.block(), config, p -> p.sub(offsetX, offsetY)); + if(out != config){ + tile.build.configureAny(out); + } + } } + }else{ tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0)); } From 541da5c0c94f4df5c4e541ade425828b060cb8f0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 09:09:10 -0500 Subject: [PATCH 246/426] Block flag documentation & cleanup --- core/assets/bundles/bundle.properties | 8 ++++++++ core/src/mindustry/logic/LStatements.java | 2 +- core/src/mindustry/world/blocks/power/ImpactReactor.java | 2 ++ core/src/mindustry/world/blocks/power/NuclearReactor.java | 2 +- core/src/mindustry/world/meta/BlockFlag.java | 3 +++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 9b3a8136b5..357d5290cc 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1587,6 +1587,14 @@ lenum.building = Building in a specific group. lenum.core = Any core. lenum.storage = Storage building, e.g. Vault. +lenum.generator = Buildings that generate power. +lenum.factory = Buildings that transform resources. +lenum.repair = Repair points. +lenum.rally = Command center. +lenum.battery = Any battery. +lenum.resupply = Resupply points.\nOnly relevant when [accent]"Unit Ammo"[] is enabled. +lenum.reactor = Impact/Thorium reactor. +lenum.turret = Any turret. sensor.in = The building/unit to sense. diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index a9c502cd6a..cfa1345ec2 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -917,7 +917,7 @@ public class LStatements{ table.add(" group ").left().self(this::param);; table.button(b -> { b.label(() -> flag.name()); - b.clicked(() -> showSelect(b, BlockFlag.all, flag, t -> flag = t, 2, cell -> cell.size(110, 50))); + b.clicked(() -> showSelect(b, BlockFlag.allLogic, flag, t -> flag = t, 2, cell -> cell.size(110, 50))); }, Styles.logict, () -> {}).size(110, 40).color(table.color).left().padLeft(2); row(table); diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index 7ecffccd1c..09a7c9acb8 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -4,6 +4,7 @@ import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; +import arc.struct.*; import arc.util.*; import arc.util.io.*; import mindustry.annotations.Annotations.*; @@ -38,6 +39,7 @@ public class ImpactReactor extends PowerGenerator{ liquidCapacity = 30f; hasItems = true; outputsPower = consumesPower = true; + flags = EnumSet.of(BlockFlag.reactor, BlockFlag.generator); } @Override diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index 7dd8be9f07..aa7eed3b71 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -48,7 +48,7 @@ public class NuclearReactor extends PowerGenerator{ hasItems = true; hasLiquids = true; rebuildable = false; - flags = EnumSet.of(BlockFlag.reactor); + flags = EnumSet.of(BlockFlag.reactor, BlockFlag.generator); } @Override diff --git a/core/src/mindustry/world/meta/BlockFlag.java b/core/src/mindustry/world/meta/BlockFlag.java index f1778accff..2fad22868e 100644 --- a/core/src/mindustry/world/meta/BlockFlag.java +++ b/core/src/mindustry/world/meta/BlockFlag.java @@ -28,4 +28,7 @@ public enum BlockFlag{ extinguisher; public final static BlockFlag[] all = values(); + + /** Values for logic only. Filters out some internal flags. */ + public final static BlockFlag[] allLogic = {core, storage, generator, turret, factory, repair, rally, battery, resupply, reactor}; } From abd07e15259b76829bffeac5fe18cfc59266f212 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 12:55:31 -0500 Subject: [PATCH 247/426] Fixed chat not working while paused --- .../mindustry/ui/fragments/ChatFragment.java | 3 +- gradle.properties | 2 +- .../mindustry/tools/BindingsGenerator.java | 102 ++++++++++++++++++ .../mindustry/tools/ScriptMainGenerator.java | 5 +- 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 tools/src/mindustry/tools/BindingsGenerator.java diff --git a/core/src/mindustry/ui/fragments/ChatFragment.java b/core/src/mindustry/ui/fragments/ChatFragment.java index 58b7735c23..75eaac5ab0 100644 --- a/core/src/mindustry/ui/fragments/ChatFragment.java +++ b/core/src/mindustry/ui/fragments/ChatFragment.java @@ -15,7 +15,6 @@ import arc.util.*; import mindustry.*; import mindustry.gen.*; import mindustry.input.*; -import mindustry.type.*; import mindustry.ui.*; import static arc.Core.*; @@ -206,7 +205,7 @@ public class ChatFragment extends Table{ } }else{ //sending chat has a delay; workaround for issue #1943 - Time.run(2f, () ->{ + Time.runTask(2f, () ->{ scene.setKeyboardFocus(null); shown = false; scrollPos = 0; diff --git a/gradle.properties b/gradle.properties index 67ecd167b9..7c0f949677 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=d23d0f0b3625ab2d7d97e6c89a773ab6a4ad8434 +archash=afbb1f5080df42d0629d5997a3f1b14dafc467bf diff --git a/tools/src/mindustry/tools/BindingsGenerator.java b/tools/src/mindustry/tools/BindingsGenerator.java new file mode 100644 index 0000000000..83d3dd7975 --- /dev/null +++ b/tools/src/mindustry/tools/BindingsGenerator.java @@ -0,0 +1,102 @@ +package mindustry.tools; + +import arc.files.*; +import arc.struct.*; +import arc.util.*; + +import java.lang.reflect.*; + +import static mindustry.tools.ScriptMainGenerator.*; + +//experimental +public class BindingsGenerator{ + + public static void main(String[] args) throws Exception{ + + Seq blacklist = Seq.with("mindustry.tools", "arc.backend"); + Seq> classes = Seq.withArrays( + getClasses("mindustry"), + getClasses("arc") + ); + classes.sort(Structs.comparing(Class::getName)); + + classes.removeAll(type -> type.isSynthetic() || type.isAnonymousClass() || type.getCanonicalName() == null || Modifier.isPrivate(type.getModifiers()) + || blacklist.contains(s -> type.getName().startsWith(s))); + + classes.distinct(); + classes.sortComparing(Class::getName); + + StringBuilder result = new StringBuilder(); + result.append("import jnim, jnim/java/lang\n\n{.experimental: \"codeReordering\".}\n\n"); + + for(Class type : classes){ + String name = type.getCanonicalName(); + result.append("jclass ").append(name).append("* of ") + .append(type.getSuperclass() == null ? "JVMObject" : type.getSuperclass().getSimpleName()).append(":\n"); + + for(Field field : type.getFields()){ + if(Modifier.isPublic(field.getModifiers())){ + result.append(" proc `").append(field.getName()).append("`*"); + result.append(": ").append(str(field.getType())); + result.append(" {.prop"); + if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); + if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); + result.append(".}\n"); + } + } + + Seq exec = new Seq<>(); + + exec.addAll(type.getDeclaredMethods()); + exec.addAll(type.getDeclaredConstructors()); + + for(Executable method : exec){ + if(Modifier.isPublic(method.getModifiers())){ + String mname = method.getName().equals("") || method.getName().equals(type.getCanonicalName()) ? "new" : method.getName(); + result.append(" proc `").append(mname).append("`*"); + + if(method.getParameterCount() > 0){ + result.append("("); + + for(int i = 0; i < method.getParameterCount(); i++){ + Class p = method.getParameterTypes()[i]; + + result.append(method.getParameters()[i].getName()).append(": ").append(str(p)); + + if(i != method.getParameterCount() - 1){ + result.append(", "); + } + } + + result.append(")"); + } + + if(method instanceof Method){ + Method m = (Method)method; + if(!m.getReturnType().equals(void.class)){ + result.append(": ").append(str(m.getReturnType())); + } + } + + //result.append(" {."); + //if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); + //if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); + //result.append(".}\n"); + result.append("\n"); + } + } + result.append("\n"); + } + + Fi.get(OS.userhome).child("mindustry.nim").writeString(result.toString()); + Log.info(result); + } + + static String str(Class type){ + if(type.isArray()){ + return "seq[" + str(type.getComponentType()) + "]"; + } + if(type.isPrimitive()) return "j" + type.getSimpleName(); + return type.getSimpleName(); + } +} diff --git a/tools/src/mindustry/tools/ScriptMainGenerator.java b/tools/src/mindustry/tools/ScriptMainGenerator.java index cfc248dca4..256ed66531 100644 --- a/tools/src/mindustry/tools/ScriptMainGenerator.java +++ b/tools/src/mindustry/tools/ScriptMainGenerator.java @@ -71,8 +71,7 @@ public class ScriptMainGenerator{ new Fi("core/assets/scripts/global.js").writeString(result.toString()); } - - private static Seq getClasses(String packageName) throws Exception{ + public static Seq getClasses(String packageName) throws Exception{ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Seq dirs = new Seq<>(); @@ -87,7 +86,7 @@ public class ScriptMainGenerator{ return classes; } - private static Seq findClasses(File directory, String packageName) throws Exception{ + public static Seq findClasses(File directory, String packageName) throws Exception{ Seq classes = new Seq<>(); if(!directory.exists()) return classes; From 146b2589e2468adcb75d794bcd55433c776b0508 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 14:54:10 -0500 Subject: [PATCH 248/426] Fixed rare network error --- .../world/blocks/units/UnitBlock.java | 2 +- gradle.properties | 2 +- .../mindustry/tools/BindingsGenerator.java | 80 ++++++++++--------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/core/src/mindustry/world/blocks/units/UnitBlock.java b/core/src/mindustry/world/blocks/units/UnitBlock.java index ac38d3452f..872745c334 100644 --- a/core/src/mindustry/world/blocks/units/UnitBlock.java +++ b/core/src/mindustry/world/blocks/units/UnitBlock.java @@ -27,7 +27,7 @@ public class UnitBlock extends PayloadAcceptor{ @Remote(called = Loc.server) public static void unitBlockSpawn(Tile tile){ - if(!(tile.build instanceof UnitBuild build)) return; + if(tile == null || !(tile.build instanceof UnitBuild build)) return; build.spawned(); } diff --git a/gradle.properties b/gradle.properties index 7c0f949677..75d98185c9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=afbb1f5080df42d0629d5997a3f1b14dafc467bf +archash=eac865a8a0f4fde121fdcd8850d9f039f725b546 diff --git a/tools/src/mindustry/tools/BindingsGenerator.java b/tools/src/mindustry/tools/BindingsGenerator.java index 83d3dd7975..8363e4a857 100644 --- a/tools/src/mindustry/tools/BindingsGenerator.java +++ b/tools/src/mindustry/tools/BindingsGenerator.java @@ -31,64 +31,66 @@ public class BindingsGenerator{ for(Class type : classes){ String name = type.getCanonicalName(); - result.append("jclass ").append(name).append("* of ") - .append(type.getSuperclass() == null ? "JVMObject" : type.getSuperclass().getSimpleName()).append(":\n"); - - for(Field field : type.getFields()){ - if(Modifier.isPublic(field.getModifiers())){ - result.append(" proc `").append(field.getName()).append("`*"); - result.append(": ").append(str(field.getType())); - result.append(" {.prop"); - if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); - if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); - result.append(".}\n"); - } - } Seq exec = new Seq<>(); exec.addAll(type.getDeclaredMethods()); exec.addAll(type.getDeclaredConstructors()); + exec.removeAll(e -> !Modifier.isPublic(e.getModifiers())); + + Seq fields = Seq.select(type.getDeclaredFields(), f -> Modifier.isPublic(f.getModifiers())); + + result.append("jclass ").append(name).append(" of `") + .append(type.getSuperclass() == null ? "JVMObject" : type.getSuperclass().getSimpleName()).append("`").append(exec.size + fields.size > 0 ? ":" : "").append("\n"); + + for(Field field : fields){ + result.append(" proc `").append(field.getName()).append("`*"); + result.append(": ").append(str(field.getType())); + result.append(" {.prop"); + if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); + if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); + result.append(".}\n"); + } + for(Executable method : exec){ - if(Modifier.isPublic(method.getModifiers())){ - String mname = method.getName().equals("") || method.getName().equals(type.getCanonicalName()) ? "new" : method.getName(); - result.append(" proc `").append(mname).append("`*"); + String mname = method.getName().equals("") || method.getName().equals(type.getCanonicalName()) ? "new" : method.getName(); + result.append(" proc `").append(mname).append("`"); - if(method.getParameterCount() > 0){ - result.append("("); + if(method.getParameterCount() > 0){ + result.append("("); - for(int i = 0; i < method.getParameterCount(); i++){ - Class p = method.getParameterTypes()[i]; + for(int i = 0; i < method.getParameterCount(); i++){ + Class p = method.getParameterTypes()[i]; - result.append(method.getParameters()[i].getName()).append(": ").append(str(p)); + result.append(method.getParameters()[i].getName()).append(": ").append(str(p)); - if(i != method.getParameterCount() - 1){ - result.append(", "); - } - } - - result.append(")"); - } - - if(method instanceof Method){ - Method m = (Method)method; - if(!m.getReturnType().equals(void.class)){ - result.append(": ").append(str(m.getReturnType())); + if(i != method.getParameterCount() - 1){ + result.append(", "); } } - //result.append(" {."); - //if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); - //if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); - //result.append(".}\n"); - result.append("\n"); + result.append(")"); } + + if(method instanceof Method){ + Method m = (Method)method; + if(!m.getReturnType().equals(void.class)){ + result.append(": ").append(str(m.getReturnType())); + } + } + + //result.append(" {."); + //if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); + //if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); + //result.append(".}\n"); + result.append("\n"); } result.append("\n"); } - Fi.get(OS.userhome).child("mindustry.nim").writeString(result.toString()); + Fi.get("/home/anuke/Projects/Nimdustry-java/mindustry_bindings.nim").writeString(result.toString()); + //Fi.get(OS.userhome).child("mindustry.nim").writeString(result.toString()); Log.info(result); } From 2e6b90d4d5e1c5965e8416965a6ba969e93f028f Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 15:41:28 -0500 Subject: [PATCH 249/426] Serializable -> JsonSerializable --- core/assets/sounds/pew_.ogg | Bin 5621 -> 0 bytes core/src/mindustry/game/Rules.java | 2 +- core/src/mindustry/game/SpawnGroup.java | 2 +- core/src/mindustry/type/ItemSeq.java | 2 +- .../mindustry/world/blocks/Attributes.java | 2 +- gradle.properties | 2 +- .../mindustry/tools/BindingsGenerator.java | 59 +++++++++++++++--- 7 files changed, 57 insertions(+), 12 deletions(-) delete mode 100644 core/assets/sounds/pew_.ogg diff --git a/core/assets/sounds/pew_.ogg b/core/assets/sounds/pew_.ogg deleted file mode 100644 index 0c1df7f711cbf6e2481a5e5af301f188cba9f2ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5621 zcmeZIPY-5bVt|4vrh8;SOzF0{F^qDIW%)%(nZ+OhMwc}pih-fQf)UKv!3fp~W`hWj zPLPb)8RHth^8ZMnkr`qPF9QREPhwe`shOUMfu5m(Au9s|0~Z4WgJV#LXK;w^``!CF z85kHsJVSh3VH`&vr%+!Ihnsok!#>n8nz@Snrq2;!;Sgb`r$|*qdv5eEX>^G85K7vg$Mn2J} zRf{JmE?MBz5v|d9VL~VaNJG10g-A=6BZp#(s%^xiW_4Q*#g-1s3XzsfkeGlIhhhtu zaJ9^s)U58vA=~oUz=Egwsl^YO7FWv%fo65b7YZ%>PCI5bud(D%Y*8`w2xw-rd?C|v zNJpcq>4?D&u@)9njh?0_1}CmGb31j+YW6h!A=Q%ZSRn?nL&ec!LNlA=35gar$B0SI zY?eDjT24EzkZRGgFVB#EX<37dZd`Rf^ZMnCRQ1rA^Nw9VY z1_psknQ1H8It-X4*}(C@!NAZU*ky2}0T##&5?*|ZIM-UA_Mt(MQ{u&&MQo8`UH^7$N(os~hey+LBdAfv#EKY2aDH8%g zCMR`hE}v7xrL_VQoC=_*VPNq8By&+v7J)v>oEKCL6jBWo(!FeCdO6rNv^4elw9?4! zwb3_PW53tl{a$cjwA4rx1o1i(1A{_~fD_2NAP>!B62)gMU#LtGfO(UHfq|hw z#2uX8JU6L$Us5@HNyq=QiNCOIpor^blhBKzv4Q5ffo7?fO=E-2Vnf4n!>8p&Z!5h$ zJ@xkY+WSZ-mL2RxAqEDkNy?g&lr$$jw&+vwbjUcN#o)jO%8^}i-$nX_KboTs%4tb{=Tqy$tJbuFvtT3OMxqN49b$E1vz(^jmUrG0AIn_cT(6GGhJ z1g^rsP@>{qq~ac=;u@slUIY%^1|Cr8${aRSaV^q0eaQsk$BV+YmxEoyOCW^?Gy)hH zcusB*Iek&aS4j10kZx$O?$sdItHGg!fbV4!Uttd3NKR0Oy%1G=X6^Jo#}{j+pU_yc z;JTmXvnAKhXf(}vE?}5E<9LvvGtaSUjxAGIot(p17y=m>8VpYu9+4?J=lM#-^_-=a z?9yYF?kg8x3G~{yEXvwz>9&yU$8#262|T5-G|GFm?9!0zRT~)?8W`9a8W^}2UYH=t z=pe$t(8v?SrP(?q>73^C2|=eUpUEV3SuUTGe9ls1?vzuO>T@RxX)c|Ud`|QEoGIr# zpUs(k$y0-YLE!)+gTetP4U-gC1_5=32L&>|lTCa@RDFeA{Y7H03%g#OYI4@ZG%zI8 zSH$;fNNA*(Z|F2tUt?cikW;Ay_0TT{=Q5*s_cG&UkF`g`l;($d(esrSQEBfqD{9=}$4|GUrSZNAs9mR=4m zy??Fr>CD{QKU_nvmWEDijh~u&|9b1g%DlVc^8!Ol?@o!04^NF0&x<#|wJ*nv(pb7R zz^i-ZQmN={Q@0++6LTg{vQ%F>1uSvKQfqGW6e|wRrBkAGG>=ADs;f5ld9f=lo#f@C zx>UkhYva@@NjjQGZ$#znJUXLTW9iXJUOB2uBcgpQw@DQDfh<=CTfTH_P*C>N;vg#y z%~U=wEzP45US5X9ejuaxoV-+*N(6gtYz<1%*1Q_wm9_EcjAC!YYXL#ss!Jujy$rWW z6z6Sxdd)FIcZpE4hUzh~F_wGC8z+V zJCEMT&fWQSR`G?ETcd(~c7j~BlQpvV-QMO4Q5s8+26*+X-5M3$W7!V1yld;x8O7Nf zzXf>ps4k80_A=cjk=3*|lUw z1_ow61_nm8DUD9fVN9TW&!XsM$hOe2!|?eM6Ar^?bEb3|K37;0WcW;`CCKQx!jwrt zAXX69(j}9EvKLMX3d&l`z|g=1%J3S>@yvI#T^y;-Jn^0UiD zlhCW%WWgf7p<8oLLqtkT?}F8Ymd3_@cL_8Ny;_M(rSC&>s{}EANpv0oPps33p>LC zCh0JD3r#6*9k8ny85|^NJFxYvNABpSTHcKNI0rXhKeOF<`kD}0Hk5jMW%&E!@Q3&Ffa(PFmP~iG8i}n7%(&N@Cn$l zJE}VrY++>Ja7t#d`#C6W)C^xjzsI0-Zf9C^gR z<#FI3r@76?HuXCXSmrJYVh8nF7z!8|_!$_EvkC}alyPf2#^&CBoZZ6%)RC)7w`wGBQ|A`}2NH{4NGFh6V=%hz-H$P?t{e603dhn~YCy#MAwJ0ma#-^FB3ET%Ho<5+56%D_xJbr^FDhf_prdE zeg3KhCWZ^=CKNvVAhi4c)k~5L2W+(%_SL6;uD7WAqG89v@UKsL@*)O?Z+d$IWv{An zHrR^(f9Jt7c@e`Kr>BN<8YU(~=>#s+(2XdGh`kfhOMcuR8 z+hF{Fp?)vB@yG5vzk0uvvog&1Iw9ct?M@$)d7hp+8_wOnkhlHzTgJ2RWwXCn{I9pX zZt+k5e8r=c@Bi2TUSa06Nmxio&b^m$qs3+U@t5>IY zaqZglAyjwPRniWrf#U2m89@S{BgBh^u5W4IgWjt@Zp`#{+r)h!k65(S}8Ws zI#KX{D8sbFEnAnAY`wqY!9)LW#yGEQ@vD#BeLFWz5YZ3*gIuYCXi|A&WD z;`N^gWpAC!%yP7P+YM%Q^N>}m3;Ulvi+fX8ch&s&wCR&w!wbWm&2`>auVMfH;Ex0U z^Sf97E?@mAb%~Xoonn6ezOB>ZkE?ZBzmLiPb^X%GM;wzQr-vsL&DN`a^|s^bzMwgu zHon=nG^tr*om<;XqBkVx|ekKi-m6dDrSA{MTVUUxWCcnG3qObN{d-$bq|6-oX z^E}_e#IWGCEc1f&lNy{|2d(@W4n$W?*RN}TWT<6sn(noE(&`6KPHmq1&XB?2^|yrm zA*)RaN*4TaK6NeU-^o>M>pvfTx@}tT^Rlg0ALh8#7Ei9pUGx3H*Fx3R%cq-a3$`k7 zT@`=X@?A1hVQuvCEg$Cl1axlVQQGP)Jo(?8Dr=#(?9@X=jehI7Km5JtcIN2TwCg!G zyKMQbo?f0-=QT^4XT^3c?JH{Gyus59Hi)vCy^-Gjed)@AJ^ydpX9{Q@ozSzoitMk}S5^GKU;FO!S*_XO;r%XeKTNHi`1RYKL&@_F{`B*82;8T ztPJMLY>PSje#Ys$_bLy>ALI}?aVK2*;^p77kGGjDxEo@>HtWO1#rI!dtc@&x`s2b1 zWr@g(+ouVbW%51#ffNsKVB`nmYp#b=i_#ec=mc;;7Z?Rssg z>ZC`hJ6@e*V>z(p^vN}|KTn8D@4vKSrMmZX+bs<9P9FXBvYqefpA%~D*?zjVoY=s` z;G@RywQY^@s%a{XrA!PL`PfPs4t;VzT~rl(D`Ex1+S~i=7qB%{?XL+AR~9H*78%*O zee;x}E4L>e+nu%em*@J&AETTmSo<>OKmVd{*>U6ZY?rA!c4P+4>6)awFEIM*#I4_d znSNcq(d_Q*%X(s^mT!;9AATaX`$_qq$cdoughp`~`0Z}hBP+H!5uggc)Z z>oSr~w!Z(f>_zcLsesPP@@Z}Mms+@TsyAimiB6vX^7(U*obb=zzH@$_mRLSNfypj& z?#(~8ZO%)hb_mpcG~QIQSd@W5!P;?IkBTSLYo-TLUJduorymngxXzH!wDwNO_2}YC zi!ZN_?b|6g?e3|}aK$wqo;kIqYO=pwi&wu?=9+)X>N=}?mZ{TC%Hi_k6&$gLzU8{F~{_b(U?f1|7 z|8Fk{YvBBFd#~Jeu7GUT8S8B9>i#bKy=TuFZ~e%#_qThPUfZ{8731qw%kuZV7Z#gt z-uv`vQbb-_=~wfduS`?ZZ|U9>*SH>4Q@pMFn&_F`pH0s8s`4Am-Bu9i=cm?K`Loh4 z>siqohWGDJq(;5}w8@Fd;pA6E2H_j>@&|;T?JlljGMSv0>u8^Khv{Ex&9}eS#i?;B zo3`Emcq5_5&}~!kfpZLd&uMhdJjl?$>))frwu!xl7i_OZZ$FY=#`0;YVWhUh+ENo0 z6Y06py&)eoUcWY%{`TeH#QWJ34!jZz+}e05>hoE*#M~QSx36BfYfJVC)%aubwb}CW zn`i#{cX8T%E#ZhdnQ!jdr%%3@Kj%LG=esRWH+`FQ;8M|cnaP?D4@a7@{$N^sfG79t WN=YB~*(^SCuO2@<*Db}s#|Hq~?4Uyc diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index 7a0bbdae7e..eb34bab55f 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -137,7 +137,7 @@ public class Rules{ } /** A simple map for storing TeamRules in an efficient way without hashing. */ - public static class TeamRules implements Serializable{ + public static class TeamRules implements JsonSerializable{ final TeamRule[] values = new TeamRule[Team.all.length]; public TeamRule get(Team team){ diff --git a/core/src/mindustry/game/SpawnGroup.java b/core/src/mindustry/game/SpawnGroup.java index 86ba7b6324..2b7e8625c9 100644 --- a/core/src/mindustry/game/SpawnGroup.java +++ b/core/src/mindustry/game/SpawnGroup.java @@ -18,7 +18,7 @@ import static mindustry.Vars.*; * weapon equipped, ammo used, and status effects. * Each spawn group can have multiple sub-groups spawned in different areas of the map. */ -public class SpawnGroup implements Serializable{ +public class SpawnGroup implements JsonSerializable{ public static final int never = Integer.MAX_VALUE; /** The unit type spawned */ diff --git a/core/src/mindustry/type/ItemSeq.java b/core/src/mindustry/type/ItemSeq.java index 4fb7409796..a02f29bdb6 100644 --- a/core/src/mindustry/type/ItemSeq.java +++ b/core/src/mindustry/type/ItemSeq.java @@ -10,7 +10,7 @@ import mindustry.world.modules.ItemModule.*; import java.util.*; -public class ItemSeq implements Iterable, Serializable{ +public class ItemSeq implements Iterable, JsonSerializable{ protected final int[] values = new int[Vars.content.items().size]; public int total; diff --git a/core/src/mindustry/world/blocks/Attributes.java b/core/src/mindustry/world/blocks/Attributes.java index ff96a2bb63..38a39bd2e3 100644 --- a/core/src/mindustry/world/blocks/Attributes.java +++ b/core/src/mindustry/world/blocks/Attributes.java @@ -6,7 +6,7 @@ import mindustry.world.meta.*; import java.util.*; -public class Attributes implements Serializable{ +public class Attributes implements JsonSerializable{ private final float[] arr = new float[Attribute.all.length]; public void clear(){ diff --git a/gradle.properties b/gradle.properties index 75d98185c9..86948088f6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=eac865a8a0f4fde121fdcd8850d9f039f725b546 +archash=e00afb8e4fb58902255b782b074e2836c027df9a diff --git a/tools/src/mindustry/tools/BindingsGenerator.java b/tools/src/mindustry/tools/BindingsGenerator.java index 8363e4a857..b0fe2b358a 100644 --- a/tools/src/mindustry/tools/BindingsGenerator.java +++ b/tools/src/mindustry/tools/BindingsGenerator.java @@ -10,6 +10,8 @@ import static mindustry.tools.ScriptMainGenerator.*; //experimental public class BindingsGenerator{ + //list of touchy class names that lead to conflicts; all typedefs and procs containing these are ignored + static Seq ignored = Seq.with(".Entry", ".MapIterator"); public static void main(String[] args) throws Exception{ @@ -18,19 +20,28 @@ public class BindingsGenerator{ getClasses("mindustry"), getClasses("arc") ); - classes.sort(Structs.comparing(Class::getName)); classes.removeAll(type -> type.isSynthetic() || type.isAnonymousClass() || type.getCanonicalName() == null || Modifier.isPrivate(type.getModifiers()) || blacklist.contains(s -> type.getName().startsWith(s))); + classes.add(Enum.class); + classes.distinct(); - classes.sortComparing(Class::getName); + + classes = sorted(classes); + classes.removeAll(BindingsGenerator::ignore); StringBuilder result = new StringBuilder(); result.append("import jnim, jnim/java/lang\n\n{.experimental: \"codeReordering\".}\n\n"); for(Class type : classes){ - String name = type.getCanonicalName(); + result.append("jclassDef ").append(type.getCanonicalName()).append(" of `") + .append(repr(type.getSuperclass())).append("`\n"); + } + + result.append("\n"); + + for(Class type : classes){ Seq exec = new Seq<>(); @@ -38,14 +49,15 @@ public class BindingsGenerator{ exec.addAll(type.getDeclaredConstructors()); exec.removeAll(e -> !Modifier.isPublic(e.getModifiers())); + exec.removeAll(e -> Structs.contains(e.getParameterTypes(), BindingsGenerator::ignore)); Seq fields = Seq.select(type.getDeclaredFields(), f -> Modifier.isPublic(f.getModifiers())); - result.append("jclass ").append(name).append(" of `") - .append(type.getSuperclass() == null ? "JVMObject" : type.getSuperclass().getSimpleName()).append("`").append(exec.size + fields.size > 0 ? ":" : "").append("\n"); + result.append("jclassImpl ").append(type.getCanonicalName()).append(" of `") + .append(repr(type.getSuperclass())).append("`").append(exec.size + fields.size > 0 ? ":" : "").append("\n"); for(Field field : fields){ - result.append(" proc `").append(field.getName()).append("`*"); + result.append(" proc `").append(field.getName()).append("`"); result.append(": ").append(str(field.getType())); result.append(" {.prop"); if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); @@ -54,7 +66,7 @@ public class BindingsGenerator{ } for(Executable method : exec){ - String mname = method.getName().equals("") || method.getName().equals(type.getCanonicalName()) ? "new" : method.getName(); + String mname = method.getName().equals("") || method.getName().equals(type.getName()) ? "new" : method.getName(); result.append(" proc `").append(mname).append("`"); if(method.getParameterCount() > 0){ @@ -94,6 +106,39 @@ public class BindingsGenerator{ Log.info(result); } + static boolean ignore(Class type){ + if(type == null) return false; + return ignored.contains(s -> type.getCanonicalName().contains(s)) || ignore(type.getSuperclass()); + } + + static Seq> sorted(Seq> classes){ + ObjectSet> visited = new ObjectSet<>(); + Seq> result = new Seq<>(); + for(Class c : classes){ + if(!visited.contains(c)){ + topoSort(c, result, visited); + } + } + return result; + } + + static void topoSort(Class c, Seq> stack, ObjectSet> visited){ + visited.add(c); + for(Class sup : c.getInterfaces()){ + if(!visited.contains(sup)){ + topoSort(sup, stack, visited); + } + } + if(c.getSuperclass() != null && !c.getSuperclass().equals(Object.class) && !visited.contains(c.getSuperclass())){ + topoSort(c.getSuperclass(), stack, visited); + } + stack.add(c); + } + + static String repr(Class type){ + return type == null ? "JVMObject" : type.getSimpleName(); + } + static String str(Class type){ if(type.isArray()){ return "seq[" + str(type.getComponentType()) + "]"; From 9050937900ba7733d70240945adcb0be37095b47 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 12 Feb 2021 19:40:29 -0500 Subject: [PATCH 250/426] Name cleanup --- core/assets/icons/icons.properties | 3 - core/src/mindustry/core/World.java | 5 +- core/src/mindustry/graphics/LoadRenderer.java | 2 +- core/src/mindustry/graphics/Shaders.java | 16 +-- core/src/mindustry/world/Build.java | 1 + core/src/mindustry/world/meta/Producers.java | 16 --- gradle.properties | 2 +- .../mindustry/tools/BindingsGenerator.java | 128 +++++++++++++++--- tools/src/mindustry/tools/Generators.java | 3 +- 9 files changed, 122 insertions(+), 54 deletions(-) delete mode 100644 core/src/mindustry/world/meta/Producers.java diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index 008fb1289a..e2dcae538f 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -14,7 +14,6 @@ 63730=magmarock|block-magmarock-medium 63729=sand|block-sand-medium 63728=darksand|block-darksand-medium -63727=holostone|block-holostone-medium 63726=grass|block-grass-medium 63725=salt|block-salt-medium 63724=snow|block-snow-medium @@ -285,7 +284,6 @@ 63451=scepter|unit-scepter-medium 63450=reign|unit-reign-medium 63449=dirt|block-dirt-medium -63448=dirtwall|block-dirtwall-medium 63447=stone-wall|block-stone-wall-medium 63446=spore-wall|block-spore-wall-medium 63445=ice-wall|block-ice-wall-medium @@ -295,7 +293,6 @@ 63441=salt-wall|block-salt-wall-medium 63440=shale-wall|block-shale-wall-medium 63439=dirt-wall|block-dirt-wall-medium -63438=holostone-wall|block-holostone-wall-medium 63437=basalt|block-basalt-medium 63436=dacite|block-dacite-medium 63435=boulder|block-boulder-medium diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index 9751a3cd0d..dcb53437c3 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -4,6 +4,7 @@ import arc.*; import arc.func.*; import arc.math.*; import arc.math.geom.*; +import arc.math.geom.Geometry.*; import arc.struct.*; import arc.struct.ObjectIntMap.*; import arc.util.*; @@ -554,10 +555,6 @@ public class World{ return dark; } - public interface Raycaster{ - boolean accept(int x, int y); - } - private class Context implements WorldContext{ Context(){ diff --git a/core/src/mindustry/graphics/LoadRenderer.java b/core/src/mindustry/graphics/LoadRenderer.java index ba3778a026..8a314b00df 100644 --- a/core/src/mindustry/graphics/LoadRenderer.java +++ b/core/src/mindustry/graphics/LoadRenderer.java @@ -54,7 +54,7 @@ public class LoadRenderer implements Disposable{ bars = new Bar[]{ new Bar("s_proc#", OS.cores / 16f, OS.cores < 4), new Bar("c_aprog", () -> assets != null, () -> assets.getProgress(), () -> false), - new Bar("g_vtype", graphics.getGLVersion().type == Type.GLES ? 0.5f : 1f, graphics.getGLVersion().type == Type.GLES), + new Bar("g_vtype", graphics.getGLVersion().type == GlType.GLES ? 0.5f : 1f, graphics.getGLVersion().type == GlType.GLES), new Bar("s_mem#", () -> true, () -> Core.app.getJavaHeap() / 1024f / 1024f / 200f, () -> Core.app.getJavaHeap() > 1024 * 1024 * 110), new Bar("v_ver#", () -> Version.build != 0, () -> Version.build == -1 ? 0.3f : (Version.build - 103f) / 10f, () -> !Version.modifier.equals("release")), new Bar("s_osv", OS.isWindows ? 0.35f : OS.isLinux ? 0.9f : OS.isMac ? 0.5f : 0.2f, OS.isMac), diff --git a/core/src/mindustry/graphics/Shaders.java b/core/src/mindustry/graphics/Shaders.java index 637b09967b..2b3ccefb46 100644 --- a/core/src/mindustry/graphics/Shaders.java +++ b/core/src/mindustry/graphics/Shaders.java @@ -15,10 +15,10 @@ import mindustry.type.*; import static mindustry.Vars.*; public class Shaders{ - public static BlockBuild blockbuild; + public static BlockBuildShader blockbuild; public static @Nullable ShieldShader shield; public static BuildBeamShader buildBeam; - public static UnitBuild build; + public static UnitBuildShader build; public static DarknessShader darkness; public static LightShader light; public static SurfaceShader water, mud, tar, slag, space; @@ -31,7 +31,7 @@ public class Shaders{ public static void init(){ mesh = new MeshShader(); - blockbuild = new BlockBuild(); + blockbuild = new BlockBuildShader(); try{ shield = new ShieldShader(); }catch(Throwable t){ @@ -40,7 +40,7 @@ public class Shaders{ t.printStackTrace(); } buildBeam = new BuildBeamShader(); - build = new UnitBuild(); + build = new UnitBuildShader(); darkness = new DarknessShader(); light = new LightShader(); water = new SurfaceShader("water"); @@ -142,12 +142,12 @@ public class Shaders{ } } - public static class UnitBuild extends LoadShader{ + public static class UnitBuildShader extends LoadShader{ public float progress, time; public Color color = new Color(); public TextureRegion region; - public UnitBuild(){ + public UnitBuildShader(){ super("unitbuild", "default"); } @@ -162,11 +162,11 @@ public class Shaders{ } } - public static class BlockBuild extends LoadShader{ + public static class BlockBuildShader extends LoadShader{ public float progress; public TextureRegion region = new TextureRegion(); - public BlockBuild(){ + public BlockBuildShader(){ super("blockbuild", "default"); } diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index 62840ebd9b..f3eb5a40e4 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -153,6 +153,7 @@ public class Build{ (type == check.block() && check.build != null && rotation == check.build.rotation && type.rotate) || //same block, same rotation !check.interactable(team) || //cannot interact !check.floor().placeableOn || //solid wall + (!checkVisible && !check.block().alwaysReplace) || //replacing a block that should be replaced (e.g. payload placement) !((type.canReplace(check.block()) || //can replace type //controversial change: allow rebuilding damaged blocks //this could be buggy and abuse-able, so I'm not enabling it yet diff --git a/core/src/mindustry/world/meta/Producers.java b/core/src/mindustry/world/meta/Producers.java deleted file mode 100644 index 56abff88d6..0000000000 --- a/core/src/mindustry/world/meta/Producers.java +++ /dev/null @@ -1,16 +0,0 @@ -package mindustry.world.meta; - -import arc.struct.*; -import mindustry.gen.*; - -public class Producers{ - private Seq producers = new Seq<>(); - - public void add(Produce prod){ - producers.add(prod); - } - - interface Produce{ - void add(Building entity); - } -} diff --git a/gradle.properties b/gradle.properties index 86948088f6..4121286a92 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=e00afb8e4fb58902255b782b074e2836c027df9a +archash=eb0aebaca471905f03b9bf7103cc68a9589ef700 diff --git a/tools/src/mindustry/tools/BindingsGenerator.java b/tools/src/mindustry/tools/BindingsGenerator.java index b0fe2b358a..5ce4a5673d 100644 --- a/tools/src/mindustry/tools/BindingsGenerator.java +++ b/tools/src/mindustry/tools/BindingsGenerator.java @@ -4,18 +4,26 @@ import arc.files.*; import arc.struct.*; import arc.util.*; +import java.io.*; import java.lang.reflect.*; +import java.nio.*; +import java.nio.charset.*; +import java.util.*; import static mindustry.tools.ScriptMainGenerator.*; //experimental public class BindingsGenerator{ - //list of touchy class names that lead to conflicts; all typedefs and procs containing these are ignored - static Seq ignored = Seq.with(".Entry", ".MapIterator"); + //list of touchy class names that lead to conflicts or should not be referenced; all typedefs and procs containing these are ignored + static Seq ignored = Seq.with(".Entry", ".MapIterator", "arc.freetype.FreeType.Glyph", "FrameBufferBuilder", "Spliterator", + "java.util.function", "java.util.stream", "ArrayList", "Constable", "Optional", "java.lang.reflect", "rhino.Context", "arc.graphics.GL20", "arc.graphics.GL30"); + static ObjectSet> classSet = new ObjectSet<>(); + static ObjectSet keywords = ObjectSet.with("object", "string"); public static void main(String[] args) throws Exception{ - Seq blacklist = Seq.with("mindustry.tools", "arc.backend"); + //37800 + Seq blacklist = Seq.with("mindustry.tools", "arc.backend", "arc.maps", "arc.util.serialization.Xml", "arc.fx", "arc.net", "arc.Net", "arc.freetype"); Seq> classes = Seq.withArrays( getClasses("mindustry"), getClasses("arc") @@ -24,15 +32,54 @@ public class BindingsGenerator{ classes.removeAll(type -> type.isSynthetic() || type.isAnonymousClass() || type.getCanonicalName() == null || Modifier.isPrivate(type.getModifiers()) || blacklist.contains(s -> type.getName().startsWith(s))); - classes.add(Enum.class); - + classes.addAll(Enum.class, FloatBuffer.class, IntBuffer.class, ByteBuffer.class, StringBuilder.class, + Comparator.class, Comparable.class, Reader.class, Writer.class, PrintStream.class, PrintWriter.class, File.class, Charset.class, + ClassLoader.class, DoubleBuffer.class, CharBuffer.class, Locale.class, + LongBuffer.class, DataInputStream.class, DataOutputStream.class); classes.distinct(); classes = sorted(classes); classes.removeAll(BindingsGenerator::ignore); + classes.removeAll(c -> !Modifier.isPublic(c.getModifiers())); + + ObjectMap>> similars = new ObjectMap<>(); + classes.each(c -> similars.get(c.getSimpleName(), Seq::new).add(c)); + similars.each((key, val) -> { + if(val.size > 1){ + Log.info("\n" + key + ":\n" + val.toString("\n", v -> "- " + v.getCanonicalName())); + } + }); + + classSet = classes.asSet(); + classSet.addAll(Object.class, Number.class, Integer.class, Double.class, Short.class, Float.class, Byte.class, Long.class, String.class, Boolean.class, Throwable.class, Exception.class); + classSet.addAll(int.class, float.class, long.class, char.class, byte.class, boolean.class, double.class, short.class); + + /* + //Cons> logger = c -> { + //if(!c.isPrimitive() && !c.isArray() && !ignore(c) && Modifier.isPublic(c.getModifiers()) && classSet.add(c)){ + // Log.info(c); + //} + //}; + + for(Class type : classes){ + for(Field f : type.getDeclaredFields()){ + if(Modifier.isPublic(f.getModifiers())){ + logger.get(f.getType()); + } + } + + for(Method f : type.getDeclaredMethods()){ + if(Modifier.isPublic(f.getModifiers())){ + logger.get(f.getReturnType()); + for(Class c : f.getParameterTypes()){ + logger.get(c); + } + } + } + }*/ StringBuilder result = new StringBuilder(); - result.append("import jnim, jnim/java/lang\n\n{.experimental: \"codeReordering\".}\n\n"); + result.append("import jnim, jnim/java/lang\n\n{.experimental: \"codeReordering\".}\n{.push hint[ConvFromXtoItselfNotNeeded]: off.}\n\n"); for(Class type : classes){ result.append("jclassDef ").append(type.getCanonicalName()).append(" of `") @@ -44,17 +91,29 @@ public class BindingsGenerator{ for(Class type : classes){ Seq exec = new Seq<>(); + Seq methods = Seq.with(type.getDeclaredMethods()); - exec.addAll(type.getDeclaredMethods()); + methods.removeAll(m -> ignore(m.getReturnType()) || !discovered(m.getReturnType())); + + exec.addAll(methods); exec.addAll(type.getDeclaredConstructors()); - exec.removeAll(e -> !Modifier.isPublic(e.getModifiers())); + exec.removeAll(e -> !Modifier.isPublic(e.getModifiers()) || keywords.contains(e.getName())); exec.removeAll(e -> Structs.contains(e.getParameterTypes(), BindingsGenerator::ignore)); + exec.removeAll(e -> Structs.contains(e.getParameterTypes(), p -> !discovered(p))); - Seq fields = Seq.select(type.getDeclaredFields(), f -> Modifier.isPublic(f.getModifiers())); + Seq fields = Seq.select(type.getDeclaredFields(), f -> + Modifier.isPublic(f.getModifiers()) && + !keywords.contains(f.getName()) && + !ignore(f.getType()) && Modifier.isPublic(f.getType().getModifiers()) && + !(f.getType().isArray() && + f.getType().getComponentType().isArray()) + ); + + if(exec.size + fields.size <= 0) continue; result.append("jclassImpl ").append(type.getCanonicalName()).append(" of `") - .append(repr(type.getSuperclass())).append("`").append(exec.size + fields.size > 0 ? ":" : "").append("\n"); + .append(repr(type.getSuperclass())).append("`").append(":").append("\n"); for(Field field : fields){ result.append(" proc `").append(field.getName()).append("`"); @@ -67,6 +126,28 @@ public class BindingsGenerator{ for(Executable method : exec){ String mname = method.getName().equals("") || method.getName().equals(type.getName()) ? "new" : method.getName(); + + if(method instanceof Method){ + Method m = (Method)method; + + //if a field by the same name exists, use it to prevent ambiguity + if(method.getParameterCount() == 0 && fields.contains(f -> f.getName().equals(method.getName()))){ + continue; + } + + //check if this is a less specific method that was overridden by another method + if(methods.contains(other -> + other != m && + m.getName().equals(other.getName()) && + m.getParameterCount() == other.getParameterCount() && + Arrays.equals(m.getParameterTypes(), other.getParameterTypes()) && + m.getReturnType().isAssignableFrom(other.getReturnType()) + )){ + continue; + } + } + + result.append(" proc `").append(mname).append("`"); if(method.getParameterCount() > 0){ @@ -92,22 +173,26 @@ public class BindingsGenerator{ } } - //result.append(" {."); - //if(Modifier.isStatic(field.getModifiers())) result.append(", `static`"); - //if(Modifier.isStatic(field.getModifiers())) result.append(", `final`"); - //result.append(".}\n"); + if(Modifier.isStatic(method.getModifiers())){ + //result.append(" {.`static`.}"); + } result.append("\n"); } result.append("\n"); } + result.append("{.pop.}\n"); Fi.get("/home/anuke/Projects/Nimdustry-java/mindustry_bindings.nim").writeString(result.toString()); - //Fi.get(OS.userhome).child("mindustry.nim").writeString(result.toString()); - Log.info(result); + Log.info("Done. Classes found: @", classes.size); + } + + static boolean discovered(Class type){ + return classSet.contains(type) || (type.isArray() && discovered(type.getComponentType())); } static boolean ignore(Class type){ if(type == null) return false; + if(type.isArray() && type.getComponentType().isArray()) return true; return ignored.contains(s -> type.getCanonicalName().contains(s)) || ignore(type.getSuperclass()); } @@ -136,13 +221,16 @@ public class BindingsGenerator{ } static String repr(Class type){ - return type == null ? "JVMObject" : type.getSimpleName(); + if(type == null || type.equals(Object.class)) return "JVMObject"; + if(type.equals(String.class)) return "string"; + if(!Modifier.isPublic(type.getModifiers())) return "Object"; + return type.getSimpleName(); } static String str(Class type){ - if(type.isArray()){ - return "seq[" + str(type.getComponentType()) + "]"; - } + if(type.equals(Object.class)) return "JVMObject"; + if(type.equals(String.class)) return "string"; + if(type.isArray()) return "seq[" + str(type.getComponentType()) + "]"; if(type.isPrimitive()) return "j" + type.getSimpleName(); return type.getSimpleName(); } diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index 1350a0ff24..7c0f7869a7 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -4,6 +4,7 @@ import arc.*; import arc.files.*; import arc.func.*; import arc.graphics.*; +import arc.graphics.Pixmap.*; import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; @@ -43,7 +44,7 @@ public class Generators{ if(!fi.extEquals("png")) return; Pixmap pix = new Pixmap(fi); - pix.setBlending(Pixmap.Blending.sourceOver); + pix.setBlending(PixmapBlending.sourceOver); pix.each((x, y) -> { int value = pix.getPixel(x, y); pix.draw(x, y, paletteMap.get(value, value)); From 91b24433b9a367b2a35135e5979121b3d14d0c0e Mon Sep 17 00:00:00 2001 From: RebornTrack970 <62565267+RebornTrack970@users.noreply.github.com> Date: Sat, 13 Feb 2021 18:37:44 +0300 Subject: [PATCH 251/426] Added the 2R2T and Rush server to Omega. (#4667) --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index e3a1688551..0c59a8fc74 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -77,7 +77,7 @@ }, { "name": "Omega", - "address": ["185.86.230.102:25906"] + "address": ["185.86.230.102:25906", "185.86.230.104:25985", "185.86.230.101:25641"] }, { "name": "md.obvilionnetwork.ru", From 56e41309b1ef24856546fe50f536fcd9275cd970 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 13 Feb 2021 11:56:40 -0500 Subject: [PATCH 252/426] Updated global script --- core/assets/scripts/global.js | 2 + tools/build.gradle | 7 ++ .../mindustry/tools/BindingsGenerator.java | 68 ++++++++----------- .../mindustry/tools/ScriptMainGenerator.java | 32 +++++++-- 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index 4e40e985f7..ac1a812efd 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -133,6 +133,7 @@ const PlayerLeave = Packages.mindustry.game.EventType.PlayerLeave const PlayerConnect = Packages.mindustry.game.EventType.PlayerConnect const PlayerJoin = Packages.mindustry.game.EventType.PlayerJoin const UnitChangeEvent = Packages.mindustry.game.EventType.UnitChangeEvent +const UnitUnloadEvent = Packages.mindustry.game.EventType.UnitUnloadEvent const UnitCreateEvent = Packages.mindustry.game.EventType.UnitCreateEvent const UnitDrownEvent = Packages.mindustry.game.EventType.UnitDrownEvent const UnitDestroyEvent = Packages.mindustry.game.EventType.UnitDestroyEvent @@ -161,6 +162,7 @@ const LaunchItemEvent = Packages.mindustry.game.EventType.LaunchItemEvent const SectorInvasionEvent = Packages.mindustry.game.EventType.SectorInvasionEvent const SectorLoseEvent = Packages.mindustry.game.EventType.SectorLoseEvent const WorldLoadEvent = Packages.mindustry.game.EventType.WorldLoadEvent +const FileTreeInitEvent = Packages.mindustry.game.EventType.FileTreeInitEvent const ClientLoadEvent = Packages.mindustry.game.EventType.ClientLoadEvent const ContentInitEvent = Packages.mindustry.game.EventType.ContentInitEvent const BlockInfoEvent = Packages.mindustry.game.EventType.BlockInfoEvent diff --git a/tools/build.gradle b/tools/build.gradle index 4e8de5b536..173cae9721 100644 --- a/tools/build.gradle +++ b/tools/build.gradle @@ -435,4 +435,11 @@ task updateScripts(dependsOn: classes, type: JavaExec){ classpath = sourceSets.main.runtimeClasspath standardInput = System.in workingDir = "../" +} + +task genBindings(dependsOn: classes, type: JavaExec){ + main = "mindustry.tools.BindingsGenerator" + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = "../" } \ No newline at end of file diff --git a/tools/src/mindustry/tools/BindingsGenerator.java b/tools/src/mindustry/tools/BindingsGenerator.java index 5ce4a5673d..f6a15f5493 100644 --- a/tools/src/mindustry/tools/BindingsGenerator.java +++ b/tools/src/mindustry/tools/BindingsGenerator.java @@ -1,6 +1,8 @@ package mindustry.tools; +import arc.*; import arc.files.*; +import arc.func.*; import arc.struct.*; import arc.util.*; @@ -12,21 +14,29 @@ import java.util.*; import static mindustry.tools.ScriptMainGenerator.*; -//experimental +//experimental binding generator - used for Nim, but can be used for other languages as well, theoretically public class BindingsGenerator{ //list of touchy class names that lead to conflicts or should not be referenced; all typedefs and procs containing these are ignored static Seq ignored = Seq.with(".Entry", ".MapIterator", "arc.freetype.FreeType.Glyph", "FrameBufferBuilder", "Spliterator", "java.util.function", "java.util.stream", "ArrayList", "Constable", "Optional", "java.lang.reflect", "rhino.Context", "arc.graphics.GL20", "arc.graphics.GL30"); + static ObjectSet> classSet = new ObjectSet<>(); static ObjectSet keywords = ObjectSet.with("object", "string"); public static void main(String[] args) throws Exception{ - //37800 - Seq blacklist = Seq.with("mindustry.tools", "arc.backend", "arc.maps", "arc.util.serialization.Xml", "arc.fx", "arc.net", "arc.Net", "arc.freetype"); + Seq blacklist = Seq.with( + "mindustry.tools", + "arc.backend", + "arc.maps", + "arc.util.serialization.Xml", + "arc.fx", + "arc.net", "arc.Net", + "arc.freetype" + ); Seq> classes = Seq.withArrays( - getClasses("mindustry"), - getClasses("arc") + getClasses("mindustry") + //getClasses("arc") ); classes.removeAll(type -> type.isSynthetic() || type.isAnonymousClass() || type.getCanonicalName() == null || Modifier.isPrivate(type.getModifiers()) @@ -35,7 +45,8 @@ public class BindingsGenerator{ classes.addAll(Enum.class, FloatBuffer.class, IntBuffer.class, ByteBuffer.class, StringBuilder.class, Comparator.class, Comparable.class, Reader.class, Writer.class, PrintStream.class, PrintWriter.class, File.class, Charset.class, ClassLoader.class, DoubleBuffer.class, CharBuffer.class, Locale.class, - LongBuffer.class, DataInputStream.class, DataOutputStream.class); + LongBuffer.class, DataInputStream.class, DataOutputStream.class, Events.class, Cons.class + ); classes.distinct(); classes = sorted(classes); @@ -51,38 +62,14 @@ public class BindingsGenerator{ }); classSet = classes.asSet(); - classSet.addAll(Object.class, Number.class, Integer.class, Double.class, Short.class, Float.class, Byte.class, Long.class, String.class, Boolean.class, Throwable.class, Exception.class); - classSet.addAll(int.class, float.class, long.class, char.class, byte.class, boolean.class, double.class, short.class); - - /* - //Cons> logger = c -> { - //if(!c.isPrimitive() && !c.isArray() && !ignore(c) && Modifier.isPublic(c.getModifiers()) && classSet.add(c)){ - // Log.info(c); - //} - //}; - - for(Class type : classes){ - for(Field f : type.getDeclaredFields()){ - if(Modifier.isPublic(f.getModifiers())){ - logger.get(f.getType()); - } - } - - for(Method f : type.getDeclaredMethods()){ - if(Modifier.isPublic(f.getModifiers())){ - logger.get(f.getReturnType()); - for(Class c : f.getParameterTypes()){ - logger.get(c); - } - } - } - }*/ + classSet.addAll(Object.class, Number.class, Integer.class, Double.class, Short.class, Float.class, Byte.class, Long.class, String.class, Boolean.class, Throwable.class, Exception.class, Class.class); + classSet.addAll(void.class, int.class, float.class, long.class, char.class, byte.class, boolean.class, double.class, short.class); StringBuilder result = new StringBuilder(); - result.append("import jnim, jnim/java/lang\n\n{.experimental: \"codeReordering\".}\n{.push hint[ConvFromXtoItselfNotNeeded]: off.}\n\n"); + result.append("import jnim, jnim/java/lang\n\n{.push hint[ConvFromXtoItselfNotNeeded]: off.}\n\n"); for(Class type : classes){ - result.append("jclassDef ").append(type.getCanonicalName()).append(" of `") + result.append("jclassDef ").append(type.getName()).append(" of `") .append(repr(type.getSuperclass())).append("`\n"); } @@ -107,12 +94,13 @@ public class BindingsGenerator{ !keywords.contains(f.getName()) && !ignore(f.getType()) && Modifier.isPublic(f.getType().getModifiers()) && !(f.getType().isArray() && - f.getType().getComponentType().isArray()) + f.getType().getComponentType().isArray()) && + classSet.contains(f.getType()) ); if(exec.size + fields.size <= 0) continue; - result.append("jclassImpl ").append(type.getCanonicalName()).append(" of `") + result.append("jclassImpl ").append(type.getName()).append(" of `") .append(repr(type.getSuperclass())).append("`").append(":").append("\n"); for(Field field : fields){ @@ -174,7 +162,7 @@ public class BindingsGenerator{ } if(Modifier.isStatic(method.getModifiers())){ - //result.append(" {.`static`.}"); + result.append(" {.`static`.}"); } result.append("\n"); } @@ -182,6 +170,7 @@ public class BindingsGenerator{ } result.append("{.pop.}\n"); + //change directory as needed later Fi.get("/home/anuke/Projects/Nimdustry-java/mindustry_bindings.nim").writeString(result.toString()); Log.info("Done. Classes found: @", classes.size); } @@ -221,14 +210,15 @@ public class BindingsGenerator{ } static String repr(Class type){ - if(type == null || type.equals(Object.class)) return "JVMObject"; + if(type == null) return "JVMObject"; + if(type.equals(Object.class)) return "Object"; if(type.equals(String.class)) return "string"; if(!Modifier.isPublic(type.getModifiers())) return "Object"; return type.getSimpleName(); } static String str(Class type){ - if(type.equals(Object.class)) return "JVMObject"; + if(type.equals(Object.class)) return "Object"; if(type.equals(String.class)) return "string"; if(type.isArray()) return "seq[" + str(type.getComponentType()) + "]"; if(type.isPrimitive()) return "j" + type.getSimpleName(); diff --git a/tools/src/mindustry/tools/ScriptMainGenerator.java b/tools/src/mindustry/tools/ScriptMainGenerator.java index 256ed66531..89e2839417 100644 --- a/tools/src/mindustry/tools/ScriptMainGenerator.java +++ b/tools/src/mindustry/tools/ScriptMainGenerator.java @@ -19,6 +19,7 @@ import java.io.*; import java.lang.reflect.*; import java.net.*; import java.util.*; +import java.util.zip.*; public class ScriptMainGenerator{ @@ -73,6 +74,7 @@ public class ScriptMainGenerator{ public static Seq getClasses(String packageName) throws Exception{ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Seq dirs = new Seq<>(); for(URL resource : Collections.list(classLoader.getResources(packageName.replace('.', '/')))){ @@ -88,16 +90,34 @@ public class ScriptMainGenerator{ public static Seq findClasses(File directory, String packageName) throws Exception{ Seq classes = new Seq<>(); + String dir = directory.toString(); + if(dir.startsWith("file:")){ + directory = new File(dir.substring("file:".length()).replace("!/arc", "").replace("!/mindustry", "")); + } if(!directory.exists()) return classes; - File[] files = directory.listFiles(); - for(File file : files){ - if(file.isDirectory()){ - classes.addAll(findClasses(file, packageName + "." + file.getName())); - }else if(file.getName().endsWith(".class")){ - classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6), false, Thread.currentThread().getContextClassLoader())); + if(directory.getName().endsWith(".jar")){ + ZipInputStream zip = new ZipInputStream(new FileInputStream(directory)); + for(ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()){ + if(!entry.isDirectory() && entry.getName().endsWith(".class")){ + String className = entry.getName().replace('/', '.'); + className = className.substring(0, className.length() - ".class".length()); + if(className.startsWith(packageName)){ + classes.add(Class.forName(className, false, Thread.currentThread().getContextClassLoader())); + } + } + } + }else{ + File[] files = directory.listFiles(); + for(File file : files){ + if(file.isDirectory()){ + classes.addAll(findClasses(file, packageName + "." + file.getName())); + }else if(file.getName().endsWith(".class")){ + classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6), false, Thread.currentThread().getContextClassLoader())); + } } } + return classes; } } From 8b756d221bea5d73bce52911baa57fabe2963491 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 13 Feb 2021 16:28:49 -0500 Subject: [PATCH 253/426] Un-broke scripts --- core/src/mindustry/mod/Scripts.java | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index 149f234899..ab3ffb89e5 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -24,7 +24,7 @@ public class Scripts implements Disposable{ private final Seq blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", "runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system", ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org."); - private final Seq whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor"); + private final Seq whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent"); private final Context context; private final Scriptable scope; private boolean errored; diff --git a/gradle.properties b/gradle.properties index 4121286a92..8dae239bcd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=eb0aebaca471905f03b9bf7103cc68a9589ef700 +archash=0c9ff6f754dacff9072b835ddbfa4f16412ed448 From 092d152bdc1ab1393409acdcbc5e35a21fabdcd4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 13 Feb 2021 18:24:22 -0500 Subject: [PATCH 254/426] Force-link effect classes on iOS --- gradle.properties | 2 +- ios/robovm.xml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 8dae239bcd..e52e016fb3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=0c9ff6f754dacff9072b835ddbfa4f16412ed448 +archash=72dd3ba5d27fddfbf52719c10738d790e129e5db diff --git a/ios/robovm.xml b/ios/robovm.xml index c82b246fad..98de82cd7b 100644 --- a/ios/robovm.xml +++ b/ios/robovm.xml @@ -23,6 +23,8 @@ mindustry.net.** mindustry.world.blocks.** mindustry.logic.** + mindustry.world.blocks.** + mindustry.entities.effect.** com.android.okhttp.HttpHandler com.android.okhttp.HttpsHandler com.android.org.conscrypt.** From 07a27e913cb9b2659079f5be4f6a4b8b6efd41fc Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 14 Feb 2021 08:47:53 -0500 Subject: [PATCH 255/426] Added UnitBuild transition class --- core/src/mindustry/entities/effect/MultiEffect.java | 7 ++++++- core/src/mindustry/graphics/Shaders.java | 4 ++++ gradle.properties | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/entities/effect/MultiEffect.java b/core/src/mindustry/entities/effect/MultiEffect.java index a969b3e440..a93c3bd276 100644 --- a/core/src/mindustry/entities/effect/MultiEffect.java +++ b/core/src/mindustry/entities/effect/MultiEffect.java @@ -25,8 +25,13 @@ public class MultiEffect extends Effect{ @Override public void render(EffectContainer e){ + int index = 0; for(Effect f : effects){ - e.scaled(f.lifetime, f::render); + int i = ++index; + e.scaled(f.lifetime, cont -> { + cont.id = e.id + i; + f.render(cont); + }); clip = Math.max(clip, f.clip); } } diff --git a/core/src/mindustry/graphics/Shaders.java b/core/src/mindustry/graphics/Shaders.java index 2b3ccefb46..8aa304065f 100644 --- a/core/src/mindustry/graphics/Shaders.java +++ b/core/src/mindustry/graphics/Shaders.java @@ -142,6 +142,10 @@ public class Shaders{ } } + /** @deprecated transition class for mods; use UnitBuildShader instead. */ + @Deprecated + public static class UnitBuild extends UnitBuildShader{} + public static class UnitBuildShader extends LoadShader{ public float progress, time; public Color color = new Color(); diff --git a/gradle.properties b/gradle.properties index e52e016fb3..e33614b1b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=72dd3ba5d27fddfbf52719c10738d790e129e5db +archash=f49f7c824adc556cba6b94579c6b0d4e24574b3e From d6c852a082cb333a023fa9fe968ba4e3618b8f49 Mon Sep 17 00:00:00 2001 From: Skin <62944380+SkinH@users.noreply.github.com> Date: Sun, 14 Feb 2021 16:54:25 +0300 Subject: [PATCH 256/426] remove-pandorum (#4676) Good luck! --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index 0c59a8fc74..b328fd3045 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -17,7 +17,7 @@ }, { "name": "C.A.M.S.", - "address": ["routerchain.ddns.net", "pandorum.su:8000", "nikochio.ddns.net"] + "address": ["routerchain.ddns.net", "nikochio.ddns.net"] }, { "name": "BE6.RUN", From 3d226246b926c0d9481627748d32babe33f6b7cc Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 14 Feb 2021 09:15:12 -0500 Subject: [PATCH 257/426] Labyrinth core fix --- core/assets/maps/labyrinth.msav | Bin 10531 -> 10613 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/core/assets/maps/labyrinth.msav b/core/assets/maps/labyrinth.msav index d63ca28bf9d83c304ebe7f62c7e4441e35e1a317..9087a6da89ae63f5555ac898a279768a8cdafbc2 100644 GIT binary patch literal 10613 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 literal 10531 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 Date: Sun, 14 Feb 2021 16:02:28 -0800 Subject: [PATCH 258/426] Add enable building hint, combine building and respawn hints (#4678) --- core/src/mindustry/input/DesktopInput.java | 43 +++++++++------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 01f9e4b5f5..278eec1a0a 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -8,7 +8,6 @@ import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; import arc.scene.*; -import arc.scene.event.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.util.*; @@ -42,38 +41,32 @@ public class DesktopInput extends InputHandler{ /** Selected build request for movement. */ public @Nullable BuildPlan sreq; /** Whether player is currently deleting removal requests. */ - public boolean deleting = false, wasBuilding = true, shouldShoot = false, panning = false; + public boolean deleting = false, shouldShoot = false, panning = false; /** Mouse pan speed. */ public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f; @Override public void buildUI(Group group){ - //respawn hints + //building and respawn hints group.fill(t -> { - t.visible(() -> Core.settings.getBool("hints") && ui.hudfrag.shown && !player.dead() && !player.unit().spawnedByCore() && !(Core.settings.getBool("hints") && lastSchematic != null && !selectRequests.isEmpty())); + t.visible(() -> ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && (!isBuilding && !Core.settings.getBool("buildautopause") || player.unit().isBuilding() || !player.dead() && !player.unit().spawnedByCore())); t.bottom(); t.table(Styles.black6, b -> { b.defaults().left(); - b.label(() -> Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString())).style(Styles.outlineLabel); - }).margin(6f); - }); - - //building hints - group.fill(t -> { - t.bottom(); - t.visible(() -> { - t.color.a = Mathf.lerpDelta(t.color.a, player.unit().isBuilding() ? 1f : 0f, 0.15f); - - return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && t.color.a > 0.01f; - }); - t.touchable(() -> t.color.a < 0.1f ? Touchable.disabled : Touchable.childrenOnly); - t.table(Styles.black6, b -> { - b.defaults().left(); - b.label(() -> Core.bundle.format(!isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.toString())).style(Styles.outlineLabel); - b.row(); - b.label(() -> Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())).style(Styles.outlineLabel); - b.row(); - b.label(() -> Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())).style(Styles.outlineLabel); + b.label(() -> { + String str = ""; + if(!isBuilding && !Core.settings.getBool("buildautopause") && !player.unit().isBuilding()){ + str += Core.bundle.format("enablebuilding", Core.keybinds.get(Binding.pause_building).key.toString()); + }else if(player.unit().isBuilding()){ + str += Core.bundle.format(isBuilding ? "pausebuilding" : "resumebuilding", Core.keybinds.get(Binding.pause_building).key.toString()) + + "\n" + Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString()) + + "\n" + Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString()); + } + if(!player.dead() && !player.unit().spawnedByCore()){ + str += (!str.isEmpty() ? "\n" : "") + Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString()); + } + return str; + }).style(Styles.outlineLabel); }).margin(10f); }); @@ -454,7 +447,6 @@ public class DesktopInput extends InputHandler{ buildWasAutoPaused = false; if(isBuilding){ - wasBuilding = player.unit().isBuilding(); player.shooting = false; } } @@ -562,7 +554,6 @@ public class DesktopInput extends InputHandler{ } mode = none; - wasBuilding = true; } if(Core.input.keyTap(Binding.toggle_block_status)){ From f2468f0b3dec1d2e34f9924a83f1bfbd2ccfc1bc Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 14 Feb 2021 19:14:02 -0500 Subject: [PATCH 259/426] Cleanup of #4678 --- core/src/mindustry/input/DesktopInput.java | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 278eec1a0a..3de5997ec4 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -45,25 +45,33 @@ public class DesktopInput extends InputHandler{ /** Mouse pan speed. */ public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f; + boolean showHint(){ + return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && + (!isBuilding && !Core.settings.getBool("buildautopause") || player.unit().isBuilding() || !player.dead() && !player.unit().spawnedByCore()); + } + @Override public void buildUI(Group group){ //building and respawn hints group.fill(t -> { - t.visible(() -> ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && (!isBuilding && !Core.settings.getBool("buildautopause") || player.unit().isBuilding() || !player.dead() && !player.unit().spawnedByCore())); + t.color.a = 0f; + t.visible(() -> (t.color.a = Mathf.lerpDelta(t.color.a, Mathf.num(showHint()), 0.15f)) > 0.001f); t.bottom(); t.table(Styles.black6, b -> { + StringBuilder str = new StringBuilder(); b.defaults().left(); b.label(() -> { - String str = ""; + if(!showHint()) return str; + str.setLength(0); if(!isBuilding && !Core.settings.getBool("buildautopause") && !player.unit().isBuilding()){ - str += Core.bundle.format("enablebuilding", Core.keybinds.get(Binding.pause_building).key.toString()); + str.append(Core.bundle.format("enablebuilding", Core.keybinds.get(Binding.pause_building).key.toString())); }else if(player.unit().isBuilding()){ - str += Core.bundle.format(isBuilding ? "pausebuilding" : "resumebuilding", Core.keybinds.get(Binding.pause_building).key.toString()) + - "\n" + Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString()) + - "\n" + Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString()); + str.append(Core.bundle.format(isBuilding ? "pausebuilding" : "resumebuilding", Core.keybinds.get(Binding.pause_building).key.toString())) + .append("\n").append(Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())) + .append("\n").append(Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())); } if(!player.dead() && !player.unit().spawnedByCore()){ - str += (!str.isEmpty() ? "\n" : "") + Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString()); + str.append(str.length() != 0 ? "\n" : "").append(Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString())); } return str; }).style(Styles.outlineLabel); From e16622afccaa34a5e0245ee2563ede9d4fb72aea Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 14 Feb 2021 20:44:40 -0500 Subject: [PATCH 260/426] Automatic retreat AI for builders/repair units --- core/src/mindustry/ai/types/BuilderAI.java | 22 ++++++++++++++++- core/src/mindustry/ai/types/RepairAI.java | 24 +++++++++++++++++++ .../entities/units/AIController.java | 2 +- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index ce8b5ae92d..8106e6731a 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -13,9 +13,12 @@ import mindustry.world.blocks.ConstructBlock.*; import static mindustry.Vars.*; public class BuilderAI extends AIController{ - float buildRadius = 1500; + public static float buildRadius = 1500, retreatDst = 110f, fleeRange = 370f, retreatDelay = Time.toSeconds * 2f; + boolean found = false; @Nullable Unit following; + @Nullable Teamc enemy; + float retreatTimer; @Override public void updateMovement(){ @@ -27,6 +30,7 @@ public class BuilderAI extends AIController{ unit.updateBuilding = true; if(following != null){ + retreatTimer = 0f; //try to follow and mimic someone //validate follower @@ -39,9 +43,25 @@ public class BuilderAI extends AIController{ //set to follower's first build plan, whatever that is unit.plans.clear(); unit.plans.addFirst(following.buildPlan()); + }else if(unit.buildPlan() == null){ + //not following anyone or building + if(timer.get(timerTarget4, 40)){ + enemy = target(unit.x, unit.y, fleeRange, true, true); + } + + //fly away from enemy when not doing anything, but only after a delay + if((retreatTimer += Time.delta) >= retreatDelay){ + if(enemy != null){ + var core = unit.closestCore(); + if(!unit.within(core, retreatDst)){ + moveTo(core, retreatDst); + } + } + } } if(unit.buildPlan() != null){ + retreatTimer = 0f; //approach request if building BuildPlan req = unit.buildPlan(); diff --git a/core/src/mindustry/ai/types/RepairAI.java b/core/src/mindustry/ai/types/RepairAI.java index db20cc7d60..24b6ac424b 100644 --- a/core/src/mindustry/ai/types/RepairAI.java +++ b/core/src/mindustry/ai/types/RepairAI.java @@ -1,11 +1,16 @@ package mindustry.ai.types; +import arc.util.*; import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.world.blocks.ConstructBlock.*; public class RepairAI extends AIController{ + public static float retreatDst = 160f, fleeRange = 310f, retreatDelay = Time.toSeconds * 3f; + + @Nullable Teamc avoid; + float retreatTimer; @Override protected void updateMovement(){ @@ -29,6 +34,25 @@ public class RepairAI extends AIController{ unit.lookAt(target); } + + //not repairing + if(!(target instanceof Building)){ + if(timer.get(timerTarget4, 40)){ + avoid = target(unit.x, unit.y, fleeRange, true, true); + } + + if((retreatTimer += Time.delta) >= retreatDelay){ + //fly away from enemy when not doing anything + if(avoid != null){ + var core = unit.closestCore(); + if(!unit.within(core, retreatDst)){ + moveTo(core, retreatDst); + } + } + } + }else{ + retreatTimer = 0f; + } } @Override diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index b42c5efdb7..71bde595ce 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -15,7 +15,7 @@ import static mindustry.Vars.*; public class AIController implements UnitController{ protected static final Vec2 vec = new Vec2(); - protected static final int timerTarget = 0, timerTarget2 = 1, timerTarget3 = 2; + protected static final int timerTarget = 0, timerTarget2 = 1, timerTarget3 = 2, timerTarget4 = 2; protected Unit unit; protected Interval timer = new Interval(4); From fa52255d044630dbdc2854e6bf8ac88e54f45702 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 15 Feb 2021 09:30:57 -0500 Subject: [PATCH 261/426] Fixed #4680 --- core/src/mindustry/ai/types/SuicideAI.java | 18 +++++++++++------- .../world/consumers/ConsumeLiquidFilter.java | 3 ++- gradle.properties | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/core/src/mindustry/ai/types/SuicideAI.java b/core/src/mindustry/ai/types/SuicideAI.java index 1143f31675..e4c1461227 100644 --- a/core/src/mindustry/ai/types/SuicideAI.java +++ b/core/src/mindustry/ai/types/SuicideAI.java @@ -1,5 +1,6 @@ package mindustry.ai.types; +import arc.math.geom.*; import mindustry.*; import mindustry.ai.*; import mindustry.entities.*; @@ -47,14 +48,17 @@ public class SuicideAI extends GroundAI{ //raycast for target boolean blocked = Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> { - Tile tile = Vars.world.tile(x, y); - if(tile != null && tile.build == target) return false; - if(tile != null && tile.build != null && tile.build.team != unit.team()){ - blockedByBlock = true; - return true; - }else{ - return tile == null || tile.solid(); + for(Point2 p : Geometry.d4c){ + Tile tile = Vars.world.tile(x + p.x, y + p.y); + if(tile != null && tile.build == target) return false; + if(tile != null && tile.build != null && tile.build.team != unit.team()){ + blockedByBlock = true; + return true; + }else{ + return tile == null || tile.solid(); + } } + return false; }); //shoot when there's an enemy block in the way diff --git a/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java index f7a3f99639..5b1881458b 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -28,7 +28,8 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{ public void build(Building build, Table table){ Seq list = content.liquids().select(l -> !l.isHidden() && filter.get(l)); MultiReqImage image = new MultiReqImage(); - list.each(liquid -> image.add(new ReqImage(liquid.icon(Cicon.medium), () -> build.liquids != null && build.liquids.get(liquid) >= Math.max(use(build), amount * build.delta())))); + list.each(liquid -> image.add(new ReqImage(liquid.icon(Cicon.medium), () -> + build.liquids != null && build.liquids.current() == liquid && build.liquids.get(liquid) >= Math.max(use(build), amount * build.delta())))); table.add(image).size(8 * 4); } diff --git a/gradle.properties b/gradle.properties index e33614b1b9..02b3252d8c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=f49f7c824adc556cba6b94579c6b0d4e24574b3e +archash=40c4e9db40cb8fbe7daa091f20ca0bf5acfd8484 From 557e5710cd5f145c20712471e07cf0a4f17955b4 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Mon, 15 Feb 2021 15:31:27 +0100 Subject: [PATCH 262/426] Fixes BuilderAI & RepairAI retreat nullpointers (#4681) * Update BuilderAI.java * Update RepairAI.java --- core/src/mindustry/ai/types/BuilderAI.java | 2 +- core/src/mindustry/ai/types/RepairAI.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index 8106e6731a..40a008c6c7 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -53,7 +53,7 @@ public class BuilderAI extends AIController{ if((retreatTimer += Time.delta) >= retreatDelay){ if(enemy != null){ var core = unit.closestCore(); - if(!unit.within(core, retreatDst)){ + if(core != null && !unit.within(core, retreatDst)){ moveTo(core, retreatDst); } } diff --git a/core/src/mindustry/ai/types/RepairAI.java b/core/src/mindustry/ai/types/RepairAI.java index 24b6ac424b..23feb2a0eb 100644 --- a/core/src/mindustry/ai/types/RepairAI.java +++ b/core/src/mindustry/ai/types/RepairAI.java @@ -45,7 +45,7 @@ public class RepairAI extends AIController{ //fly away from enemy when not doing anything if(avoid != null){ var core = unit.closestCore(); - if(!unit.within(core, retreatDst)){ + if(core != null && !unit.within(core, retreatDst)){ moveTo(core, retreatDst); } } From 7a21c024768985bf43658e4772170559ff3dd93b Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Mon, 15 Feb 2021 15:32:46 +0100 Subject: [PATCH 263/426] Makes the top sprite visible on liquid turret icons (#4683) * Add top region to liquid turret icons * Attempt to change outline icon generation * Draw regions above the outlined icon over it * Draw regions **above** the outlined icon over it * Add clarrifying comment * Implement backwards compatibility for mods * an -> any --- core/src/mindustry/world/Block.java | 6 ++++-- .../world/blocks/defense/turrets/LiquidTurret.java | 7 +++++++ tools/src/mindustry/tools/Generators.java | 10 +++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index d8cca61641..da9702d902 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -160,8 +160,10 @@ public class Block extends UnlockableContent{ public boolean canOverdrive = true; /** Outlined icon color.*/ public Color outlineColor = Color.valueOf("404049"); - /** Whether the icon region has an outline added. */ + /** Whether any icon region has an outline added. */ public boolean outlineIcon = false; + /** Which of the icon regions gets the outline added. */ + public int outlinedIcon = -1; /** Whether this block has a shadow under it. */ public boolean hasShadow = true; /** Sounds made when this block breaks.*/ @@ -768,7 +770,7 @@ public class Block extends UnlockableContent{ if(outlineIcon){ final int radius = 4; - PixmapRegion region = Core.atlas.getPixmap(getGeneratedIcons()[getGeneratedIcons().length-1]); + PixmapRegion region = Core.atlas.getPixmap(getGeneratedIcons()[outlinedIcon >= 0 ? outlinedIcon : getGeneratedIcons().length -1]); Pixmap out = new Pixmap(region.width, region.height); Color color = new Color(); for(int x = 0; x < region.width; x++){ diff --git a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java index 4abfa3140c..bb53932b4c 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java @@ -27,6 +27,7 @@ public class LiquidTurret extends Turret{ hasLiquids = true; loopSound = Sounds.spray; shootSound = Sounds.none; + outlinedIcon = 1; } /** Initializes accepted ammo map. Format: [liquid1, bullet1, liquid2, bullet2...] */ @@ -63,6 +64,12 @@ public class LiquidTurret extends Turret{ super.init(); } + @Override + public TextureRegion[] icons(){ + if(topRegion.found()) return new TextureRegion[]{baseRegion, region, topRegion}; + return super.icons(); + } + public class LiquidTurretBuild extends TurretBuild{ @Override public void draw(){ diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index 7c0f7869a7..ef579df8c4 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -247,7 +247,7 @@ public class Generators{ Image last = null; if(block.outlineIcon){ int radius = 4; - GenRegion region = (GenRegion)regions[regions.length - 1]; + GenRegion region = (GenRegion)regions[block.outlinedIcon >= 0 ? block.outlinedIcon : regions.length -1]; Image base = ImagePacker.get(region); Image out = last = new Image(region.width, region.height); for(int x = 0; x < out.width; x++){ @@ -273,6 +273,14 @@ public class Generators{ } } + //do not run for legacy ones + if(block.outlinedIcon >= 0){ + //prevents the regions above from being ignored/invisible/etc + for(int i = block.outlinedIcon + 1; i < regions.length; i++){ + out.draw(ImagePacker.get(regions[i])); + } + } + region.path.delete(); out.save(block.name); From af39d6a6eeb136672e142dd2010c314435c91776 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 15 Feb 2021 10:37:24 -0500 Subject: [PATCH 264/426] Fixed #4685 --- core/src/mindustry/ai/types/LogicAI.java | 3 +++ gradle.properties | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index b20bc87db6..c910999c2f 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -119,6 +119,9 @@ public class LogicAI extends AIController{ vec.set(target).sub(unit); + //do not move when infinite vectors are used. + if(vec.isNaN() || vec.isInfinite()) return; + float length = circleLength <= 0.001f ? 1f : Mathf.clamp((unit.dst(target) - circleLength) / smooth, -1f, 1f); vec.setLength(unit.realSpeed() * length); diff --git a/gradle.properties b/gradle.properties index 02b3252d8c..a2de2401ed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=40c4e9db40cb8fbe7daa091f20ca0bf5acfd8484 +archash=baaa8652a41304abff81995aaf90f6589461ec0c From e528e35e06d7155d50dbdadd2d8e4efb6eb6e58e Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Mon, 15 Feb 2021 07:41:56 -0800 Subject: [PATCH 265/426] Add sector icon picker back button (#4682) --- core/src/mindustry/ui/dialogs/ControlsDialog.java | 2 +- core/src/mindustry/ui/dialogs/PlanetDialog.java | 7 ++++--- core/src/mindustry/ui/dialogs/SettingsMenuDialog.java | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/ui/dialogs/ControlsDialog.java b/core/src/mindustry/ui/dialogs/ControlsDialog.java index 746470526a..400d5f086a 100644 --- a/core/src/mindustry/ui/dialogs/ControlsDialog.java +++ b/core/src/mindustry/ui/dialogs/ControlsDialog.java @@ -17,7 +17,7 @@ public class ControlsDialog extends KeybindDialog{ @Override public void addCloseButton(){ - buttons.button("@back", Icon.left, this::hide).size(230f, 64f); + buttons.button("@back", Icon.left, this::hide).size(210f, 64f); keyDown(key -> { if(key == KeyCode.escape || key == KeyCode.back) hide(); diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index bb187d3a9d..f7d5044469 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -208,11 +208,11 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ } void addBack(){ - buttons.button("@back", Icon.left, this::hide).size(200, 54).pad(2).bottom(); + buttons.button("@back", Icon.left, this::hide).size(200f, 54f).pad(2).bottom(); } void addTech(){ - buttons.button("@techtree", Icon.tree, () -> ui.research.show()).size(200, 54).pad(2).bottom(); + buttons.button("@techtree", Icon.tree, () -> ui.research.show()).size(200f, 54f).pad(2).bottom(); } public void showOverview(){ @@ -677,7 +677,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ setFillParent(true); cont.pane(t -> { t.marginRight(19f); - t.defaults().size(48); + t.defaults().size(48f); t.button(Icon.none, Styles.clearTogglei, () -> { sector.info.icon = null; @@ -701,6 +701,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ if(++i % 8 == 0) t.row(); } }); + buttons.button("@back", Icon.left, this::hide).size(210f, 64f); }}.show(); }).size(40f); }).row(); diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index 6661ea1ae4..6047fd7858 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -146,7 +146,7 @@ public class SettingsMenuDialog extends SettingsDialog{ } } } - + for(var slot : control.saves.getSaveSlots().copy()){ if(slot.isSector()){ slot.delete(); @@ -501,13 +501,13 @@ public class SettingsMenuDialog extends SettingsDialog{ @Override public void addCloseButton(){ - buttons.button("@back", Icon.leftOpen, () -> { + buttons.button("@back", Icon.left, () -> { if(prefs.getChildren().first() != menu){ back(); }else{ hide(); } - }).size(230f, 64f); + }).size(210f, 64f); keyDown(key -> { if(key == KeyCode.escape || key == KeyCode.back){ From 561deacce4ed145a01ba5596914414915e7b231b Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Mon, 15 Feb 2021 18:42:01 +0300 Subject: [PATCH 266/426] [Bundle][RU] Logic Popups L10n (#4677) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Logic popups * Block flag documentation * Распознование -> Распознавание (@Prosta4okua) * Сбрсывание -> Сбрасывание (@XEN0PHIL) * нахдиться -> находиться (@XEN0PHIL) * распознования -> распознавания (@XEN0PHIL) * распознования -> распознавания (@XEN0PHIL) * распозновать -> распознавать (@XEN0PHIL) * распознования -> распознавания (@XEN0PHIL) * Включен -> Включён (@XEN0PHIL) * - -> - (@XEN0PHIL) * lst.unitradar (@XEN0PHIL) * единиц -> единицы (@XEN0PHIL) --- core/assets/bundles/bundle_ru.properties | 123 +++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 38f89eb669..fdf148cd48 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -1511,3 +1511,126 @@ unit.omura.description = Стреляет дальнобойным пробив unit.alpha.description = Защищает ядро «Осколок» от врагов. Основная строительная единица. unit.beta.description = Защищает ядро «Штаб» от врагов. Основная строительная единица. unit.gamma.description = Защищает ядро «Атом» от врагов. Основная строительная единица. + +lst.read = Считывает число из соединённой ячейки памяти. +lst.write = Записывает число в соединённую ячейку памяти. +lst.print = Добавляет текст в текстовый буфер. Ничего не отображает, пока не будет вызван [accent]Print Flush[]. +lst.draw = Добавляет операцию в буфер отрисовки. Ничего не отображает, пока не будет вызван [accent]Draw Flush[]. +lst.drawflush = Сбрасывает буфер [accent]Draw[] операций на дисплей. +lst.printflush = Сбрасывает буфер [accent]Print[] операций в блок-сообщение. +lst.getlink = Получает соединение процессора по индексу. Начинает с 0. +lst.control = Контролирует блок. +lst.radar = Обнаруживает единицы вокруг постройки с заданным радиусом. +lst.sensor = Получает данные из постройки или единицы. +lst.set = Устанавливает переменную. +lst.operation = Совершает операцию над 1-2 переменными. +lst.end = Переходит к началу стека операций. +lst.jump = Условно переходит к другой операции. +lst.unitbind = Привязывается к единице определённого типа и сохраняет её в [accent]@unit[]. +lst.unitcontrol = Управляет привязанной в данный момент единицей. +lst.unitradar = Обнаруживает единицы вокруг привязанной в данный момент единицы. +lst.unitlocate = Обнаруживает позицию/постройку определённого типа где-либо на карте. Требует привязанную единицу. + +lenum.type = Тип постройки/единицы. \nНапример, для маршрутизатора это будет [accent]@router[].\nНе строка. +lenum.shoot = Стрельба в определённую позицию. +lenum.shootp = Стрельба в единицу/постройку с расчётом скорости. +lenum.configure = Конфигурация постройки, например, предмет сортировки. +lenum.enabled = Включён ли блок. +lenum.color = Цвет осветителя. + +lenum.always = Всегда истина. +lenum.idiv = Целочисленное деление. +lenum.div = Деление.\nВозвращает [accent]null[] при делении на ноль. +lenum.mod = Остаток от деления. +lenum.equal = Равно. Приводит типы.\nНе-null объекты, по сравнению с числами, становятся 1, иначе — 0. +lenum.notequal = Не равно. Приводит типы. +lenum.strictequal = Строгое равенство. Не приводит типы.\nМожет быть использовано для проверки на [accent]null[]. +lenum.shl = Побитовый сдвиг влево. +lenum.shr = Побитовый сдвиг вправо. +lenum.or = Побитовое ИЛИ. +lenum.land = Булевое И. +lenum.and = Побитовое И. +lenum.not = Побитовое НЕ. +lenum.xor = Побитовое исключающее ИЛИ. + +lenum.min = Минимальное из двух чисел. +lenum.max = Максимальное из двух чисел. +lenum.angle = Угол вектора в градусах. +lenum.len = Длина вектора. +lenum.sin = Синус, в градусах. +lenum.cos = Косинус, в градусах. +lenum.tan = Тангенс, в градусах. +#это не ошибка, поищите 'обозначение диапазонов' +lenum.rand = Случайное число в диапазоне [0, значение). +lenum.log = Натуральный логарифм (ln). +lenum.log10 = Логарифм по основанию 10. +lenum.noise = Симплексный шум, 2D. +lenum.abs = Абсолютная величина. +lenum.sqrt = Квадратный корень. + +lenum.any = Любая единица. +lenum.ally = Дружеская единица. +lenum.attacker = Единица с оружием. +lenum.enemy = Вражеская единица. +lenum.boss = Страж. +lenum.flying = Летающая единица. +lenum.ground = Наземная единица. +lenum.player = Единица, управляемая игроком. + +lenum.ore = Источник руды. +lenum.damaged = Повреждённая дружеская постройка. +lenum.spawn = Точка появления врагов.\nМожет быть ядром или позицией на карте. +lenum.building = Постройка определённой группы. + +lenum.core = Любое ядро. +lenum.storage = Здание хранения, например, хранилище. +lenum.generator = Постройки, вырабатывающие энергию. +lenum.factory = Постройки, перерабатывающие предметы. +lenum.repair = Ремонтные пункты. +lenum.rally = Командный центр. +lenum.battery = Любой аккумулятор. +lenum.resupply = Пункты снабжения.\nАктуально только при включённом [accent]"Боев. ед. требуют боеприпасы"[]. +lenum.reactor = Импульсный/ториевый реактор. +lenum.turret = Любое ядро. + +sensor.in = Постройка/единица для распознавания. + +radar.from = Постройка, от которой распознавать.\nДальность сенсора ограничена дальностью постройки. +radar.target = Фильтр для распознавания единиц. +radar.and = Дополнительные фильтры. +radar.order = Порядок сортировки. 0 для обратного. +radar.sort = Показатель для сортировки результатов. +radar.output = Переменная для записи конечной единицы. +unitradar.target = Фильтр для распознавания единиц. +unitradar.and = Дополнительные фильтры. +unitradar.order = Порядок сортировки. 0 для обратного. +unitradar.sort = Показатель для сортировки результатов. +unitradar.output = Переменная для записи конечной единицы. + +control.of = Постройка для контролирования. +control.unit = Единица/постройка для прицеливания. +control.shoot = Стрелять ли. + +unitlocate.enemy = Обнаруживать ли вражеские постройки. +unitlocate.found = Найден ли объект. +unitlocate.building = Переменная для записи обнаруженной постройки. +unitlocate.outx = Вывод X координаты. +unitlocate.outy = Вывод Y координаты. +unitlocate.group = Группа построек для поиска. + +lenum.stop = Остановка передвижения/копания/стротельства. +lenum.move = Перемещение в определённую позицию. +lenum.approach = Приближение к позиции с указанным радиусом. +lenum.pathfind = Перемещение к точке появления врагов. +lenum.target = Стрельба в определённую позицию. +lenum.targetp = Стрельба в единицу/постройку с расчётом скорости. +lenum.itemdrop = Сбрасывание предметов. +lenum.itemtake = Взятие предметов из постройки. +lenum.paydrop = Сбрасывание текущего груза. +lenum.paytake = Взятие груза на текущей позиции. +lenum.flag = Числовой флаг единицы. +lenum.mine = Копание в позиции. +lenum.build = Строительство структур. +lenum.getblock = Распознавание блока и его типа на координатах.\nЕдиница должна находиться в пределах досягаемости.\nТвёрдые не-постройки будут иметь тип [accent]@solid[]. +lenum.within = Проверка на нахождение единицы рядом с позицией. +lenum.boost = Включение/выключение полёта. From a9f9946a3993b00c320ed44f479aa967183bf1e6 Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Tue, 16 Feb 2021 00:42:28 +0900 Subject: [PATCH 267/426] [KO] TYPO (#4665) * [KO] i got typo! * typo From d5645b8a7bf502c7dc68c1f4ed9fa37d37e52436 Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Mon, 15 Feb 2021 17:43:34 +0200 Subject: [PATCH 268/426] [Bundle][RO] Update (#4631) * [Bundle][RO][124.1] Update This PR was tested in-game and is ready to merge at any time. Changelog: - New strings/changes up to commit 64acd6c1e4b4044b7fdd7153bc3c35c31f1c6eed - Fixed ancient mod-related bundles not fitting the new install button - Typo fixes & various other improvements * Logic tooltips - initial English commit * Block flags * Romanian logic hints * polishing * Since when is this missing * Polishing --- core/assets/bundles/bundle_ro.properties | 140 ++++++++++++++++++++++- 1 file changed, 134 insertions(+), 6 deletions(-) diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index 0867ae0668..d2ff766a93 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -43,8 +43,8 @@ be.check = Verifică updateurile mods.browser = Browser de Moduri mods.browser.selected = Mod selectat -mods.browser.add = Instalează -mods.browser.reinstall = Reinstalează +mods.browser.add = Instalare +mods.browser.reinstall = Reinstal. mods.github.open = Github mods.browser.sortdate = Cele mai recente mods.browser.sortstars = Cele mai multe stele @@ -312,6 +312,7 @@ cancelbuilding = [accent][[{0}][] pt a curăța planul selectschematic = [accent][[{0}][] pt selectare+copiere pausebuilding = [accent][[{0}][] pt a face o pauză de la construit resumebuilding = [scarlet][[{0}][] pt a continua construitul +enablebuilding = [scarlet][[{0}][] pt a construi showui = Interfață ascunsă.\nApasă [accent][[{0}][] pt a vedea interfața. wave = [accent]Valul {0} wave.cap = [accent]Valul {0}/{1} @@ -683,6 +684,7 @@ stat.drillspeed = Viteză Burghiu (Bază) stat.boosteffect = Efect de Îmbunătățire stat.maxunits = Maxim Unități Active stat.health = Viață +stat.armor = Armură stat.buildtime = Timp Construcție stat.maxconsecutive = Maxim Consecutive stat.buildcost = Cost Construcție @@ -794,6 +796,7 @@ setting.shadows.name = Umbre setting.blockreplace.name = Sugestii Plasare Automats setting.linear.name = Filtrare Liniară setting.hints.name = Indicii +setting.logichints.name = Indicii Procesoare Logice setting.flow.name = Afișează Rata de Curgere a lichidelor setting.buildautopause.name = Autopauză de la Construit setting.backgroundpause.name = Pune Pauză în Fundal @@ -1144,10 +1147,6 @@ block.armored-conveyor.name = Bandă Armată block.junction.name = Intersecție block.router.name = Router block.distributor.name = Distributor -#experimental, pot fi șterse în viitor -block.block-forge.name = Forjă de Blocuri -block.block-loader.name = Încărcător de Blocuri -block.block-unloader.name = Descărcător de Blocuri block.sorter.name = Sortator block.inverted-sorter.name = Sortator Invers block.message.name = Mesaj @@ -1248,6 +1247,10 @@ block.disassembler.name = Dezasamblator block.silicon-crucible.name = Creuzet de Silicon block.overdrive-dome.name = Dom de Suprasolicitare block.interplanetary-accelerator.name = Accelerator Interplanetar +#experimental, pot fi șterse în viitor +block.block-forge.name = Forjă de Blocuri +block.block-loader.name = Încărcător de Blocuri +block.block-unloader.name = Descărcător de Blocuri block.switch.name = Întrerupător block.micro-processor.name = Microprocesor @@ -1450,6 +1453,7 @@ block.ripple.description = Lovește cu capsule către inamici pe distanțe mari. block.cyclone.description = Trage cu grămezi explozive de material către unitățile inamice din apropiere. block.spectre.description = Trage cu gloanțe mari care penetrează scuturile inamicilor din apropiere. block.meltdown.description = Se încarcă și trage cu un laser continuu la inamicii din apropiere. Necesită răcitor pt a opera. +block.foreshadow.description = Trage către o țintă cu un glonț imens pe distanțe lungi. block.repair-point.description = Repară încontinuu cea mai deteriorată unitate din vecinătate. block.segment.description = Deteriorează și distruge proiectilele din apropiere. Laserele nu sunt afectate. block.parallax.description = Trage cu o rază tractoare care atrage aeronavele inamice, deteriorându-le. @@ -1510,3 +1514,127 @@ unit.omura.description = Trage cu un railgun cu gloanțe care penetrează scutur unit.alpha.description = Apără nucleul Shard de inamici. Construiește structuri. unit.beta.description = Apără nucleul Foundation de inamici. Construiește structuri. unit.gamma.description = Apără nucleul Core de inamici. Construiește structuri. + +lst.read = Citește un număr dintr-o celulă de memorie conectată. +lst.write = Scrie un număr într-o celulă de memorie conectată. +lst.print = Adaugă text în bufferul de tipărire.\nNu tipărește decât când se execută [accent]Print Flush[]. +lst.draw = Adaugă o operație în bufferul de desenare.\nNu afișează decât când se execută [accent]Draw Flush[]. +lst.drawflush = Afișează pe un monitor instrucțiunile [accent]Draw[] aflate în așteptare. +lst.printflush = Tipărește într-un bloc Mesaj instrucțiunile [accent]Print[] aflate în așteptare. +lst.getlink = Obține o conexiune a procesorului după index. Începe de la 0. +lst.control = Controlează o clădire. +lst.radar = Localizează unitățile aflate în jurul unei clădiri. Are o anumită rază de acțiune. +lst.sensor = Obține date de la o clădire sau unitate. +lst.set = Setează o variabilă. +lst.operation = Efectuează o operație pe 1-2 variabile. +lst.end = Sari la începutul listei de instrucțiuni. +lst.jump = Dacă condiția este adevărată, mergi la o altă instrucțiune. +lst.unitbind = Controlează următoarea unitate de tipul selectat și reține-o în [accent]@unit[]. +lst.unitcontrol = Controlează unitatea controlată de procesor. +lst.unitradar = Localizează unitățile din jurul unității controlate de procesor. +lst.unitlocate = Localizează o poziție/clădire specifică oriunde pe hartă.\nNecesită o unitate controlată de procesor. + +lenum.type = Tipul clădirii/unității.\nde ex.: pt orice Router, va returna [accent]@router[].\nNu e un șir de caractere. +lenum.shoot = Lovește către o locație. +lenum.shootp = Lovește către o unitate/clădire. Anticipează viteza țintei și a proiectilului. +lenum.configure = Configurașia clădirii, de ex. materialul selectat pt Sortator. +lenum.enabled = Specifică dacă clădirea este pornită. +lenum.color = Culoarea Iluminatorului. + +lenum.always = Mereu adevărat. +lenum.idiv = Împărțirea naturală a numerelor (int). +lenum.div = Împărțirea.\nReturnează [accent]null[] dacă împarți la 0. +lenum.mod = Modulo (restul împărțirii). +lenum.equal = Egal. Convertește tipurile variabilelor.\nObiectele nenule comparate cu numere devin 1, cele nule devin 0. +lenum.notequal = Nu e egal. Convertește tipurile variabilelor. +lenum.strictequal = Egalitate strictă. Nu convertește tipurile variabilelor.\nPoate fi folosit pt a verifica dacă ceva este [accent]null[]. +lenum.shl = Shift left pe biți. +lenum.shr = Shift right pe biți. +lenum.or = OR/SAU. Ține cont de biți. +lenum.land = Logical AND/ȘI logic. Nu ține cont de biți. +lenum.and = AND/ȘI. Ține cont de biți. +lenum.not = NOT. Inversează biții. +lenum.xor = XOR/disjuncție exclusivă. Ține cont de biți. + +lenum.min = Minimul a două numere. +lenum.max = Maximul a două numere. +lenum.angle = Unghiul unui vector în grade. +lenum.len = Lungimea unui vector. +lenum.sin = Sinus în grade. +lenum.cos = Cosinus în grade. +lenum.tan = Tangentă în grade. +#cea de mai jos nu-i o greșeală, caută pe net notarea intervalelor în matematică +lenum.rand = Număr aleatoriu în intervalul [0, val). +lenum.log = Logaritm natural (ln). +lenum.log10 = Logaritm în baza 10. +lenum.noise = 2D simplex noise. +lenum.abs = Valoarea absolută. +lenum.sqrt = Radical/rădăcina pătrată. + +lenum.any = Orice unitate. +lenum.ally = Unitate aliată. +lenum.attacker = Unitate cu armă. +lenum.enemy = Unitate inamică. +lenum.boss = Unitate gardian. +lenum.flying = Unitate care zboară. +lenum.ground = Unitate de artilerie. +lenum.player = Unitate controlată de un jucător. + +lenum.ore = Depozit de minereu. +lenum.damaged = Clădire aliată deteriorată. +lenum.spawn = Punct de lansare inamic.\nPoate fi un nucleu sau o poziție. +lenum.building = Clădire dintr-un grup specific. + +lenum.core = Orice nucleu. +lenum.storage = Clădire de stocare, de ex. Containerul. +lenum.generator = Clădiri care generează electricitate. +lenum.factory = Clădiri care transformă resurse. +lenum.repair = Puncte de Reparare. +lenum.rally = Centre de Comandă. +lenum.battery = Orice baterie. +lenum.resupply = Puncte de Realimentare.\nRelevant doar când [accent]"Unitățile Necesită Muniție"[] este activată. +lenum.reactor = Reactor de Toriu/Impact. +lenum.turret = Orice armă. + +sensor.in = Clădirea/unitatea care trebuie detectată. + +radar.from = Clădirea de la care detectăm.\nRaza senzorului e limitată de raza de costrucție. +radar.target = Filtru pt unitățile care trebuie detectate. +radar.and = Adaugă filtre. +radar.order = Ordinea de sortare. 0 pt a inversa ordinea. +radar.sort = Modul cum sortăm rezultatele. +radar.output = Variabila în care se va scrie unitatea detectată. + +unitradar.target = Filtru pt unitățile care trebuie detectate. +unitradar.and = Adaugă filtre. +unitradar.order = Ordinea de sortare. 0 pt a inversa ordinea. +unitradar.sort = Modul cum sortăm rezultatele. +unitradar.output = Variabila în care se reține unitatea detectată. + +control.of = Clădirea de controlat. +control.unit = Unitatea/clădirea către care se țintește. +control.shoot = Specifică dacă armele trag. + +unitlocate.enemy = Specifică dacă se detectează clădirile inamice. +unitlocate.found = Specifică dacă obiectul a fost găsit. +unitlocate.building = Clădirea detectată. +unitlocate.outx = Coordonata X a obiectului detectat. +unitlocate.outy = Coordonata Y a obiectului detectat. +unitlocate.group = Grupul clădirilor de detectat. + +lenum.stop = Oprește acțiunea curentă. Nu mișca/mina/construi. +lenum.move = Mergi la această poziție. +lenum.approach = Apropie-te la o anumită distanță de poziție. +lenum.pathfind = Găsește ruta către punctul de lansare inamic. Poate fi un nucleu. +lenum.target = Lovește către o poziție. +lenum.targetp = Lovește o țintă. Anticipează viteza țintei și a proiectilului. +lenum.itemdrop = Descarcă o bucată de material. +lenum.itemtake = Ia o bucată de material dintr-o clădire. +lenum.paydrop = Descarcă încărcătura curentă. +lenum.paytake = Ia o încărcătură de la locația curentă. +lenum.flag = Oferă o etichetă numerică unității. +lenum.mine = Minează din această locație. +lenum.build = Construiește o structură. +lenum.getblock = Obține clădirea și tipul clădirii aflate la coordonatele specificate.\nUnitatea trebuie să se afle în raza poziției.\nBlocurile solide care nu sunt clădiri vor avea tipul [accent]@solid[]. +lenum.within = Verifică dacă unitatea se află în apropierea poziției. +lenum.boost = Pornește/oprește propulsorul. From a2e5dae27f74aea7bcc916018f5d7c3c663b4c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Mon, 15 Feb 2021 23:46:19 +0800 Subject: [PATCH 269/426] Updated zh-TW translations of Logic Hints (#4666) * Logic Hint pt.1 Some Logic Hints and minor tweaks in previous translations * Logic Hints pt.2 * Logic Hints pt. 3/3 --- core/assets/bundles/bundle_zh_TW.properties | 136 +++++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 9027c173a9..1cf73184e8 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -41,10 +41,11 @@ be.ignore = 忽略 be.noupdates = 沒有新的更新。 be.check = 檢查是否有新的更新 -mod.featured.dialog.title = 模組瀏覽器 (尚未完成) +mods.browser = 模組瀏覽器 mods.browser.selected = 已選模組 mods.browser.add = 安裝 -mods.github.open = 查看 +mods.github.reinstall = 重新安裝 +mods.github.open = 查看Github mods.browser.sortdate = 以最近篩選 mods.browser.sortstars = 以星數篩選 @@ -118,9 +119,11 @@ mods.none = [lightgray]找不到模組! mods.guide = 模組指南 mods.report = 回報錯誤 mods.openfolder = 開啟模組資料夾 +mods.viewcontent = 查看內容 mods.reload = 重新載入 mods.reloadexit = 遊戲將會結束以重新載入模組。 mod.display = [gray]模組:[orange]{0} +mod.installed = [[已安裝] mod.enabled = [lightgray]已啟用 mod.disabled = [scarlet]已禁用 mod.disable = 禁用 @@ -309,6 +312,7 @@ cancelbuilding = [accent][[{0}][]清除計畫 selectschematic = [accent][[{0}][]選擇並複製 pausebuilding = [accent][[{0}][]暫停建造 resumebuilding = [scarlet][[{0}][]繼續建造 +enablebuilding = [scarlet][[{0}][]啟用建造 showui = 已隱藏介面。\n按[accent][[{0}][]顯示介面。 wave = [accent]第{0}波 wave.cap = [accent]Wave {0}/{1} @@ -422,7 +426,7 @@ editor.exportimage = 匯出地形圖片檔 editor.exportimage.description = 匯出地形圖片檔 editor.loadimage = 載入圖片 editor.saveimage = 儲存圖片 -editor.unsaved = [scarlet]尚未儲存變更![]\n您確定要退出嗎? +editor.unsaved = 您確定要退出嗎?\n[scarlet](將遺失未儲存的變更)[] editor.resizemap = 調整地圖大小 editor.mapname = 地圖名稱: editor.overwrite = [accent]警告!這將會覆蓋現有的地圖。 @@ -680,6 +684,7 @@ stat.drillspeed = 基本鑽取速度 stat.boosteffect = 加速效果 stat.maxunits = 最大活躍單位 stat.health = 耐久度 +stat.armor = 裝甲 stat.buildtime = 建設時間 stat.maxconsecutive = 最大連續 stat.buildcost = 建造成本 @@ -791,6 +796,7 @@ setting.shadows.name = 陰影 setting.blockreplace.name = 方塊建造建議 setting.linear.name = 線性過濾 setting.hints.name = 提示 +setting.logichints.name = 邏輯提示 setting.flow.name = 顯示資源輸送速度 setting.backgroundpause.name = 背景執行時暫停 setting.buildautopause.name = 自動暫停建築 @@ -1508,3 +1514,127 @@ unit.omura.description = 對敵人發射遠程穿透型砲彈。建造曳光戰 unit.alpha.description = 抵禦敵軍對核心:碎片的攻擊。建造建築物。 unit.beta.description = 抵禦敵軍對核心:基地的攻擊。建造建築物。 unit.gamma.description = 抵禦敵軍對核心:核子的攻擊。建造建築物。 + +lst.read = [accent]讀取[]記憶體中的一項數值 +lst.write = [accent]寫入[]一項數值到記憶體中 +lst.print = 將文字加入輸出的暫存中,搭配[accent]Print Flush[]使用 +lst.draw = 將圖形加入顯示的暫存中,搭配[accent]Draw Flush[]使用 +lst.drawflush = 將所有暫存的[accent]Draw[]指令推到顯示器上 +lst.printflush = 將所有暫存的[accent]Print[]指令推到訊息板上 +lst.getlink = 由連接順序回傳連接的建築,第一個從"0"開始 +lst.control = 控制一個建築 +lst.radar = 偵測建築範圍內的單位 +lst.sensor = 獲取該建築或單位的數據 +lst.set = 設一個變數 +lst.operation = 加減乘除和計算機概論 +lst.end = 跳到第一個重頭開始執行 +lst.jump = 條件式跳到其他指令執行 +lst.unitbind = 綁定下一同種單位,存入[accent]@unit[]中. +lst.unitcontrol = 控制現在綁定的單位 +lst.unitradar = 偵測綁定單位附近的單位 +lst.unitlocate = 尋找整個地圖上特定的位置/建築\n需要綁定的單位 + +lenum.type = 建築/單位種類。\n例:操控單位建造光矛砲應使用[accent]@lancer[],而非字串 +lenum.shoot = 對該位置開火 +lenum.shootp = 對指定單位/建築開火,具自瞄功能 +lenum.configure = 建築設定,如分類器、兵器工廠 +lenum.enabled = 確認該建築是否啟用 +lenum.color = 設定照明燈的顏色 + +lenum.always = 永遠 true (直接跳). +lenum.idiv = 整數除法,無條件捨去. +lenum.div = 除法.\n除以零時回傳 [accent]null[] +lenum.mod = Modulo,求餘數 +lenum.equal = 是否相等,不管資料型態。\n非null 物件和數值相比時回傳1 +lenum.notequal = 不相等,不管資料型態. +lenum.strictequal = 嚴格檢查是否相等,會看資料型態。\n可用來檢查[accent]null[] +lenum.shl = Bit-shift left. +lenum.shr = Bit-shift right. +lenum.or = Bitwise OR. +lenum.land = Logical AND. +lenum.and = Bitwise AND. +lenum.not = Bitwise flip. +lenum.xor = Bitwise XOR. + +lenum.min = Minimum of two numbers. +lenum.max = Maximum of two numbers. +lenum.angle = Angle of vector in degrees. +lenum.len = Length of vector. +lenum.sin = Sine, in degrees. +lenum.cos = Cosine, in degrees. +lenum.tan = Tangent, in degrees. +#not a typo, look up 'range notation' +lenum.rand = Random number in range [0, value). +lenum.log = Natural logarithm (ln). +lenum.log10 = Base 10 logarithm. +lenum.noise = 2D simplex noise. +lenum.abs = 取絕對值 +lenum.sqrt = 開根號 + +lenum.any = 任何單位 +lenum.ally = 友方單位 +lenum.attacker = 具武器的單位 +lenum.enemy = 敵方單位 +lenum.boss = 頭目單位 +lenum.flying = 飛行單位 +lenum.ground = 陸上單位 +lenum.player = 玩家單位 + +lenum.ore = 尋找礦物 +lenum.damaged = 尋找受損友方建築 +lenum.spawn = 敵方重生點\n可以是核心或一個位置 +lenum.building = 尋找特定建築 + +lenum.core = 任何核心 +lenum.storage = 儲藏建築 +lenum.generator = 會發電的建築 +lenum.factory = 生產加工資源的建築,如煉矽場 +lenum.repair = 維修點 +lenum.rally = 指揮中心 +lenum.battery = 電池 +lenum.resupply = 補給點\n只有在[accent]"單位需要彈藥"[]被啟用時才有效果 +lenum.reactor = 衝擊/釷反應爐 +lenum.turret = 任何砲塔 + +sensor.in = 想查閱的建築/單位 + +radar.from = 作為雷達的建築\n偵測範圍同該建築的範圍 +radar.target = 搜索條件 +radar.and = 額外條件 +radar.order = 輸出順序,1:距離最近、血量最大 +radar.sort = 篩選方式 +radar.output = 回傳該單位為變數 + +unitradar.target = 搜索條件 +unitradar.and = 額外條件 +unitradar.order = 輸出順序,1:距離最近、血量最大 +unitradar.sort = 篩選方式 +unitradar.output = 存該單位的變數 + +control.of = 要控制的建築 +control.unit = 指定的建築/單位 +control.shoot = 是否開火 + +unitlocate.enemy = 搜索敵方或友方建築 +unitlocate.found = 回傳是否找到建築 +unitlocate.building = 回傳找到的建築為變數 +unitlocate.outx = 回傳 X 座標 +unitlocate.outy = 回傳 Y 座標 +unitlocate.group = 搜索建築種類 + +lenum.stop = 停止移動/挖礦/建造 +lenum.move = 移動到指定位置 +lenum.approach = 移動到距離指定位置一段距離的地方 +lenum.pathfind = 由內建AI前往敵方重生點 +lenum.target = 射擊指定區域 +lenum.targetp = 帶自瞄射擊指定的目標 +lenum.itemdrop = 放下物品 +lenum.itemtake = 從建築拿取物品 +lenum.paydrop = 放下拾取的負載 +lenum.paytake = 拾取船身下方的單位/建築 +lenum.flag = 單位編號(可異) +lenum.mine = 挖指定位置的礦物 +lenum.build = 建造一個建築 +lenum.getblock = 獲取指定位置的建築種類和該建築\n必須在單位的範圍內\n實體障礙物,如高山會回傳[accent]@solid[] +lenum.within = 單位是否在指定範圍內 +lenum.boost = 使用推進器 From 4bbb4b9a19b1e14acf252e8c61cca21ce9c18a9a Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 15 Feb 2021 11:00:49 -0500 Subject: [PATCH 270/426] Reorder NaN check --- core/src/mindustry/ai/types/LogicAI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index c910999c2f..5f72520729 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -119,9 +119,6 @@ public class LogicAI extends AIController{ vec.set(target).sub(unit); - //do not move when infinite vectors are used. - if(vec.isNaN() || vec.isInfinite()) return; - float length = circleLength <= 0.001f ? 1f : Mathf.clamp((unit.dst(target) - circleLength) / smooth, -1f, 1f); vec.setLength(unit.realSpeed() * length); @@ -131,6 +128,9 @@ public class LogicAI extends AIController{ vec.setZero(); } + //do not move when infinite vectors are used. + if(vec.isNaN() || vec.isInfinite()) return; + unit.approach(vec); } From 710a55dc2db76bec6734d75b736f439370df8c0a Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 15 Feb 2021 11:08:56 -0500 Subject: [PATCH 271/426] Reverted pixmap blending rename --- gradle.properties | 2 +- tools/src/mindustry/tools/Generators.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index a2de2401ed..caf85797e8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=baaa8652a41304abff81995aaf90f6589461ec0c +archash=477c5e7892e49a8ae1d840feae2379fec15c838c diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index ef579df8c4..2cc68f1eff 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -4,7 +4,6 @@ import arc.*; import arc.files.*; import arc.func.*; import arc.graphics.*; -import arc.graphics.Pixmap.*; import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; @@ -44,7 +43,7 @@ public class Generators{ if(!fi.extEquals("png")) return; Pixmap pix = new Pixmap(fi); - pix.setBlending(PixmapBlending.sourceOver); + pix.setBlending(Pixmap.Blending.sourceOver); pix.each((x, y) -> { int value = pix.getPixel(x, y); pix.draw(x, y, paletteMap.get(value, value)); From c942331117cb3809f576eeb8a9ab29e4d183019e Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 15 Feb 2021 18:00:47 -0500 Subject: [PATCH 272/426] New splash damage algorithm --- core/src/mindustry/content/Fx.java | 6 + core/src/mindustry/content/UnitTypes.java | 14 +-- core/src/mindustry/entities/Damage.java | 110 ++++++++++-------- .../entities/units/AIController.java | 2 +- .../world/blocks/power/NuclearReactor.java | 4 +- 5 files changed, 77 insertions(+), 59 deletions(-) diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index a97b3386c6..2b5fd4220b 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -1609,6 +1609,12 @@ public class Fx{ Fill.square(e.x, e.y, e.rotation * tilesize / 2f); }), + lightBlock = new Effect(60, e -> { + color(e.color); + alpha(e.fout() * 1); + Fill.square(e.x, e.y, e.rotation * tilesize / 2f); + }), + overdriveBlockFull = new Effect(60, e -> { color(e.color); alpha(e.fslope() * 0.4f); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 194c7a605d..14767e5a7a 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -565,9 +565,9 @@ public class UnitTypes implements ContentList{ hitEffect = Fx.pulverize; lifetime = 10f; speed = 1f; - splashDamageRadius = 70f; + splashDamageRadius = 58f; instantDisappear = true; - splashDamage = 80f; + splashDamage = 85f; killShooter = true; hittable = false; collidesAir = true; @@ -769,7 +769,7 @@ public class UnitTypes implements ContentList{ width = height = 19f; collidesTiles = true; ammoMultiplier = 4f; - splashDamageRadius = 95f; + splashDamageRadius = 80f; splashDamage = 65f; backColor = Pal.sapBulletBack; frontColor = lightningColor = Pal.sapBullet; @@ -867,7 +867,7 @@ public class UnitTypes implements ContentList{ width = height = 25f; collidesTiles = collides = true; ammoMultiplier = 4f; - splashDamageRadius = 90f; + splashDamageRadius = 80f; splashDamage = 75f; backColor = Pal.sapBulletBack; frontColor = lightningColor = Pal.sapBullet; @@ -888,7 +888,7 @@ public class UnitTypes implements ContentList{ lifetime = 90f; width = height = 20f; collidesTiles = false; - splashDamageRadius = 80f; + splashDamageRadius = 70f; splashDamage = 40f; backColor = Pal.sapBulletBack; frontColor = lightningColor = Pal.sapBullet; @@ -1367,7 +1367,7 @@ public class UnitTypes implements ContentList{ healPercent = 15f; splashDamage = 230f; - splashDamageRadius = 120f; + splashDamageRadius = 81f; }}; }}); }}; @@ -1537,7 +1537,7 @@ public class UnitTypes implements ContentList{ width = 15f; collidesTiles = false; ammoMultiplier = 4f; - splashDamageRadius = 60f; + splashDamageRadius = 50f; splashDamage = 80f; backColor = Pal.missileYellowBack; frontColor = Pal.missileYellow; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 285259f60e..83639450d0 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -6,7 +6,6 @@ import arc.math.*; import arc.math.geom.*; import arc.struct.*; import arc.util.*; -import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.core.*; import mindustry.game.EventType.*; @@ -25,11 +24,10 @@ public class Damage{ private static Rect hitrect = new Rect(); private static Vec2 tr = new Vec2(), seg1 = new Vec2(), seg2 = new Vec2(); private static Seq units = new Seq<>(); - private static GridBits bits = new GridBits(30, 30); - private static IntQueue propagation = new IntQueue(); private static IntSet collidedBlocks = new IntSet(); private static Building tmpBuilding; private static Unit tmpUnit; + private static IntFloatMap damages = new IntFloatMap(); /** Creates a dynamic explosion based on specified parameters. */ public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage){ @@ -365,64 +363,85 @@ public class Damage{ if(ground){ if(!complete){ - int trad = (int)(radius / tilesize); - Tile tile = world.tileWorld(x, y); - if(tile != null){ - tileDamage(team, tile.x, tile.y, trad, damage); - } + //increase damage slightly to compensate for new algorithm + tileDamage(team, World.toTile(x), World.toTile(y), radius / tilesize, damage * 1.1f); }else{ completeDamage(team, x, y, radius, damage); } } } - public static void tileDamage(Team team, int startx, int starty, int baseRadius, float baseDamage){ - //tile damage is posted, so that destroying a block that causes a chain explosion will run in the next frame - //this prevents recursive damage calls from messing up temporary variables + public static void tileDamage(Team team, int x, int y, float baseRadius, float damage){ + Core.app.post(() -> { - bits.clear(); - propagation.clear(); - int bitOffset = bits.width() / 2; + var in = world.build(x, y); + //spawned inside a multiblock. this means that damage needs to be dealt directly. + //why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion. + //this needs to be compensated + if(in != null && in.team != team && in.block.size > 1 && in.health > damage){ + //deal the damage of an entire side * 2, to be equivalent with the maximum "standard" side damage + 1 + in.damage(damage * (in.block.size * 2)); + //no need to continue with the explosion + return; + } - propagation.addFirst(PropCell.get((byte)0, (byte)0, (short)baseDamage)); - //clamp radius to fit bits - int radius = Math.min(baseRadius, bits.width() / 2); + //cap radius to prevent lag + float radius = Math.min(baseRadius, 30), rad2 = radius * radius; + int rays = Mathf.ceil(radius * 2 * Mathf.pi); + double spacing = Math.PI * 2.0 / rays; + damages.clear(); - while(!propagation.isEmpty()){ - int prop = propagation.removeLast(); - int x = PropCell.x(prop); - int y = PropCell.y(prop); - int damage = PropCell.damage(prop); - //manhattan distance used for calculating falloff, results in a diamond pattern - int dst = Math.abs(x) + Math.abs(y); + //raycast from each angle + for(int i = 0; i <= rays; i++){ + float dealt = 0f; + int startX = x; + int startY = y; + int endX = x + (int)(Math.cos(spacing * i) * radius), endY = y + (int)(Math.sin(spacing * i) * radius); - int scaledDamage = (int)(damage * (1f - (float)dst / radius)); + int xDist = Math.abs(endX - startX); + int yDist = -Math.abs(endY - startY); + int xStep = (startX < endX ? +1 : -1); + int yStep = (startY < endY ? +1 : -1); + int error = xDist + yDist; - bits.set(bitOffset + x, bitOffset + y); - Tile tile = world.tile(startx + x, starty + y); + while(startX != endX || startY != endY){ + var build = world.build(startX, startY); + if(build != null && build.team != team){ + //damage dealt at circle edge + float edgeScale = 0.6f; + float mult = (1f-(Mathf.dst2(startX, startY, x, y) / rad2) + edgeScale) / (1f + edgeScale); + float next = damage * mult - dealt; + //register damage dealt + int p = Point2.pack(startX, startY); + damages.put(p, Math.max(damages.get(p), next)); + //register as hit + dealt += build.health; - if(scaledDamage <= 0 || tile == null) continue; - - //apply damage to entity if needed - if(tile.build != null && tile.build.team != team){ - int health = (int)(tile.build.health / (tile.block().size * tile.block().size)); - if(tile.build.health > 0){ - tile.build.damage(scaledDamage); - scaledDamage -= health; - - if(scaledDamage <= 0) continue; + if(next - dealt <= 0){ + break; + } } - } - for(Point2 p : Geometry.d4){ - if(!bits.get(bitOffset + x + p.x, bitOffset + y + p.y)){ - propagation.addFirst(PropCell.get((byte)(x + p.x), (byte)(y + p.y), (short)scaledDamage)); + if(2 * error - yDist > xDist - 2 * error){ + error += yDist; + startX += xStep; + }else{ + error += xDist; + startY += yStep; } } } - }); + //apply damage + for(var e : damages){ + int cx = Point2.x(e.key), cy = Point2.y(e.key); + var build = world.build(cx, cy); + if(build != null){ + build.damage(e.value); + } + } + }); } private static void completeDamage(Team team, float x, float y, float radius, float damage){ @@ -443,11 +462,4 @@ public class Damage{ float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff); return damage * scaled; } - - @Struct - static class PropCellStruct{ - byte x; - byte y; - short damage; - } } diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 71bde595ce..c4fc27792a 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -15,7 +15,7 @@ import static mindustry.Vars.*; public class AIController implements UnitController{ protected static final Vec2 vec = new Vec2(); - protected static final int timerTarget = 0, timerTarget2 = 1, timerTarget3 = 2, timerTarget4 = 2; + protected static final int timerTarget = 0, timerTarget2 = 1, timerTarget3 = 2, timerTarget4 = 3; protected Unit unit; protected Interval timer = new Interval(4); diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index aa7eed3b71..dd15da24cc 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -33,8 +33,8 @@ public class NuclearReactor extends PowerGenerator{ public float itemDuration = 120; //time to consume 1 fuel public float heating = 0.01f; //heating per frame * fullness public float smokeThreshold = 0.3f; //threshold at which block starts smoking - public int explosionRadius = 40; - public int explosionDamage = 1350; + public int explosionRadius = 20; + public int explosionDamage = 1250; public float flashThreshold = 0.46f; //heat threshold at which the lights start flashing public float coolantPower = 0.5f; From 957583071d23b240c5d5b5ae92492da6795ed7e0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 15 Feb 2021 18:42:24 -0500 Subject: [PATCH 273/426] Splash damage tweaks --- core/assets/maps/tarFields.msav | Bin 15542 -> 15543 bytes core/src/mindustry/content/UnitTypes.java | 4 ++-- core/src/mindustry/entities/Damage.java | 4 ++-- gradle.properties | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/assets/maps/tarFields.msav b/core/assets/maps/tarFields.msav index 72230396d942886117e3fed03c912c45909588be..995db24ab1c609077a965518ff72ced3f240d380 100644 GIT binary patch literal 15543 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 diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 14767e5a7a..b7c5062164 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1366,8 +1366,8 @@ public class UnitTypes implements ContentList{ collides = false; healPercent = 15f; - splashDamage = 230f; - splashDamageRadius = 81f; + splashDamage = 220f; + splashDamageRadius = 80f; }}; }}); }}; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 83639450d0..df4e5c3a35 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -380,8 +380,8 @@ public class Damage{ //why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion. //this needs to be compensated if(in != null && in.team != team && in.block.size > 1 && in.health > damage){ - //deal the damage of an entire side * 2, to be equivalent with the maximum "standard" side damage + 1 - in.damage(damage * (in.block.size * 2)); + //deal the damage of an entire side + 1, to be equivalent with maximum 'standard' damage + in.damage(damage * (in.block.size + 1)); //no need to continue with the explosion return; } diff --git a/gradle.properties b/gradle.properties index caf85797e8..aef9f992ed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=477c5e7892e49a8ae1d840feae2379fec15c838c +archash=2f044212b72385c64f4f1a1e488e8c5ee62c5740 From 631e4d9eefca8b94de4fc52e57387b2c2f4ffecf Mon Sep 17 00:00:00 2001 From: TranquillyUnpleasant <62061444+TranquillyUnpleasant@users.noreply.github.com> Date: Tue, 16 Feb 2021 06:15:56 +0500 Subject: [PATCH 274/426] Unit cap (#4689) * Add unit caps as a map setting. * Use int and add maximum and minimum handling. * Put a lower limit of 0 for unit cap --- core/assets/bundles/bundle.properties | 2 ++ core/src/mindustry/entities/Units.java | 2 +- core/src/mindustry/game/Rules.java | 2 ++ .../src/mindustry/ui/dialogs/CustomRulesDialog.java | 13 +++++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 357d5290cc..af0e18042c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -957,6 +957,8 @@ rules.blockdamagemultiplier = Block Damage Multiplier rules.unitbuildspeedmultiplier = Unit Production Speed Multiplier rules.unithealthmultiplier = Unit Health Multiplier rules.unitdamagemultiplier = Unit Damage Multiplier +rules.unitcapvariable = Cores Contribute To Unit Cap +rules.unitcap = Base Unit Cap rules.enemycorebuildradius = Enemy Core No-Build Radius:[lightgray] (tiles) rules.wavespacing = Wave Spacing:[lightgray] (sec) rules.buildcostmultiplier = Build Cost Multiplier diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index 3d73faebd6..970374811b 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -76,7 +76,7 @@ public class Units{ if((team == state.rules.waveTeam && !state.rules.pvp) || (state.isCampaign() && team == state.rules.waveTeam)){ return Integer.MAX_VALUE; } - return state.rules.unitCap + indexer.getExtraUnits(team); + return Math.max(0, state.rules.unitCapVariable ? state.rules.unitCap + indexer.getExtraUnits(team) : state.rules.unitCap); } /** @return whether this player can interact with a specific tile. if either of these are null, returns true.*/ diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index eb34bab55f..538422fef0 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -44,6 +44,8 @@ public class Rules{ public boolean fire = true; /** Whether units use and require ammo. */ public boolean unitAmmo = false; + /** Whether cores add to unit limit */ + public boolean unitCapVariable = true; /** How fast unit pads build units. */ public float unitBuildSpeedMultiplier = 1f; /** How much damage any other units deal. */ diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index b150b5fa9f..94ea454d21 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -161,6 +161,8 @@ public class CustomRulesDialog extends BaseDialog{ title("@rules.title.unit"); check("@rules.unitammo", b -> rules.unitAmmo = b, () -> rules.unitAmmo); + check("@rules.unitcapvariable", b -> rules.unitCapVariable = b, () -> rules.unitCapVariable); + number("@rules.unitcap", true, f -> rules.unitCap = f, () -> rules.unitCap, -999, 999); number("@rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0.001f, 50f); @@ -204,6 +206,17 @@ public class CustomRulesDialog extends BaseDialog{ number(text, false, cons, prov, condition, 0, Float.MAX_VALUE); } + void number(String text, boolean integer, Intc cons, Intp prov, int min, int max){ + main.table(t -> { + t.left(); + t.add(text).left().padRight(5); + t.field((integer ? (int)prov.get() : prov.get()) + "", s -> cons.get(Strings.parseInt(s))) + .padRight(100f) + .valid(f -> Strings.parseInt(f) >= min && Strings.parseInt(f) <= max).width(120f).left().addInputDialog(); + }).padTop(0); + main.row(); + } + void number(String text, boolean integer, Floatc cons, Floatp prov, Boolp condition, float min, float max){ main.table(t -> { t.left(); From 9d5454e5cea5ff5f38ae8f506865e58902fc2c21 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 16 Feb 2021 09:13:44 -0500 Subject: [PATCH 275/426] Fixed #4694 --- core/assets/maps/tarFields.msav | Bin 15543 -> 15541 bytes core/src/mindustry/core/Renderer.java | 2 +- .../src/mindustry/graphics/FloorRenderer.java | 1 + core/src/mindustry/input/Placement.java | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/assets/maps/tarFields.msav b/core/assets/maps/tarFields.msav index 995db24ab1c609077a965518ff72ced3f240d380..c2967456f334bf881bfd53a10c619d8c5df96ab0 100644 GIT binary patch delta 14914 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

@2ObIPeT$0qyK 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 diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 12e025f7c2..67815fd1d2 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -208,7 +208,7 @@ public class Renderer implements ApplicationListener{ Draw.draw(Layer.background, this::drawBackground); Draw.draw(Layer.floor, blocks.floor::drawFloor); Draw.draw(Layer.block - 1, blocks::drawShadows); - Draw.draw(Layer.block, () -> { + Draw.draw(Layer.block - 0.09f, () -> { blocks.floor.beginDraw(); blocks.floor.drawLayer(CacheLayer.walls); blocks.floor.endDraw(); diff --git a/core/src/mindustry/graphics/FloorRenderer.java b/core/src/mindustry/graphics/FloorRenderer.java index 3e8d4e1fcb..9f46b65c87 100644 --- a/core/src/mindustry/graphics/FloorRenderer.java +++ b/core/src/mindustry/graphics/FloorRenderer.java @@ -119,6 +119,7 @@ public class FloorRenderer implements Disposable{ return; } + Draw.flush(); cbatch.setProjection(Core.camera.mat); cbatch.beginDraw(); diff --git a/core/src/mindustry/input/Placement.java b/core/src/mindustry/input/Placement.java index 874269846f..85d14f2416 100644 --- a/core/src/mindustry/input/Placement.java +++ b/core/src/mindustry/input/Placement.java @@ -100,7 +100,7 @@ public class Placement{ i ++; } - if(!addedLast) result.add(base.peek()); + if(!addedLast && !base.isEmpty()) result.add(base.peek()); points.clear(); points.addAll(result); From 3f5114988352dcff5d2381b64441d8d7c863e2c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=82=A4=EC=97=90=EB=A5=B4?= <44261958+Kieaer@users.noreply.github.com> Date: Tue, 16 Feb 2021 23:50:52 +0900 Subject: [PATCH 276/426] Remove dead server (#4669) --- servers_v6.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/servers_v6.json b/servers_v6.json index b328fd3045..377f442023 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -47,10 +47,6 @@ "name": "mindustry.ddns.net", "address": ["mindustry.ddns.net:1000", "mindustry.ddns.net:2000", "mindustry.ddns.net:3000", "mindustry.ddns.net:4000"] }, - { - "name": "Gearblock", - "address": ["attack.gearblock.app"] - }, { "name": "Surrealment", "address": ["md.surrealment.com"] From 214f3bb9b5da3628d7af02eb0ee7e4bd71a9c799 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 16 Feb 2021 10:57:20 -0500 Subject: [PATCH 277/426] Improved data file zipping --- .../ui/dialogs/SettingsMenuDialog.java | 19 ++++++++++++++++--- gradle.properties | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index 6047fd7858..e531581f9b 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -453,11 +453,24 @@ public class SettingsMenuDialog extends SettingsDialog{ files.addAll(schematicDirectory.list()); String base = Core.settings.getDataDirectory().path(); + //add directories + for(Fi other : files.copy()){ + Fi parent = other.parent(); + while(!files.contains(parent) && !parent.equals(settings.getDataDirectory())){ + files.add(parent); + } + } + try(OutputStream fos = file.write(false, 2048); ZipOutputStream zos = new ZipOutputStream(fos)){ for(Fi add : files){ - if(add.isDirectory()) continue; - zos.putNextEntry(new ZipEntry(add.path().substring(base.length()))); - Streams.copy(add.read(), zos); + String path = add.path().substring(base.length()); + if(add.isDirectory()) path += "/"; + //fix trailing / in path + path = path.startsWith("/") ? path.substring(1) : path; + zos.putNextEntry(new ZipEntry(path)); + if(!add.isDirectory()){ + Streams.copy(add.read(), zos); + } zos.closeEntry(); } } diff --git a/gradle.properties b/gradle.properties index aef9f992ed..ee030c6ea9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=2f044212b72385c64f4f1a1e488e8c5ee62c5740 +archash=733430e6bc8bf4d997f43e30a7009b9b84d3e0f0 From f64ad2db9f76f38c57a62c37290c91320b81c13c Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 16 Feb 2021 17:46:51 +0100 Subject: [PATCH 278/426] Remove another dead server (#4699) --- servers_be.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/servers_be.json b/servers_be.json index 15293d25f5..eeb7ce8b21 100644 --- a/servers_be.json +++ b/servers_be.json @@ -4,8 +4,5 @@ }, { "address": "nydustry.nydus.app:6060" - }, - { - "address": "mindustry.pl:6660" } ] From 1ffdd9fd99965131ef7714364891db6ca8b0fbd8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 16 Feb 2021 12:20:30 -0500 Subject: [PATCH 279/426] Fixed #4701 --- core/src/mindustry/world/blocks/power/PowerNode.java | 1 - gradle.properties | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 0c66eef09a..ad17ea3acd 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -145,7 +145,6 @@ public class PowerNode extends PowerBlock{ getPotentialLinks(tile, other -> { Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place); - insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> { Drawf.square(cause.x, cause.y, cause.block.size * tilesize / 2f + 2f, Pal.plastanium); }); diff --git a/gradle.properties b/gradle.properties index ee030c6ea9..5d248978cc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=733430e6bc8bf4d997f43e30a7009b9b84d3e0f0 +archash=9882706f68a954ce9d29b64cb8224cd4ec3cedc3 From b0082c92c502f6cf7d541d9f8691194c7679a805 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 16 Feb 2021 13:02:15 -0500 Subject: [PATCH 280/426] Fixed green line bug - Removed stencil+depth buffers --- .../mindustry/android/AndroidLauncher.java | 1 - core/src/mindustry/core/Renderer.java | 1 - .../mindustry/ui/fragments/HudFragment.java | 38 +++++++++---------- .../world/blocks/power/PowerNode.java | 1 + .../mindustry/desktop/DesktopLauncher.java | 1 - gradle.properties | 2 +- ios/src/mindustry/ios/IOSLauncher.java | 7 +--- 7 files changed, 22 insertions(+), 29 deletions(-) diff --git a/android/src/mindustry/android/AndroidLauncher.java b/android/src/mindustry/android/AndroidLauncher.java index 1c9ee8f144..b92865c68a 100644 --- a/android/src/mindustry/android/AndroidLauncher.java +++ b/android/src/mindustry/android/AndroidLauncher.java @@ -162,7 +162,6 @@ public class AndroidLauncher extends AndroidApplication{ }, new AndroidApplicationConfiguration(){{ useImmersiveMode = true; hideStatusBar = true; - stencil = 8; }}); checkFiles(getIntent()); diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 67815fd1d2..52f99b72d5 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -67,7 +67,6 @@ public class Renderer implements ApplicationListener{ @Override public void update(){ Color.white.set(1f, 1f, 1f, 1f); - Gl.clear(Gl.stencilBufferBit); float dest = Mathf.round(targetscale, 0.5f); camerascale = Mathf.lerpDelta(camerascale, dest, 0.1f); diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index a5f1269cbc..1f8568a920 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -637,20 +637,11 @@ public class HudFragment extends Fragment{ if(Float.isNaN(value) || Float.isInfinite(value)) value = 1f; - drawInner(Pal.darkishGray); - - Draw.beginStencil(); - - Fill.crect(x, y, width, height * value); - - Draw.beginStenciled(); - - drawInner(Tmp.c1.set(color).lerp(Color.white, blink)); - - Draw.endStencil(); + drawInner(Pal.darkishGray, 1f); + drawInner(Tmp.c1.set(color).lerp(Color.white, blink), value); } - void drawInner(Color color){ + void drawInner(Color color, float fract){ if(flip){ x += width; width = -width; @@ -660,19 +651,26 @@ public class HudFragment extends Fragment{ float bh = height/2f; Draw.color(color); + float f1 = Math.min(fract * 2f, 1f), f2 = (fract - 0.5f) * 2f; + + float bo = -(1f - f1) * (width - stroke); + Fill.quad( x, y, x + stroke, y, - x + width, y + bh, - x + width - stroke, y + bh + x + width + bo, y + bh * f1, + x + width - stroke + bo, y + bh * f1 ); - Fill.quad( - x + width, y + bh, - x + width - stroke, y + bh, - x, y + height, - x + stroke, y + height - ); + if(f2 > 0){ + float bx = x + (width - stroke) * (1f - f2); + Fill.quad( + x + width, y + bh, + x + width - stroke, y + bh, + bx, y + height * fract, + bx + stroke, y + height * fract + ); + } Draw.reset(); diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index ad17ea3acd..0c66eef09a 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -145,6 +145,7 @@ public class PowerNode extends PowerBlock{ getPotentialLinks(tile, other -> { Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place); + insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> { Drawf.square(cause.x, cause.y, cause.block.size * tilesize / 2f + 2f, Pal.plastanium); }); diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index cf60813b7b..ad8e03d5c0 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -36,7 +36,6 @@ public class DesktopLauncher extends ClientLauncher{ new SdlApplication(new DesktopLauncher(arg), new SdlConfig(){{ title = "Mindustry"; maximized = true; - stencil = 1; width = 900; height = 700; setWindowIcon(FileType.internal, "icons/icon_64.png"); diff --git a/gradle.properties b/gradle.properties index 5d248978cc..c5fbb43378 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=9882706f68a954ce9d29b64cb8224cd4ec3cedc3 +archash=383cca56f16c9cb00c77db681860d6f420f25b53 diff --git a/ios/src/mindustry/ios/IOSLauncher.java b/ios/src/mindustry/ios/IOSLauncher.java index 73f6fa1b93..eda03585bc 100644 --- a/ios/src/mindustry/ios/IOSLauncher.java +++ b/ios/src/mindustry/ios/IOSLauncher.java @@ -16,7 +16,6 @@ import mindustry.net.*; import mindustry.ui.*; import org.robovm.apple.coregraphics.*; import org.robovm.apple.foundation.*; -import org.robovm.apple.glkit.*; import org.robovm.apple.uikit.*; import org.robovm.objc.block.*; @@ -25,7 +24,7 @@ import java.util.*; import java.util.zip.*; import static mindustry.Vars.*; -import static org.robovm.apple.foundation.NSPathUtilities.getDocumentsDirectory; +import static org.robovm.apple.foundation.NSPathUtilities.*; //warnings for deprecated functions related to multi-window applications are not applicable here @SuppressWarnings("deprecation") @@ -175,9 +174,7 @@ public class IOSLauncher extends IOSApplication.Delegate{ forced = false; UINavigationController.attemptRotationToDeviceOrientation(); } - }, new IOSApplicationConfiguration(){{ - stencilFormat = GLKViewDrawableStencilFormat._8; - }}); + }, new IOSApplicationConfiguration()); } @Override From 66bdfcf877b6438607a2cd146ee31e3c312a0876 Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Wed, 17 Feb 2021 03:12:06 +0900 Subject: [PATCH 281/426] [KO] Update bundles again (#4695) *translated updated new logic hint *translated new rule *typo --- core/assets/bundles/bundle_ko.properties | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 891249bb55..b1ad628fa6 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -957,6 +957,8 @@ rules.blockdamagemultiplier = 블록 공격력 배수 rules.unitbuildspeedmultiplier = 유닛 생산 속도 배수 rules.unithealthmultiplier = 유닛 체력 배수 rules.unitdamagemultiplier = 유닛 공격력 배수 +rules.unitcapvariable = 코어 유닛 제한 추가 +rules.unitcap = 기본 유닛 제한 rules.enemycorebuildradius = 적 코어 건설 금지구역 범위:[lightgray] (타일) rules.wavespacing = 단계 간격:[lightgray] (초) rules.buildcostmultiplier = 건설 비용 배수 @@ -1410,7 +1412,7 @@ block.power-node.description = 연결된 노드에 전력을 전송합니다. block.power-node-large.description = 더 넓은 범위의 고급 전력 노드. block.surge-tower.description = 사용 가능한 연결 수가 적은 장거리 전력 노드. block.diode.description = 배터리 전력은 이 블록을 통해 한 방향으로만 흐를 수 있지만, 출력 방향 배터리의 전력이 더 적은 경우에만 가능합니다. -block.battery.description = 전기가 넘쳐날 때 전력을 저장할 수 있습니다. 전력에 적자가 발생할 때 전력을 출력합니다. +block.battery.description = 전력이 넘쳐날 때 저장할 수 있습니다. 전력에 적자가 발생할 때 전력을 출력합니다. block.battery-large.description = 일반 배터리보다 훨씬 더 많은 전력을 저장합니다. block.combustion-generator.description = 석탄과 같은 가연성 물질을 연소 시켜 전력을 생산합니다. block.thermal-generator.description = 열이 있는 곳에 설치하면 전력이 생성됩니다. @@ -1563,14 +1565,15 @@ lenum.len = 벡터의 길이 lenum.sin = 사인(도) lenum.cos = 코사인(도) lenum.tan = 탄젠트(도) -lenum.rand = 범위 내 난수[0 ~ 값] +#not a typo, look up 'range notation' +lenum.rand = 범위 내 난수[0 ~ 값) lenum.log = 자연 로그(진수) lenum.log10 = 상수 로그 lenum.noise = 2D 심플렉스 노이즈 lenum.abs = 절댓값 lenum.sqrt = 제곱근 -lenum.any = 아무 유닛 +lenum.any = 유닛 lenum.ally = 아군 유닛 lenum.attacker = 무기를 가진 유닛 lenum.enemy = 적 유닛 @@ -1584,8 +1587,16 @@ lenum.damaged = 손상된 아군 건물 lenum.spawn = 적 스폰 지점\n코어 또는 지점일 수 있음. lenum.building = 특정 건물 집단에 속한 건물 -lenum.core = 아무 코어 +lenum.core = 코어 lenum.storage = 창고같은 저장 건물 +lenum.generator = 전력을 생산하는 건물 +lenum.factory = 자원을 변환하는 건물 +lenum.repair = 수리 지점 +lenum.rally = 지휘소 +lenum.battery = 배터리 +lenum.resupply = 보급 지점.\n[accent]"유닛 탄약 필요"[]가 활성화되었을 때만 유의미합니다. +lenum.reactor = 핵융합로/토륨 원자로 +lenum.turret = 포탑ㅁ sensor.in = 감지할 건물/유닛 From b65dffca9d050152b29108f95883927ee53289fa Mon Sep 17 00:00:00 2001 From: Vanguard <55051135+XEN0PHIL@users.noreply.github.com> Date: Tue, 16 Feb 2021 21:12:17 +0300 Subject: [PATCH 282/426] 4 new, 1 changed (#4688) New: enablebuilding stat.armor setting.logichints.name (newline between radar.output and unitradar.target) Changed: lenum.turret --- core/assets/bundles/bundle_ru.properties | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index fdf148cd48..59cc1caa92 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -312,6 +312,7 @@ cancelbuilding = [accent][[{0}][] для очистки плана selectschematic = [accent][[{0}][] выделить и скопировать pausebuilding = [accent][[{0}][] для приостановки строительства resumebuilding = [scarlet][[{0}][] для продолжения строительства +enablebuilding = [scarlet][[{0}][] для включения строительства showui = Интерфейс скрыт.\nНажмите [accent][[{0}][] для отображения интерфейса. wave = [accent]Волна {0} wave.cap = [accent]Волна {0}/{1} @@ -683,6 +684,7 @@ stat.drillspeed = Базовая скорость бурения stat.boosteffect = Ускоряющий эффект stat.maxunits = Максимальное количество активных единиц stat.health = Прочность +stat.armor = Броня stat.buildtime = Время строительства stat.maxconsecutive = Макс. последовательность stat.buildcost = Стоимость строительства @@ -794,6 +796,7 @@ setting.shadows.name = Тени setting.blockreplace.name = Автоматическая замена блоков setting.linear.name = Линейная фильтрация setting.hints.name = Подсказки +setting.logichints.name = Подсказки для логики setting.flow.name = Показывать скорость потока ресурсов setting.backgroundpause.name = Фоновая пауза setting.buildautopause.name = Автоматическая приостановка строительства @@ -1591,7 +1594,7 @@ lenum.rally = Командный центр. lenum.battery = Любой аккумулятор. lenum.resupply = Пункты снабжения.\nАктуально только при включённом [accent]"Боев. ед. требуют боеприпасы"[]. lenum.reactor = Импульсный/ториевый реактор. -lenum.turret = Любое ядро. +lenum.turret = Любая турель. sensor.in = Постройка/единица для распознавания. @@ -1601,6 +1604,7 @@ radar.and = Дополнительные фильтры. radar.order = Порядок сортировки. 0 для обратного. radar.sort = Показатель для сортировки результатов. radar.output = Переменная для записи конечной единицы. + unitradar.target = Фильтр для распознавания единиц. unitradar.and = Дополнительные фильтры. unitradar.order = Порядок сортировки. 0 для обратного. From 41b50d67af2c7ebb5f3ac1f9a7852fbcb7023ac0 Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Tue, 16 Feb 2021 20:12:29 +0200 Subject: [PATCH 283/426] [Bundle][RO] Update (#4696) This PR was tested in-game and is ready to merge at any time. Changelog: - New strings/changes up to commit 631e4d9eefca8b94de4fc52e57387b2c2f4ffecf - Typo fixes & various other improvements --- core/assets/bundles/bundle_ro.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index d2ff766a93..c6c8ecd72f 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -957,6 +957,8 @@ rules.blockdamagemultiplier = Multiplicatorul Deteriorării Blocurilor rules.unitbuildspeedmultiplier = Multiplicatorul Vitezei de Producere a Unităților rules.unithealthmultiplier = Multiplicatorul Vieții Unităților rules.unitdamagemultiplier = Multiplicatorul Deteriorării Unităților +rules.unitcapvariable = Nucleele Contribuie la Limita Unităților +rules.unitcap = Limita de Bază a Unităților rules.enemycorebuildradius = Interzisă Construirea în Jurul Nucleului Inamic:[lightgray] (pătrate) rules.wavespacing = Spațiul Dintre Valuri:[lightgray] (sec) rules.buildcostmultiplier = Multiplicatorul Costului Construcției From 48745d7380fa7620fd5bcaa94a8c26d8a2a269d5 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 16 Feb 2021 13:40:34 -0500 Subject: [PATCH 284/426] Steam crash fix --- core/src/mindustry/editor/MapEditorDialog.java | 2 +- fastlane/metadata/android/en-US/changelogs/29816.txt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/29816.txt diff --git a/core/src/mindustry/editor/MapEditorDialog.java b/core/src/mindustry/editor/MapEditorDialog.java index 747615a637..f862256995 100644 --- a/core/src/mindustry/editor/MapEditorDialog.java +++ b/core/src/mindustry/editor/MapEditorDialog.java @@ -158,7 +158,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ platform.publish(map); }).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.tags.containsKey("steamid") ? - editor.tags.get("author").equals(steamPlayerName) ? "@workshop.listing" : "@view.workshop" : + editor.tags.get("author", "").equals(steamPlayerName) ? "@workshop.listing" : "@view.workshop" : "@editor.publish.workshop")); menu.cont.row(); diff --git a/fastlane/metadata/android/en-US/changelogs/29816.txt b/fastlane/metadata/android/en-US/changelogs/29816.txt new file mode 100644 index 0000000000..d16a60d0b6 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29816.txt @@ -0,0 +1,8 @@ +[This is a truncated changelog, see Github for full notes] +- Fixed enemy power nodes getting linked w/ allied ones, leading to buggy power behavior +- Fixed chat not working when paused +- Fixed 128+ cores on map breaking servers +- Fixed editor breaking building links on resize +- Made turrets/units take enemy hitbox size into account when targeting +- Made builder/repair AI flee from enemies when idle +- Mods: Many various bugfixes for json effects From 080fe8c3c4893ee2df3fc2f5bfb84b936e5ae35b Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 16 Feb 2021 15:54:20 -0500 Subject: [PATCH 285/426] Decreased impact reactor explosion radius --- core/src/mindustry/world/blocks/power/ImpactReactor.java | 4 ++-- core/src/mindustry/world/blocks/power/NuclearReactor.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/ImpactReactor.java b/core/src/mindustry/world/blocks/power/ImpactReactor.java index 09a7c9acb8..adf46ace7d 100644 --- a/core/src/mindustry/world/blocks/power/ImpactReactor.java +++ b/core/src/mindustry/world/blocks/power/ImpactReactor.java @@ -24,8 +24,8 @@ public class ImpactReactor extends PowerGenerator{ public float warmupSpeed = 0.001f; public float itemDuration = 60f; - public int explosionRadius = 50; - public int explosionDamage = 2000; + public int explosionRadius = 23; + public int explosionDamage = 1900; public Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b"); diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index dd15da24cc..7560a9d30d 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -33,7 +33,7 @@ public class NuclearReactor extends PowerGenerator{ public float itemDuration = 120; //time to consume 1 fuel public float heating = 0.01f; //heating per frame * fullness public float smokeThreshold = 0.3f; //threshold at which block starts smoking - public int explosionRadius = 20; + public int explosionRadius = 19; public int explosionDamage = 1250; public float flashThreshold = 0.46f; //heat threshold at which the lights start flashing public float coolantPower = 0.5f; From 5d9506eb12e1802e4614d5bdfd99e37aea624fd3 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Wed, 17 Feb 2021 15:12:20 +0100 Subject: [PATCH 286/426] Reshuffle nydus servers (#4708) --- servers.json | 2 +- servers_be.json | 2 +- servers_v6.json | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/servers.json b/servers.json index 2aaea0169a..49e3ddf346 100644 --- a/servers.json +++ b/servers.json @@ -6,7 +6,7 @@ "address": "mindustry.indielm.com" }, { - "address": "mindustry.nydus.app:1337" + "address": "v5.mindustry.nydus.app:6565" }, { "address": "mindustry.ru" diff --git a/servers_be.json b/servers_be.json index eeb7ce8b21..aa10471809 100644 --- a/servers_be.json +++ b/servers_be.json @@ -3,6 +3,6 @@ "address": "mindustry.us.to" }, { - "address": "nydustry.nydus.app:6060" + "address": "be.mindustry.nydus.app:6567" } ] diff --git a/servers_v6.json b/servers_v6.json index 377f442023..2b85b2bec5 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -82,5 +82,9 @@ { "name": "Mindustry PLAY", "address": ["92.63.100.160"] + }, + { + "name": "Nydus", + "address": ["v6.mindustry.nydus.app:6566"] } ] From fb40c0b9de9f2596ffa62055d6ba5de0360197bc Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Wed, 17 Feb 2021 23:12:49 +0900 Subject: [PATCH 287/426] cursed typo (#4705) cursed typocursed typocursed typocursed typocursed typocursed typocursed typocursed typo --- core/assets/bundles/bundle_ko.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index b1ad628fa6..5d5ab625ab 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -1528,7 +1528,7 @@ lst.control = 건물 조종하기 lst.radar = 건물 주변의 유닛 검색하기 lst.sensor = 건물 또는 유닛의 정보 얻기 lst.set = 변수 선언/할당하기 -lst.operation = 1~2개의 변수로 연산자하기 +lst.operation = 1~2개의 변수로 연산하기 lst.end = 실행줄의 가장 위로 점프하기 lst.jump = 조건부로 다른 실행문으로 점프하기 lst.unitbind = type 옆에 있는 유닛을 지정하고, [accent]@unit[]에 저장하기 From 00342ddaaed554c3ed5e5de0e4651dbb1eae014c Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 17 Feb 2021 09:15:17 -0500 Subject: [PATCH 288/426] Misc cleanup --- core/assets/bundles/bundle.properties | 1 - core/src/mindustry/ai/BaseAI.java | 10 ++++++++++ core/src/mindustry/ui/fragments/HudFragment.java | 1 + .../world/blocks/power/NuclearReactor.java | 13 +++++++++---- gradle.properties | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index af0e18042c..b989b942c1 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1541,7 +1541,6 @@ lenum.shoot = Shoot at a position. lenum.shootp = Shoot at a unit/building with velocity prediction. lenum.configure = Building configuration, e.g. sorter item. lenum.enabled = Whether the block is enabled. -lenum.color = Illuminator color. lenum.always = Always true. lenum.idiv = Integer division. diff --git a/core/src/mindustry/ai/BaseAI.java b/core/src/mindustry/ai/BaseAI.java index 1a3fa81a80..6fa84883e8 100644 --- a/core/src/mindustry/ai/BaseAI.java +++ b/core/src/mindustry/ai/BaseAI.java @@ -209,6 +209,16 @@ public class BaseAI{ } Tile wtile = world.tile(realX, realY); + if(tile.block instanceof PayloadConveyor || tile.block instanceof PayloadAcceptor){ + //near a building + for(Point2 point : Edges.getEdges(tile.block.size)){ + var t = world.build(tile.x + point.x, tile.y + point.y); + if(t != null){ + return false; + } + } + } + //may intersect AI path tmpTiles.clear(); if(tile.block.solid && wtile != null && wtile.getLinkedTilesAs(tile.block, tmpTiles).contains(t -> path.contains(t.pos()))){ diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index 1f8568a920..d43410facb 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -642,6 +642,7 @@ public class HudFragment extends Fragment{ } void drawInner(Color color, float fract){ + if(fract < 0) return; if(flip){ x += width; width = -width; diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index 7560a9d30d..53630c4cd0 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -30,12 +30,17 @@ public class NuclearReactor extends PowerGenerator{ public Color lightColor = Color.valueOf("7f19ea"); public Color coolColor = new Color(1, 1, 1, 0f); public Color hotColor = Color.valueOf("ff9575a3"); - public float itemDuration = 120; //time to consume 1 fuel - public float heating = 0.01f; //heating per frame * fullness - public float smokeThreshold = 0.3f; //threshold at which block starts smoking + /** ticks to consume 1 fuel */ + public float itemDuration = 120; + /** heating per frame * fullness */ + public float heating = 0.01f; + /** threshold at which block starts smoking */ + public float smokeThreshold = 0.3f; + /** heat threshold at which lights start flashing */ + public float flashThreshold = 0.46f; public int explosionRadius = 19; public int explosionDamage = 1250; - public float flashThreshold = 0.46f; //heat threshold at which the lights start flashing + /** heat removed per unit of coolant */ public float coolantPower = 0.5f; public @Load("@-top") TextureRegion topRegion; diff --git a/gradle.properties b/gradle.properties index c5fbb43378..5c197796e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=383cca56f16c9cb00c77db681860d6f420f25b53 +archash=8a929ec9ae5eb3501f7d3d69848481d49044aad1 From 07a39d0da8944efa2ddb455e2fbe5cf69dc5a17d Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Wed, 17 Feb 2021 09:36:31 -0500 Subject: [PATCH 289/426] V6 servers arent BE last i checked (#4713) This has been bothering me the last few days and i assumed someone else would fix it and i wouldnt have to make a pr for something so tiny but here i am --- core/src/mindustry/Vars.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index ec002b6325..3846092846 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -62,7 +62,7 @@ public class Vars implements Loadable{ public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/"; /** URL to the JSON file containing all the BE servers. Only queried in BE. */ public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json"; - /** URL to the JSON file containing all the BE servers. */ + /** URL to the JSON file containing all the stable servers. */ public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json"; /** URL of the github issue report template.*/ public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md"; From 1ef7ae70796beb4a28dee8f2c74b626d28348481 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 17 Feb 2021 09:49:01 -0500 Subject: [PATCH 290/426] Logic hints for draw operations --- core/assets/bundles/bundle.properties | 13 +++++++++++++ core/src/mindustry/logic/LCanvas.java | 9 +++++++++ core/src/mindustry/logic/LStatement.java | 2 +- core/src/mindustry/logic/LStatements.java | 2 +- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index b989b942c1..b81792596c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1542,6 +1542,19 @@ lenum.shootp = Shoot at a unit/building with velocity prediction. lenum.configure = Building configuration, e.g. sorter item. lenum.enabled = Whether the block is enabled. +laccess.color = Illuminator color. + +graphicstype.clear = Fill the display with a color. +graphicstype.color = Set color for next drawing operation. +graphicstype.stroke = Set line width. +graphicstype.line = Draw line segment. +graphicstype.rect = Fill a rectangle. +graphicstype.linerect = Draw a rectangle outline. +graphicstype.poly = Fill a regular polygon. +graphicstype.linepoly = Draw a regular polygon outline. +graphicstype.triangle = Fill a triangle. +graphicstype.image = Draw an image of some content.\nex: [accent]@router[] or [accent]@dagger[]. + lenum.always = Always true. lenum.idiv = Integer division. lenum.div = Division.\nReturns [accent]null[] on divide-by-zero. diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index e401b3079f..3b2e465243 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -48,6 +48,15 @@ public class LCanvas extends Table{ } } + public static void tooltip(Cell cell, Enum key){ + String cl = key.getClass().getSimpleName().toLowerCase() + "." + key.name().toLowerCase(); + if(Core.bundle.has(cl)){ + tooltip(cell, cl); + }else{ + tooltip(cell, "lenum." + key.name()); + } + } + public void rebuild(){ targetWidth = useRows() ? 400f : 900f; float s = pane != null ? pane.getScrollPercentY() : 0f; diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index cd707f1819..dbcee427ff 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -75,7 +75,7 @@ public abstract class LStatement{ sizer.get(t.button(p.toString(), Styles.logicTogglet, () -> { getter.get(p); hide.run(); - }).self(c -> tooltip(c, "lenum." + p.name())).checked(current == p).group(group)); + }).self(c -> tooltip(c, p)).checked(current == p).group(group)); if(++i % cols == 0) t.row(); } diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index cfa1345ec2..15735359a7 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -512,7 +512,7 @@ public class LStatements{ i.button(sensor.name(), Styles.cleart, () -> { stype("@" + sensor.name()); hide.run(); - }).size(240f, 40f).self(c -> tooltip(c, "lenum." + sensor.name())).row(); + }).size(240f, 40f).self(c -> tooltip(c, sensor)).row(); } }) }; From 76dbdb59ce879a72569e386a7178af0910e14ca5 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 17 Feb 2021 11:02:49 -0500 Subject: [PATCH 291/426] Draw cells for unit payloads --- core/src/mindustry/world/blocks/payloads/UnitPayload.java | 1 + gradle.properties | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/payloads/UnitPayload.java b/core/src/mindustry/world/blocks/payloads/UnitPayload.java index c1b5b8a014..2dd7125083 100644 --- a/core/src/mindustry/world/blocks/payloads/UnitPayload.java +++ b/core/src/mindustry/world/blocks/payloads/UnitPayload.java @@ -83,6 +83,7 @@ public class UnitPayload implements Payload{ public void draw(){ Drawf.shadow(unit.x, unit.y, 20); Draw.rect(unit.type.icon(Cicon.full), unit.x, unit.y, unit.rotation - 90); + unit.type.drawCell(unit); //draw warning if(deactiveTime > 0){ diff --git a/gradle.properties b/gradle.properties index 5c197796e5..a8ba31e088 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=8a929ec9ae5eb3501f7d3d69848481d49044aad1 +archash=e402c9743e107fb53ed6f069ae72a19a59fbfd3b From ff9fad6a2c6bf4351a3f508a288f04d1031242ab Mon Sep 17 00:00:00 2001 From: RebornTrack970 <62565267+RebornTrack970@users.noreply.github.com> Date: Wed, 17 Feb 2021 19:05:16 +0300 Subject: [PATCH 292/426] One last server for the Omega (#4714) * One last server for the Omega Added the Annexation server from the OmegaHub to the list as it is the final server people actualy play on. * Update servers_v6.json Co-authored-by: Patrick 'Quezler' Mounier Co-authored-by: Anuken Co-authored-by: Patrick 'Quezler' Mounier --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index 2b85b2bec5..82ccf11903 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -73,7 +73,7 @@ }, { "name": "Omega", - "address": ["185.86.230.102:25906", "185.86.230.104:25985", "185.86.230.101:25641"] + "address": ["185.86.230.102:25906", "185.86.230.104:25985", "185.86.230.101:25641", "185.86.230.104:25677"] }, { "name": "md.obvilionnetwork.ru", From d0dc1ea132ecaa63d163a64fba2cb77270bdddff Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 17 Feb 2021 17:12:32 -0500 Subject: [PATCH 293/426] Fixed #4715 --- core/src/mindustry/ai/types/FlyingAI.java | 4 ++-- core/src/mindustry/entities/units/AIController.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java index 239e48682a..6df803b1f4 100644 --- a/core/src/mindustry/ai/types/FlyingAI.java +++ b/core/src/mindustry/ai/types/FlyingAI.java @@ -49,10 +49,10 @@ public class FlyingAI extends AIController{ float ang = unit.angleTo(target); float diff = Angles.angleDist(ang, unit.rotation()); - if(diff > 100f && vec.len() < circleLength){ + if(diff > 70f && vec.len() < circleLength){ vec.setAngle(unit.vel().angle()); }else{ - vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f)); + vec.setAngle(Angles.moveToward(unit.vel().angle(), vec.angle(), 6f)); } vec.setLength(unit.speed()); diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index c4fc27792a..745a90171b 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -167,7 +167,7 @@ public class AIController implements UnitController{ } protected boolean retarget(){ - return timer.get(timerTarget, 40); + return timer.get(timerTarget, target == null ? 40 : 90); } protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){ From dc5cd196ed19586c0f901135359219138aff70e6 Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Wed, 17 Feb 2021 19:44:04 -0500 Subject: [PATCH 294/426] Use github build status (#4718) Why does this still use travis? It was ditched months ago --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97aece9742..86d8a207e0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Logo](core/assets-raw/sprites/ui/logo.png) -[![Build Status](https://travis-ci.org/Anuken/Mindustry.svg?branch=master)](https://travis-ci.org/Anuken/Mindustry) +[![Build Status](https://github.com/Anuken/Mindustry/workflows/Tests/badge.svg?event=push)](https://github.com/Anuken/Mindustry/actions) [![Discord](https://img.shields.io/discord/391020510269669376.svg?logo=discord&logoColor=white&logoWidth=20&labelColor=7289DA&label=Discord)](https://discord.gg/mindustry) A sandbox tower defense game written in Java. From 0bf0d48a021267d54cd088ca6ccc1266de70be1f Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Thu, 18 Feb 2021 10:24:52 -0500 Subject: [PATCH 295/426] Make status colors the same (#4719) It bothers me ok --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86d8a207e0..109bc42fdb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![Logo](core/assets-raw/sprites/ui/logo.png) [![Build Status](https://github.com/Anuken/Mindustry/workflows/Tests/badge.svg?event=push)](https://github.com/Anuken/Mindustry/actions) -[![Discord](https://img.shields.io/discord/391020510269669376.svg?logo=discord&logoColor=white&logoWidth=20&labelColor=7289DA&label=Discord)](https://discord.gg/mindustry) +[![Discord](https://img.shields.io/discord/391020510269669376.svg?logo=discord&logoColor=white&logoWidth=20&labelColor=7289DA&label=Discord&color=17cf48)](https://discord.gg/mindustry) A sandbox tower defense game written in Java. From a7188c48845dd423fc9b58bc6bcf6797f6d25b46 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 18 Feb 2021 13:11:20 -0500 Subject: [PATCH 296/426] Content parser class discovery improvements --- build.gradle | 2 +- core/src/mindustry/mod/ClassMap.java | 259 ++++++++++++++++++ core/src/mindustry/mod/ContentParser.java | 132 ++++----- core/src/mindustry/mod/Scripts.java | 13 +- core/src/mindustry/world/Block.java | 6 +- .../mindustry/tools/ScriptMainGenerator.java | 39 ++- 6 files changed, 379 insertions(+), 72 deletions(-) create mode 100644 core/src/mindustry/mod/ClassMap.java diff --git a/build.gradle b/build.gradle index 102c0babfd..cb151f6fb3 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ allprojects{ if(!project.hasProperty("versionType")) versionType = 'official' appName = 'Mindustry' steamworksVersion = '891ed912791e01fe9ee6237a6497e5212b85c256' - rhinoVersion = '2617981f706e50b8753155d8e15e326308be3b22' + rhinoVersion = '378626d8abc552bba57864358358045d2f2dbe9b' loadVersionProps = { return new Properties().with{p -> p.load(file('../core/assets/version.properties').newReader()); return p } diff --git a/core/src/mindustry/mod/ClassMap.java b/core/src/mindustry/mod/ClassMap.java new file mode 100644 index 0000000000..5d650511fb --- /dev/null +++ b/core/src/mindustry/mod/ClassMap.java @@ -0,0 +1,259 @@ +package mindustry.mod; + +import arc.struct.*; +/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */ +public class ClassMap{ + public static final ObjectMap> classes = new ObjectMap<>(); + + static{ + classes.put("BuilderAI", mindustry.ai.types.BuilderAI.class); + classes.put("FlyingAI", mindustry.ai.types.FlyingAI.class); + classes.put("FormationAI", mindustry.ai.types.FormationAI.class); + classes.put("GroundAI", mindustry.ai.types.GroundAI.class); + classes.put("LogicAI", mindustry.ai.types.LogicAI.class); + classes.put("MinerAI", mindustry.ai.types.MinerAI.class); + classes.put("RepairAI", mindustry.ai.types.RepairAI.class); + classes.put("SuicideAI", mindustry.ai.types.SuicideAI.class); + classes.put("ArtilleryBulletType", mindustry.entities.bullet.ArtilleryBulletType.class); + classes.put("BasicBulletType", mindustry.entities.bullet.BasicBulletType.class); + classes.put("BombBulletType", mindustry.entities.bullet.BombBulletType.class); + classes.put("BulletType", mindustry.entities.bullet.BulletType.class); + classes.put("ContinuousLaserBulletType", mindustry.entities.bullet.ContinuousLaserBulletType.class); + classes.put("FlakBulletType", mindustry.entities.bullet.FlakBulletType.class); + classes.put("LaserBoltBulletType", mindustry.entities.bullet.LaserBoltBulletType.class); + classes.put("LaserBulletType", mindustry.entities.bullet.LaserBulletType.class); + classes.put("LightningBulletType", mindustry.entities.bullet.LightningBulletType.class); + classes.put("LiquidBulletType", mindustry.entities.bullet.LiquidBulletType.class); + classes.put("MassDriverBolt", mindustry.entities.bullet.MassDriverBolt.class); + classes.put("MissileBulletType", mindustry.entities.bullet.MissileBulletType.class); + classes.put("PointBulletType", mindustry.entities.bullet.PointBulletType.class); + classes.put("RailBulletType", mindustry.entities.bullet.RailBulletType.class); + classes.put("SapBulletType", mindustry.entities.bullet.SapBulletType.class); + classes.put("ShrapnelBulletType", mindustry.entities.bullet.ShrapnelBulletType.class); + classes.put("MultiEffect", mindustry.entities.effect.MultiEffect.class); + classes.put("ParticleEffect", mindustry.entities.effect.ParticleEffect.class); + classes.put("WaveEffect", mindustry.entities.effect.WaveEffect.class); + classes.put("Objectives", mindustry.game.Objectives.class); + classes.put("Objective", mindustry.game.Objectives.Objective.class); + classes.put("Produce", mindustry.game.Objectives.Produce.class); + classes.put("Research", mindustry.game.Objectives.Research.class); + classes.put("SectorComplete", mindustry.game.Objectives.SectorComplete.class); + classes.put("ParticleWeather", mindustry.type.weather.ParticleWeather.class); + classes.put("RainWeather", mindustry.type.weather.RainWeather.class); + classes.put("Attributes", mindustry.world.blocks.Attributes.class); + classes.put("Autotiler", mindustry.world.blocks.Autotiler.class); + classes.put("AutotilerHolder", mindustry.world.blocks.Autotiler.AutotilerHolder.class); + classes.put("SliceMode", mindustry.world.blocks.Autotiler.SliceMode.class); + classes.put("ConstructBlock", mindustry.world.blocks.ConstructBlock.class); + classes.put("ConstructBuild", mindustry.world.blocks.ConstructBlock.ConstructBuild.class); + classes.put("ControlBlock", mindustry.world.blocks.ControlBlock.class); + classes.put("ItemSelection", mindustry.world.blocks.ItemSelection.class); + classes.put("Accelerator", mindustry.world.blocks.campaign.Accelerator.class); + classes.put("AcceleratorBuild", mindustry.world.blocks.campaign.Accelerator.AcceleratorBuild.class); + classes.put("LaunchPad", mindustry.world.blocks.campaign.LaunchPad.class); + classes.put("LaunchPadBuild", mindustry.world.blocks.campaign.LaunchPad.LaunchPadBuild.class); + classes.put("Door", mindustry.world.blocks.defense.Door.class); + classes.put("DoorBuild", mindustry.world.blocks.defense.Door.DoorBuild.class); + classes.put("ForceProjector", mindustry.world.blocks.defense.ForceProjector.class); + classes.put("ForceBuild", mindustry.world.blocks.defense.ForceProjector.ForceBuild.class); + classes.put("MendProjector", mindustry.world.blocks.defense.MendProjector.class); + classes.put("MendBuild", mindustry.world.blocks.defense.MendProjector.MendBuild.class); + classes.put("OverdriveProjector", mindustry.world.blocks.defense.OverdriveProjector.class); + classes.put("OverdriveBuild", mindustry.world.blocks.defense.OverdriveProjector.OverdriveBuild.class); + classes.put("ShockMine", mindustry.world.blocks.defense.ShockMine.class); + classes.put("ShockMineBuild", mindustry.world.blocks.defense.ShockMine.ShockMineBuild.class); + classes.put("Thruster", mindustry.world.blocks.defense.Thruster.class); + classes.put("ThrusterBuild", mindustry.world.blocks.defense.Thruster.ThrusterBuild.class); + classes.put("Wall", mindustry.world.blocks.defense.Wall.class); + classes.put("WallBuild", mindustry.world.blocks.defense.Wall.WallBuild.class); + classes.put("BaseTurret", mindustry.world.blocks.defense.turrets.BaseTurret.class); + classes.put("BaseTurretBuild", mindustry.world.blocks.defense.turrets.BaseTurret.BaseTurretBuild.class); + classes.put("ItemTurret", mindustry.world.blocks.defense.turrets.ItemTurret.class); + classes.put("ItemTurretBuild", mindustry.world.blocks.defense.turrets.ItemTurret.ItemTurretBuild.class); + classes.put("LaserTurret", mindustry.world.blocks.defense.turrets.LaserTurret.class); + classes.put("LaserTurretBuild", mindustry.world.blocks.defense.turrets.LaserTurret.LaserTurretBuild.class); + classes.put("LiquidTurret", mindustry.world.blocks.defense.turrets.LiquidTurret.class); + classes.put("LiquidTurretBuild", mindustry.world.blocks.defense.turrets.LiquidTurret.LiquidTurretBuild.class); + classes.put("PointDefenseTurret", mindustry.world.blocks.defense.turrets.PointDefenseTurret.class); + classes.put("PointDefenseBuild", mindustry.world.blocks.defense.turrets.PointDefenseTurret.PointDefenseBuild.class); + classes.put("PowerTurret", mindustry.world.blocks.defense.turrets.PowerTurret.class); + classes.put("PowerTurretBuild", mindustry.world.blocks.defense.turrets.PowerTurret.PowerTurretBuild.class); + classes.put("ReloadTurret", mindustry.world.blocks.defense.turrets.ReloadTurret.class); + classes.put("ReloadTurretBuild", mindustry.world.blocks.defense.turrets.ReloadTurret.ReloadTurretBuild.class); + classes.put("TractorBeamTurret", mindustry.world.blocks.defense.turrets.TractorBeamTurret.class); + classes.put("TractorBeamBuild", mindustry.world.blocks.defense.turrets.TractorBeamTurret.TractorBeamBuild.class); + classes.put("Turret", mindustry.world.blocks.defense.turrets.Turret.class); + classes.put("AmmoEntry", mindustry.world.blocks.defense.turrets.Turret.AmmoEntry.class); + classes.put("TurretBuild", mindustry.world.blocks.defense.turrets.Turret.TurretBuild.class); + classes.put("ArmoredConveyor", mindustry.world.blocks.distribution.ArmoredConveyor.class); + classes.put("ArmoredConveyorBuild", mindustry.world.blocks.distribution.ArmoredConveyor.ArmoredConveyorBuild.class); + classes.put("BufferedItemBridge", mindustry.world.blocks.distribution.BufferedItemBridge.class); + classes.put("BufferedItemBridgeBuild", mindustry.world.blocks.distribution.BufferedItemBridge.BufferedItemBridgeBuild.class); + classes.put("ChainedBuilding", mindustry.world.blocks.distribution.ChainedBuilding.class); + classes.put("Conveyor", mindustry.world.blocks.distribution.Conveyor.class); + classes.put("ConveyorBuild", mindustry.world.blocks.distribution.Conveyor.ConveyorBuild.class); + classes.put("ExtendingItemBridge", mindustry.world.blocks.distribution.ExtendingItemBridge.class); + classes.put("ExtendingItemBridgeBuild", mindustry.world.blocks.distribution.ExtendingItemBridge.ExtendingItemBridgeBuild.class); + classes.put("ItemBridge", mindustry.world.blocks.distribution.ItemBridge.class); + classes.put("ItemBridgeBuild", mindustry.world.blocks.distribution.ItemBridge.ItemBridgeBuild.class); + classes.put("Junction", mindustry.world.blocks.distribution.Junction.class); + classes.put("JunctionBuild", mindustry.world.blocks.distribution.Junction.JunctionBuild.class); + classes.put("MassDriver", mindustry.world.blocks.distribution.MassDriver.class); + classes.put("DriverBulletData", mindustry.world.blocks.distribution.MassDriver.DriverBulletData.class); + classes.put("DriverState", mindustry.world.blocks.distribution.MassDriver.DriverState.class); + classes.put("MassDriverBuild", mindustry.world.blocks.distribution.MassDriver.MassDriverBuild.class); + classes.put("OverflowGate", mindustry.world.blocks.distribution.OverflowGate.class); + classes.put("OverflowGateBuild", mindustry.world.blocks.distribution.OverflowGate.OverflowGateBuild.class); + classes.put("PayloadConveyor", mindustry.world.blocks.distribution.PayloadConveyor.class); + classes.put("PayloadConveyorBuild", mindustry.world.blocks.distribution.PayloadConveyor.PayloadConveyorBuild.class); + classes.put("PayloadRouter", mindustry.world.blocks.distribution.PayloadRouter.class); + classes.put("PayloadRouterBuild", mindustry.world.blocks.distribution.PayloadRouter.PayloadRouterBuild.class); + classes.put("Router", mindustry.world.blocks.distribution.Router.class); + classes.put("RouterBuild", mindustry.world.blocks.distribution.Router.RouterBuild.class); + classes.put("Sorter", mindustry.world.blocks.distribution.Sorter.class); + classes.put("SorterBuild", mindustry.world.blocks.distribution.Sorter.SorterBuild.class); + classes.put("StackConveyor", mindustry.world.blocks.distribution.StackConveyor.class); + classes.put("StackConveyorBuild", mindustry.world.blocks.distribution.StackConveyor.StackConveyorBuild.class); + classes.put("AirBlock", mindustry.world.blocks.environment.AirBlock.class); + classes.put("Boulder", mindustry.world.blocks.environment.Boulder.class); + classes.put("Cliff", mindustry.world.blocks.environment.Cliff.class); + classes.put("DoubleOverlayFloor", mindustry.world.blocks.environment.DoubleOverlayFloor.class); + classes.put("Floor", mindustry.world.blocks.environment.Floor.class); + classes.put("OreBlock", mindustry.world.blocks.environment.OreBlock.class); + classes.put("OverlayFloor", mindustry.world.blocks.environment.OverlayFloor.class); + classes.put("ShallowLiquid", mindustry.world.blocks.environment.ShallowLiquid.class); + classes.put("SpawnBlock", mindustry.world.blocks.environment.SpawnBlock.class); + classes.put("StaticTree", mindustry.world.blocks.environment.StaticTree.class); + classes.put("StaticWall", mindustry.world.blocks.environment.StaticWall.class); + classes.put("TreeBlock", mindustry.world.blocks.environment.TreeBlock.class); + classes.put("BlockForge", mindustry.world.blocks.experimental.BlockForge.class); + classes.put("BlockForgeBuild", mindustry.world.blocks.experimental.BlockForge.BlockForgeBuild.class); + classes.put("BlockLoader", mindustry.world.blocks.experimental.BlockLoader.class); + classes.put("BlockLoaderBuild", mindustry.world.blocks.experimental.BlockLoader.BlockLoaderBuild.class); + classes.put("BlockUnloader", mindustry.world.blocks.experimental.BlockUnloader.class); + classes.put("BlockUnloaderBuild", mindustry.world.blocks.experimental.BlockUnloader.BlockUnloaderBuild.class); + classes.put("LegacyBlock", mindustry.world.blocks.legacy.LegacyBlock.class); + classes.put("LegacyMechPad", mindustry.world.blocks.legacy.LegacyMechPad.class); + classes.put("LegacyMechPadBuild", mindustry.world.blocks.legacy.LegacyMechPad.LegacyMechPadBuild.class); + classes.put("LegacyUnitFactory", mindustry.world.blocks.legacy.LegacyUnitFactory.class); + classes.put("LegacyUnitFactoryBuild", mindustry.world.blocks.legacy.LegacyUnitFactory.LegacyUnitFactoryBuild.class); + classes.put("ArmoredConduit", mindustry.world.blocks.liquid.ArmoredConduit.class); + classes.put("ArmoredConduitBuild", mindustry.world.blocks.liquid.ArmoredConduit.ArmoredConduitBuild.class); + classes.put("Conduit", mindustry.world.blocks.liquid.Conduit.class); + classes.put("ConduitBuild", mindustry.world.blocks.liquid.Conduit.ConduitBuild.class); + classes.put("LiquidBlock", mindustry.world.blocks.liquid.LiquidBlock.class); + classes.put("LiquidBuild", mindustry.world.blocks.liquid.LiquidBlock.LiquidBuild.class); + classes.put("LiquidBridge", mindustry.world.blocks.liquid.LiquidBridge.class); + classes.put("LiquidBridgeBuild", mindustry.world.blocks.liquid.LiquidBridge.LiquidBridgeBuild.class); + classes.put("LiquidExtendingBridge", mindustry.world.blocks.liquid.LiquidExtendingBridge.class); + classes.put("LiquidExtendingBridgeBuild", mindustry.world.blocks.liquid.LiquidExtendingBridge.LiquidExtendingBridgeBuild.class); + classes.put("LiquidJunction", mindustry.world.blocks.liquid.LiquidJunction.class); + classes.put("LiquidJunctionBuild", mindustry.world.blocks.liquid.LiquidJunction.LiquidJunctionBuild.class); + classes.put("LiquidRouter", mindustry.world.blocks.liquid.LiquidRouter.class); + classes.put("LiquidRouterBuild", mindustry.world.blocks.liquid.LiquidRouter.LiquidRouterBuild.class); + classes.put("LogicBlock", mindustry.world.blocks.logic.LogicBlock.class); + classes.put("LogicBuild", mindustry.world.blocks.logic.LogicBlock.LogicBuild.class); + classes.put("LogicLink", mindustry.world.blocks.logic.LogicBlock.LogicLink.class); + classes.put("LogicDisplay", mindustry.world.blocks.logic.LogicDisplay.class); + classes.put("GraphicsType", mindustry.world.blocks.logic.LogicDisplay.GraphicsType.class); + classes.put("LogicDisplayBuild", mindustry.world.blocks.logic.LogicDisplay.LogicDisplayBuild.class); + classes.put("MemoryBlock", mindustry.world.blocks.logic.MemoryBlock.class); + classes.put("MemoryBuild", mindustry.world.blocks.logic.MemoryBlock.MemoryBuild.class); + classes.put("MessageBlock", mindustry.world.blocks.logic.MessageBlock.class); + classes.put("MessageBuild", mindustry.world.blocks.logic.MessageBlock.MessageBuild.class); + classes.put("SwitchBlock", mindustry.world.blocks.logic.SwitchBlock.class); + classes.put("SwitchBuild", mindustry.world.blocks.logic.SwitchBlock.SwitchBuild.class); + classes.put("BuildPayload", mindustry.world.blocks.payloads.BuildPayload.class); + classes.put("Payload", mindustry.world.blocks.payloads.Payload.class); + classes.put("UnitPayload", mindustry.world.blocks.payloads.UnitPayload.class); + classes.put("Battery", mindustry.world.blocks.power.Battery.class); + classes.put("BatteryBuild", mindustry.world.blocks.power.Battery.BatteryBuild.class); + classes.put("BurnerGenerator", mindustry.world.blocks.power.BurnerGenerator.class); + classes.put("BurnerGeneratorBuild", mindustry.world.blocks.power.BurnerGenerator.BurnerGeneratorBuild.class); + classes.put("ConditionalConsumePower", mindustry.world.blocks.power.ConditionalConsumePower.class); + classes.put("DecayGenerator", mindustry.world.blocks.power.DecayGenerator.class); + classes.put("ImpactReactor", mindustry.world.blocks.power.ImpactReactor.class); + classes.put("ImpactReactorBuild", mindustry.world.blocks.power.ImpactReactor.ImpactReactorBuild.class); + classes.put("ItemLiquidGenerator", mindustry.world.blocks.power.ItemLiquidGenerator.class); + classes.put("ItemLiquidGeneratorBuild", mindustry.world.blocks.power.ItemLiquidGenerator.ItemLiquidGeneratorBuild.class); + classes.put("LightBlock", mindustry.world.blocks.power.LightBlock.class); + classes.put("LightBuild", mindustry.world.blocks.power.LightBlock.LightBuild.class); + classes.put("NuclearReactor", mindustry.world.blocks.power.NuclearReactor.class); + classes.put("NuclearReactorBuild", mindustry.world.blocks.power.NuclearReactor.NuclearReactorBuild.class); + classes.put("PowerBlock", mindustry.world.blocks.power.PowerBlock.class); + classes.put("PowerDiode", mindustry.world.blocks.power.PowerDiode.class); + classes.put("PowerDiodeBuild", mindustry.world.blocks.power.PowerDiode.PowerDiodeBuild.class); + classes.put("PowerDistributor", mindustry.world.blocks.power.PowerDistributor.class); + classes.put("PowerGenerator", mindustry.world.blocks.power.PowerGenerator.class); + classes.put("GeneratorBuild", mindustry.world.blocks.power.PowerGenerator.GeneratorBuild.class); + classes.put("PowerGraph", mindustry.world.blocks.power.PowerGraph.class); + classes.put("PowerNode", mindustry.world.blocks.power.PowerNode.class); + classes.put("PowerNodeBuild", mindustry.world.blocks.power.PowerNode.PowerNodeBuild.class); + classes.put("SingleTypeGenerator", mindustry.world.blocks.power.SingleTypeGenerator.class); + classes.put("SolarGenerator", mindustry.world.blocks.power.SolarGenerator.class); + classes.put("SolarGeneratorBuild", mindustry.world.blocks.power.SolarGenerator.SolarGeneratorBuild.class); + classes.put("ThermalGenerator", mindustry.world.blocks.power.ThermalGenerator.class); + classes.put("ThermalGeneratorBuild", mindustry.world.blocks.power.ThermalGenerator.ThermalGeneratorBuild.class); + classes.put("AttributeSmelter", mindustry.world.blocks.production.AttributeSmelter.class); + classes.put("AttributeSmelterBuild", mindustry.world.blocks.production.AttributeSmelter.AttributeSmelterBuild.class); + classes.put("Cultivator", mindustry.world.blocks.production.Cultivator.class); + classes.put("CultivatorBuild", mindustry.world.blocks.production.Cultivator.CultivatorBuild.class); + classes.put("Drill", mindustry.world.blocks.production.Drill.class); + classes.put("DrillBuild", mindustry.world.blocks.production.Drill.DrillBuild.class); + classes.put("Fracker", mindustry.world.blocks.production.Fracker.class); + classes.put("FrackerBuild", mindustry.world.blocks.production.Fracker.FrackerBuild.class); + classes.put("GenericCrafter", mindustry.world.blocks.production.GenericCrafter.class); + classes.put("GenericCrafterBuild", mindustry.world.blocks.production.GenericCrafter.GenericCrafterBuild.class); + classes.put("GenericSmelter", mindustry.world.blocks.production.GenericSmelter.class); + classes.put("SmelterBuild", mindustry.world.blocks.production.GenericSmelter.SmelterBuild.class); + classes.put("Incinerator", mindustry.world.blocks.production.Incinerator.class); + classes.put("IncineratorBuild", mindustry.world.blocks.production.Incinerator.IncineratorBuild.class); + classes.put("LiquidConverter", mindustry.world.blocks.production.LiquidConverter.class); + classes.put("LiquidConverterBuild", mindustry.world.blocks.production.LiquidConverter.LiquidConverterBuild.class); + classes.put("PayloadAcceptor", mindustry.world.blocks.production.PayloadAcceptor.class); + classes.put("PayloadAcceptorBuild", mindustry.world.blocks.production.PayloadAcceptor.PayloadAcceptorBuild.class); + classes.put("Pump", mindustry.world.blocks.production.Pump.class); + classes.put("PumpBuild", mindustry.world.blocks.production.Pump.PumpBuild.class); + classes.put("Separator", mindustry.world.blocks.production.Separator.class); + classes.put("SeparatorBuild", mindustry.world.blocks.production.Separator.SeparatorBuild.class); + classes.put("SolidPump", mindustry.world.blocks.production.SolidPump.class); + classes.put("SolidPumpBuild", mindustry.world.blocks.production.SolidPump.SolidPumpBuild.class); + classes.put("ItemSource", mindustry.world.blocks.sandbox.ItemSource.class); + classes.put("ItemSourceBuild", mindustry.world.blocks.sandbox.ItemSource.ItemSourceBuild.class); + classes.put("ItemVoid", mindustry.world.blocks.sandbox.ItemVoid.class); + classes.put("ItemVoidBuild", mindustry.world.blocks.sandbox.ItemVoid.ItemVoidBuild.class); + classes.put("LiquidSource", mindustry.world.blocks.sandbox.LiquidSource.class); + classes.put("LiquidSourceBuild", mindustry.world.blocks.sandbox.LiquidSource.LiquidSourceBuild.class); + classes.put("LiquidVoid", mindustry.world.blocks.sandbox.LiquidVoid.class); + classes.put("LiquidVoidBuild", mindustry.world.blocks.sandbox.LiquidVoid.LiquidVoidBuild.class); + classes.put("PowerSource", mindustry.world.blocks.sandbox.PowerSource.class); + classes.put("PowerSourceBuild", mindustry.world.blocks.sandbox.PowerSource.PowerSourceBuild.class); + classes.put("PowerVoid", mindustry.world.blocks.sandbox.PowerVoid.class); + classes.put("CoreBlock", mindustry.world.blocks.storage.CoreBlock.class); + classes.put("CoreBuild", mindustry.world.blocks.storage.CoreBlock.CoreBuild.class); + classes.put("StorageBlock", mindustry.world.blocks.storage.StorageBlock.class); + classes.put("StorageBuild", mindustry.world.blocks.storage.StorageBlock.StorageBuild.class); + classes.put("Unloader", mindustry.world.blocks.storage.Unloader.class); + classes.put("UnloaderBuild", mindustry.world.blocks.storage.Unloader.UnloaderBuild.class); + classes.put("CommandCenter", mindustry.world.blocks.units.CommandCenter.class); + classes.put("CommandBuild", mindustry.world.blocks.units.CommandCenter.CommandBuild.class); + classes.put("Reconstructor", mindustry.world.blocks.units.Reconstructor.class); + classes.put("ReconstructorBuild", mindustry.world.blocks.units.Reconstructor.ReconstructorBuild.class); + classes.put("RepairPoint", mindustry.world.blocks.units.RepairPoint.class); + classes.put("RepairPointBuild", mindustry.world.blocks.units.RepairPoint.RepairPointBuild.class); + classes.put("ResupplyPoint", mindustry.world.blocks.units.ResupplyPoint.class); + classes.put("ResupplyPointBuild", mindustry.world.blocks.units.ResupplyPoint.ResupplyPointBuild.class); + classes.put("UnitBlock", mindustry.world.blocks.units.UnitBlock.class); + classes.put("UnitBuild", mindustry.world.blocks.units.UnitBlock.UnitBuild.class); + classes.put("UnitFactory", mindustry.world.blocks.units.UnitFactory.class); + classes.put("UnitFactoryBuild", mindustry.world.blocks.units.UnitFactory.UnitFactoryBuild.class); + classes.put("UnitPlan", mindustry.world.blocks.units.UnitFactory.UnitPlan.class); + classes.put("DrawAnimation", mindustry.world.draw.DrawAnimation.class); + classes.put("DrawBlock", mindustry.world.draw.DrawBlock.class); + classes.put("DrawGlow", mindustry.world.draw.DrawGlow.class); + classes.put("DrawMixer", mindustry.world.draw.DrawMixer.class); + classes.put("DrawRotator", mindustry.world.draw.DrawRotator.class); + classes.put("DrawWeave", mindustry.world.draw.DrawWeave.class); + classes.put("Block", mindustry.world.Block.class); + } +} diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index c00ae23fe1..6467bd7813 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -15,10 +15,12 @@ import arc.util.serialization.*; import arc.util.serialization.Json.*; import arc.util.serialization.Jval.*; import mindustry.*; +import mindustry.ai.types.*; import mindustry.content.*; import mindustry.content.TechTree.*; import mindustry.ctype.*; import mindustry.entities.*; +import mindustry.entities.abilities.*; import mindustry.entities.bullet.*; import mindustry.entities.effect.*; import mindustry.game.*; @@ -26,6 +28,7 @@ import mindustry.game.Objectives.*; import mindustry.gen.*; import mindustry.mod.Mods.*; import mindustry.type.*; +import mindustry.type.weather.*; import mindustry.world.*; import mindustry.world.blocks.units.*; import mindustry.world.blocks.units.UnitFactory.*; @@ -42,14 +45,14 @@ public class ContentParser{ private static final boolean ignoreUnknownFields = true; ObjectMap, ContentType> contentTypes = new ObjectMap<>(); ObjectSet> implicitNullable = ObjectSet.with(TextureRegion.class, TextureRegion[].class, TextureRegion[][].class); - ObjectMap sounds = new ObjectMap<>(); + ObjectMap> sounds = new ObjectMap<>(); ObjectMap, FieldParser> classParsers = new ObjectMap<>(){{ put(Effect.class, (type, data) -> { if(data.isString()){ return field(Fx.class, data); } - Class bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.effect") : ParticleEffect.class; + Class bc = resolve(data.getString("type", ""), ParticleEffect.class); data.remove("type"); Effect result = make(bc); readFields(result, data); @@ -83,12 +86,23 @@ public class ContentParser{ if(data.isString()){ return field(Bullets.class, data); } - Class bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.bullet") : BasicBulletType.class; + var bc = resolve(data.getString("type", ""), BasicBulletType.class); data.remove("type"); BulletType result = make(bc); readFields(result, data); return result; }); + put(DrawBlock.class, (type, data) -> { + if(data.isString()){ + //try to instantiate + return make(resolve(data.asString())); + } + var bc = resolve(data.getString("type", ""), DrawBlock.class); + data.remove("type"); + var result = make(bc); + readFields(result, data); + return result; + }); put(Sound.class, (type, data) -> { if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data); if(Vars.headless) return new Sound(); @@ -104,12 +118,19 @@ public class ContentParser{ return sound; }); put(Objectives.Objective.class, (type, data) -> { - Class oc = data.has("type") ? resolve(data.getString("type"), "mindustry.game.Objectives") : SectorComplete.class; + var oc = resolve(data.getString("type", ""), SectorComplete.class); data.remove("type"); Objectives.Objective obj = make(oc); readFields(obj, data); return obj; }); + put(Ability.class, (type, data) -> { + Class oc = resolve(data.getString("type", "")); + data.remove("type"); + Ability obj = make(oc); + readFields(obj, data); + return obj; + }); put(Weapon.class, (type, data) -> { Weapon weapon = new Weapon(); readFields(weapon, data); @@ -118,12 +139,13 @@ public class ContentParser{ }); }}; /** Stores things that need to be parsed fully, e.g. reading fields of content. - * This is done to accomodate binding of content names first.*/ + * This is done to accommodate binding of content names first.*/ private Seq reads = new Seq<>(); private Seq postreads = new Seq<>(); private ObjectSet toBeParsed = new ObjectSet<>(); + LoadedMod currentMod; - private Content currentContent; + Content currentContent; private Json parser = new Json(){ @Override @@ -160,11 +182,6 @@ public class ContentParser{ } } - //try to load DrawBlock by instantiating it - if(type == DrawBlock.class && jsonData.isString()){ - return Reflect.make("mindustry.world.draw." + Strings.capitalize(jsonData.asString())); - } - if(Content.class.isAssignableFrom(type)){ ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName())); String prefix = currentMod != null ? currentMod.name + "-" : ""; @@ -194,30 +211,7 @@ public class ContentParser{ throw new IllegalArgumentException("When defining properties for an existing block, you must not re-declare its type. The original type will be used. Block: " + name); } }else{ - //TODO generate dynamically instead of doing.. this - Class type; - - try{ - type = resolve(getType(value), - "mindustry.world", - "mindustry.world.blocks", - "mindustry.world.blocks.defense", - "mindustry.world.blocks.defense.turrets", - "mindustry.world.blocks.distribution", - "mindustry.world.blocks.environment", - "mindustry.world.blocks.liquid", - "mindustry.world.blocks.logic", - "mindustry.world.blocks.power", - "mindustry.world.blocks.production", - "mindustry.world.blocks.sandbox", - "mindustry.world.blocks.storage", - "mindustry.world.blocks.units" - ); - }catch(IllegalArgumentException e){ - type = Block.class; - } - - block = make(type, mod + "-" + name); + block = make(resolve(getType(value), Block.class), mod + "-" + name); } currentContent = block; @@ -225,22 +219,19 @@ public class ContentParser{ read(() -> { if(value.has("consumes") && value.get("consumes").isObject()){ for(JsonValue child : value.get("consumes")){ - if(child.name.equals("item")){ - block.consumes.item(find(ContentType.item, child.asString())); - }else if(child.name.equals("items")){ - block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child)); - }else if(child.name.equals("liquid")){ - block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child)); - }else if(child.name.equals("power")){ - if(child.isNumber()){ - block.consumes.power(child.asFloat()); - }else{ - block.consumes.add((Consume)parser.readValue(ConsumePower.class, child)); + switch(child.name){ + case "item" -> block.consumes.item(find(ContentType.item, child.asString())); + case "items" -> block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child)); + case "liquid" -> block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child)); + case "power" -> { + if(child.isNumber()){ + block.consumes.power(child.asFloat()); + }else{ + block.consumes.add((Consume)parser.readValue(ConsumePower.class, child)); + } } - }else if(child.name.equals("powerBuffered")){ - block.consumes.powerBuffered(child.asFloat()); - }else{ - throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'."); + case "powerBuffered" -> block.consumes.powerBuffered(child.asFloat()); + default -> throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'."); } } value.remove("consumes"); @@ -308,7 +299,7 @@ public class ContentParser{ } if(value.has("controller")){ - unit.defaultController = make(resolve(value.getString("controller"), "mindustry.ai.types")); + unit.defaultController = supply(resolve(value.getString("controller"), FlyingAI.class)); } //read extra default waves @@ -334,8 +325,7 @@ public class ContentParser{ readBundle(ContentType.weather, name, value); }else{ readBundle(ContentType.weather, name, value); - Class type = resolve(getType(value), "mindustry.type.weather"); - item = make(type); + item = make(resolve(getType(value), ParticleWeather.class)); } currentContent = item; read(() -> readFields(item, value)); @@ -624,8 +614,8 @@ public class ContentParser{ JsonValue research = jsonMap.remove("research"); toBeParsed.remove(object); - Class type = object.getClass(); - ObjectMap fields = parser.getFields(type); + var type = object.getClass(); + var fields = parser.getFields(type); for(JsonValue child = jsonMap.child; child != null; child = child.next){ FieldMetadata metadata = fields.get(child.name().replace(" ", "_")); if(metadata == null){ @@ -654,7 +644,6 @@ public class ContentParser{ } } - if(object instanceof UnlockableContent unlock && research != null){ //add research tech node @@ -706,21 +695,34 @@ public class ContentParser{ } } - /** Tries to resolve a class from a list of potential class names. */ - Class resolve(String base, String... potentials){ + /** Tries to resolve a class from the class type map. */ + Class resolve(String base){ + return resolve(base, null); + } + + /** Tries to resolve a class from the class type map. */ + Class resolve(String base, Class def){ + //no base class specified + if(base.isEmpty() && def != null) return def; if(!base.isEmpty() && Character.isLowerCase(base.charAt(0))) base = Strings.capitalize(base); - for(String type : potentials){ + //return mapped class if found in the global map + var out = ClassMap.classes.get(base); + if(out != null) return (Class)out; + + //try to resolve it as a raw class name if it's allowed + if(base.indexOf('.') != -1 && Scripts.allowClass(base)){ try{ - return (Class)Class.forName(type + '.' + base); + return (Class)Class.forName(base); }catch(Exception ignored){ - try{ - return (Class)Class.forName(type + '$' + base); - }catch(Exception ignored2){ - } } } - throw new IllegalArgumentException("Types not found: " + base + "." + potentials[0]); + + if(def != null){ + Log.warn("[@] No type '" + base + "' found, defaulting to type '" + def.getSimpleName() + "'", currentContent == null ? currentMod.name : ""); + return def; + } + throw new IllegalArgumentException("Type not found: " + base); } private interface FieldParser{ diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index ab3ffb89e5..1de3573f94 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -21,20 +21,25 @@ import java.net.*; import java.util.regex.*; public class Scripts implements Disposable{ - private final Seq blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", + private static final Seq blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", "runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system", - ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org."); - private final Seq whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent"); + ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.", "mod.classmap"); + private static final Seq whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent"); + private final Context context; private final Scriptable scope; private boolean errored; LoadedMod currentMod = null; + public static boolean allowClass(String type){ + return !blacklist.contains(type.toLowerCase()::contains) || whitelist.contains(type.toLowerCase()::contains); + } + public Scripts(){ Time.mark(); context = Vars.platform.getScriptContext(); - context.setClassShutter(type -> !blacklist.contains(type.toLowerCase()::contains) || whitelist.contains(type.toLowerCase()::contains)); + context.setClassShutter(Scripts::allowClass); context.getWrapFactory().setJavaPrimitiveWrap(false); context.setLanguageVersion(Context.VERSION_ES6); diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index da9702d902..17f86f69b7 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -335,7 +335,11 @@ public class Block extends UnlockableContent{ super.setStats(); stats.add(Stat.size, "@x@", size, size); - stats.add(Stat.health, health, StatUnit.none); + + if(synthetic()){ + stats.add(Stat.health, health, StatUnit.none); + } + if(canBeBuilt()){ stats.add(Stat.buildTime, buildCost / 60, StatUnit.seconds); stats.add(Stat.buildCost, new ItemListValue(false, requirements)); diff --git a/tools/src/mindustry/tools/ScriptMainGenerator.java b/tools/src/mindustry/tools/ScriptMainGenerator.java index 89e2839417..845d056f9a 100644 --- a/tools/src/mindustry/tools/ScriptMainGenerator.java +++ b/tools/src/mindustry/tools/ScriptMainGenerator.java @@ -14,6 +14,7 @@ import mindustry.game.*; import mindustry.gen.*; import mindustry.io.*; import mindustry.net.*; +import mindustry.world.*; import java.io.*; import java.lang.reflect.*; @@ -70,6 +71,40 @@ public class ScriptMainGenerator{ } new Fi("core/assets/scripts/global.js").writeString(result.toString()); + + //map simple name to type + Seq packages = Seq.with( + "mindustry.entities.effect", + "mindustry.entities.bullet", + "mindustry.ai.types", + "mindustry.type.weather", + "mindustry.game.Objectives", + "mindustry.world.blocks", + "mindustry.world.draw" + ); + + String classTemplate = "package mindustry.mod;\n" + + "\n" + + "import arc.struct.*;\n" + + "/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */\n" + + "public class ClassMap{\n" + + " public static final ObjectMap> classes = new ObjectMap<>();\n" + + " \n" + + " static{\n$CLASSES$" + + " }\n" + + "}\n"; + + StringBuilder cdef = new StringBuilder(); + + Seq> mapped = classes.select(c -> Modifier.isPublic(c.getModifiers()) && packages.contains(c.getCanonicalName()::startsWith)) + .and(Block.class); //special case + + for(Class c : mapped){ + cdef.append(" classes.put(\"").append(c.getSimpleName()).append("\", ").append(c.getCanonicalName()).append(".class);\n"); + } + + new Fi("core/src/mindustry/mod/ClassMap.java").writeString(classTemplate.replace("$CLASSES$", cdef.toString())); + Log.info("Generated @ class mappings.", mapped.size); } public static Seq getClasses(String packageName) throws Exception{ @@ -103,7 +138,9 @@ public class ScriptMainGenerator{ String className = entry.getName().replace('/', '.'); className = className.substring(0, className.length() - ".class".length()); if(className.startsWith(packageName)){ - classes.add(Class.forName(className, false, Thread.currentThread().getContextClassLoader())); + Class res = Class.forName(className, false, Thread.currentThread().getContextClassLoader()); + classes.add(res); + //classes.addAll(res.getDeclaredClasses()); //???? } } } From 06b8dd61c7ce77e8af1e9d71efcda24bee842e1e Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 18 Feb 2021 15:02:09 -0500 Subject: [PATCH 297/426] Better splash damage handling for small radii --- core/src/mindustry/content/UnitTypes.java | 2 +- core/src/mindustry/entities/Damage.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index b7c5062164..a070550c4c 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -138,7 +138,7 @@ public class UnitTypes implements ContentList{ collides = true; collidesTiles = true; splashDamageRadius = 28f; - splashDamage = 54f; + splashDamage = 52f; backColor = Pal.bulletYellowBack; frontColor = Pal.bulletYellow; }}; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index df4e5c3a35..69c16a8f50 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -363,8 +363,7 @@ public class Damage{ if(ground){ if(!complete){ - //increase damage slightly to compensate for new algorithm - tileDamage(team, World.toTile(x), World.toTile(y), radius / tilesize, damage * 1.1f); + tileDamage(team, World.toTile(x), World.toTile(y), radius / tilesize, damage); }else{ completeDamage(team, x, y, radius, damage); } @@ -381,7 +380,7 @@ public class Damage{ //this needs to be compensated if(in != null && in.team != team && in.block.size > 1 && in.health > damage){ //deal the damage of an entire side + 1, to be equivalent with maximum 'standard' damage - in.damage(damage * (in.block.size + 1)); + in.damage(damage * Math.min((in.block.size + 1), baseRadius * 0.44f)); //no need to continue with the explosion return; } From 5a58f9c71a6c5b87557a747e3e0c1f88a8b5fb6f Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 18 Feb 2021 17:00:23 -0500 Subject: [PATCH 298/426] Fixed #4729 --- core/src/mindustry/content/Bullets.java | 10 +++++----- core/src/mindustry/content/UnitTypes.java | 4 ++-- core/src/mindustry/entities/Damage.java | 2 +- core/src/mindustry/entities/comp/UnitComp.java | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java index 2792146ce9..6cc2a15757 100644 --- a/core/src/mindustry/content/Bullets.java +++ b/core/src/mindustry/content/Bullets.java @@ -63,7 +63,7 @@ public class Bullets implements ContentList{ lifetime = 80f; width = height = 11f; collidesTiles = false; - splashDamageRadius = 25f; + splashDamageRadius = 25f * 0.75f; splashDamage = 33f; }}; @@ -84,7 +84,7 @@ public class Bullets implements ContentList{ lifetime = 80f; width = height = 13f; collidesTiles = false; - splashDamageRadius = 35f; + splashDamageRadius = 35f * 0.75f; splashDamage = 45f; fragBullet = artilleryPlasticFrag; fragBullets = 10; @@ -98,7 +98,7 @@ public class Bullets implements ContentList{ lifetime = 80f; width = height = 11f; collidesTiles = false; - splashDamageRadius = 25f; + splashDamageRadius = 25f * 0.75f; splashDamage = 33f; reloadMultiplier = 1.2f; ammoMultiplier = 3f; @@ -112,7 +112,7 @@ public class Bullets implements ContentList{ lifetime = 80f; width = height = 13f; collidesTiles = false; - splashDamageRadius = 25f; + splashDamageRadius = 25f * 0.75f; splashDamage = 35f; status = StatusEffects.burning; frontColor = Pal.lightishOrange; @@ -128,7 +128,7 @@ public class Bullets implements ContentList{ width = height = 14f; collidesTiles = false; ammoMultiplier = 4f; - splashDamageRadius = 45f; + splashDamageRadius = 45f * 0.75f; splashDamage = 50f; backColor = Pal.missileYellowBack; frontColor = Pal.missileYellow; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index a070550c4c..1d12279b07 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -138,7 +138,7 @@ public class UnitTypes implements ContentList{ collides = true; collidesTiles = true; splashDamageRadius = 28f; - splashDamage = 52f; + splashDamage = 54f; backColor = Pal.bulletYellowBack; frontColor = Pal.bulletYellow; }}; @@ -1537,7 +1537,7 @@ public class UnitTypes implements ContentList{ width = 15f; collidesTiles = false; ammoMultiplier = 4f; - splashDamageRadius = 50f; + splashDamageRadius = 40f; splashDamage = 80f; backColor = Pal.missileYellowBack; frontColor = Pal.missileYellow; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 69c16a8f50..458fd5220b 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -380,7 +380,7 @@ public class Damage{ //this needs to be compensated if(in != null && in.team != team && in.block.size > 1 && in.health > damage){ //deal the damage of an entire side + 1, to be equivalent with maximum 'standard' damage - in.damage(damage * Math.min((in.block.size + 1), baseRadius * 0.44f)); + in.damage(damage * Math.min((in.block.size), baseRadius * 0.45f)); //no need to continue with the explosion return; } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 8b0dbc67fe..f4bd772950 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -140,7 +140,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case controlled -> controller instanceof LogicAI || controller instanceof Player ? 1 : 0; case commanded -> controller instanceof FormationAI ? 1 : 0; case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; - default -> 0; + default -> Float.NaN; }; } @@ -162,7 +162,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I @Override public double sense(Content content){ if(content == stack().item) return stack().amount; - return 0; + return Float.NaN; } @Override From 78317e61268f14d516957af7d36829312880f82e Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 18 Feb 2021 20:15:46 -0500 Subject: [PATCH 299/426] Uncap content names in resolution --- core/src/mindustry/mod/ContentParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 6467bd7813..3e5ca141e2 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -704,10 +704,9 @@ public class ContentParser{ Class resolve(String base, Class def){ //no base class specified if(base.isEmpty() && def != null) return def; - if(!base.isEmpty() && Character.isLowerCase(base.charAt(0))) base = Strings.capitalize(base); //return mapped class if found in the global map - var out = ClassMap.classes.get(base); + var out = ClassMap.classes.get(!base.isEmpty() && Character.isLowerCase(base.charAt(0)) ? Strings.capitalize(base) : base); if(out != null) return (Class)out; //try to resolve it as a raw class name if it's allowed From d5448b59a2bb91e7d749931cc8f031516fa981bd Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 18 Feb 2021 21:07:48 -0500 Subject: [PATCH 300/426] Fixed UnitReq parsing --- core/src/mindustry/mod/ContentParser.java | 18 +++++++++--------- .../world/blocks/campaign/Accelerator.java | 2 +- .../world/blocks/units/Reconstructor.java | 2 +- .../world/blocks/units/UnitFactory.java | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 3e5ca141e2..1279a98ea4 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -275,15 +275,6 @@ public class ContentParser{ if(value.has("requirements")){ JsonValue rec = value.remove("requirements"); - //intermediate class for parsing - class UnitReq{ - public Block block; - public ItemStack[] requirements = {}; - @Nullable - public UnitType previous; - public float time = 60f * 10f; - } - UnitReq req = parser.readValue(UnitReq.class, rec); if(req.block instanceof Reconstructor r){ @@ -732,4 +723,13 @@ public class ContentParser{ T parse(String mod, String name, JsonValue value) throws Exception; } + //intermediate class for parsing + static class UnitReq{ + public Block block; + public ItemStack[] requirements = {}; + @Nullable + public UnitType previous; + public float time = 60f * 10f; + } + } diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index b5a33bc2d3..6f998ccd8f 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -21,7 +21,7 @@ public class Accelerator extends Block{ public @Load("launch-arrow") TextureRegion arrowRegion; public Block launching = Blocks.coreNucleus; - public int[] capacities; + public int[] capacities = {}; public Accelerator(String name){ super(name); diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index c80cb35b83..b48f4741b6 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -24,7 +24,7 @@ import static mindustry.Vars.*; public class Reconstructor extends UnitBlock{ public float constructTime = 60 * 2; public Seq upgrades = new Seq<>(); - public int[] capacities; + public int[] capacities = {}; public Reconstructor(String name){ super(name); diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 798c6fe26e..f6555dcc2f 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -24,7 +24,7 @@ import mindustry.world.consumers.*; import mindustry.world.meta.*; public class UnitFactory extends UnitBlock{ - public int[] capacities; + public int[] capacities = {}; public Seq plans = new Seq<>(4); From 1072c310ad3025880470baacfa673d6738a47367 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 09:04:13 -0500 Subject: [PATCH 301/426] Fixed #4732 --- core/src/mindustry/entities/comp/BuildingComp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index f270929f3a..c63e538363 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -911,7 +911,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, if(net.client()) return; if(block.consumesPower || block.outputsPower){ - int range = 10; + int range = 12; tempTiles.clear(); Geometry.circle(tileX(), tileY(), range, (x, y) -> { Building other = world.build(x, y); From b46a5c0bdae09de33925f2b3b336f9afebe3b733 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 09:45:51 -0500 Subject: [PATCH 302/426] Allow JSON mod content types from other class loaders --- .../src/mindustry/android/AndroidLauncher.java | 5 ++--- core/src/mindustry/core/Platform.java | 7 +++---- core/src/mindustry/mod/ContentParser.java | 8 ++++++++ core/src/mindustry/mod/Mods.java | 15 +++++++++++---- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/android/src/mindustry/android/AndroidLauncher.java b/android/src/mindustry/android/AndroidLauncher.java index b92865c68a..cd813c6ff0 100644 --- a/android/src/mindustry/android/AndroidLauncher.java +++ b/android/src/mindustry/android/AndroidLauncher.java @@ -72,9 +72,8 @@ public class AndroidLauncher extends AndroidApplication{ } @Override - public Class loadJar(Fi jar, String mainClass) throws Exception{ - DexClassLoader loader = new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, getClassLoader()); - return Class.forName(mainClass, true, loader); + public ClassLoader loadJar(Fi jar, String mainClass) throws Exception{ + return new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, getClassLoader()); } @Override diff --git a/core/src/mindustry/core/Platform.java b/core/src/mindustry/core/Platform.java index bddcd3d749..911583f822 100644 --- a/core/src/mindustry/core/Platform.java +++ b/core/src/mindustry/core/Platform.java @@ -20,10 +20,9 @@ import static mindustry.Vars.*; public interface Platform{ - /** Dynamically loads a jar file. */ - default Class loadJar(Fi jar, String mainClass) throws Exception{ - URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, getClass().getClassLoader()); - return Class.forName(mainClass, true, classLoader); + /** Dynamically creates a class loader for a jar file. */ + default ClassLoader loadJar(Fi jar, String mainClass) throws Exception{ + return new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, getClass().getClassLoader()); } /** Steam: Update lobby visibility.*/ diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 1279a98ea4..12fb11fde8 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -705,6 +705,14 @@ public class ContentParser{ try{ return (Class)Class.forName(base); }catch(Exception ignored){ + //try to load from a mod's class loader + for(LoadedMod mod : mods.mods){ + if(mod.loader != null){ + try{ + return (Class)Class.forName(base, true, mod.loader); + }catch(Exception ignore){} + } + } } } diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 3566b08ebe..41e2bf31ea 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -92,6 +92,8 @@ public class Mods implements Loadable{ var loaded = loadMod(dest, true); mods.add(loaded); requiresReload = true; + //enable the mod on import + Core.settings.put("mod-" + loaded.name + "-enabled", true); sortMods(); //try to load the mod's icon so it displays on import Core.app.post(() -> { @@ -664,9 +666,10 @@ public class Mods implements Loadable{ } } + ClassLoader loader = null; Mod mainMod; - Fi mainFile = zip; + if(android){ mainFile = mainFile.child("classes.dex"); }else{ @@ -687,7 +690,8 @@ public class Mods implements Loadable{ throw new IllegalArgumentException("Java class mods are not supported on iOS."); } - Class main = platform.loadJar(sourceFile, mainClass); + loader = platform.loadJar(sourceFile, mainClass); + Class main = Class.forName(mainClass, true, loader); metas.put(main, meta); mainMod = (Mod)main.getDeclaredConstructor().newInstance(); }else{ @@ -710,7 +714,7 @@ public class Mods implements Loadable{ if(!headless){ Log.info("Loaded mod '@' in @ms", meta.name, Time.elapsed()); } - return new LoadedMod(sourceFile, zip, mainMod, meta); + return new LoadedMod(sourceFile, zip, mainMod, loader, meta); }catch(Exception e){ //delete root zip file so it can be closed on windows @@ -743,10 +747,13 @@ public class Mods implements Loadable{ public ModState state = ModState.enabled; /** Icon texture. Should be disposed. */ public @Nullable Texture iconTexture; + /** Class loader for JAR mods. Null if the mod isn't loaded or this isn't a jar mod. */ + public @Nullable ClassLoader loader; - public LoadedMod(Fi file, Fi root, Mod main, ModMeta meta){ + public LoadedMod(Fi file, Fi root, Mod main, ClassLoader loader, ModMeta meta){ this.root = root; this.file = file; + this.loader = loader; this.main = main; this.meta = meta; this.name = meta.name.toLowerCase().replace(" ", "-"); From fa7697fc4070f1f8b8049d6a4bb4ff8a409a9a4d Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 13:28:31 -0500 Subject: [PATCH 303/426] Better JSON null validation / Disable mods on startup crash --- core/assets/bundles/bundle.properties | 3 ++- core/src/mindustry/ClientLauncher.java | 19 +++++++++++++- core/src/mindustry/Vars.java | 25 +++++++++++++++++++ core/src/mindustry/core/Control.java | 9 +++++++ core/src/mindustry/mod/ContentParser.java | 6 +++++ core/src/mindustry/mod/Mods.java | 21 +++++++++++++--- core/src/mindustry/ui/dialogs/ModsDialog.java | 5 ---- .../ui/dialogs/SettingsMenuDialog.java | 4 +++ .../blocks/environment/ShallowLiquid.java | 8 ++++-- .../world/blocks/production/Drill.java | 2 +- .../blocks/production/GenericCrafter.java | 5 ++-- gradle.properties | 2 +- 12 files changed, 93 insertions(+), 16 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index b81792596c..d7476036c9 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -113,7 +113,7 @@ committingchanges = Committing Changes done = Done feature.unsupported = Your device does not support this feature. -mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry GitHub. +mods.initfailed = [red]⚠[] The previous Mindustry instance failed to initialize. This was likely caused by misbehaving mods.\n\nTo prevent a crash loop, [red]all mods have been disabled.[]\n\nTo disable this feature, turn it off in [accent]Settings->Game->Disable Mods On Startup Crash[]. mods = Mods mods.none = [lightgray]No mods found! mods.guide = Modding Guide @@ -800,6 +800,7 @@ setting.logichints.name = Logic Hints setting.flow.name = Display Resource Flow Rate setting.backgroundpause.name = Pause In Background setting.buildautopause.name = Auto-Pause Building +setting.modcrashdisable = Disable Mods On Startup Crash setting.animatedwater.name = Animated Surfaces setting.animatedshields.name = Animated Shields setting.antialias.name = Antialias[lightgray] (requires restart)[] diff --git a/core/src/mindustry/ClientLauncher.java b/core/src/mindustry/ClientLauncher.java index 978361898a..d8c0de2556 100644 --- a/core/src/mindustry/ClientLauncher.java +++ b/core/src/mindustry/ClientLauncher.java @@ -34,6 +34,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform @Override public void setup(){ + checkLaunch(); loadLogger(); loader = new LoadRenderer(); @@ -145,7 +146,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform finished = true; Events.fire(new ClientLoadEvent()); super.resize(graphics.getWidth(), graphics.getHeight()); - app.post(() -> app.post(() -> app.post(() -> app.post(() -> super.resize(graphics.getWidth(), graphics.getHeight()))))); + app.post(() -> app.post(() -> app.post(() -> app.post(() -> { + super.resize(graphics.getWidth(), graphics.getHeight()); + + //mark initialization as complete + finishLaunch(); + })))); } }else{ asyncCore.begin(); @@ -168,6 +174,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform lastTime = Time.nanos(); } + @Override + public void exit(){ + //on graceful exit, finish the launch normally. + Vars.finishLaunch(); + } + @Override public void init(){ setup(); @@ -182,6 +194,11 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform @Override public void pause(){ + //when the user tabs out on mobile, the exit() event doesn't fire reliably - in that case, just assume they're about to kill the app + //this isn't 100% reliable but it should work for most cases + if(mobile){ + Vars.finishLaunch(); + } if(finished){ super.pause(); } diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 3846092846..45e3606c8e 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -32,6 +32,8 @@ import java.util.*; import static arc.Core.*; public class Vars implements Loadable{ + /** Whether the game failed to launch last time. */ + public static boolean failedToLaunch = false; /** Whether to load locales.*/ public static boolean loadLocales = true; /** Whether the logger is loaded. */ @@ -172,6 +174,8 @@ public class Vars implements Loadable{ public static Fi schematicDirectory; /** data subdirectory used for bleeding edge build versions */ public static Fi bebuildDirectory; + /** file used to store launch ID */ + public static Fi launchIDFile; /** empty map, indicates no current map */ public static Map emptyMap; /** map file extension */ @@ -284,6 +288,27 @@ public class Vars implements Loadable{ maps.load(); } + /** Checks if a launch failure occurred. + * If this is the case, failedToLaunch is set to true. */ + public static void checkLaunch(){ + settings.setAppName(appName); + launchIDFile = settings.getDataDirectory().child("launchid.dat"); + + if(launchIDFile.exists()){ + failedToLaunch = true; + }else{ + failedToLaunch = false; + launchIDFile.writeString("go away"); + } + } + + /** Cleans up after a successful launch. */ + public static void finishLaunch(){ + if(launchIDFile != null){ + launchIDFile.delete(); + } + } + public static void loadLogger(){ if(loadedLogger) return; diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 8109bbcd7c..2ca30a2d51 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -59,6 +59,15 @@ public class Control implements ApplicationListener, Loadable{ saves = new Saves(); sound = new SoundControl(); + //show dialog saying that mod loading was skipped. + Events.on(ClientLoadEvent.class, e -> { + if(Vars.mods.skipModLoading() && Vars.mods.list().any()){ + Time.runTask(4f, () -> { + ui.showInfo("@mods.initfailed"); + }); + } + }); + Events.on(StateChangeEvent.class, event -> { if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){ Time.runTask(5f, platform::updateRPC); diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 12fb11fde8..818d518963 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -406,6 +406,12 @@ public class ContentParser{ this.currentMod = mod; this.currentContent = cont; run.run(); + + //check nulls after parsing + if(cont != null){ + toBeParsed.remove(cont); + checkNullFields(cont); + } }); } diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 41e2bf31ea..6b3f3ecaee 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -259,6 +259,11 @@ public class Mods implements Loadable{ return requiresReload; } + /** @return whether to skip mod loading due to previous initialization failure. */ + public boolean skipModLoading(){ + return failedToLaunch && Core.settings.getBool("modcrashdisable", true); + } + /** Loads all mods from the folder, but does not call any methods on them.*/ public void load(){ for(Fi file : modDirectory.list()){ @@ -683,8 +688,13 @@ public class Mods implements Loadable{ //make sure the main class exists before loading it; if it doesn't just don't put it there //if the mod is explicitly marked as java, try loading it anyway - if((mainFile.exists() || meta.java) && - Core.settings.getBool("mod-" + baseName + "-enabled", true) && Version.isAtLeast(meta.minGameVersion) && (meta.getMinMajor() >= 105 || headless)){ + if( + (mainFile.exists() || meta.java) && + !skipModLoading() && + Core.settings.getBool("mod-" + baseName + "-enabled", true) && + Version.isAtLeast(meta.minGameVersion) && + (meta.getMinMajor() >= 105 || headless) + ){ if(ios){ throw new IllegalArgumentException("Java class mods are not supported on iOS."); @@ -711,11 +721,16 @@ public class Mods implements Loadable{ } } + //skip mod loading if it failed + if(skipModLoading()){ + Core.settings.put("mod-" + baseName + "-enabled", false); + } + if(!headless){ Log.info("Loaded mod '@' in @ms", meta.name, Time.elapsed()); } - return new LoadedMod(sourceFile, zip, mainMod, loader, meta); + return new LoadedMod(sourceFile, zip, mainMod, loader, meta); }catch(Exception e){ //delete root zip file so it can be closed on windows if(rootZip != null) rootZip.delete(); diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 7c5f766db6..bd3f63bf03 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -106,11 +106,6 @@ public class ModsDialog extends BaseDialog{ } }); - shown(() -> Core.app.post(() -> { - Core.settings.getBoolOnce("modsalpha", () -> { - ui.showText("@mods", "@mods.alphainfo"); - }); - })); } void modError(Throwable error){ diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index e531581f9b..60acd1637b 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -327,6 +327,10 @@ public class SettingsMenuDialog extends SettingsDialog{ game.checkPref("buildautopause", false); } + if(!ios){ + game.checkPref("modcrashdisable", true); + } + if(steam){ game.sliderPref("playerlimit", 16, 2, 32, i -> { platform.updateLobby(); diff --git a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java index 28d94c05fe..bea6797f37 100644 --- a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java +++ b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java @@ -1,10 +1,14 @@ package mindustry.world.blocks.environment; +import arc.util.*; import mindustry.world.*; -//do not use in mods! +/** + * Do not use in mods. This class provides no new functionality, and is only used for the Mindustry sprite generator. + * Use the standard Floor class instead. + * */ public class ShallowLiquid extends Floor{ - public Floor liquidBase, floorBase; + public @Nullable Floor liquidBase, floorBase; public float liquidOpacity = 0.35f; public ShallowLiquid(String name){ diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index 373d5bb9de..bfefd96050 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -38,7 +38,7 @@ public class Drill extends Block{ public float warmupSpeed = 0.02f; //return variables for countOre - protected Item returnItem; + protected @Nullable Item returnItem; protected int returnCount; /** Whether to draw the item this drill is mining. */ diff --git a/core/src/mindustry/world/blocks/production/GenericCrafter.java b/core/src/mindustry/world/blocks/production/GenericCrafter.java index 39a2e2ac4f..25021ad20d 100644 --- a/core/src/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/mindustry/world/blocks/production/GenericCrafter.java @@ -3,6 +3,7 @@ package mindustry.world.blocks.production; import arc.graphics.g2d.*; import arc.math.*; import arc.struct.*; +import arc.util.*; import arc.util.io.*; import mindustry.content.*; import mindustry.entities.*; @@ -13,8 +14,8 @@ import mindustry.world.draw.*; import mindustry.world.meta.*; public class GenericCrafter extends Block{ - public ItemStack outputItem; - public LiquidStack outputLiquid; + public @Nullable ItemStack outputItem; + public @Nullable LiquidStack outputLiquid; public float craftTime = 80; public Effect craftEffect = Fx.none; diff --git a/gradle.properties b/gradle.properties index a8ba31e088..6a5b6bcb50 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=e402c9743e107fb53ed6f069ae72a19a59fbfd3b +archash=f6caa903fd34c016a902b70c4d41690f5f022431 From fb4807038864835679759f8e851a4bf424af1bb5 Mon Sep 17 00:00:00 2001 From: Fatonndev <56699208+Fatonndev@users.noreply.github.com> Date: Sat, 20 Feb 2021 01:04:48 +0300 Subject: [PATCH 304/426] Add Survival and PvP servers (#4736) --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index 82ccf11903..fef7d2c5d9 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -77,7 +77,7 @@ }, { "name": "md.obvilionnetwork.ru", - "address": ["obvilionnetwork.ru:7001", "obvilionnetwork.ru:7002"] + "address": ["obvilionnetwork.ru", "obvilionnetwork.ru:7001", "obvilionnetwork.ru:7002", "obvilionnetwork.ru:7003"] }, { "name": "Mindustry PLAY", From 73d6f95d2e0d89285a1dc0d9e2fa81a2581e22b5 Mon Sep 17 00:00:00 2001 From: CxZxRainzz <78591136+CxZxRainzz@users.noreply.github.com> Date: Fri, 19 Feb 2021 22:11:51 +0000 Subject: [PATCH 305/426] Update servers_v6.json (#4735) add 1 more server for CxZx --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index fef7d2c5d9..432553f84c 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -61,7 +61,7 @@ }, { "name": "CxZx", - "address": ["frfr1.quackhost.uk:20060", "frfr1.quackhost.uk:20185"] + "address": ["frfr1.quackhost.uk:20060", "frfr1.quackhost.uk:20185", "defr2.forcehost.net:1069"] }, { "name": "Korea", From f043a5f34063968e30eeb44ad2572884ecf0c8ce Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 17:18:17 -0500 Subject: [PATCH 306/426] Logic tooltips on mobile devices w/ long-press --- .../mindustry/entities/comp/BuildingComp.java | 1 + .../src/mindustry/entities/comp/UnitComp.java | 1 + core/src/mindustry/logic/LAccess.java | 1 + core/src/mindustry/logic/LCanvas.java | 40 ++++++++++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index c63e538363..ae987d7592 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1312,6 +1312,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, return switch(sensor){ case x -> World.conv(x); case y -> World.conv(y); + //case dead -> !isValid(); //TODO 126 case team -> team.id; case health -> health; case maxHealth -> maxHealth; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index f4bd772950..83dcf435c1 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -128,6 +128,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case ammoCapacity -> type.ammoCapacity; case x -> World.conv(x); case y -> World.conv(y); + //case dead -> dead || !isAdded(); //TODO 126 case team -> team.id; case shooting -> isShooting() ? 1 : 0; case range -> range() / tilesize; diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index 4fcaba35a5..bf3f9dd3b1 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -27,6 +27,7 @@ public enum LAccess{ y, shootX, shootY, + //dead, //TODO 126 range, shooting, mineX, diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 3b2e465243..e6ca89e23b 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -13,6 +13,7 @@ import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; +import mindustry.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.ui.*; @@ -29,10 +30,26 @@ public class LCanvas extends Table{ StatementElem hovered; float targetWidth; int jumpCount = 0; + Seq tooltips = new Seq<>(); public LCanvas(){ canvas = this; + Core.scene.addListener(new InputListener(){ + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ + //hide tooltips on tap + for(var t : tooltips){ + t.container.toFront(); + } + Core.app.post(() -> { + tooltips.each(Tooltip::hide); + tooltips.clear(); + }); + return super.touchDown(event, x, y, pointer, button); + } + }); + rebuild(); } @@ -44,7 +61,28 @@ public class LCanvas extends Table{ public static void tooltip(Cell cell, String key){ String lkey = key.toLowerCase().replace(" ", ""); if(Core.settings.getBool("logichints", true) && Core.bundle.has(lkey)){ - cell.get().addListener(new Tooltip(t -> t.background(Styles.black8).margin(4f).add("[lightgray]" + Core.bundle.get(lkey)).style(Styles.outlineLabel))); + var tip = new Tooltip(t -> t.background(Styles.black8).margin(4f).add("[lightgray]" + Core.bundle.get(lkey)).style(Styles.outlineLabel)); + + //mobile devices need long-press tooltips + if(Vars.mobile){ + cell.get().addListener(new ElementGestureListener(20, 0.4f, 0.43f, 0.15f){ + @Override + public boolean longPress(Element element, float x, float y){ + tip.show(element, x, y); + canvas.tooltips.add(tip); + //prevent touch down for other listeners + for(var list : cell.get().getListeners()){ + if(list instanceof ClickListener cl){ + cl.cancel(); + } + } + return true; + } + }); + }else{ + cell.get().addListener(tip); + } + } } From 820f7f0ef2ff38c07e758f2493bcd67fe6bf5e84 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 17:25:37 -0500 Subject: [PATCH 307/426] arc --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 6a5b6bcb50..a787392872 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=f6caa903fd34c016a902b70c4d41690f5f022431 +archash=a9c305d4f920e46a7b92c3fedc8f76d9c2fb38de From 0316009a9cfc0119ea6149014fb43241ce4b8988 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 18:28:51 -0500 Subject: [PATCH 308/426] Balance tweaks --- core/src/mindustry/content/UnitTypes.java | 8 ++++---- core/src/mindustry/entities/Damage.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 1d12279b07..b26b418862 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -240,8 +240,8 @@ public class UnitTypes implements ContentList{ fragVelocityMin = 0.4f; hitEffect = Fx.blastExplosion; - splashDamage = 18f; - splashDamageRadius = 30f; + splashDamage = 16f; + splashDamageRadius = 13f; fragBullets = 2; fragLifeMin = 0f; @@ -257,7 +257,7 @@ public class UnitTypes implements ContentList{ lifetime = 20f; hitEffect = Fx.flakExplosion; splashDamage = 15f; - splashDamageRadius = 15f; + splashDamageRadius = 10f; }}; }}; }} @@ -769,7 +769,7 @@ public class UnitTypes implements ContentList{ width = height = 19f; collidesTiles = true; ammoMultiplier = 4f; - splashDamageRadius = 80f; + splashDamageRadius = 70f; splashDamage = 65f; backColor = Pal.sapBulletBack; frontColor = lightningColor = Pal.sapBullet; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 458fd5220b..e3f9be816b 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -379,7 +379,7 @@ public class Damage{ //why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion. //this needs to be compensated if(in != null && in.team != team && in.block.size > 1 && in.health > damage){ - //deal the damage of an entire side + 1, to be equivalent with maximum 'standard' damage + //deal the damage of an entire side, to be equivalent with maximum 'standard' damage in.damage(damage * Math.min((in.block.size), baseRadius * 0.45f)); //no need to continue with the explosion return; From b94aba03012b662c00e6cac840715358850f6bd8 Mon Sep 17 00:00:00 2001 From: Phinner <62483793+Phinner@users.noreply.github.com> Date: Sat, 20 Feb 2021 00:30:49 +0100 Subject: [PATCH 309/426] Fixing remaining typos\errors in bundle_fr (#4397) * Fixing remaining typos errors in bundle_fr There are some errors that had managed to get through the verification. Imma chase them down! * added logic hints and some typo fixes * Fixing 2 typos in bundle.properties L1548: Color statement affects every following draw operations. * smolfixes --- core/assets/bundles/bundle.properties | 4 +- core/assets/bundles/bundle_fr.properties | 257 ++++++++++++++++++----- 2 files changed, 204 insertions(+), 57 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index d7476036c9..be766129a3 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1546,7 +1546,7 @@ lenum.enabled = Whether the block is enabled. laccess.color = Illuminator color. graphicstype.clear = Fill the display with a color. -graphicstype.color = Set color for next drawing operation. +graphicstype.color = Set color for next drawing operations. graphicstype.stroke = Set line width. graphicstype.line = Draw line segment. graphicstype.rect = Fill a rectangle. @@ -1579,7 +1579,7 @@ lenum.sin = Sine, in degrees. lenum.cos = Cosine, in degrees. lenum.tan = Tangent, in degrees. #not a typo, look up 'range notation' -lenum.rand = Random number in range [0, value). +lenum.rand = Random number in range [0, value]. lenum.log = Natural logarithm (ln). lenum.log10 = Base 10 logarithm. lenum.noise = 2D simplex noise. diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index ab44ee3d80..08146a578b 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -6,7 +6,7 @@ link.discord.description = Discord officiel de Mindustry link.reddit.description = Subreddit de Mindustry link.github.description = Code source du jeu link.changelog.description = Liste des mises à jour -link.dev-builds.description = Versions expérimentale du jeu +link.dev-builds.description = Versions expérimentales du jeu link.trello.description = Trello officiel pour les nouvelles fonctionalités planifiées link.itch.io.description = Page itch.io avec les différentes versions du jeu. link.google-play.description = Page Google Play du jeu @@ -41,17 +41,20 @@ be.ignore = Ignorer be.noupdates = Aucune mise à jour trouvée. be.check = Chercher des mises à jour -mod.featured.dialog.title = Navigateur de Mods (WIP) +mods.browser = Navigateur de Mods mods.browser.selected = Mod sélectionné mods.browser.add = Installer -mods.github.open = Voir +mods.browser.reinstall = Reinstaller +mods.github.open = Voir sur Github +mods.browser.sortdate = Classer par date +mods.browser.sortstars = Classer par étoiles schematic = Schéma -schematic.add = Enregistrer le Schéma... +schematic.add = Enregistrer le Schéma schematics = Schémas -schematic.replace = Un schéma avec ce nom existe déjà. Voulez-vous le remplacer ? +schematic.replace = Un schéma avec ce nom existe déjà. Voulez-vous le remplacer? schematic.exists = Un schéma avec ce nom existe déjà. -schematic.import = Importer un schéma... +schematic.import = Importer un schéma schematic.exportfile = Exporter le fichier schematic.importfile = Importer un fichier schematic.browseworkshop = Consulter le Steam Workshop @@ -63,7 +66,7 @@ schematic.saved = Schéma enregistré. schematic.delete.confirm = Ce schéma sera supprimé définitivement. schematic.rename = Renommer le Schéma schematic.info = {0}x{1}, {2} blocs -schematic.disabled = [scarlet] Schémas désactivés![]\nVous n'êtes pas autorisés à utiliser des schémas sur cette [accent]cartemap[] ou ce [accent]serveur. +schematic.disabled = [scarlet]Schémas désactivés![]\nVous n'êtes pas autorisés à utiliser des schémas sur cette [accent]carte[] ou dans ce [accent]serveur. stats = Stats stat.wave = Vagues vaincues:[accent] {0} @@ -84,8 +87,8 @@ coreattack = [scarlet]< Le Noyau est attaqué! > nearpoint = [[ [scarlet]QUITTEZ LE POINT D'APPARITION ENNEMI IMMÉDIATEMENT[] ]\nannihilation imminente database = Base de données savegame = Sauvegarder la partie -loadgame = Charger la partie -joingame = Rejoindre la partie +loadgame = Charger une partie +joingame = Rejoindre une partie customgame = Partie personnalisée newgame = Nouvelle partie none = @@ -116,8 +119,10 @@ mods.none = [lightgray]Aucun Mod trouvé! mods.guide = Guide de Modding mods.report = Signaler un Bug mods.openfolder = Ouvrir le Dossier +mods.viewcontent = Voir le Contenu mods.reload = Relancer mods.reloadexit = Le jeu va se fermer pour relancer les mods. +mod.installed = [[Installé] mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Activé mod.disabled = [scarlet]Désactivé @@ -125,7 +130,7 @@ mod.disable = Désactiver mod.content = Contenu: mod.delete.error = Impossible de supprimer le mod. Le fichier est probablement en cours d'utilisation. mod.requiresversion = [scarlet]Version minimale du jeu requise : [accent]{0} -mod.outdated = [scarlet]non compatible avec la V6 (no minGameVersion: 105) +mod.outdated = [scarlet]Non compatible avec la V6 (no minGameVersion: 105) mod.missingdependencies = [scarlet]Dépendances manquantes: {0} mod.erroredcontent = [scarlet]Erreurs de contenu mod.errors = Des erreurs se sont produites lors du chargement du contenu. @@ -137,7 +142,7 @@ mod.reloadrequired = [scarlet]Redémarrage requis mod.import = Importer un mod mod.import.file = Importer un fichier mod.import.github = Importer un mod depuis GitHub -mod.jarwarn = [scarlet]Les mods JAR sont par nature peu sûrs.[]\nFaites en sorte d'Importer ce mod depuis une source digne de confiance. +mod.jarwarn = [scarlet]Les mods JAR sont par nature peu sûrs.[]\nFaites en sorte d'importer ce mod depuis une source digne de confiance. mod.item.remove = Cet objet fait partie du mod[accent] '{0}'[]. Pour le supprimer, désinstallez le mod en question. mod.remove.confirm = Ce mod sera supprimé. mod.author = [lightgray]Auteur:[] {0} @@ -148,7 +153,7 @@ mod.scripts.disable = Votre appareil ne prend pas an charge les mods avec des sc about.button = À propos name = Nom: -noname = Commencez par choisir un[accent] pseudo[]. +noname = Commencez par choisir un[accent] nom[]. planetmap = Carte de la planète launchcore = Lancer le Noyau filename = Nom du fichier: @@ -156,8 +161,8 @@ unlocked = Nouveau contenu débloqué! available = Nouvelle recherche disponible! completed = [accent]Complété techtree = Arbre technologique -research.legacy = Données de recherche de la [accent]5.0[] trouvées.\nVoulez-vous [accent]charger les données[] ou [accent]les ignorer[] et recommencer la recherche dans la nouvelle campagne? (recommandé) -research.load = Chargement +research.legacy = Des données de recherche de la [accent]5.0[] ont été trouvées.\nVoulez-vous [accent]charger ces données[] ou [accent]les ignorer[] et recommencer la recherche dans la nouvelle campagne? (recommandé) +research.load = Charger research.discard = Ignorer research.list = [lightgray]Recherche: research = Rechercher @@ -176,7 +181,7 @@ server.kicked.clientOutdated = Client obsolète! Mettez votre jeu à jour! server.kicked.serverOutdated = Serveur obsolète! Demandez à l'hôte de le mettre à jour! server.kicked.banned = Vous avez été banni de ce serveur. server.kicked.typeMismatch = Ce serveur n'est pas compatible avec votre version du jeu. -server.kicked.playerLimit = Ce serveur est complet. Attendez qu'une place se libére. +server.kicked.playerLimit = Ce serveur est complet. Attendez qu'une place se libère. server.kicked.recentKick = Vous avez été expulsé récemment.\nAttendez avant de vous reconnecter. server.kicked.nameInUse = Il y a déjà quelqu'un avec\nce nom sur ce serveur. server.kicked.nameEmpty = Votre nom est invalide. @@ -203,9 +208,9 @@ servers.local = Serveurs locaux servers.remote = Serveurs distants servers.global = Serveurs communautaires -servers.disclaimer = Les serveurs communautaires ne sont [accent]pas[] gérés ou controllés par le développeur.\n\nCes serveurs peuvent contenir du contenu qui ne convient pas à tout les âges. +servers.disclaimer = Les serveurs communautaires ne sont [accent]pas[] gérés, ni controllés par le développeur.\n\nCes serveurs peuvent contenir du contenu qui ne convient pas à tout les âges. servers.showhidden = Montrer les serveurs cachés -server.shown = Montré +server.shown = Visible server.hidden = Caché trace = Suivre le joueur @@ -307,6 +312,7 @@ cancelbuilding = [accent][[{0}][] pour effacer le plan selectschematic = [accent][[{0}][] pour sélectionner+copier pausebuilding = [accent][[{0}][] pour mettre la construction en pause resumebuilding = [scarlet][[{0}][] pour reprendre la construction +enablebuilding = [scarlet][[{0}][] pour activer la construction showui = Interface cachée.\nPressez [accent][[{0}][] pour montrer l'interface. wave = [accent]Vague {0} wave.cap = [accent]Vague {0}/{1} @@ -327,9 +333,9 @@ custom = Personnalisé builtin = Pré-fait map.delete.confirm = Voulez-vous vraiment supprimer cette carte? Il n'y aura pas de retour en arrière! map.random = [accent]Carte aléatoire -map.nospawn = Cette carte ne possède pas de base pour que le joueur puisse apparaître! Ajouter un [royalNoyau orange[] sur cette carte dans l'éditeur. -map.nospawn.pvp = Cette carte n'a pas de base ennemie pour qu'un joueur ennemi puisse y apparaître! Ajoutez au moins une base [scarlet] non-orange[] dans l'éditeur. -map.nospawn.attack = Cette carte n'a aucune base ennemie à attaquer! Veuillez ajouter une base[scarlet] rouge[] sur cette carte dans l'éditeur. +map.nospawn = Cette carte ne possède pas de base pour que le joueur puisse apparaître! Ajouter un [accent]Noyau orange[] sur cette carte dans l'éditeur. +map.nospawn.pvp = Cette carte n'a pas de base ennemie pour qu'un joueur ennemi puisse y apparaître! Ajoutez au moins un Noyau[scarlet] non-orange[] dans l'éditeur. +map.nospawn.attack = Cette carte n'a aucune base ennemie à attaquer! Veuillez ajouter un Noyau[scarlet] rouge[] sur cette carte dans l'éditeur. map.invalid = Erreur lors du chargement de la carte: carte corrompue ou invalide. workshop.update = Mettre à jour workshop.error = Erreur lors de la récupération des détails du Steam Workshop: {0} @@ -487,7 +493,7 @@ play = Jouer campaign = Campagne load = Charger save = Sauvegarder -fps = IPS: {0} +fps = FPS: {0} ping = Ping: {0}ms memory = Mem: {0}mb memory2 = Mem:\n {0}mb +\n {1}mb @@ -601,9 +607,9 @@ sector.craters.description = Ce cratère est une relique d'anciennes guerres. De sector.ruinousShores.description = Au-delà des déchets, se trouve le littoral. Autrefois, cet endroit abritait un réseau de défense côtière, mais il n’en reste pas grand-chose. Seules quelques structures de défense basiques sont restées intactes, tout le reste a été réduit en ferraille.\nContinuez votre exploration en redécouvrant la technologie. sector.stainedMountains.description = Plus loin, à l’intérieur des terres, se trouvent des montagnes qui n'ont pas touchées par les spores.\nExploitez le Titane présent en abondance dans cette zone et apprenez comment l'utiliser.\n\nLa présence ennemie est bien plus grande ici. Ne leur donnez pas le temps d’envoyer leurs unités les plus fortes. sector.overgrowth.description = Étant plus proche de la source des spores, cette zone a été complètement envahie.\nL'ennemi y a établi un avant-poste. Formez des Titans et détruisez-le. -sector.tarFields.description = La périphérie d’une zone de production de pétrole, situé entre les montagnes et le désert. L’une des rares avec des réserves de goudron utilisables.\nBien qu’abandonnée, cette zone a quelques forces ennemies dangereuses à proximité. Ne les sous-estimez pas!\n\n[lightgray]Recherchez la technologie de traitement de pétrole si possible. +sector.tarFields.description = La périphérie d’une zone de production de pétrole, situé entre les montagnes et le désert. L’une des rares avec des réserves de goudron utilisables.\nBien qu’abandonnée, quelques forces ennemies dangereuses se trouvent à proximité. Ne les sous-estimez pas!\n\n[lightgray]Recherchez la technologie de traitement de pétrole si possible. sector.desolateRift.description = Une zone extrêmement dangereuse. Des ressources abondantes, mais peu d’espace. Un risque élevé de destruction donc partez dès que possible! Ne vous laissez surtout pas berner par le long temps d'attente entre les vagues ennemies. Vous risquerez de le regretter. -sector.nuclearComplex.description = Une ancienne installation de production et de traitement de thorium, réduite en ruines.\n[lightgray]Faites des recherches sur le thorium et ses nombreuses utilisations.\n\nL’ennemi est présent ici en grand nombre, recherchant constamment des attaquants. +sector.nuclearComplex.description = Une ancienne installation de production et de traitement de thorium, réduite en ruines.\n[lightgray]Faites des recherches sur ce minerai et ses nombreuses utilisations.\n\nL’ennemi est présent ici en grand nombre, recherchant constamment des attaquants. sector.fungalPass.description = Une zone de transition entre les hautes montagnes et les terres plus basses, infestées de spores. Une petite base de reconnaissance ennemie se trouve ici.\nDétruisez les 2 Noyaux ennemis en utilisant des Poingnards et des Rampeurs. sector.biomassFacility.description = L’origine des spores. Il s’agit de l’installation dans laquelle elles ont été étudiées et initialement produites.\nRecherchez la technologie présente sur les lieux et cultivez des spores pour la production de carburant et de plastique.\n\n[lightgray]Lors de la destruction de cette installation, les spores ont été libérées. Rien dans l’écosystème local ne pouvait concurrencer un organisme aussi envahissant. sector.windsweptIslands.description = Au delà du rivage se trouve cette chaîne d’îles reculées. Les registres montrent qu’il y avait autrefois des usines de [accent]Plastanium[].\n\nDéfendez-vous contre les unités navales ennemies, établissez-y une base et faites des recherches sur ces usines. @@ -631,17 +637,17 @@ settings.clearcampaignsaves = Supprimer la Campagne settings.clearcampaignsaves.confirm = Êtes-vous sûr de vouloir supprimer toutes les sauvegardes de la campagne? paused = [accent]< Pause > clear = Effacer -banned = [scarlet]Bannis +banned = [scarlet]Banni yes = Oui no = Non info.title = Info error.title = [scarlet]Une erreur s'est produite error.crashtitle = Une erreur s'est produite -unit.nobuild = [scarlet]Cette unité ne peut construire +unit.nobuild = [scarlet]Cette unité ne peut pas construire lastaccessed = [lightgray]Dernier accès: {0} block.unknown = [lightgray]??? -stat.description = But +stat.description = Description stat.input = Ressource(s) requise(s) stat.output = Ressource(s) produite(s) stat.booster = Boosteur @@ -678,6 +684,7 @@ stat.drillspeed = Vitesse de forage de Base stat.boosteffect = Effet(s) du Boost stat.maxunits = Max d'Unités Actives stat.health = Santé +stat.armor = Armure stat.buildtime = Durée de construction stat.maxconsecutive = Max Consécutif stat.buildcost = Coût de construction @@ -693,6 +700,7 @@ stat.lightningchance = Chance d'Éclairs stat.lightningdamage = Dégats des Éclairs stat.flammability = Inflammabilité stat.radioactivity = Radioactivité +stat.charge = Charge stat.heatcapacity = Capacité Thermique stat.viscosity = Viscosité stat.temperature = Température @@ -709,7 +717,7 @@ stat.ammouse = Utilisation de munitions ability.forcefield = Champ de Force ability.repairfield = Champ de Réparation -ability.statusfield = Champ de statut +ability.statusfield = Champ d'Amélioration ability.unitspawn = Usine de {0} ability.shieldregenfield = Champ de regénération de bouclier ability.movelightning = Déplacement éclair @@ -736,7 +744,7 @@ bar.progress = Construction en cours bar.input = Entrée bar.output = Sortie -units.processorcontrol = [lightgray]Contrôlée par un processeur +units.processorcontrol = [lightgray]Contrôlé par un processeur bullet.damage = [stat]{0}[lightgray] dégâts bullet.splashdamage = [stat]{0}[lightgray] dégâts de zone ~[stat] {1}[lightgray] blocs @@ -775,8 +783,8 @@ unit.thousands = k unit.millions = mil unit.billions = Md unit.pershot = /tirs -category.purpose = But -category.general = Général +category.purpose = Description +category.general = Caractéristiques category.power = Énergie category.liquids = Liquides category.items = Objets @@ -788,6 +796,7 @@ setting.shadows.name = Ombres setting.blockreplace.name = Suggestion automatique des Blocs setting.linear.name = Filtrage linéaire setting.hints.name = Astuces +setting.logichints.name = Astuces pour les commandes des processeurs setting.flow.name = Afficher le Débit des ressources setting.backgroundpause.name = Pause en Arrière-plan setting.buildautopause.name = Confirmation avant construction @@ -799,10 +808,10 @@ setting.indicators.name = Indicateurs ennemis setting.autotarget.name = Visée automatique setting.keyboard.name = Contrôles Souris+Clavier setting.touchscreen.name = Commandes d'écran tactile -setting.fpscap.name = Max IPS +setting.fpscap.name = Max FPS setting.fpscap.none = Illimité -setting.fpscap.text = {0} IPS -Échelle de l'interface[lightgray] (redémarrage du jeu nécessaire)[] +setting.fpscap.text = {0} FPS +setting.uiscale.name = Échelle de l'interface[lightgray] (redémarrage du jeu nécessaire)[] setting.swapdiagonal.name = Autoriser le placement en diagonale setting.difficulty.training = Entraînement setting.difficulty.easy = Facile @@ -821,7 +830,7 @@ setting.seconds = {0} secondes setting.milliseconds = {0} millisecondes setting.fullscreen.name = Plein Écran setting.borderlesswindow.name = Fenêtre sans bords[lightgray] (peut nécessiter le redémarrage du jeu) -setting.fps.name = Afficher IPS et Ping +setting.fps.name = Afficher FPS et Ping setting.smoothcamera.name = Lissage de la Caméra setting.vsync.name = Synchronisation Verticale setting.pixelate.name = Pixeliser @@ -858,7 +867,7 @@ category.blocks.name = Sélection des blocs command.attack = Attaquer command.rally = Rallier command.retreat = Retraite -command.idle = Pause +command.idle = Inactif placement.blockselectkeys = \n[lightgray]Raccourci: [{0}, keybind.respawn.name = Réapparaître keybind.control.name = Controler une Unité @@ -948,6 +957,8 @@ rules.blockdamagemultiplier = Multiplicateur de Dégât des Blocs rules.unitbuildspeedmultiplier = Multiplicateur de Vitesse de Construction des Unités rules.unithealthmultiplier = Multiplicateur de Santé des Unités rules.unitdamagemultiplier = Multiplicateur de Dégât des Unités +rules.unitcapvariable = Les Noyaux contribuent à la limite d'Unités actives +rules.unitcap = Limite d'Unités actives de Base rules.enemycorebuildradius = Périmètre de Non-Construction autour du Noyau ennemi:[lightgray] (blocs) rules.wavespacing = Temps entre les Vagues:[lightgray] (sec) rules.buildcostmultiplier = Multiplicateur du prix de construction @@ -1140,7 +1151,7 @@ block.router.name = Routeur block.distributor.name = Distributeur block.sorter.name = Trieur block.inverted-sorter.name = Trieur Inversé -block.message.name = Message +block.message.name = Bloc de Message block.illuminator.name = Illuminateur block.overflow-gate.name = Barrière de Débordement block.underflow-gate.name = Barrière de Refoulement @@ -1249,7 +1260,7 @@ block.logic-processor.name = Processeur block.hyper-processor.name = Hyper Processeur block.logic-display.name = Écran block.large-logic-display.name = Grand Écran -block.memory-cell.name = Bloc de mémoire +block.memory-cell.name = Cellule de mémoire block.memory-bank.name = Banque de mémoire team.blue.name = bleu @@ -1286,8 +1297,8 @@ hint.schematicSelect = Retenez [accent][[F][] pour sélectionner des blocs dans hint.conveyorPathfind = Retenez [accent][[Ctrl-gauche][] pendant que vous placez des convoyeurs, afin de générer un chemin automatiquement. hint.conveyorPathfind.mobile = Activez le mode \ue844 [accent]Diagonale[] et déplacez des convoyeurs, afin de générer un chemin automatiquement. hint.boost = Retenez [accent][[Maj-gauche][] pour voler au-dessus des obstacles avec votre unité actuelle.\n\nSeules quelques unités terrestres peuvent voler. -hint.command = Pressez [accent][[G][] pour commander les unités proches d'un [accent]type similaire[] et bouger une formation.\n\nSeules les unités terrestres peuvent controller d'autres unités terrestres. -hint.command.mobile = [accent][[Tapez][] 2 fois votre unité pour commander les unités proches d'un [accent]type similaire[] et bouger une formation. +hint.command = Pressez [accent][[G][] pour commander les unités proches d'un [accent]type similaire[] et bouger en formation.\n\nSeules les unités terrestres peuvent controller d'autres unités terrestres. +hint.command.mobile = [accent][[Tapez][] 2 fois votre unité pour commander les unités proches d'un [accent]type similaire[] et bouger en formation. hint.payloadPickup = Pressez [accent][[[] pour transporter des blocs ou des unités. hint.payloadPickup.mobile = [accent]Tapez et retenez[] votre doigt pour transporter des blocs ou des unités. hint.payloadDrop = Pressez [accent]][] pour larguer votre chargement. @@ -1363,8 +1374,8 @@ block.thorium-wall.description = Un bloc défensif puissant.\nProcure une très block.thorium-wall-large.description = Un bloc défensif puissant.\nProcure une très bonne protection contre les attaques ennemies. block.phase-wall.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes. block.phase-wall-large.description = Ce mur est moins puissant qu'un mur en thorium, mais il peut dévier les balles, sauf si elles sont trop puissantes. -block.surge-wall.description = Le plus puissant bloc défensif.\nA une faible chance de créer des éclairs vers les ennemis. -block.surge-wall-large.description = Le plus puissant bloc défensif.\nA une faible chance de créer des éclairs vers les ennemis. +block.surge-wall.description = Le plus puissant bloc défensif.\nA une faible chance d'envoyer des éclairs vers les ennemis. +block.surge-wall-large.description = Le plus puissant bloc défensif.\nA une faible chance d'envoyer des éclairs vers les ennemis. block.door.description = Une petite porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers. block.door-large.description = Une grande porte pouvant être ouverte et fermée en appuyant dessus.\nSi elle est ouverte, les ennemis peuvent passer à travers. block.mender.description = Soigne périodiquement les bâtiments autour de lui, ce qui permet de remettre les défenses en bon état entre les vagues ennemies.\nPeut utiliser du silicium pour booster la portée et l'efficacité. @@ -1374,7 +1385,7 @@ block.force-projector.description = Crée un champ de force hexagonal autour de block.shock-mine.description = Blesse les ennemis qui marchent dessus. block.conveyor.description = Convoyeur basique servant à transporter des objets. Les objets déplacés en avant sont automatiquement déposés dans les tourelles ou les bâtiments. Peut être tourné. block.titanium-conveyor.description = Convoyeur avancé. Déplace les objets plus rapidement que les convoyeurs standards. -block.plastanium-conveyor.description = Convoyeur transportant les ressources par paquets. Accepte les ressources par derrière et les déchargent par 3 directions à l'avant. Pour une efficacité maximale, utilisez plusieurs points de chargement et de déchargement pour une même ligne. +block.plastanium-conveyor.description = Convoyeur transportant les ressources par paquets. Accepte les ressources par derrière et les décharge par 3 directions à l'avant. Pour une efficacité maximale, utilisez plusieurs points de chargement et de déchargement pour une même ligne. block.junction.description = Agit comme un pont pour deux lignes de convoyeurs se croisant. Utile lorsque deux lignes de convoyeurs différentes déplacent différents matériaux à différents endroits. block.bridge-conveyor.description = Bloc de transport avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment. block.phase-conveyor.description = Convoyeur très avancé. Utilise de l'énergie pour téléporter des objets à un autre convoyeur phasé. Possède une longue portée. @@ -1393,13 +1404,13 @@ block.conduit.description = Bloc de transport de liquide de base, faisant avance block.pulse-conduit.description = Conduit avancé permettant le transport de liquide. Transporte les liquides plus rapidement et en stocke plus que les conduits standards. block.plated-conduit.description = Déplace les liquides au même rythme que les conduits à impulsion, mais est renforcé et empêche les fuites en cas de rupture. N'accepte pas les liquides provenant des côtés, seuls les autres conduits peuvent le faire. block.liquid-router.description = Accepte les liquides depuis une direction et les distribue jusqu'à 3 directions équitablement. Utile pour envoyer un liquide à plusieurs endroits. Peut aussi stocker une certaine quantité de liquide. -block.liquid-tank.description = Stocke une grande quantité de liquide et peut les distribuer dans tous les côtés, un peu comme un routeur liquide.\nUtile pour réguler la sortie quand la demande en liquide si elle est inconstante ou comme sécurité pour refroidir des bâtiments importants. +block.liquid-tank.description = Stocke une grande quantité de liquide et peut les distribuer dans tous les côtés, un peu comme un routeur liquide.\nUtile pour réguler la demande en liquide si elle est inconstante ou comme sécurité pour refroidir des bâtiments importants. block.liquid-junction.description = Agit comme un pont pour deux conduits se croisant. Utile si deux conduits amènent différents liquides à différents endroits. block.bridge-conduit.description = Bloc de transport de liquide avancé permettant de traverser jusqu'à 3 blocs, au-dessus de n'importe quel terrain ou bâtiment. block.phase-conduit.description = Conduit très avancé permettant le transport de liquide. Utilise de l'énergie pour téléporter les liquides à un autre conduit phasé sur une longue distance. block.power-node.description = Transmet de l'énergie aux autres transmetteurs énergétiques connectés. Le transmetteur recevra de l'énergie ou la transmettra à n'importe quel bâtiment adjacent. La connexion peut être activée/désactivée manuellement. block.power-node-large.description = Ce transmetteur possède un rayon plus grand que le transmetteur énergétique standard. Il peut aussi accepter plus de connexions. -block.surge-tower.description = Un transmetteur énergétique de très grande portée mais avec moins de connections disponibles. +block.surge-tower.description = Un transmetteur énergétique à très grande portée mais avec moins de connections disponibles. block.diode.description = L'énergie ne circule que dans un sens à travers ce bloc, et uniquement si l’autre côté présente moins d’énergie en stock. Idéal pour protéger les lieux de production d'énergie. block.battery.description = Stocke le surplus d'énergie et le redistribue en cas de besoin. block.battery-large.description = Stocke bien plus d'énergie qu'une batterie normale. @@ -1418,7 +1429,7 @@ block.laser-drill.description = Permet de forer bien plus vite grâce à la tech block.blast-drill.description = La Foreuse ultime. Demande une grande quantité d'énergie pour fonctionner. block.water-extractor.description = Extrait l'eau des nappes phréatiques. Utile quand il n'y a pas d'étendue d'eau à proximité. block.cultivator.description = Cultive une petite quantité de spores atmosphériques afin de former des bulbes sporifères. -block.cultivator.details = Technologie de récupération. Utilisée pour produire des quantités massives de biomasse aussi efficacement que possible. Probablement l’incubateur initial des spores qui couvrent maintenant Serpulo. +block.cultivator.details = Technologie de récupération. Utilisée pour produire des quantités massives de biomasse aussi efficacement que possible. Probablement l’incubateur initial des spores, qui couvrent maintenant Serpulo. block.oil-extractor.description = Utilise de grandes quantités d'énergie pour extraire le pétrole du sable. Utilisez-le lorsqu'il n'y a pas de source directe de pétrole à proximité. block.core-shard.description = Le coeur de votre base. Une fois détruit, le secteur est perdu. Ne laissez pas cela arriver. block.core-shard.details = La première version du Noyau. Il est compact, doté d'un module d'auto-réplication et est équippé de propulseurs de lancement à usage unique. Equipped with single-use launch thrusters. Ceux-ci n'ont pas été conçus pour le voyage interplanétaire. @@ -1445,7 +1456,7 @@ block.cyclone.description = Une grande tourelle qui tire rapidement des balles e block.spectre.description = Une tourelle massive à double cannon qui tire de puissantes balles perçantes. block.meltdown.description = Une tourelle massive chargeant et tirant de puissants rayons lasers. Nécessite un liquide de refroidissement. block.foreshadow.description = Une tourelle massive tirant une puissante balle sur une cible, sur de très longues distances. Elle vise les unités ayant le plus de santé en priorité. -block.repair-point.description = Soigne en permanence l'unité endommagée la plus proche à proximité. +block.repair-point.description = Soigne l'unité endommagée la plus proche. block.segment.description = Endommage et détruit les tirs ennemis. Les lasers ne peuvent pas être ciblés. block.parallax.description = Tire un rayon tracteur qui attire les ennemis volants, infligeant aussi des dégâts. block.tsunami.description = Tire un puissant jet de liquide aux ennemis. Peut éteindre les incendies automatiquement si elle est alimentée en eau. @@ -1453,7 +1464,7 @@ block.silicon-crucible.description = Raffine du silicium avec du sable et du cha block.disassembler.description = Cette verion avancée du séparateur peut produire du thorium. block.overdrive-dome.description = Accélère le fonctionnement des bâtiments autour de lui. Requiert du silicium et du tissu phasé pour fonctionner. block.payload-conveyor.description = Ce grand convoyeur peut déplacer de gros chargements, comme des unité depuis leurs usines ou bien des conteneurs. -block.payload-router.description = Distribue les chargements qui entrent dans 3 directions différentes. +block.payload-router.description = Distribue les chargements qui entrent jusqu'à 3 directions différentes. block.command-center.description = Contrôle le comportement des unités avec plusieurs commandes différentes. block.ground-factory.description = Produit des unités terrestres. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées. block.air-factory.description = Produit des unités aériennes. Elles peuvent être soit utilisées directement, soit envoyées vers des reconstructeurs pour être améliorées. @@ -1479,21 +1490,21 @@ unit.scepter.description = Tire un barrage de balles superchargées aux ennemis unit.reign.description = Tire un barrage de grosses balles perçantes aux ennemis proches. unit.nova.description = Tire des balles laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler. unit.pulsar.description = Tire des arcs électriques qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler. -unit.quasar.description = Tire des faisceaux laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler et est dotée d'un champ de force. +unit.quasar.description = Tire des faisceaux laser qui infligent des dégâts aux ennemis et réparent les structures alliées. Est capable de voler et est doté d'un champ de force. unit.vela.description = Tire un rayon laser continu qui inflige des dégâts aux ennemis, cause des incendies aux structures ennemies et répare les structures alliées. Est capable de voler. -unit.corvus.description = Tire un rayon laser massif qui inflige des dégâts aux ennemis et répare les structures alliées. Peut marcher sur de la plupart des terrains. +unit.corvus.description = Tire un rayon laser massif qui inflige des dégâts aux ennemis et répare les structures alliées. Peut marcher sur la plupart des terrains. unit.crawler.description = Court vers un ennemi proche pour s'auto-détruire, causant une large explosion. -unit.atrax.description = Tire des orbes débilitants de scories sur des cibles terrestres. Peut marcher sur de la plupart des terrains. -unit.spiroct.description = Tire des faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur de la plupart des terrains. -unit.arkyid.description = Tire de larges faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur de la plupart des terrains. -unit.toxopid.description = Tire de larges obus électriques et des lasers perçants aux ennemis proches. Peut marcher sur de la plupart des terrains. -unit.flare.description = Tire des balles normales cibles terrestres. +unit.atrax.description = Tire des orbes débilitants de scories sur des cibles terrestres. Peut marcher sur la plupart des terrains. +unit.spiroct.description = Tire des faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur la plupart des terrains. +unit.arkyid.description = Tire de larges faisceaux laser sapants aux ennemis proches, le réparant aussi. Peut marcher sur la plupart des terrains. +unit.toxopid.description = Tire de larges obus électriques et des lasers perçants aux ennemis proches. Peut marcher sur la plupart des terrains. +unit.flare.description = Tire des balles normales aux cibles terrestres. unit.horizon.description = Largue des bombes sur des cibles terrestres. unit.zenith.description = Tire des salves de missiles sur les ennemis proches. unit.antumbra.description = Tire un barrage de balles aux ennemis proches. unit.eclipse.description = Tire 2 lasers perçants et un barrage de balles explosives aux ennemis proches. unit.mono.description = Mine automatiquement du cuivre et du plomb et le dépose dans un Noyau proche. -unit.poly.description = Reconstruit automatiquement les structures détruites (sauf les réacteurs au thorium) et assiste les autres unités lorsqu'elles construisent. +unit.poly.description = Reconstruit automatiquement les structures détruites (sauf les réacteurs à thorium) et assiste les autres unités lorsqu'elles construisent. unit.mega.description = Répare automatiquement les structures endommagées. Capable de transporter des blocs et de petites unités terrestres. unit.quad.description = Largue de grosses bombes sur des cibles terrestres, réparant les structures alliées et infligeant des dégâts aux ennemis. Capable de transporter des blocs et des unités terrestres de taille moyenne. unit.oct.description = Protège les alliés proches avec son champ de force auto-regénérant. Capable de transporter des blocs et de grosses unités terrestres. @@ -1505,3 +1516,139 @@ unit.omura.description = Tire avec un canon à rails à longue portée, une puis unit.alpha.description = Défend le Noyau fragment contre les ennemis. Peut construire des structures. unit.beta.description = Défend le Noyau fondation contre les ennemis. Peut construire des structures. unit.gamma.description = Défend le Noyau épicentre contre les ennemis. Peut construire des structures. + +lst.read = Lit un nombre depuis un bloc de mémoire relié au processeur. +lst.write = Écrit un nombre dans un bloc de mémoire relié au processeur. +lst.print = Ajoute du texte dans la mémoire tampon de l'imprimante.\nNe montrera aucun texte tant que [accent]Print Flush[] ne sera pas utilisé. +lst.draw = Ajoute une opération dans la mémoire tampon de dessin.\nNe montrera aucune image tant que [accent]Draw Flush[] ne sera pas utilisé. +lst.drawflush = Affiche les opérations [accent]Draw[] en file d'attente vers un écran. +lst.printflush = Affiche les opérations [accent]Print[] en file d'attente vers un bloc de message. +lst.getlink = Obtient un lien de processeur par index. Commence à 0. +lst.control = Contrôle un bâtiment. +lst.radar = Localise des unités dans la portée d'un bâtiment. +lst.sensor = Récupère des données depuis un bâtiment ou une unité. +lst.set = Définit une variable. +lst.operation = Éffectue une opération sur 1 ou 2 variables. +lst.end = Saute au sommet de la série d’instructions. +lst.jump = Saute conditionnelement vers une autre instruction. +lst.unitbind = Se lie à une unité du type donné et la stocke dans [accent]@unit[]. +lst.unitcontrol = Contrôle l'unité actuellement liée. +lst.unitradar = Localise des unités dans la portée de l'unité actuellement liée. +lst.unitlocate = Localise une position ou un type spécifique de bâtiment, n'importe où sur la carte.\nRequiert une unité reliée. + +lenum.type = Type de bâtiment/unité.\nPar exemple, pour tout routeur, cela retournera [accent]@router[].\nPas en texte. +lenum.shoot = Tire à une position donnée. +lenum.shootp = Tire à une unité/bâtiment avec la prédiction de mouvement. +lenum.configure = La configuration d'un bâtiment. Par exemple, l'objet sélectionné dans un trieur. +lenum.enabled = Retourne si le bloc est activé ou pas. + +laccess.color = La couleur d'un illuminateur. + +graphicstype.clear = Remplit l’écran d’une couleur. +graphicstype.color = Définit une couleur pour les prochaines opérations de dessin. +graphicstype.stroke = Définit la largeur d'une ligne. +graphicstype.line = Dessine un segment de droite. +graphicstype.rect = Dessine un rectangle. +graphicstype.linerect = Dessine le contour d'un rectangle. +graphicstype.poly = Dessine un polygone régulier. +graphicstype.linepoly = Dessine le contour un polygone régulier. +graphicstype.triangle = Dessine un triangle. +graphicstype.image = Dessine une image venant du contenu du jeu.\nex: [accent]@router[] ou [accent]@dagger[]. + +lenum.always = Toujours [accent]true[]. +lenum.idiv = Division entière. +lenum.div = Division.\nRetourne [accent]null[] lors d'une division par zéro. +lenum.mod = Modulo. +lenum.equal = Égalité. Conversion des types.\nLes objets non-nuls comparés avec des nombres deviennent 1, sinon 0. +lenum.notequal = Inégalité. Conversion des types. +lenum.strictequal = Égalité stricte. Ne convertit pas les types.\nPeut être utilisé pour vérifier les valeurs [accent]null[]. +lenum.shl = Décalage de bits gauche. +lenum.shr = Décalage de bits droite. +lenum.or = Opération binaire OR. +lenum.land = Opération logique AND. +lenum.and = Opération binaire AND. +lenum.not = Opération binaire flip. +lenum.xor = Opération binaire XOR. + +lenum.min = Le minimum des 2 nombres. +lenum.max = Le maximum des 2 nombres. +lenum.angle = Angle d'un vecteur en degrés. +lenum.len = Longueur d'un vecteur. +lenum.sin = Sinus, en degrés. +lenum.cos = Cosinus, en degrés. +lenum.tan = Tangente, en degrés. +#not a typo, look up 'range notation' +lenum.rand = Nombre aléatoire dans la plage [0, valeur]. +lenum.log = Logarithme naturel (ln). +lenum.log10 = Logarithme de base 10. +lenum.noise = Bruit simplex 2D. +lenum.abs = Valeur absolue. +lenum.sqrt = Racine carrée. + +lenum.any = N'importe quelle unité. +lenum.ally = Unité alliée. +lenum.attacker = Unité avec des armes. +lenum.enemy = Unité ennemie. +lenum.boss = Gardien. +lenum.flying = Unité volante. +lenum.ground = Unité terrestre. +lenum.player = Unité controllée par un joueur. + +lenum.ore = Gisement de minerai. +lenum.damaged = Bâtiments alliés endommagés. +lenum.spawn = Point d'apparition ennemi.\nPeut être un noyau ou une position. +lenum.building = Bâtiment dans un groupe spécifique. + +lenum.core = N'importe quel noyau. +lenum.storage = Bâtiments de stockage, un coffre-fort par exemple. +lenum.generator = Bâtiments générant de l'énergie. +lenum.factory = Bâtiments traitant des ressources. +lenum.repair = Points de réparation. +lenum.rally = Centres de commandes. +lenum.battery = N'importe quelle batterie. +lenum.resupply = Points de rechargement.\nUtile seulement lorsque [accent]"munitions"[] sont limitées. +lenum.reactor = Réacteur à Impact/Thorium. +lenum.turret = N'importe quelle tourelle. + +sensor.in = Les bâtiments/unités à analyser. + +radar.from = Bâtiment de détection.\nLa portée du détecteur est limitée à la portée du bâtiment. +radar.target = Filtre pour les unités à détecter. +radar.and = Filtres additionnels +radar.order = Ordre de filtrage. 0 pour inverser. +radar.sort = Valeur par laquelle les résultats sont triés. +radar.output = Variable dans laquelle écrire l'unité retournée. + +unitradar.target = Filtre pour les unités à détecter. +unitradar.and = Filtres additionnels +unitradar.order = Ordre de filtrage. 0 pour inverser. +unitradar.sort = Valeur par laquelle les résultats sont triés. +unitradar.output = Variable dans laquelle écrire l'unité retournée. + +control.of = Bâtiment à contrôler. +control.unit = Unité/bâtiment à viser. +control.shoot = S’il faut tirer ou non. + +unitlocate.enemy = S'il faut détecter les bâtiments ennemis au non. +unitlocate.found = Retourne un boolean s'il l'objet a été trouvé ou non. +unitlocate.building = Retourne une variable pour le bâtiment localisé. +unitlocate.outx = Retourne la coordonnée X. +unitlocate.outy = Retourne la coordonnée Y. +unitlocate.group = Le groupe de bâtiments à rechercher. + +lenum.stop = Empêche l'unité de bouger/miner/construire. +lenum.move = Bouge vers la position exacte. +lenum.approach = Approche une position avec un rayon. +lenum.pathfind = Détermine un itinéraire et bouge vers le point d'apparition ennemi. +lenum.target = Tire vers la position donnée. +lenum.targetp = Tire sur un cible avec la prédiction de mouvement. +lenum.itemdrop = Lâche un objet. +lenum.itemtake = Prend un objet depuis un bâtiment. +lenum.paydrop = Lâche le chargement actuel. +lenum.paytake = Prend un chargement à la position actuelle. +lenum.flag = Drapeau numérique d'une unité. +lenum.mine = Mine à une position donnée. +lenum.build = Construit une structure. +lenum.getblock = Récupère des données sur un bâtiment et son type aux coordonnées données.\nL'unité doit se trouver dans la portée de la position.\nLes blocs solides qui ne sont pas des bâtiments auront le type [accent]@solid[]. +lenum.within = Vérifie si l'unité est près de la position. +lenum.boost = Active/Désactive le boost. \ No newline at end of file From 68020fa7d48536d93e333802e262c618029b88ef Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 18:31:34 -0500 Subject: [PATCH 310/426] Fixed "fix" in #4397 --- core/assets/bundles/bundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index be766129a3..8f22aab6cd 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1579,7 +1579,7 @@ lenum.sin = Sine, in degrees. lenum.cos = Cosine, in degrees. lenum.tan = Tangent, in degrees. #not a typo, look up 'range notation' -lenum.rand = Random number in range [0, value]. +lenum.rand = Random number in range [0, value). lenum.log = Natural logarithm (ln). lenum.log10 = Base 10 logarithm. lenum.noise = 2D simplex noise. From 7bb4b09308cb3d90f63cca1afd7c9f658ad281ef Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Sat, 20 Feb 2021 01:32:07 +0200 Subject: [PATCH 311/426] [Bundle][RO] Update (#4725) * [Bundle][RO] Update This PR was tested in-game and is ready to merge at any time. Changelog: - New strings/changes up to commit 1ef7ae70796beb4a28dee8f2c74b626d28348481 - Typo fixes & various other improvements * Reducing confusion * Update bundle_ro.properties --- core/assets/bundles/bundle_ro.properties | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index c6c8ecd72f..0ce1983a4f 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -113,7 +113,7 @@ committingchanges = Se Încarcă Schimbările done = Gata feature.unsupported = Dispozitivul tău nu suportă această funcție. -mods.alphainfo = Modurile sunt încă în alpha și[scarlet] pot avea multe buguri[].\nRaportează orice probleme apărute pe Githubul Mindustry. +mods.initfailed = [red]⚠[] Instanța Mindustry precedentă a eșuat la inițializare. De obicei se întâmplă din cauza unui mod care nu se acționează cum trebuie.\n\nPt a preveni un lanț de crashuri continue, [red]toate modurile au fost dezactivate.[]\n\nPoți dezactiva asta din [accent]Setări->Joc->Dezactivează Modurile în Cazul unui Crash la Pornire[]. mods = Moduri mods.none = [lightgray]Nu s-au găsit moduri! mods.guide = Ghid de Modding @@ -800,6 +800,7 @@ setting.logichints.name = Indicii Procesoare Logice setting.flow.name = Afișează Rata de Curgere a lichidelor setting.buildautopause.name = Autopauză de la Construit setting.backgroundpause.name = Pune Pauză în Fundal +setting.modcrashdisable = Dezactivează Modurile în Cazul unui Crash la Pornire setting.animatedwater.name = Suprafețe Animate setting.animatedshields.name = Scuturi Animate setting.antialias.name = Antialiasing[lightgray] (necesită repornire)[] @@ -1039,7 +1040,7 @@ unit.omura.name = Omura unit.alpha.name = Alpha unit.beta.name = Beta unit.gamma.name = Gamma -unit.scepter.name = Septer +unit.scepter.name = Scepter unit.reign.name = Reign unit.vela.name = Vela unit.corvus.name = Corvus @@ -1228,7 +1229,7 @@ block.overdrive-projector.name = Proiector de Suprasolicitare block.force-projector.name = Proiector de Forță block.arc.name = Arc block.rtg-generator.name = Generator RTG -block.spectre.name = Specter +block.spectre.name = Spectre block.meltdown.name = Meltdown block.foreshadow.name = Foreshadow block.container.name = Container @@ -1541,7 +1542,19 @@ lenum.shoot = Lovește către o locație. lenum.shootp = Lovește către o unitate/clădire. Anticipează viteza țintei și a proiectilului. lenum.configure = Configurașia clădirii, de ex. materialul selectat pt Sortator. lenum.enabled = Specifică dacă clădirea este pornită. -lenum.color = Culoarea Iluminatorului. + +laccess.color = Culoarea iluminatorului. + +graphicstype.clear = Umple monitorul cu o culoare. +graphicstype.color = Setează culoarea pt următoarea instrucțiune Draw. +graphicstype.stroke = Setează grosimea liniei. +graphicstype.line = Desenează un segment de linie. +graphicstype.rect = Desenează un dreptunghi. +graphicstype.linerect = Desenează conturul unui dreptunghi. +graphicstype.poly = Desenează un poligon regulat. +graphicstype.linepoly = Desenează conturul unui poligon regulat. +graphicstype.triangle = Desenează un triunghi. +graphicstype.image = Desenează imaginea unui obiect din joc.\nde ex.: [accent]@router[] sau [accent]@dagger[]. lenum.always = Mereu adevărat. lenum.idiv = Împărțirea naturală a numerelor (int). From 6de53343a4f32e5204305532429c9c02faeacc9e Mon Sep 17 00:00:00 2001 From: BlueThecno <69437358+BlueThecno@users.noreply.github.com> Date: Fri, 19 Feb 2021 19:32:17 -0400 Subject: [PATCH 312/426] Fixing typos and descriptions [bundle_es.properties] (#4727) * Fixing and descriptions [bundle_es.properties] * Forgot something --- core/assets/bundles/bundle_es.properties | 27 ++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index 6f62033ba2..ffe4a20976 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -693,7 +693,8 @@ stat.lightningchance = Probabilidad de descarga stat.lightningdamage = Daño por rayo stat.flammability = Inflamabilidad stat.radioactivity = Radioactividad -stat.heatcapacity = Resistencia temperatura +stat.charge = Carga eléctrica +stat.heatcapacity = Resistencia a la temperatura stat.viscosity = Viscosidad stat.temperature = Temperatura stat.speed = Velocidad @@ -1116,7 +1117,7 @@ block.plastanium-wall.name = Muro de Plastanio block.plastanium-wall-large.name = Muro de Plastanio grande block.phase-wall.name = Muro de Fase grande block.phase-wall-large.name = Muro de Fase grande -block.thorium-wall.name = Pared de Torio +block.thorium-wall.name = Muro de Torio block.thorium-wall-large.name = Muro de Torio grande block.door.name = Puerta block.door-large.name = Puerta Grande @@ -1329,16 +1330,16 @@ block.graphite-press.description = Comprime carbón en piezas de grafito puro. block.multi-press.description = Una versión mejorada de la prensa de grafito. Utiliza agua y energía para procesar carbón rápida y eficientemente. block.silicon-smelter.description = Reduce la arena con carbón puro. Produce silicio. block.kiln.description = Funde arena y plomo en metacristal. Requiere cantidades pequeñas de energía para funcionar. -block.plastanium-compressor.description = Produce plastanio con aceite y titanio. +block.plastanium-compressor.description = Produce plastanio con petróleo y titanio. block.phase-weaver.description = Produce tejido de fase del torio radioactivo y altas cantidades de arena. block.alloy-smelter.description = Produce aleación eléctrica con titanio, plomo, silicio y cobre. block.cryofluid-mixer.description = Combina agua y titanio en líquido criogénico, que es mucho más eficiente para enfriar. -block.blast-mixer.description = Usa aceite para transformar pirotita en un objeto menos inflamable pero más explosivo: el compuesto explosivo. +block.blast-mixer.description = Usa esporas para transformar pirotita en un objeto menos inflamable pero más explosivo: el compuesto explosivo. block.pyratite-mixer.description = Mezcla carbón, plomo y arena en pirotita altamente inflamable. -block.melter.description = Calienta piedra a temperaturas muy altas para obtener lava. +block.melter.description = Calienta chatarra a temperaturas muy altas para obtener magma. block.separator.description = Expone piedra a la presión del agua para obtener diversos minerales contenidos en la piedra. block.spore-press.description = Comprime esporas en petróleo. -block.pulverizer.description = Despedaza la piedra en arena. Útil cuando no hay arena natural. +block.pulverizer.description = Despedaza la chatarra en arena. Útil cuando no hay arena natural. block.coal-centrifuge.description = Solidifica petróleo en piezas de carbón. block.incinerator.description = Se deshace de cualquier líquido o material producido en exceso. block.power-void.description = Elimina toda la energía que se le da. Solo en disponible en el modo Libre. @@ -1351,7 +1352,7 @@ block.copper-wall.description = Un bloque defensivo barato.\nÚtil para defender block.copper-wall-large.description = Un bloque defensivo barato.\nÚtil para defender el núcleo y las torres en las primeras oleadas.\nOcupa múltiples casillas. block.titanium-wall.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos. block.titanium-wall-large.description = Un bloque defensivo moderadamente fuerte.\nProporciona protección moderada contra los enemigos.\nOcupa múltiples casillas. -block.plastanium-wall.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia.. +block.plastanium-wall.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia. block.plastanium-wall-large.description = Un tipo especial de pared que absorbe los arcos eléctricos y bloquea las conexiones automáticas de los nodos de potencia.\nOcupa múltiples casillas. block.thorium-wall.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos. block.thorium-wall-large.description = Un bloque defensivo fuerte.\nBuena protección contra enemigos.\nOcupa múltiples casillas. @@ -1359,8 +1360,8 @@ block.phase-wall.description = No es tan fuerte como un muro de torio pero hace block.phase-wall-large.description = No es tan fuerte como un muro de torio pero rebota balas al enemigo si no son demasiado fuertes.\nOcupa múltiples casillas. block.surge-wall.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante. block.surge-wall-large.description = El bloque defensivo más fuerte.\nTiene una pequeña probabilidad de disparar rayos al atacante.\nOcupa múltiplies casillas. -block.door.description = Una puerta pequeña que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella. -block.door-large.description = Una puerta grande que puede ser abierta y cerrada tocándola.\nSi está abirta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas. +block.door.description = Una puerta pequeña que puede ser abierta y cerrada tocándola.\nSi está abierta, los enemigos pueden moverse y disparar a través de ella. +block.door-large.description = Una puerta grande que puede ser abierta y cerrada tocándola.\nSi está abierta, los enemigos pueden moverse y disparar a través de ella.\nOcupa múltiples casillas. block.mender.description = Repara bloques cercanos de forma constante. Mantiene a las defensas reparadas entre oleadas. Puede usar silicio opcionalmente para mejorar el alcance y la eficiencia. block.mend-projector.description = Regenera edificios cercanos de forma constante. Ocupa multiples casillas. block.overdrive-projector.description = Aumenta la velocidad de edificios cercanos como taladros y transportadores. @@ -1388,7 +1389,7 @@ block.pulse-conduit.description = Bloque de transporte de líquidos avanzado. Tr block.plated-conduit.description = Mueve líquidos a la misma velocidad que los conductos de pulso, pero posee más armadura. No acepta líquidos de los lados por otra cosa que no sean conductos.\nGotea menos. block.liquid-router.description = Acepta líquidos de una dirección y los deja en hasta 3 direcciones equitativamente. También puede almacenar cierta capacidad de líquido. Útil para dividir los líquidos de una fuente a varios objetivos. block.liquid-tank.description = Almacena una gran cantidad de líquidos. Úsalo para crear almacenes cuando no hay una demanda constante de materiales o para asegurarse de enfriar bloques vitales. -block.liquid-junction.description = Actúa como un puente para dos condusctos que se cruzan. Útil en situaciones en las que hay dos conductos con líquidos diferentes a diferentes lugares. +block.liquid-junction.description = Actúa como un puente para dos conductos que se cruzan. Útil en situaciones en las que hay dos conductos con líquidos diferentes a diferentes lugares. block.bridge-conduit.description = Bloque avanzado de transporte de líquidos. Permite transportar líquidos por encima de hasta 3 casillas de cualquier terreno o construcción. block.phase-conduit.description = Bloque de transporte de líquidos avanzado. Usa energía para transportar líquidos a otro conducto de fase conectado a través de varias casillas. block.power-node.description = Transmite energía a nodos conectados, conecta hasta diez fuentes de energía, edificios que usan energía o nodos. El nodo obtendrá o transmitirá energía de cualquier bloque adyacente. @@ -1398,7 +1399,7 @@ block.diode.description = La energía de la batería puede fluir a través de es block.battery.description = Guarda energía cuando hay abundancia y proporciona energía cuando hay escasez de energía mientras la batería tenga energía. block.battery-large.description = Almacena mucha más energía que una batería normal. block.combustion-generator.description = Genera energía quemando materiales inflamables o petróleo. -block.thermal-generator.description = Genera una gran cantidad de energía con la lava. +block.thermal-generator.description = Genera una gran cantidad de energía con el magma. block.steam-generator.description = Más eficiente que un generador de combustión, pero requiere agua adicional. block.differential-generator.description = Genera grandes cantidades de energía. Utiliza la diferencia de temperatura entre el fluído criogenico y la quema de pirotita. block.rtg-generator.description = Un generador radioisótropo termoeléctrico que no necesita enfriamiento, pero proporciona menos energía que un reactor de torio. @@ -1444,7 +1445,7 @@ block.segment.description = Daña y destruye proyectiles que se acerquen. No afe block.parallax.description = Dispara un rayo tractor que atrae enemigos aéreos, dañándolos en el proceso. block.tsunami.description = Dispara poderosos torrentes de líquido a los enemigos. También apaga fuegos automáticamente si se lo abastece con agua. block.silicon-crucible.description = Refina silicio a partir de arena y carbón, usando pirotita como una fuente de calor adicional. Es más eficiente en lugares cálidos. -block.disassembler.description = Separa magma cantidades moderadas de componentes minerales exóticos con baja eficiencia. Puede producir Torio. +block.disassembler.description = Separa magma en cantidades moderadas de componentes minerales exóticos con baja eficiencia. Puede producir Torio. block.overdrive-dome.description = Incrementa la velocidad de estructuras cercanas. Requiere Tejido de Fase y Silicio para operar. block.payload-conveyor.description = Mueve tanto grandes cargas, como unidades recién ensambladas de sus fábricas. block.payload-router.description = Divide las cargas entrantes en 3 direcciones de salida. @@ -1487,7 +1488,7 @@ unit.zenith.description = Dispara ráfagas de misiles a enemigos cercanos. unit.antumbra.description = Dispara un enjambre de balas a cualquer enemigo cercano. unit.eclipse.description = Dispara dos láseres perforantes y un enjambre de balas de fragmentación. unit.mono.description = Extrae cobre y plomo, y los deposita en el núcleo. -unit.poly.description = Recosntruye automáticamente estructuras dañadas y asiste a otras unidades en la construcción. +unit.poly.description = Reconstruye automáticamente estructuras dañadas y asiste a otras unidades en la construcción. unit.mega.description = Repara automáticamente estructuras dañadas. Puede llevar estructuras y unidades terrestres pequeñas. unit.quad.description = Suelta grandes bombas sobre objetivos terrestres, repara estructuras aliadas y daña enemigos. Puede cargar con unidades terrestres de tamaño medio. unit.oct.description = Protege aliados con su escudo. Puede cargar con la mayoría de unidades terrestres. From 57a833c2fb1d81179f6d110d363e56521a51a514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E7=91=9E=E6=9A=84?= Date: Sat, 20 Feb 2021 07:32:32 +0800 Subject: [PATCH 313/426] Update Logic Draw Hints (#4734) Wrapped up some previous logic hints, too. --- core/assets/bundles/bundle_zh_TW.properties | 36 ++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 1cf73184e8..83c78dafbe 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -957,6 +957,8 @@ rules.blockdamagemultiplier = 建築物傷害倍數 rules.unitbuildspeedmultiplier = 單位建設速度倍數 rules.unithealthmultiplier = 單位生命值倍數 rules.unitdamagemultiplier = 單位傷害倍數 +rules.unitcapvariable = 核心限制單位上限 +rules.unitcap = 基礎單位上限 rules.enemycorebuildradius = 敵人核心禁止建設半徑︰[lightgray](格) rules.wavespacing = 波次間距︰[lightgray](秒) rules.buildcostmultiplier = 建設成本倍數 @@ -1539,7 +1541,19 @@ lenum.shoot = 對該位置開火 lenum.shootp = 對指定單位/建築開火,具自瞄功能 lenum.configure = 建築設定,如分類器、兵器工廠 lenum.enabled = 確認該建築是否啟用 -lenum.color = 設定照明燈的顏色 + +laacess.color = 設定照明燈的顏色 + +graphicstype.clear = 重製版面為指定顏色 +graphicstype.color = 為接下來的圖畫指令設定顏色 +graphicstype.stroke = 為接下來的圖畫指令設定直線寬度 +graphicstype.line = 畫一直線 +graphicstype.rect = 畫實心長方形 +graphicstype.linerect = 畫空心長方形 +graphicstype.poly = 畫實心正多邊形 +graphicstype.linepoly = 畫空心正多邊形 +graphicstype.triangle = 畫實心三角形 +graphicstype.image = 繪製內建圖畫\n如: [accent]@router[]或[accent]@dagger[]. lenum.always = 永遠 true (直接跳). lenum.idiv = 整數除法,無條件捨去. @@ -1556,17 +1570,17 @@ lenum.and = Bitwise AND. lenum.not = Bitwise flip. lenum.xor = Bitwise XOR. -lenum.min = Minimum of two numbers. -lenum.max = Maximum of two numbers. -lenum.angle = Angle of vector in degrees. -lenum.len = Length of vector. -lenum.sin = Sine, in degrees. -lenum.cos = Cosine, in degrees. -lenum.tan = Tangent, in degrees. +lenum.min = 兩數取小 +lenum.max = 兩數取大 +lenum.angle = 向量與x軸夾角 +lenum.len = 向量長度 +lenum.sin = 度數Sin值 +lenum.cos = 度數Cos值 +lenum.tan = 度數Tan值 #not a typo, look up 'range notation' -lenum.rand = Random number in range [0, value). -lenum.log = Natural logarithm (ln). -lenum.log10 = Base 10 logarithm. +lenum.rand = 產生隨機數值: [0, 值). +lenum.log = 自然對數(ln、log_e). +lenum.log10 = 高中數學. lenum.noise = 2D simplex noise. lenum.abs = 取絕對值 lenum.sqrt = 開根號 From 1613f49c160333db0e1dc4810ff51012a088a591 Mon Sep 17 00:00:00 2001 From: Catchears <57631841+Catchears@users.noreply.github.com> Date: Sat, 20 Feb 2021 00:32:44 +0100 Subject: [PATCH 314/426] german translation for build 125, full android translation (#4703) * update german translation to https://github.com/Anuken/Mindustry/commit/631e4d9eefca8b94de4fc52e57387b2c2f4ffecf * update android translation to https://github.com/Anuken/Mindustry/commit/e816f6110de6ec9638b5a6be8a9710bdc49f5f4d with regard to https://github.com/Anuken/Mindustry/commit/5ec5f1aa93dcac5c813027b23379f529dbf69e3d * improve translation with ideas from others * update german steam discription to https://github.com/Anuken/Mindustry/commit/e86a3e9d09d0f41a651d5e66403ea48c70add048 * update german translation to https://github.com/Anuken/Mindustry/commit/1ef7ae70796beb4a28dee8f2c74b626d28348481#diff-5e346bcec4e8e1d545e035b1e438472bc51937398ac3e8e81308605ec82aea2c * changes from stuffyAI * cross-platform as suggested by stuffyAI * stuffyAI genau, hast recht Co-authored-by: stuffyAI <59014072+stuffyAI@users.noreply.github.com> Co-authored-by: stuffyAI <59014072+stuffyAI@users.noreply.github.com> --- core/assets/bundles/bundle_de.properties | 26 ++++++++- .../android/de-DE/full_description.txt | 57 ++++++++++++++++--- .../metadata/steam/german/description.txt | 43 ++++++++------ 3 files changed, 99 insertions(+), 27 deletions(-) diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index 13c4725bee..ca9d806c2f 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -957,6 +957,8 @@ rules.blockdamagemultiplier = Block-Schaden-Multiplikator rules.unitbuildspeedmultiplier = Baugeschwindigkeit-Einheit Multiplikator rules.unithealthmultiplier = Lebenspunkte-Einheit Multiplikator rules.unitdamagemultiplier = Schaden-Einheit Multiplikator +rules.unitcapvariable = Kerne zählen zum Einheiten-Limit dazu +rules.unitcap = Einheiten-Limit rules.enemycorebuildradius = Bauverbot-Radius durch feindlichen Kern:[lightgray] (Kacheln) rules.wavespacing = Wellen-Abstand:[lightgray] (Sek) rules.buildcostmultiplier = Bau-Kosten Multiplikator @@ -1042,7 +1044,7 @@ unit.reign.name = Reign unit.vela.name = Vela unit.corvus.name = Korvus -block.resupply-point.name = Nachlade-Punkt +block.resupply-point.name = Munitionsvorrat block.parallax.name = Parallax block.cliff.name = Klippe block.sand-boulder.name = Sandbrocken @@ -1539,8 +1541,19 @@ lenum.shoot = Schießt auf eine Position. lenum.shootp = Schießt auf eine Einheit / einen Block und sagt deren Position voraus. lenum.configure = Blockkonfiguration, z.B. das ausgewählte Item in einem Sortierer. lenum.enabled = Ob der Block an oder aus ist. -lenum.color = Illuminiererfarbe. +laccess.color = Illuminiererfarbe. + +graphicstype.stroke = Setzt die Linienbreite fest. +graphicstype.line = Zeichnet eine Linie. +graphicstype.clear = Füllt den Bildschirm mit einer Farbe. +graphicstype.color = Wählt eine Farbe aus. +graphicstype.rect = Zeichnet ein Rechteck. +graphicstype.linerect = Zeichnet den Umriss eines Rechtecks. +graphicstype.poly = Füllt ein gleichmäßiges Polygon. +graphicstype.linepoly = Zeichnet den Umriss eines gleichmäßigen Polygons. +graphicstype.triangle = Zeichnet ein Dreieck. +graphicstype.image = Zeichnet ein Bild von einem englischen Namen.\nz.B. [accent]@router[] oder [accent]@dagger[]. lenum.always = Immer. lenum.idiv = Division mit ganzen Zahlen. lenum.div = Division.\nGibt bei Teilung durch null [accent]null[] zurück. @@ -1563,6 +1576,7 @@ lenum.len = Length of vector. lenum.sin = Sinus in Grad. lenum.cos = Cosinus in Grad. lenum.tan = Tangens in Grad. +#not a typo, look up 'range notation' lenum.rand = Zufällige Zahl zwischen [0, ). lenum.log = Logarithmus (ln). lenum.log10 = Logarithmus zur Basis 10. @@ -1586,6 +1600,14 @@ lenum.building = Ein Block einer bestimmten Sorte. lenum.core = Irgendein Kern. lenum.storage = Speicherblock, z.B. ein Tresor. +lenum.generator = Blöcke, die Strom generieren. +lenum.factory = Blöcke, die Ressourcen verarbeiten. +lenum.repair = Reperaturpunkt. +lenum.rally = Kommandozentrale +lenum.battery = Irgendeine Batterie. +lenum.resupply = Munitionsvorrat.\nNur wichtig, wenn [accent]"Einheiten benötigen Munition"[] an ist. +lenum.reactor = Schlag- / Thoriumreaktor. +lenum.turret = Irgendein Geschütz. sensor.in = Der Block / die Einheit. diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt index 84717be4ba..1eab8ba2b8 100644 --- a/fastlane/metadata/android/de-DE/full_description.txt +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -1,11 +1,52 @@ Baue komplexe Produktionsketten aus Förderbändern, um deine Geschütztürme mit Munition zu versorgen. Stelle Materialien her, um deine Fabrik zu vergrößern und sie vor Gegnerwellen zu schützen. Spiele mit deinen Freunden in plattformübergreifenden Partien oder fordere sie zum Kampf heraus. -Dieses Tower-Defense-Spiel bietet: -- 24 Karten -- Eine Kampagne, die ins Spiel einführt und einen Forschungsbaum enthält -- 4 mächtige Bosse -- Transportsysteme für Materialien, Flüssigkeiten und Strom -- 19 verschiedene Einheiten, die du kommandieren kannst -- Mehrspielerpartien im lokalen Netzwerk oder über einen Server +

Spielmechanik

+ +- Benutze Produktionsblöcke, um eine große Vielfalt an Ressourcen herzustellen +- Beschütze deine Basis vor Gegnerwellen +- Spiele platformübergreifend mit deinen Freunden, oder fordere sie zu einem Team-basiertem PvP-Match hinaus +- Transportiere Flüssigkeiten und bekämpfe die ständige Bedrohung von Feuerausbrüchen oder gegnerische Luftangriffe +- Nutze deine Produktionsblöcke voll aus, indem du Schmiermittle und Kühlung besorgst +- Stelle eine Vielfalt an Einheiten her, welche je nach Typ Angriff und Verteidigung oder Abläufe in der Basis unterstützen können -Mithilfe eines eingebauten Editors können eigene Karten und Gegnerwellen erstellt werden. Die Spielregeln kannst du flexibel nach deinen Wünschen anpassen. + +

Kampagne

+ +- Erobere den Planeten Serpulo, indem du über 250 prozedural generierte Sektoren und 16 handgemachte Karten durchspielst +- Erorbere ein Gebiet und stelle Fabriken auf, welche dir Ressourcen produzieren, während du den nächsten Sektor eroberst +- Verteidige deine Sektoren vor regelmäßigen Invasionen +- Koordiniere Ressourcesverteilung zwischen Sektoren mit Launchpads +- Erforsche neue Blöcke, um deinen Fortschitt foranzutreiben +- Schließe Missionen zusammen mit deinen Freunden ab +- 130+ verschiedenste Blöcke +- 33 verschiedene Einheite + + +

Spielmodi

+ +- Überleben: Baue Geschütztürme, um deine Basis zu beschützen. Überlebe so lange wie möglich und starte deine Ressourcen, um mit ihnen zu forschen. Bereite deine Basis auf gegnerische Bossangriffe vor. +- Angriff: Baue Fabriken für Einheiten, die den gegnerischen Kern zerstören und währenddessen deinen beschützen. Erstelle eine Mischung aus defensive und offensive Einheiten, um dich zu unterstüzen. Aktiviere wahlweise eine KI, sodass der Gegner auch bauen kann. +- PvP: Kämpfe mit bis zu vier Teams um den Sieg und zerstöre die gegnerischen Kerne. Baue Einheiten oder greife die Gegner direkt an. +- Sandkasten: Spiele mit unendlichen Ressources und ohne Gegnergefahr. Benutze besondere Ressourcenquellen um Sachen auszuprobieren, oder erstelle Gegner auf Anfrage. + + +

Benutzerdefinierte Spiele & plattformübergreifender Multiplayer

+ +- 16 eingebaute Karten für eigene Spiele +- Spielt gemeinsam, gegeneinander oder im Sandkasten +- Trete einem öffentlichen Server bei oder eröffne ein Spiel für deine Freunde +- Anpassbare Spielregeln: Verändere Blockkosten, Gegnerstärke, Anfangsitems, Wellen und mehr! +- Kombiniere PvP und PvE (player versus enemies) + + +

Eigener Karten-Editor

+ +- Male Terrain +- Editiere und sehe eine Vorschau deiner Karte im Spiel +- Passe die Werkzeuge nach deinen Vorstellungen an +- Nützliches Generationssystem für Karten mit vielen verschiedenen Filtern für das Bearbeiten vom Terrain +- Verschönere die Landschaft mit Rauschen, Verzerrungen, Glätte, Erosion, Symmetrie, Erzgeneration und Zufallsgenerierung +- Lasse Erze, Flüsse und andere Ressourcen automatisch generieren +- Konfiguriere die Gegnerwellen +- Gib der Karte besondere Spielregeln +- Benutze 80+ verschiedene Umgebungsblöcke diff --git a/fastlane/metadata/steam/german/description.txt b/fastlane/metadata/steam/german/description.txt index 941444cdbd..25a5d54432 100644 --- a/fastlane/metadata/steam/german/description.txt +++ b/fastlane/metadata/steam/german/description.txt @@ -3,11 +3,13 @@ [h2]Spielmechanik[/h2] [list] -[*] Baue komplexe Produktionsketten aus Förderbändern, um deine Geschütztürme mit Munition zu versorgen -[*] Stelle Materialien her, um deine Fabrik zu vergrößern und sie vor Gegnerwellen zu schützen -[*] Spiele mit deinen Freunden in plattformübergreifenden Partien oder fordere sie zum Kampf heraus -[*] Es gibt immer etwas zu tun: Wenn du deine Kühlsysteme nicht im Blick behältst, könnte dein Reaktor explodieren! -[*] Produziere Einheiten, die bei deiner Basis helfen oder den Gegner angreifen +[*] Baue komplexe Produktionsketten aus Förderbändern, um deine Geschütztürme mit Munition zu versorgen und erweiterte Ressourcen zum Verbessern deiner Basis herzustellen +[*] Benutze Produktionsblöcke, um eine große Vielfalt an Ressourcen herzustellen +[*] Beschütze deine Basis vor Gegnerwellen +[*] Spiele platformübergreifend mit deinen Freunden, oder fordere sie zu einem Team-basiertem PvP-Match hinaus +[*] Transportiere Flüssigkeiten und bekämpfe die ständige Bedrohung von Feuerausbrüchen oder gegnerische Luftangriffe +[*] Nutze deine Produktionsblöcke voll aus, indem du Schmiermittle und Kühlung besorgst +[*] Stelle eine Vielfalt an Einheiten her, welche je nach Typ Angriffe und Verteidigung oder Abläufe in der Basis unterstützen können [/list] [img]{STEAM_APP_IMAGE}/extras/ezgif-1-8679abe089cd.gif[/img] @@ -16,11 +18,12 @@ [list] [*] Erobere den Planeten Serpulo, indem du über 250 prozedural generierte Sektoren und 16 handgemachte Karten eroberst -[*] Stelle Materialien in eroberten Sektoren her, während du den nächsten Sektor eroberst +[*] Erorbere ein Gebiet und stelle Fabriken auf, welche dir Ressourcen produzieren, während du den nächsten Sektor eroberst [*] Verteidige deine Sektoren vor regelmäßigen Invasionen -[*] Transportiere Materialien zwischen deinen Sektoren -[*] Schalte neue Blöcke in der Forschung frei +[*] Koordiniere Ressourcenverteilung zwischen Sektoren mit Launchpads +[*] Erforsche neue Blöcke, um deinen Fortschitt foranzutreiben [*] Schließe Missionen zusammen mit deinen Freunden ab +[*] 130+ verschiedenste Blöcke [*] 33 verschiedene Einheiten [*] über 50 Erfolge [/list] @@ -28,10 +31,10 @@ [h2]Spielmodi[/h2] [list] -[*] [b]Überleben[/b]: Baue Geschütztürme und verteidige Wellen von Gegnern. Bereite dich auf zwischenzeitliche Zerstörungsangriffe von flugfähigen Einheiten vor. -[*] [b]Angriff[/b]: Stelle Einheiten her, um den gegnerischen Kern zu zerstören. Vergesse dabei nicht, deinen eigenen Kern zu schützen! -[*] [b]PvP[/b]: Kämpfe gegen andere Spieler in Teams und zerstöre die gegnerischen Kerne. -[*] [b]Sandkasten[/b]: Probiere deine Designs mit unendlichen Ressourcen und Gegnerwellen auf Anfrage aus. +[*] [b]Überleben[/b]: Baue Geschütztürme, um deine Basis zu beschützen. Überlebe so lange wie möglich und starte deine Ressourcen, um mit ihnen zu forschen. Bereite deine Basis auf gegnerische Bossangriffe vor. +[*] [b]Angriff[/b]: Baue Fabriken für Einheiten, die den gegnerischen Kern zerstören und währenddessen deinen beschützen. Erstelle eine Mischung aus defensive und offensive Einheiten, um dich zu unterstüzen. Aktiviere wahlweise eine KI, sodass der Gegner auch bauen kann. +[*] [b]PvP[/b]: Kämpfe mit bis zu vier Teams um den Sieg und zerstöre die gegnerischen Kerne. Baue Einheiten oder greife die Gegner direkt an. +[*] [b]Sandkasten[/b]: Spiele mit unendlichen Ressources und ohne Gegnergefahr. Benutze besondere Ressourcenquellen um Sachen auszuprobieren, oder erstelle Gegner auf Anfrage. [/list] [img]{STEAM_APP_IMAGE}/extras/2020-11-30_10-46-02.gif[/img] @@ -39,18 +42,24 @@ [h2]Mehrspielermodus[/h2] [list] +[*] 16 eingebaute Karten für eigene Spiele +[*] Spielt gemeinsam, gegeneinander oder im Sandkasten [*] Trete einem öffentlichen Server bei oder eröffne ein Spiel für deine Freunde -[*] Ändere die Spielregeln: Kosten, Schadenswerte und mehr! +[*] Anpassbare Spielregeln: Verändere Blockkosten, Gegnerstärke, Anfangsitems, Wellen und mehr! [*] Kombiniere PvP und PvE (player versus enemies) [/list] [h2]Karteneditor[/h2] [list] +[*] Male Terrain +[*] Editiere und sehe eine Vorschau deiner Karte im Spiel [*] Passe die Werkzeuge nach deinen Vorstellungen an -[*] Viele Filter für das prozedurale Generieren der Umgebung -[*] Verschönere die Landschaft mit Rauschen, Verzerrungen, Erosion, Symmetrie und Zufallsgenerierung -[*] Modifiziere die Gegnerwellen +[*] Nützliches Generationssystem für Karten mit vielen verschiedenen Filtern für das Bearbeiten vom Terrain +[*] Verschönere die Landschaft mit Rauschen, Verzerrungen, Glätte, Erosion, Symmetrie, Erzgeneration und Zufallsgenerierung +[*] Lasse Erze, Flüsse und andere Ressourcen automatisch generieren +[*] Konfiguriere die Gegnerwellen [*] Teile deine Karten im Steam-Workshop +[*] Gib der Karte besondere Spielregeln [*] Nutze über 80 verschiedene Umgebungsblöcke -[/list] +[/list] \ No newline at end of file From aeddf7014c78062cdaac738441c3fa9b76e79e88 Mon Sep 17 00:00:00 2001 From: Arnyyx <74717260+Arnyyx@users.noreply.github.com> Date: Sat, 20 Feb 2021 06:32:52 +0700 Subject: [PATCH 315/426] Update bundle_vi.properties (#4724) --- core/assets/bundles/bundle_vi.properties | 134 +++++++++++------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/core/assets/bundles/bundle_vi.properties b/core/assets/bundles/bundle_vi.properties index cc33ff9bee..7f02eccd1a 100644 --- a/core/assets/bundles/bundle_vi.properties +++ b/core/assets/bundles/bundle_vi.properties @@ -40,24 +40,24 @@ be.ignore = Bỏ qua be.noupdates = Không tìm thấy bản cập nhật mới. be.check = Kiểm tra các bản cập nhật. -schematic = Schematic -schematic.add = Lưu Schematic... -schematics = Schematics -schematic.replace = Schematics có tên đó đã tồn tại. Thay thế nó? -schematic.exists = Schematics có tên đó đã tồn tại. -schematic.import = Nhập Schematic... +schematic = Bản thiết kế +schematic.add = Lưu bản thiết kế... +schematics = Các bản thiết kế +schematic.replace = Bản thiết kế có tên đó đã tồn tại. Thay thế nó? +schematic.exists = Bản thiết kế có tên đó đã tồn tại. +schematic.import = Nhập Bản thiết kế... schematic.exportfile = Xuất tệp schematic.importfile = Nhập tệp schematic.browseworkshop = Duyệt qua Workshop schematic.copy = Sao chép vào bộ nhớ tạm schematic.copy.import = Nhập từ bộ nhớ tạm schematic.shareworkshop = Chia sẻ từ Workshop -schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Lật Schematic -schematic.saved = Đã lưu Schematic. -schematic.delete.confirm = Schematic này sẽ bị xóa hoàn toàn. -schematic.rename = Đổi tên Schematic +schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Lật bản thiết kế +schematic.saved = Đã lưu bản thiết kế. +schematic.delete.confirm = Bản thiết kế này sẽ bị xóa hoàn toàn. +schematic.rename = Đổi tên bản thiết kế schematic.info = {0}x{1}, {2} khối -schematic.disabled = [scarlet]Tính năng Schematics đã bị tắt[]\nBạn không được sử dụng schematic trong [accent]bản đồ[] hoặc [accent]máy chủ. +schematic.disabled = [scarlet]Tính năng bản thiết kế đã bị tắt[]\nBạn không được sử dụng bản thiết kế trong [accent]bản đồ[] hoặc [accent]máy chủ. stats = Thống kê stat.wave = Đợt đã vượt qua:[accent] {0} @@ -76,7 +76,7 @@ level.select = Chọn cấp độ level.mode = Chế độ: coreattack = < Căn cứ đang bị tấn công! > nearpoint = [[ [scarlet]RỜI KHỎI ĐIỂM THẢ NGAY LẬP TỨC[] ]\nsự hủy diệt sắp xảy ra -database = Cơ sở dữ liệu căn cứ +database = Cơ sở dữ liệu savegame = Lưu trò chơi loadgame = Tải trò chơi joingame = Tham gia trò chơi @@ -700,11 +700,11 @@ stat.abilities = Khả năng stat.canboost = Nâng cấp stat.flying = Bay -ability.forcefield = Force Field -ability.repairfield = Repair Field +ability.forcefield = Tạo khiên +ability.repairfield = Sửa chữa/Xây dựng ability.statusfield = Status Field -ability.unitspawn = {0} Factory -ability.shieldregenfield = Shield Regen Field +ability.unitspawn = Sản xuất {0} +ability.shieldregenfield = Tạo khiên nhỏ ability.movelightning = Movement Lightning bar.drilltierreq = Cần máy khoan tốt hơn @@ -735,12 +735,12 @@ bullet.damage = [stat]{0}[lightgray] sát thương bullet.splashdamage = [stat]{0}[lightgray] sát thương diện rộng ~[stat] {1}[lightgray] ô bullet.incendiary = [stat]cháy bullet.sapping = [stat]sapping -bullet.homing = [stat]homing +bullet.homing = [stat]truy đuổi bullet.shock = [stat]sốc -bullet.frag = [stat]frag +bullet.frag = [stat]phá mảnh bullet.knockback = [stat]{0}[lightgray] bật lùi bullet.pierce = [stat]{0}[lightgray]x xuyên giáp -bullet.infinitepierce = [stat]pierce +bullet.infinitepierce = [stat]xuyên thấu bullet.healpercent = [stat]{0}[lightgray]% sửa chửa bullet.freezing = [stat]đóng băng bullet.tarred = [stat]tarred @@ -788,8 +788,8 @@ setting.antialias.name = Khử răng cưa[lightgray] (yêu cầu khởi động setting.playerindicators.name = Hướng người chơi setting.indicators.name = Hướng kẻ địch setting.autotarget.name = Tự động nhắm mục tiêu -setting.keyboard.name = Điều khiển bằng chuột+bàn phím -setting.touchscreen.name = Điều khiển bằng màng hình cảm ứng +setting.keyboard.name = Điều khiển bằng chuột + bàn phím +setting.touchscreen.name = Điều khiển bằng màn hình cảm ứng setting.fpscap.name = FPS tối đa setting.fpscap.none = Không giới hạn setting.fpscap.text = {0} FPS @@ -810,13 +810,13 @@ setting.sensitivity.name = Độ nhạy điều khiển setting.saveinterval.name = Khoảng thời gian lưu setting.seconds = {0} giây setting.milliseconds = {0} mili giây -setting.fullscreen.name = Toàn màng hình +setting.fullscreen.name = Toàn màn hình setting.borderlesswindow.name = Không viền[lightgray] (yêu cầu khởi động lại) setting.fps.name = Hiển thị FPS & Ping setting.smoothcamera.name = Chế độ mượt mà setting.vsync.name = VSync setting.pixelate.name = Đồ họa pixel -setting.minimap.name = Hiển thị bảng đồ mini +setting.minimap.name = Hiển thị bản đồ mini setting.coreitems.name = Hiển thị vật phẩm trong căn cứ setting.position.name = Hiển thị vị trí người chơi setting.musicvol.name = Âm lượng nhạc @@ -855,17 +855,17 @@ keybind.clear_building.name = Xóa công trình keybind.press = Nhấn một phím... keybind.press.axis = Nhấn một tổ hợp phím hoặc một phím... keybind.screenshot.name = Chụp ảnh bản đồ -keybind.toggle_power_lines.name = Toggle Power Lasers -keybind.toggle_block_status.name = Toggle Block Statuses +keybind.toggle_power_lines.name = Ẩn/Hiện đường truyền năng lượng +keybind.toggle_block_status.name = Ẩn/Hiện trạng thái khối keybind.move_x.name = Di chuyển X keybind.move_y.name = Di chuyển Y keybind.mouse_move.name = Theo chuột -keybind.pan.name = Xem Pan +keybind.pan.name = Di chuyển góc nhìn keybind.boost.name = Tăng tốc keybind.schematic_select.name = Chọn khu vực -keybind.schematic_menu.name = Menu Schematic -keybind.schematic_flip_x.name = Lật Schematic X -keybind.schematic_flip_y.name = Lật Schematic Y +keybind.schematic_menu.name = Menu bản thiết kế +keybind.schematic_flip_x.name = Lật bản thiết kế X +keybind.schematic_flip_y.name = Lật bản thiết kế Y keybind.category_prev.name = Danh mục trước keybind.category_next.name = Danh mục tiếp theo keybind.block_select_left.name = Chọn khối trái @@ -903,8 +903,8 @@ keybind.chat.name = Trò chuyện keybind.player_list.name = Danh sách người chơi keybind.console.name = Bảng điều khiển keybind.rotate.name = Xoay -keybind.rotateplaced.name = Xoay hiện có (Giữ) -keybind.toggle_menus.name = Chuyển đổi Menus +keybind.rotateplaced.name = Xoay khối (Giữ) +keybind.toggle_menus.name = Ẩn/Hiện Menus keybind.chat_history_prev.name = Lịch sử trò chuyện trước keybind.chat_history_next.name = Lịch sử trò chuyện sau keybind.chat_scroll.name = Cuộn trò chuyện @@ -924,7 +924,7 @@ mode.custom = Tùy chỉnh luật rules.infiniteresources = Tài nguyên vô hạn rules.reactorexplosions = Nổ lò phản ứng -rules.schematic = Cho phép dùng schematic +rules.schematic = Cho phép dùng bản thiết kế rules.wavetimer = Đếm ngược đợt rules.waves = Đợt rules.attack = Chế độ tấn công @@ -977,7 +977,7 @@ item.surge-alloy.name = Hợp kim item.spore-pod.name = Vỏ bào tử item.sand.name = Cát item.blast-compound.name = Chất nổ -item.pyratite.name = Tiền chất nổ +item.pyratite.name = Nhiệt thạch item.metaglass.name = Thuỷ tinh item.scrap.name = Phế liệu liquid.water.name = Nước @@ -1044,7 +1044,7 @@ block.moss.name = Rêu block.shrubs.name = Bụi cây block.spore-moss.name = Rêu bào tử block.shale-wall.name = Tường đá phiến sét -block.scrap-wall.name = Tường sắt vụn +block.scrap-wall.name = Tường phế liệu block.scrap-wall-large.name = Tường phế liệu lớn block.scrap-wall-huge.name = Tường phế liệu khổng lồ block.scrap-wall-gigantic.name = Tường phế liệu siêu khổng lồ @@ -1105,8 +1105,8 @@ block.copper-wall.name = Tường đồng block.copper-wall-large.name = Tường đồng lớn block.titanium-wall.name = Tường titan block.titanium-wall-large.name = Tường titan lớn -block.plastanium-wall.name = Tường Plastanium -block.plastanium-wall-large.name = Tường Plastanium lớn +block.plastanium-wall.name = Tường Nhựa +block.plastanium-wall-large.name = Tường Nhựa lớn block.phase-wall.name = Tường Phase block.phase-wall-large.name = Tường Phase lớn block.thorium-wall.name = Tường Thorium @@ -1122,9 +1122,9 @@ block.conveyor.name = Băng chuyền block.titanium-conveyor.name = Băng chuyền titan block.plastanium-conveyor.name = Băng chuyền nhựa block.armored-conveyor.name = Băng chuyền bọc giáp -block.junction.name = Junction -block.router.name = Bộ định tuyến -block.distributor.name = Bộ phân phát +block.junction.name = Giao điểm +block.router.name = Bộ phân phát +block.distributor.name = Bộ phân phát lớn block.sorter.name = Bộ lọc block.inverted-sorter.name = Bộ lọc ngược block.message.name = Thông điệp @@ -1134,8 +1134,8 @@ block.underflow-gate.name = Cổng tràn ngược block.silicon-smelter.name = Máy nấu silicon block.phase-weaver.name = Máy tạo Phase block.pulverizer.name = Máy nghiền -block.cryofluid-mixer.name = Máy sản xuất chất làm mát -block.melter.name = Máy nung chảy +block.cryofluid-mixer.name = Máy sản xuất chất làm lạnh +block.melter.name = Lò nung chảy block.incinerator.name = Máy phân hủy block.spore-press.name = Máy nén bào tử block.separator.name = Máy phân tách @@ -1171,9 +1171,9 @@ block.swarmer.name = Swarmer block.salvo.name = Salvo block.ripple.name = Ripple block.phase-conveyor.name = Phase Conveyor -block.bridge-conveyor.name = Bridge Conveyor +block.bridge-conveyor.name = Cầu dẫn block.plastanium-compressor.name = Máy sản xuất nhựa -block.pyratite-mixer.name = Máy trộn tiền chất nổ +block.pyratite-mixer.name = Máy trộn nhiệt thạch block.blast-mixer.name = Máy trộn chất nổ block.solar-panel.name = Pin mặt trời block.solar-panel-large.name = Pin mặt trời lớn @@ -1182,10 +1182,10 @@ block.repair-point.name = Điểm sửa chữa block.pulse-conduit.name = Ống dẫn titan block.plated-conduit.name = Ống dẫn bọc giáp block.phase-conduit.name = Ống dẫn Phase -block.liquid-router.name = Bộ định tuyến chất lỏng +block.liquid-router.name = Bộ phân phát chất lỏng block.liquid-tank.name = Thùng chất lỏng -block.liquid-junction.name = Liquid Junction -block.bridge-conduit.name = Bridge Conduit +block.liquid-junction.name = Giao điểm chất lỏng +block.bridge-conduit.name = Cầu dẫn chất lỏng block.rotary-pump.name = Bơm điện block.thorium-reactor.name = Lò phản ứng Thorium block.mass-driver.name = Máy phóng điện từ @@ -1227,11 +1227,11 @@ block.overdrive-dome.name = Máy tăng tốc lớn #experimental, may be removed block.block-forge.name = Block Forge block.block-loader.name = Block Loader -block.block-unloader.name = Block Unloader +block.block-unloader.name = Điểm dỡ hàng block.interplanetary-accelerator.name = Máy gia tốc liên hành tinh block.switch.name = Công tắc -block.micro-processor.name = Bộ xử lí mini +block.micro-processor.name = Bộ xử lí nhỏ block.logic-processor.name = Bộ xử lý block.hyper-processor.name = Bộ xử lý lớn block.logic-display.name = Màn hình @@ -1315,15 +1315,15 @@ block.armored-conveyor.description = Vận chuyển vật phẩm về phía. Kh block.illuminator.description = Phát sáng. block.message.description = Lưu trữ tin nhắn giao tiếp giữa đồng đội. block.graphite-press.description = Nén than thành than chì. -block.multi-press.description = Nén than thành than chì. Cần nước làm chất làm mát. +block.multi-press.description = Nén than thành than chì. Cần nước làm mát. block.silicon-smelter.description = Tinh chế silicon từ cát và than. block.kiln.description = Nấu chảy cát và chì thành thuỷ tinh. block.plastanium-compressor.description = Sản xuất nhựa từ dầu và titan. block.phase-weaver.description = Tổng hợp phase fabric từ thorium và cát. block.alloy-smelter.description = Trộn titan, chì, silicon và đồng thành hợp kim. block.cryofluid-mixer.description = Trộn nước và bột titan để sản xuất chất làm mát. -block.blast-mixer.description = Tạo ra hợp chất nổ từ tiền chất nổ và vỏ bào tử. -block.pyratite-mixer.description = Trộn than, chì và cát thành tiền chất nổ. +block.blast-mixer.description = Tạo ra hợp chất nổ từ nhiệt thạch và vỏ bào tử. +block.pyratite-mixer.description = Trộn than, chì và cát thành nhiệt thạch. block.melter.description = Nung phế liệu thành xỉ. block.separator.description = Tách xỉ thành các thành phần khoáng của nó. block.spore-press.description = Nén vỏ bào tử thành dầu. @@ -1389,7 +1389,7 @@ block.battery-large.description = Tích trữ năng lượng khi dư thừa. Xu block.combustion-generator.description = Tạo ra năng lượng bằng cách đốt các vật liệu dễ cháy như than. block.thermal-generator.description = Tạo ra năng lượng khi đặt ở những nơi nóng. block.steam-generator.description = Tạo ra năng lượng bằng cách đốt cháy các vật liệu dễ cháy và chuyển nước thành hơi nước. -block.differential-generator.description = Tạo ra một lượng lớn năng lượng. Sử dụng sự chênh lệch nhiệt độ giữa cryofluid và pyratite đang cháy. +block.differential-generator.description = Tạo ra một lượng lớn năng lượng. Sử dụng sự chênh lệch nhiệt độ giữa chất làm lạnh và nhiệt thạch đang cháy. block.rtg-generator.description = Sử dụng nhiệt của các hợp chất phóng xạ đang phân hủy để tạo ra năng lượng với tốc độ chậm. block.solar-panel.description = Cung cấp một lượng nhỏ năng lượng từ mặt trời. block.solar-panel-large.description = Cung cấp một lượng nhỏ năng lượng từ mặt trời. Hiệu quả hơn pin mặt trời tiêu chuẩn. @@ -1405,10 +1405,10 @@ block.cultivator.details = Công nghệ được phục hồi. Được sử d block.oil-extractor.description = Sử dụng lượng năng lượng năng lớn, sử dụng cát và nước để khoan dầu. block.core-shard.description = Trung tâm của căn cứ. Sau khi bị phá hủy, khu vực này sẽ bị mất. block.core-shard.details = Lần thử đầu tiên. Gọn nhẹ. Tự thay thế. Được trang bị tên lửa đẩy dùng một lần. Không được thiết kế để di chuyển giữa các hành tinh. -block.core-foundation.description = Trung tâm của căn cứ. Được bọc giáp. Stores more resources than a Shard. -block.core-foundation.details = The second iteration. +block.core-foundation.description = Trung tâm của căn cứ. Được bọc giáp. Chứa được nhiều tài nguyên hơn Căn cứ: Cơ sỏ. +block.core-foundation.details = Căn cứ cấp 2. block.core-nucleus.description = Lõi của căn cứ. Bọc giáp chắc chắn. Lưu trữ lượng lớn tài nguyên. -block.core-nucleus.details = Lần thử thứ ba và lần thử cuối. +block.core-nucleus.details = Căn cứ cấp 3 và cũng là cấp cao nhất. block.vault.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng. block.container.description = Lưu trữ lượng lớn vật phẩm mỗi loại. Nội dung có thể được lấy ra với điểm dỡ hàng. block.unloader.description = Lấy các vật phẩm được chọn từ các ô gần đó. @@ -1421,17 +1421,17 @@ block.wave.description = Phóng một tia chất lỏng vào kẻ địch. Tự block.lancer.description = Tích tụ và phóng tia năng lượng mạnh vào kẻ địch trên mặt đất. block.arc.description = Phóng tia điện vào kẻ địch trên mặt đất. block.swarmer.description = Bắn tên lửa truy đuổi vào kẻ địch. -block.salvo.description = Bắn đạn salvo vào kẻ địch. +block.salvo.description = Bắn loạt đạn vào kẻ địch. block.fuse.description = Bắn ba đạn xuyên giáp tầm gần vào kẻ địch. block.ripple.description = Bắn cụm đạn vào kẻ địch trên mặt đất ở tầm xa. block.cyclone.description = Bắn đạn nổ vào kẻ địch ở gần. block.spectre.description = Bắn đạn xuyên giáp lớn ở kẻ địch trên không và trên mặt đất. block.meltdown.description = Nạp và bắn một tia laser liên tục vào kẻ địch ở gần. Cần có chất làm mát để hoạt động. block.foreshadow.description = Bắn viên một viên đạn tỉa lớn ở tầm xa. -block.repair-point.description = Liên tục sửa chữa robot ở gần trong phạm vi hoạt động. +block.repair-point.description = Liên tục sửa chữa robot ở trong phạm vi hoạt động. block.segment.description = Gây hư hại và phá hủy đạn đến. Ngoại trừ tia laser. block.parallax.description = Bắn một tia kéo máy bay địch và làm hư hỏng nó trong quá trình kéo. -block.tsunami.description = Phóng một tia chất lỏng mạnh vào kẻ địch. Tự chữa cháy nếu được cung cấp nước. +block.tsunami.description = Phóng một tia chất lỏng mạnh vào kẻ địch. Tự chữa cháy nếu được cung cấp nước hoặc chất làm mát. block.silicon-crucible.description = Tinh chế silicon từ cát và than, sử dụng tiền chất nổ làm nguồn nhiệt phụ. Có hiệu quả cao hơn khi ở nơi nóng. block.disassembler.description = Tách xỉ thành các kim loại khác nhau với hiệu suất thấp. Có thể sản xuất thorium. block.overdrive-dome.description = Tăng tốc độ làm việc của các công trình lân cận. Sử dụng phase fabric and silicon để hoạt động. @@ -1447,12 +1447,12 @@ block.exponential-reconstructor.description = Nâng cấp quân của bạn lên block.tetrative-reconstructor.description = Nâng cấp quân của bạn nên cấp năm (cuối cùng). block.switch.description = Công tắc, trạng thái có thể được đọc và điều khiển với vi xử lí logic. block.micro-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. -block.logic-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn vi xử lí micro. -block.hyper-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn vi xử lí logic. -block.memory-cell.description = Lưu trữ thông tin cho bộ xử lí logic. -block.memory-bank.description = Lưu trữ thông tin cho bộ xử lí logic. Dung lượng cao. -block.logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí logic. -block.large-logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí logic. +block.logic-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn bộ xử lí nhỏ. +block.hyper-processor.description = Chạy tập hợp các chỉ dẫn trong một vòng lặp, có thể dùng để điều khiển robot và công trình. Nhanh hơn bộ xử lí. +block.memory-cell.description = Lưu trữ thông tin cho bộ xử lí. +block.memory-bank.description = Lưu trữ thông tin cho bộ xử lí. Dung lượng cao. +block.logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí. +block.large-logic-display.description = Hiển thị đồ họa tùy ý từ bộ xử lí. block.interplanetary-accelerator.description = Tòa súng từ trường cỡ lớn. Tăng tốc vật phóng đến vận tốc thoát để di chuyển giữa các hành tinh. unit.dagger.description = Bắn đạn tiêu chuẩn vào tất cả kẻ địch xung quanh. @@ -1466,7 +1466,7 @@ unit.quasar.description = Bắn tia laser xuyên giáp làm tổn hại kẻ đ unit.vela.description = Bắn tia laser liên tục xuyên giáp làm tổn hại kẻ địch, gây cháy và sửa chữa các tòa nhà. Có khả năng bay. unit.corvus.description = Bắn đia laser đánh bật kẻ địch và sửa chữa các tòa nhà. Có thể đi qua đa số địa hình. unit.crawler.description = Chạy đến kẻ địch và nổ. -unit.atrax.description = Bắn cục xỉ vào kẻ địch trên mặt đất. Có thể đi qua đa số địa hình. +unit.atrax.description = Phun xỉ nóng chảy vào kẻ địch trên mặt đất. Có thể đi qua đa số địa hình. unit.spiroct.description = Bắn tia laser vào kẻ địch trên mặt đất và tự sửa chữa nó. Có thể đi qua đa số địa hình. unit.arkyid.description = Bắn tia laser lớn vào kẻ địch trên mặt đất và tự sửa chữa chính nó. Có thể đi qua đa số địa hình. unit.toxopid.description = Bắn chùm đạn điện và tia laser xuyên giáp vào kẻ địch trên mặt đất và tự sửa chữa chính nó. Có thể đi qua đa số địa hình. @@ -1479,12 +1479,12 @@ unit.mono.description = Tự động khai thác đồng và chì, và vận chuy unit.poly.description = Tự động xây dựng lại các công trình bị hỏng và hỗ trợ các quân lính khác thi công. unit.mega.description = Tự động sửa chữa các công trình bị hỏng. Có khả năng mang bộ binh nhỏ. unit.quad.description = Thả bom to lên kẻ địch, sửa chữa các tòa nhà và tổn hại kẻ địch. Có khả năng mang bộ binh vừa. -unit.oct.description = Bảo vệ đồng minh với giáp. Có kả năng mang đa số bộ binh. +unit.oct.description = Bảo vệ đồng minh với giáp. Có khả năng mang đa số bộ binh. unit.risso.description = Bắn chùm tên lửa và đạn lên kẻ địch tầm gần. unit.minke.description = Bắn đạn và đạn thường lên kẻ địch tầm gần trên mặt đất. unit.bryde.description = Bắn đạn tầm xa và tên lửa vào kẻ địch. unit.sei.description = Bắn chùm tên lửa và đạn xuyên giáp vào kẻ địch. -unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào kẻ địch. Tạo nên drone báo hiệu. +unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào kẻ địch. Tạo nên Flare. unit.alpha.description = Bảo vệ căn cứ cơ sở khỏi kẻ thù. Có thể xây dựng. unit.beta.description = Bảo vệ căn cứ trụ sở khỏi kẻ thù. Có thể xây dựng. unit.gamma.description = Bảo vệ căn cứ trung tâm khỏi kẻ thù. Có thể xây dựng. From e6513702d63db112b99aa99a148d42fd96ced301 Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Sat, 20 Feb 2021 02:33:43 +0300 Subject: [PATCH 316/426] [Bundle][RU] actual L10n (#4726) * 3 new, 1 deleted New: rules.unitcapvariable rules.unitcap laccess.color Deleted: lenum.color * 1 line changed rules.unitcap Co-authored-by: Vanguard <55051135+XEN0PHIL@users.noreply.github.com> --- core/assets/bundles/bundle_ru.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 59cc1caa92..e83cd3535c 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -957,6 +957,8 @@ rules.blockdamagemultiplier = Множитель урона блоков rules.unitbuildspeedmultiplier = Множитель скорости производства боев. ед. rules.unithealthmultiplier = Множитель здоровья боев. ед. rules.unitdamagemultiplier = Множитель урона боев. ед. +rules.unitcapvariable = Ядра увеличивают лимит единиц +rules.unitcap = Начальный лимит единиц rules.enemycorebuildradius = Радиус защиты враж. ядер:[lightgray] (блок.) rules.wavespacing = Интервал волн:[lightgray] (сек) rules.buildcostmultiplier = Множитель затрат на строительство @@ -1539,7 +1541,8 @@ lenum.shoot = Стрельба в определённую позицию. lenum.shootp = Стрельба в единицу/постройку с расчётом скорости. lenum.configure = Конфигурация постройки, например, предмет сортировки. lenum.enabled = Включён ли блок. -lenum.color = Цвет осветителя. + +laccess.color = Цвет осветителя. lenum.always = Всегда истина. lenum.idiv = Целочисленное деление. From f78719afc0e9799a385fde2db9ec4650f3f3fb39 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 19:10:27 -0500 Subject: [PATCH 317/426] Fixed mod crash disable setting name --- core/assets/bundles/bundle.properties | 2 +- fastlane/metadata/android/en-US/changelogs/29821.txt | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/29821.txt diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 8f22aab6cd..6e0a662482 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -800,7 +800,7 @@ setting.logichints.name = Logic Hints setting.flow.name = Display Resource Flow Rate setting.backgroundpause.name = Pause In Background setting.buildautopause.name = Auto-Pause Building -setting.modcrashdisable = Disable Mods On Startup Crash +setting.modcrashdisable.name = Disable Mods On Startup Crash setting.animatedwater.name = Animated Surfaces setting.animatedshields.name = Animated Shields setting.antialias.name = Antialias[lightgray] (requires restart)[] diff --git a/fastlane/metadata/android/en-US/changelogs/29821.txt b/fastlane/metadata/android/en-US/changelogs/29821.txt new file mode 100644 index 0000000000..eab2c7b50d --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29821.txt @@ -0,0 +1,7 @@ +[This is a truncated changelog, see Github for full notes] +This is a minor update that reduces building splash damage for certain projectiles and fixes various mods issues. +While build 125 servers should be compatible with 125.1 clients, updating is still recommended. + +- Fixed player health bar glitching out at negative health +- Fixed large power nodes sometimes not connecting to placed blocks +- Made unit payloads draw with correct cell colors From 467402ef7311da257e6a7dbe5f9b720b1cdc559a Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 19:20:04 -0500 Subject: [PATCH 318/426] Various fixes --- core/assets/bundles/bundle_ro.properties | 2 +- core/src/mindustry/mod/ClassMap.java | 7 +++++++ core/src/mindustry/mod/ContentParser.java | 2 +- tools/src/mindustry/tools/ScriptMainGenerator.java | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index 0ce1983a4f..d8372d10eb 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -800,7 +800,7 @@ setting.logichints.name = Indicii Procesoare Logice setting.flow.name = Afișează Rata de Curgere a lichidelor setting.buildautopause.name = Autopauză de la Construit setting.backgroundpause.name = Pune Pauză în Fundal -setting.modcrashdisable = Dezactivează Modurile în Cazul unui Crash la Pornire +setting.modcrashdisable.name = Dezactivează Modurile în Cazul unui Crash la Pornire setting.animatedwater.name = Suprafețe Animate setting.animatedshields.name = Scuturi Animate setting.antialias.name = Antialiasing[lightgray] (necesită repornire)[] diff --git a/core/src/mindustry/mod/ClassMap.java b/core/src/mindustry/mod/ClassMap.java index 5d650511fb..af000c2f96 100644 --- a/core/src/mindustry/mod/ClassMap.java +++ b/core/src/mindustry/mod/ClassMap.java @@ -14,6 +14,13 @@ public class ClassMap{ classes.put("MinerAI", mindustry.ai.types.MinerAI.class); classes.put("RepairAI", mindustry.ai.types.RepairAI.class); classes.put("SuicideAI", mindustry.ai.types.SuicideAI.class); + classes.put("Ability", mindustry.entities.abilities.Ability.class); + classes.put("ForceFieldAbility", mindustry.entities.abilities.ForceFieldAbility.class); + classes.put("MoveLightningAbility", mindustry.entities.abilities.MoveLightningAbility.class); + classes.put("RepairFieldAbility", mindustry.entities.abilities.RepairFieldAbility.class); + classes.put("ShieldRegenFieldAbility", mindustry.entities.abilities.ShieldRegenFieldAbility.class); + classes.put("StatusFieldAbility", mindustry.entities.abilities.StatusFieldAbility.class); + classes.put("UnitSpawnAbility", mindustry.entities.abilities.UnitSpawnAbility.class); classes.put("ArtilleryBulletType", mindustry.entities.bullet.ArtilleryBulletType.class); classes.put("BasicBulletType", mindustry.entities.bullet.BasicBulletType.class); classes.put("BombBulletType", mindustry.entities.bullet.BombBulletType.class); diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 818d518963..0531fe4eb6 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -211,7 +211,7 @@ public class ContentParser{ throw new IllegalArgumentException("When defining properties for an existing block, you must not re-declare its type. The original type will be used. Block: " + name); } }else{ - block = make(resolve(getType(value), Block.class), mod + "-" + name); + block = make(resolve(value.getString("type", ""), Block.class), mod + "-" + name); } currentContent = block; diff --git a/tools/src/mindustry/tools/ScriptMainGenerator.java b/tools/src/mindustry/tools/ScriptMainGenerator.java index 845d056f9a..0406783661 100644 --- a/tools/src/mindustry/tools/ScriptMainGenerator.java +++ b/tools/src/mindustry/tools/ScriptMainGenerator.java @@ -76,6 +76,7 @@ public class ScriptMainGenerator{ Seq packages = Seq.with( "mindustry.entities.effect", "mindustry.entities.bullet", + "mindustry.entities.abilities", "mindustry.ai.types", "mindustry.type.weather", "mindustry.game.Objectives", From 158e23bd5efd9c239a917c28d2974e05ec4a96f6 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 19 Feb 2021 19:43:37 -0500 Subject: [PATCH 319/426] Steam icon changes --- core/src/mindustry/ui/dialogs/ModsDialog.java | 2 +- core/src/mindustry/ui/fragments/MenuFragment.java | 2 +- .../metadata/android/en-US/changelogs/{29821.txt => 29825.txt} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename fastlane/metadata/android/en-US/changelogs/{29821.txt => 29825.txt} (100%) diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index bd3f63bf03..cbb57b6d3f 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -304,7 +304,7 @@ public class ModsDialog extends BaseDialog{ if(steam && !mod.hasSteamID()){ right.row(); - right.button(Icon.download, Styles.clearTransi, () -> { + right.button(Icon.export, Styles.clearTransi, () -> { platform.publish(mod); }).size(50f); } diff --git a/core/src/mindustry/ui/fragments/MenuFragment.java b/core/src/mindustry/ui/fragments/MenuFragment.java index d536ae1c00..cef8b0108e 100644 --- a/core/src/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/mindustry/ui/fragments/MenuFragment.java @@ -171,7 +171,7 @@ public class MenuFragment extends Fragment{ new Buttoni("@customgame", Icon.terrain, () -> checkPlay(ui.custom::show)), new Buttoni("@loadgame", Icon.download, () -> checkPlay(ui.load::show)) ), - new Buttoni("@editor", Icon.terrain, () -> checkPlay(ui.maps::show)), steam ? new Buttoni("@workshop", Icon.book, platform::openWorkshop) : null, + new Buttoni("@editor", Icon.terrain, () -> checkPlay(ui.maps::show)), steam ? new Buttoni("@workshop", Icon.steam, platform::openWorkshop) : null, new Buttoni("@mods", Icon.book, ui.mods::show), //not enough space for this button //new Buttoni("@schematics", Icon.paste, ui.schematics::show), diff --git a/fastlane/metadata/android/en-US/changelogs/29821.txt b/fastlane/metadata/android/en-US/changelogs/29825.txt similarity index 100% rename from fastlane/metadata/android/en-US/changelogs/29821.txt rename to fastlane/metadata/android/en-US/changelogs/29825.txt From 2df2a0971ad7b222d1b95e537f3bc343ce67e24f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 20 Feb 2021 09:49:49 -0500 Subject: [PATCH 320/426] arc --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a787392872..7ecfa9aaf8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=a9c305d4f920e46a7b92c3fedc8f76d9c2fb38de +archash=1d7c415cd528ee0148fa2f498fcb1ec563528825 From a2e075ee54df1a3ab26723e86e8edbb1d22f1091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ng=E1=BB=8Dc=20Lam?= <33188123+NgLamVN@users.noreply.github.com> Date: Sat, 20 Feb 2021 22:07:19 +0700 Subject: [PATCH 321/426] Update Vietnamese Translation. (#4660) * Update translation, fix some typo * About 150 lines to do left. * Typos fix #_1 * Typos fix + add trans * Update to lastest commit. * Base logic translation. * a lot of typo ... * some update from main bundle. * Add more logic hint. --- core/assets/bundles/bundle_vi.properties | 226 ++++++++++++++++++++--- 1 file changed, 196 insertions(+), 30 deletions(-) diff --git a/core/assets/bundles/bundle_vi.properties b/core/assets/bundles/bundle_vi.properties index 7f02eccd1a..aae2419fc1 100644 --- a/core/assets/bundles/bundle_vi.properties +++ b/core/assets/bundles/bundle_vi.properties @@ -13,6 +13,7 @@ link.google-play.description = Google Play store listing link.f-droid.description = F-Droid listing link.wiki.description = Mindustry wiki chính thức link.suggestions.description = Đề xuất các tính năng mới +link.bug.description = Tìm thấy lỗi? Báo cáo nó ở đây linkfail = Không mở được liên kết!\nURL đã được sao chép vào bộ nhớ tạm. screenshot = Ảnh chụp màn hình được lưu vào {0} screenshot.invalid = Bản đồ quá lớn, có khả năng không đủ bộ nhớ để chụp ảnh màn hình. @@ -40,6 +41,14 @@ be.ignore = Bỏ qua be.noupdates = Không tìm thấy bản cập nhật mới. be.check = Kiểm tra các bản cập nhật. +mods.browser = Duyệt mod +mods.browser.selected = Mod Đã chọn +mods.browser.add = Cài đặt +mods.browser.reinstall = Cài đặt lại +mods.github.open = Repo +mods.browser.sortdate = Sắp xếp theo gần đây +mods.browser.sortstars = Sắp xếp theo sao + schematic = Bản thiết kế schematic.add = Lưu bản thiết kế... schematics = Các bản thiết kế @@ -50,7 +59,7 @@ schematic.exportfile = Xuất tệp schematic.importfile = Nhập tệp schematic.browseworkshop = Duyệt qua Workshop schematic.copy = Sao chép vào bộ nhớ tạm -schematic.copy.import = Nhập từ bộ nhớ tạm +schematic.copy.import = Thêm từ bộ nhớ tạm schematic.shareworkshop = Chia sẻ từ Workshop schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Lật bản thiết kế schematic.saved = Đã lưu bản thiết kế. @@ -75,14 +84,15 @@ level.highscore = Điểm cao nhất: [accent]{0} level.select = Chọn cấp độ level.mode = Chế độ: coreattack = < Căn cứ đang bị tấn công! > -nearpoint = [[ [scarlet]RỜI KHỎI ĐIỂM THẢ NGAY LẬP TỨC[] ]\nsự hủy diệt sắp xảy ra +nearpoint = [[ [scarlet]RỜI KHỎI KHU VỰC ĐÁP NGAY LẬP TỨC[] ]\nsự hủy diệt sắp xảy ra database = Cơ sở dữ liệu savegame = Lưu trò chơi -loadgame = Tải trò chơi +loadgame = Tải lại màn chơi joingame = Tham gia trò chơi customgame = Tùy chỉnh newgame = Trò chơi mới none = +none.found = [lightgray] minimap = Bản đồ nhỏ position = Vị trí close = Đóng @@ -90,9 +100,9 @@ website = Website quit = Thoát save.quit = Lưu & Thoát maps = Bản đồ -maps.browse = Duyệt bản đồ +maps.browse = Chọn bản đồ continue = Tiếp tục -maps.none = [lightgray]Không có bản đồ nào được tìm thấy! +maps.none = [lightgray]Không tìm thấy bản đồ! invalid = Không hợp lệ pickcolor = Chọn màu preparingconfig = Đang chuẩn bị cấu hình @@ -103,14 +113,16 @@ committingchanges = Đang cập nhật các thay đổi done = Hoàn tất feature.unsupported = Thiết bị của bạn không hỗ trợ tính năng này. -mods.alphainfo = Hãy nhớ rằng các bản mod đang ở giai đoạn alpha, và[scarlet] có thể chứa rất rất lỗi[].\nBáo cáo bất kỳ vấn đề nào bạn gặp phải tại Mindustry GitHub. +mods.initfailed = [red]⚠[] Mindustry không khởi chạy được. Điều này có thể do các mod bị lỗi.\n\nĐể tránh gặp sự cố liên tiếp, [red]tất cả các mod đã bị tắt.[]\n\nĐể tắt tính năng này, vào [accent]Cài đặt->Trò chơi->Tắt các mod khi gặp sự cố trong khởi động[]. mods = Mods -mods.none = [lightgray]Không có mod nào được tìm thấy! +mods.none = [lightgray]Không tìm thấy mod! mods.guide = Hướng dẫn mod mods.report = Báo lỗi mods.openfolder = Mở thư mục +mods.viewcontent = Xem nội dung mods.reload = Tải lại -mods.reloadexit = Trò chơi sẽ đóng để tải lại mod. +mods.reloadexit = Trò chơi sẽ đóng để mod được tải. +mod.installed = [[Đã cài đặt] mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Đã Bật mod.disabled = [scarlet]Đã Tắt @@ -122,21 +134,21 @@ mod.outdated = [scarlet]Không tương thích với V6 (no minGameVersion: 105) mod.missingdependencies = [scarlet]Thiếu phụ thuộc: {0} mod.erroredcontent = [scarlet]Lỗi nội dung mod.errors = Đã xảy ra lỗi khi tải nội dung. -mod.noerrorplay = [scarlet]Bạn có mod bị lỗi.[]Tắt các mod bị ảnh hưởng hoặc sửa chữa các lỗi trước khi chơi. +mod.noerrorplay = [scarlet]Bạn có mod bị lỗi.[]Tắt các mod bị lỗi hoặc sửa các lỗi trước khi chơi. mod.nowdisabled = [scarlet]Mod '{0}' cần mod này để chạy:[accent] {1}\n[lightgray]Trước tiên bạn cần tải các mod này xuống.\nBản mod này sẽ tự động tắt. mod.enable = Bật mod.requiresrestart = Trò chơi sẽ đóng để áp dụng các thay đổi của mod. mod.reloadrequired = [scarlet]Yêu cầu khởi động lại -mod.import = Nhập Mod -mod.import.file = Nhập tệp -mod.import.github = Nhập từ GitHub -mod.jarwarn = [scarlet]JAR mod vốn dĩ không an toàn.[]\nĐảm bảo rằng bạn đang nhập bản mod này từ một nguồn đáng tin cậy! +mod.import = Thêm Mod +mod.import.file = Thêm từ tệp +mod.import.github = Thêm từ GitHub +mod.jarwarn = [scarlet]Các JAR mod vốn dĩ không an toàn.[]\nĐảm bảo rằng bạn đang thêm mod này từ một nguồn đáng tin cậy! mod.item.remove = Mục này là một phần của[accent] '{0}'[] mod. Để xóa nó, hãy gỡ cài đặt mod này. mod.remove.confirm = Mod này sẽ bị xóa. mod.author = [lightgray]Tác giả:[] {0} -mod.missing = Bản lưu này chứa các mod mà bạn đã cập nhật gần đây hoặc không còn cài đặt nữa. Có thể gây ra lỗi khi mở. Bạn có chắc muốn mở nó?\n[lightgray]Mods:\n{0} -mod.preview.missing = Trước khi xuất bản bản mod này lên workshop, bạn phải thêm hình ảnh xem trước.\nĐặt một hình ảnh có tên[accent] preview.png[] vào thư mục của mod và thử lại. -mod.folder.missing = Chỉ có thể xuất bản các mod ở dạng thư mục lên workshop.\nĐể chuyển đổi bất kỳ mod nào thành một thư mục, chỉ cần giải nén tệp của nó vào một thư mục và xóa tệp nén cũ, sau đó khởi động lại trò chơi của bạn hoặc tải lại các bản mod của bạn. +mod.missing = Bản lưu này chứa các mod mà bạn đã cập nhật gần đây hoặc không được cài đặt. Có thể gây ra lỗi khi mở. Bạn có chắc muốn mở nó?\n[lightgray]Mods:\n{0} +mod.preview.missing = Trước khi đăng bản mod này lên workshop, bạn phải thêm hình ảnh xem trước.\nĐặt một hình ảnh có tên[accent] preview.png[] vào thư mục của mod và thử lại. +mod.folder.missing = Chỉ có thể đăng các mod ở dạng thư mục lên workshop.\nĐể chuyển đổi bất kỳ mod nào thành một thư mục, chỉ cần giải nén tệp của nó vào một thư mục và xóa tệp nén cũ, sau đó khởi động lại trò chơi của bạn hoặc tải lại các bản mod của bạn. mod.scripts.disable = Thiết bị của bạn không hổ trợ mod chứa scripts này. Bạn phải tắt các mod này để chơi trò chơi. about.button = Thông tin @@ -196,6 +208,7 @@ servers.local = Máy chủ cục bộ servers.remote = Máy chủ tùy chỉnh servers.global = Máy chủ từ cộng đồng +servers.disclaimer = Nhà phát triển [accent]không[] sở hữu và kiểm soát máy chủ cộng đồng.\n\nMáy chủ có thể chứa nội dung do người dùng tạo và không phù hợp với mọi lứa tuổi. servers.showhidden = Hiển thị Máy chủ Ẩn server.shown = Hiện server.hidden = Ẩn @@ -279,6 +292,7 @@ cancel = Hủy openlink = Mở link copylink = Sao chép link back = Quay lại +max = Tối đa crash.export = Xuất Crash Logs crash.none = Không có Crash Logs nào được tìm thấy. crash.exported = Crash logs đã được xuất. @@ -298,6 +312,7 @@ cancelbuilding = [accent][[{0}][] để hủy xây selectschematic = [accent][[{0}][] to để chọn+sao chép pausebuilding = [accent][[{0}][] để tạm dừng xây dựng resumebuilding = [scarlet][[{0}][] để tiếp tục xây dựng +enablebuilding = [scarlet][[{0}][] để bật xây dựng showui = UI hidden.\nPress [accent][[{0}][] để hiện UI. wave = [accent]Đợt {0} wave.cap = [accent]Đợt {0}/{1} @@ -353,7 +368,6 @@ editor.center = Trung tâm workshop = Workshop waves.title = Đợt waves.remove = Xóa -waves.never = waves.every = mỗi waves.waves = đợt waves.perspawn = mỗi lần xuất hiện @@ -382,7 +396,7 @@ editor.removeunit = Xóa kẻ địch editor.teams = Đội editor.errorload = Lỗi khi tải tệp. editor.errorsave = Lỗi khi lưu tệp. -editor.errorimage = Đó là một hình ảnh, không phải bản đồ.\n\nNếu bạn muốn nhập một bản đồ 3.5/build 40, sử dụng nút 'Nhập bản đồ thay thế' trong trình chỉnh sửa. +editor.errorimage = Đó là một hình ảnh, không phải bản đồ. editor.errorlegacy = Bản đồ này quá cũ, và sử dụng định dạng bản đồ cũ không còn được hỗ trợ. editor.errornot = Đây không phải là tệp bản đồ. editor.errorheader = Tệp bản đồ này không hợp lệ hoặc bị hỏng. @@ -672,9 +686,10 @@ stat.drillspeed = Tốc độ khoang cơ bản stat.boosteffect = Hiệu ứng tăng cường stat.maxunits = Số quân lính hoạt động tối đa stat.health = Độ bền +stat.armor = Giáp stat.buildtime = Thời gian xây stat.maxconsecutive = Đầu ra tối đa -stat.buildcost = Chi phí +stat.buildcost = Yêu cầu stat.inaccuracy = Độ lệch stat.shots = Phát bắn stat.reload = Phát bắn/Giây @@ -687,6 +702,7 @@ stat.lightningchance = Tỷ lệ phóng điện stat.lightningdamage = Sát thương tia điện stat.flammability = Dễ cháy stat.radioactivity = Phóng xạ +stat.charge = Phóng điện stat.heatcapacity = Nhiệt dung stat.viscosity = Độ nhớt stat.temperature = Nhiệt độ @@ -699,6 +715,7 @@ stat.commandlimit = Giới hạn lệnh stat.abilities = Khả năng stat.canboost = Nâng cấp stat.flying = Bay +stat.ammouse = Sử dụng đạn ability.forcefield = Tạo khiên ability.repairfield = Sửa chữa/Xây dựng @@ -713,6 +730,7 @@ bar.corereq = Yêu cầu căn cứ bar.drillspeed = Tốc độ khoan: {0}/giây bar.pumpspeed = Tốc độ bơm: {0}/giây bar.efficiency = Hiệu suất: {0}% +bar.boost = Tăng tốc: {0}% bar.powerbalance = Năng lượng: {0}/giây bar.powerstored = Lưu trữ: {0}/{1} bar.poweramount = Năng lượng: {0} @@ -721,7 +739,6 @@ bar.powerlines = Số lượng kết nối: {0}/{1} bar.items = Vật phẩm: {0} bar.capacity = Sức chứa: {0} bar.unitcap = {0} {1}/{2} -bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[quân lính bị vô hiệu hóa] bar.liquid = Chất lỏng bar.heat = Nhiệt độ bar.power = Năng lượng @@ -737,6 +754,7 @@ bullet.incendiary = [stat]cháy bullet.sapping = [stat]sapping bullet.homing = [stat]truy đuổi bullet.shock = [stat]sốc +bullet.buildingdamage = [stat]{0}%[lightgray] sát thương khối bullet.frag = [stat]phá mảnh bullet.knockback = [stat]{0}[lightgray] bật lùi bullet.pierce = [stat]{0}[lightgray]x xuyên giáp @@ -763,9 +781,10 @@ unit.timesspeed = x tốc độ unit.percent = % unit.shieldhealth = độ bền khiên unit.items = vật phẩm -unit.thousands = nghìn -unit.millions = triệu -unit.billions = tỷ +unit.thousands = k +unit.millions = mil +unit.billions = b +unit.pershot = /shot category.purpose = Mô tả category.general = Chung category.power = Năng lượng @@ -782,6 +801,7 @@ setting.hints.name = Gợi ý setting.flow.name = Hiện thị tốc độ chuyền tài nguyên setting.backgroundpause.name = Tạm dừng trong nền setting.buildautopause.name = Tự động dừng xây dựng +setting.modcrashdisable.name = Tắt các mod khi gặp sự cố trong khởi động setting.animatedwater.name = Hiệu ứng nước setting.animatedshields.name = Hiệu ứng khiên setting.antialias.name = Khử răng cưa[lightgray] (yêu cầu khởi động lại)[] @@ -833,7 +853,9 @@ setting.chatopacity.name = Độ mờ trò chuyện setting.lasersopacity.name = Độ mờ kết nối năng lượng setting.bridgeopacity.name = Độ mờ cầu setting.playerchat.name = Hiển thị bong bóng trò chuyện của người chơi +setting.showweather.name = Hiển thị đồ họa thời tiết public.confirm = Bạn có muốn công khai trò chơi của mình không?\n[accent]Bất kỳ ai cũng có thể tham gia trò chơi của bạn.\n[lightgray]Điều này có thể được thay đổi sau trong Cài đặt-> Trò chơi-> Hiển thị trò chơi công khai. +public.confirm.really = Nếu bạn muốn chơi với bạn bè, sử dụng [green]Invite Friend[] thay vì [scarlet]Public server[]!\nBạn có chắc chắn muốn làm trò chơi của mình [scarlet]công khai[]? public.beta = Lưu ý rằng phiên bản beta của trò chơi không thể tạo sảnh công khai. uiscale.reset = Kích thước UI đã được thay đổi.\nNhấn "OK" để xác nhận.\n[scarlet]Hoàn lại và thoát trong[accent] {0}[] giây... uiscale.cancel = Hủy & Thoát @@ -908,6 +930,7 @@ keybind.toggle_menus.name = Ẩn/Hiện Menus keybind.chat_history_prev.name = Lịch sử trò chuyện trước keybind.chat_history_next.name = Lịch sử trò chuyện sau keybind.chat_scroll.name = Cuộn trò chuyện +keybind.chat_mode.name = Thay đổi chế độ trò chuyện keybind.drop_unit.name = Thả quân keybind.zoom_minimap.name = Thu phóng bản đồ mini mode.help.title = Mô tả chế độ @@ -924,6 +947,7 @@ mode.custom = Tùy chỉnh luật rules.infiniteresources = Tài nguyên vô hạn rules.reactorexplosions = Nổ lò phản ứng +rules.coreincinerates = Hủy vật phẩm khi căn cứ đầy rules.schematic = Cho phép dùng bản thiết kế rules.wavetimer = Đếm ngược đợt rules.waves = Đợt @@ -935,6 +959,8 @@ rules.blockdamagemultiplier = Hệ số sát thương của khối rules.unitbuildspeedmultiplier = Hệ số tốc độ sản xuất lính rules.unithealthmultiplier = Hệ số máu của quân lính rules.unitdamagemultiplier = Hệ số sát thương của quân lính +rules.unitcapvariable = Căn cứ tăng giới hạn quân lính +rules.unitcap = Giới hạn quân lính rules.enemycorebuildradius = Bán kính không xây dựng trong căn cứ của kẻ địch:[lightgray] (ô) rules.wavespacing = Thời gian giữa các đợt:[lightgray] (giây) rules.buildcostmultiplier = Hệ số chi phí xây dựng @@ -956,6 +982,7 @@ rules.explosions = Sát thương nổ của Khối/Quân lính rules.ambientlight = Ánh sáng môi trường rules.weather = Thời tiết rules.weather.frequency = Tần suất: +rules.weather.always = Luôn luôn rules.weather.duration = Thời gian: content.item.name = Vật phẩm @@ -1162,7 +1189,7 @@ block.item-void.name = Hủy vật phẩm block.liquid-source.name = Nguồn chất lỏng block.liquid-void.name = Hủy chất lỏng block.power-void.name = Hủy năng lượng -block.power-source.name = Vô hạn năng lượng +block.power-source.name = Nguồn năng lượng block.unloader.name = Điểm dỡ hàng block.vault.name = Nhà kho block.wave.name = Wave @@ -1282,6 +1309,9 @@ hint.payloadDrop.mobile = [accent]Nhấn và giữ[] tại một khu vực trố hint.waveFire = [accent]Wave[] súng có nước làm đạn dược sẽ tự động dập tắt các đám cháy gần đó. hint.generator = \uf879 [accent]Máy phát điện đốt cháy[] đốt than và truyền năng lượng cho các khối liền kề.\n\nPhạm vi truyền tải năng lượng có thể được mở rộng với \uf87f [accent]Chốt điện[]. hint.guardian = [accent]Boss[] được bọc giáp. Sử dụng loại đạn yếu chẳng hạn như [accent]Đồng[] và [accent]Chì[] là [scarlet]không hiệu quả[].\n\nSử dụng súng tiên tiến hơn hoặc sử dụng \uf835 [accent]Than chì làm đạn [] \uf861Duo/\uf859Salvo đạn dược để hạ gục Boss. +hint.coreUpgrade = Các căn cứ có thể được nâng cấp bằng cách [accent]đặt căn cứ cấp cao hơn trên chúng[].\n\nĐặt một căn cứ  [accent]Trụ sở[] trên căn cứ  [accent]Cơ sở[]. Đảm bảo không có vật cản gần đó. +hint.presetLaunch = Khác khu vực đáp [accent] xám[], như [accent]Frozen Forest[], có thể được phóng đến từ bất cứ đâu. Nó không yêu cầu chiếm các khu vực lân cận.\n\n[accent]Các khu vực được đánh số[], chẳng hạn như cái này, là [accent]không bắt buộc[]. +hint.coopCampaign = Khi chơi chiến dịch[accent]co-op[], các vật phẩm được sản xuất trong bản đồ hiện tại cũng sẽ được gửi [accent]đến các khu vực của bạn[].\n\nBất kỳ nghiên cứu mới nào được thực hiện đều được lưu lại. item.copper.description = Dùng trong tất cả các khu xây dựng và các loại đạn dược. item.copper.details = Đồng, là kim loại phổ biến trên Serpulo. Có cấu trúc yếu trừ khi được tôi luyện. @@ -1350,10 +1380,10 @@ block.surge-wall.description = Bảo vệ công trình khỏi đạn của kẻ block.surge-wall-large.description = Bảo vệ nhiều công trình khỏi đạn của kẻ thù, đôi khi tạo ra tia điện khi bị bắn. block.door.description = Một bức tường có thể đóng mở. block.door-large.description = Một bức tường có thể đóng mở. -block.mender.description = Sửa chữa định kỳ các khối trong vùng lân cận.\nSử dụng silicon để tăng phạm vi và hiệu quả. -block.mend-projector.description = Sửa chữa các khối lân cận.\nSử dụng silicon để tăng phạm vi và hiệu quả. +block.mender.description = Sửa chữa định kỳ các khối trong vùng lân cận.\nSử dụng Phase Fabric để tăng phạm vi và hiệu quả. +block.mend-projector.description = Sửa chữa các khối lân cận.\nSử dụng Phase Fabric để tăng phạm vi và hiệu quả. block.overdrive-projector.description = Tăng tốc độ làm việc của các công trình lân cận.\nSử dụng phase fabric để tăng phạm vi và hiệu quả. -block.force-projector.description = Tạo ra một trường lực lục giác xung quanh nó, bảo vệ các tòa nhà và quân lính bên trong khỏi bị hư hại.\nQuá nóng nếu chịu quá nhiều sát thương. Sử dụng chất làm mát để giảm nhiệt độ. Sử dụng Phase fabric để tăng kích thước lá chắn. +block.force-projector.description = Tạo ra một trường lực lục giác xung quanh nó, bảo vệ các công trình và quân lính bên trong khỏi bị hư hại.\nQuá nóng nếu chịu quá nhiều sát thương. Sử dụng chất làm mát để giảm nhiệt độ. Sử dụng Phase fabric để tăng kích thước lá chắn. block.shock-mine.description = Giải phóng tia điện khi tiếp xúc với quân lính đối phương. block.conveyor.description = Vận chuyển vật phẩm về phía trước. block.titanium-conveyor.description = Vận chuyển vật phẩm về phía trước. Nhanh hơn băng chuyền tiêu chuẩn. @@ -1366,9 +1396,9 @@ block.inverted-sorter.description = Giống như máy phân loại, nhưng vật block.router.description = Phân phối các vật phẩm đầu vào thành 3 hướng đầu ra như nhau. block.router.details = Không khuyên dùng cạnh đầu vào dây chuyền vì sẽ bị kẹt bởi đầu ra. block.distributor.description = Phân phối các vật phẩm đầu vào thành 7 hướng đầu ra như nhau. -block.overflow-gate.description = Chỉ đưa vật phẩm ra 2 phía nếu phía trước bị chặn, không thể đặt cạnh nhau. -block.underflow-gate.description = Ngược với cổng tràn, chỉ đưa vật phẩm đến trước khi hai bên bị chặn, không thể đặt cạnh nhau. -block.mass-driver.description = Cấu trúc vận chuyển vật phẩm tầm xa. Thu thập các lô vật phẩm và bắn chúng cho các mass driver khác. +block.overflow-gate.description = Chỉ đưa vật phẩm ra 2 phía nếu phía trước bị chặn. +block.underflow-gate.description = Ngược với cổng tràn, chỉ đưa vật phẩm đến trước khi hai bên bị chặn. +block.mass-driver.description = Cấu trúc vận chuyển vật phẩm tầm xa. Thu thập các lô vật phẩm và bắn chúng cho các máy phóng điện từ khác. block.mechanical-pump.description = Bơm chất lỏng, không yêu cầu năng lượng. block.rotary-pump.description = Bơm chất lỏng, yêu cầu năng lượng. block.thermal-pump.description = Bơm chất lỏng. @@ -1488,3 +1518,139 @@ unit.omura.description = Bắn đạn từ trường xuyên giáp tầm xa vào unit.alpha.description = Bảo vệ căn cứ cơ sở khỏi kẻ thù. Có thể xây dựng. unit.beta.description = Bảo vệ căn cứ trụ sở khỏi kẻ thù. Có thể xây dựng. unit.gamma.description = Bảo vệ căn cứ trung tâm khỏi kẻ thù. Có thể xây dựng. + +lst.read = Đọc một số từ bộ nhớ được liên kết. +lst.write = Ghi một số vào bộ nhớ được liên kết. +lst.print = Thêm văn bản vào bộ nhớ in.\nKhông hiển thị gì cho đến khi sử dụng [accent]Print Flush[]. +lst.draw = Thêm một thao tác vào bộ nhớ vẽ.\nKhông hiển thị gì cho đến khi sử dụng [accent]Draw Flush[]. +lst.drawflush = Chuyển các thao tác [accent]Draw[] đến màng hình. +lst.printflush = Chuyển các thao tác [accent]Print[] đến khối tin nhắn. +lst.getlink = Nhận liên kết bộ xử lý theo thứ tự. Bắt đầu từ 0. +lst.control = Điều khiển một khối. +lst.radar = Định vị các quân lính trong phạm vi xung quanh một khối. +lst.sensor = Lấy dữ liệu từ một khối hoặc quân lính. +lst.set = Đặt một biến. +lst.operation = Thực hiện thao tác trên 1-2 biến. +lst.end = Chuyển đến lệnh đầu tiên. +lst.jump = Chuyển qua lệnh khác nếu điều kiện đúng. +lst.unitbind = Bind to the next unit of a type, and store it in [accent]@unit[]. +lst.unitcontrol = Control the currently bound unit. +lst.unitradar = Locate units around the currently bound unit. +lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit. + +lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string. +lenum.shoot = Bắn vào vị trí xác định. +lenum.shootp = Shoot at a unit/building with velocity prediction. +lenum.configure = Building configuration, e.g. sorter item. +lenum.enabled = Bất cứ khi nào khối hoạt động. + +laccess.color = Màu đèn chiếu sáng. + +graphicstype.clear = Tô màu cho màn hình. +graphicstype.color = Đặt màu cho thao tác vẽ tiếp theo. +graphicstype.stroke = Đặt chiều rộng đoạn thẳng. +graphicstype.line = Vẽ đoạn thẳng. +graphicstype.rect = Tô một hình chữ nhật. +graphicstype.linerect = Vẽ đường viền hình chữ nhật. +graphicstype.poly = Tô vào đa giác đều. +graphicstype.linepoly = Vẽ đường viền đa giác đều. +graphicstype.triangle = Tô một hình tam giác. +graphicstype.image = Vẽ hình ảnh một số nội dung.\nVd: [accent]@router[] hoặc [accent]@dagger[]. + +lenum.always = Luôn đúng. +lenum.idiv = Chia lấy phần nguyên. +lenum.div = Phép chia.\nTrả về [accent]null[] khi chia cho 0. +lenum.mod = Chia lấy phần dư. +lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0. +lenum.notequal = Not equal. Coerces types. +lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[]. +lenum.shl = Bit-shift left. +lenum.shr = Bit-shift right. +lenum.or = Bitwise OR. +lenum.land = Logical AND. +lenum.and = Bitwise AND. +lenum.not = Bitwise flip. +lenum.xor = Bitwise XOR. + +lenum.min = Số nhỏ nhất giữa hai số. +lenum.max = Số lớn nhất giữa hai số. +lenum.angle = Góc của vectơ tính bằng độ. +lenum.len = Chiều dài của vectơ. +lenum.sin = Sin, tính bằng độ. +lenum.cos = Cos, tính bằng độ. +lenum.tan = Tan, tính bằng độ. +#not a typo, look up 'range notation' +lenum.rand = Số ngẫu nhiên trong phạm vi [0, giá trị). +lenum.log = Lôgarit tự nhiên (ln). +lenum.log10 = Lôgarit cơ số 10. +lenum.noise = 2D simplex noise. +lenum.abs = Giá trị tuyệt đối. +lenum.sqrt = Căn bậc hai. + +lenum.any = Bất kì quân lính. +lenum.ally = Quân lính cùng đội. +lenum.attacker = Quân lính với vũ khí. +lenum.enemy = Quân lính địch. +lenum.boss = Boss. +lenum.flying = Không quân. +lenum.ground = Bộ binh. +lenum.player = Quân lính do người chơi điều khiển. + +lenum.ore = Ore deposit. +lenum.damaged = Damaged ally building. +lenum.spawn = Enemy spawn point.\nMay be a core or a position. +lenum.building = Building in a specific group. + +lenum.core = Bất kì căn cứ. +lenum.storage = Khối lưu trữ, Ví dụ Nhà kho. +lenum.generator = Khối có thể tạo ra năng lượng. +lenum.factory = Khối có thể biến đổi vật phẩm. +lenum.repair = Điểm sửa chữa. +lenum.rally = Trung tâm chỉ huy. +lenum.battery = Bất kì pin. +lenum.resupply = Điểm tiếp tế.\nChỉ phù hợp khi [accent]"Quân lính cần đạn"[] được bật. +lenum.reactor = Lò phản ứng Thorium\Nhiệt hạch. +lenum.turret = Bất kì súng. + +sensor.in = The building/unit to sense. + +radar.from = Building to sense from.\nSensor range is limited by building range. +radar.target = Filter for units to sense. +radar.and = Additional filters. +radar.order = Sorting order. 0 to reverse. +radar.sort = Metric to sort results by. +radar.output = Variable to write output unit to. + +unitradar.target = Filter for units to sense. +unitradar.and = Additional filters. +unitradar.order = Sorting order. 0 to reverse. +unitradar.sort = Metric to sort results by. +unitradar.output = Variable to write output unit to. + +control.of = Building to control. +control.unit = Unit/building to aim at. +control.shoot = Whether to shoot. + +unitlocate.enemy = Whether to locate enemy buildings. +unitlocate.found = Whether the object was found. +unitlocate.building = Output variable for located building. +unitlocate.outx = Output X coordinate. +unitlocate.outy = Output Y coordinate. +unitlocate.group = Building group to look for. + +lenum.stop = Dừng di chuyển/Đào/Xây dựng. +lenum.move = Di chuyển đến vị trí xác định. +lenum.approach = Approach a position with a radius. +lenum.pathfind = Tìm đường đến nơi tạo ra kẻ địch. +lenum.target = Bắn vào vị trí xác định. +lenum.targetp = Shoot a target with velocity prediction. +lenum.itemdrop = Thả vật phẩm. +lenum.itemtake = Lấy vật phẩm từ khối. +lenum.paydrop = Thả khối hàng hiện tại. +lenum.paytake = Nhất khối hàng tại vị trí hiện tại. +lenum.flag = Numeric unit flag. +lenum.mine = Đào tại vị trí. +lenum.build = Xây công trình. +lenum.getblock = Fetch a building and type at coordinates.\nUnit must be in range of position.\nSolid non-buildings will have the type [accent]@solid[]. +lenum.within = Kiểm tra xem quân lính có gần vị trí không. +lenum.boost = Start/stop boosting. \ No newline at end of file From d76795e0ae2dc86a1d8a559ff53ae670e2e64ddf Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Sun, 21 Feb 2021 00:07:29 +0900 Subject: [PATCH 322/426] translated recent update (#4742) --- core/assets/bundles/bundle_ko.properties | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 5d5ab625ab..46cd9f857f 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -1,6 +1,6 @@ credits.text = 만든이: [royal]Anuken[] - [sky]anukendev@gmail.com[] credits = 제작진 -contributors = 번역가와 기여자 +contributors = 번역가와 기여 discord = Mindustry Discord 서버에 가입하세요! link.discord.description = Mindustry Discord 공식 대화방 link.reddit.description = Mindustry 서브레딧 @@ -113,7 +113,7 @@ committingchanges = 바뀐 점 적용 done = 완료 feature.unsupported = 기기가 이 기능을 지원하지 않습니다. -mods.alphainfo = 현재 모드는 정식 출시 버전이 아니며, [scarlet]오류가 많을 수 있습니다[].\n발견한 문제는 Mindustry Github 또는 Discord에 보고하세요. +mods.initfailed = [red]⚠[]이전 Mindustry 인스턴스를 초기화하지 못했습니다. 잘못된 모드로 인해 발생한 것일 수 있습니다.\n\n 게임 충돌 무한반복을 막기 위해, [red]모든 모드가 비활성화되었습니다.[]\n\n이 시스템을 비활성화할려면, [accent]설정->게임->로딩 중 충돌 시 모드 비활성화[]설정을 끄세요. mods = 모드 mods.none = [lightgray]모드를 찾을 수 없습니다! mods.guide = 모드 제작 가이드 @@ -800,6 +800,7 @@ setting.logichints.name = 로직 힌트 표시 setting.flow.name = 자원 흐름량 표시 setting.backgroundpause.name = 백그라운드에서 일시정지 setting.buildautopause.name = 건설 자동 일시정지 +setting.modcrashdisable.name = 로딩 중 충돌 시 모드 비활성화 setting.animatedwater.name = 액체 애니메이션 효과 setting.animatedshields.name = 보호막 애니메이션 효과 setting.antialias.name = 위신호 제거 필터[lightgray] (재시작 필요)[] From a3bf39d86b3dd23d185c3586e2f1783ccc547e31 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 20 Feb 2021 10:08:15 -0500 Subject: [PATCH 323/426] Minor cleanup --- core/src/mindustry/net/Administration.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/mindustry/net/Administration.java b/core/src/mindustry/net/Administration.java index b7d0c451e9..bd312bacdf 100644 --- a/core/src/mindustry/net/Administration.java +++ b/core/src/mindustry/net/Administration.java @@ -479,9 +479,7 @@ public class Administration{ autosave("Whether the periodically save the map when playing.", false), autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10), autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5), - debug("Enable debug logging", false, () -> { - Log.level = debug() ? LogLevel.debug : LogLevel.info; - }); + debug("Enable debug logging", false, () -> Log.level = debug() ? LogLevel.debug : LogLevel.info); public static final Config[] all = values(); From 868d4e05f7d4eb39d2098b9be1e7491d9022c1c3 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sat, 20 Feb 2021 18:51:12 +0100 Subject: [PATCH 324/426] Move update function of resupply point 5x1 spaces back (#4746) --- .../mindustry/world/blocks/units/ResupplyPoint.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/world/blocks/units/ResupplyPoint.java b/core/src/mindustry/world/blocks/units/ResupplyPoint.java index 6402b20147..aa765127a9 100644 --- a/core/src/mindustry/world/blocks/units/ResupplyPoint.java +++ b/core/src/mindustry/world/blocks/units/ResupplyPoint.java @@ -47,11 +47,11 @@ public class ResupplyPoint extends Block{ } @Override - public void updateTile(){ - if(consValid() && timer(timerResupply, resupplyRate / timeScale) && resupply(this, range, ammoAmount, ammoColor)){ - consume(); - } - } + public void updateTile(){ + if(consValid() && timer(timerResupply, resupplyRate / timeScale) && resupply(this, range, ammoAmount, ammoColor)){ + consume(); + } + } } /** Tries to resupply nearby units. From 4d9dc66a961272d2a1a53f635f20a4e8296d4d18 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sat, 20 Feb 2021 18:52:56 +0100 Subject: [PATCH 325/426] Remove stray spaces from accelerator (#4465) --- core/src/mindustry/world/blocks/campaign/Accelerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index 6f998ccd8f..7160c6291a 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -48,7 +48,7 @@ public class Accelerator extends Block{ public boolean outputsItems(){ return false; } - + public class AcceleratorBuild extends Building{ public float heat, statusLerp; @@ -58,7 +58,7 @@ public class Accelerator extends Block{ heat = Mathf.lerpDelta(heat, consValid() ? 1f : 0f, 0.05f); statusLerp = Mathf.lerpDelta(statusLerp, power.status, 0.05f); } - + @Override public void draw(){ super.draw(); @@ -72,7 +72,7 @@ public class Accelerator extends Block{ Draw.rect(arrowRegion, x + Angles.trnsx(rot, length), y + Angles.trnsy(rot, length), rot + 180f); } } - + if(heat < 0.0001f) return; float rad = size * tilesize / 2f * 0.74f; From 0d287e6d59e12dec62e72057838a9bfdd77422c2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 21 Feb 2021 08:53:47 -0500 Subject: [PATCH 326/426] Water Extractor: Use metaglass to be consistent with pumps --- core/src/mindustry/content/Blocks.java | 2 +- desktop/src/mindustry/desktop/DesktopLauncher.java | 3 +-- gradle.properties | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index e9f8abf2a4..78d27b61a2 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1285,7 +1285,7 @@ public class Blocks implements ContentList{ }}; waterExtractor = new SolidPump("water-extractor"){{ - requirements(Category.production, with(Items.copper, 30, Items.graphite, 30, Items.lead, 30)); + requirements(Category.production, with(Items.metaglass, 30, Items.graphite, 30, Items.lead, 30)); result = Liquids.water; pumpAmount = 0.11f; size = 2; diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index ad8e03d5c0..29fe405905 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -64,8 +64,7 @@ public class DesktopLauncher extends ClientLauncher{ if(useSteam){ //delete leftover dlls - Fi file = new Fi("."); - for(Fi other : file.parent().list()){ + for(Fi other : new Fi(".").parent().list()){ if(other.name().contains("steam") && (other.extension().equals("dll") || other.extension().equals("so") || other.extension().equals("dylib"))){ other.delete(); } diff --git a/gradle.properties b/gradle.properties index 7ecfa9aaf8..f7f78d81b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=1d7c415cd528ee0148fa2f498fcb1ec563528825 +archash=7e4bc7e1c7c25bdf4321a22356f6ddb1943f6d60 From ca726d579e342139afd1fa82c5ea5581bda8dd1b Mon Sep 17 00:00:00 2001 From: liuxilu <53636947+liuxilu@users.noreply.github.com> Date: Sun, 21 Feb 2021 22:20:36 +0800 Subject: [PATCH 327/426] unit boosting sensor (#4738) --- core/src/mindustry/entities/comp/UnitComp.java | 1 + core/src/mindustry/logic/LAccess.java | 1 + 2 files changed, 2 insertions(+) diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 83dcf435c1..94615f3c96 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -131,6 +131,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I //case dead -> dead || !isAdded(); //TODO 126 case team -> team.id; case shooting -> isShooting() ? 1 : 0; + case boosting -> type.canBoost && isFlying() ? 1 : 0; case range -> range() / tilesize; case shootX -> World.conv(aimX()); case shootY -> World.conv(aimY()); diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index bf3f9dd3b1..deec3a2bf3 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -30,6 +30,7 @@ public enum LAccess{ //dead, //TODO 126 range, shooting, + boosting, mineX, mineY, mining, From 544828d9fbf8798426cd8d1f926a72257c720e05 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 21 Feb 2021 09:22:02 -0500 Subject: [PATCH 328/426] Logic `controller` & dead`` sensors --- core/assets/bundles/bundle.properties | 2 ++ core/src/mindustry/entities/comp/BuildingComp.java | 2 +- core/src/mindustry/entities/comp/UnitComp.java | 3 ++- core/src/mindustry/logic/LAccess.java | 3 ++- gradle.properties | 2 +- server/build.gradle | 3 +++ 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 6e0a662482..a0d3fd7682 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1544,6 +1544,8 @@ lenum.configure = Building configuration, e.g. sorter item. lenum.enabled = Whether the block is enabled. laccess.color = Illuminator color. +laccess.controller = Unit controller. If processor controlled, returns processor.\nIf in a formation, returns leader.\nOtherwise, returns the unit itself. +laccess.dead = Whether a unit/building is dead or no longer valid. graphicstype.clear = Fill the display with a color. graphicstype.color = Set color for next drawing operations. diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index ae987d7592..407fe6a9d1 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1312,7 +1312,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, return switch(sensor){ case x -> World.conv(x); case y -> World.conv(y); - //case dead -> !isValid(); //TODO 126 + case dead -> !isValid() ? 1 : 0; case team -> team.id; case health -> health; case maxHealth -> maxHealth; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 83dcf435c1..e6afbc4f1a 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -128,7 +128,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case ammoCapacity -> type.ammoCapacity; case x -> World.conv(x); case y -> World.conv(y); - //case dead -> dead || !isAdded(); //TODO 126 + case dead -> dead || !isAdded() ? 1 : 0; case team -> team.id; case shooting -> isShooting() ? 1 : 0; case range -> range() / tilesize; @@ -151,6 +151,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case type -> type; case name -> controller instanceof Player p ? p.name : null; case firstItem -> stack().amount == 0 ? null : item(); + case controller -> controller instanceof LogicAI log ? log.controller : controller instanceof FormationAI form ? form.leader : this; case payloadType -> self() instanceof Payloadc pay ? (pay.payloads().isEmpty() ? null : pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type : diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index bf3f9dd3b1..a928418404 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -27,7 +27,7 @@ public enum LAccess{ y, shootX, shootY, - //dead, //TODO 126 + dead, range, shooting, mineX, @@ -42,6 +42,7 @@ public enum LAccess{ config, payloadCount, payloadType, + controller, //values with parameters are considered controllable enabled("to"), //"to" is standard for single parameter access diff --git a/gradle.properties b/gradle.properties index f7f78d81b9..83c7ad7b59 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=7e4bc7e1c7c25bdf4321a22356f6ddb1943f6d60 +archash=26a96b2eb63608f200e5b93873013dd85c31e39f diff --git a/server/build.gradle b/server/build.gradle index a62fb66121..0f526c9f56 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -42,6 +42,9 @@ task dist(type: Jar, dependsOn: configurations.runtimeClasspath){ exclude("zones/**") exclude("icons/**") exclude("bundles/**") + exclude("cubemaps/**") + exclude("cursors/**") + exclude("shaders/**") manifest{ attributes 'Main-Class': project.mainClassName From 61d9dea487f9cd4c1e271528c54c4028bb372682 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 21 Feb 2021 10:23:46 -0500 Subject: [PATCH 329/426] Logic config replication / logicUnitBuild rule / Copy-able ConstructBlocks --- core/assets/bundles/bundle.properties | 3 +++ core/src/mindustry/ai/types/LogicAI.java | 2 +- .../src/mindustry/entities/comp/BuildingComp.java | 11 +++++++++++ core/src/mindustry/game/Rules.java | 2 ++ core/src/mindustry/game/Schematics.java | 15 +++++++++------ core/src/mindustry/logic/LExecutor.java | 8 +++++--- core/src/mindustry/logic/LStatements.java | 6 +++++- core/src/mindustry/logic/LUnitControl.java | 1 + 8 files changed, 37 insertions(+), 11 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index a0d3fd7682..2727246299 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1537,6 +1537,8 @@ lst.unitcontrol = Control the currently bound unit. lst.unitradar = Locate units around the currently bound unit. lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit. +logic.nounitbuild = [red]Unit building logic is not allowed here. + lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string. lenum.shoot = Shoot at a position. lenum.shootp = Shoot at a unit/building with velocity prediction. @@ -1639,6 +1641,7 @@ unitlocate.outx = Output X coordinate. unitlocate.outy = Output Y coordinate. unitlocate.group = Building group to look for. +lenum.idle = Don't move, but keep building/mining.\nThe default state. lenum.stop = Stop moving/mining/building. lenum.move = Move to exact position. lenum.approach = Approach a position with a radius. diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index 5f72520729..abd76201e6 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -19,7 +19,7 @@ public class LogicAI extends AIController{ /** Time after which the unit resets its controlled and reverts to a normal unit. */ public static final float logicControlTimeout = 10f * 60f; - public LUnitControl control = LUnitControl.stop; + public LUnitControl control = LUnitControl.idle; public float moveX, moveY, moveRad; public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer; @Nullable diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 407fe6a9d1..4a6ba5b1d4 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -962,8 +962,19 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, lastAccessed = builder.getPlayer().name; } + Log.info("@ configured @ with @", builder, this, value); + if(block.configurations.containsKey(type)){ block.configurations.get(type).get(this, value); + }else if(value instanceof Building build){ + Log.info("conf w build"); + //copy config of another building + var conf = build.config(); + if(conf != null && !(conf instanceof Building)){ + configured(builder, conf); + }else{ + Log.info("no build"); + } } } diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index 538422fef0..9b95bbf7d3 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -50,6 +50,8 @@ public class Rules{ public float unitBuildSpeedMultiplier = 1f; /** How much damage any other units deal. */ public float unitDamageMultiplier = 1f; + /** Whether to allow units to build with logic. */ + public boolean logicUnitBuild = true; /** How much health blocks start with. */ public float blockHealthMultiplier = 1f; /** How much damage blocks (turrets) deal. */ diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index 92179b7c9c..e0e067a029 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -27,6 +27,7 @@ import mindustry.input.Placement.*; import mindustry.io.*; import mindustry.world.*; import mindustry.world.blocks.*; +import mindustry.world.blocks.ConstructBlock.*; import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.legacy.*; import mindustry.world.blocks.power.*; @@ -357,10 +358,11 @@ public class Schematics implements Loadable{ for(int cx = x; cx <= x2; cx++){ for(int cy = y; cy <= y2; cy++){ Building linked = world.build(cx, cy); + Block realBlock = linked == null ? null : linked instanceof ConstructBuild cons ? cons.cblock : linked.block; - if(linked != null && (linked.block.isVisible() || linked.block() instanceof CoreBlock) && !(linked.block instanceof ConstructBlock)){ - int top = linked.block.size/2; - int bot = linked.block.size % 2 == 1 ? -linked.block.size/2 : -(linked.block.size - 1)/2; + if(linked != null && (realBlock.isVisible() || realBlock instanceof CoreBlock)){ + int top = realBlock.size/2; + int bot = realBlock.size % 2 == 1 ? -realBlock.size/2 : -(realBlock.size - 1)/2; minx = Math.min(linked.tileX() + bot, minx); miny = Math.min(linked.tileY() + bot, miny); maxx = Math.max(linked.tileX() + top, maxx); @@ -385,12 +387,13 @@ public class Schematics implements Loadable{ for(int cx = ox; cx <= ox2; cx++){ for(int cy = oy; cy <= oy2; cy++){ Building tile = world.build(cx, cy); + Block realBlock = tile == null ? null : tile instanceof ConstructBuild cons ? cons.cblock : tile.block; - if(tile != null && !counted.contains(tile.pos()) && !(tile.block instanceof ConstructBlock) - && (tile.block.isVisible() || tile.block instanceof CoreBlock)){ + if(tile != null && !counted.contains(tile.pos()) + && (realBlock.isVisible() || realBlock instanceof CoreBlock)){ Object config = tile.config(); - tiles.add(new Stile(tile.block, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation)); + tiles.add(new Stile(realBlock, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation)); counted.add(tile.pos()); } } diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 6c4ec55281..c7082e4cb1 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -447,7 +447,7 @@ public class LExecutor{ } } case build -> { - if(unit.canBuild() && exec.obj(p3) instanceof Block block){ + if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block){ int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize); int rot = exec.numi(p4); @@ -458,12 +458,14 @@ public class LExecutor{ ai.plan.stuck = false; } + var conf = exec.obj(p5); ai.plan.set(x, y, rot, block); - ai.plan.config = exec.obj(p5) instanceof Content c ? c : null; + ai.plan.config = conf instanceof Content c ? c : conf instanceof Building b ? b : null; unit.clearBuilding(); + Tile tile = ai.plan.tile(); - if(ai.plan.tile() != null){ + if(tile != null && !(tile.block() == block && tile.build != null && tile.build.rotation == rot)){ unit.updateBuilding = true; unit.addBuild(ai.plan); } diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 15735359a7..21fddc023f 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -829,7 +829,11 @@ public class LStatements{ table.button(b -> { b.label(() -> type.name()); b.clicked(() -> showSelect(b, LUnitControl.all, type, t -> { - type = t; + if(t == LUnitControl.build && !Vars.state.rules.logicUnitBuild){ + Vars.ui.showInfo("@logic.nounitbuild"); + }else{ + type = t; + } rebuild(table); }, 2, cell -> cell.size(120, 50))); }, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2); diff --git a/core/src/mindustry/logic/LUnitControl.java b/core/src/mindustry/logic/LUnitControl.java index 41f00da025..f5bc4dbd52 100644 --- a/core/src/mindustry/logic/LUnitControl.java +++ b/core/src/mindustry/logic/LUnitControl.java @@ -1,6 +1,7 @@ package mindustry.logic; public enum LUnitControl{ + idle, stop, move("x", "y"), approach("x", "y", "radius"), From d8552915f75066e0f360c00ebba546dbd5f7b6b2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 21 Feb 2021 10:35:33 -0500 Subject: [PATCH 330/426] Cleanup --- core/src/mindustry/entities/comp/BuildingComp.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 4a6ba5b1d4..7a438d19ff 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -962,18 +962,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, lastAccessed = builder.getPlayer().name; } - Log.info("@ configured @ with @", builder, this, value); - if(block.configurations.containsKey(type)){ block.configurations.get(type).get(this, value); }else if(value instanceof Building build){ - Log.info("conf w build"); //copy config of another building var conf = build.config(); if(conf != null && !(conf instanceof Building)){ configured(builder, conf); - }else{ - Log.info("no build"); } } } From e6787c51465188505734f055d9fc9a02e67f8c75 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 21 Feb 2021 12:28:00 -0500 Subject: [PATCH 331/426] Controlled sensor improvements --- core/assets/bundles/bundle.properties | 2 ++ core/src/mindustry/entities/comp/BuildingComp.java | 2 +- core/src/mindustry/entities/comp/UnitComp.java | 2 +- core/src/mindustry/logic/GlobalConstants.java | 6 ++++++ core/src/mindustry/logic/LAccess.java | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 2727246299..30c58e23b1 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1548,6 +1548,8 @@ lenum.enabled = Whether the block is enabled. laccess.color = Illuminator color. laccess.controller = Unit controller. If processor controlled, returns processor.\nIf in a formation, returns leader.\nOtherwise, returns the unit itself. laccess.dead = Whether a unit/building is dead or no longer valid. +laccess.controlled = Returns:\n[accent]@contProcessor[] if unit controller is processor\n[accent]@contPlayer[] if unit/building controller is player\n[accent]@contFormation[] if unit is in formation\nOtherwise, 0. +laccess.commanded = [red]Deprecated. Will be removed![]\nUse [accent]controlled[] instead. graphicstype.clear = Fill the display with a color. graphicstype.color = Set color for next drawing operations. diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 7a438d19ff..9cc2573147 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1337,7 +1337,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored(); case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity(); case enabled -> enabled ? 1 : 0; - case controlled -> this instanceof ControlBlock c ? c.isControlled() ? 1 : 0 : 0; + case controlled -> this instanceof ControlBlock c && c.isControlled() ? 2 : 0; case payloadCount -> getPayload() != null ? 1 : 0; default -> Float.NaN; //gets converted to null in logic }; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 93b3342878..de80519ba6 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -139,7 +139,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case mineX -> mining() ? mineTile.x : -1; case mineY -> mining() ? mineTile.y : -1; case flag -> flag; - case controlled -> controller instanceof LogicAI || controller instanceof Player ? 1 : 0; + case controlled -> controller instanceof LogicAI ? 1 : controller instanceof Player ? 2 : controller instanceof FormationAI ? 3 : 0; case commanded -> controller instanceof FormationAI ? 1 : 0; case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; default -> Float.NaN; diff --git a/core/src/mindustry/logic/GlobalConstants.java b/core/src/mindustry/logic/GlobalConstants.java index eea74416c0..9781b66c52 100644 --- a/core/src/mindustry/logic/GlobalConstants.java +++ b/core/src/mindustry/logic/GlobalConstants.java @@ -19,6 +19,12 @@ public class GlobalConstants{ put("true", 1); put("null", null); + //special enums + + put("@contProcessor", 1); + put("@contPlayer", 2); + put("@contFormation", 3); + //store base content for(Item item : Vars.content.items()){ diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index e2a49e1f87..e3403a56be 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -38,12 +38,12 @@ public enum LAccess{ type, flag, controlled, + controller, commanded, name, config, payloadCount, payloadType, - controller, //values with parameters are considered controllable enabled("to"), //"to" is standard for single parameter access From 9e8a2b82966e1fd9fb31dd8546698f5827b1b489 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 21 Feb 2021 20:07:20 -0500 Subject: [PATCH 332/426] Minor bridge linking fix --- core/assets/bundles/bundle.properties | 2 +- core/src/mindustry/input/InputHandler.java | 1 + core/src/mindustry/input/Placement.java | 12 ++++++------ core/src/mindustry/world/Block.java | 5 +++++ .../world/blocks/distribution/ItemBridge.java | 10 +++++----- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 30c58e23b1..4eec090d97 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1585,7 +1585,7 @@ lenum.sin = Sine, in degrees. lenum.cos = Cosine, in degrees. lenum.tan = Tangent, in degrees. #not a typo, look up 'range notation' -lenum.rand = Random number in range [0, value). +lenum.rand = Random decimal in range [0, value). lenum.log = Natural logarithm (ln). lenum.log10 = Base 10 logarithm. lenum.noise = 2D simplex noise. diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 638353b982..c4731befe9 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -859,6 +859,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ req.animScale = 1f; lineRequests.add(req); }); + block.handlePlacementLine(lineRequests); if(Core.settings.getBool("blockreplace")){ lineRequests.each(req -> { diff --git a/core/src/mindustry/input/Placement.java b/core/src/mindustry/input/Placement.java index 85d14f2416..bc17d9eb97 100644 --- a/core/src/mindustry/input/Placement.java +++ b/core/src/mindustry/input/Placement.java @@ -12,16 +12,16 @@ import mindustry.world.blocks.distribution.*; import static mindustry.Vars.*; public class Placement{ - private final static Seq tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>(); + private static final Seq tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>(); private static final NormalizeResult result = new NormalizeResult(); private static final NormalizeDrawResult drawResult = new NormalizeDrawResult(); - private static Bresenham2 bres = new Bresenham2(); - private static Seq points = new Seq<>(); + private static final Bresenham2 bres = new Bresenham2(); + private static final Seq points = new Seq<>(); //for pathfinding - private static IntFloatMap costs = new IntFloatMap(); - private static IntIntMap parents = new IntIntMap(); - private static IntSet closed = new IntSet(); + private static final IntFloatMap costs = new IntFloatMap(); + private static final IntIntMap parents = new IntIntMap(); + private static final IntSet closed = new IntSet(); /** Normalize a diagonal line into points. */ public static Seq pathfindLine(boolean conveyors, int startX, int startY, int endX, int endY){ diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 17f86f69b7..66f64c5e4a 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -403,6 +403,11 @@ public class Block extends UnlockableContent{ } + /** Mutates the given list of requests used during line placement. */ + public void handlePlacementLine(Seq plans){ + + } + public Object nextConfig(){ if(saveConfig && lastConfig != null){ return lastConfig; diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 2ab0c9b047..8d4b952038 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -176,11 +176,11 @@ public class ItemBridge extends Block{ public void playerPlaced(Object config){ super.playerPlaced(config); - if(config != null) return; - - Tile link = findLink(tile.x, tile.y); - if(linkValid(tile, link) && !proximity.contains(link.build)){ - link.build.configure(tile.pos()); + if(config == null){ + Tile link = findLink(tile.x, tile.y); + if(linkValid(tile, link) && !proximity.contains(link.build)){ + link.build.configure(tile.pos()); + } } lastBuild = this; From 5b652ae51fc2716d777bbb18f9977910d9044114 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 22 Feb 2021 09:04:22 -0500 Subject: [PATCH 333/426] Added guidelines for inappropriate server content --- SERVERLIST.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/SERVERLIST.md b/SERVERLIST.md index 83aa15a3d7..bef8443c8d 100644 --- a/SERVERLIST.md +++ b/SERVERLIST.md @@ -6,16 +6,17 @@ This is done by letting clients `GET` a [JSON list of servers](https://github.co You may want to add your server to this list. The steps for getting this done are as follows: 1. **Ensure your server is properly moderated.** For the most part, this applies to survival servers, but PvP servers can be affected as well. -You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins. +You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins. *Consider enabling a rate limit:* `config messageRateLimit 2` will make it so that players can only send messages every 2 seconds, for example. -2. **Set an appropriate MOTD, name and description.** This is set with `config `. "Appropriate" means that: +2. Make sure that your server is able to handle inappropriate content - this includes NSFW display/sorter art and abusive messages. **Servers that allow such content will be removed immediately.** Consider banning display blocks if it is a problem for your server: `rules add bannedBlocks ["logic-display", "large-logic-display"]`. +3. **Set an appropriate MOTD, name and description.** This is set with `config `. "Appropriate" means that: - Your name or description must reflect the type of server you're hosting. Since new players may be exposed to the server list early on, put in a phrase like "Co-op survival" or "PvP" so players know what they're getting into. Yes, this is also displayed in the server mode info text, but having extra info in the name doesn't hurt. - Make sure players know where to refer to for server support. It should be fairly clear that the server owner is not me, but you. - Try to be professional in your text; use common sense. -3. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option. -4. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`). -5. Finally, **submit a pull request** to add your server's IP to the list. +4. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option. +5. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`). +6. Finally, **submit a pull request** to add your server's IP to the list. This should be fairly straightforward: Press the edit button on the [server file](https://github.com/Anuken/Mindustry/blob/master/servers_v6.json), then add a JSON object with a single key, indicating your server address. For example, if your server address is `google.com`, you would add a comma after the last entry and insert: ```json From 3b2a0cfd66d7eddf5266fafb5b75f75847e1f9fe Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 22 Feb 2021 09:05:27 -0500 Subject: [PATCH 334/426] Removed RCR due to lack of moderation --- servers_v6.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/servers_v6.json b/servers_v6.json index 432553f84c..54f1691e0f 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -1,8 +1,4 @@ -[ - { - "name": "RCR", - "address": ["rcr.fvds.ru"] - }, +[ { "name": "mindustry.pl", "address": ["mindustry.pl:6000", "mindustry.pl:6666", "mindustry.pl"] From dbdfdac94baea58d0c51af6d72252c6112599c3f Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Mon, 22 Feb 2021 23:19:46 +0900 Subject: [PATCH 335/426] translated yesterday update (#4755) * translated newest bundle updates * ps. why did i forgot https://github.com/Anuken/Mindustry/commit/1ef7ae70796beb4a28dee8f2c74b626d28348481#diff-5e346bcec4e8e1d545e035b1e438472bc51937398ac3e8e81308605ec82aea2c this commit previous translation update? --- core/assets/bundles/bundle_ko.properties | 27 ++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 46cd9f857f..d4ebba340b 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -9,7 +9,7 @@ link.changelog.description = 업데이트 내용 목록 link.dev-builds.description = 불안정한 개발 버전 link.trello.description = 출시 예정 기능 계획을 게시한 공식 Trello 보드 link.itch.io.description = PC 다운로드가 있는 itch.io 페이지 -link.google-play.description = Google Play 스토어 목록 +link.google-play.description = oogle Play 스토어 목록 link.f-droid.description = F-Droid 카탈로그 목록 link.wiki.description = 공식 Mindustry 위키 link.suggestions.description = 새 기능 제안하기 @@ -1537,12 +1537,30 @@ lst.unitcontrol = 현재 지정된 유닛을 조종하기 lst.unitradar = 현재 지정된 유닛 주변의 유닛 검색하기 lst.unitlocate = 특정 유형의 위치/건물을 지도상에서 찾기\n지정된 유닛이 필요합니다. -lenum.type = 건물/유닛의 타입\n예로 분배기는 [accent]@router[]를 반환할 것입니다.\n문자열이 아니라. +logic.nounitbuild = [red]유닛의 건물 로직은 여기서 허용되지 않습니다. + +lenum.type = 건물/유닛의 타입\n예로 분배기는 문자열이 아니라 [accent]@router[]를 반환합니다. lenum.shoot = 특정 위치에 발사 lenum.shootp = 목표물 속도를 예측하여 발사 lenum.configure = 필터의 아이템같은 건물의 설정 lenum.enabled = 블록의 활성 여부 + lenum.color = 조명 색 설정 +laccess.controller = 유닛 제어자. 프로세서가 제어하면, 프로세서를 반환합니다.\n다른 유닛에 의해 지휘되면(G키), 지휘하는 유닛을 반환합니다.\n그 외에는 자신을 반환합니다. +laccess.dead = 유닛 또는 건물 사망/무효 여부 +laccess.controlled = 만약 유닛 제어자가 프로세서라면 [accent]@contProcessor[]를 반환합니다.\n만약 유닛/건물 제어자가 플레이어라면 [accent]@contPlayer[]를 반환합니다.\n만약 유닛이 다른 유닛에 의해 지휘되면(G키)[accent]@contFormation[]를 반환합니다.\n그 외에는 0을 반환합니다. +laccess.commanded = [red]이제 사용되지 않으며, 곧 제거될 예정입니다![]\대신 [accent]controlled[]를 사용하세요. + +graphicstype.clear = 이 색으로 화면을 채우기 +graphicstype.color = 아래 그래픽 실행문들의 색 설정하기 +graphicstype.stroke = 선 굵기 설정하기 +graphicstype.line = 선분 그리기 +graphicstype.rect = 직사각형 채우기 +graphicstype.linerect = 직사각형 외곽선 그리기 +graphicstype.poly = 정다각형 채우기 +graphicstype.linepoly = 정다각형 외곽선 그리기 +graphicstype.triangle = 삼각형 채우기 +graphicstype.image = 일부 콘텐츠의 이미지 그리기\n예: [accent]@router[] 또는 [accent]@dagger[]. lenum.always = 항상 참 lenum.idiv = 정수 나누기 @@ -1567,7 +1585,7 @@ lenum.sin = 사인(도) lenum.cos = 코사인(도) lenum.tan = 탄젠트(도) #not a typo, look up 'range notation' -lenum.rand = 범위 내 난수[0 ~ 값) +lenum.rand = 범위 내 십진법 난수[0 ~ 값) lenum.log = 자연 로그(진수) lenum.log10 = 상수 로그 lenum.noise = 2D 심플렉스 노이즈 @@ -1597,7 +1615,7 @@ lenum.rally = 지휘소 lenum.battery = 배터리 lenum.resupply = 보급 지점.\n[accent]"유닛 탄약 필요"[]가 활성화되었을 때만 유의미합니다. lenum.reactor = 핵융합로/토륨 원자로 -lenum.turret = 포탑ㅁ +lenum.turret = 포탑 sensor.in = 감지할 건물/유닛 @@ -1625,6 +1643,7 @@ unitlocate.outx = X좌표 unitlocate.outy = Y좌표 unitlocate.group = 찾을 건물 집단 +lenum.idle = 채광/건설 제외 이동만 중단\n기본 상태입니다. lenum.stop = 이동/채광/건설 중단 lenum.move = 특정 위치로 이동 lenum.approach = 특정 위치로 반지름만큼 접근 From d06a7bb7a246e95f3c5b6ab289f06075711b397c Mon Sep 17 00:00:00 2001 From: UnCaughT Date: Mon, 22 Feb 2021 18:09:55 +0300 Subject: [PATCH 336/426] Update servers_v6.json (#4756) The server now has a new domain. --- servers_v6.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servers_v6.json b/servers_v6.json index 54f1691e0f..e40885d0f1 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -64,8 +64,8 @@ "address": ["mindustry.kr"] }, { - "name": "HexPvP", - "address": ["hexpvp.ddns.net"] + "name": "hexpvp.ml", + "address": ["hexpvp.ml"] }, { "name": "Omega", From e2515fc4bf4dc2c2bb0921605accd57703a55890 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 22 Feb 2021 10:15:40 -0500 Subject: [PATCH 337/426] Automatic conveyor/conduit bridging --- .../mindustry/entities/units/BuildPlan.java | 4 ++ core/src/mindustry/input/InputHandler.java | 11 ++-- core/src/mindustry/input/MobileInput.java | 1 + core/src/mindustry/input/Placement.java | 57 ++++++++++++++++++- .../mindustry/ui/dialogs/LoadoutDialog.java | 2 +- .../world/blocks/distribution/Conveyor.java | 12 ++++ .../world/blocks/distribution/ItemBridge.java | 20 +++---- .../world/blocks/liquid/Conduit.java | 6 ++ 8 files changed, 95 insertions(+), 18 deletions(-) diff --git a/core/src/mindustry/entities/units/BuildPlan.java b/core/src/mindustry/entities/units/BuildPlan.java index 04117b1661..053d12651d 100644 --- a/core/src/mindustry/entities/units/BuildPlan.java +++ b/core/src/mindustry/entities/units/BuildPlan.java @@ -62,6 +62,10 @@ public class BuildPlan implements Position{ } + public boolean placeable(Team team){ + return Build.validPlace(block, team, x, y, rotation); + } + public boolean isRotation(Team team){ if(breaking) return false; Tile tile = tile(); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index c4731befe9..c8ab2b4f21 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -30,11 +30,10 @@ import mindustry.net.*; import mindustry.type.*; import mindustry.ui.fragments.*; import mindustry.world.*; -import mindustry.world.blocks.*; import mindustry.world.blocks.ConstructBlock.*; +import mindustry.world.blocks.*; import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.payloads.*; -import mindustry.world.blocks.power.*; import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.meta.*; @@ -771,7 +770,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Draw.reset(); Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime, 6f, 0.28f)); Draw.alpha(1f); - request.block.drawRequestConfigTop(request, selectRequests); + request.block.drawRequestConfigTop(request, cons -> { + selectRequests.each(cons); + lineRequests.each(cons); + }); Draw.reset(); } @@ -859,7 +861,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ req.animScale = 1f; lineRequests.add(req); }); - block.handlePlacementLine(lineRequests); if(Core.settings.getBool("blockreplace")){ lineRequests.each(req -> { @@ -868,6 +869,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ req.block = replace; } }); + + block.handlePlacementLine(lineRequests); } } diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index a1ca88635a..22a61c3d18 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -314,6 +314,7 @@ public class MobileInput extends InputHandler implements GestureListener{ request.block.drawPlan(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation) && getRequest(request.x, request.y, request.block.size, null) == null); drawSelected(request.x, request.y, request.block, Pal.accent); } + lineRequests.each(this::drawOverRequest); }else if(mode == breaking){ drawBreakSelection(lineStartX, lineStartY, tileX, tileY); } diff --git a/core/src/mindustry/input/Placement.java b/core/src/mindustry/input/Placement.java index bc17d9eb97..8c0586857e 100644 --- a/core/src/mindustry/input/Placement.java +++ b/core/src/mindustry/input/Placement.java @@ -6,12 +6,14 @@ import arc.math.*; import arc.math.geom.*; import arc.struct.*; import arc.util.pooling.*; +import mindustry.entities.units.*; import mindustry.world.*; import mindustry.world.blocks.distribution.*; import static mindustry.Vars.*; public class Placement{ + private static final Seq plans1 = new Seq<>(); private static final Seq tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>(); private static final NormalizeResult result = new NormalizeResult(); private static final NormalizeDrawResult drawResult = new NormalizeDrawResult(); @@ -75,7 +77,7 @@ public class Placement{ var base = tmpPoints2; var result = tmpPoints.clear(); - base.selectFrom(points, p -> p == points.first() || p == points.peek() || Build.validPlace(block, player.team(), p.x, p.y, rotation, false)); + base.selectFrom(points, p -> p == points.first() || p == points.peek() || Build.validPlace(block, player.team(), p.x, p.y, rotation)); boolean addedLast = false; outer: @@ -106,6 +108,59 @@ public class Placement{ points.addAll(result); } + public static void calculateBridges(Seq plans, ItemBridge bridge){ + //check for orthogonal placement + unlocked state + if(!(plans.first().x == plans.peek().x || plans.first().y == plans.peek().y || !bridge.unlockedNow())){ + return; + } + + var result = plans1.clear(); + var team = player.team(); + + outer: + for(int i = 0; i < plans.size;){ + var cur = plans.get(i); + result.add(cur); + + //gap found + if(i < plans.size - 1 && cur.placeable(team) && !plans.get(i + 1).placeable(team)){ + + //find the closest valid position within range + for(int j = i + 1; j < plans.size; j++){ + var other = plans.get(j); + + //out of range now, set to current position and keep scanning forward for next occurrence + if(!bridge.positionsValid(cur.x, cur.y, other.x, other.y)){ + //add 'missed' conveyors + for(int k = i + 1; k < j; k++){ + result.add(plans.get(k)); + } + i = j; + continue outer; + }else if(other.placeable(team)){ + //found a link, assign bridges + cur.block = bridge; + other.block = bridge; + cur.config = new Point2(other.x - cur.x, other.y - cur.y); + + i = j; + continue outer; + } + } + + //if it got here, that means nothing was found. this likely means there's a bunch of stuff at the end; add it and bail out + for(int j = i + 1; j < plans.size; j++){ + result.add(plans.get(j)); + } + break; + }else{ + i ++; + } + } + + plans.set(result); + } + private static float tileHeuristic(Tile tile, Tile other){ Block block = control.input.block; diff --git a/core/src/mindustry/ui/dialogs/LoadoutDialog.java b/core/src/mindustry/ui/dialogs/LoadoutDialog.java index 24e3b2d8f4..311e4d2ea7 100644 --- a/core/src/mindustry/ui/dialogs/LoadoutDialog.java +++ b/core/src/mindustry/ui/dialogs/LoadoutDialog.java @@ -59,7 +59,7 @@ public class LoadoutDialog extends BaseDialog{ public void maxItems() { for(ItemStack stack : stacks){ - stack.amount = total == null ? capacity : Math.min(capacity, total.get(stack.item)); + stack.amount = total == null ? capacity : Math.max(Math.min(capacity, total.get(stack.item)), 0); } } diff --git a/core/src/mindustry/world/blocks/distribution/Conveyor.java b/core/src/mindustry/world/blocks/distribution/Conveyor.java index 8b0a7d45eb..c1f6f53ef6 100644 --- a/core/src/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/mindustry/world/blocks/distribution/Conveyor.java @@ -12,6 +12,7 @@ import mindustry.content.*; import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.input.*; import mindustry.type.*; import mindustry.ui.*; import mindustry.world.*; @@ -71,6 +72,17 @@ public class Conveyor extends Block implements Autotiler{ && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock); } + //stack conveyors should be bridged over, not replaced + @Override + public boolean canReplace(Block other){ + return super.canReplace(other) && !(other instanceof StackConveyor); + } + + @Override + public void handlePlacementLine(Seq plans){ + Placement.calculateBridges(plans, (ItemBridge)Blocks.itemBridge); + } + @Override public TextureRegion[] icons(){ return new TextureRegion[]{regions[0][0]}; diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 8d4b952038..b674de28b7 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -1,6 +1,5 @@ package mindustry.world.blocks.distribution; -import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; @@ -32,10 +31,7 @@ public class ItemBridge extends Block{ public @Load("@-arrow") TextureRegion arrowRegion; //for autolink - @Nullable - public ItemBridgeBuild lastBuild; - @Nullable - public BuildPlan lastPlan; + public @Nullable ItemBridgeBuild lastBuild; public ItemBridge(String name){ super(name); @@ -151,12 +147,12 @@ public class ItemBridge extends Block{ } @Override - public void onNewPlan(BuildPlan plan){ - if(lastPlan != null && lastPlan.config == null && positionsValid(lastPlan.x, lastPlan.y, plan.x, plan.y)){ - lastPlan.config = new Point2(plan.x - lastPlan.x, plan.y - lastPlan.y); + public void handlePlacementLine(Seq plans){ + for(int i = 0; i < plans.size - 1; i++){ + var cur = plans.get(i); + var next = plans.get(i + 1); + cur.config = new Point2(next.x - cur.x, next.y - cur.y); } - - lastPlan = plan; } @Override @@ -176,12 +172,12 @@ public class ItemBridge extends Block{ public void playerPlaced(Object config){ super.playerPlaced(config); - if(config == null){ + //if(config == null){ Tile link = findLink(tile.x, tile.y); if(linkValid(tile, link) && !proximity.contains(link.build)){ link.build.configure(tile.pos()); } - } + //} lastBuild = this; } diff --git a/core/src/mindustry/world/blocks/liquid/Conduit.java b/core/src/mindustry/world/blocks/liquid/Conduit.java index fe7f0086b0..393af2e8e5 100644 --- a/core/src/mindustry/world/blocks/liquid/Conduit.java +++ b/core/src/mindustry/world/blocks/liquid/Conduit.java @@ -13,6 +13,7 @@ import mindustry.content.*; import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.input.*; import mindustry.type.*; import mindustry.world.*; import mindustry.world.blocks.*; @@ -69,6 +70,11 @@ public class Conduit extends LiquidBlock implements Autotiler{ return otherblock.hasLiquids && (otherblock.outputsLiquid || (lookingAt(tile, rotation, otherx, othery, otherblock))) && lookingAtEither(tile, rotation, otherx, othery, otherrot, otherblock); } + @Override + public void handlePlacementLine(Seq plans){ + Placement.calculateBridges(plans, (ItemBridge)Blocks.bridgeConduit); + } + @Override public TextureRegion[] icons(){ return new TextureRegion[]{Core.atlas.find("conduit-bottom"), topRegions[0]}; From d7f848f8cd1e855df2f7e9262ca8a9d5c2566f27 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 22 Feb 2021 10:18:42 -0500 Subject: [PATCH 338/426] contXXXXX constants -> ctrl --- core/assets/bundles/bundle.properties | 2 +- core/assets/bundles/bundle_ko.properties | 4 ++-- core/src/mindustry/logic/GlobalConstants.java | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 4eec090d97..40a3e10fb4 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1548,7 +1548,7 @@ lenum.enabled = Whether the block is enabled. laccess.color = Illuminator color. laccess.controller = Unit controller. If processor controlled, returns processor.\nIf in a formation, returns leader.\nOtherwise, returns the unit itself. laccess.dead = Whether a unit/building is dead or no longer valid. -laccess.controlled = Returns:\n[accent]@contProcessor[] if unit controller is processor\n[accent]@contPlayer[] if unit/building controller is player\n[accent]@contFormation[] if unit is in formation\nOtherwise, 0. +laccess.controlled = Returns:\n[accent]@ctrlProcessor[] if unit controller is processor\n[accent]@ctrlPlayer[] if unit/building controller is player\n[accent]@ctrlFormation[] if unit is in formation\nOtherwise, 0. laccess.commanded = [red]Deprecated. Will be removed![]\nUse [accent]controlled[] instead. graphicstype.clear = Fill the display with a color. diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index d4ebba340b..8a7bf5dfe8 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -1548,8 +1548,8 @@ lenum.enabled = 블록의 활성 여부 lenum.color = 조명 색 설정 laccess.controller = 유닛 제어자. 프로세서가 제어하면, 프로세서를 반환합니다.\n다른 유닛에 의해 지휘되면(G키), 지휘하는 유닛을 반환합니다.\n그 외에는 자신을 반환합니다. laccess.dead = 유닛 또는 건물 사망/무효 여부 -laccess.controlled = 만약 유닛 제어자가 프로세서라면 [accent]@contProcessor[]를 반환합니다.\n만약 유닛/건물 제어자가 플레이어라면 [accent]@contPlayer[]를 반환합니다.\n만약 유닛이 다른 유닛에 의해 지휘되면(G키)[accent]@contFormation[]를 반환합니다.\n그 외에는 0을 반환합니다. -laccess.commanded = [red]이제 사용되지 않으며, 곧 제거될 예정입니다![]\대신 [accent]controlled[]를 사용하세요. +laccess.controlled = 만약 유닛 제어자가 프로세서라면 [accent]@ctrlProcessor[]를 반환합니다.\n만약 유닛/건물 제어자가 플레이어라면 [accent]@ctrlPlayer[]를 반환합니다.\n만약 유닛이 다른 유닛에 의해 지휘되면(G키)[accent]@ctrlFormation[]를 반환합니다.\n그 외에는 0을 반환합니다. +laccess.commanded = [red]이제 사용되지 않으며, 곧 제거될 예정입니다![]\n대신 [accent]controlled[]를 사용하세요. graphicstype.clear = 이 색으로 화면을 채우기 graphicstype.color = 아래 그래픽 실행문들의 색 설정하기 diff --git a/core/src/mindustry/logic/GlobalConstants.java b/core/src/mindustry/logic/GlobalConstants.java index 9781b66c52..be0500bc77 100644 --- a/core/src/mindustry/logic/GlobalConstants.java +++ b/core/src/mindustry/logic/GlobalConstants.java @@ -21,9 +21,9 @@ public class GlobalConstants{ //special enums - put("@contProcessor", 1); - put("@contPlayer", 2); - put("@contFormation", 3); + put("@ctrlProcessor", 1); + put("@ctrlPlayer", 2); + put("@ctrlFormation", 3); //store base content From 2f836d779aa2023f66179203cd5a9e7139db473f Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 22 Feb 2021 10:22:28 -0500 Subject: [PATCH 339/426] Update servers_v6.json --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index e40885d0f1..d7ecfcf0a6 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -1,4 +1,8 @@ [ + { + "name": "RCR", + "address": ["rcr.fvds.ru"] + }, { "name": "mindustry.pl", "address": ["mindustry.pl:6000", "mindustry.pl:6666", "mindustry.pl"] From aabbfd624a31434d220726132010eaf705f87564 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Tue, 23 Feb 2021 15:51:43 +0100 Subject: [PATCH 340/426] Add disarmed status effect that disarms (#4762) * Add disarmed status effect that disarms * Update core/src/mindustry/entities/comp/StatusComp.java Co-authored-by: Anuken * Rename disarms -> disarm Co-authored-by: Anuken --- core/src/mindustry/content/StatusEffects.java | 7 ++++++- core/src/mindustry/entities/comp/StatusComp.java | 5 +++++ core/src/mindustry/entities/comp/UnitComp.java | 4 ++-- core/src/mindustry/entities/comp/WeaponsComp.java | 3 ++- core/src/mindustry/type/StatusEffect.java | 4 +++- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/content/StatusEffects.java b/core/src/mindustry/content/StatusEffects.java index fffdee4018..e0de7ede42 100644 --- a/core/src/mindustry/content/StatusEffects.java +++ b/core/src/mindustry/content/StatusEffects.java @@ -12,7 +12,7 @@ import mindustry.graphics.*; import static mindustry.Vars.*; public class StatusEffects implements ContentList{ - public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed; + public static StatusEffect none, burning, freezing, unmoving, slow, wet, muddy, melting, sapped, tarred, overdrive, overclock, shielded, shocked, blasted, corroded, boss, sporeSlowed, disarmed; @Override public void load(){ @@ -173,5 +173,10 @@ public class StatusEffects implements ContentList{ color = Pal.plastanium; damage = 0.1f; }}; + + disarmed = new StatusEffect("disarmed"){{ + color = Color.valueOf("e9ead3"); + disarm = true; + }}; } } diff --git a/core/src/mindustry/entities/comp/StatusComp.java b/core/src/mindustry/entities/comp/StatusComp.java index 744da3b386..58177c5fdb 100644 --- a/core/src/mindustry/entities/comp/StatusComp.java +++ b/core/src/mindustry/entities/comp/StatusComp.java @@ -20,6 +20,7 @@ abstract class StatusComp implements Posc, Flyingc{ private transient Bits applied = new Bits(content.getBy(ContentType.status).size); @ReadOnly transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1; + @ReadOnly transient boolean disarmed = false; @Import UnitType type; @@ -111,6 +112,7 @@ abstract class StatusComp implements Posc, Flyingc{ applied.clear(); speedMultiplier = damageMultiplier = healthMultiplier = reloadMultiplier = 1f; + disarmed = false; if(statuses.isEmpty()) return; @@ -132,6 +134,9 @@ abstract class StatusComp implements Posc, Flyingc{ healthMultiplier *= entry.effect.healthMultiplier; damageMultiplier *= entry.effect.damageMultiplier; reloadMultiplier *= entry.effect.reloadMultiplier; + + disarmed |= entry.effect.disarm; + entry.effect.update(self(), entry.time); } } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index de80519ba6..47a89e101a 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -32,7 +32,7 @@ import static mindustry.Vars.*; @Component(base = true) abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{ - @Import boolean hovering, dead; + @Import boolean hovering, dead, disarmed; @Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed; @Import Team team; @Import int id; @@ -178,7 +178,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I @Replace public boolean canShoot(){ //cannot shoot while boosting - return !(type.canBoost && isFlying()); + return !disarmed && !(type.canBoost && isFlying()); } @Override diff --git a/core/src/mindustry/entities/comp/WeaponsComp.java b/core/src/mindustry/entities/comp/WeaponsComp.java index 9cc5f8487a..10f2d59b2f 100644 --- a/core/src/mindustry/entities/comp/WeaponsComp.java +++ b/core/src/mindustry/entities/comp/WeaponsComp.java @@ -16,6 +16,7 @@ import static mindustry.Vars.*; @Component abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{ @Import float x, y, rotation, reloadMultiplier; + @Import boolean disarmed; @Import Vec2 vel; @Import UnitType type; @@ -81,7 +82,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{ } boolean canShoot(){ - return true; + return !disarmed; } @Override diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index 19e0135960..2355cbbcaa 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -17,8 +17,10 @@ public class StatusEffect extends MappableContent{ public float healthMultiplier = 1f; /** Unit speed multiplier */ public float speedMultiplier = 1f; - /** Unit speed multiplier */ + /** Unit reload multiplier. */ public float reloadMultiplier = 1f; + /** Unit weapon(s) disabled. */ + public boolean disarm = false; /** Damage per frame. */ public float damage; /** Chance of effect appearing. */ From 08e36aca98e82f5eb57d6f8356aa333e2d35da35 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 23 Feb 2021 10:47:54 -0500 Subject: [PATCH 341/426] Crafter progress modulo / Segment buff --- core/src/mindustry/content/Blocks.java | 4 ++-- .../world/blocks/distribution/ItemBridge.java | 10 ++++------ .../world/blocks/production/GenericCrafter.java | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 78d27b61a2..e7d5915653 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1606,12 +1606,12 @@ public class Blocks implements ContentList{ requirements(Category.turret, with(Items.silicon, 130, Items.thorium, 80, Items.phaseFabric, 40)); health = 250 * size * size; - range = 160f; + range = 180f; hasPower = true; consumes.powerCond(8f, (PointDefenseBuild b) -> b.target != null); size = 2; shootLength = 5f; - bulletDamage = 25f; + bulletDamage = 30f; reloadTime = 9f; }}; diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index b674de28b7..f4c67825eb 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -172,12 +172,10 @@ public class ItemBridge extends Block{ public void playerPlaced(Object config){ super.playerPlaced(config); - //if(config == null){ - Tile link = findLink(tile.x, tile.y); - if(linkValid(tile, link) && !proximity.contains(link.build)){ - link.build.configure(tile.pos()); - } - //} + Tile link = findLink(tile.x, tile.y); + if(linkValid(tile, link) && !proximity.contains(link.build)){ + link.build.configure(tile.pos()); + } lastBuild = this; } diff --git a/core/src/mindustry/world/blocks/production/GenericCrafter.java b/core/src/mindustry/world/blocks/production/GenericCrafter.java index 25021ad20d..11b6c37bc0 100644 --- a/core/src/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/mindustry/world/blocks/production/GenericCrafter.java @@ -119,7 +119,7 @@ public class GenericCrafter extends Block{ } craftEffect.at(x, y); - progress = 0f; + progress %= 1f; } if(outputItem != null && timer(timerDump, dumpTime)){ From e5413cebdca2a11365826d3ee44beabe32a70c53 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 23 Feb 2021 11:29:51 -0500 Subject: [PATCH 342/426] Fixed #4766 --- core/src/mindustry/content/UnitTypes.java | 12 ++++++------ .../maps/planet/SerpuloPlanetGenerator.java | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index b26b418862..c11531fafc 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -412,14 +412,14 @@ public class UnitTypes implements ContentList{ mechStepShake = 0.15f; ammoType = AmmoTypes.powerHigh; - speed = 0.35f; + speed = 0.36f; boostMultiplier = 2.1f; engineOffset = 12f; engineSize = 6f; lowAltitude = true; - health = 7200f; - armor = 8f; + health = 7500f; + armor = 9f; canBoost = true; landShake = 4f; immunities = ObjectSet.with(StatusEffects.burning); @@ -443,8 +443,8 @@ public class UnitTypes implements ContentList{ cooldownTime = 200f; bullet = new ContinuousLaserBulletType(){{ - damage = 26f; - length = 170f; + damage = 28f; + length = 175f; hitEffect = Fx.hitMeltHeal; drawSize = 420f; lifetime = 160f; @@ -454,7 +454,7 @@ public class UnitTypes implements ContentList{ shootEffect = Fx.greenLaserChargeSmall; - incendChance = 0.08f; + incendChance = 0.09f; incendSpread = 5f; incendAmount = 1; diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java index cc0b1ea934..504c07dfa3 100644 --- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java @@ -338,7 +338,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ } }else if(floor != Blocks.basalt && floor != Blocks.ice && floor.asFloor().hasSurface()){ float noise = noise(x + 782, y, 5, 0.75f, 260f, 1f); - if(noise > 0.67f && !enemies.contains(e -> Mathf.within(x, y, e.x, e.y, 8))){ + if(noise > 0.67f && !roomseq.contains(e -> Mathf.within(x, y, e.x, e.y, 14))){ if(noise > 0.72f){ floor = noise > 0.78f ? Blocks.taintedWater : (floor == Blocks.sand ? Blocks.sandWater : Blocks.darksandTaintedWater); }else{ From 830eb86a0f2d7ee26177d52ffee6b233a5887e3f Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 23 Feb 2021 12:53:43 -0500 Subject: [PATCH 343/426] Better power node linking visualization --- .../src/mindustry/world/blocks/power/PowerNode.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 0c66eef09a..6057a513c8 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -27,7 +27,7 @@ public class PowerNode extends PowerBlock{ protected static BuildPlan otherReq; protected final static ObjectSet graphs = new ObjectSet<>(); - protected final static Seq tmpPoints = new Seq<>(), tmpPoints2 = new Seq<>(); + protected static int returnInt = 0; public @Load("laser") TextureRegion laser; public @Load("laser-end") TextureRegion laserEnd; @@ -144,6 +144,9 @@ public class PowerNode extends PowerBlock{ Drawf.circles(x * tilesize + offset, y * tilesize + offset, laserRange * tilesize); getPotentialLinks(tile, other -> { + Draw.color(laserColor1, Renderer.laserOpacity * 0.5f); + drawLaser(tile.team(), x * tilesize + offset, y * tilesize + offset, other.x, other.y, size, other.block.size); + Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place); insulators(tile.x, tile.y, other.tileX(), other.tileY(), cause -> { @@ -214,9 +217,13 @@ public class PowerNode extends PowerBlock{ return Float.compare(a.dst2(tile), b.dst2(tile)); }); + returnInt = 0; + tempTileEnts.each(valid, t -> { - graphs.add(t.power.graph); - others.get(t); + if(returnInt ++ < maxNodes){ + graphs.add(t.power.graph); + others.get(t); + } }); } From ad2a18f929bc3a0d9b28eb03213b3c0061cd34bf Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Tue, 23 Feb 2021 22:53:23 +0300 Subject: [PATCH 344/426] Fix player.locale to be default (#4768) * fix player.locale == default * Update NetClient.java --- core/src/mindustry/core/NetClient.java | 8 +++++++- core/src/mindustry/core/NetServer.java | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index d89b7f8481..e0cdfee91d 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -26,6 +26,7 @@ import mindustry.world.*; import mindustry.world.modules.*; import java.io.*; +import java.util.*; import java.util.zip.*; import static mindustry.Vars.*; @@ -73,9 +74,14 @@ public class NetClient implements ApplicationListener{ disconnectQuietly(); }); + String locale = Core.settings.getString("locale"); + if(locale.equals("default")){ + locale = Locale.getDefault().toString(); + } + ConnectPacket c = new ConnectPacket(); c.name = player.name; - c.locale = Core.settings.getString("locale"); + c.locale = locale; c.mods = mods.getModStrings(); c.mobile = mobile; c.versionType = Version.type; diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 9ce38aa62a..daf6582dbc 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -196,7 +196,7 @@ public class NetServer implements ApplicationListener{ } if(packet.locale == null){ - packet.locale = "en_US"; + packet.locale = "en"; } String ip = con.address; From 502c7eb3886b0ed351a16c779ad1ab108fc196c7 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 23 Feb 2021 17:07:40 -0500 Subject: [PATCH 345/426] arc --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 83c7ad7b59..50e7c186cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=26a96b2eb63608f200e5b93873013dd85c31e39f +archash=cace621b0f6dbbe263e9adbfc1a9f82bd74a6b9a From afbde49fa2ee4aa2e631dd8ca32b9e367fdda837 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 24 Feb 2021 09:52:53 -0500 Subject: [PATCH 346/426] Fixed #4776 / Fixed #4772 --- core/src/mindustry/ai/types/FlyingAI.java | 2 +- core/src/mindustry/entities/comp/BuildingComp.java | 1 + core/src/mindustry/entities/comp/UnitComp.java | 1 + core/src/mindustry/logic/LAccess.java | 1 + .../mindustry/world/blocks/distribution/ItemBridge.java | 8 +++++--- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java index 6df803b1f4..72d7eda4ff 100644 --- a/core/src/mindustry/ai/types/FlyingAI.java +++ b/core/src/mindustry/ai/types/FlyingAI.java @@ -13,7 +13,7 @@ public class FlyingAI extends AIController{ public void updateMovement(){ if(target != null && unit.hasWeapons() && command() == UnitCommand.attack){ if(!unit.type.circleTarget){ - moveTo(target, unit.range() * 0.8f); + moveTo(target, unit.type.range * 0.8f); unit.lookAt(target); }else{ attack(120f); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 9cc2573147..d52e3816a8 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1339,6 +1339,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case enabled -> enabled ? 1 : 0; case controlled -> this instanceof ControlBlock c && c.isControlled() ? 2 : 0; case payloadCount -> getPayload() != null ? 1 : 0; + case size -> block.size; default -> Float.NaN; //gets converted to null in logic }; } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 47a89e101a..9acc0f8c95 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -142,6 +142,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case controlled -> controller instanceof LogicAI ? 1 : controller instanceof Player ? 2 : controller instanceof FormationAI ? 3 : 0; case commanded -> controller instanceof FormationAI ? 1 : 0; case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; + case size -> hitSize / tilesize; default -> Float.NaN; }; } diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index e3403a56be..dad09faf56 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -27,6 +27,7 @@ public enum LAccess{ y, shootX, shootY, + size, dead, range, shooting, diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index f4c67825eb..91d25be0c4 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -172,9 +172,11 @@ public class ItemBridge extends Block{ public void playerPlaced(Object config){ super.playerPlaced(config); - Tile link = findLink(tile.x, tile.y); - if(linkValid(tile, link) && !proximity.contains(link.build)){ - link.build.configure(tile.pos()); + if(config == null){ + Tile link = findLink(tile.x, tile.y); + if(linkValid(tile, link) && !proximity.contains(link.build)){ + link.build.configure(tile.pos()); + } } lastBuild = this; From 25ae7b97aaa3006ed38d25469a6f3ab97e6034ce Mon Sep 17 00:00:00 2001 From: Minxyzgo <71958008+Minxyzgo@users.noreply.github.com> Date: Thu, 25 Feb 2021 01:25:38 +0800 Subject: [PATCH 347/426] schematic uses camera position (#4775) * Update InputHandler.java * Update InputHandler.java * Update MobileInput.java * Update InputHandler.java * Update MobileInput.java --- core/src/mindustry/input/MobileInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 22a61c3d18..c05d709fa9 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -424,7 +424,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public void useSchematic(Schematic schem){ selectRequests.clear(); - selectRequests.addAll(schematics.toRequests(schem, player.tileX(), player.tileY())); + selectRequests.addAll(schematics.toRequests(schem, World.toTile(Core.camera.position.x), World.toTile(Core.camera.position.y))); lastSchematic = schem; } From 4b6a83dd82cce8023fb7f66ac65f3f545a52f3cf Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 24 Feb 2021 15:01:44 -0500 Subject: [PATCH 348/426] Improved auto-bridging with conveyors --- core/src/mindustry/input/Placement.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/input/Placement.java b/core/src/mindustry/input/Placement.java index 8c0586857e..a60853e8e5 100644 --- a/core/src/mindustry/input/Placement.java +++ b/core/src/mindustry/input/Placement.java @@ -114,6 +114,9 @@ public class Placement{ return; } + Boolf placeable = plan -> (plan.placeable(player.team())) || + (plan.tile() != null && plan.tile().block() == plan.block); //don't count the same block as inaccessible + var result = plans1.clear(); var team = player.team(); @@ -123,7 +126,7 @@ public class Placement{ result.add(cur); //gap found - if(i < plans.size - 1 && cur.placeable(team) && !plans.get(i + 1).placeable(team)){ + if(i < plans.size - 1 && placeable.get(cur) && !placeable.get(plans.get(i + 1))){ //find the closest valid position within range for(int j = i + 1; j < plans.size; j++){ From 0672878920249c9337f71dedeabf4e8bbd1f55cf Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 24 Feb 2021 15:27:22 -0500 Subject: [PATCH 349/426] Fixed #4781 --- core/src/mindustry/game/Schematics.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index e0e067a029..1895857e43 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -391,7 +391,7 @@ public class Schematics implements Loadable{ if(tile != null && !counted.contains(tile.pos()) && (realBlock.isVisible() || realBlock instanceof CoreBlock)){ - Object config = tile.config(); + Object config = tile instanceof ConstructBuild cons ? cons.lastConfig : tile.config(); tiles.add(new Stile(realBlock, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation)); counted.add(tile.pos()); From c0d9712beb2f7867e10537ecc1b5ddce4000c5a0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 25 Feb 2021 08:39:35 -0500 Subject: [PATCH 350/426] Fixed #4784 --- core/src/mindustry/world/blocks/units/RepairPoint.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index 72e0f506d2..8e6a03e834 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -38,6 +38,7 @@ public class RepairPoint extends Block{ flags = EnumSet.of(BlockFlag.repair); hasPower = true; outlineIcon = true; + expanded = true; } @Override From 781410ea049752480b5cd29f97389cee553009c0 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Thu, 25 Feb 2021 06:43:40 -0700 Subject: [PATCH 351/426] Double-tap to mine, tap anywhere to cancel (#4469) * Double-tap to mine, tap anywhere to cancel * Make comment consistent * Remove desktop left-click mining cancel, prioritize mobile unit control over mining * Mobile: double-tap doesn't configure blocks if unit was double-tapped; control unit detected in first tap of double-tap * Add 'double-tap to mine' setting (default off) * Desktop: cancel mining when mined tile is clicked * Comment typo * Prevent redundant condition check * Cleanup Co-authored-by: Anuken --- core/assets/bundles/bundle.properties | 1 + core/src/mindustry/input/DesktopInput.java | 12 ++++++++-- core/src/mindustry/input/InputHandler.java | 17 +++++++++++++ core/src/mindustry/input/MobileInput.java | 24 ++++++++++++------- .../ui/dialogs/SettingsMenuDialog.java | 2 ++ 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 40a3e10fb4..c76e21001d 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -800,6 +800,7 @@ setting.logichints.name = Logic Hints setting.flow.name = Display Resource Flow Rate setting.backgroundpause.name = Pause In Background setting.buildautopause.name = Auto-Pause Building +setting.doubletapmine.name = Double-Tap to Mine setting.modcrashdisable.name = Disable Mods On Startup Crash setting.animatedwater.name = Animated Surfaces setting.animatedshields.name = Animated Shields diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 3de5997ec4..4b7143b22f 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -44,6 +44,10 @@ public class DesktopInput extends InputHandler{ public boolean deleting = false, shouldShoot = false, panning = false; /** Mouse pan speed. */ public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f; + /** Delta time between consecutive clicks. */ + public long selectMillis = 0; + /** Previously selected tile. */ + public Tile prevSelected; boolean showHint(){ return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && @@ -487,15 +491,19 @@ public class DesktopInput extends InputHandler{ sreq = req; }else if(req != null && req.breaking){ deleting = true; + }else if(Core.settings.getBool("doubletapmine") && selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500){ + tryBeginMine(selected); }else if(selected != null){ //only begin shooting if there's no cursor event - if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem && - !tryBeginMine(selected) && player.unit().mineTile == null && !Core.scene.hasKeyboard()){ + if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem + && (Core.settings.getBool("doubletapmine") ? !tryStopMine(selected) : !tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ player.shooting = shouldShoot; } }else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine player.shooting = shouldShoot; } + selectMillis = Time.millis(); + prevSelected = selected; }else if(Core.input.keyTap(Binding.deselect) && isPlacing()){ block = null; mode = none; diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index c8ab2b4f21..fe082d5468 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -955,6 +955,23 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ return false; } + /** Tries to stop mining, returns true if mining was stopped. */ + boolean tryStopMine(){ + if(player.unit().mining()){ + player.unit().mineTile = null; + return true; + } + return false; + } + + boolean tryStopMine(Tile tile){ + if(player.unit().mineTile == tile){ + player.unit().mineTile = null; + return true; + } + return false; + } + boolean canMine(Tile tile){ return !Core.scene.hasMouse() && tile.drop() != null diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index c05d709fa9..1624beedef 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -71,6 +71,8 @@ public class MobileInput extends InputHandler implements GestureListener{ public Teamc target; /** Payload target being moved to. Can be a position (for dropping), or a unit/block. */ public Position payloadTarget; + /** Unit last tapped, or null if last tap was not on a unit. */ + public Unit unitTapped; //region utility methods @@ -599,11 +601,7 @@ public class MobileInput extends InputHandler implements GestureListener{ //add to selection queue if it's a valid BREAK position selectRequests.add(new BuildPlan(linked.x, linked.y)); }else{ - if(!canTapPlayer(worldx, worldy) && !tileTapped(linked.build)){ - tryBeginMine(cursor); - } - - //control units. + //control units if(count == 2){ //reset payload target payloadTarget = null; @@ -611,12 +609,20 @@ public class MobileInput extends InputHandler implements GestureListener{ 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); }else{ - //control a unit/block - Unit on = selectedUnit(); - if(on != null){ - Call.unitControl(player, on); + //control a unit/block detected on first tap of double-tap + if(unitTapped != null){ + Call.unitControl(player, unitTapped); + }else if(!tryBeginMine(cursor)){ + tileTapped(linked.build); } } + return false; + } + + unitTapped = selectedUnit(); + //prevent mining if placing/breaking blocks + if(!tryStopMine() && !canTapPlayer(worldx, worldy) && !tileTapped(linked.build) && mode == none && !Core.settings.getBool("doubletapmine")){ + tryBeginMine(cursor); } } diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index 60acd1637b..5290b6c5aa 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -327,6 +327,8 @@ public class SettingsMenuDialog extends SettingsDialog{ game.checkPref("buildautopause", false); } + game.checkPref("doubletapmine", false); + if(!ios){ game.checkPref("modcrashdisable", true); } From f6eba3edaeba7a1af36212b8d20de1f219a7d0ec Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 25 Feb 2021 09:12:17 -0500 Subject: [PATCH 352/426] Synchronized settings / Dead units sense as non-controlled --- core/src/mindustry/entities/comp/UnitComp.java | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 9acc0f8c95..f0c26cc0b4 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -139,8 +139,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case mineX -> mining() ? mineTile.x : -1; case mineY -> mining() ? mineTile.y : -1; case flag -> flag; - case controlled -> controller instanceof LogicAI ? 1 : controller instanceof Player ? 2 : controller instanceof FormationAI ? 3 : 0; - case commanded -> controller instanceof FormationAI ? 1 : 0; + case controlled -> !isValid() ? 0 : controller instanceof LogicAI ? 1 : controller instanceof Player ? 2 : controller instanceof FormationAI ? 3 : 0; + case commanded -> controller instanceof FormationAI && isValid() ? 1 : 0; case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; case size -> hitSize / tilesize; default -> Float.NaN; diff --git a/gradle.properties b/gradle.properties index 50e7c186cd..e8bee058ae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=cace621b0f6dbbe263e9adbfc1a9f82bd74a6b9a +archash=919af3d6fab9319626fbd0e28ccb0a8588fcc221 From f5ac3ff7b00648f00f17a0ee12d1195a642604eb Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 25 Feb 2021 10:54:05 -0500 Subject: [PATCH 353/426] null controller for dead units --- core/src/mindustry/entities/comp/UnitComp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index f0c26cc0b4..bd251d4d3b 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -153,7 +153,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case type -> type; case name -> controller instanceof Player p ? p.name : null; case firstItem -> stack().amount == 0 ? null : item(); - case controller -> controller instanceof LogicAI log ? log.controller : controller instanceof FormationAI form ? form.leader : this; + case controller -> !isValid() ? null : controller instanceof LogicAI log ? log.controller : controller instanceof FormationAI form ? form.leader : this; case payloadType -> self() instanceof Payloadc pay ? (pay.payloads().isEmpty() ? null : pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type : From 1bb97cae39bc4a8faa91626053067ddc18fa7a7e Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 25 Feb 2021 18:34:24 -0500 Subject: [PATCH 354/426] Fixed #4792 --- core/src/mindustry/world/blocks/distribution/ItemBridge.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 91d25be0c4..527acbe78a 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -151,7 +151,9 @@ public class ItemBridge extends Block{ for(int i = 0; i < plans.size - 1; i++){ var cur = plans.get(i); var next = plans.get(i + 1); - cur.config = new Point2(next.x - cur.x, next.y - cur.y); + if(positionsValid(cur.x, cur.y, next.x, next.y)){ + cur.config = new Point2(next.x - cur.x, next.y - cur.y); + } } } From 2df74846491197d877a9f808af16f096446274bd Mon Sep 17 00:00:00 2001 From: Darkness6030 <79508138+Darkness6030@users.noreply.github.com> Date: Fri, 26 Feb 2021 19:13:51 +0300 Subject: [PATCH 355/426] Add servers to global list (#4761) * Add servers to global list --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index d7ecfcf0a6..da0b3cbd65 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -86,5 +86,9 @@ { "name": "Nydus", "address": ["v6.mindustry.nydus.app:6566"] + }, + { + "name": "Darkdustry", + "address": ["mindurka.ru"] } ] From 8349c8a5b85d2cff4620f3a17d34a561bb2a5f5e Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 26 Feb 2021 13:13:37 -0500 Subject: [PATCH 356/426] Fixed #4802 --- core/src/mindustry/core/NetClient.java | 7 +++++++ core/src/mindustry/type/UnitType.java | 2 +- core/src/mindustry/ui/dialogs/JoinDialog.java | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index e0cdfee91d..8e6032c359 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -66,6 +66,13 @@ public class NetClient implements ApplicationListener{ reset(); + //connection after reset + if(!net.client()){ + Log.info("Connection canceled."); + disconnectQuietly(); + return; + } + ui.loadfrag.hide(); ui.loadfrag.show("@connecting.data"); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 30d4e5155b..7616618e48 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -193,7 +193,7 @@ public class UnitType extends UnlockableContent{ if(unit.controller() instanceof LogicAI){ table.row(); - table.add(Blocks.microProcessor.emoji() + " " + Core.bundle.get("units.processorcontrol")).growX().left(); + table.add(Blocks.microProcessor.emoji() + " " + Core.bundle.get("units.processorcontrol")).growX().wrap().left(); table.row(); table.label(() -> Iconc.settings + " " + (long)unit.flag + "").color(Color.lightGray).growX().wrap().left(); } diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index 166b4c53a9..cd559de581 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -463,8 +463,10 @@ public class JoinDialog extends BaseDialog{ net.reset(); Vars.netClient.beginConnecting(); net.connect(lastIp = ip, lastPort = port, () -> { - hide(); - add.hide(); + if(net.client()){ + hide(); + add.hide(); + } }); }); } From ae6be1db3b2ab4153024464fb687f401496fe8c1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 26 Feb 2021 18:51:14 -0500 Subject: [PATCH 357/426] UnitSpawnAbility 'type' field JSON compat / Fixed health bar out of bounds --- .../entities/abilities/UnitSpawnAbility.java | 16 ++++++++-------- core/src/mindustry/net/Net.java | 2 +- core/src/mindustry/ui/fragments/HudFragment.java | 2 ++ gradle.properties | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/src/mindustry/entities/abilities/UnitSpawnAbility.java b/core/src/mindustry/entities/abilities/UnitSpawnAbility.java index 422a02bbba..ac4218946b 100644 --- a/core/src/mindustry/entities/abilities/UnitSpawnAbility.java +++ b/core/src/mindustry/entities/abilities/UnitSpawnAbility.java @@ -15,14 +15,14 @@ import mindustry.ui.*; import static mindustry.Vars.*; public class UnitSpawnAbility extends Ability{ - public UnitType type; + public UnitType unit; public float spawnTime = 60f, spawnX, spawnY; public Effect spawnEffect = Fx.spawn; protected float timer; - public UnitSpawnAbility(UnitType type, float spawnTime, float spawnX, float spawnY){ - this.type = type; + public UnitSpawnAbility(UnitType unit, float spawnTime, float spawnX, float spawnY){ + this.unit = unit; this.spawnTime = spawnTime; this.spawnX = spawnX; this.spawnY = spawnY; @@ -35,10 +35,10 @@ public class UnitSpawnAbility extends Ability{ public void update(Unit unit){ timer += Time.delta * state.rules.unitBuildSpeedMultiplier; - if(timer >= spawnTime && Units.canCreate(unit.team, type)){ + if(timer >= spawnTime && Units.canCreate(unit.team, this.unit)){ float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX); spawnEffect.at(x, y); - Unit u = type.create(unit.team); + Unit u = this.unit.create(unit.team); u.set(x, y); u.rotation = unit.rotation; if(!Vars.net.client()){ @@ -51,16 +51,16 @@ public class UnitSpawnAbility extends Ability{ @Override public void draw(Unit unit){ - if(Units.canCreate(unit.team, type)){ + if(Units.canCreate(unit.team, this.unit)){ Draw.draw(Draw.z(), () -> { float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX); - Drawf.construct(x, y, type.icon(Cicon.full), unit.rotation - 90, timer / spawnTime, 1f, timer); + Drawf.construct(x, y, this.unit.icon(Cicon.full), unit.rotation - 90, timer / spawnTime, 1f, timer); }); } } @Override public String localized(){ - return Core.bundle.format("ability.unitspawn", type.localizedName); + return Core.bundle.format("ability.unitspawn", unit.localizedName); } } diff --git a/core/src/mindustry/net/Net.java b/core/src/mindustry/net/Net.java index 85499dd1d2..194c6dabbf 100644 --- a/core/src/mindustry/net/Net.java +++ b/core/src/mindustry/net/Net.java @@ -337,7 +337,7 @@ public class Net{ */ void discoverServers(Cons callback, Runnable done); - /** Ping a host. If an error occured, failed() should be called with the exception. */ + /** Ping a host. If an error occurred, failed() should be called with the exception. */ void pingHost(String address, int port, Cons valid, Cons failed); /** Host a server at specified port. */ diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index d43410facb..0884707e9e 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -643,6 +643,8 @@ public class HudFragment extends Fragment{ void drawInner(Color color, float fract){ if(fract < 0) return; + + fract = Mathf.clamp(fract); if(flip){ x += width; width = -width; diff --git a/gradle.properties b/gradle.properties index e8bee058ae..92097f8f77 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=919af3d6fab9319626fbd0e28ccb0a8588fcc221 +archash=9f916a1b401216c68e39635f6c99769391c8555a From e4ecfc4ee7b1d4b65ebbbd231314ecc77ad837b1 Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Fri, 26 Feb 2021 19:06:27 -0500 Subject: [PATCH 358/426] Fixed #4791 since it is 100% a bug (#4801) * Fixed #4719 since it is 100% a bug This fix is somewhat janky as it checks if the rotation matches the exact original rotation but the likelihood of someone needing bridges along a belt rotated 1 or -1 times is super low. https://aethex.is-a.fail/t13ETd.webm * unjank rotation * fix potential crash, styling * Use mathf.mod --- core/src/mindustry/input/Placement.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/input/Placement.java b/core/src/mindustry/input/Placement.java index a60853e8e5..21532f21c7 100644 --- a/core/src/mindustry/input/Placement.java +++ b/core/src/mindustry/input/Placement.java @@ -119,6 +119,7 @@ public class Placement{ var result = plans1.clear(); var team = player.team(); + var rotated = plans.first().tile() != null && plans.first().tile().absoluteRelativeTo(plans.peek().x, plans.peek().y) == Mathf.mod(plans.first().rotation + 2, 4); outer: for(int i = 0; i < plans.size;){ @@ -144,7 +145,11 @@ public class Placement{ //found a link, assign bridges cur.block = bridge; other.block = bridge; - cur.config = new Point2(other.x - cur.x, other.y - cur.y); + if(rotated){ + other.config = new Point2(cur.x - other.x, cur.y - other.y); + }else{ + cur.config = new Point2(other.x - cur.x, other.y - cur.y); + } i = j; continue outer; From 5037c4e00e51b70fcfd9f817233736fdcd6c04cf Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Sat, 27 Feb 2021 10:12:00 -0500 Subject: [PATCH 359/426] Fix a few issues w/ double tap mining (#4798) Currently, double tap mining consumes clicks so it prevents the player from configuring any block if they click twice within 500ms. The double tap mining was also using the `selected` var which could have been null causing a crash. This is a very messy solution but it does the job good enough --- core/src/mindustry/input/DesktopInput.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 4b7143b22f..a5114a4832 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -491,12 +491,10 @@ public class DesktopInput extends InputHandler{ sreq = req; }else if(req != null && req.breaking){ deleting = true; - }else if(Core.settings.getBool("doubletapmine") && selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500){ - tryBeginMine(selected); }else if(selected != null){ //only begin shooting if there's no cursor event if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem - && (Core.settings.getBool("doubletapmine") ? !tryStopMine(selected) : !tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ + && !((!settings.getBool("doubletapmine") || selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ player.shooting = shouldShoot; } }else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine From 44d10a355ed7f4be3f712243fd1a8b1b7bab11f6 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 27 Feb 2021 10:16:54 -0500 Subject: [PATCH 360/426] Improved power node link preview check --- core/src/mindustry/input/DesktopInput.java | 2 +- core/src/mindustry/world/Tile.java | 5 +++++ .../mindustry/world/blocks/power/PowerNode.java | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index a5114a4832..d3d22c0510 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -494,7 +494,7 @@ public class DesktopInput extends InputHandler{ }else if(selected != null){ //only begin shooting if there's no cursor event if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem - && !((!settings.getBool("doubletapmine") || selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ + && !((!settings.getBool("doubletapmine") || (selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500)) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ player.shooting = shouldShoot; } }else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine diff --git a/core/src/mindustry/world/Tile.java b/core/src/mindustry/world/Tile.java index e5fb9cbc0d..6a4dac41b8 100644 --- a/core/src/mindustry/world/Tile.java +++ b/core/src/mindustry/world/Tile.java @@ -491,6 +491,11 @@ public class Tile implements Position, QuadTreeObject, Displayable{ return block.solid && block.fillsTile && !block.synthetic() ? data : 0; } + /** @return true if these tiles are right next to eacho ther. */ + public boolean adjacentTo(Tile tile){ + return relativeTo(tile) != -1; + } + protected void preChanged(){ if(build != null){ //only call removed() for the center block - this only gets called once. diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 6057a513c8..ee7bea0356 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -196,10 +196,23 @@ public class PowerNode extends PowerBlock{ Boolf valid = other -> other != null && other.tile() != tile && other.power != null && (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() - && !other.proximity.contains(e -> e.tile == tile) && !graphs.contains(other.power.graph); + && !graphs.contains(other.power.graph) && + !Structs.contains(Edges.getEdges(size), p -> { //do not link to adjacent buildings + var t = world.tile(tile.x + p.x, tile.y + p.y); + return t != null && t.build == other; + }); tempTileEnts.clear(); graphs.clear(); + + //add conducting graphs to prevent double link + for(var p : Edges.getEdges(size)){ + Tile other = tile.nearby(p); + if(other != null && other.team() == player.team() && other.build != null && other.build.power != null){ + graphs.add(other.build.power.graph); + } + } + if(tile.build != null && tile.build.power != null){ graphs.add(tile.build.power.graph); } From 2146b35e5a57592d700f6e9bbd15e0475c29903d Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sat, 27 Feb 2021 16:21:11 +0100 Subject: [PATCH 361/426] eacho ther (#4810) * eacho ther * Update Tile.java --- core/src/mindustry/world/Tile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/world/Tile.java b/core/src/mindustry/world/Tile.java index 6a4dac41b8..2d9f1f98fb 100644 --- a/core/src/mindustry/world/Tile.java +++ b/core/src/mindustry/world/Tile.java @@ -491,7 +491,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{ return block.solid && block.fillsTile && !block.synthetic() ? data : 0; } - /** @return true if these tiles are right next to eacho ther. */ + /** @return true if these tiles are right next to each other. */ public boolean adjacentTo(Tile tile){ return relativeTo(tile) != -1; } From 0c00760ae0dcc4396df986c722f01a2d6ad08fa0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 27 Feb 2021 15:10:34 -0500 Subject: [PATCH 362/426] Fixed result duplication in logic UI --- core/src/mindustry/logic/LStatements.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 21fddc023f..80c7548c87 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -603,7 +603,7 @@ public class LStatements{ table.add(" = "); if(op.unary){ - opButton(table); + opButton(table, table); field(table, a, str -> a = str); }else{ @@ -617,35 +617,35 @@ public class LStatements{ table.table(c -> { c.color.set(color()); c.left(); - funcs(c); + funcs(c, table); }).colspan(2).left(); }else{ - funcs(table); + funcs(table, table); } }else{ field(table, a, str -> a = str); - opButton(table); + opButton(table, table); field(table, b, str -> b = str); } } } - void funcs(Table table){ - opButton(table); + void funcs(Table table, Table parent){ + opButton(table, parent); field(table, a, str -> a = str); field(table, b, str -> b = str); } - void opButton(Table table){ + void opButton(Table table, Table parent){ table.button(b -> { b.label(() -> op.symbol); b.clicked(() -> showSelect(b, LogicOp.all, op, o -> { op = o; - rebuild(table); + rebuild(parent); })); }, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color); } From c55ff4ad5e912b1effffe523c6c2e2437aca49e3 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Sun, 28 Feb 2021 06:19:27 -0800 Subject: [PATCH 363/426] Desktop double-click mining: fix click on mined tile to cancel (#4815) --- core/src/mindustry/input/DesktopInput.java | 2 +- core/src/mindustry/input/InputHandler.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index d3d22c0510..5ec8b98fce 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -494,7 +494,7 @@ public class DesktopInput extends InputHandler{ }else if(selected != null){ //only begin shooting if there's no cursor event if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem - && !((!settings.getBool("doubletapmine") || (selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500)) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ + && !(tryStopMine(selected) || (!settings.getBool("doubletapmine") || selected == prevSelected && Time.timeSinceMillis(selectMillis) < 500) && tryBeginMine(selected)) && !Core.scene.hasKeyboard()){ player.shooting = shouldShoot; } }else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index fe082d5468..23e798273d 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -948,8 +948,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ /** Tries to begin mining a tile, returns true if successful. */ boolean tryBeginMine(Tile tile){ if(canMine(tile)){ - //if a block is clicked twice, reset it - player.unit().mineTile = player.unit().mineTile == tile ? null : tile; + player.unit().mineTile = tile; return true; } return false; From 662515ce2e6847216aad1642e7fd035327df0661 Mon Sep 17 00:00:00 2001 From: genNAowl <68400583+genNAowl@users.noreply.github.com> Date: Sun, 28 Feb 2021 06:19:35 -0800 Subject: [PATCH 364/426] Make RepairPoints implement Ranged (#4813) Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com> --- core/src/mindustry/world/blocks/units/RepairPoint.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index 8e6a03e834..9833276112 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -11,6 +11,7 @@ import mindustry.annotations.Annotations.*; import mindustry.entities.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.logic.*; import mindustry.world.*; import mindustry.world.meta.*; @@ -63,7 +64,7 @@ public class RepairPoint extends Block{ return new TextureRegion[]{baseRegion, region}; } - public class RepairPointBuild extends Building{ + public class RepairPointBuild extends Building implements Ranged{ public Unit target; public float strength, rotation = 90; @@ -126,6 +127,11 @@ public class RepairPoint extends Block{ return Mathf.equal(efficiency(), 0f, 0.01f) ? BlockStatus.noInput : cons.status(); } + @Override + public float range(){ + return repairRadius; + } + @Override public void write(Writes write){ super.write(write); From d025ba63e1c692845f713deceb4d536d8af19d7d Mon Sep 17 00:00:00 2001 From: FiliusPatris Date: Sun, 28 Feb 2021 19:27:47 +0100 Subject: [PATCH 365/426] Display map names with underscores (#4819) This makes it obvious how to specify map names with spaces. It also allows for copy-pasting form the output of `maps`. --- server/src/mindustry/server/ServerControl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index 66ba27b107..bd3507c936 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -339,7 +339,7 @@ public class ServerControl implements ApplicationListener{ if(!maps.all().isEmpty()){ info("Maps:"); for(Map map : maps.all()){ - info(" @: &fi@ / @x@", map.name(), map.custom ? "Custom" : "Default", map.width, map.height); + info(" @: &fi@ / @x@", map.name().replace(' ', '_'), map.custom ? "Custom" : "Default", map.width, map.height); } }else{ info("No maps found."); From 526157a514f1d36e697560992fc6bd8366463052 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Sun, 28 Feb 2021 19:58:06 +0100 Subject: [PATCH 366/426] Draw to-be affected blocks when placing projectors (#4818) --- core/src/mindustry/world/blocks/defense/MendProjector.java | 4 +++- .../mindustry/world/blocks/defense/OverdriveProjector.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/blocks/defense/MendProjector.java b/core/src/mindustry/world/blocks/defense/MendProjector.java index 25a4c64544..9a478e05c0 100644 --- a/core/src/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/mindustry/world/blocks/defense/MendProjector.java @@ -54,7 +54,9 @@ public class MendProjector extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ - Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.accent); + Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, baseColor); + + indexer.eachBlock(player.team(), x * tilesize + offset, y * tilesize + offset, range, other -> true, other -> Drawf.selected(other, Tmp.c1.set(baseColor).a(Mathf.absin(4f, 1f)))); } public class MendBuild extends Building implements Ranged{ diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index 5066186e71..5de49cacd2 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -47,7 +47,9 @@ public class OverdriveProjector extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ - Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.accent); + Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, baseColor); + + indexer.eachBlock(player.team(), x * tilesize + offset, y * tilesize + offset, range, other -> other.block.canOverdrive, other -> Drawf.selected(other, Tmp.c1.set(baseColor).a(Mathf.absin(4f, 1f)))); } @Override From 49bccffd7cbdd14452de270ee08207db81fbc69f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 28 Feb 2021 17:17:03 -0500 Subject: [PATCH 367/426] Link previews for power blocks near nodes --- .../mindustry/entities/comp/BuildingComp.java | 20 ++------ core/src/mindustry/world/Block.java | 17 +++++++ .../world/blocks/experimental/BlockForge.java | 2 +- .../world/blocks/power/PowerNode.java | 49 ++++++++++++++++++- .../world/blocks/units/Reconstructor.java | 2 +- .../world/blocks/units/UnitFactory.java | 2 +- 6 files changed, 72 insertions(+), 20 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index d52e3816a8..b7dd1af01b 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -910,24 +910,12 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, public void placed(){ if(net.client()) return; - if(block.consumesPower || block.outputsPower){ - int range = 12; - tempTiles.clear(); - Geometry.circle(tileX(), tileY(), range, (x, y) -> { - Building other = world.build(x, y); - if(other != null && other.block instanceof PowerNode node && node.linkValid(other, self()) && !PowerNode.insulated(other, self()) - && !other.proximity().contains(this.self()) && - !(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){ - tempTiles.add(other.tile); + if((block.consumesPower || block.outputsPower) && block.hasPower){ + PowerNode.getNodeLinks(tile, block, other -> { + if(!other.power.links.contains(pos())){ + other.configureAny(pos()); } }); - tempTiles.sort(Structs.comparingFloat(t -> t.dst2(tile))); - if(!tempTiles.isEmpty()){ - Tile toLink = tempTiles.first(); - if(!toLink.build.power.links.contains(pos())){ - toLink.build.configureAny(pos()); - } - } } } diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 66f64c5e4a..052e439594 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -26,6 +26,7 @@ import mindustry.graphics.MultiPacker.*; import mindustry.type.*; import mindustry.ui.*; import mindustry.world.blocks.environment.*; +import mindustry.world.blocks.power.*; import mindustry.world.consumers.*; import mindustry.world.meta.*; import mindustry.world.meta.values.*; @@ -255,6 +256,22 @@ public class Block extends UnlockableContent{ /** Drawn when you are placing a block. */ public void drawPlace(int x, int y, int rotation, boolean valid){ + if((consumesPower || outputsPower) && hasPower){ + Tile tile = world.tile(x, y); + if(tile != null){ + PowerNode.getNodeLinks(tile, this, other -> { + PowerNode node = (PowerNode)other.block; + Draw.color(node.laserColor1, Renderer.laserOpacity * 0.5f); + node.drawLaser(tile.team(), x * tilesize + offset, y * tilesize + offset, other.x, other.y, size, other.block.size); + + Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place); + + PowerNode.insulators(other.tileX(), other.tileY(), tile.x, tile.y, cause -> { + Drawf.square(cause.x, cause.y, cause.block.size * tilesize / 2f + 2f, Pal.plastanium); + }); + }); + } + } } public float drawPlaceText(String text, int x, int y, boolean valid){ diff --git a/core/src/mindustry/world/blocks/experimental/BlockForge.java b/core/src/mindustry/world/blocks/experimental/BlockForge.java index 506593db03..fa871d347c 100644 --- a/core/src/mindustry/world/blocks/experimental/BlockForge.java +++ b/core/src/mindustry/world/blocks/experimental/BlockForge.java @@ -105,7 +105,7 @@ public class BlockForge extends PayloadAcceptor{ consume(); payload = new BuildPayload(recipe, team); payVector.setZero(); - progress = 0f; + progress %= 1f; } } diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index ee7bea0356..dbf9d4b891 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -167,7 +167,7 @@ public class PowerNode extends PowerBlock{ Draw.alpha(Renderer.laserOpacity); } - protected void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){ + public void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){ float angle1 = Angles.angle(x1, y1, x2, y2), vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1), len1 = size1 * tilesize / 2f - 1.5f, len2 = size2 * tilesize / 2f - 1.5f; @@ -240,6 +240,53 @@ public class PowerNode extends PowerBlock{ }); } + //TODO code duplication w/ method above? + /** Iterates through linked nodes of a block at a tile. All returned buildings are power nodes. */ + public static void getNodeLinks(Tile tile, Block block, Cons others){ + Boolf valid = other -> other != null && other.tile() != tile && other.block instanceof PowerNode node && + other.power.links.size < node.maxNodes && + node.overlaps(tile.x * tilesize + block.offset, tile.y * tilesize + block.offset, other.tile(), node.laserRange * tilesize) && other.team == player.team() + && !graphs.contains(other.power.graph) && + !Structs.contains(Edges.getEdges(block.size), p -> { //do not link to adjacent buildings + var t = world.tile(tile.x + p.x, tile.y + p.y); + return t != null && t.build == other; + }); + + tempTileEnts.clear(); + graphs.clear(); + + //add conducting graphs to prevent double link + for(var p : Edges.getEdges(block.size)){ + Tile other = tile.nearby(p); + if(other != null && other.team() == player.team() && other.build != null && other.build.power != null){ + graphs.add(other.build.power.graph); + } + } + + if(tile.build != null && tile.build.power != null){ + graphs.add(tile.build.power.graph); + } + + //max linking range is currently 12 + Geometry.circle(tile.x, tile.y, 12, (x, y) -> { + Building other = world.build(x, y); + if(valid.get(other) && !tempTileEnts.contains(other)){ + tempTileEnts.add(other); + } + }); + + tempTileEnts.sort((a, b) -> { + int type = -Boolean.compare(a.block instanceof PowerNode, b.block instanceof PowerNode); + if(type != 0) return type; + return Float.compare(a.dst2(tile), b.dst2(tile)); + }); + + tempTileEnts.each(valid, t -> { + graphs.add(t.power.graph); + others.get(t); + }); + } + @Override public void drawRequestConfigTop(BuildPlan req, Eachable list){ if(req.config instanceof Point2[] ps){ diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index b48f4741b6..f53636f1a2 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -175,7 +175,7 @@ public class Reconstructor extends UnitBlock{ //upgrade the unit if(progress >= constructTime){ payload.unit = upgrade(payload.unit.type).create(payload.unit.team()); - progress = 0; + progress %= 1f; Effect.shake(2f, 3f, this); Fx.producesmoke.at(this); consume(); diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index f6555dcc2f..2cd64fd33e 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -225,7 +225,7 @@ public class UnitFactory extends UnitBlock{ UnitPlan plan = plans.get(currentPlan); if(progress >= plan.time && consValid()){ - progress = 0f; + progress %= 1f; payload = new UnitPayload(plan.unit.create(team)); payVector.setZero(); From 01f7b1c9a6022427df44ad8e024c778e800cd758 Mon Sep 17 00:00:00 2001 From: Sunny Kim <58885089+sk7725@users.noreply.github.com> Date: Mon, 1 Mar 2021 07:32:28 +0900 Subject: [PATCH 368/426] New overdrive visuals for colorblind users (#4807) --- .../world/blocks/defense/OverdriveProjector.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index 5de49cacd2..7ccfa633e7 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -4,6 +4,7 @@ import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; +import arc.math.geom.*; import arc.util.*; import arc.util.io.*; import mindustry.annotations.Annotations.*; @@ -134,7 +135,19 @@ public class OverdriveProjector extends Block{ Draw.rect(topRegion, x, y); Draw.alpha(1f); Lines.stroke((2f * f + 0.1f) * heat); - Lines.square(x, y, Math.min(1f + (1f - f) * size * tilesize / 2f, size * tilesize/2f)); + //float hype = 1.414f * size * tilesize / 2f; // hypotenuse + float r = Math.max(0f, Mathf.clamp(2f - f * 2f) * size * tilesize / 2f - f - 0.2f); + float w = Mathf.clamp(0.5f - f) * size * tilesize; + Lines.beginLine(); + for(int i = 0; i < 4; i++){ + Lines.linePoint(x + Geometry.d4(i).x * r + Geometry.d4(i).y * w, y + Geometry.d4(i).y * r - Geometry.d4(i).x * w); + if(f < 0.5f) Lines.linePoint(x + Geometry.d4(i).x * r - Geometry.d4(i).y * w, y + Geometry.d4(i).y * r + Geometry.d4(i).x * w); + + //Lines.lineAngleCenter(x + Geometry.d8edge(i).x * size * tilesize / 2f * (1f - f), y + Geometry.d8edge(i).y * size * tilesize / 2f * (1f - f), 135f + 90f * i, hype * (0.5f - Math.abs(f - 0.5f)) * 2f); + //if(f < 0.5f) Lines.lineAngleCenter(x + Geometry.d4(i).x * size * tilesize / 2f - Geometry.d4(i).x * f, y + Geometry.d4(i).y * size * tilesize / 2f - Geometry.d4(i).y * f, 90f + 90f * i, (0.5f - f) * 2f * size * tilesize); + } + Lines.endLine(true); + //Lines.square(x, y, Math.min(1f + (1f - f) * size * tilesize / 2f, size * tilesize/2f)); Draw.reset(); } From 4c9cda7e40730d88613e214eb2583e4e32adbef7 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 28 Feb 2021 17:33:08 -0500 Subject: [PATCH 369/426] Cleanup --- .../world/blocks/defense/OverdriveProjector.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index 7ccfa633e7..29e373578f 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -135,19 +135,14 @@ public class OverdriveProjector extends Block{ Draw.rect(topRegion, x, y); Draw.alpha(1f); Lines.stroke((2f * f + 0.1f) * heat); - //float hype = 1.414f * size * tilesize / 2f; // hypotenuse - float r = Math.max(0f, Mathf.clamp(2f - f * 2f) * size * tilesize / 2f - f - 0.2f); - float w = Mathf.clamp(0.5f - f) * size * tilesize; + + float r = Math.max(0f, Mathf.clamp(2f - f * 2f) * size * tilesize / 2f - f - 0.2f), w = Mathf.clamp(0.5f - f) * size * tilesize; Lines.beginLine(); for(int i = 0; i < 4; i++){ Lines.linePoint(x + Geometry.d4(i).x * r + Geometry.d4(i).y * w, y + Geometry.d4(i).y * r - Geometry.d4(i).x * w); if(f < 0.5f) Lines.linePoint(x + Geometry.d4(i).x * r - Geometry.d4(i).y * w, y + Geometry.d4(i).y * r + Geometry.d4(i).x * w); - - //Lines.lineAngleCenter(x + Geometry.d8edge(i).x * size * tilesize / 2f * (1f - f), y + Geometry.d8edge(i).y * size * tilesize / 2f * (1f - f), 135f + 90f * i, hype * (0.5f - Math.abs(f - 0.5f)) * 2f); - //if(f < 0.5f) Lines.lineAngleCenter(x + Geometry.d4(i).x * size * tilesize / 2f - Geometry.d4(i).x * f, y + Geometry.d4(i).y * size * tilesize / 2f - Geometry.d4(i).y * f, 90f + 90f * i, (0.5f - f) * 2f * size * tilesize); } Lines.endLine(true); - //Lines.square(x, y, Math.min(1f + (1f - f) * size * tilesize / 2f, size * tilesize/2f)); Draw.reset(); } From 5f83c928294c5bb252e75b48f816a1a9d76351c6 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 1 Mar 2021 09:45:31 -0500 Subject: [PATCH 370/426] Fixed #4824 / Fixed #4827 / Fixed #4829 --- core/src/mindustry/core/NetClient.java | 2 +- core/src/mindustry/entities/comp/BuildingComp.java | 2 +- core/src/mindustry/world/Block.java | 2 +- core/src/mindustry/world/blocks/power/PowerNode.java | 11 ++++++++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index 8e6032c359..0594c3403a 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -633,7 +633,7 @@ public class NetClient implements ApplicationListener{ lastSent++, uid, player.dead(), - unit.x, unit.y, + player.dead() ? player.x : unit.x, player.dead() ? player.y : unit.y, player.unit().aimX(), player.unit().aimY(), unit.rotation, unit instanceof Mechc m ? m.baseRotation() : 0, diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index b7dd1af01b..3495255ded 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -911,7 +911,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, if(net.client()) return; if((block.consumesPower || block.outputsPower) && block.hasPower){ - PowerNode.getNodeLinks(tile, block, other -> { + PowerNode.getNodeLinks(tile, block, team, other -> { if(!other.power.links.contains(pos())){ other.configureAny(pos()); } diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 052e439594..69600c9f16 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -259,7 +259,7 @@ public class Block extends UnlockableContent{ if((consumesPower || outputsPower) && hasPower){ Tile tile = world.tile(x, y); if(tile != null){ - PowerNode.getNodeLinks(tile, this, other -> { + PowerNode.getNodeLinks(tile, this, player.team(), other -> { PowerNode node = (PowerNode)other.block; Draw.color(node.laserColor1, Renderer.laserOpacity * 0.5f); node.drawLaser(tile.team(), x * tilesize + offset, y * tilesize + offset, other.x, other.y, size, other.block.size); diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index dbf9d4b891..a48647b03f 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -175,6 +175,11 @@ public class PowerNode extends PowerBlock{ Drawf.laser(team, laser, laserEnd, x1 + vx*len1, y1 + vy*len1, x2 - vx*len2, y2 - vy*len2, 0.25f); } + protected boolean overlaps(float srcx, float srcy, Tile other, Block otherBlock, float range){ + return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), Tmp.r1.setCentered(other.worldx() + otherBlock.offset, other.worldy() + otherBlock.offset, + otherBlock.size * tilesize, otherBlock.size * tilesize)); + } + protected boolean overlaps(float srcx, float srcy, Tile other, float range){ return Intersector.overlaps(Tmp.cr1.set(srcx, srcy, range), other.getHitbox(Tmp.r1)); } @@ -242,10 +247,10 @@ public class PowerNode extends PowerBlock{ //TODO code duplication w/ method above? /** Iterates through linked nodes of a block at a tile. All returned buildings are power nodes. */ - public static void getNodeLinks(Tile tile, Block block, Cons others){ + public static void getNodeLinks(Tile tile, Block block, Team team, Cons others){ Boolf valid = other -> other != null && other.tile() != tile && other.block instanceof PowerNode node && other.power.links.size < node.maxNodes && - node.overlaps(tile.x * tilesize + block.offset, tile.y * tilesize + block.offset, other.tile(), node.laserRange * tilesize) && other.team == player.team() + node.overlaps(other.x - block.offset, other.y - block.offset, tile, block, node.laserRange * tilesize) && other.team == team && !graphs.contains(other.power.graph) && !Structs.contains(Edges.getEdges(block.size), p -> { //do not link to adjacent buildings var t = world.tile(tile.x + p.x, tile.y + p.y); @@ -258,7 +263,7 @@ public class PowerNode extends PowerBlock{ //add conducting graphs to prevent double link for(var p : Edges.getEdges(block.size)){ Tile other = tile.nearby(p); - if(other != null && other.team() == player.team() && other.build != null && other.build.power != null){ + if(other != null && other.team() == team && other.build != null && other.build.power != null){ graphs.add(other.build.power.graph); } } From 4019c49fffaade8b4be349e2d78606556b5703d9 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Mon, 1 Mar 2021 15:47:23 +0100 Subject: [PATCH 371/426] Log who skipped the wave to the console (#4825) --- core/src/mindustry/core/NetServer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index daf6582dbc..36d24770dc 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -725,6 +725,7 @@ public class NetServer implements ApplicationListener{ //no verification is done, so admins can hypothetically spam waves //not a real issue, because server owners may want to do just that logic.skipWave(); + info("&lc@ has skipped the wave.", player.name); }else if(action == AdminAction.ban){ netServer.admins.banPlayerIP(other.con.address); netServer.admins.banPlayerID(other.con.uuid); From 8f91576f85542770ece907b5e36f009519c21731 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 1 Mar 2021 11:58:53 -0500 Subject: [PATCH 372/426] Fixed script loading for Turkish locale --- core/src/mindustry/mod/Mods.java | 9 +++++---- core/src/mindustry/mod/Scripts.java | 3 ++- core/src/mindustry/ui/dialogs/JoinDialog.java | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 6b3f3ecaee..85f195ad54 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -24,6 +24,7 @@ import mindustry.type.*; import mindustry.ui.*; import java.io.*; +import java.util.*; import static mindustry.Vars.*; @@ -526,7 +527,7 @@ public class Mods implements Loadable{ if(mod.root.child("content").exists()){ Fi contentRoot = mod.root.child("content"); for(ContentType type : ContentType.all){ - Fi folder = contentRoot.child(type.name().toLowerCase() + "s"); + Fi folder = contentRoot.child(type.name().toLowerCase(Locale.ROOT) + "s"); if(folder.exists()){ for(Fi file : folder.findAll(f -> f.extension().equals("json") || f.extension().equals("hjson"))){ runs.add(new LoadRun(type, file, mod)); @@ -646,8 +647,8 @@ public class Mods implements Loadable{ ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain)); meta.cleanup(); String camelized = meta.name.replace(" ", ""); - String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main; - String baseName = meta.name.toLowerCase().replace(" ", "-"); + String mainClass = meta.main == null ? camelized.toLowerCase(Locale.ROOT) + "." + camelized + "Mod" : meta.main; + String baseName = meta.name.toLowerCase(Locale.ROOT).replace(" ", "-"); var other = mods.find(m -> m.name.equals(baseName)); @@ -771,7 +772,7 @@ public class Mods implements Loadable{ this.loader = loader; this.main = main; this.meta = meta; - this.name = meta.name.toLowerCase().replace(" ", "-"); + this.name = meta.name.toLowerCase(Locale.ROOT).replace(" ", "-"); } /** @return whether this is a java class mod. */ diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index 1de3573f94..80ab1633e7 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -18,6 +18,7 @@ import rhino.module.provider.*; import java.io.*; import java.net.*; +import java.util.*; import java.util.regex.*; public class Scripts implements Disposable{ @@ -32,7 +33,7 @@ public class Scripts implements Disposable{ LoadedMod currentMod = null; public static boolean allowClass(String type){ - return !blacklist.contains(type.toLowerCase()::contains) || whitelist.contains(type.toLowerCase()::contains); + return !blacklist.contains(t -> type.toLowerCase(Locale.ROOT).contains(t)) || whitelist.contains(t -> type.toLowerCase(Locale.ROOT).contains(t)); } public Scripts(){ diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index cd559de581..2077d5e091 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -570,7 +570,7 @@ public class JoinDialog extends BaseDialog{ if(isIpv6 && ip.lastIndexOf("]:") != -1 && ip.lastIndexOf("]:") != ip.length() - 1){ int idx = ip.indexOf("]:"); this.ip = ip.substring(1, idx); - this.port = Integer.parseInt(ip.substring(idx + 2, ip.length())); + this.port = Integer.parseInt(ip.substring(idx + 2)); }else if(!isIpv6 && ip.lastIndexOf(':') != -1 && ip.lastIndexOf(':') != ip.length() - 1){ int idx = ip.lastIndexOf(':'); this.ip = ip.substring(0, idx); From 1de4dd1bfe0904b105cc1173939452d02a3e93e6 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Mon, 1 Mar 2021 19:02:27 +0100 Subject: [PATCH 373/426] Call super.drawPlace for menders & overdrives (#4831) --- core/src/mindustry/world/blocks/defense/MendProjector.java | 2 ++ core/src/mindustry/world/blocks/defense/OverdriveProjector.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/core/src/mindustry/world/blocks/defense/MendProjector.java b/core/src/mindustry/world/blocks/defense/MendProjector.java index 9a478e05c0..6fb362f7d3 100644 --- a/core/src/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/mindustry/world/blocks/defense/MendProjector.java @@ -54,6 +54,8 @@ public class MendProjector extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, baseColor); indexer.eachBlock(player.team(), x * tilesize + offset, y * tilesize + offset, range, other -> true, other -> Drawf.selected(other, Tmp.c1.set(baseColor).a(Mathf.absin(4f, 1f)))); diff --git a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java index 29e373578f..499165f1bc 100644 --- a/core/src/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/mindustry/world/blocks/defense/OverdriveProjector.java @@ -48,6 +48,8 @@ public class OverdriveProjector extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, baseColor); indexer.eachBlock(player.team(), x * tilesize + offset, y * tilesize + offset, range, other -> other.block.canOverdrive, other -> Drawf.selected(other, Tmp.c1.set(baseColor).a(Mathf.absin(4f, 1f)))); From 05dc13c9228224e4dd02a465e0168a50fdd2e723 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 1 Mar 2021 13:06:47 -0500 Subject: [PATCH 374/426] Fixed #4830 --- core/src/mindustry/world/Block.java | 4 ++++ .../mindustry/world/blocks/defense/turrets/BaseTurret.java | 2 ++ core/src/mindustry/world/blocks/distribution/ItemBridge.java | 2 ++ core/src/mindustry/world/blocks/distribution/MassDriver.java | 2 ++ core/src/mindustry/world/blocks/power/PowerNode.java | 3 ++- core/src/mindustry/world/blocks/power/ThermalGenerator.java | 2 ++ core/src/mindustry/world/blocks/production/Cultivator.java | 2 ++ core/src/mindustry/world/blocks/production/Drill.java | 2 ++ core/src/mindustry/world/blocks/production/Pump.java | 2 ++ core/src/mindustry/world/blocks/production/SolidPump.java | 2 ++ core/src/mindustry/world/blocks/units/RepairPoint.java | 2 ++ gradle.properties | 2 +- 12 files changed, 25 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 69600c9f16..1f3f6ba00a 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -256,6 +256,10 @@ public class Block extends UnlockableContent{ /** Drawn when you are placing a block. */ public void drawPlace(int x, int y, int rotation, boolean valid){ + drawPotentialLinks(x, y); + } + + public void drawPotentialLinks(int x, int y){ if((consumesPower || outputsPower) && hasPower){ Tile tile = world.tile(x, y); if(tile != null){ diff --git a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java index 44d4f63f93..0742348e5d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java @@ -41,6 +41,8 @@ public class BaseTurret extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, Pal.placing); } diff --git a/core/src/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/mindustry/world/blocks/distribution/ItemBridge.java index 527acbe78a..5047b5e8ba 100644 --- a/core/src/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/mindustry/world/blocks/distribution/ItemBridge.java @@ -90,6 +90,8 @@ public class ItemBridge extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Tile link = findLink(x, y); Lines.stroke(2f, Pal.placing); diff --git a/core/src/mindustry/world/blocks/distribution/MassDriver.java b/core/src/mindustry/world/blocks/distribution/MassDriver.java index 67c4c23191..5b9d4e6f13 100644 --- a/core/src/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/mindustry/world/blocks/distribution/MassDriver.java @@ -57,6 +57,8 @@ public class MassDriver extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Drawf.dashCircle(x * tilesize, y * tilesize, range, Pal.accent); //check if a mass driver is selected while placing this driver diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index a48647b03f..960c106bf3 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -263,7 +263,8 @@ public class PowerNode extends PowerBlock{ //add conducting graphs to prevent double link for(var p : Edges.getEdges(block.size)){ Tile other = tile.nearby(p); - if(other != null && other.team() == team && other.build != null && other.build.power != null){ + if(other != null && other.team() == team && other.build != null && other.build.power != null + && !(block.consumesPower && other.block().consumesPower && !block.outputsPower && !other.block().outputsPower)){ graphs.add(other.build.power.graph); } } diff --git a/core/src/mindustry/world/blocks/power/ThermalGenerator.java b/core/src/mindustry/world/blocks/power/ThermalGenerator.java index 154bd02a0c..c57284c667 100644 --- a/core/src/mindustry/world/blocks/power/ThermalGenerator.java +++ b/core/src/mindustry/world/blocks/power/ThermalGenerator.java @@ -27,6 +27,8 @@ public class ThermalGenerator extends PowerGenerator{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + drawPlaceText(Core.bundle.formatFloat("bar.efficiency", sumAttribute(attribute, x, y) * 100, 1), x, y, valid); } diff --git a/core/src/mindustry/world/blocks/production/Cultivator.java b/core/src/mindustry/world/blocks/production/Cultivator.java index 57b2372f6c..57f79a98a0 100644 --- a/core/src/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/mindustry/world/blocks/production/Cultivator.java @@ -47,6 +47,8 @@ public class Cultivator extends GenericCrafter{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + drawPlaceText(Core.bundle.formatFloat("bar.efficiency", (1 + sumAttribute(attribute, x, y)) * 100, 1), x, y, valid); } diff --git a/core/src/mindustry/world/blocks/production/Drill.java b/core/src/mindustry/world/blocks/production/Drill.java index bfefd96050..4186dca2f7 100644 --- a/core/src/mindustry/world/blocks/production/Drill.java +++ b/core/src/mindustry/world/blocks/production/Drill.java @@ -113,6 +113,8 @@ public class Drill extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Tile tile = world.tile(x, y); if(tile == null) return; diff --git a/core/src/mindustry/world/blocks/production/Pump.java b/core/src/mindustry/world/blocks/production/Pump.java index c31d346c80..692b637428 100644 --- a/core/src/mindustry/world/blocks/production/Pump.java +++ b/core/src/mindustry/world/blocks/production/Pump.java @@ -31,6 +31,8 @@ public class Pump extends LiquidBlock{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Tile tile = world.tile(x, y); if(tile == null) return; diff --git a/core/src/mindustry/world/blocks/production/SolidPump.java b/core/src/mindustry/world/blocks/production/SolidPump.java index 78a423dcec..e13090ec4e 100644 --- a/core/src/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/mindustry/world/blocks/production/SolidPump.java @@ -35,6 +35,8 @@ public class SolidPump extends Pump{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + drawPotentialLinks(x, y); + if(attribute != null){ drawPlaceText(Core.bundle.formatFloat("bar.efficiency", Math.max(sumAttribute(attribute, x, y) / size / size + baseEfficiency, 0f) * 100 * percentSolid(x, y), 1), x, y, valid); } diff --git a/core/src/mindustry/world/blocks/units/RepairPoint.java b/core/src/mindustry/world/blocks/units/RepairPoint.java index 9833276112..905c1c63f7 100644 --- a/core/src/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/mindustry/world/blocks/units/RepairPoint.java @@ -56,6 +56,8 @@ public class RepairPoint extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ + super.drawPlace(x, y, rotation, valid); + Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, repairRadius, Pal.accent); } diff --git a/gradle.properties b/gradle.properties index 92097f8f77..cc383fd0f4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=9f916a1b401216c68e39635f6c99769391c8555a +archash=768529cbe1cd450df16f08431e71d6280ddc5f0e From a89d50e74d5b547081e354b48e3f04d5e9dac305 Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Tue, 2 Mar 2021 06:25:15 -0800 Subject: [PATCH 375/426] Cursor should not change for other teams when hovering over doors and construction. (#4838) * Cursor should not change for other teams. * Use Built-in interaction check Co-authored-by: Patrick 'Quezler' Mounier * Building should use built-in check, same treatment for ConstructBlock Co-authored-by: Patrick 'Quezler' Mounier --- core/src/mindustry/entities/comp/BuildingComp.java | 2 +- core/src/mindustry/world/blocks/ConstructBlock.java | 2 +- core/src/mindustry/world/blocks/defense/Door.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 3495255ded..dfa7fd75cc 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1142,7 +1142,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, /** Returns whether or not a hand cursor should be shown over this block. */ public Cursor getCursor(){ - return block.configurable && team == player.team() ? SystemCursor.hand : SystemCursor.arrow; + return block.configurable && interactable(player.team()) ? SystemCursor.hand : SystemCursor.arrow; } /** diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index 85ca209ab6..b9621fe736 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -172,7 +172,7 @@ public class ConstructBlock extends Block{ @Override public Cursor getCursor(){ - return SystemCursor.hand; + return interactable(player.team()) ? SystemCursor.hand : SystemCursor.arrow; } @Override diff --git a/core/src/mindustry/world/blocks/defense/Door.java b/core/src/mindustry/world/blocks/defense/Door.java index f17ca43946..a1d84a7595 100644 --- a/core/src/mindustry/world/blocks/defense/Door.java +++ b/core/src/mindustry/world/blocks/defense/Door.java @@ -126,7 +126,7 @@ public class Door extends Wall{ @Override public Cursor getCursor(){ - return SystemCursor.hand; + return interactable(player.team()) ? SystemCursor.hand : SystemCursor.arrow; } @Override From 7e216d198e6b9ca7408dad5172607d7c9af1f1ed Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Tue, 2 Mar 2021 06:28:04 -0800 Subject: [PATCH 376/426] Remove duplicates and mild formatting. (#4837) * Remove duplicate definitions in UnitTypes * If Tsunami is indented, so should the others It looks nicer as well. --- core/src/mindustry/content/Blocks.java | 143 +++++++++++----------- core/src/mindustry/content/UnitTypes.java | 5 +- 2 files changed, 72 insertions(+), 76 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index e7d5915653..d9761c9495 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -647,10 +647,10 @@ public class Blocks implements ContentList{ separator = new Separator("separator"){{ requirements(Category.crafting, with(Items.copper, 30, Items.titanium, 25)); results = with( - Items.copper, 5, - Items.lead, 3, - Items.graphite, 2, - Items.titanium, 2 + Items.copper, 5, + Items.lead, 3, + Items.graphite, 2, + Items.titanium, 2 ); hasPower = true; craftTime = 35f; @@ -663,10 +663,10 @@ public class Blocks implements ContentList{ disassembler = new Separator("disassembler"){{ requirements(Category.crafting, with(Items.graphite, 140, Items.titanium, 100, Items.silicon, 150, Items.surgeAlloy, 70)); results = with( - Items.sand, 4, - Items.graphite, 2, - Items.titanium, 2, - Items.thorium, 1 + Items.sand, 4, + Items.graphite, 2, + Items.titanium, 2, + Items.thorium, 1 ); hasPower = true; craftTime = 15f; @@ -1394,10 +1394,10 @@ public class Blocks implements ContentList{ duo = new ItemTurret("duo"){{ requirements(Category.turret, with(Items.copper, 35), true); ammo( - Items.copper, Bullets.standardCopper, - Items.graphite, Bullets.standardDense, - Items.pyratite, Bullets.standardIncendiary, - Items.silicon, Bullets.standardHoming + Items.copper, Bullets.standardCopper, + Items.graphite, Bullets.standardDense, + Items.pyratite, Bullets.standardIncendiary, + Items.silicon, Bullets.standardHoming ); spread = 4f; @@ -1416,9 +1416,9 @@ public class Blocks implements ContentList{ scatter = new ItemTurret("scatter"){{ requirements(Category.turret, with(Items.copper, 85, Items.lead, 45)); ammo( - Items.scrap, Bullets.flakScrap, - Items.lead, Bullets.flakLead, - Items.metaglass, Bullets.flakGlass + Items.scrap, Bullets.flakScrap, + Items.lead, Bullets.flakLead, + Items.metaglass, Bullets.flakGlass ); reloadTime = 18f; range = 160f; @@ -1439,8 +1439,8 @@ public class Blocks implements ContentList{ scorch = new ItemTurret("scorch"){{ requirements(Category.turret, with(Items.copper, 25, Items.graphite, 22)); ammo( - Items.coal, Bullets.basicFlame, - Items.pyratite, Bullets.pyraFlame + Items.coal, Bullets.basicFlame, + Items.pyratite, Bullets.pyraFlame ); recoilAmount = 0f; reloadTime = 6f; @@ -1456,9 +1456,9 @@ public class Blocks implements ContentList{ hail = new ItemTurret("hail"){{ requirements(Category.turret, with(Items.copper, 40, Items.graphite, 17)); ammo( - Items.graphite, Bullets.artilleryDense, - Items.silicon, Bullets.artilleryHoming, - Items.pyratite, Bullets.artilleryIncendiary + Items.graphite, Bullets.artilleryDense, + Items.silicon, Bullets.artilleryHoming, + Items.pyratite, Bullets.artilleryIncendiary ); targetAir = false; reloadTime = 60f; @@ -1473,10 +1473,10 @@ public class Blocks implements ContentList{ wave = new LiquidTurret("wave"){{ requirements(Category.turret, with(Items.metaglass, 45, Items.lead, 75)); ammo( - Liquids.water, Bullets.waterShot, - Liquids.slag, Bullets.slagShot, - Liquids.cryofluid, Bullets.cryoShot, - Liquids.oil, Bullets.oilShot + Liquids.water, Bullets.waterShot, + Liquids.slag, Bullets.slagShot, + Liquids.cryofluid, Bullets.cryoShot, + Liquids.oil, Bullets.oilShot ); size = 2; recoilAmount = 0f; @@ -1562,9 +1562,9 @@ public class Blocks implements ContentList{ swarmer = new ItemTurret("swarmer"){{ requirements(Category.turret, with(Items.graphite, 35, Items.titanium, 35, Items.plastanium, 45, Items.silicon, 30)); ammo( - Items.blastCompound, Bullets.missileExplosive, - Items.pyratite, Bullets.missileIncendiary, - Items.surgeAlloy, Bullets.missileSurge + Items.blastCompound, Bullets.missileExplosive, + Items.pyratite, Bullets.missileIncendiary, + Items.surgeAlloy, Bullets.missileSurge ); reloadTime = 30f; shots = 4; @@ -1580,11 +1580,11 @@ public class Blocks implements ContentList{ salvo = new ItemTurret("salvo"){{ requirements(Category.turret, with(Items.copper, 100, Items.graphite, 90, Items.titanium, 60)); ammo( - Items.copper, Bullets.standardCopper, - Items.graphite, Bullets.standardDense, - Items.pyratite, Bullets.standardIncendiary, - Items.silicon, Bullets.standardHoming, - Items.thorium, Bullets.standardThorium + Items.copper, Bullets.standardCopper, + Items.graphite, Bullets.standardDense, + Items.pyratite, Bullets.standardIncendiary, + Items.silicon, Bullets.standardHoming, + Items.thorium, Bullets.standardThorium ); size = 2; @@ -1624,7 +1624,6 @@ public class Blocks implements ContentList{ Liquids.oil, Bullets.heavyOilShot ); size = 3; - recoilAmount = 0f; reloadTime = 2f; shots = 2; velocityInaccuracy = 0.1f; @@ -1658,31 +1657,31 @@ public class Blocks implements ContentList{ float brange = range + 10f; ammo( - Items.titanium, new ShrapnelBulletType(){{ - length = brange; - damage = 66f; - ammoMultiplier = 4f; - width = 17f; - reloadMultiplier = 1.3f; - }}, - Items.thorium, new ShrapnelBulletType(){{ - length = brange; - damage = 105f; - ammoMultiplier = 5f; - toColor = Pal.thoriumPink; - shootEffect = smokeEffect = Fx.thoriumShoot; - }} + Items.titanium, new ShrapnelBulletType(){{ + length = brange; + damage = 66f; + ammoMultiplier = 4f; + width = 17f; + reloadMultiplier = 1.3f; + }}, + Items.thorium, new ShrapnelBulletType(){{ + length = brange; + damage = 105f; + ammoMultiplier = 5f; + toColor = Pal.thoriumPink; + shootEffect = smokeEffect = Fx.thoriumShoot; + }} ); }}; ripple = new ItemTurret("ripple"){{ requirements(Category.turret, with(Items.copper, 150, Items.graphite, 135, Items.titanium, 60)); ammo( - Items.graphite, Bullets.artilleryDense, - Items.silicon, Bullets.artilleryHoming, - Items.pyratite, Bullets.artilleryIncendiary, - Items.blastCompound, Bullets.artilleryExplosive, - Items.plastanium, Bullets.artilleryPlastic + Items.graphite, Bullets.artilleryDense, + Items.silicon, Bullets.artilleryHoming, + Items.pyratite, Bullets.artilleryIncendiary, + Items.blastCompound, Bullets.artilleryExplosive, + Items.plastanium, Bullets.artilleryPlastic ); targetAir = false; @@ -1708,10 +1707,10 @@ public class Blocks implements ContentList{ cyclone = new ItemTurret("cyclone"){{ requirements(Category.turret, with(Items.copper, 200, Items.titanium, 125, Items.plastanium, 80)); ammo( - Items.metaglass, Bullets.fragGlass, - Items.blastCompound, Bullets.fragExplosive, - Items.plastanium, Bullets.fragPlastic, - Items.surgeAlloy, Bullets.fragSurge + Items.metaglass, Bullets.fragGlass, + Items.blastCompound, Bullets.fragExplosive, + Items.plastanium, Bullets.fragPlastic, + Items.surgeAlloy, Bullets.fragSurge ); xRand = 4f; reloadTime = 8f; @@ -1731,19 +1730,19 @@ public class Blocks implements ContentList{ requirements(Category.turret, with(Items.copper, 1000, Items.metaglass, 600, Items.surgeAlloy, 300, Items.plastanium, 200, Items.silicon, 600)); ammo( - Items.surgeAlloy, new PointBulletType(){{ - shootEffect = Fx.instShoot; - hitEffect = Fx.instHit; - smokeEffect = Fx.smokeCloud; - trailEffect = Fx.instTrail; - despawnEffect = Fx.instBomb; - trailSpacing = 20f; - damage = 1350; - buildingDamageMultiplier = 0.3f; - speed = brange; - hitShake = 6f; - ammoMultiplier = 1f; - }} + Items.surgeAlloy, new PointBulletType(){{ + shootEffect = Fx.instShoot; + hitEffect = Fx.instHit; + smokeEffect = Fx.smokeCloud; + trailEffect = Fx.instTrail; + despawnEffect = Fx.instBomb; + trailSpacing = 20f; + damage = 1350; + buildingDamageMultiplier = 0.3f; + speed = brange; + hitShake = 6f; + ammoMultiplier = 1f; + }} ); maxAmmo = 40; @@ -1772,9 +1771,9 @@ public class Blocks implements ContentList{ spectre = new ItemTurret("spectre"){{ requirements(Category.turret, with(Items.copper, 900, Items.graphite, 300, Items.surgeAlloy, 250, Items.plastanium, 175, Items.thorium, 250)); ammo( - Items.graphite, Bullets.standardDenseBig, - Items.pyratite, Bullets.standardIncendiaryBig, - Items.thorium, Bullets.standardThoriumBig + Items.graphite, Bullets.standardDenseBig, + Items.pyratite, Bullets.standardIncendiaryBig, + Items.thorium, Bullets.standardThoriumBig ); reloadTime = 6f; coolantMultiplier = 0.5f; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index c11531fafc..c53770e0fc 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -322,9 +322,8 @@ public class UnitTypes implements ContentList{ x = 5f; shake = 2.2f; y = 0.5f; - shootY = 5f; - shootY = 2.5f; + reload = 38f; shots = 3; inaccuracy = 35; @@ -359,7 +358,6 @@ public class UnitTypes implements ContentList{ quasar = new UnitType("quasar"){{ mineTier = 3; - hitSize = 12f; boostMultiplier = 2f; health = 650f; buildSpeed = 1.7f; @@ -471,7 +469,6 @@ public class UnitTypes implements ContentList{ }}; corvus = new UnitType("corvus"){{ - mineTier = 1; hitSize = 29f; health = 18000f; armor = 9f; From e992be1bfbcc42ff20d5256d53866085d6632f1d Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 2 Mar 2021 09:28:38 -0500 Subject: [PATCH 377/426] Higher LogicBlock schem priority --- core/src/mindustry/world/blocks/logic/LogicBlock.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index f54480170f..dace504cae 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -39,6 +39,7 @@ public class LogicBlock extends Block{ solid = true; configurable = true; group = BlockGroup.logic; + schematicPriority = 5; config(byte[].class, (LogicBuild build, byte[] data) -> build.readCompressed(data, true)); From 8289da1415d80d08aa306d3ff0b1ce92fffd004c Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Tue, 2 Mar 2021 10:49:22 -0500 Subject: [PATCH 378/426] Nuclear reactor schem priority of -5 (#4840) * Nuclear reactor schem priority of -5 --- core/src/mindustry/world/blocks/power/NuclearReactor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/mindustry/world/blocks/power/NuclearReactor.java b/core/src/mindustry/world/blocks/power/NuclearReactor.java index 53630c4cd0..2a53e1b4c0 100644 --- a/core/src/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/mindustry/world/blocks/power/NuclearReactor.java @@ -54,6 +54,7 @@ public class NuclearReactor extends PowerGenerator{ hasLiquids = true; rebuildable = false; flags = EnumSet.of(BlockFlag.reactor, BlockFlag.generator); + schematicPriority = -5; } @Override From ea8277315735d10bcdca599b53cbed5779956b3f Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 2 Mar 2021 18:45:18 -0500 Subject: [PATCH 379/426] Non-overdriveable core / Spurious mod warning fix --- core/src/mindustry/mod/ContentParser.java | 1 + core/src/mindustry/world/blocks/storage/CoreBlock.java | 1 + 2 files changed, 2 insertions(+) diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 0531fe4eb6..ae8ea58056 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -291,6 +291,7 @@ public class ContentParser{ if(value.has("controller")){ unit.defaultController = supply(resolve(value.getString("controller"), FlyingAI.class)); + value.remove("controller"); } //read extra default waves diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 8767554939..09cb9288b5 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -52,6 +52,7 @@ public class CoreBlock extends StorageBlock{ loopSoundVolume = 1f; group = BlockGroup.none; drawDisabled = false; + canOverdrive = false; } @Remote(called = Loc.server) From ae838b939236271dc6b54532e3d62e82372a6270 Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Wed, 3 Mar 2021 15:09:05 +0100 Subject: [PATCH 380/426] Trace times joined & kicked (#4844) * Trace times joined & kicked * Make mindustry.* import obsolete --- core/assets/bundles/bundle.properties | 4 +++- core/src/mindustry/core/NetServer.java | 3 ++- core/src/mindustry/io/TypeIO.java | 4 +++- core/src/mindustry/net/Administration.java | 5 ++++- core/src/mindustry/ui/dialogs/TraceDialog.java | 4 ++++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index c76e21001d..671a34ebaf 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -216,9 +216,11 @@ server.hidden = Hidden trace = Trace Player trace.playername = Player name: [accent]{0} trace.ip = IP: [accent]{0} -trace.id = Unique ID: [accent]{0} +trace.id = ID: [accent]{0} trace.mobile = Mobile Client: [accent]{0} trace.modclient = Custom Client: [accent]{0} +trace.times.joined = Times Joined: [accent]{0} +trace.times.kicked = Times Kicked: [accent]{0} invalidid = Invalid client ID! Submit a bug report. server.bans = Bans server.bans.none = No banned players found! diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 36d24770dc..5054402310 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -735,7 +735,8 @@ public class NetServer implements ApplicationListener{ other.kick(KickReason.kick); info("&lc@ has kicked @.", player.name, other.name); }else if(action == AdminAction.trace){ - TraceInfo info = new TraceInfo(other.con.address, other.uuid(), other.con.modclient, other.con.mobile); + PlayerInfo stats = netServer.admins.getInfo(other.uuid()); + TraceInfo info = new TraceInfo(other.con.address, other.uuid(), other.con.modclient, other.con.mobile, stats.timesJoined, stats.timesKicked); if(player.con != null){ Call.traceInfo(player.con, other, info); }else{ diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 9e8ab187dd..e91ebedb6f 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -572,10 +572,12 @@ public class TypeIO{ writeString(write, trace.uuid); write.b(trace.modded ? (byte)1 : 0); write.b(trace.mobile ? (byte)1 : 0); + write.i(trace.timesJoined); + write.i(trace.timesKicked); } public static TraceInfo readTraceInfo(Reads read){ - return new TraceInfo(readString(read), readString(read), read.b() == 1, read.b() == 1); + return new TraceInfo(readString(read), readString(read), read.b() == 1, read.b() == 1, read.i(), read.i()); } public static void writeStringData(DataOutput buffer, String string) throws IOException{ diff --git a/core/src/mindustry/net/Administration.java b/core/src/mindustry/net/Administration.java index bd312bacdf..3ef4784dda 100644 --- a/core/src/mindustry/net/Administration.java +++ b/core/src/mindustry/net/Administration.java @@ -584,12 +584,15 @@ public class Administration{ public static class TraceInfo{ public String ip, uuid; public boolean modded, mobile; + public int timesJoined, timesKicked; - public TraceInfo(String ip, String uuid, boolean modded, boolean mobile){ + public TraceInfo(String ip, String uuid, boolean modded, boolean mobile, int timesJoined, int timesKicked){ this.ip = ip; this.uuid = uuid; this.modded = modded; this.mobile = mobile; + this.timesJoined = timesJoined; + this.timesKicked = timesKicked; } } diff --git a/core/src/mindustry/ui/dialogs/TraceDialog.java b/core/src/mindustry/ui/dialogs/TraceDialog.java index c6582aa005..53b4f59b92 100644 --- a/core/src/mindustry/ui/dialogs/TraceDialog.java +++ b/core/src/mindustry/ui/dialogs/TraceDialog.java @@ -32,6 +32,10 @@ public class TraceDialog extends BaseDialog{ table.row(); table.add(Core.bundle.format("trace.mobile", info.mobile)); table.row(); + table.add(Core.bundle.format("trace.times.joined", info.timesJoined)); + table.row(); + table.add(Core.bundle.format("trace.times.kicked", info.timesKicked)); + table.row(); table.add().pad(5); table.row(); From 019898dfc38be8d1e89d13ceb8c466960c3269be Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Wed, 3 Mar 2021 09:15:50 -0500 Subject: [PATCH 381/426] Turrets can properly replace eachother, cores can replace conveyors and minor cleanup. (#4841) --- core/src/mindustry/content/Blocks.java | 4 ---- .../mindustry/world/blocks/defense/turrets/BaseTurret.java | 4 ++++ core/src/mindustry/world/blocks/defense/turrets/Turret.java | 6 ------ core/src/mindustry/world/blocks/storage/CoreBlock.java | 1 - core/src/mindustry/world/blocks/storage/StorageBlock.java | 3 ++- core/src/mindustry/world/meta/BlockGroup.java | 2 +- 6 files changed, 7 insertions(+), 13 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index d9761c9495..ce383efbbd 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1370,16 +1370,12 @@ public class Blocks implements ContentList{ requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125)); size = 3; itemCapacity = 1000; - flags = EnumSet.of(BlockFlag.storage); - group = BlockGroup.transportation; }}; container = new StorageBlock("container"){{ requirements(Category.effect, with(Items.titanium, 100)); size = 2; itemCapacity = 300; - flags = EnumSet.of(BlockFlag.storage); - group = BlockGroup.transportation; }}; unloader = new Unloader("unloader"){{ diff --git a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java index 0742348e5d..8289b42366 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java @@ -1,5 +1,6 @@ package mindustry.world.blocks.defense.turrets; +import arc.struct.*; import mindustry.content.*; import mindustry.entities.*; import mindustry.gen.*; @@ -27,6 +28,9 @@ public class BaseTurret extends Block{ update = true; solid = true; outlineIcon = true; + priority = TargetPriority.turret; + group = BlockGroup.turrets; + flags = EnumSet.of(BlockFlag.turret); } @Override diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 562e84a1e3..645264b459 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -93,12 +93,6 @@ public class Turret extends ReloadTurret{ public Turret(String name){ super(name); - priority = TargetPriority.turret; - update = true; - solid = true; - group = BlockGroup.turrets; - flags = EnumSet.of(BlockFlag.turret); - outlineIcon = true; liquidCapacity = 20f; } diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 09cb9288b5..087ba838fd 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -50,7 +50,6 @@ public class CoreBlock extends StorageBlock{ unitCapModifier = 10; loopSound = Sounds.respawning; loopSoundVolume = 1f; - group = BlockGroup.none; drawDisabled = false; canOverdrive = false; } diff --git a/core/src/mindustry/world/blocks/storage/StorageBlock.java b/core/src/mindustry/world/blocks/storage/StorageBlock.java index 1ead7b97ab..006d462e6f 100644 --- a/core/src/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/mindustry/world/blocks/storage/StorageBlock.java @@ -20,7 +20,8 @@ public class StorageBlock extends Block{ solid = true; update = false; destructible = true; - group = BlockGroup.storage; + group = BlockGroup.transportation; + flags = EnumSet.of(BlockFlag.storage); } @Override diff --git a/core/src/mindustry/world/meta/BlockGroup.java b/core/src/mindustry/world/meta/BlockGroup.java index 690e181b64..d1e995887e 100644 --- a/core/src/mindustry/world/meta/BlockGroup.java +++ b/core/src/mindustry/world/meta/BlockGroup.java @@ -1,7 +1,7 @@ package mindustry.world.meta; public enum BlockGroup{ - none, walls(true), projectors(true), turrets, transportation(true), power, liquids(true), drills, storage, units, logic(true); + none, walls(true), projectors(true), turrets(true), transportation(true), power, liquids(true), drills, units, logic(true); /** if true, any block in this category replaces any other block in this category. */ public final boolean anyReplace; From 3075616b037dc9e80304cf11b8e0a3e38a50a59f Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 3 Mar 2021 10:49:52 -0500 Subject: [PATCH 382/426] arc --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index cc383fd0f4..f5c6485e88 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=768529cbe1cd450df16f08431e71d6280ddc5f0e +archash=9f6d0e3a7fd5defa2c3fe1cf47a22aaba423427e From 93dafc82eb633e3d6a5b9a3cc8fc2a759bd6a00b Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 3 Mar 2021 12:44:56 -0500 Subject: [PATCH 383/426] Fixed #4847 --- core/src/mindustry/world/blocks/power/PowerNode.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 960c106bf3..b44c350af5 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -250,7 +250,7 @@ public class PowerNode extends PowerBlock{ public static void getNodeLinks(Tile tile, Block block, Team team, Cons others){ Boolf valid = other -> other != null && other.tile() != tile && other.block instanceof PowerNode node && other.power.links.size < node.maxNodes && - node.overlaps(other.x - block.offset, other.y - block.offset, tile, block, node.laserRange * tilesize) && other.team == team + node.overlaps(other.x, other.y, tile, block, node.laserRange * tilesize) && other.team == team && !graphs.contains(other.power.graph) && !Structs.contains(Edges.getEdges(block.size), p -> { //do not link to adjacent buildings var t = world.tile(tile.x + p.x, tile.y + p.y); @@ -273,8 +273,7 @@ public class PowerNode extends PowerBlock{ graphs.add(tile.build.power.graph); } - //max linking range is currently 12 - Geometry.circle(tile.x, tile.y, 12, (x, y) -> { + Geometry.circle(tile.x, tile.y, 13, (x, y) -> { Building other = world.build(x, y); if(valid.get(other) && !tempTileEnts.contains(other)){ tempTileEnts.add(other); From d73cf9fcff026a581b06c0aaab89a9c3231d3310 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 3 Mar 2021 14:42:41 -0500 Subject: [PATCH 384/426] Prevent early return in PowerNode config render --- core/src/mindustry/world/blocks/power/PowerNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index b44c350af5..60f235bb49 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -307,7 +307,7 @@ public class PowerNode extends PowerBlock{ } }); - if(otherReq == null || otherReq.block == null) return; + if(otherReq == null || otherReq.block == null) continue; drawLaser(player == null ? Team.sharded : player.team(), req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), size, otherReq.block.size); } From efa5c5db7b65dfb281ae8732654abf78598efba9 Mon Sep 17 00:00:00 2001 From: Javier Domingo Cansino Date: Thu, 4 Mar 2021 16:34:23 +0100 Subject: [PATCH 385/426] Enable client to use a different data dir through env MINDUSTRY_DATA_DIR (#4851) --- core/src/mindustry/ClientLauncher.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/mindustry/ClientLauncher.java b/core/src/mindustry/ClientLauncher.java index d8c0de2556..ef9352db76 100644 --- a/core/src/mindustry/ClientLauncher.java +++ b/core/src/mindustry/ClientLauncher.java @@ -34,6 +34,11 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform @Override public void setup(){ + String dataDir = OS.env("MINDUSTRY_DATA_DIR"); + if(dataDir != null){ + Core.settings.setDataDirectory(files.absolute(dataDir)); + } + checkLaunch(); loadLogger(); From 3ccdf45ed1d4f7287da87d5fbdd5eec9b700bbac Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Thu, 4 Mar 2021 07:38:47 -0800 Subject: [PATCH 386/426] Is this what you wanted sk? (#4848) --- core/src/mindustry/world/Block.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 1f3f6ba00a..e40fdbca45 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -625,6 +625,14 @@ public class Block extends UnlockableContent{ return cacheLayer == CacheLayer.walls; } + public void setupRequirements(Category cat, ItemStack[] stacks){ + requirements(cat, stacks); + } + + public void setupRequirements(Category cat, BuildVisibility visible, ItemStack[] stacks){ + requirements(cat, visible, stacks); + } + public void requirements(Category cat, ItemStack[] stacks, boolean unlocked){ requirements(cat, BuildVisibility.shown, stacks); this.alwaysUnlocked = unlocked; From d863c971c2bd5110320fd159c355ee35170e920d Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 4 Mar 2021 13:40:50 -0500 Subject: [PATCH 387/426] Gradle update / Mech animation fixes / Formation movement tweaks --- core/src/mindustry/ai/types/FormationAI.java | 2 +- core/src/mindustry/entities/comp/MechComp.java | 6 +++--- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/ai/types/FormationAI.java b/core/src/mindustry/ai/types/FormationAI.java index 49ca55c68b..7a465bf3cf 100644 --- a/core/src/mindustry/ai/types/FormationAI.java +++ b/core/src/mindustry/ai/types/FormationAI.java @@ -48,7 +48,7 @@ public class FormationAI extends AIController implements FormationMember{ Vec2 realtarget = vec.set(target).add(leader.vel); - float speed = unit.realSpeed() * unit.floorSpeedMultiplier() * Time.delta; + float speed = unit.realSpeed() * Time.delta; unit.approach(Mathf.arrive(unit.x, unit.y, realtarget.x, realtarget.y, unit.vel, speed, 0f, speed, 1f).scl(1f / Time.delta)); if(unit.canMine() && leader.canMine()){ diff --git a/core/src/mindustry/entities/comp/MechComp.java b/core/src/mindustry/entities/comp/MechComp.java index 6d99f368cb..e8ed72974d 100644 --- a/core/src/mindustry/entities/comp/MechComp.java +++ b/core/src/mindustry/entities/comp/MechComp.java @@ -78,16 +78,16 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati @Override public void moveAt(Vec2 vector, float acceleration){ + //mark walking state when moving in a controlled manner if(!vector.isZero()){ - //mark walking state when moving in a controlled manner walked = true; } } @Override public void approach(Vec2 vector){ - if(!vector.isZero(0.09f)){ - //mark walking state when moving in a controlled manner + //mark walking state when moving in a controlled manner + if(!vector.isZero(0.001f)){ walked = true; } } diff --git a/gradle.properties b/gradle.properties index f5c6485e88..8d7da5a740 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=9f6d0e3a7fd5defa2c3fe1cf47a22aaba423427e +archash=e270ac561e10cbc1dc1f13907d75d614e2d51be0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index da9702f9e7..442d9132ea 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From c12b9ee3e3cb1426404476866a5e1cfcd24746ce Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 4 Mar 2021 17:58:28 -0500 Subject: [PATCH 388/426] Minor network packet handling tweaks --- .../java/mindustry/annotations/remote/RemoteProcess.java | 4 ++-- core/src/mindustry/core/NetClient.java | 8 ++++++-- core/src/mindustry/core/NetServer.java | 9 ++++++++- core/src/mindustry/net/NetConnection.java | 2 ++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java b/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java index b3a473795a..6be9c9c2d2 100644 --- a/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java +++ b/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java @@ -71,12 +71,12 @@ public class RemoteProcess extends BaseProcessor{ //check for static if(!element.is(Modifier.STATIC) || !element.is(Modifier.PUBLIC)){ - err("All @Remote methods must be public and static: ", element); + err("All @Remote methods must be public and static", element); } //can't generate none methods if(annotation.targets() == Loc.none){ - err("A @Remote method's targets() cannot be equal to 'none':", element); + err("A @Remote method's targets() cannot be equal to 'none'", element); } //get and create class entry if needed diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index 0594c3403a..b9fc8037de 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -86,7 +86,7 @@ public class NetClient implements ApplicationListener{ locale = Locale.getDefault().toString(); } - ConnectPacket c = new ConnectPacket(); + var c = new ConnectPacket(); c.name = player.name; c.locale = locale; c.mods = mods.getModStrings(); @@ -188,6 +188,10 @@ public class NetClient implements ApplicationListener{ //called when a server receives a chat message from a player @Remote(called = Loc.server, targets = Loc.client) public static void sendChatMessage(Player player, String message){ + + //do not receive chat messages from clients that are too young or not registered + if(Time.timeSinceMillis(player.con.connectTime) < 500 || !player.con.hasConnected || !player.isAdded()) return; + if(message.length() > maxTextLength){ throw new ValidateException(player, "Player has sent a message above the text limit."); } @@ -198,7 +202,7 @@ public class NetClient implements ApplicationListener{ CommandResponse response = netServer.clientCommands.handleMessage(message, player); if(response.type == ResponseType.noCommand){ //no command to handle message = netServer.admins.filterMessage(player, message); - //supress chat message if it's filtered out + //suppress chat message if it's filtered out if(message == null){ return; } diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 5054402310..8747e8f00c 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -93,10 +93,14 @@ public class NetServer implements ApplicationListener{ }); net.handleServer(ConnectPacket.class, (con, packet) -> { + if(con.kicked) return; + if(con.address.startsWith("steam:")){ packet.uuid = con.address.substring("steam:".length()); } + con.connectTime = Time.millis(); + String uuid = packet.uuid; byte[] buuid = Base64Coder.decode(uuid); CRC32 crc = new CRC32(); @@ -249,7 +253,8 @@ public class NetServer implements ApplicationListener{ }); net.handleServer(InvokePacket.class, (con, packet) -> { - if(con.player == null) return; + if(con.player == null || con.kicked) return; + try{ RemoteReadServer.readPacket(packet.reader(), packet.type, con.player); }catch(ValidateException e){ @@ -748,6 +753,8 @@ public class NetServer implements ApplicationListener{ @Remote(targets = Loc.client) public static void connectConfirm(Player player){ + if(player.con.kicked) return; + player.add(); if(player.con == null || player.con.hasConnected) return; diff --git a/core/src/mindustry/net/NetConnection.java b/core/src/mindustry/net/NetConnection.java index cf1e47bbbd..02b1c1649d 100644 --- a/core/src/mindustry/net/NetConnection.java +++ b/core/src/mindustry/net/NetConnection.java @@ -19,6 +19,8 @@ public abstract class NetConnection{ public @Nullable Player player; public boolean kicked = false; + /** When this connection was established. */ + public long connectTime = Time.millis(); /** ID of last received client snapshot. */ public int lastReceivedClientSnapshot = -1; /** Timestamp of last received snapshot. */ From cc65feb392a261e2354234d4b2abd872a8823007 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 4 Mar 2021 18:39:47 -0500 Subject: [PATCH 389/426] Added ConnectionEvent --- .../java/mindustry/annotations/remote/RemoteProcess.java | 2 +- core/src/mindustry/core/NetServer.java | 2 ++ core/src/mindustry/game/EventType.java | 9 +++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java b/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java index 6be9c9c2d2..916bb3f278 100644 --- a/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java +++ b/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java @@ -63,7 +63,7 @@ public class RemoteProcess extends BaseProcessor{ classes = new Seq<>(); Seq orderedElements = elements.copy(); - orderedElements.sortComparing(Object::toString); + orderedElements.sort((a, b) -> -a.toString().compareTo(b.toString())); //create methods for(Smethod element : orderedElements){ diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 8747e8f00c..565134b9a9 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -81,6 +81,8 @@ public class NetServer implements ApplicationListener{ public NetServer(){ net.handleServer(Connect.class, (con, connect) -> { + Events.fire(new ConnectionEvent(con)); + if(admins.isIPBanned(connect.addressTCP) || admins.isSubnetBanned(connect.addressTCP)){ con.kick(KickReason.banned); } diff --git a/core/src/mindustry/game/EventType.java b/core/src/mindustry/game/EventType.java index 73590f3679..46729b1baf 100644 --- a/core/src/mindustry/game/EventType.java +++ b/core/src/mindustry/game/EventType.java @@ -383,6 +383,15 @@ public class EventType{ } } + /** Called when a connection is established to a client. */ + public static class ConnectionEvent{ + public final NetConnection connection; + + public ConnectionEvent(NetConnection connection){ + this.connection = connection; + } + } + /** Called after connecting; when a player receives world data and is ready to play.*/ public static class PlayerJoin{ public final Player player; From 2bb303e7095a7749bc1e1a327ff1253329eb73b8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 4 Mar 2021 18:41:30 -0500 Subject: [PATCH 390/426] Fixed #4856 --- core/src/mindustry/logic/ConditionOp.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/logic/ConditionOp.java b/core/src/mindustry/logic/ConditionOp.java index 54a88f4d29..6af660bafe 100644 --- a/core/src/mindustry/logic/ConditionOp.java +++ b/core/src/mindustry/logic/ConditionOp.java @@ -1,8 +1,10 @@ package mindustry.logic; +import arc.util.*; + public enum ConditionOp{ - equal("==", (a, b) -> Math.abs(a - b) < 0.000001, (a, b) -> a == b), - notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001, (a, b) -> a != b), + equal("==", (a, b) -> Math.abs(a - b) < 0.000001, Structs::eq), + notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001, (a, b) -> !Structs.eq(a, b)), lessThan("<", (a, b) -> a < b), lessThanEq("<=", (a, b) -> a <= b), greaterThan(">", (a, b) -> a > b), From 0c28bb7dcf8745c26021cd9933e766b5d38abb1c Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Fri, 5 Mar 2021 07:21:26 -0800 Subject: [PATCH 391/426] DefenderAI that makes octs follow units (#4757) --- core/src/mindustry/ai/types/DefenderAI.java | 34 +++++++++++++++++++++ core/src/mindustry/content/UnitTypes.java | 2 ++ core/src/mindustry/entities/Units.java | 20 +++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 core/src/mindustry/ai/types/DefenderAI.java diff --git a/core/src/mindustry/ai/types/DefenderAI.java b/core/src/mindustry/ai/types/DefenderAI.java new file mode 100644 index 0000000000..04cc59435d --- /dev/null +++ b/core/src/mindustry/ai/types/DefenderAI.java @@ -0,0 +1,34 @@ +package mindustry.ai.types; + +import arc.math.*; +import mindustry.entities.*; +import mindustry.entities.Units.*; +import mindustry.entities.units.*; +import mindustry.gen.*; +import mindustry.world.meta.*; + +public class DefenderAI extends AIController{ + + @Override + public void updateMovement(){ + if(target != null){ + moveTo(target, unit.range(), 5f); + unit.lookAt(target); + }else{ + Teamc block = targetFlag(unit.x, unit.y, BlockFlag.rally, false); + if(block == null) block = unit.closestCore(); + moveTo(block, 60f); + } + } + + @Override + protected void updateTargeting(){ + if(retarget()) target = findTarget(unit.x, unit.y, 0f, true, true); + } + + @Override + protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){ + //Sort by max health and closer target. + return Units.closest(unit.team, x, y, u -> !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 800f); + } +} diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index c53770e0fc..7f4ae97766 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1370,6 +1370,8 @@ public class UnitTypes implements ContentList{ }}; oct = new UnitType("oct"){{ + defaultController = DefenderAI::new; + armor = 16f; health = 24000; speed = 0.8f; diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index 970374811b..0b0538adb6 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -248,7 +248,7 @@ public class Units{ return result; } - /** Returns the closest ally of this team. Filter by predicate. */ + /** Returns the closest ally of this team in a range. Filter by predicate. */ public static Unit closest(Team team, float x, float y, float range, Boolf predicate){ result = null; cdist = 0f; @@ -266,6 +266,24 @@ public class Units{ return result; } + /** Returns the closest ally of this team using a custom comparison function. Filter by predicate. */ + public static Unit closest(Team team, float x, float y, Boolf predicate, Sortf sort){ + result = null; + cdist = 0f; + + for(Unit e : Groups.unit){ + if(!predicate.get(e) || e.team() != team) continue; + + float cost = sort.cost(e, x, y); + if(result == null || cost < cdist){ + result = e; + cdist = cost; + } + } + + return result; + } + /** Returns the closest ally of this team. Filter by predicate. * Unlike the closest() function, this only guarantees that unit hitboxes overlap the range. */ public static Unit closestOverlap(Team team, float x, float y, float range, Boolf predicate){ From b6c645b7018d06fea1ded727fc58ddd91de8fe91 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 11:10:12 -0500 Subject: [PATCH 392/426] Better DefenderAI / Vela building / Anuken/Mindustry-Suggestions/issues/2074 --- .../sprites/blocks/environment/ice-snow1.png | Bin 338 -> 514 bytes .../sprites/blocks/environment/ice-snow2.png | Bin 359 -> 536 bytes .../sprites/blocks/environment/ice-snow3.png | Bin 290 -> 430 bytes core/src/mindustry/ai/types/DefenderAI.java | 24 +++++++++++------- core/src/mindustry/content/UnitTypes.java | 5 ++-- core/src/mindustry/entities/Units.java | 16 ++++++------ 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/core/assets-raw/sprites/blocks/environment/ice-snow1.png b/core/assets-raw/sprites/blocks/environment/ice-snow1.png index ee593e9f64deccecdd4eaad55be67d7015532f58..d2010a010684c0665acfcc620cb0879013082af0 100644 GIT binary patch delta 489 zcmcb_)WkADxt@WsILO_JVcj{ImkbPydpunnLn2y_PB+XtY#`D$zg3}?r;$(cvY|jx ztJ4eDn#MT`z4HThmArB7Ss1R-)^{!}*vGg;L*$C$iK+AMO`iA2?C0_u8^6>~nqPO) z_4l{L2R)a5xZU<~<(>X|!OG>=r@w#r{pzd9wSGs>yj~@r8W(O`f7_kmz|6;dMQ2ol zUb_D~e}{R2RBoQ0`^@RLIj7wA+!C7@e(>^P@l2azF^djKB$wU2$6VmpXL{W9=-QS; z62?ys+|5;A)OWIPPSiP(7Ip@P183d(EZH3#SHy1ro~QH7IPl|eD>Z_Fw$j@5ekW~I#M zIW3c&T*QA$6l=0@PsrXk<9BIuxVU~IR?jw16>jcee0WxEX@;PeeNf*-*6Z(Fv);3Dbbp?4d9ro( ztl!B7K0cXROOC|5EuY33{_g0?vy5~2Cl|kDU)cIBW%2(H2@DJj44$rjF6*2UngFnc B=rRBR delta 312 zcmZo-xx_Rwd)5S5Q;?~jYzFdb41Xv&J+##*6Rv|q7Xm7RnMJ`RnbJd?GyKpya zT>NgTBCNgrZQ#GiOZ5eNZDP0HxxNgudp#`bU#q{8x*!nf@&E9O z_8GS~u=a>VUC=tP`Ic>ND076d>ckHm42mHQ<~E!53qIl&;5^T8#!ZAXogr6zDWmek zz>YOs{)|S)SC-Cf$Y^(7JB=~Iexl?ZueNPV z8Cp8@qJ$gH<+jXVU6IV{Yq<3Lm(vWlHomko__hB5Lj~Jfh6~S|t}^^8`SZGp(cVCf VcVYYV00ssI22WQ%mvv4FO#tOPh|B;0 diff --git a/core/assets-raw/sprites/blocks/environment/ice-snow2.png b/core/assets-raw/sprites/blocks/environment/ice-snow2.png index a9ffcf10887c28627abb1aed9cfa584800d5bbcf..5a0d5458d4c892e96d7d7572a97bceef3bbbb17f 100644 GIT binary patch delta 511 zcmaFPG=pV=ayM1Gu(LhZ1EY>hwD04 zFS67+GRLm_!=$duJkwskzAxzU?DpN74LePyU165UvI|*sSmJYyeP+GAUCoT_4o8b; zXERTIEd4q0$#2hk_G5Xwrxiun9QpEW?YTRmJ)Cp5+)6pu+Sh(+X4EvxUj8YwSSMM= zUvTHpnYo?emTz946xTwg9SSSzE$0ezEo4pSHs}r3|NOtL!?alHZB4m_3&#l)KkMld zEwg?qc_&U>sx*baWy-U_z-zpB8MFLWOGz!hw~CwL%jvaZ1yQ{(89ZFs6fGE9A1KHi z3Vm=(`GVFQ|K%(T(gjWJQ#z#DF2e-t4n*GS4DI^Rrv8?WA~9u zS1SD_l3mM`=Jn^Fe!I85@}D`^Mg|SZ3OA>Jyw`<(nSXrn{r0sYR+*&=KQs><_!Hb}Jo5~w!ZaROUUZ2U`?ZcakpB}tZ zIm5BxxwPqW%dUwIPb*U2H=j-wIe0v4?IZy#I!v|4}HVRMb7(d^iXP=y?vqS@zqRLXB}JK zTsU+lY+?DHZT{YotlL%Al+ST{pm$(e&a+1sKj;Pgv`JRg`Qhqd@4$PEtKvhQWa`6= u-50)9eo#AbU^UZ+$5TX4c%?jM-?TLF+xnl1n-~}v7(8A5T-G@yGywoo*`xjd diff --git a/core/assets-raw/sprites/blocks/environment/ice-snow3.png b/core/assets-raw/sprites/blocks/environment/ice-snow3.png index f38d778b297c8baae5fde0effdeb720fb3e9c860..4375ee71397f595367cfdd5b8acdadaa5a537b5d 100644 GIT binary patch delta 404 zcmZ3)w2pa#NGZx^prw85kHdJY5_^B3jQ*H_SV1z~j1~nOV|`<;4TTo5k%+ zj{1|hzi`D?wZ$zE=VW@qclYsHxvr`c0t*_fPfkb)Qqh&xW8|O2vtNJGq8E>TeZ8FM z7_H0sU!3XGPR83=!ac8-UFFu~^DWbsr{+4Qxl&u5?P+%c!eXb%05}c!~PUuHr1uFxi5mN6fSB z6}c9axi_i`sQZXE8R}iT*EM?C`Gb`CB+odWSA|Ap&Qw=d6|x$hwFVFm^U N22WQ%mvv4FO#t|fvMB%n delta 262 zcmZ3-yohOnO8rYu7srr_TW_cNay2{fv=$ed@160$cUQ^td#>HBni8MCAF~MVYRn0F zR_iC{`NC3v{X9?e1Lv819`Ex0lAs;Kpx5VAk;s(sD3HVDk4QtAhEg1Ff^5${37!Xk zC8M@6A4r}N`tj}D^0h0IVu>PFp2a zc;0zZ=gHNYvu3rcH1xA?YO!?K(lg!X@H+;vBlWr}lE#fjEtV{II5&&+>RzaA+SH=Y z?64?pu@|Go=1YOs%B1hA2iXJ|bI&qe^g`!{-(k7j3iH0`vrKE}oK0u^eo5Muca6)O T)uHhW3=9mOu6{1-oD!M !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 800f); + //find unit to follow if not in rally mode + if(command() != UnitCommand.rally){ + //Sort by max health and closer target. + var result = Units.closest(unit.team, x, y, Math.max(range, 400f), u -> !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 800f); + if(result != null) return result; + } + + //find rally point + var block = targetFlag(unit.x, unit.y, BlockFlag.rally, false); + if(block != null) return block; + //return core if found + return unit.closestCore(); } } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 7f4ae97766..ed966e869d 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -405,13 +405,14 @@ public class UnitTypes implements ContentList{ rotateSpeed = 1.6f; canDrown = false; mechFrontSway = 1f; + buildSpeed = 3f; mechStepParticles = true; mechStepShake = 0.15f; ammoType = AmmoTypes.powerHigh; - speed = 0.36f; - boostMultiplier = 2.1f; + speed = 0.38f; + boostMultiplier = 2.2f; engineOffset = 12f; engineSize = 6f; lowAltitude = true; diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index 0b0538adb6..49e33ec06b 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -266,20 +266,20 @@ public class Units{ return result; } - /** Returns the closest ally of this team using a custom comparison function. Filter by predicate. */ - public static Unit closest(Team team, float x, float y, Boolf predicate, Sortf sort){ + /** Returns the closest ally of this team in a range. Filter by predicate. */ + public static Unit closest(Team team, float x, float y, float range, Boolf predicate, Sortf sort){ result = null; cdist = 0f; - for(Unit e : Groups.unit){ - if(!predicate.get(e) || e.team() != team) continue; + nearby(team, x, y, range, e -> { + if(!predicate.get(e)) return; - float cost = sort.cost(e, x, y); - if(result == null || cost < cdist){ + float dist = sort.cost(e, x, y); + if(result == null || dist < cdist){ result = e; - cdist = cost; + cdist = dist; } - } + }); return result; } From d34dd0c6033d229299a5460f64e885c2462f2c1a Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Fri, 5 Mar 2021 08:17:55 -0800 Subject: [PATCH 393/426] Add message for mods that have hidden = true (#4717) * Multiplayer compatability message * Make more sense? --- core/assets/bundles/bundle.properties | 1 + core/src/mindustry/ui/dialogs/ModsDialog.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 671a34ebaf..cd3d67bba1 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -126,6 +126,7 @@ mod.installed = [[Installed] mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Enabled mod.disabled = [scarlet]Disabled +mod.multiplayercompatable = Multiplayer Compatible mod.disable = Disable mod.content = Content: mod.delete.error = Unable to delete mod. File may be in use. diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index cbb57b6d3f..b53866b817 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -278,6 +278,9 @@ public class ModsDialog extends BaseDialog{ }else if(mod.hasContentErrors()){ text.labelWrap("@mod.erroredcontent").growX(); text.row(); + }else if(mod.meta.hidden){ + text.labelWrap("@mod.multiplayercompatable").growX(); + text.row(); } }).top().growX(); From 4f0f2499be400fbe68b791e5df433e5fff2be8bb Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 11:19:55 -0500 Subject: [PATCH 394/426] mod.multiplayercompatable in gray --- core/assets/bundles/bundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index cd3d67bba1..960c6a435f 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -126,7 +126,7 @@ mod.installed = [[Installed] mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Enabled mod.disabled = [scarlet]Disabled -mod.multiplayercompatable = Multiplayer Compatible +mod.multiplayercompatable = [gray]Multiplayer Compatible mod.disable = Disable mod.content = Content: mod.delete.error = Unable to delete mod. File may be in use. From 569293e577a8c19c11b27ce0d80759d8def34326 Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Fri, 5 Mar 2021 08:21:23 -0800 Subject: [PATCH 395/426] Shadow with width/height (#4609) --- core/src/mindustry/graphics/Drawf.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/mindustry/graphics/Drawf.java b/core/src/mindustry/graphics/Drawf.java index e38fa74c82..32576bf55a 100644 --- a/core/src/mindustry/graphics/Drawf.java +++ b/core/src/mindustry/graphics/Drawf.java @@ -111,6 +111,12 @@ public class Drawf{ Draw.rect(region, x, y); Draw.color(); } + + public static void shadow(TextureRegion region, float x, float y, float width, float height, float rotation){ + Draw.color(Pal.shadow); + Draw.rect(region, x, y, width, height, rotation); + Draw.color(); + } public static void liquid(TextureRegion region, float x, float y, float alpha, Color color, float rotation){ Draw.color(color, alpha); From 120c694a4237b54b7606f1bfb03ffbad4bb36b28 Mon Sep 17 00:00:00 2001 From: MEEP of Faith <54301439+MEEPofFaith@users.noreply.github.com> Date: Fri, 5 Mar 2021 08:25:58 -0800 Subject: [PATCH 396/426] Mention Foreshadow's special targeting in its description. (#4419) * Mention Foreshadow special targetting. * Better wording --- core/assets/bundles/bundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 960c6a435f..6cf1e0ad1e 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1460,7 +1460,7 @@ block.ripple.description = Shoots clusters of shells at ground enemies over long block.cyclone.description = Fires explosive clumps of flak at nearby enemies. block.spectre.description = Fires large armor-piercing bullets at air and ground targets. block.meltdown.description = Charges and fires a persistent laser beam at nearby enemies. Requires coolant to operate. -block.foreshadow.description = Fires a large single-target bolt over long distances. +block.foreshadow.description = Fires a large single-target bolt over long distances. Prioritizes enemies with higher max health. block.repair-point.description = Continuously repairs the closest damaged unit in its vicinity. block.segment.description = Damages and destroys incoming projectiles. Laser projectiles are not targeted. block.parallax.description = Fires a tractor beam that pulls in air targets, damaging them in the process. From b75a8d52606b8cf5e6b554844e5fad4ddd3c556b Mon Sep 17 00:00:00 2001 From: Patrick 'Quezler' Mounier Date: Fri, 5 Mar 2021 17:27:51 +0100 Subject: [PATCH 397/426] Fix typo to preserve sanity (#4857) * compatable > compatible * compatable > compatible --- core/assets/bundles/bundle.properties | 4 ++-- core/src/mindustry/ui/dialogs/ModsDialog.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 6cf1e0ad1e..408f63bc72 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -126,7 +126,7 @@ mod.installed = [[Installed] mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Enabled mod.disabled = [scarlet]Disabled -mod.multiplayercompatable = [gray]Multiplayer Compatible +mod.multiplayer.compatible = [gray]Multiplayer Compatible mod.disable = Disable mod.content = Content: mod.delete.error = Unable to delete mod. File may be in use. @@ -1663,4 +1663,4 @@ lenum.mine = Mine at a position. lenum.build = Build a structure. lenum.getblock = Fetch a building and type at coordinates.\nUnit must be in range of position.\nSolid non-buildings will have the type [accent]@solid[]. lenum.within = Check if unit is near a position. -lenum.boost = Start/stop boosting. \ No newline at end of file +lenum.boost = Start/stop boosting. diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index b53866b817..012dc54af8 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -279,7 +279,7 @@ public class ModsDialog extends BaseDialog{ text.labelWrap("@mod.erroredcontent").growX(); text.row(); }else if(mod.meta.hidden){ - text.labelWrap("@mod.multiplayercompatable").growX(); + text.labelWrap("@mod.multiplayer.compatible").growX(); text.row(); } }).top().growX(); From 7478cdf4a497c12336908f6fa813a2ca9cafea20 Mon Sep 17 00:00:00 2001 From: Antsiferov Andrew Date: Fri, 5 Mar 2021 19:28:28 +0300 Subject: [PATCH 398/426] [Bundle][RU] actual L10n (#4748) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 3 new, 1 deleted New: rules.unitcapvariable rules.unitcap laccess.color Deleted: lenum.color * 1 line changed rules.unitcap * 2 new, 1 deleted New: mods.initfailed setting.modcrashdisable.name Deleted: mods.alphainfo - Отключение модов после вылета на старте * Fixed #4715 * Content parser class discovery improvements * Use github build status (#4718) Why does this still use travis? It was ditched months ago * Make status colors the same (#4719) It bothers me ok * Better splash damage handling for small radii * Fixed #4729 * Uncap content names in resolution * Fixed UnitReq parsing * Fixed #4732 * Allow JSON mod content types from other class loaders * Better JSON null validation / Disable mods on startup crash * Logic tooltips on mobile devices w/ long-press * Add Survival and PvP servers (#4736) * Update servers_v6.json (#4735) add 1 more server for CxZx * arc * Balance tweaks * Fixing remaining typos\errors in bundle_fr (#4397) * Fixing remaining typos errors in bundle_fr There are some errors that had managed to get through the verification. Imma chase them down! * added logic hints and some typo fixes * Fixing 2 typos in bundle.properties L1548: Color statement affects every following draw operations. * smolfixes * Fixed "fix" in #4397 * [Bundle][RO] Update (#4725) * [Bundle][RO] Update This PR was tested in-game and is ready to merge at any time. Changelog: - New strings/changes up to commit 1ef7ae70796beb4a28dee8f2c74b626d28348481 - Typo fixes & various other improvements * Reducing confusion * Update bundle_ro.properties * Fixing typos and descriptions [bundle_es.properties] (#4727) * Fixing and descriptions [bundle_es.properties] * Forgot something * Update Logic Draw Hints (#4734) Wrapped up some previous logic hints, too. * german translation for build 125, full android translation (#4703) * update german translation to https://github.com/Anuken/Mindustry/commit/631e4d9eefca8b94de4fc52e57387b2c2f4ffecf * update android translation to https://github.com/Anuken/Mindustry/commit/e816f6110de6ec9638b5a6be8a9710bdc49f5f4d with regard to https://github.com/Anuken/Mindustry/commit/5ec5f1aa93dcac5c813027b23379f529dbf69e3d * improve translation with ideas from others * update german steam discription to https://github.com/Anuken/Mindustry/commit/e86a3e9d09d0f41a651d5e66403ea48c70add048 * update german translation to https://github.com/Anuken/Mindustry/commit/1ef7ae70796beb4a28dee8f2c74b626d28348481#diff-5e346bcec4e8e1d545e035b1e438472bc51937398ac3e8e81308605ec82aea2c * changes from stuffyAI * cross-platform as suggested by stuffyAI * stuffyAI genau, hast recht Co-authored-by: stuffyAI <59014072+stuffyAI@users.noreply.github.com> Co-authored-by: stuffyAI <59014072+stuffyAI@users.noreply.github.com> * Update bundle_vi.properties (#4724) * Fixed mod crash disable setting name * Various fixes * Steam icon changes * arc * Update Vietnamese Translation. (#4660) * Update translation, fix some typo * About 150 lines to do left. * Typos fix #_1 * Typos fix + add trans * Update to lastest commit. * Base logic translation. * a lot of typo ... * some update from main bundle. * Add more logic hint. * translated recent update (#4742) * Move update function of resupply point 5x1 spaces back (#4746) * Remove stray spaces from accelerator (#4465) * 10 new lines graphicstype.clear graphicstype.color graphicstype.stroke graphicstype.line graphicstype.rect graphicstype.linerect graphicstype.poly graphicstype.linepoly graphicstype.triangle graphicstype.image * 1 line changed lenum.stop (typo) * 6 new lines logic.nounitbuild laccess.controller laccess.dead laccess.controlled laccess.commanded lenum.idle * 1 new line setting.doubletapmine.name * 2 new, 2 changed New: trace.times.joined trace.times.kicked Changed: unit.seconds unit.minutes * 1 line changed trace.times.joined * 1 new line mod.multiplayercompatable - quick commit before potential merge, might fix it later Co-authored-by: Vanguard <55051135+XEN0PHIL@users.noreply.github.com> Co-authored-by: Anuken Co-authored-by: buthed010203 Co-authored-by: Fatonndev <56699208+Fatonndev@users.noreply.github.com> Co-authored-by: CxZxRainzz <78591136+CxZxRainzz@users.noreply.github.com> Co-authored-by: Phinner <62483793+Phinner@users.noreply.github.com> Co-authored-by: YellOw139 <70975516+YellOw139@users.noreply.github.com> Co-authored-by: BlueThecno <69437358+BlueThecno@users.noreply.github.com> Co-authored-by: 彭瑞暄 Co-authored-by: Catchears <57631841+Catchears@users.noreply.github.com> Co-authored-by: stuffyAI <59014072+stuffyAI@users.noreply.github.com> Co-authored-by: Arnyyx <74717260+Arnyyx@users.noreply.github.com> Co-authored-by: Ngọc Lam <33188123+NgLamVN@users.noreply.github.com> Co-authored-by: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Co-authored-by: Patrick 'Quezler' Mounier --- core/assets/bundles/bundle_ru.properties | 31 +++++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index e83cd3535c..b1e14dcbd2 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -113,7 +113,7 @@ committingchanges = Внесение изменений done = Готово feature.unsupported = Ваше устройство не поддерживает эту возможность. -mods.alphainfo = Имейте в виду, что модификации находятся в альфа-версии и [scarlet]могут содержать много ошибок[]. Докладывайте о любых проблемах, которые вы найдете в Mindustry Github. +mods.initfailed = [red]⚠[] Не удалось инициализировать предыдущий запуск Mindustry. Это могло быть вызвано неисправными модификациями.\n\nЧтобы предотвратить зацикленные вылеты игры, [red]все модификации были отключены.[]\n\nЧтобы отключить эту функцию, выключите её в [accent]Настройки->Игра->Отключение модификаций после вылета при запуске[]. mods = Модификации mods.none = [lightgray]Модификации не найдены! mods.guide = Руководство по модификациям @@ -126,6 +126,7 @@ mod.installed = [[Установлено] mod.display = [gray]Модификация:[orange] {0} mod.enabled = [lightgray]Включён mod.disabled = [scarlet]Выключен +mod.multiplayercompatable = [gray]Доступен в игре по сети mod.disable = Выкл. mod.content = Содержимое: mod.delete.error = Невозможно удалить модификацию. Возможно, файл используется. @@ -217,6 +218,8 @@ trace = Отслеживать игрока trace.playername = Имя игрока: [accent]{0} trace.ip = IP: [accent]{0} trace.id = ID: [accent]{0} +trace.times.joined = Присоединялся раз: [accent]{0} +trace.times.kicked = Был выгнан раз: [accent]{0} trace.mobile = Мобильный клиент: [accent]{0} trace.modclient = Пользовательский клиент: [accent]{0} invalidid = Недопустимый ID клиента! Отправьте отчёт об ошибке. @@ -771,8 +774,8 @@ unit.itemssecond = предметов/секунду unit.liquidunits = жидкостных единиц unit.powerunits = энерг. единиц unit.degrees = ° -unit.seconds = сек. -unit.minutes = мин. +unit.seconds = сек +unit.minutes = мин unit.persecond = /сек unit.perminute = /мин unit.timesspeed = x скорость @@ -800,6 +803,8 @@ setting.logichints.name = Подсказки для логики setting.flow.name = Показывать скорость потока ресурсов setting.backgroundpause.name = Фоновая пауза setting.buildautopause.name = Автоматическая приостановка строительства +setting.doubletapmine.name = Добыча руды двойным нажатием +setting.modcrashdisable.name = Отключение модификаций после вылета при запуске setting.animatedwater.name = Анимированные поверхности setting.animatedshields.name = Анимированные щиты setting.antialias.name = Сглаживание[lightgray] (требует перезапуска)[] @@ -1536,6 +1541,8 @@ lst.unitcontrol = Управляет привязанной в данный мо lst.unitradar = Обнаруживает единицы вокруг привязанной в данный момент единицы. lst.unitlocate = Обнаруживает позицию/постройку определённого типа где-либо на карте. Требует привязанную единицу. +logic.nounitbuild = [red]Строительство с помощью процессоров здесь запрещено. + lenum.type = Тип постройки/единицы. \nНапример, для маршрутизатора это будет [accent]@router[].\nНе строка. lenum.shoot = Стрельба в определённую позицию. lenum.shootp = Стрельба в единицу/постройку с расчётом скорости. @@ -1543,6 +1550,21 @@ lenum.configure = Конфигурация постройки, например, lenum.enabled = Включён ли блок. laccess.color = Цвет осветителя. +laccess.controller = Командующий единицей. Если единица управляется процессором, возвращает процессор. Если в строю, возращает командуещего.\nВ противном случае возвращает саму единицу. +laccess.dead = Является ли единица/постройка неработающей или несуществующей. +laccess.controlled = Возвращает:\n[accent]@ctrlProcessor[] если единица управляется процессором\n[accent]@ctrlPlayer[] если единица/постройка управляется игроком\n[accent]@ctrlFormation[] если единица в строю\nВ противном случае — 0. +laccess.commanded = [red]Устарело. Будет удалено![]\nВместо этого, используйте [accent]controlled[]. + +graphicstype.clear = Заливка дисплея цветом. +graphicstype.color = Установка цвета для следующих операций отрисовки. +graphicstype.stroke = Установка толщины линии. +graphicstype.line = Отрисовка отрезка. +graphicstype.rect = Отрисовка закрашенного прямоугольника. +graphicstype.linerect = Отрисовка контура прямоугольника. +graphicstype.poly = Отрисовка закрашенного правильного многоугольника. +graphicstype.linepoly = Отрисовка контура правильного многоугольника. +graphicstype.triangle = Отрисовка закрашенного треугольника. +graphicstype.image = Отрисовка внутриигровых спрайтов.\nНапример: [accent]@router[] или [accent]@dagger[]. lenum.always = Всегда истина. lenum.idiv = Целочисленное деление. @@ -1625,7 +1647,8 @@ unitlocate.outx = Вывод X координаты. unitlocate.outy = Вывод Y координаты. unitlocate.group = Группа построек для поиска. -lenum.stop = Остановка передвижения/копания/стротельства. +lenum.idle = Остановка движения, но продолжение строительства/копания.\nСостояние по умолчанию. +lenum.stop = Остановка передвижения/копания/строительства. lenum.move = Перемещение в определённую позицию. lenum.approach = Приближение к позиции с указанным радиусом. lenum.pathfind = Перемещение к точке появления врагов. From 39cbd607eff0991937042bdf6ee3e612a56a1d37 Mon Sep 17 00:00:00 2001 From: Catchears <57631841+Catchears@users.noreply.github.com> Date: Fri, 5 Mar 2021 17:29:18 +0100 Subject: [PATCH 399/426] update german translation (#4826) * update german translation to 781410ea049752480b5cd29f97389cee553009c0 * change from stuffyAI * update german translation to https://github.com/Anuken/Mindustry/commit/ae838b939236271dc6b54532e3d62e82372a6270 --- core/assets/bundles/bundle_de.properties | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index ca9d806c2f..b9a65373d4 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -113,7 +113,7 @@ committingchanges = Veränderungen werden übernommen done = Fertig feature.unsupported = Dein System unterstützt dieses Feature nicht. -mods.alphainfo = Vergiss nicht, dass Mods in der Alpha sind und[scarlet] sehr fehlerhaft sein können[].\nMelde alle Probleme auf GitHub oder Discord. +mods.initfailed = [red]⚠[] Die vorherige Mindustry-Instanz konnte nicht starten. Dies lag wahrscheinlich an fehlerhaften Mods.\n\nDamit das Spiel starten kann, [red]wurden alle Mods deaktiviert.[]\n\nWenn du nicht willst, dass das passiert, kannst du es unter [accent]Einstellungen->Spiel->Mods bei Absturz deaktivieren[] ändern. mods = Mods mods.none = [lightgray]Keine Mods gefunden! mods.guide = Modding-Anleitung @@ -216,9 +216,11 @@ server.hidden = Versteckt trace = Spieler verfolgen trace.playername = Spielername: [accent]{0} trace.ip = IP: [accent]{0} -trace.id = Eindeutige ID: [accent]{0} +trace.id = ID: [accent]{0} trace.mobile = Mobiler Client: [accent]{0} trace.modclient = Gemoddeter Client: [accent]{0} +trace.times.joined = Beigetreten: [accent]{0}[] Mal +trace.times.kicked = Rausgeworfen: [accent]{0}[] Mal invalidid = Ungültige Client-ID! Berichte den Fehler. server.bans = Verbannungen server.bans.none = Keine verbannten Spieler gefunden! @@ -800,6 +802,8 @@ setting.logichints.name = Logiktipps setting.flow.name = Ressourcen-Fluss anzeigen setting.backgroundpause.name = Im Hintergrund pausieren setting.buildautopause.name = Bauen automatisch pausieren +setting.doubletapmine.name = Doppeltippen zum Abbauen +setting.modcrashdisable.name = Mods bei Absturz deaktivieren setting.animatedwater.name = Animiertes Wasser setting.animatedshields.name = Animierte Schilde setting.antialias.name = Antialias[lightgray] (Neustart erforderlich)[] @@ -1536,6 +1540,8 @@ lst.unitcontrol = Steuert [accent]@unit[]. lst.unitradar = Findet Einheiten in der Nähe von [accent]@unit[]. lst.unitlocate = Findet mit [accent]@unit[] bestimmte Positionen / Blöcke auf der ganzen Karte. +logic.nounitbuild = [red]Logik, die Blöcke baut, ist hier nicht erlaubt. + lenum.type = Englischer Name eines Blocks / einer Einheit. Ein Verteiler gibt [accent]@router[] wieder.\nKein string. lenum.shoot = Schießt auf eine Position. lenum.shootp = Schießt auf eine Einheit / einen Block und sagt deren Position voraus. @@ -1543,6 +1549,10 @@ lenum.configure = Blockkonfiguration, z.B. das ausgewählte Item in einem Sortie lenum.enabled = Ob der Block an oder aus ist. laccess.color = Illuminiererfarbe. +laccess.controller = Einheitensteurer. Gibt "processor" zurück, wenn die Einheit prozessorgesteuert ist,.\nGibt den Steuerer zurück, wenn die Einheit Teil einer Formation ist.\nSonst wird einfach die Einheit zurückgegeben. +laccess.dead = Ob ein Block / eine Einheit tot oder nicht mehr gültig ist. +laccess.controlled = Gibt zurück:\n[accent]@ctrlProcessor[] wenn die Einheit prozessorgesteuert ist\n[accent]@ctrlPlayer[] wenn die Einheit / der Block von einem Spieler gesteuert wird\n[accent]@ctrlFormation[] wenn die Einheit Teil einer Formation ist\nSonst 0. +laccess.commanded = [red]Veraltet. Wird bald entfernt![]\nBenutze stattdessen [accent]controlled[]. graphicstype.stroke = Setzt die Linienbreite fest. graphicstype.line = Zeichnet eine Linie. @@ -1554,6 +1564,7 @@ graphicstype.poly = Füllt ein gleichmäßiges Polygon. graphicstype.linepoly = Zeichnet den Umriss eines gleichmäßigen Polygons. graphicstype.triangle = Zeichnet ein Dreieck. graphicstype.image = Zeichnet ein Bild von einem englischen Namen.\nz.B. [accent]@router[] oder [accent]@dagger[]. + lenum.always = Immer. lenum.idiv = Division mit ganzen Zahlen. lenum.div = Division.\nGibt bei Teilung durch null [accent]null[] zurück. @@ -1635,6 +1646,7 @@ unitlocate.outx = Variable für die X-Koordinate. unitlocate.outy = Variable für die Y-Koordinate. unitlocate.group = Gesuchter Blocktyp. +lenum.idle = Bewegt sich nicht, baut aber weiter ab.\nDer normale Zustand. lenum.stop = Bewegung / Abbau / Bau abbrechen. lenum.move = Geht zu diese Position. lenum.approach = Geht auf einen Punkt mit einem bestimmten Radius zu. From 879adb745848f7c35c52af8a5723a60a95f57fda Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Sat, 6 Mar 2021 01:29:26 +0900 Subject: [PATCH 400/426] [KO] Update bundle_ko.properties (#4803) * Update bundle_ko.properties * translated recent changing * https://github.com/Anuken/Mindustry/pull/4844 * Update bundle_ko.properties * Add files via upload * unofficial details --- core/assets/bundles/bundle_ko.properties | 207 +++++++++++++++++- .../android/ko-KR/changelogs/29825.txt | 7 + 2 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/ko-KR/changelogs/29825.txt diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 8a7bf5dfe8..f8cc1aec98 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -1,6 +1,6 @@ credits.text = 만든이: [royal]Anuken[] - [sky]anukendev@gmail.com[] credits = 제작진 -contributors = 번역가와 기여 +contributors = 번역가와 기여자 discord = Mindustry Discord 서버에 가입하세요! link.discord.description = Mindustry Discord 공식 대화방 link.reddit.description = Mindustry 서브레딧 @@ -219,6 +219,8 @@ trace.ip = IP: [accent]{0} trace.id = UUID: [accent]{0} trace.mobile = 모바일 클라이언트: [accent]{0} trace.modclient = 사용자 지정 클라이언트: [accent]{0} +trace.times.joined = 입장 횟수: [accent]{0} +trace.times.kicked = 추방 횟수: [accent]{0} invalidid = 잘못된 클라이언트 ID입니다! 버그 보고서를 보내주세요. server.bans = 차단 목록 server.bans.none = 차단된 플레이어를 찾을 수 없습니다! @@ -800,6 +802,7 @@ setting.logichints.name = 로직 힌트 표시 setting.flow.name = 자원 흐름량 표시 setting.backgroundpause.name = 백그라운드에서 일시정지 setting.buildautopause.name = 건설 자동 일시정지 +setting.doubletapmine.name = 연속 터치로 채광 setting.modcrashdisable.name = 로딩 중 충돌 시 모드 비활성화 setting.animatedwater.name = 액체 애니메이션 효과 setting.animatedshields.name = 보호막 애니메이션 효과 @@ -1660,3 +1663,205 @@ lenum.build = 구조물 건설 lenum.getblock = 특정 좌표의 빌딩과 블록을 반환합니다.\n위치는 유닛의 인지 범위 내여야 합니다.\n자연 지형은 [accent]@solid[]의 타입을 가집니다. lenum.within = 좌표 주변 유닛 발견 여부 lenum.boost = 이륙 시작/중단 +#1665 줄 매칭 + +#-------------비공식 번역주------------- +#팁, 패치 기록, 약간의 관련 드립을 넣는 곳입니다. 이미 쓰여진 줄이 있다면 \n\n를 입력한 다음 작성하고 끝에 깃허브 작성자 닉네임(또는 디스코드)을 적어주세요. +#심각한 노잼, 뇌절, 무례한 말들을 적지 말아주세요, 이는 목적이 어떠하든 공통적으로 적용됩니다(친근함 유도를 위한 평어 x). 다음 패치에 업데이트되어 그 언어를 쓰는 모든 유저가 보게 됩니다. +#양이 너무 많으면 사족을 더 붙이는걸 추천하지 않습니다. +#이 비공식 번역주는 공식 디테일이 추가되면 언제든지 삭제될 수 있습니다. +#비어있는 디테일은 아래 details가 전부이므로 추가 또는 삭제를 따로 안하셔도 됩니다. +#유색코드가 아닌, 흑백 색코드만 사용 가능합니다. 되도록이면 그냥 안쓰시는걸 추천. +#관련 문의는 공식 디스코드에서 절 불러주세요. Sharlotte#0018 + +#아이템 +item.metaglass.details = 쓰임세가 가장 적은 아이템 +item.graphite.details = +item.sand.details = +item.titanium.details = +item.thorium.details = +item.silicon.details = +item.plastanium.details = +item.phase-fabric.details = +item.surge-alloy.details = +item.blast-compound.details = 화력 발전기에 넣어보세요. +item.pyratite.details = + +#액체 +liquid.water.details = +liquid.slag.details = +liquid.oil.details = +liquid.cryofluid.details = 티타늄을 갈아서 물에 희석했다는 소문이 있다. + +#블록 +block.resupply-point.details = +block.armored-conveyor.details = +block.illuminator.details = +block.message.details = +block.graphite-press.details = +block.multi-press.details = +block.silicon-smelter.details = +block.kiln.details = +block.plastanium-compressor.details = 석유를 정말 많이 먹는다. +block.phase-weaver.details = +block.alloy-smelter.details = +block.cryofluid-mixer.details = +block.blast-mixer.details = +block.pyratite-mixer.details = +block.melter.details = +block.separator.details = +block.spore-press.details = +block.pulverizer.details = +block.coal-centrifuge.details = 가성비가 매우 뛰어나다. +block.incinerator.details = +block.power-void.details = +block.power-source.details = +block.item-source.details = +block.item-void.details = +block.liquid-source.details = +block.liquid-void.details = +block.copper-wall.details = +block.copper-wall-large.details = +block.titanium-wall.details = +block.titanium-wall-large.details = +block.plastanium-wall.details = +block.plastanium-wall-large.details = +block.thorium-wall.details = +block.thorium-wall-large.details = +block.phase-wall.details = +block.phase-wall-large.details = +block.surge-wall.details = +block.surge-wall-large.details = +block.door.details = +block.door-large.details = +block.mender.details = +block.mend-projector.details = +block.overdrive-projector.details = +block.force-projector.details = +block.shock-mine.details = +block.conveyor.details = +block.titanium-conveyor.details = +block.plastanium-conveyor.details = +block.junction.details = +block.bridge-conveyor.details = 티타늄 컨베이어보다 빠르다. +block.phase-conveyor.details = +block.sorter.details = 자원을 분류하여 주변 블록에 건내는 과정이 거의 한순간에 일어난다. +block.inverted-sorter.details = +block.distributor.details = +block.overflow-gate.details = +block.underflow-gate.details = +block.mass-driver.details = 발사할려면 최소 아이템 10개가 필요하다. +block.mechanical-pump.details = +block.rotary-pump.details = +block.thermal-pump.details = +block.conduit.details = +block.pulse-conduit.details = +block.plated-conduit.details = +block.liquid-router.details = +block.liquid-tank.details = +block.liquid-junction.details = +block.bridge-conduit.details = +block.phase-conduit.details = +block.power-node.details = +block.power-node-large.details = +block.surge-tower.details = +block.diode.details = +block.battery.details = +block.battery-large.details = +block.combustion-generator.details = +block.thermal-generator.details = +block.steam-generator.details = +block.differential-generator.details = +block.rtg-generator.details = +block.solar-panel.details = +block.solar-panel-large.details = +block.thorium-reactor.details = +block.impact-reactor.details = +block.mechanical-drill.details = +block.pneumatic-drill.details = +block.laser-drill.details = +block.blast-drill.details = +block.water-extractor.details = +block.cultivator.details = +block.cultivator.details = +block.oil-extractor.details = +block.vault.details = +block.container.details = +block.unloader.details = +block.launch-pad.details = +block.duo.details = +block.scatter.details = +block.scorch.details = +block.hail.details = 일점사하면 립플보다 더 뛰어난 정확도와 연사력을 보여준다. +block.wave.details = +block.lancer.details = +block.arc.details = +block.swarmer.details = +block.salvo.details = +block.fuse.details = +block.ripple.details = +block.cyclone.details = +block.spectre.details = +block.meltdown.details = +block.foreshadow.details = +block.repair-point.details = +block.segment.details = +block.parallax.details = +block.tsunami.details = +block.silicon-crucible.details = +block.disassembler.details = +block.overdrive-dome.details = +block.payload-conveyor.details = +block.payload-router.details = +block.command-center.details = +block.ground-factory.details = +block.air-factory.details = 건설&연구 재료는 구리와 납뿐이지만, 정작 유닛을 생산할 땐 실리콘이 필요하다. +block.naval-factory.details = +block.additive-reconstructor.details = +block.multiplicative-reconstructor.details = +block.exponential-reconstructor.details = +block.tetrative-reconstructor.details = +block.switch.details = +block.micro-processor.details = +block.logic-processor.details = +block.hyper-processor.details = +block.memory-cell.details = +block.memory-bank.details = +block.logic-display.details = +block.large-logic-display.details = +block.interplanetary-accelerator.details = + +#유닛 +unit.dagger.details = 이전에 디거란 이명으로 종교가 생겼었다. +unit.mace.details = +unit.fortress.details = +unit.scepter.details = +unit.reign.details = +unit.nova.details = +unit.pulsar.details = +unit.quasar.details = +unit.vela.details = +unit.corvus.details = 정말 느리다. +unit.crawler.details = 최근에 자폭 AI가 향상되면서 컨베이어로 자폭을 유도할 수 없게 되었다. +unit.atrax.details = +unit.spiroct.details = +unit.arkyid.details = +unit.toxopid.details = +unit.flare.details = +unit.horizon.details = +unit.zenith.details = +unit.antumbra.details = +unit.eclipse.details = +unit.mono.details = +unit.poly.details = +unit.mega.details = +unit.quad.details = +unit.oct.details = +unit.risso.details = 뭉치면 연사력이 무시무시하다. +unit.minke.details = +unit.bryde.details = +unit.sei.details = +unit.omura.details = +unit.alpha.details = +unit.beta.details = +unit.gamma.details = diff --git a/fastlane/metadata/android/ko-KR/changelogs/29825.txt b/fastlane/metadata/android/ko-KR/changelogs/29825.txt new file mode 100644 index 0000000000..fb082693cd --- /dev/null +++ b/fastlane/metadata/android/ko-KR/changelogs/29825.txt @@ -0,0 +1,7 @@ +[대부분의 변경점이 생략되었습니다. 모든 변경점을 볼려면 Github를 보세요.] +이 업데이트는 특정 발사체에 대한 건물 광역 피해를 줄이고 다양한 모드 문제를 해결한 사소한 업데이트입니다. +빌드 125버전 서버는 125.1버전 클라이언트와 호환되어야 하지만 여전히 업데이트를 권장합니다. + +- 플레이어 체력바가 음수에서 깨지는 현상 고침 +- 대형 전력 노드가 가끔 설치된 블록에 연결하지 않는 현상 고침 +- 올바른 셀 색상으로 유닛 화물을 그리게 함 \ No newline at end of file From ab83b872a2d20c3c3aa03a2baf5c3bb9f299c9e5 Mon Sep 17 00:00:00 2001 From: PolgarSasa <59579595+PolgarSasa@users.noreply.github.com> Date: Fri, 5 Mar 2021 17:30:39 +0100 Subject: [PATCH 401/426] Update bundle_hu.properties (#4790) --- core/assets/bundles/bundle_hu.properties | 1538 +++++++++++----------- 1 file changed, 773 insertions(+), 765 deletions(-) diff --git a/core/assets/bundles/bundle_hu.properties b/core/assets/bundles/bundle_hu.properties index 1b32ac77da..47734eb072 100644 --- a/core/assets/bundles/bundle_hu.properties +++ b/core/assets/bundles/bundle_hu.properties @@ -1,5 +1,5 @@ -#Fordította: Vajda Simon -credits.text = Created by [royal]Anuken[] - [sky]anukendev@gmail.com[] +#A fordításban közreműködött: Vajda Simon, Polgár Sándor és Erdélyi Nimród +credits.text = Készítette: [royal]Anuken[] - [sky]anukendev@gmail.com[] credits = Credits contributors = Fordítok és készítők discord = Csatlakozz a Mindustry Discord szerverhez! @@ -7,14 +7,14 @@ link.discord.description = Az eredeti Mindustry Discord chatszoba link.reddit.description = A Mindustry subreddit link.github.description = A játék forráskódja link.changelog.description = Frissítési változások listája -link.dev-builds.description = Instabil fejlesztői build-ek +link.dev-builds.description = Instabil fejlesztői buildek link.trello.description = Hivatalos Trello tábla a tervezett funkcióknak link.itch.io.description = itch.io oldal PC letöltésekkel link.google-play.description = Google Play áruház listázás link.f-droid.description = F-Droid katalógus listázás link.wiki.description = Hivatalos Mindustry wiki link.suggestions.description = Új funkciók ajánlása -link.bug.description = Találtál egyett? Jelentsd itt +link.bug.description = Találtál egyet? Jelentsd itt linkfail = Nem sikerült megnyitni a linket!\nAz URL a vágólapra lett másolva. screenshot = Képernyőkép mentve ide: {0} screenshot.invalid = Túl nagy a térkép, nincsen elég memória a képernyőképhez. @@ -25,7 +25,7 @@ gameover.waiting = [accent]Várakozás a következő mapra... highscore = [accent]Új rekord! copied = Másolva. indev.notready = A játéknak ez a része még nincsen kész -indev.campaign = [accent]Gratulálunk! Elérte a kampány végét! []\n\nEz a tartalom mostanáig terjedt. A bolygóközi utazás a jövőbeli frissítésekben szerepel. +indev.campaign = [accent]Gratulálunk! Elérted a kampány végét! []\n\nA tartalom jelenleg csak eddig tart. A bolygóközi utazás a jövőbeli frissítésekben szerepel. load.sound = Hangok load.map = Mapok @@ -35,10 +35,10 @@ load.system = Rendszer load.mod = Modok load.scripts = Szkriptek -be.update = Új Bleeding Edge épület áll rendelkezésre: -be.update.confirm = Letölti és újra indítja? +be.update = Új Bleeding Edge build áll rendelkezésre: +be.update.confirm = Letölti és újraindítod? be.updating = Frissítés... -be.ignore = Mellőzés +be.ignore = Most nem be.noupdates = Nem találtunk frissítést. be.check = Frissítések keresése. @@ -46,11 +46,13 @@ mod.featured.dialog.title = Mod kereső (WIP) mods.browser.selected = Mod kiválasztása mods.browser.add = Letöltés mods.github.open = Megtekintés +mods.browser.sortdate = Rendezés dátum szerint +mods.browser.sortstars = Rendezés értékelés szerint schematic = Schematic schematic.add = Schematic mentése... schematics = Schematicok -schematic.replace = Már van ilyen nevű schematic. Csere? +schematic.replace = Már van ilyen nevű schematic. Lecseréled? schematic.exists = Már van ilyen nevű schematic. schematic.import = Schematic importálása... schematic.exportfile = Exportálás fájlba @@ -64,24 +66,24 @@ schematic.saved = Schematic mentve. schematic.delete.confirm = Ez a Schematic törölve lesz. schematic.rename = Schematic átnevezése schematic.info = {0}x{1}, {2} blokk -schematic.disabled = [scarlet]Sémák letiltva[]\nNem használhat sematikákat ezen a [accent]mapon[] vagy [accent] szerveren. +schematic.disabled = [scarlet]Schematicok letiltva[]\nNem használhat Schematicot ezen a [accent]mapon[] vagy [accent] szerveren. stats = Statisztika -stat.wave = Hullámok kivádve:[accent] {0} -stat.enemiesDestroyed = Kivédett ellenség:[accent] {0} +stat.wave = Hullámok kivédve:[accent] {0} +stat.enemiesDestroyed = Elpusztított ellenség:[accent] {0} stat.built = Épített épületek:[accent] {0} stat.destroyed = Szétrombolt épületek:[accent] {0} stat.deconstructed = Törölt épületek:[accent] {0} -stat.delivered = Elindított erőforrások: +stat.delivered = Felküldött nyersanyagok: stat.playtime = Játszott idő:[accent] {0} stat.rank = Végső értékelés: [accent]{0} -globalitems = [accent]Összes item -map.delete = Biztosan törli ezt a mapot"[accent]{0}[]"? -level.highscore = Magas pontszám: [accent]{0} +globalitems = [accent]Összes nyersanyag +map.delete = Biztosan törlöd a "[accent]{0}[]" mapot? +level.highscore = Legmagasabb pontszám: [accent]{0} level.select = Szint kiválasztása level.mode = Játékmód: -coreattack = < A mag támadás alatt! > +coreattack = < A mag támadás alatt van! > nearpoint = [[ [scarlet]AZONNAL HAGYD EL A LEDOBÁSI PONTOT[] ]\nveszélyes zóna database = Mag adatbázis savegame = Játék mentése @@ -90,6 +92,7 @@ joingame = Csatlakozás játékhoz customgame = Egyedi játék newgame = Új játék none = +none.found = [lightgray] minimap = Minimap position = Pozíció close = Bezárás @@ -101,7 +104,7 @@ maps.browse = Mapok keresése continue = Folytatás maps.none = [lightgray]Nem találtunk ilyen mapot! invalid = Érvénytelen -pickcolor = Válasszon színt +pickcolor = Válassz színt preparingconfig = Konfiguráció előkészítése preparingcontent = Tartalom előkészítése uploadingcontent = Tartalom feltöltése @@ -110,14 +113,14 @@ committingchanges = Változások mentése done = Kész feature.unsupported = Az eszköz nem támogatja ezt a funkciót. -mods.alphainfo = Figyelem! a modok alfa állapotban vannak, és[scarlet] nagyon sok lehet benne a hiba[].\nJelentsd be az esetleges hibákat a Mindustry GitHubon. +mods.alphainfo = Figyelem! a modok alfa állapotban vannak, és[scarlet] nagyon sok lehet bennük a hiba[].\nJelentsd be az esetleges hibákat a Mindustry GitHubon. mods = Modok mods.none = [lightgray]Nincsen mod! mods.guide = Mod készítési útmutató mods.report = Hiba jelentése mods.openfolder = Megnyitás mappából mods.reload = Újratöltés -mods.reloadexit = Indítsa újra a játékot, hogy betöltődjenek a modok. +mods.reloadexit = Indítsd újra a játékot, hogy betöltődjenek a modok. mod.display = [gray]Mod:[orange] {0} mod.enabled = [lightgray]Aktív mod.disabled = [scarlet]Inaktív @@ -125,11 +128,11 @@ mod.disable = Letiltás mod.content = Tartalom: mod.delete.error = Nem lehet törölni a Modot. Lehet, hogy egy másik folyamat használja. mod.requiresversion = [scarlet]Minimális játék verzió: [accent]{0} -mod.outdated = [scarlet]Nem kompatibilis V6-al (no minGameVersion: 105) +mod.outdated = [scarlet]Nem kompatibilis V6-tal (no minGameVersion: 105) mod.missingdependencies = [scarlet]Hiányzó függőség: {0} mod.erroredcontent = [scarlet]Tartalom hiba mod.errors = Hiba történt a tartalom betöltése közben. -mod.noerrorplay = [scarlet]Vannak hibás Modok.[] Töröld le vagy javítsd ki a játék előtt. +mod.noerrorplay = [scarlet]Vannak hibás Modok.[] Kapcsold ki vagy javítsd ki őket a játék előtt. mod.nowdisabled = [scarlet]A '{0}' Modnak nincsen megfelelő függősége:[accent] {1}\n[lightgray]Ezeket előbb le kell tölteni.\nEz a Mod automatikusan törölve lesz. mod.enable = Engedélyezés mod.requiresrestart = A játék kilép a módosítások alkalmazásához. @@ -137,18 +140,18 @@ mod.reloadrequired = [scarlet]Újratöltés szükséges mod.import = Mod importálása mod.import.file = Fájl importálása mod.import.github = GitHub Mod importálása -mod.jarwarn = [scarlet]A JAR modok eredendően nem biztonságosak.[]\nGyőződjön meg arról, hogy ezt a modot megbízható forrásból importálja! +mod.jarwarn = [scarlet]A JAR modok eredendően nem biztonságosak.[]\nGyőződj meg arról, hogy ezt a modot megbízható forrásból importálod! mod.item.remove = Ez az elem része a [accent] '{0}'[] Modnak. A törléshez távolítsd el a Modot. mod.remove.confirm = Ez a Mod törölve lesz. mod.author = [LIGHT_GRAY]Készítő:[] {0} mod.missing = Ez a mentés nemrég törölt vagy frissített Modokat tartalmaz. Elképzelhető, hogy nem fog működni. Biztosan betöltöd?\n[lightgray]Modok:\n{0} mod.preview.missing = Mielőtt publikálod ezt a modot a workshopra, adj hozzá egy borítóképet.\nKészíts egy[accent] preview.png[] nevű képet a mod mappájába, majd próbáld újra. -mod.folder.missing = Csak mappa formában lehet feltölteni a workshopra.\nHogy átalakítsd, csomagold ki a ZIP-et egy mappába és töröld le a régit, Majd indítsd újra a játékot vagy töltsd újra a modot. -mod.scripts.disable = Az eszköz nem támogatja a szkriptekkel rendelkező modokat. \nA játékhoz le kell tiltania ezeket a modokat. +mod.folder.missing = Csak mappa formában lehet feltölteni a workshopra.\nHogy átalakítsd, csomagold ki a ZIP-et egy mappába és töröld le a régit, majd indítsd újra a játékot vagy töltsd újra a modot. +mod.scripts.disable = Az eszköz nem támogatja a szkriptekkel rendelkező modokat. \nA játékhoz tiltsd le ezeket a modokat. about.button = Közreműködők name = Név: -noname = Válassz egy[accent] nevet[] előbb. +noname = Előbb válassz egy[accent] nevet[]. planetmap = Bolygó térkép launchcore = Mag kilövése filename = Fájl név: @@ -156,14 +159,14 @@ unlocked = Új tartalom kinyitva! available = Új kutatás áll rendelkezésre! completed = [accent]Kész techtree = Tech Tree -research.legacy = [accent]5.0[] kutatási adatok találhatók.\nSzeretné [accent] betölteni ezeket az adatokat [], vagy [accent] eldobni [], és újraindítani a kutatást az új kampányban (ajánlott)? +research.legacy = [accent]5.0[] kutatási adatok találhatók.\nSzeretnéd [accent] betölteni ezeket az adatokat [], vagy [accent] eldobni [], és újraindítani a kutatást az új kampányban (ajánlott)? research.load = Betöltés research.discard = Eldobás research.list = [lightgray]Fedezd fel: research = Felfedezés researched = [lightgray]{0} felfedezve. research.progress = {0}% kész -players = {0} játékosok +players = {0} játékos players.single = {0} játékos players.search = keresés players.notfound = [gray]nincsen játékos @@ -171,7 +174,7 @@ server.closing = [accent]Szerver bezárása... server.kicked.kick = Ki lettél rúgva a szerverről! server.kicked.whitelist = Nem vagy a fehérlistán. server.kicked.serverClose = A szerver be lett zárva. -server.kicked.vote = Le lettél szavazva. Viszlát. +server.kicked.vote = Ki lettél szavazva. Viszlát! server.kicked.clientOutdated = Elavult verziót használsz! Frissítsd a játékot! server.kicked.serverOutdated = Elavult a szerver! Kérd meg a tulajdonost, hogy frissítse! server.kicked.banned = Ki vagy tiltva a szerverről. @@ -185,25 +188,25 @@ server.kicked.customClient = Ez a szerver nem támogatja a saját készítésű server.kicked.gameover = Vége a játéknak! server.kicked.serverRestarting = Ez a szerver újraindul. server.versions = Te verziód:[accent] {0}[]\nSzerver verzió:[accent] {1}[] -host.info = Az [accent]host[] gomb kiszolgálót üzemeltet a [scarlet]6567[] porton.\nAzon a [lightgray] wifin vagy a helyi hálózaton [] bárki láthatja a szervert a szerverlistáján.\n\nHa azt szeretné, hogy az emberek bárhonnan IP-címmel csatlakozhassanak, [accent] port-továbbítás []\n\n[lightgray] Megjegyzés: Ha valakinek problémái vannak a LAN-játékhoz való csatlakozással, győződjön meg arról, hogy a tűzfal beállításaiban engedélyezte-e a Mindustry hozzáférését a helyi hálózathoz. Ne feledje, hogy a nyilvános hálózatok néha nem teszik lehetővé a kiszolgálók felderítését. -join.info = Itt megadhat egy [accent]szerver IP-t[] a csatlakozáshoz, vagy felfedezheti a [accent]helyi hálózat[] vagy [accent]globális[] szervereket, amelyekhez csatlakozni szeretne.\nMindkét LAN és WAN multiplayer támogatott.\n\n[lightgray]Ha IP-vel akarsz csatlakozni valakihez, akkor meg kell kérdezned a gazdagéptől az IP-jét, amely megtalálható a "my ip" Google kereséssel. -hostserver = Másik játékos meghívása +host.info = A [accent]Hosztolás[] gomb szervert nyit a [scarlet]6567[] porton.\nEzen a [lightgray] wifin vagy a helyi hálózaton [] bárki láthatja a szervert a szerverlistáján.\n\nHa azt szeretnéd, hogy az emberek bárhonnan IP-címmel csatlakozhassanak, [accent] port forwarding [] szükséges.\n\n[lightgray] Megjegyzés: Ha valakinek problémái vannak a LAN-játékhoz való csatlakozással, győződj meg arról, hogy a tűzfal beállításaiban engedélyezted-e a Mindustry hozzáférését a helyi hálózathoz. Ne feledd, hogy a nyilvános hálózatok néha nem teszik lehetővé a szerverek felderítését. +join.info = Itt megadhatsz egy [accent]szerver IP-t[] a csatlakozáshoz, vagy felfedezheted a [accent]helyi hálózatot[] vagy [accent]globális[] szervereket, amelyekhez csatlakozhatsz.\n LAN és WAN multiplayer is támogatott.\n\n[lightgray]Ha IP-vel akarsz csatlakozni valakihez, akkor meg kell tudnod a gazdagép IP-jét, amit megtalálhatsz a "my ip" Google kereséssel. +hostserver = Többjátékos játék hosztolása invitefriends = Barátok meghívása -hostserver.mobile = Játékos meghívása -host = meghívás +hostserver.mobile = Játék hosztolása +host = Hosztolás hosting = [accent]Szerver megnyitása... hosts.refresh = Frissítés hosts.discovering = LAN játék keresése hosts.discovering.any = Játék keresése server.refreshing = Szerver frissítése -hosts.none = [lightgray]Nincsen helyi játék! +hosts.none = [lightgray]Nincs helyi játék! host.invalid = [scarlet]Nem sikerült csatlakozni. -servers.local = Lokális Szerverek +servers.local = Helyi Szerverek servers.remote = Távoli Szerverek servers.global = Közösségi szerverek -servers.disclaimer = A közösségi szervereket [accent]nem[] a fejlesztő birtokolja és nem ellenőrzi.\n\nA szerverek tartalmazhatnak olyan felhasználók által létrehozott tartalmat, amely nem minden korosztály számára megfelelő. +servers.disclaimer = A közösségi szervereket [accent]nem[] a fejlesztő birtokolja és ellenőrzi.\n\nA szerverek tartalmazhatnak olyan felhasználók által létrehozott tartalmat, amely nem minden korosztály számára megfelelő. servers.showhidden = Rejtett szerverek megjelenítése server.shown = Látható server.hidden = Rejtett @@ -213,8 +216,8 @@ trace.playername = Játékos neve: [accent]{0} trace.ip = IP: [accent]{0} trace.id = Azonosító: [accent]{0} trace.mobile = Mobil kliens: [accent]{0} -trace.modclient = Nemhivatalos kliens: [accent]{0} -invalidid = Érvénytelen kliens ID! Submit a bug report. +trace.modclient = Nem hivatalos kliens: [accent]{0} +invalidid = Érvénytelen kliens ID! Küldj hibajelentést. server.bans = Tiltások server.bans.none = Nincsenek tiltott játékosok! server.admins = Adminok @@ -231,20 +234,20 @@ confirmkick = Biztosan kirúgod ezt a játékost? confirmvotekick = Biztosan ki akarod rúgatni ezt a játékost? confirmunban = Biztosan újra engedélyezed ezt a játékost? confirmadmin = Biztosan hozzá akarod adni ezt a játékost az adminokhoz? -confirmunadmin = Biztosan meg akarod szűntetni ennek a játékosnak az admin szátuszát? +confirmunadmin = Biztosan meg akarod szűntetni ennek a játékosnak az adminstátuszát? joingame.title = Csatlakozás joingame.ip = Cím: disconnect = Leválasztva. disconnect.error = Csatlakozási hiba. -disconnect.closed = Csatlakozás bezárva. +disconnect.closed = Kapcsolat bontva. disconnect.timeout = Időtúllépés. disconnect.data = Nem sikerült betölteni az adatokat! -cantconnect = Nem sikerült csatlakozni ehhez: ([accent]{0}[]). +cantconnect = Nem sikerült csatlakozni a ([accent]{0}[]) játékhoz. connecting = [accent]Csatlakozás... -reconnecting = [accent]Újra csatlakozás... +reconnecting = [accent]Újracsatlakozás... connecting.data = [accent]Betöltés... server.port = Port: -server.addressinuse = Már van ilyen cím! +server.addressinuse = A cím már használatban van! server.invalidport = Érvénytelen port! server.error = [crimson]Nem sikerült megnyitni a szervert. save.new = Új mentés @@ -256,8 +259,8 @@ save.delete.confirm = Biztosan törlöd ezt a mentést? save.delete = Törlés save.export = Exportálás save.import.invalid = [accent]Ez a mentés érvénytelen! -save.import.fail = [crimson]Nem sikerült importálni a[accent]{0}[] mentést -save.export.fail = [crimson]Nem sikerült exportálni a[accent]{0}[] mentést +save.import.fail = [crimson]Nem sikerült importálni a [accent]{0}[] mentést +save.export.fail = [crimson]Nem sikerült exportálni a [accent]{0}[] mentést save.import = Importálás save.newslot = Név: save.rename = Átnevezés @@ -272,7 +275,7 @@ off = Ki save.autosave = Automatikus mentés: {0} save.map = Térkép: {0} save.wave = Hullám: {0} -save.mode = Mód: {0} +save.mode = Játékmód: {0} save.date = Utolsó Mentés: {0} save.playtime = Játékidő: {0} warning = Figyelmeztetés. @@ -287,6 +290,7 @@ cancel = Mégse openlink = Link megnyitása copylink = Link másolása back = Vissza +max = Max crash.export = Összeomlási napló exportálása crash.none = Nem található összeomlási napló. crash.exported = Összeomlási napló exportálva. @@ -295,190 +299,189 @@ data.import = Adatok Importálása data.openfolder = Adat mappa megnyitása data.exported = Adat exportálva. data.invalid = Érvénytelen adatok. -data.import.confirm = Külső adat importálása felülírja[scarlet] minden[] jelenlegi állapotodat.\n[accent]Nem lehet visszavonni![]\n\nAmint kész az importálás, kilép a játék. +data.import.confirm = Külső adat importálása felülírja[scarlet] minden[] jelenlegi adatodat.\n[accent]Nem lehet visszavonni![]\n\nAmint kész az importálás, kilép a játék. quit.confirm = Biztos kilépsz? quit.confirm.tutorial = Biztosan tudod, mit csinálsz?\nA bevezetőt megtalálod itt:[accent] Beállítások->Játék->Bevezető újrajátszása[] loading = [accent]Betöltés... reloading = [accent]Modok Újratöltése... saving = [accent]Mentés... -respawn = Nyomd meg a [accent][[{0}][] gombot, hogy újra élegy a magban. +respawn = Nyomd meg a(z) [accent][[{0}][] gombot, hogy újraéledj a magban. cancelbuilding = Használd a(z) [accent][[{0}][] gombot, hogy töröld a tervrajzot. selectschematic = Használd a(z) [accent][[{0}][] gombot, hogy kijelölj és másolj. pausebuilding = Használd a(z) [accent][[{0}][] gombot, hogy megállítsd az építkezést. resumebuilding = Használd a(z) [scarlet][[{0}][] gombot, hogy folytasd az építkezést. -showui = A kezelőfelület elrejtve.\nNyomja meg a(z) [accent][[{0}][] gombot a megjelenítéséhez. -wave = [accent]{0}. Hullám -wave.cap = [accent]{0}/{1} Hullám +showui = A kezelőfelület elrejtve.\nNyomd meg a(z) [accent][[{0}][] gombot a megjelenítéséhez. +wave = [accent]{0}. hullám +wave.cap = [accent]{0}./{1} hullám wave.waiting = [lightgray]Következő hullám {0} wave.waveInProgress = [lightgray]Hullám folyamatban waiting = [lightgray]Várakozás... waiting.players = Várakozás a játékosokra... -wave.enemies = [lightgray]Fennmaradó ellenségek: {0} -wave.enemycores = [accent]{0}[lightgray] Ellenséges magok +wave.enemies = [lightgray]{0} Megmaradt ellenség +wave.enemycores = [accent]{0}[lightgray] Ellenséges mag wave.enemycore = [accent]{0}[lightgray] Ellenséges mag wave.enemy = [lightgray]{0} Megmaradt ellenség -wave.guardianwarn = Az őrző [accent]{0}[] hullám múlva érkezik. -wave.guardianwarn.one = Az őrző [accent]{0}[] hullám múlva érkezik. +wave.guardianwarn = Egy őrző érkezik [accent]{0}[] hullám múlva. +wave.guardianwarn.one = Egy őrző érkezik [accent]{0}[] hullám múlva. loadimage = Fénykép betöltése saveimage = Fénykép mentése unknown = Ismeretlen custom = Egyedi builtin = Beépített -map.delete.confirm = Biztosan törli ezt a mapot? Ez a művelet nem visszavonható! -map.random = [accent]Random Map -map.nospawn = Ez a map nem rendelkezik maggal, amelybe a játékos beleszülethet! Adjon hozzá egy [accent]narancssárga[] magot ehhez a maphoz a szerkesztőben. -map.nospawn.pvp = Ezen a térképen nincsen ellenséges mag, amiba az másik csapat éledhet! Adjon hozzá [scarlet]nem narancssárga[] magok ehhez a maphoz a szerkesztőben. -map.nospawn.attack = Ezen a térképen nincsen ellenséges mag! Adjon hozzá [scarlet]piros[] magot ehhez a maphoz a szerkesztőben. -map.invalid = Hiba a map betöltésekor: sérült vagy érvénytelen mapfájl. -workshop.update = Item frisítése -workshop.error = Hiba történt a műhely részleteinek lekérésekor: {0} -map.publish.confirm = Biztos, hogy közzéteszi ezt a mapot?\n\n[lightgray] Győződjön meg róla, hogy először elfogadta a Workshop EULA-t, különben a mapok nem jelennek meg! -workshop.menu = Válassza ki, mit szeretne csinálni ezzel az itemmel. +map.delete.confirm = Biztosan törlöd ezt a mapot? Ez a művelet nem visszavonható! +map.random = [accent]Véletlenszerű Map +map.nospawn = Ez a map nem rendelkezik maggal, amelyen a játékos kezdhet! Adj hozzá egy [accent]narancssárga[] magot ehhez a maphoz a szerkesztőben! +map.nospawn.pvp = Ezen a térképen nincsen ellenséges mag, amelyen a másik csapat kezdhet! Adjon hozzá [scarlet]nem narancssárga[] magot ehhez a maphoz a szerkesztőben! +map.nospawn.attack = Ezen a térképen nincsen ellenséges mag! Adjon hozzá [scarlet]piros[] magot ehhez a maphoz a szerkesztőben! +map.invalid = Hiba történt a map betöltésekor: sérült vagy érvénytelen mapfájl. +workshop.update = Item frissítése +workshop.error = Hiba történt a workshop részleteinek lekérdezésekor: {0} +map.publish.confirm = Biztos, hogy közzéteszed ezt a mapot?\n\n[lightgray] Győződj meg róla, hogy elfogadtad a Workshop EULA-t, különben a mapjaid nem jelennek meg! +workshop.menu = Válaszd ki, mit szeretnél csinálni ezzel az itemmel. workshop.info = Item Infó -changelog = Changelog (opcionális): +changelog = Változtatási napló (opcionális): eula = Steam EULA -missing = Ezt az elemet törölték vagy áthelyezték.\n[lightgray] A műhely adatait automatikusan leválasztották. +missing = Ezt az elemet törölték vagy áthelyezték.\n[lightgray] A workshop adatait automatikusan leválasztották. publishing = [accent]Publikálás... -publish.confirm = Biztosan közzéteszi ezt?\n\n[lightgray] Győződjön meg róla, hogy először elfogadta a Workshop EULA-t, különben az itemei nem jelennek meg! +publish.confirm = Biztosan közzéteszed?\n\n[lightgray] Győződj meg róla, hogy elfogadtad a Workshop EULA-t, különben az itemjeid nem jelennek meg! publish.error = Hiba az item publikálásakor: {0} steam.error = Nem sikerült inicializálni a Steam szolgáltatásokat.\nHiba: {0} -editor.brush = Brush -editor.openin = Open In Editor -editor.oregen = Ore Generation -editor.oregen.info = Ore Generation: -editor.mapinfo = Map Info -editor.author = Author: -editor.description = Description: -editor.nodescription = A map must have a description of at least 4 characters before being published. -editor.waves = Waves: -editor.rules = Rules: -editor.generation = Generation: -editor.ingame = Edit In-Game -editor.publish.workshop = Publish On Workshop -editor.newmap = New Map -editor.center = Center +editor.brush = Méret +editor.openin = Megnyitás a szerkesztőben +editor.oregen = Érc generálás +editor.oregen.info = Érc generálás: +editor.mapinfo = Általános +editor.author = Készítő: +editor.description = Leírás: +editor.nodescription = A mapnak rendelkeznie kell egy legalább 4 karakter hosszú leírással, mielőtt megosztod. +editor.waves = Hullámok: +editor.rules = Szabályok: +editor.generation = generálás: +editor.ingame = Szerkesztés játékban +editor.publish.workshop = Közzététel workshopon +editor.newmap = Új Map +editor.center = Ugrás középre workshop = Workshop -waves.title = Waves -waves.remove = Remove -waves.never = -waves.every = every -waves.waves = wave(s) +waves.title = Hullámok +waves.remove = Eltávolítás +waves.every = +waves.waves = hullámonként waves.perspawn = per spawn -waves.shields = shields/wave -waves.to = to -waves.guardian = Guardian -waves.preview = Preview -waves.edit = Edit... -waves.copy = Copy to Clipboard -waves.load = Load from Clipboard -waves.invalid = Invalid waves in clipboard. -waves.copied = Waves copied. -waves.none = No enemies defined.\nNote that empty wave layouts will automatically be replaced with the default layout. +waves.shields = pajzs/hullám +waves.to = - +waves.guardian = őrző +waves.preview = Előnézet +waves.edit = Szerksztés... +waves.copy = Másolás a vágólapra +waves.load = Másolás a vágólapról +waves.invalid = Nem lehet beilleszteni a vágólapról. +waves.copied = Hullámok másolva. +waves.none = Nincs ellenség megadva.\nAz üresen hagyott tervek automatikusan lecserélődnek az alapbeállításra. #these are intentionally in lower case -wavemode.counts = counts -wavemode.totals = totals -wavemode.health = health +wavemode.counts = típusokra bontva +wavemode.totals = öszzesítés +wavemode.health = életpontok -editor.default = [lightgray] -details = Details... -edit = Edit... -editor.name = Name: +editor.default = [lightgray] +details = Részletek... +edit = Szerkesztés... +editor.name = Név: editor.spawn = Spawn Unit editor.removeunit = Remove Unit -editor.teams = Teams -editor.errorload = Error loading file. -editor.errorsave = Error saving file. -editor.errorimage = That's an image, not a map.\n\nIf you want to import a 3.5/build 40 map, use the 'Import Legacy Map' button in the editor. -editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. -editor.errornot = This is not a map file. -editor.errorheader = This map file is either not valid or corrupt. -editor.errorname = Map has no name defined. Are you trying to load a save file? -editor.update = Update -editor.randomize = Randomize -editor.apply = Apply -editor.generate = Generate -editor.resize = Resize -editor.loadmap = Load Map -editor.savemap = Save Map -editor.saved = Saved! -editor.save.noname = Your map does not have a name! Set one in the 'map info' menu. -editor.save.overwrite = Your map overwrites a built-in map! Pick a different name in the 'map info' menu. -editor.import.exists = [scarlet]Unable to import:[] a built-in map named '{0}' already exists! -editor.import = Import... -editor.importmap = Import Map -editor.importmap.description = Import an already existing map -editor.importfile = Import File -editor.importfile.description = Import an external map file -editor.importimage = Import Image File -editor.importimage.description = Import an external map image file -editor.export = Export... -editor.exportfile = Export File -editor.exportfile.description = Export a map file -editor.exportimage = Export Terrain Image -editor.exportimage.description = Export an image file containing only basic terrain -editor.loadimage = Import Terrain -editor.saveimage = Export Terrain -editor.unsaved = Are you sure you want to exit?\n[scarlet]Any unsaved changes will be lost. -editor.resizemap = Resize Map -editor.mapname = Map Name: -editor.overwrite = [accent]Warning!\nThis overwrites an existing map. -editor.overwrite.confirm = [scarlet]Warning![] A map with this name already exists. Are you sure you want to overwrite it?\n"[accent]{0}[]" -editor.exists = A map with this name already exists. -editor.selectmap = Select a map to load: +editor.teams = Csapatok +editor.errorload = Hiba a fájl betöltése közben. +editor.errorsave = Hiba a fájl mentése közben. +editor.errorimage = Ez egy kép, nem egy Map.\n\nHa egy 3.5/build 40 Mapot szeretnél betölteni, használd a "Régi map betöltése" gombot a szerkesztőben. +editor.errorlegacy = Ez a Map túl régi, és már nem támogatott formátumot használ. +editor.errornot = Ez nem egy Map fájl. +editor.errorheader = Ez a map fájl vagy érvénytelen vagy sérült. +editor.errorname = A Mapnak nincs neve. Mentést próbálsz betölteni? +editor.update = Frissítés +editor.randomize = Véletlenszerű +editor.apply = Alkalmazás +editor.generate = Haladó funkciók +editor.resize = Átméretezés +editor.loadmap = Map betöltése +editor.savemap = Mentés +editor.saved = Mentve! +editor.save.noname = Nem adtál meg nevet! Állíts be egyet az "Általános" menüpont alatt! +editor.save.overwrite = A Mapod felülír egy már létező Mapot! Válassz egy másik nevet az "Általános" menüpont alatt! +editor.import.exists = [scarlet]Nem lehet importálni:[] Már létezik "{0}" nevű Map! +editor.import = Importálás +editor.importmap = Map importálása +editor.importmap.description = Létező Map importálása +editor.importfile = Fájl importálása +editor.importfile.description = Külső Map fájl importálása +editor.importimage = Képfájl importálása +editor.importimage.description = Külső Map képfájl importálása +editor.export = Exportálás +editor.exportfile = Fájl exportálása +editor.exportfile.description = Exportálás Map fájlba +editor.exportimage = Domborzat exportálása +editor.exportimage.description = Domborzat exportálása képfájlba +editor.loadimage = Domborzat importálása +editor.saveimage = Domborzat exportálása +editor.unsaved = Biztos ki akarsz lépni?\n[scarlet]A nem mentett módosításaid elvesznek! +editor.resizemap = Átméretezés +editor.mapname = Map neve: +editor.overwrite = [accent]Vigyázz!\nEzzel felülírsz egy már létező Mapot. +editor.overwrite.confirm = [scarlet]Vigyázz![] Ilyen nevű Map már létezik:\n"[accent]{0}[]"\nBiztosan felülírod? +editor.exists = Ilyen nevű Map már létezik. +editor.selectmap = Válassz ki egy Mapot: -toolmode.replace = Replace +toolmode.replace = Csere toolmode.replace.description = Draws only on solid blocks. -toolmode.replaceall = Replace All -toolmode.replaceall.description = Replace all blocks in map. -toolmode.orthogonal = Orthogonal -toolmode.orthogonal.description = Draws only orthogonal lines. -toolmode.square = Square -toolmode.square.description = Square brush. -toolmode.eraseores = Erase Ores -toolmode.eraseores.description = Erase only ores. +toolmode.replaceall = Összes cseréje +toolmode.replaceall.description = Összes cseréje +toolmode.orthogonal = Merőleges +toolmode.orthogonal.description = Csak merőleges vonalakat rajzol. +toolmode.square = Négyzet +toolmode.square.description = Négyzet ecset +toolmode.eraseores = Ércradír +toolmode.eraseores.description = Csak az érceket törli. toolmode.fillteams = Fill Teams toolmode.fillteams.description = Fill teams instead of blocks. toolmode.drawteams = Draw Teams toolmode.drawteams.description = Draw teams instead of blocks. -filters.empty = [lightgray]No filters! Add one with the button below. +filters.empty = [lightgray]Még nincs filter! Adj hozzá egyet a lenti gombra kattintva! filter.distort = Distort -filter.noise = Noise +filter.noise = Zaj filter.enemyspawn = Enemy Spawn Select filter.spawnpath = Path To Spawn filter.corespawn = Core Select -filter.median = Median -filter.oremedian = Ore Median +filter.median = Medián +filter.oremedian = Érc medián filter.blend = Blend -filter.defaultores = Default Ores -filter.ore = Ore -filter.rivernoise = River Noise -filter.mirror = Mirror -filter.clear = Clear +filter.defaultores = Alapértelmezett ércek +filter.ore = Érc +filter.rivernoise = Vízfolyás zaj +filter.mirror = Tükrözés +filter.clear = Blokkok törlése filter.option.ignore = Ignore filter.scatter = Scatter -filter.terrain = Terrain -filter.option.scale = Scale -filter.option.chance = Chance +filter.terrain = Domborzat +filter.option.scale = Méret +filter.option.chance = Gyakoriság filter.option.mag = Magnitude filter.option.threshold = Threshold filter.option.circle-scale = Circle Scale filter.option.octaves = Octaves filter.option.falloff = Falloff filter.option.angle = Angle -filter.option.amount = Amount +filter.option.amount = Mennyiség filter.option.block = Block -filter.option.floor = Floor -filter.option.flooronto = Target Floor -filter.option.target = Target -filter.option.wall = Wall -filter.option.ore = Ore +filter.option.floor = Talaj +filter.option.flooronto = Jelenlegi mező +filter.option.target = Jelenlegi mező +filter.option.wall = Fal +filter.option.ore = Érc filter.option.floor2 = Secondary Floor filter.option.threshold2 = Secondary Threshold -filter.option.radius = Radius -filter.option.percentile = Percentile +filter.option.radius = Sugár +filter.option.percentile = Arány width = Szélesség: height = Magasság: @@ -491,91 +494,91 @@ fps = FPS: {0} ping = Ping: {0}ms memory = Mem: {0}mb memory2 = Mem:\n {0}mb +\n {1}mb -language.restart = Indítsa újra a játékot, hogy betöltődjenek a nyelvi beállítások. +language.restart = Indítsd újra a játékot, hogy betöltődjenek a nyelvi beállítások! settings = Beállítások -tutorial = Tutorial -tutorial.retake = Re-Take Tutorial +tutorial = Bevezető +tutorial.retake = Bevezető újrajátszása editor = Szerkesztő mapeditor = Map szerkesztő -abandon = Abandon -abandon.text = This zone and all its resources will be lost to the enemy. +abandon = Feladás +abandon.text = Ez a szektor benne minden nyersanyaggal az ellenség kezére kerül. locked = Lezárva -complete = [lightgray]Complete: -requirement.wave = Reach Wave {0} in {1} -requirement.core = Destroy Enemy Core in {0} -requirement.research = Research {0} -requirement.produce = Produce {0} -requirement.capture = Capture {0} +complete = [lightgray]Feltételek: +requirement.wave = Juss el a {0}. hullámig {1} szektorban +requirement.core = Pusztítsd el az ellenséges magot {0} szektorban +requirement.research = Fedezd fel: {0} +requirement.produce = Gyártsd le: {0} +requirement.capture = Foglald el a(z) {0} szektort launch.text = Indítás -research.multiplayer = Only the host can research items. -map.multiplayer = Only the host can view sectors. -uncover = Uncover -configure = Configure Loadout +research.multiplayer = Csak a host fedezhet fel itemeket. +map.multiplayer = Csak a host tekintheti meg a szektorokat. +uncover = Felfedés +configure = Rakomány szerkesztése -loadout = Loadout -resources = Resources -bannedblocks = Banned Blocks +loadout = Rakomány +resources = Nyersanyagok +bannedblocks = Tiltott blokkok addall = Összes hozzáadása -launch.from = Launching From: [accent]{0} -launch.destination = Destination: {0} -configure.invalid = Amount must be a number between 0 and {0}. -add = Add... -boss.health = Guardian Health +launch.from = Indítás: [accent]{0} +launch.destination = Irány: {0} +configure.invalid = A mennyiségnek 0 és {0} között kell lennie. +add = Hozzáadás... +boss.health = Őrző élete connectfail = [scarlet]Csatlakozási hiba:\n\n[accent]{0} -error.unreachable = Server unreachable.\nIs the address spelled correctly? -error.invalidaddress = Invalid address. -error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct! -error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! -error.alreadyconnected = Already connected. +error.unreachable = A szervert nem lehet elérni.\nBiztosan jól írtad be a címet? +error.invalidaddress = Érvénytelen cím. +error.timedout = Időtúllépés!\nGyőződj meg róla, hogy a port forwarding be van kapcsolva a host gépen és a cím helyes! +error.mismatch = Packet error:\nLehetséges kliens/szerver verzió eltérés.\nGyőződj meg róla, hogy te és a host is a Mindustry legfrissebb verzióját használjátok! +error.alreadyconnected = Már csatlakozva vagy. error.mapnotfound = A map fájl nem található! error.io = Internet I/O hiba. error.any = Ismeretlen internet hiba. error.bloom = Failed to initialize bloom.\nYour device may not support it. -weather.rain.name = Rain -weather.snow.name = Snow -weather.sandstorm.name = Sandstorm -weather.sporestorm.name = Sporestorm -weather.fog.name = Fog +weather.rain.name = Eső +weather.snow.name = Hóesés +weather.sandstorm.name = Homokvihar +weather.sporestorm.name = Spóravihar +weather.fog.name = Köd -sectors.unexplored = [lightgray]Unexplored -sectors.resources = Resources: -sectors.production = Production: +sectors.unexplored = [lightgray]Felderítetlen +sectors.resources = Nyersanyagok: +sectors.production = Gyártás: sectors.export = Export: sectors.time = Idő: -sectors.threat = Threat: +sectors.threat = Fenyegetés: sectors.wave = Hullámok: -sectors.stored = Stored: +sectors.stored = Tárolt: sectors.resume = Folytatás -sectors.launch = Launch +sectors.launch = Indítás sectors.select = Kiválasztás sectors.nonelaunch = [lightgray]none (sun) sectors.rename = Szektor átnevezése sectors.enemybase = [scarlet]Ellenséges bázis -sectors.vulnerable = [scarlet]Vulnerable -sectors.underattack = [scarlet]Under attack! [accent]{0}% damaged -sectors.survives = [accent]Survives {0} waves -sectors.go = Go -sector.curcapture = Sector Captured -sector.curlost = Elvesztett szektor -sector.missingresources = [scarlet]Insufficient Core Resources -sector.attacked = Sector [accent]{0}[white] under attack! -sector.lost = Sector [accent]{0}[white] lost! +sectors.vulnerable = [scarlet]Sebezhető +sectors.underattack = [scarlet]Támadás alatt! [accent]{0}% sérült +sectors.survives = [accent]Túlél {0} hullámot +sectors.go = Utazás +sector.curcapture = Szektor megszerezve +sector.curlost = A szektor elveszett +sector.missingresources = [scarlet]Nincs elég nyersanyag +sector.attacked = A(z) [accent]{0}[white] szektor támadás alatt áll! +sector.lost = A(z) [accent]{0}[white] szektor elveszett! #note: the missing space in the line below is intentional -sector.captured = Sector [accent]{0}[white]captured! +sector.captured = A(z) [accent]{0}[white] szektor megvédve! -threat.low = Gyenge +threat.low = Alacsony threat.medium = Közepes -threat.high = Nehéz +threat.high = Magas threat.extreme = Extrém threat.eradication = Felszámolás -planets = Planets +planets = Bolygók planet.serpulo.name = Serpulo -planet.sun.name = Sun +planet.sun.name = Nap sector.impact0078.name = Impact 0078 sector.groundZero.name = Ground Zero @@ -594,41 +597,42 @@ sector.windsweptIslands.name = Windswept Islands sector.extractionOutpost.name = Extraction Outpost sector.planetaryTerminal.name = Planetary Launch Terminal -sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. -sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. -sector.saltFlats.description = On the outskirts of the desert lie the Salt Flats. Few resources can be found in this location.\n\nThe enemy has erected a resource storage complex here. Eradicate their core. Leave nothing standing. -sector.craters.description = Water has accumulated in this crater, relic of the old wars. Reclaim the area. Collect sand. Smelt metaglass. Pump water to cool turrets and drills. -sector.ruinousShores.description = Past the wastes, is the shoreline. Once, this location housed a coastal defense array. Not much of it remains. Only the most basic defense structures have remained unscathed, everything else reduced to scrap.\nContinue the expansion outwards. Rediscover the technology. -sector.stainedMountains.description = Further inland lie the mountains, yet untainted by spores.\nExtract the abundant titanium in this area. Learn how to use it.\n\nThe enemy presence is greater here. Do not give them time to send their strongest units. -sector.overgrowth.description = This area is overgrown, closer to the source of the spores.\nThe enemy has established an outpost here. Build Mace units. Destroy it. -sector.tarFields.description = The outskirts of an oil production zone, between the mountains and desert. One of the few areas with usable tar reserves.\nAlthough abandoned, this area has some dangerous enemy forces nearby. Do not underestimate them.\n\n[lightgray]Research oil processing technology if possible. -sector.desolateRift.description = An extremely dangerous zone. Plentiful resources, but little space. High risk of destruction. Leave as soon as possible. Do not be fooled by the long spacing between enemy attacks. -sector.nuclearComplex.description = A former facility for the production and processing of thorium, reduced to ruins.\n[lightgray]Research the thorium and its many uses.\n\nThe enemy is present here in great numbers, constantly scouting for attackers. -sector.fungalPass.description = A transition area between high mountains and lower, spore-ridden lands. A small enemy reconnaissance base is located here.\nDestroy it.\nUse Dagger and Crawler units. Take out the two cores. -sector.biomassFacility.description = The origin of spores. This is the facility in which they were researched and initially produced.\nResearch the technology contained within. Cultivate spores for the production of fuel and plastics.\n\n[lightgray]Upon this facility's demise, the spores were released. Nothing in the local ecosystem could compete with such an invasive organism. -sector.windsweptIslands.description = Further past the shoreline is this remote chain of islands. Records show they once had [accent]Plastanium[]-producing structures.\n\nFend off the enemy's naval units. Establish a base on the islands. Research these factories. -sector.extractionOutpost.description = A remote outpost, constructed by the enemy for the purpose of launching resources to other sectors.\n\nCross-sector transport technology is essential for further conquest. Destroy the base. Research their Launch Pads. -sector.impact0078.description = Here lie remnants of the interstellar transport vessel that first entered this system.\n\nSalvage as much as possible from the wreckage. Research any intact technology. -sector.planetaryTerminal.description = The final target.\n\nThis coastal base contains a structure capable of launching Cores to local planets. It is extremely well guarded.\n\nProduce naval units. Eliminate the enemy as quickly as possible. Research the launch structure. + +sector.groundZero.description = Az ideális helyszín, hogy ismét belekezdjünk. Alacsony ellenséges fenyegetés. Némi nyersanyag.\nGyűjts annyi rezet és ólmot, amennyit csak tudsz.\nHaladj tovább. +sector.frozenForest.description = Még itt, a hegyekhez közel is elterjedtek a spórák. A fagypont alatti hőmérséklet nem tudja örökké fogva tartani őket.\n\nFedezd fel az lelktromosság erejét! Építs combustion generatort! Használj mendert! +sector.saltFlats.description = A sivatag peremén terül el a Salt Flats néven ismert síkság. Kevés nyersanyag található errefelé.\n\nAz ellenség egy raktárkomplexumot létesített itt. Pusztítsd el a magot! Kő kövön ne maradjon! +sector.craters.description = Régen háborúk folytak ezen a helyen és csak egy kráter maradt utánuk. De szerencsédre az évezredek alatt feltöltődött vízzel így letudod hűteni vele a drilljeidet. Persze előtte használd a homokot, hogy legyen üveged! +sector.ruinousShores.description = A romokon túl fekszik a vízpart. Egykor itt állt egy parti védelmi vonal. Mára nem sok maradt belőle. Csak a legegyszerűbb védelmi épületek maradtak sértetlenek, bármi más csak törmelékként van jelen.\nFolytasd a terjeszkedést! Fedezd fel a régi technológiákat! +sector.stainedMountains.description = Mélyebben benn a szárazföldön fekszenek a hegyek, a spóráktól még érintetlenül.\nTermeld ki a bőséges titanium készleteket a körzetben. Tanuld meg felhasználni!.\n\nAz ellenség itt nagyobb létszámban van jelen. Ne hagyj nekik időt, hogy a legerősebb egységeiket hadba állíthassák! +sector.overgrowth.description = Ez a terület közelebb esik a spórák forrásához, a spórák már kinőtték.\nAz ellenség egy helyőrséget létesített itt. Építs Mace egységeket! Pusztítsd el! +sector.tarFields.description = Egy olajtermelő övezet peremvidéke a hegyek és a sivatag között. Egy a kevés térség közül, ahol még hasznosítható kátránykészletek találhatók.\nBár a terület elhagyatott, veszélyes ellenséges erők fészkelnek a közelben. Ne becsüld alá őket!\n\n[lightgray]Fedezd fel az olajfeldolgozási lehetőségeket, ha tudod! +sector.desolateRift.description = Egy extrém veszélyes zóna. Nyersanyagokban gazdag, de szűkös a hely. Magas kockázat. Hagyd el, amint lehet! Ne tévesszen meg a hosszú szünet az ellenség támadásai között! +sector.nuclearComplex.description = Egy néhai létesítmény thorium kitermelésére és feldolgozására, romokban.\n[lightgray] Fedezd fel a thoriumot és sokrétű felhasználását!\n\nAz ellenség nagy létszámban van jelen, és folyamatosan megfigyelés alatt tartják a környéket. +sector.fungalPass.description = Átmenet a magas hegyek és a mélyebben fekvő, spórák uralta lapály között. Egy kisebb ellenséges megfigyelő állomás található itt.\nSemmisítsd meg!.\nHasználj Dagger és Crawler egységeket! Pusztítsd el a két magot! +sector.biomassFacility.description = A spórák származási helye. Ebben a létesítményben fejlesztették ki őket és eredetileg itt került sor a gyártásukra.\nFedezd fel az itt található technológiákat! Használd a spórákat üzemanyag és műanyagok gyártására!\n\n[lightgray]A létesítmény pusztulása nyomán a spórák elszabadultak. A helyi ökoszisztémában semmi sem tudta felvenni a versenyt egy ennyire invazív életformával. +sector.windsweptIslands.description = Távolabb a partvonalon túl fekszik ez az elszigetelt szigetcsoport. Feljegyzések szerint egykor [accent]Plastanium[] gyártása zajlott itt.\n\nVerd vissza az ellenség vízi egységeit! Állíts fel egy bázist a szigeteken! Fedezd fel az itt talált gyárakat! +sector.extractionOutpost.description = Távoli ellenséges támaszpont, fő célja nyersanyagok továbbítása másik szektorokba.\n\n A szektorok közötti szállítás elengedhetetlen a további előrehaladáshoz. Pusztítsd el a bázist! Tanulmányozd a Launch Padot! +sector.impact0078.description = Itt fekszenek a roncsai az első csillagközi űrhajónak, amely a csillagrendszerbe érkezett.\n\nMents ki a romokból amit csak tudsz! Fedezd fel az épen maradt technológiákat. +sector.planetaryTerminal.description = A végső célpont.\n\nEzen a vízparti bázison található egy olyan építmény, amely képes magokat kilőni közeli bolygókra. Folyamatosan őrzik.\n\nKészíts vízi egységeket! Ártalmatlanítsd az ellenséget amilyen gyorsan tudod! Fedezd fel a kilövőszerkezetet! settings.language = Nyelvek settings.data = Játék adatok -settings.reset = Visszaállítás az alapértelmezett értékekre -settings.rebind = Rebind +settings.reset = Alapértelmezett +settings.rebind = Módosítás settings.resetKey = Visszaállítás settings.controls = Irányítás settings.game = Játék settings.sound = Hangok settings.graphics = Grafika settings.cleardata = Játék adatok törlése... -settings.clear.confirm = Biztosan törli ezeket az adatokat?\n A végrehajtottakat nem lehet visszavonni! -settings.clearall.confirm = [scarlet] FIGYELEM! []\n Ez törli az összes adatot, beleértve a mentéseket, a térképeket, a feloldásokat és a billentyűzárakat.\n Amint megnyomja az 'OK' gombot, a játék minden adatot töröl és automatikusan kilép. -settings.clearsaves.confirm = Biztosan törli az összes mentést? +settings.clear.confirm = Biztosan törlöd ezeket az adatokat?\n A műveletet nem lehet visszavonni! +settings.clearall.confirm = [scarlet] FIGYELEM! []\n Ez törli az összes adatot, beleértve a mentéseket, Mapokat, felfedezéseket és a billentyű beállításokat.\nAz 'OK' gomb megnyomásával a játék minden adatot töröl és automatikusan kilép. +settings.clearsaves.confirm = Biztosan törlöd az összes mentést? settings.clearsaves = Mentések törlése -settings.clearresearch = Kutatások törlése -settings.clearresearch.confirm = Biztosan törli az összes kutatást? +settings.clearresearch = Kutatás törlése +settings.clearresearch.confirm = Biztosan törlöd az összes kutatást? settings.clearcampaignsaves = Kampány mentések törlése -settings.clearcampaignsaves.confirm = Biztosan törli az összes kampány mentést? +settings.clearcampaignsaves.confirm = Biztosan törlöd az összes kampány mentést? paused = [accent]< Megállítva > clear = Törlés banned = [scarlet]Kitiltva @@ -642,180 +646,182 @@ lastaccessed = [lightgray]Utoljára megtekintve: {0} block.unknown = [lightgray]??? stat.description = Célja -stat.input = Input -stat.output = Output -stat.booster = Booster -stat.tiles = Required Tiles -stat.affinities = Affinities -stat.powercapacity = Power Capacity -stat.powershot = Power/Shot -stat.damage = Damage -stat.targetsair = Targets Air -stat.targetsground = Targets Ground -stat.itemsmoved = Move Speed -stat.launchtime = Time Between Launches -stat.shootrange = Range -stat.size = Size -stat.displaysize = Display Size -stat.liquidcapacity = Liquid Capacity -stat.powerrange = Power Range -stat.linkrange = Link Range -stat.instructions = Instructions -stat.powerconnections = Max Connections -stat.poweruse = Power Use -stat.powerdamage = Power/Damage -stat.itemcapacity = Item Capacity -stat.memorycapacity = Memory Capacity -stat.basepowergeneration = Base Power Generation -stat.productiontime = Production Time -stat.repairtime = Block Full Repair Time -stat.weapons = Weapons -stat.bullet = Bullet -stat.speedincrease = Speed Increase -stat.range = Range -stat.drilltier = Drillables -stat.drillspeed = Base Drill Speed -stat.boosteffect = Boost Effect -stat.maxunits = Max Active Units -stat.health = Health -stat.buildtime = Build Time -stat.maxconsecutive = Max Consecutive -stat.buildcost = Build Cost -stat.inaccuracy = Inaccuracy -stat.shots = Shots -stat.reload = Shots/Second -stat.ammo = Ammo -stat.shieldhealth = Shield Health -stat.cooldowntime = Cooldown Time -stat.explosiveness = Explosiveness +stat.input = Bemenet +stat.output = Kimenet +stat.booster = Gyorsító +stat.tiles = Szükséges talaj +stat.affinities = Módosító körülmények +stat.powercapacity = Elektromos kapacitás +stat.powershot = Áram/Lövés +stat.damage = Sebzés +stat.targetsair = Repülő célpontok +stat.targetsground = Földi célpontok +stat.itemsmoved = Hozam +stat.launchtime = Kilövések közti idő +stat.shootrange = Hatótáv +stat.size = Méret +stat.displaysize = Felbontás +stat.liquidcapacity = Folyadék kapacitás +stat.powerrange = Áram hatótáv +stat.linkrange = Kapcsolat hatótáv +stat.instructions = Műveletek +stat.powerconnections = Max kapcsolat +stat.poweruse = Áramhasználat +stat.powerdamage = Áram/Sebzés +stat.itemcapacity = Item kapacitás +stat.memorycapacity = Memória méret +stat.basepowergeneration = Alap áramtermelés +stat.productiontime = Gyártás hossza +stat.repairtime = Teljes javítás hossza +stat.weapons = Fegyverek +stat.bullet = Töltény +stat.speedincrease = Gyorsítás +stat.range = Hatótáv +stat.drilltier = Kitermelhető +stat.drillspeed = Alap kitermelési sebesség +stat.boosteffect = Boost hatása +stat.maxunits = Maximális aktív egység +stat.health = Életpontok +stat.buildtime = Építés hossza +stat.maxconsecutive = Maximum egymást követő +stat.buildcost = Építés ára +stat.inaccuracy = Pontatlanság +stat.shots = Lövés +stat.reload = Lövés/Másodperc +stat.ammo = Lövedék +stat.shieldhealth = Pajzs élete +stat.cooldowntime = Újratöltés hossza +stat.explosiveness = Robbanékonyság stat.basedeflectchance = Base Deflect Chance -stat.lightningchance = Lightning Chance -stat.lightningdamage = Lightning Damage -stat.flammability = Flammability -stat.radioactivity = Radioactivity -stat.heatcapacity = Heat Capacity -stat.viscosity = Viscosity -stat.temperature = Temperature -stat.speed = Speed -stat.buildspeed = Build Speed -stat.minespeed = Mine Speed -stat.minetier = Mine Tier -stat.payloadcapacity = Payload Capacity -stat.commandlimit = Command Limit -stat.abilities = Abilities +stat.lightningchance = Villámlás esélye +stat.lightningdamage = Villámlás sebzése +stat.flammability = Éghetőség +stat.radioactivity = Radioaktivitás +stat.charge = Charge +stat.heatcapacity = Hőkapacitás +stat.viscosity = Viszkozitás +stat.temperature = Hőmérséklet +stat.speed = Sebesség +stat.buildspeed = Építési sebesség +stat.minespeed = Kitermelési sebesség +stat.minetier = Kitermelési szint +stat.payloadcapacity = Teher kapacitás +stat.commandlimit = Utasítás limit +stat.abilities = Képességek stat.canboost = Can Boost -stat.flying = Flying -stat.ammouse = Ammo Use +stat.flying = Repül +stat.ammouse = Lövedék használat -ability.forcefield = Force Field -ability.repairfield = Repair Field +ability.forcefield = Erőtér +ability.repairfield = Javító mező ability.statusfield = Status Field -ability.unitspawn = {0} Factory -ability.shieldregenfield = Shield Regen Field -ability.movelightning = Movement Lightning +ability.unitspawn = {0} Gyár +ability.shieldregenfield = Pajzsos regeneráló mező +ability.movelightning = Világítás -bar.drilltierreq = Better Drill Required -bar.noresources = Missing Resources +bar.drilltierreq = Erősebb Drill szükséges +bar.noresources = Nincs elég nyersanyag bar.corereq = Core Base Required -bar.drillspeed = Drill Speed: {0}/s -bar.pumpspeed = Pump Speed: {0}/s -bar.efficiency = Efficiency: {0}% -bar.powerbalance = Power: {0}/s -bar.powerstored = Stored: {0}/{1} -bar.poweramount = Power: {0} -bar.poweroutput = Power Output: {0} -bar.powerlines = Connections: {0}/{1} -bar.items = Items: {0} -bar.capacity = Capacity: {0} +bar.drillspeed = Kitermelés: {0}/s +bar.pumpspeed = Kitermelés: {0}/s +bar.efficiency = Hatékonyság: {0}% +bar.boost = Boost: {0}% +bar.powerbalance = Áram: {0}/s +bar.powerstored = Tárolt: {0}/{1} +bar.poweramount = Áram: {0} +bar.poweroutput = Áramtermelés: {0} +bar.powerlines = Kapcsolat: {0}/{1} +bar.items = Nyersanyag: {0} +bar.capacity = Tárhely: {0} bar.unitcap = {0} {1}/{2} -bar.liquid = Liquid -bar.heat = Heat -bar.power = Power -bar.progress = Build Progress -bar.input = Input -bar.output = Output +bar.liquid = Folyadék +bar.heat = Hő +bar.power = Áram +bar.progress = Építés állapota +bar.input = Bemenet +bar.output = Kimenet units.processorcontrol = [lightgray]Processor Controlled -bullet.damage = [stat]{0}[lightgray] damage -bullet.splashdamage = [stat]{0}[lightgray] area dmg ~[stat] {1}[lightgray] tiles -bullet.incendiary = [stat]incendiary -bullet.sapping = [stat]sapping -bullet.homing = [stat]homing -bullet.shock = [stat]shock -bullet.frag = [stat]frag -bullet.buildingdamage = [stat]{0}%[lightgray] building damage -bullet.knockback = [stat]{0}[lightgray] knockback -bullet.pierce = [stat]{0}[lightgray]x pierce -bullet.infinitepierce = [stat]pierce -bullet.healpercent = [stat]{0}[lightgray]% healing -bullet.freezing = [stat]freezing +bullet.damage = [stat]{0}[lightgray] sebzés +bullet.splashdamage = [stat]{0}[lightgray] területi sebzés ~[stat] {1}[lightgray] mező +bullet.incendiary = [stat]gyújtó +bullet.sapping = [stat]szipoly +bullet.homing = [stat]nyomkövető +bullet.shock = [stat]sokkoló +bullet.frag = [stat]repesz +bullet.buildingdamage = [stat]{0}%[lightgray] épület sebzés +bullet.knockback = [stat]{0}[lightgray] hátralökés +bullet.pierce = [stat]{0}[lightgray]x átütő +bullet.infinitepierce = [stat]átütő +bullet.healpercent = [stat]{0}[lightgray]% gyógyító +bullet.freezing = [stat]fagyasztó bullet.tarred = [stat]tarred -bullet.multiplier = [stat]{0}[lightgray]x ammo multiplier -bullet.reload = [stat]{0}[lightgray]x fire rate +bullet.multiplier = [stat]{0}[lightgray]x lövedék szorzó +bullet.reload = [stat]{0}[lightgray]x tüzelési sebesség -unit.blocks = blocks -unit.blockssquared = blocks² -unit.powersecond = power units/second -unit.liquidsecond = liquid units/second -unit.itemssecond = items/second -unit.liquidunits = liquid units -unit.powerunits = power units -unit.degrees = degrees -unit.seconds = seconds -unit.minutes = mins +unit.blocks = blokk +unit.blockssquared = blokk² +unit.powersecond = egység/sec +unit.liquidsecond = egység/sec +unit.itemssecond = item/sec +unit.liquidunits = egység +unit.powerunits = egység +unit.degrees = fok +unit.seconds = másodperc +unit.minutes = perc unit.persecond = /sec unit.perminute = /min unit.timesspeed = x speed unit.percent = % unit.shieldhealth = shield health -unit.items = items +unit.items = item unit.thousands = k unit.millions = mil -unit.billions = b -unit.pershot = /shot -category.purpose = Purpose -category.general = General -category.power = Power -category.liquids = Liquids -category.items = Items -category.crafting = Input/Output -category.function = Function -category.optional = Optional Enhancements +unit.billions = Mrd +unit.pershot = /lövés +category.purpose = Cél +category.general = Általános +category.power = Áram +category.liquids = Folyadékok +category.items = Itemek +category.crafting = Bemenet/Kimenet +category.function = Funkció +category.optional = Lehetséges fokozás setting.landscape.name = Fekvő mód zárolása setting.shadows.name = Árnyékok setting.blockreplace.name = Automatikus blokk javaslatok setting.linear.name = Lineáris szűrés setting.hints.name = Tippek -setting.flow.name = Az erőforrás áramlási sebességének megjelenítése -setting.backgroundpause.name = Szünet a háttérben +setting.flow.name = A nyersanyagok áramlási sebességének megjelenítése +setting.backgroundpause.name = Szüneteltetés a háttérben setting.buildautopause.name = Automatikus szünet építéskor setting.animatedwater.name = Animált víz setting.animatedshields.name = Animált pajzsok -setting.antialias.name = Antialias[lightgray] (újra kell indítani)[] +setting.antialias.name = Antialias[lightgray] (újraindítás szükséges)[] setting.playerindicators.name = Játékos mutató setting.indicators.name = Ellenség mutató -setting.autotarget.name = Automatikus lövés +setting.autotarget.name = Automatikus célzás setting.keyboard.name = Irányítás egérrel és billentyűzettel setting.touchscreen.name = Irányítás érintőképernyővel setting.fpscap.name = Max FPS setting.fpscap.none = Nincs setting.fpscap.text = {0} FPS -setting.uiscale.name = UI Scaling[lightgray] (restart required)[] -setting.swapdiagonal.name = Always Diagonal Placement +setting.uiscale.name = UI mérete [lightgray] (újraindítás szükséges)[] +setting.swapdiagonal.name = Mindig átlós elhelyezés setting.difficulty.training = Kiképzés setting.difficulty.easy = Könnyű -setting.difficulty.normal = közepes +setting.difficulty.normal = Közepes setting.difficulty.hard = Nehéz setting.difficulty.insane = Őrült setting.difficulty.name = Nehézség: -setting.screenshake.name = Screen Shake -setting.effects.name = Display Effects -setting.destroyedblocks.name = Display Destroyed Blocks +setting.screenshake.name = Képernyő rázkódása +setting.effects.name = Effektek +setting.destroyedblocks.name = Elpusztított épületek megjelenítése setting.blockstatus.name = Blokk állapotának megjelenítése -setting.conveyorpathfinding.name = Conveyor Placement Pathfinding -setting.sensitivity.name = Controller Sensitivity -setting.saveinterval.name = Save Interval +setting.conveyorpathfinding.name = Futószalag útvonalkeresés építéskor +setting.sensitivity.name = Controller érzékenység +setting.saveinterval.name = Mentési időköz setting.seconds = {0} másodperc setting.milliseconds = {0} ezredmásodperc setting.fullscreen.name = Teljesképernyő @@ -825,150 +831,151 @@ setting.smoothcamera.name = Sima kamera setting.vsync.name = VSync setting.pixelate.name = Pixeles setting.minimap.name = Minimap -setting.coreitems.name = Az alapvető elemek megjelenítése +setting.coreitems.name = Magban lévő nyersanyagok megjelenítése setting.position.name = A játékos pozíciójának megjelenítése setting.musicvol.name = Zene hangerő setting.atmosphere.name = Bolygó atmoszféra setting.ambientvol.name = Környezeti hangerő -setting.mutemusic.name = Néma zene +setting.mutemusic.name = Zene némítása setting.sfxvol.name = SFX hangerő -setting.mutesound.name = Néma hang -setting.crashreport.name = Send Anonymous Crash Reports +setting.mutesound.name = Hang némítása +setting.crashreport.name = Névtelen crash jelentések setting.savecreate.name = Automatikus mentés -setting.publichost.name = Public Game Visibility +setting.publichost.name = Nyilvános játék láthatósága setting.playerlimit.name = Játékos limit -setting.chatopacity.name = Chat átlátszatlanság -setting.lasersopacity.name = Power Laser Opacity -setting.bridgeopacity.name = Híd átlátszatlanság -setting.playerchat.name = A játékos buborékos csevegésének megjelenítése +setting.chatopacity.name = Chat átlátszatlansága +setting.lasersopacity.name = Villanyvezeték álátszatlansága +setting.bridgeopacity.name = Híd átlátszatlansága +setting.playerchat.name = Játékos szóbuborékok megjelenítése setting.showweather.name = Időjárás grafika megjelenítése -public.confirm = Do you want to make your game public?\n[accent]Anyone will be able to join your games.\n[lightgray]This can be changed later in Settings->Game->Public Game Visibility. -public.confirm.really = If you want to play with friends, use [green]Invite Friend[] instead of a [scarlet]Public server[]!\nAre you sure you want to make your game [scarlet]public[]? -public.beta = Note that beta versions of the game cannot make public lobbies. -uiscale.reset = UI scale has been changed.\nPress "OK" to confirm this scale.\n[scarlet]Reverting and exiting in[accent] {0}[] seconds... +public.confirm = Szeretnéd a játékot nyilvánossá tenni?\n[accent]Bárki beléphet a játékaidba.\n[lightgray]Ezt később megváltoztathatod a Beállítások->Játék->Nyilvános játék láthatósága menüpontban. +public.confirm.really = Ha a barátaiddal szeretnél játszani, használd a [green]Barátok meghívása[] funkciót [scarlet]Nyilvános szerver[] helyett!\nBiztosan szeretnéd, hogy a játékod [scarlet]nyilvános[] legyen? +public.beta = Ne feledd, hogy a játék béta verziójában nem tudsz nyilvános szobát nyitni. +uiscale.reset = Az UI mérete megváltozott.\nAz "OK" gombbal megerősítheted ezt a méretet.\n[scarlet]Visszavonás és kilépés [accent] {0}[] másodperc múlva... uiscale.cancel = Mégse és Kilépés -setting.bloom.name = Virágzás -keybind.title = Rebind Keys -keybinds.mobile = [scarlet]Most keybinds here are not functional on mobile. Only basic movement is supported. -category.general.name = General -category.view.name = View -category.multiplayer.name = Multiplayer -category.blocks.name = Block Select -command.attack = Attack -command.rally = Rally -command.retreat = Retreat -command.idle = Idle +setting.bloom.name = Bloom +keybind.title = Gyorsbillentyűk +keybinds.mobile = [scarlet]A legtöbb billentyűfunkció mobilon nem működik. Csak a mozgás támogatott. +category.general.name = Általános +category.view.name = Nézet +category.multiplayer.name = Többjátékos +category.blocks.name = Blokk választás +command.attack = Támadás +command.rally = Gyülekezés +command.retreat = Visszavonulás +command.idle = Semmi placement.blockselectkeys = \n[lightgray]Key: [{0}, -keybind.respawn.name = Respawn -keybind.control.name = Control Unit -keybind.clear_building.name = Clear Building -keybind.press = Press a key... +keybind.respawn.name = Újraéledés +keybind.control.name = Egység irányítása +keybind.clear_building.name = Építési terv törlése +keybind.press = Nyomj meg egy billentyűt keybind.press.axis = Press an axis or key... -keybind.screenshot.name = Map Screenshot -keybind.toggle_power_lines.name = Toggle Power Lasers -keybind.toggle_block_status.name = Toggle Block Statuses -keybind.move_x.name = Move X -keybind.move_y.name = Move Y -keybind.mouse_move.name = Follow Mouse -keybind.pan.name = Pan View +keybind.screenshot.name = Map képernyőkép +keybind.toggle_power_lines.name = Villanyvezetékek be/ki +keybind.toggle_block_status.name = Blokk státusz be/ki +keybind.move_x.name = Mozgás vízszintesen +keybind.move_y.name = Mozgás függőlegesen +keybind.mouse_move.name = Egér követése +keybind.pan.name = Felderítés keybind.boost.name = Boost -keybind.schematic_select.name = Select Region -keybind.schematic_menu.name = Schematic Menu -keybind.schematic_flip_x.name = Flip Schematic X -keybind.schematic_flip_y.name = Flip Schematic Y -keybind.category_prev.name = Previous Category -keybind.category_next.name = Next Category -keybind.block_select_left.name = Block Select Left -keybind.block_select_right.name = Block Select Right -keybind.block_select_up.name = Block Select Up -keybind.block_select_down.name = Block Select Down -keybind.block_select_01.name = Category/Block Select 1 -keybind.block_select_02.name = Category/Block Select 2 -keybind.block_select_03.name = Category/Block Select 3 -keybind.block_select_04.name = Category/Block Select 4 -keybind.block_select_05.name = Category/Block Select 5 -keybind.block_select_06.name = Category/Block Select 6 -keybind.block_select_07.name = Category/Block Select 7 -keybind.block_select_08.name = Category/Block Select 8 -keybind.block_select_09.name = Category/Block Select 9 -keybind.block_select_10.name = Category/Block Select 10 -keybind.fullscreen.name = Toggle Fullscreen -keybind.select.name = Select/Shoot -keybind.diagonal_placement.name = Diagonal Placement -keybind.pick.name = Pick Block -keybind.break_block.name = Break Block -keybind.deselect.name = Deselect -keybind.pickupCargo.name = Pickup Cargo -keybind.dropCargo.name = Drop Cargo -keybind.command.name = Command -keybind.shoot.name = Shoot +keybind.schematic_select.name = Terület kijelölése +keybind.schematic_menu.name = Schematic menü +keybind.schematic_flip_x.name = Schematic tükrözése vízszintesen +keybind.schematic_flip_y.name = Schematic tükrözése függőlegesen +keybind.category_prev.name = Előző kategória +keybind.category_next.name = Következő kategória +keybind.block_select_left.name = Blokk váltás balra +keybind.block_select_right.name = Blokk váltás jobbra +keybind.block_select_up.name = Blokk váltás fel +keybind.block_select_down.name = Blokk váltás le +keybind.block_select_01.name = Blokk kategória 1 +keybind.block_select_02.name = Blokk kategória 2 +keybind.block_select_03.name = Blokk kategória 3 +keybind.block_select_04.name = Blokk kategória 4 +keybind.block_select_05.name = Blokk kategória 5 +keybind.block_select_06.name = Blokk kategória 6 +keybind.block_select_07.name = Blokk kategória 7 +keybind.block_select_08.name = Blokk kategória 8 +keybind.block_select_09.name = Blokk kategória 9 +keybind.block_select_10.name = Blokk kategória 10 +keybind.fullscreen.name = Teljesképernyő be/ki +keybind.select.name = Kiválasztás/Lövés +keybind.diagonal_placement.name = Átlós elhelyezés +keybind.pick.name = Blokk másolása +keybind.break_block.name = Blokk törlése +keybind.deselect.name = Blokk választás törlése +keybind.pickupCargo.name = Rakomány felvétele +keybind.dropCargo.name = Rakomány lerakása +keybind.command.name = Irányítás +keybind.shoot.name = Lövés keybind.zoom.name = Zoom -keybind.menu.name = Menu -keybind.pause.name = Pause -keybind.pause_building.name = Pause/Resume Building +keybind.menu.name = Menü +keybind.pause.name = Szünet +keybind.pause_building.name = Építés szüneteltetése/folytatása keybind.minimap.name = Minimap -keybind.planet_map.name = Planet Map -keybind.research.name = Research +keybind.planet_map.name = Bolygó térkép +keybind.research.name = Kutatás keybind.chat.name = Chat -keybind.player_list.name = Player List -keybind.console.name = Console -keybind.rotate.name = Rotate -keybind.rotateplaced.name = Rotate Existing (Hold) +keybind.player_list.name = Játékos lista +keybind.console.name = Konzol +keybind.rotate.name = Frogatás +keybind.rotateplaced.name = Épület forgatása (tartsd nyomva) keybind.toggle_menus.name = Toggle Menus -keybind.chat_history_prev.name = Chat History Prev -keybind.chat_history_next.name = Chat History Next -keybind.chat_scroll.name = Chat Scroll -keybind.chat_mode.name = Change Chat Mode -keybind.drop_unit.name = Drop Unit -keybind.zoom_minimap.name = Zoom Minimap -mode.help.title = Description of modes -mode.survival.name = Survival -mode.survival.description = The normal mode. Limited resources and automatic incoming waves.\n[gray]Requires enemy spawns in the map to play. -mode.sandbox.name = Sandbox -mode.sandbox.description = Infinite resources and no timer for waves. -mode.editor.name = Editor +keybind.chat_history_prev.name = Chat görgetés fel +keybind.chat_history_next.name = Chat görgetés le +keybind.chat_scroll.name = Chat görgetés +keybind.chat_mode.name = Chat mód megváltoztatása +keybind.drop_unit.name = Egység elengedése +keybind.zoom_minimap.name = Zoom a Minimapoon +mode.help.title = Játékmódok leírása +mode.survival.name = Túlélő +mode.survival.description = A normál mód. Korlátozott nyersanyag és automatikusan érkező hullámok.\n[gray]Szükséges hozzá ellenséges spawn a Mapon. +mode.sandbox.name = Homokozó +mode.sandbox.description = Végtelen erőforrás, nincs időzítés a hullámokhoz. +mode.editor.name = Szerkesztő mode.pvp.name = PvP -mode.pvp.description = Fight against other players locally.\n[gray]Requires at least 2 differently-colored cores in the map to play. -mode.attack.name = Attack -mode.attack.description = Destroy the enemy's base. \n[gray]Requires a red core in the map to play. -mode.custom = Custom Rules +mode.pvp.description = Harcolj másik játékosok ellen.\n[gray]Szükséges hozzá legalább két különböző színű mag a Mapon. +mode.attack.name = Támadás +mode.attack.description = Pusztítsd el az ellenség bázisát. \n[gray]Szükséges hozzá egy piros mag a Mapon. +mode.custom = Egyéni szabályok -rules.infiniteresources = Infinite Resources -rules.reactorexplosions = Reactor Explosions -rules.schematic = Schematics Allowed -rules.wavetimer = Wave Timer -rules.waves = Waves -rules.attack = Attack Mode +rules.infiniteresources = Végtelen erőforrás +rules.reactorexplosions = Reaktor robbanás +rules.coreincinerates = Túlcsorduló itemek megsemmisítse a magban +rules.schematic = Schematicok +rules.wavetimer = Hullám időzítő +rules.waves = Hullámok +rules.attack = Támadás mód rules.buildai = AI Building -rules.enemyCheat = Infinite AI (Red Team) Resources -rules.blockhealthmultiplier = Block Health Multiplier -rules.blockdamagemultiplier = Block Damage Multiplier -rules.unitbuildspeedmultiplier = Unit Production Speed Multiplier -rules.unithealthmultiplier = Unit Health Multiplier -rules.unitdamagemultiplier = Unit Damage Multiplier -rules.enemycorebuildradius = Enemy Core No-Build Radius:[lightgray] (tiles) -rules.wavespacing = Wave Spacing:[lightgray] (sec) -rules.buildcostmultiplier = Build Cost Multiplier -rules.buildspeedmultiplier = Build Speed Multiplier -rules.deconstructrefundmultiplier = Deconstruct Refund Multiplier +rules.enemyCheat = Végtelen AI (Piros csapat) Erőforrás +rules.blockhealthmultiplier = Épület életpont szorzó +rules.blockdamagemultiplier = Épület sebzés szorzó +rules.unitbuildspeedmultiplier = Egység gyártási sebesség szorzó +rules.unithealthmultiplier = Egység életpont szorzó +rules.unitdamagemultiplier = Egység sebzés szorzó +rules.enemycorebuildradius = Ellenséges mag körüli tiltott zóna sugara:[lightgray] (mező) +rules.wavespacing = Hullám időzítés:[lightgray] (sec) +rules.buildcostmultiplier = Építési költség szorzó +rules.buildspeedmultiplier = Építési sebesség szorzó +rules.deconstructrefundmultiplier = Bontási visszatérítés szorzó rules.waitForWaveToEnd = Waves Wait for Enemies -rules.dropzoneradius = Drop Zone Radius:[lightgray] (tiles) -rules.unitammo = Units Require Ammo -rules.title.waves = Waves -rules.title.resourcesbuilding = Resources & Building -rules.title.enemy = Enemies -rules.title.unit = Units -rules.title.experimental = Experimental -rules.title.environment = Environment -rules.lighting = Lighting -rules.enemyLights = Enemy Lights -rules.fire = Fire -rules.explosions = Block/Unit Explosion Damage -rules.ambientlight = Ambient Light -rules.weather = Weather -rules.weather.frequency = Frequency: +rules.dropzoneradius = Ledobási zóna sugara:[lightgray] (mező) +rules.unitammo = Egységeknek kell lövedék +rules.title.waves = Hullámok +rules.title.resourcesbuilding = Erőforrások és épületek +rules.title.enemy = Ellenségek +rules.title.unit = Egységek +rules.title.experimental = Kísérleti +rules.title.environment = Környezet +rules.lighting = Világítás +rules.enemyLights = Ellenséges fények +rules.fire = Tűz +rules.explosions = Épület/Egység robbanás sebzés +rules.ambientlight = Háttérvilágítás +rules.weather = Időjárás +rules.weather.frequency = Gyakoriság: rules.weather.always = Mindig -rules.weather.duration = Duration: +rules.weather.duration = Időtartam: content.item.name = Itemek content.liquid.name = Folyadékok @@ -976,26 +983,26 @@ content.unit.name = Egységek content.block.name = Blokkok content.sector.name = Szektor -item.copper.name = Copper -item.lead.name = Lead -item.coal.name = Coal -item.graphite.name = Graphite -item.titanium.name = Titanium -item.thorium.name = Thorium -item.silicon.name = Silicon -item.plastanium.name = Plastanium -item.phase-fabric.name = Phase Fabric -item.surge-alloy.name = Surge Alloy -item.spore-pod.name = Spore Pod -item.sand.name = Sand -item.blast-compound.name = Blast Compound -item.pyratite.name = Pyratite -item.metaglass.name = Metaglass -item.scrap.name = Scrap -liquid.water.name = Water -liquid.slag.name = Slag -liquid.oil.name = Oil -liquid.cryofluid.name = Cryofluid +item.copper.name = Réz +item.lead.name = Ólom +item.coal.name = Szén +item.graphite.name = Grafit +item.titanium.name = Titán +item.thorium.name = Tórium +item.silicon.name = Szilícium +item.plastanium.name = Plasztínium +item.phase-fabric.name = Fázisos Szövet +item.surge-alloy.name = Multiötvözet +item.spore-pod.name = Spóratok +item.sand.name = Homok +item.blast-compound.name = Robbanóelegy +item.pyratite.name = Piratit +item.metaglass.name = Ólomüveg +item.scrap.name = Hulladék +liquid.water.name = Víz +liquid.slag.name = Salak +liquid.oil.name = Olaj +liquid.cryofluid.name = Hűtőfolyadék unit.dagger.name = Dagger unit.mace.name = Mace @@ -1254,252 +1261,253 @@ team.blue.name = kék team.crux.name = piros team.sharded.name = narancssárga team.orange.name = narancssárga -team.derelict.name = elhagyott +team.derelict.name = elhagyatott team.green.name = zöld team.purple.name = lila hint.skip = Átugrás hint.desktopMove = Használd a [accent][[WASD][] gombokat a mozgáshoz. hint.zoom = Használd a [accent]görgőt[] a zoomhoz.. -hint.mine = Mozogjon a \uf8c4 copper közelében, és [accent]érintse meg[] a kézi bányászathoz. -hint.desktopShoot = Használja a [accent]bal egér gombot[] a lövéshez. -hint.depositItems = Az átviteléhez húzzaaz itemeket a hajóról a magra. -hint.respawn = Ha újból hajóvá akar válni, nyomja meg a [accent][[V][] gombot. -hint.respawn.mobile = You have switched control to a unit/structure. To respawn as a ship, [accent]tap the avatar in the top left.[] -hint.desktopPause = Press [accent][[Space][] to pause and unpause the game. -hint.placeDrill = Select the \ue85e [accent]Drill[] tab in the menu at the bottom right, then select a \uf870 [accent]Drill[] and click on a copper patch to place it. -hint.placeDrill.mobile = Select the \ue85e [accent]Drill[] tab in the menu at the bottom right, then select a \uf870 [accent]Drill[] and tap on a copper patch to place it.\n\nPress the \ue800 [accent]checkmark[] at the bottom right to confirm. -hint.placeConveyor = Conveyors move items from drills into other blocks. Select a \uf896 [accent]Conveyor[] from the \ue814 [accent]Distribution[] tab.\n\nClick and drag to place multiple conveyors.\n[accent]Scroll[] to rotate. -hint.placeConveyor.mobile = Conveyors move items from drills into other blocks. Select a \uf896 [accent]Conveyor[] from the \ue814 [accent]Distribution[] tab.\n\nHold down your finger for a second and drag to place multiple conveyors. -hint.placeTurret = Place \uf861 [accent]Turrets[] to defend your base from enemies.\n\nTurrets require ammo - in this case, \uf838copper.\nUse conveyors and drills to supply them. -hint.breaking = [accent]Right-click[] and drag to break blocks. -hint.breaking.mobile = Activate the \ue817 [accent]hammer[] in the bottom right and tap to break blocks.\n\nHold down your finger for a second and drag to break in a selection. -hint.research = Use the \ue875 [accent]Research[] button to research new technology. -hint.research.mobile = Use the \ue875 [accent]Research[] button in the \ue88c [accent]Menu[] to research new technology. -hint.unitControl = Hold [accent][[L-ctrl][] and [accent]click[] to control friendly units or turrets. -hint.unitControl.mobile = [accent][[Double-tap][] to control friendly units or turrets. -hint.launch = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the bottom right. -hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. -hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. -hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. -hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. -hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. -hint.command = Press [accent][[G][] to command nearby units of [accent]similar type[] into formation.\n\nTo command ground units, you must first control another ground unit. -hint.command.mobile = [accent][[Double-tap][] your unit to command nearby units into formation. -hint.payloadPickup = Press [accent][[[] to pick up small blocks or units. -hint.payloadPickup.mobile = [accent]Tap and hold[] a small block or unit to pick it up. -hint.payloadDrop = Press [accent]][] to drop a payload. -hint.payloadDrop.mobile = [accent]Tap and hold[] an empty location to drop a payload there. -hint.waveFire = [accent]Wave[] turrets with water as ammunition will automatically put out nearby fires. -hint.generator = \uf879 [accent]Combustion Generators[] burn coal and transmit power to adjacent blocks.\n\nPower transmission range can be extended with \uf87f [accent]Power Nodes[]. -hint.guardian = [accent]Guardian[] units are armored. Weak ammo such as [accent]Copper[] and [accent]Lead[] is [scarlet]not effective[].\n\nUse higher tier turrets or \uf835 [accent]Graphite[] \uf861Duo/\uf859Salvo ammunition to take Guardians down. -hint.coreUpgrade = Cores can be upgraded by [accent]placing higher-tier cores over them[].\n\nPlace a  [accent]Foundation[] core over the  [accent]Shard[] core. Make sure it is free from nearby obstructions. -hint.presetLaunch = Gray [accent]landing zone sectors[], such as [accent]Frozen Forest[], can be launched to from anywhere. They do not require capture of nearby territory.\n\n[accent]Numbered sectors[], such as this one, are [accent]optional[]. -hint.coreIncinerate = After the core is filled to capacity with an item, any extra items of that type it receives will be [accent]incinerated[]. -hint.coopCampaign = When playing the [accent]co-op campaign[], items that are produced in the current map will also be sent [accent]to your local sectors[].\n\nAny new research done by the host also carries over. +hint.mine = Menj a \uf8c4 copper közelébe, és [accent]kattints rá[] a kézi bányászáshoz. +hint.desktopShoot = Használd a [accent]bal egérgombot[] a lövéshez. +hint.depositItems = Az itemeket a hajóról a magra húzva áthelyezheted. +hint.respawn = Hogy hajóként újraéledj, nyomd meg a [accent][[V][] gombot. +hint.respawn.mobile = Átvetted az irányítást egy egység vagy torony felett. Hogy újraéledj hajóként, [accent]érintsd meg az avatárt a bal felső sarokban.[] +hint.desktopPause = Nyomd meg a [accent][[Space][]-t, hogy szüneteltesd vagy folytasd a játékot. +hint.placeDrill = Válaszd ki a \ue85e [accent]Drill[] lapot a jobb alsó sarokban található menüben, válassz ki egy \uf870 [accent]Drill[] épületet, és kattints egy rézfoltra, hogy lerakd. +hint.placeDrill.mobile = Válaszd ki a \ue85e [accent]Drill[] lapot a jobb alsó sarokban található menüben, válassz ki egy \uf870 [accent]Drill[] épületet, és nyomj egy rézfoltra, hogy lerakd.\n\nNyomj a \ue800 [accent]pipára[] jobb lent, hogy megerősítsd. +hint.placeConveyor = A futószalagok az itemeket a Drillektől más épületekhez szállítják. Válassz ki egy \uf896 [accent]futószalagot[] a \ue814 [accent]Distribution[] lapról.\n\nKattints és tartsd lenyomva, hogy többet is lehelyezz.\n[accent]Görgess[] a forgatáshoz. +hint.placeConveyor.mobile = A futószalagok az itemeket a Drillektől más épületekhez szállítják. Válassz ki egy \uf896 [accent]futószalagot[] a \ue814 [accent]Distribution[] lapról.\n\nTartsd lenyomva az ujjad és húzd, hgy egyszerre többet is lehelyezz. +hint.placeTurret = Helyezz le \uf861 [accent]Tornyokat[], hogy megvédd a bázisod az ellenségtől.\n\nA tornyoknak lövedékre van szükségük - ebben az esetben \uf838rézre.\nHasználd a futószalagokat és Drilleket, hogy ellásd őket. +hint.breaking = [accent]Jobb gombot[] nyomva kijelölhetsz lebontandó épületeket. +hint.breaking.mobile = Használd a \ue817 [accent]kalapácsot[] jobb lent és töröld vele az útban lévő épületeket.\n\nTartsd lenyomva az ujjad és húzd, hogy nagyobb területet kijelölj. +hint.research = Használd a \ue875 [accent]Kutatás[] gombot, hogy felfedezz új technológiákat. +hint.research.mobile = Használd a \ue875 [accent]Kutatás[] gombot a \ue88c [accent]Menü[]ben, hogy felfedezz új technológiákat. +hint.unitControl = Nyomd le a [accent][[L-ctrl][] billentyőt és [accent]kattints[], hogy átvedd az irányítást szövetséges egységek vagy tornyok felett. +hint.unitControl.mobile = [accent][[Dupla koppintás][]sal átveheted az irányítást szövetséges egységek és tornyok felett. +hint.launch = Ha elegendő nyersanyagot gyűjtöttél, [accent]Kilőhetsz[] egy közeli szektorba. Ezt a jobb lent látható \ue827 [accent]Térkép[]en teheted meg. +hint.launch.mobile = Ha elegendő nyersanyagot gyűjtöttél, [accent]Kilőhetsz[] egy közeli szektorba. Ezt a \ue88c [accent]Menü[]ből elérhető \ue827 [accent]Térkép[]en teheted meg. +hint.schematicSelect = Az [accent][[F][] nyomva tartásával kijelölhetsz és másolhastz épületeket.\n\nKattints a [accent][[görgővel][], hogy egy épületet lemásolj. +hint.conveyorPathfind = Tartsd nyomva a [accent][[L-Ctrl][] billentyűt futószalagok lerakása közben, hogy a játék útvnalat generáljon. +hint.conveyorPathfind.mobile = Enegdélyezd az \ue844 [accent]átlós mód[]ot és tagyél le egyszerre több futószalagot, hogy a játék útvonalat generáljon. +hint.boost = Tartsd nyomva a [accent][[L-Shift][] billentyűt, hogy átrepülj az akadályok felett.\n\nErre nem minden földi egység képes. +hint.command = A [accent][[G][] megnyomására a [accent]azonos típusú[] közeli egységek formációba rendeződnek.\n\nA földi egységek irányításához neked is földi egységet kell irányítanod. +hint.command.mobile = [accent][[Koppints kétszer][] a hajódra, hogy a közeli egységeid formációba rendeződjenek. +hint.payloadPickup = A [accent][[[] gombbal kis épületeket vagy egységeket emelhetsz fel. +hint.payloadPickup.mobile = [accent]Tartsd nyomva az ujjad[] egy kis épületen vagy egségen, hogy felemeld. +hint.payloadDrop = A [accent]][] megnyomásával lerakhatod a terhedet. +hint.payloadDrop.mobile = [accent]Tartsd nyomva az ujjad[] egy üres területen, hogy letedd a terhedet. +hint.waveFire = A [accent]Wave[] tornyok, ha víz van bennük, automatikusan eloltják a közeli tüzeket. +hint.generator = \uf879 A [accent]Combustion Generator[] szenet éget, és átadja az áramot a vele érintkező épületeknek.\n\n Áramot nagyobb távolságra is szállíthatsz \uf87f [accent]Power Node[]-ok segítségével. +hint.guardian = Az [accent]Őrző[]knek páncélja van. A gyenge lövedékeknek, mint a [accent]Copper[] vagy a [accent]Lead[] [scarlet]nincs hatásuk[].\n\nHasználj magasabb szintű tornyokat vagy \uf835 [accent]Graphite[] lövedéket a \uf861Duo/\uf859Salvo tornyokba, hogy leszedd az Őrzőket. +hint.coreUpgrade = A magot fejlesztheted, ha [accent]magasabb sintű magot teszel rá[].\n\nHelyezz egy [accent]Foundation[] magot a [accent]Shard[] magra. Figyelj rá, hogy ne legyenek az új mag területén épületek. +hint.presetLaunch = A szürke [accent]kampány szektorok[]ba, amilyen például a [accent]Frozen Forest[], bárhonnan kilőhetsz. Nem kell szomszédos területtel rendelkezned.\n\nA [accent]számozott szektorok[], mint ez is, [accent]opcionálisak[]. +hint.coreIncinerate = Ha a magodban egy nyersanyag elérte a maximumot, a beérkező ilyen nyersanyagaid azonnal [accent]megsemmisítésre kerülnek[]. +hint.coopCampaign = Ha [accent]co-op kampány[]t játszol, az adott mapon termelt nyersanyagok a [accent]saját szektoraidba[] is bekerülnek.\n\nA host minden fejlesztése is átkerül. -item.copper.description = Used in all types of construction and ammunition. -item.copper.details = Copper. Abnormally abundant metal on Serpulo. Structurally weak unless reinforced. -item.lead.description = Used in liquid transportation and electrical structures. -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 = Used in liquid distribution/storage structures. -item.graphite.description = Used in electrical components and turret ammunition. -item.sand.description = Used for production of other refined materials. -item.coal.description = Used for fuel and refined material production. -item.coal.details = Appears to be fossilized plant matter, formed long before the seeding event. -item.titanium.description = Used in liquid transportation structures, drills and aircraft. -item.thorium.description = Used in durable structures and as nuclear fuel. -item.scrap.description = Used in Melters and Pulverizers for refining into other materials. -item.scrap.details = Leftover remnants of old structures and units. -item.silicon.description = Used in solar panels, complex electronics and homing turret ammunition. -item.plastanium.description = Used in advanced units, insulation and fragmentation ammunition. -item.phase-fabric.description = Used in advanced electronics and self-repairing structures. -item.surge-alloy.description = Used in advanced weaponry and reactive defense structures. -item.spore-pod.description = Used for conversion into oil, explosives and fuel. -item.spore-pod.details = Spores. Likely a synthetic life form. Emit gases toxic to other biological life. Extremely invasive. Highly flammable in certain conditions. -item.blast-compound.description = Used in bombs and explosive ammunition. -item.pyratite.description = Used in incendiary weapons and combustion-fueled generators. +item.copper.description = Széleskörűen felhasználható építkezésre és lövedékként. +item.copper.details = Szokatlanul elterjedt fém a Serpulón. Gyenge szerkezetű, de megerősíthető. +item.lead.description = Folyadékszállításban és elektromos eszközökben használható. +item.lead.details = Sűrű. Közömbös. Széles körben használják elemekben.\nMegjegyzés: Valószínűleg mérgező a biológiai életformákra. Nem mintha sok maradt volna errefelé. +item.metaglass.description = Folyadékok szállítására és tárolására használható. +item.graphite.description = Elektromos alkatrészek alapanyaga és lövedék. +item.sand.description = Egyéb finom nyersanyagok gyártási alapanyaga. +item.coal.description = Tüzelőanyag és gyártási alapanyag. +item.coal.details = Fosszílizálódott növényi anyagnak tűnik, jóval a "seeding event" előttről. +item.titanium.description = Folyadékok szállítására, fúrókban és légi járművekben használható. +item.thorium.description = Strapabíró szerkezetekben használható nukleáris tüzelőanyagként. +item.scrap.description = Olvasztással és porítással finom nyersanyagok nyerhetők ki belőle. +item.scrap.details = Ősi építmények és egységek hátrahagyott maradványai. +item.silicon.description = Napelemek, összetett áramkörök és nyomkövető lövedékek fontos alapanyaga. Sosincs elég. +item.plastanium.description = Fejlett egységek alapanyagaként, hőszigetelésre és repeszes lövedékekhez használható. +item.phase-fabric.description = Fejlett elektromos eszközökben és önjavító szerkezetekben használható. +item.surge-alloy.description = Magas szintű fegyverzetekben és aktív védelemhez használható. +item.spore-pod.description = Átalakítható olajjá vagy robbanószerekké, de használható tüzelőanyagként is. +item.spore-pod.details = Spórák. Egy valószínűleg mesterséges életforma. Más életformák számára halálos gázt bocsátanak ki. Szélsőségesen invazív. Megfelelő körülmények között erősen gyúlékony. +item.blast-compound.description = Bombák és robbanó lövedékek része. +item.pyratite.description = Gyújtó lövedékekben és tüzelőanyag-alapú generátorokban használható. -liquid.water.description = Used for cooling machines and waste processing. -liquid.slag.description = Refined in separators into constituent metals, or sprayed at enemies as a weapon. -liquid.oil.description = Used in advanced material production and as incendiary ammunition. -liquid.cryofluid.description = Used as coolant in reactors, turrets and factories. +liquid.water.description = Gépek hűtésére és hulladékfeldolgozásra használható. +liquid.slag.description = Separatorban finomítva értékes fémek forrása, az ellenségre fröcskölve gyilkos fegyver. +liquid.oil.description = Magas szintű nyersanyagok gyártására vagy gyújtólövedékként használható. +liquid.cryofluid.description = Hűtőfolyadék reaktorok, tornyok és gyárak számára. block.resupply-point.description = Resupplies nearby units with copper ammunition. Not compatible with units that require battery power. -block.armored-conveyor.description = Moves items forward. Does not accept inputs from the sides. -block.illuminator.description = Emits light. -block.message.description = Stores a message for communication between allies. -block.graphite-press.description = Compresses coal into graphite. -block.multi-press.description = Compresses coal into graphite. Requires water as coolant. -block.silicon-smelter.description = Refines silicon from sand and coal. -block.kiln.description = Smelts sand and lead into metaglass. -block.plastanium-compressor.description = Produces plastanium from oil and titanium. -block.phase-weaver.description = Synthesizes phase fabric from thorium and sand. -block.alloy-smelter.description = Fuses titanium, lead, silicon and copper into surge alloy. -block.cryofluid-mixer.description = Mixes water and fine titanium powder to produce cryofluid. -block.blast-mixer.description = Produces blast compound from pyratite and spore pods. -block.pyratite-mixer.description = Mixes coal, lead and sand into pyratite. -block.melter.description = Melts down scrap into slag. -block.separator.description = Separates slag into its mineral components. -block.spore-press.description = Compresses spore pods into oil. -block.pulverizer.description = Crushes scrap into fine sand. -block.coal-centrifuge.description = Transforms oil into coal. -block.incinerator.description = Vaporizes any item or liquid it receives. -block.power-void.description = Voids all power inputted. Sandbox only. -block.power-source.description = Infinitely outputs power. Sandbox only. -block.item-source.description = Infinitely outputs items. Sandbox only. -block.item-void.description = Destroys any items. Sandbox only. -block.liquid-source.description = Infinitely outputs liquids. Sandbox only. -block.liquid-void.description = Removes any liquids. Sandbox only. -block.copper-wall.description = Protects structures from enemy projectiles. -block.copper-wall-large.description = Protects structures from enemy projectiles. -block.titanium-wall.description = Protects structures from enemy projectiles. -block.titanium-wall-large.description = Protects structures from enemy projectiles. -block.plastanium-wall.description = Protects structures from enemy projectiles. Absorbs lasers and electric arcs. Blocks automatic power connections. -block.plastanium-wall-large.description = Protects structures from enemy projectiles. Absorbs lasers and electric arcs. Blocks automatic power connections. -block.thorium-wall.description = Protects structures from enemy projectiles. -block.thorium-wall-large.description = Protects structures from enemy projectiles. -block.phase-wall.description = Protects structures from enemy projectiles, reflecting most bullets upon impact. -block.phase-wall-large.description = Protects structures from enemy projectiles, reflecting most bullets upon impact. -block.surge-wall.description = Protects structures from enemy projectiles, periodically releasing electric arcs upon contact. -block.surge-wall-large.description = Protects structures from enemy projectiles, periodically releasing electric arcs upon contact. -block.door.description = A wall that can be opened and closed. -block.door-large.description = A wall that can be opened and closed. -block.mender.description = Periodically repairs blocks in its vicinity.\nOptionally uses silicon to boost range and efficiency. -block.mend-projector.description = Repairs blocks in its vicinity.\nOptionally uses phase fabric to boost range and efficiency. -block.overdrive-projector.description = Increases the speed of nearby buildings.\nOptionally uses phase fabric to boost range and efficiency. +block.armored-conveyor.description = Nyersanyagokat továbbít. Nem fogad el nyersanyagot oldalról. +block.illuminator.description = Világít. +block.message.description = Üzenetet tárol szövetségesek kommunikációjához. +block.graphite-press.description = Szenet présel grafittá. +block.multi-press.description = Szenet présel grafittá. Hatékonyan dolgozik, de vizet igényel hűtéshez. +block.silicon-smelter.description = Szilíciumot nyer ki homok és szén keverékéből. +block.kiln.description = Ólmomból és homokból olvaszt ólomüveget. +block.plastanium-compressor.description = Plastaniumot gyárt olaj és titán felhasználásával. +block.phase-weaver.description = Phase fabricot szintetizál tórium és homok keverékéből. +block.alloy-smelter.description = Titán, ólom, szilícium és réz olvadékából állít elő surge alloy-t. +block.cryofluid-mixer.description = Finom titánport kever vízhez cryofluid előállításához. +block.blast-mixer.description = Piratitból és spóra kapszulákból készít robbanóelegyet. +block.pyratite-mixer.description = Szenet, homokot és ólmot vegyít piratittá. +block.melter.description = Hulladékot olvaszt salakká. +block.separator.description = Szétbontja a salakot ásványi összetevőire. +block.spore-press.description = Nagy nyomáson olajat présel spórákból. +block.pulverizer.description = Finom homokká őrli a hulladékot. +block.coal-centrifuge.description = Szenet nyer ki olajból. +block.incinerator.description = Megsemmisít minden nyersanyagot és folyadékot. +block.power-void.description = Elnyel minden áramot. Csak homokozó módban. +block.power-source.description = Végtelen áramot termel. Csak homokozó módban. +block.item-source.description = Végtelen nyersanyagot bocsát ki. Csak homokozó módban. +block.item-void.description = Megsemmisít minden nyersanyagot. Csak homokozó módban. +block.liquid-source.description = Végtelen folyadékot bocsát ki. Csak homokozó módban. +block.liquid-void.description = Megsemmisít minden folyadékot. Csak homokozó módban. +block.copper-wall.description = Megvédi az épületeket az ellenséges lövedékektől. +block.copper-wall-large.description = Megvédi az épületeket az ellenséges lövedékektől. +block.titanium-wall.description = Megvédi az épületeket az ellenséges lövedékektől. +block.titanium-wall-large.description = Megvédi az épületeket az ellenséges lövedékektől. +block.plastanium-wall.description = Megvédi az épületeket az ellenséges lövedékektől. Elnyeli a lézereket és elektromos szikrákat. Gátolja a villanyvezetékek automatikus kapcsolódását. +block.plastanium-wall-large.description = Megvédi az épületeket az ellenséges lövedékektől. Elnyeli a lézereket és elektromos szikrákat. Gátolja a villanyvezetékek automatikus kapcsolódását. +block.thorium-wall.description = Megvédi az épületeket az ellenséges lövedékektől. +block.thorium-wall-large.description = Megvédi az épületeket az ellenséges lövedékektől. +block.phase-wall.description = Megvédi az épületeket az ellenséges lövedékektől, a legtöbb lövedék visszapattan róla. +block.phase-wall-large.description = Megvédi az épületeket az ellenséges lövedékektől, a legtöbb lövedék visszapattan róla. +block.surge-wall.description = Megvédi az épületeket az ellenséges lövedékektől, periodikusan elektromos kisüléseket generál, ha hozzáérnek. +block.surge-wall-large.description = Megvédi az épületeket az ellenséges lövedékektől, periodikusan elektromos kisüléseket generál, ha hozzáérnek. +block.door.description = Fal, amit nyitni és zárni lehet. +block.door-large.description = Fal, amit nyitni és zárni lehet. De ez nagyobb. +block.mender.description = Javítja az épületeket a hatókörén belül.\nSzilíciummal növelhető a hatósugara és hatékonysága. +block.mend-projector.description = Javítja az épületeket a hatókörén belül.\nSzilíciummal növelhető a hatósugara és hatékonysága. +block.overdrive-projector.description = Növeli a közeli épületek sebességét.\nPhase fabric-kal növelhető a hatósugara és hatékonysága. block.force-projector.description = Creates a hexagonal force field around itself, protecting buildings and units inside from damage.\nOverheats if too much damage is sustained. Optionally uses coolant to prevent overheating. Phase fabric increases shield size. -block.shock-mine.description = Releases electric arcs upon enemy unit contact. -block.conveyor.description = Transports items forward. -block.titanium-conveyor.description = Transports items forward. Faster than a standard conveyor. -block.plastanium-conveyor.description = Transports items forward in batches. Accepts items at the back, and unloads them in three directions at the front. Requires multiple loading and unloading points for peak throughput. -block.junction.description = Acts as a bridge for two crossing conveyor belts. -block.bridge-conveyor.description = Transports items over terrain or buildings. -block.phase-conveyor.description = Instantly transports items over terrain or buildings. Longer range than the item bridge, but requires power. -block.sorter.description = If an input item matches the selection, it passes forward. Otherwise, the item is outputted to the left and right. -block.inverted-sorter.description = Similar to a standard sorter, but outputs selected items to the sides instead. -block.router.description = Distributes input items to 3 output directions equally. -block.router.details = A necessary evil. Using next to production inputs is not advised, as they will get clogged by output. -block.distributor.description = Distributes input items to 7 output directions equally. -block.overflow-gate.description = Only outputs items to the left and right if the front path is blocked. Cannot be used next to other gates. -block.underflow-gate.description = Opposite of an overflow gate. Outputs to the front if the left and right paths are blocked. Cannot be used next to other gates. -block.mass-driver.description = Long-range item transport structure. Collects batches of items and shoots them to other mass drivers. -block.mechanical-pump.description = Pumps and outputs liquids. Does not require power. -block.rotary-pump.description = Pumps and outputs liquids. Requires power. -block.thermal-pump.description = Pumps and outputs liquids. -block.conduit.description = Moves liquids forward. Used in conjunction with pumps and other conduits. -block.pulse-conduit.description = Moves liquids forward. Transports faster and stores more than standard conduits. -block.plated-conduit.description = Moves liquids forward. Does not accept input from the sides. Does not leak. -block.liquid-router.description = Accepts liquids from one direction and outputs them to up to 3 other directions equally. Can also store a certain amount of liquid. -block.liquid-tank.description = Stores a large amount of liquid. Outputs to all sides, similarly to a liquid router. -block.liquid-junction.description = Acts as a bridge for two crossing conduits. -block.bridge-conduit.description = Transports liquids over terrain or buildings. -block.phase-conduit.description = Transports liquids over terrain or buildings. Longer range than the bridge conduit, but requires power. -block.power-node.description = Transmits power to connected nodes. The node will receive power from or supply power to any adjacent blocks. -block.power-node-large.description = An advanced power node with greater range. -block.surge-tower.description = A long-range power node with fewer available connections. -block.diode.description = Moves battery power in one direction, but only if the other side has less power stored. -block.battery.description = Stores power in times of surplus energy. Outputs power in times of deficit. -block.battery-large.description = Stores power in times of surplus energy. Outputs power in times of deficit. Higher capacity than a regular battery. -block.combustion-generator.description = Generates power by burning flammable materials, such as coal. -block.thermal-generator.description = Generates power when placed in hot locations. -block.steam-generator.description = Generates power by burning flammable materials and converting water to steam. -block.differential-generator.description = Generates large amounts of energy. Utilizes the temperature difference between cryofluid and burning pyratite. -block.rtg-generator.description = Uses the heat of decaying radioactive compounds to produce energy at a slow rate. -block.solar-panel.description = Provides a small amount of power from the sun. -block.solar-panel-large.description = Provides a small amount of power from the sun. More efficient than the standard solar panel. -block.thorium-reactor.description = Generates significant amounts of power from thorium. Requires constant cooling. Will explode violently if insufficient amounts of coolant are supplied. -block.impact-reactor.description = Creates massive amounts of power at peak efficiency. Requires a significant power input to kickstart the process. -block.mechanical-drill.description = When placed on ore, outputs items at a slow pace indefinitely. Only capable of mining basic resources. -block.pneumatic-drill.description = An improved drill, capable of mining titanium. Mines at a faster pace than a mechanical drill. -block.laser-drill.description = Allows drilling even faster through laser technology, but requires power. Capable of mining thorium. -block.blast-drill.description = The ultimate drill. Requires large amounts of power. -block.water-extractor.description = Extracts groundwater. Used in locations with no surface water available. -block.cultivator.description = Cultivates tiny concentrations of atmospheric spores into spore pods. -block.cultivator.details = Recovered technology. Used to produce massive amounts of biomass as efficiently as possible. Likely the initial incubator of the spores now covering Serpulo. -block.oil-extractor.description = Uses large amounts of power, sand and water to drill for oil. -block.core-shard.description = Core of the base. Once destroyed, the sector is lost. -block.core-shard.details = The first iteration. Compact. Self-replicating. Equipped with single-use launch thrusters. Not designed for interplanetary travel. -block.core-foundation.description = Core of the base. Well armored. Stores more resources than a Shard. -block.core-foundation.details = The second iteration. -block.core-nucleus.description = Core of the base. Extremely well armored. Stores massive amounts of resources. -block.core-nucleus.details = The third and final iteration. -block.vault.description = Stores a large amount of items of each type. Contents can be retrieved with an unloader. -block.container.description = Stores a small amount of items of each type. Contents can be retrieved with an unloader. -block.unloader.description = Unloads the selected item from nearby blocks. -block.launch-pad.description = Launches batches of items to selected sectors. -block.duo.description = Fires alternating bullets at enemies. -block.scatter.description = Fires clumps of lead, scrap or metaglass flak at enemy aircraft. -block.scorch.description = Burns any ground enemies close to it. Highly effective at close range. -block.hail.description = Fires small shells at ground enemies over long distances. -block.wave.description = Fires streams of liquid at enemies. Automatically extinguishes fires when supplied with water. -block.lancer.description = Charges and fires powerful beams of energy at ground targets. -block.arc.description = Fires arcs of electricity at ground targets. -block.swarmer.description = Fires homing missiles at enemies. -block.salvo.description = Fires quick salvos of bullets at enemies. -block.fuse.description = Fires three close-range piercing blasts at nearby enemies. -block.ripple.description = Shoots clusters of shells at ground enemies over long distances. -block.cyclone.description = Fires explosive clumps of flak at nearby enemies. -block.spectre.description = Fires large armor-piercing bullets at air and ground targets. -block.meltdown.description = Charges and fires a persistent laser beam at nearby enemies. Requires coolant to operate. +block.shock-mine.description = Elektromos kisülést hoz létre, ha ellenséggel érintkezik. +block.conveyor.description = Futószalag. Nyersanyagokat továbbít. +block.titanium-conveyor.description = Nyersanyagokat továbbít. Gyorsabb a sima futószalagnál. +block.plastanium-conveyor.description = Nyersanyagokat szállít tömbösítve. Hátulról fogadja a nyersanyagokat, elöl három irányba szétosztja őket. Több kezdő- és végponttal növelhető az áteresztőképessége. +block.junction.description = Hídként működik két kereszteződő futószalag között. +block.bridge-conveyor.description = Nyersanyagokat szállít épületek és terepakadályok fölött. +block.phase-conveyor.description = Nyersanyagokat szállít épületek és terepakadályok fölött. Nagyobb távolságra ér, mint a sima bridge conveyor, de áramot használ. +block.sorter.description = Csak a kiválasztott nyersanyagot engedi tovább egyenesen, minden mást oldalra ad ki. +block.inverted-sorter.description = A kiválasztott nyersanyagot oldalra adja ki, minden mást egyenesen enged tovább. +block.router.description = Háromfelé osztja szét a beérkező nyersanyagokat. +block.router.details = Pokoli masina. Ne tedd közvetlenül gyárak mellé, mert az épületek termékei eltömítik. +block.distributor.description = Hétfelé osztja szét a beérkező nyersanyagokat. +block.overflow-gate.description = Csak akkor ad ki nyersanyagot oldalra, ha előrefelé már nem tud. Nem használható közvetlenül owerflow gate vagy underflow gate mellett. +block.underflow-gate.description = Csak akkor enged tovább nyersanyagokat előre, ha oldalra már nem tudja kiadni őket. Nem használható közvetlenül owerflow gate vagy underflow gate mellett. +block.mass-driver.description = Nagy hatótávolságú nyeranyagszállító. Csomagokban lő át nyersanyagokat egy másik mass drivernek. +block.mechanical-pump.description = Folyadékot szivattyúz. Nem igényel áramot. +block.rotary-pump.description = Folyadékot szivattyúz. Árammal működik. +block.thermal-pump.description = Folyadékot szivattyúz. Sokat termel, sok áramot fogyaszt. +block.conduit.description = Folyadékot továbbít. +block.pulse-conduit.description = Folyadékot továbbít. Gyorsabb és nagyobb tárolókapacitású, mint a sima conduit. +block.plated-conduit.description = Folyadékot továbbít. Nem fogad el folyadékot oldalról. Nem önti ki a folyadékot, ha nincs a végén semmi. +block.liquid-router.description = Háromfelé osztja szét a beérkező folyadékot. Bizonyos mennyiség tárolására is képes. +block.liquid-tank.description = Nagy mennyiségű folyadékot tárol, minden oldalán képes leadni. +block.liquid-junction.description = Hídként működik két kereszteződő conduit között. +block.bridge-conduit.description = Folyadékot szállít épületek és terepakadályok fölött. +block.phase-conduit.description = Folyadékot szállít épületek és terepakadályok fölött. Nagyobb távolságr ér, mint a sima bridge conduit, de áramot használ. +block.power-node.description = Áramot továbbít az összekapcsolt épületekhez. Az érintkező épületekkel automatikusan kapcsolatban van. +block.power-node-large.description = Nagyobb power node nagyobb hatótávolsággal. +block.surge-tower.description = Hosszútávú power node, csak kevés kapcsolatra képes. +block.diode.description = Tárolt áramot irányít át egy irányba, de csak ha a fogadó oldalon van kevesebb tárolva. +block.battery.description = Áramot raktároz el, ha túltermelés van. Leadja az áramot, ha hiány van. +block.battery-large.description = Áramot raktároz el, ha túltermelés van. Leadja az áramot, ha hiány van. Nagyobb kapacitású a sima battery-nél. +block.combustion-generator.description = Áramot termel éghető anyagok elégetésével. +block.thermal-generator.description = Forró környezetben áramot termel. +block.steam-generator.description = Áramot termel éghető anyagok elégetésével és víz gőzzé alakításával. +block.differential-generator.description = Egy lórúgásnyi áramot termel. Hasznosítja a cryofluid és az égő piratit hőmérsékletkülönbségét. +block.rtg-generator.description = A radioaktív bomlás energiáját hasznosítja, hogy lassan de biztosan áramot termeljen. +block.solar-panel.description = Napfényből állít elő kevés áramot. +block.solar-panel-large.description = Napfényből állít elő kevés áramot. Hatékonyabb a sima solar panelnél. +block.thorium-reactor.description = Jelentős áramot állít elő tóriumból. Állandó hűtést igényel. Ha túlmelegszik, felrobban. +block.impact-reactor.description = Csúcsra járatva rengeteg áramot termel. Jelentős árambefektetést igényel a reakció beindításához. +block.mechanical-drill.description = Ércre helyezve kis tempóban termeli ki az adott nyersanyagot. Csak alapvető nyersanyagok kitermelésére képes. +block.pneumatic-drill.description = Egy fejlettebb drill, képes titán kitermelésére. Gyorsabban dolgozik a mechanical drillnél. +block.laser-drill.description = Lézerek használatával még gyorsabban tud dolgozni, de áramot használ. Képes tóriumot kitermelni. +block.blast-drill.description = A technológia csúcsa. Rengeteg áramot használ. +block.water-extractor.description = Képes a talajvíz kiszívására. Használd, ha nincs elérhető víz a felszínen. +block.cultivator.description = A légkörben szálló spórákat kapszulákba sűríti. +block.cultivator.details = Visszaszerzett technológia. Hatalmas tömegű biomassza gyártására alkalmas a lehető leghatékonyabban. Valószínűleg a Serpulót ma borító spórák kezdeti inkubátora. +block.oil-extractor.description = Nagy mennyiségben használ vizet, homokot és áramot, hogy olajat nyerjen ki a földből. +block.core-shard.description = A bázis magja. Ha elpusztul, a szektor elveszett. +block.core-shard.details = Az első modell. Kompakt. Önsokszorosító. Egyszer használatós gyorsítófúvókákkal van felszerelve, nem bolygóközi utazásra tervezték. +block.core-foundation.description = A bázis magja. Páncélozott. Több nyersanyagot tárol, mint a shard. +block.core-foundation.details = A második modell. +block.core-nucleus.description = A bázis magja. Megerősített páncélzat. Hatalmas mennyiségek tárolására képes. +block.core-nucleus.details = A harmadik, végső modell. +block.vault.description = Nagy mennyiséget tárol minden nyersanyagtípusból. A tartalma unloader segítségével nyerhető ki. +block.container.description = Kis mennyiséget tárol minden nyersanyagtípusból. A tartalma unloader segítségével nyerhető ki. +block.unloader.description = Kitölti a szomszédos épületekből a kiválasztott nyersanyagot. +block.launch-pad.description = Nyersanyagokat juttat el más szektorokba. +block.duo.description = Változatos lövedékekkel lő az ellenségre. +block.scatter.description = Ólom, ólomüveg vagy hulladék darabokkal tüzel az ellenséges légierőre. +block.scorch.description = Megégeti az ellenség közeli földi egységeit. Kis távolságra nagyon hatékony. +block.hail.description = Kis lemezeketFires small shells at ground enemies over long distances. +block.wave.description = Folyadékot önt az ellenségre. Eloltja a tüzet, ha vízzel van feltöltve. +block.lancer.description = Erős energiasugarakat lő közeli földi célpontokra. +block.arc.description = Elektromos szikrákat kelt földi célpontok között. +block.swarmer.description = Nyomkövető rakétákat lő az ellenségre. +block.salvo.description = Kis sorozatokat lő az ellenségre. +block.fuse.description = Három kis hatótávú átütő töltényt lő egyszerre. +block.ripple.description = Lövedékek csoportjával tüzel földi célpontokra nagy távolságra. +block.cyclone.description = Robbanó lövedékeket lő közeli ellenségekre. +block.spectre.description = Nagy, a páncélon is áthatoló lövedékekkel tüzel légi és földi célpontokra is. +block.meltdown.description = Feltöltődés után folyamatos lézersugarat lő a közeli ellenségekre. Hűtést igényel. block.foreshadow.description = Fires a large single-target bolt over long distances. -block.repair-point.description = Continuously repairs the closest damaged unit in its vicinity. -block.segment.description = Damages and destroys incoming projectiles. Laser projectiles are not targeted. -block.parallax.description = Fires a tractor beam that pulls in air targets, damaging them in the process. -block.tsunami.description = Fires powerful streams of liquid at enemies. Automatically extinguishes fires when supplied with water. -block.silicon-crucible.description = Refines silicon from sand and coal, using pyratite as an additional heat source. More efficient in hot locations. -block.disassembler.description = Separates slag into trace amounts of exotic mineral components at low efficiency. Can produce thorium. -block.overdrive-dome.description = Increases the speed of nearby buildings. Requires phase fabric and silicon to operate. -block.payload-conveyor.description = Moves large payloads, such as units from factories. -block.payload-router.description = Splits input payloads into 3 output directions. -block.command-center.description = Controls unit behavior with several different commands. -block.ground-factory.description = Produces ground units. Output units can be used directly, or moved into reconstructors for upgrading. -block.air-factory.description = Produces air units. Output units can be used directly, or moved into reconstructors for upgrading. -block.naval-factory.description = Produces naval units. Output units can be used directly, or moved into reconstructors for upgrading. -block.additive-reconstructor.description = Upgrades inputted units to the second tier. -block.multiplicative-reconstructor.description = Upgrades inputted units to the third tier. -block.exponential-reconstructor.description = Upgrades inputted units to the fourth tier. -block.tetrative-reconstructor.description = Upgrades inputted units to the fifth and final tier. -block.switch.description = A toggleable switch. State can be read and controlled with logic processors. -block.micro-processor.description = Runs a sequence of logic instructions in a loop. Can be used to control units and buildings. -block.logic-processor.description = Runs a sequence of logic instructions in a loop. Can be used to control units and buildings. Faster than the micro processor. -block.hyper-processor.description = Runs a sequence of logic instructions in a loop. Can be used to control units and buildings. Faster than the logic processor. -block.memory-cell.description = Stores information for a logic processor. -block.memory-bank.description = Stores information for a logic processor. High capacity. -block.logic-display.description = Displays arbitrary graphics from a logic processor. -block.large-logic-display.description = Displays arbitrary graphics from a logic processor. -block.interplanetary-accelerator.description = A massive electromagnetic railgun tower. Accelerates cores to escape velocity for interplanetary deployment. +block.repair-point.description = Folyamatosan gyógyítja a legközelebbi sérült egységet a körzetében. +block.segment.description = Megsemmisíti a beérkező lövedékeket. A lézerrel szemben hatástalan. +block.parallax.description = Vonónyalábot bocsát ki, amivel magához vonzza és sebzi a repülő egységeket. +block.tsunami.description = Erős folyadékhullámokat lő az ellenségre. Eloltja a tüzet, ha vízzel van feltöltve. +block.silicon-crucible.description = Szilíciumot finomít homokból és szénből, piratitot használ kiegészítő hőforrásként. Forró környezetben hatékonyabb. +block.disassembler.description = Ritka ásványi elemeket választ ki salakból. Képes tóriumot kiválasztani. +block.overdrive-dome.description = Megnöveli a környező épületek sebességét. Phase fabricot és szilíciumot igényel. +block.payload-conveyor.description = Képes egységeket továbbítani. +block.payload-router.description = Háromfelé osztja szét a beérkező egységeket. +block.command-center.description = Néhány paranccsal képes az egységeket irányítani. +block.ground-factory.description = Földi egységeket gyárt. A kész egységek használhatók azonnal, vagy reconstructorokban fejleszthetők. +block.air-factory.description = Légi egységeket gyárt. A kész egységek használhatók azonnal, vagy reconstructorokban fejleszthetők. +block.naval-factory.description = Vízi egységeket gyárt. A kész egységek használhatók azonnal, vagy reconstructorokban fejleszthetők. +block.additive-reconstructor.description = Kettes szintre fejleszti a beérkező egységeket. +block.multiplicative-reconstructor.description = Hármas szintre fejleszti a beérkező egységeket. +block.exponential-reconstructor.description = Négyes szintre fejleszti a beérkező egységeket. +block.tetrative-reconstructor.description = Ötös szintre fejleszti a beérkező egységeket. +block.switch.description = Kétállású kapcsoló. Az állapota leolvasható és módosítható processzorokkal. +block.micro-processor.description = Logikai műveletek sorozatát hajtja végre végtelenítve. Használható egységek vagy épületek irányítására is. +block.logic-processor.description = Logikai műveletek sorozatát hajtja végre végtelenítve. Használható egységek vagy épületek irányítására is. Gyorsabb a micro processornál. +block.hyper-processor.description = Logikai műveletek sorozatát hajtja végre végtelenítve. Használható egységek vagy épületek irányítására is. Gyorsabb a logic processornál. +block.memory-cell.description = Információt tárol processzorok számára. +block.memory-bank.description = Információt tárol processzorok számára. Nagyobb kapacitású. +block.logic-display.description = Ábrák rajzolhatók rá processzorral. +block.large-logic-display.description = Ábrák rajzolhatók rá processzorral. +block.interplanetary-accelerator.description = Hatalmas elektromágneses gyorsítótorony. Képes magokat szökési sebességre gyorsítani bolygóközi bevetéshez. + +unit.dagger.description = Egyszerű töltényeket lő közeli ellenségekre +unit.mace.description = Lángnyelveket küld a közeli ellenségek felé. +unit.fortress.description = Nagy hatótávú rakétákat lő földi célpontokra. +unit.scepter.description = Töltött lövedékek záporát lövi közeli ellenségekre. +unit.reign.description = Méretes átütő lövedékeket zúdít minden közeli ellenségre. +unit.nova.description = Lézereket lő, amik az ellenséget sebzik, de gyógyítják a szövetségeseket. Repülésre alkalmas. +unit.pulsar.description = Elektromos szikrákat indít, amik az ellenséget sebzik, de gyógyítják a szövetségeseket. Repülésre alkalmas. +unit.quasar.description = Átütő lézersugarakat lő, amik az ellenséget sebzik, de gyógyítják a szövetségeseket. Repülésre alkalmas. Pajzsa van. +unit.vela.description = Folyamatos lézernyalábot bocsát ki, ami sebzi az ellenséget, felgyújtja az épületeiket, de gyógyítja a szövetségeseket. Repülésre alkalmas. +unit.corvus.description = Hatalmas lézersugarat lő, ami ami sebzi az ellenséget, de gyógyítja a szövetségeseket. A legtöbb terepakadályt átlépi. +unit.crawler.description = Az ellenséghez rohan és nagy robbanásban megsemmisíti magát. +unit.atrax.description = Gyengítő salakgolyókat lő a földi célpontokra. A legtöbb terepakadályt átlépi. +unit.spiroct.description = Elszívja az ellenség életerejét, önmagát gyógyítva közben. A legtöbb terepakadályt átlépi. +unit.arkyid.description = Nagy lézernyalábokkal elszívja az ellenség életerejét, önmagát gyógyítva közben. A legtöbb terepakadályt átlépi. +unit.toxopid.description = Nagy elektromos bombákat és átütő lézert lő az ellenségre. A legtöbb terepakadályt átlépi. +unit.flare.description = Egyszerű töltényeket lő közeli földi célpontokra. +unit.horizon.description = Bombákat szór földi célpontokra. +unit.zenith.description = Rakétasorozatokat lő közeli ellenségekre. +unit.antumbra.description = Lövedékek záporát zúdítja minden közeli ellenségre. +unit.eclipse.description = Két átütő lézersugarat és rengeteg lövedéket zúdít minden közeli ellenségre. +unit.mono.description = Automatikusan bányászik rezet és ólmot a magba juttatva őket. +unit.poly.description = Automatikusan újjáépíti az elpusztult épületeket és segít más egységeknek építkezni. +unit.mega.description = Automatikusan javítja a sérült épületeket. Képes kis épülete és földi egységek szállítására. +unit.quad.description = Nagy bombákat szór földi célpontokra, amik sebzik az ellenséget, de javítják a szövetséges épületeket. Képes közepes méretű földi egységek szállítására. +unit.oct.description = Megvédi a közeli szövetségeseket regeneráló pajzsával. Képes szállítani a legtöbb földi egységet. +unit.risso.description = Rakéták és lövedékek záporát zúdítja minden közeli ellenségre. +unit.minke.description = Tüzérségi lövedékeket és egyszerű töltényeket lő közeli föld célpontokra. +unit.bryde.description = Nagytávolságú tüzérségi rakétákat lő az ellenségre. +unit.sei.description = Rakéták és páncéltörő lövedékek záporát zúdítja az ellenségre. +unit.omura.description = Nagy hatótávolságú átütő lövedékeket lő az ellenségre. Flare egységeket gyárt. +unit.alpha.description = Megvédi a Shard core-t az ellenségtől. Épít. +unit.beta.description = Megvédi a Foundation core-t az ellenségtől. Épít. +unit.gamma.description = Megvédi a Nucleus core-t az ellenségtől. Épít. -unit.dagger.description = Fires standard bullets at all nearby enemies. -unit.mace.description = Fires streams of flame at all nearby enemies. -unit.fortress.description = Fires long-range artillery at ground targets. -unit.scepter.description = Fires a barrage of charged bullets at all nearby enemies. -unit.reign.description = Fires a barrage of massive piercing bullets at all nearby enemies. -unit.nova.description = Fires laser bolts that damage enemies and repair allied structures. Capable of flight. -unit.pulsar.description = Fires arcs of electricity that damage enemies and repair allied structures. Capable of flight. -unit.quasar.description = Fires piercing laser beams that damage enemies and repair allied structures. Capable of flight. Shielded. -unit.vela.description = Fires a massive continuous laser beam that damages enemies, causes fires and repairs allied structures. Capable of flight. -unit.corvus.description = Fires a massive laser blast that damages enemies and repairs allied structures. Can step over most terrain. -unit.crawler.description = Runs toward enemies and self-destructs, causing a large explosion. -unit.atrax.description = Fires debilitating orbs of slag at ground targets. Can step over most terrain. -unit.spiroct.description = Fires sapping laser beams at enemies, repairing itself in the process. Can step over most terrain. -unit.arkyid.description = Fires large sapping laser beams at enemies, repairing itself in the process. Can step over most terrain. -unit.toxopid.description = Fires large electric cluster-shells and piercing lasers at enemies. Can step over most terrain. -unit.flare.description = Fires standard bullets at nearby ground targets. -unit.horizon.description = Drops clusters of bombs on ground targets. -unit.zenith.description = Fires salvos of missiles at all nearby enemies. -unit.antumbra.description = Fires a barrage of bullets at all nearby enemies. -unit.eclipse.description = Fires two piercing lasers and a barrage of flak at all nearby enemies. -unit.mono.description = Automatically mines copper and lead, depositing it into the core. -unit.poly.description = Automatically rebuilds destroyed structures and assists other units in construction. -unit.mega.description = Automatically repairs damaged structures. Capable of carrying blocks and small ground units. -unit.quad.description = Drops large bombs on ground targets, repairing allied structures and damaging enemies. Capable of carrying medium-sized ground units. -unit.oct.description = Protects nearby allies with its regenerating shield. Capable of carrying most ground units. -unit.risso.description = Fires a barrage of missiles and bullets at all nearby enemies. -unit.minke.description = Fires shells and standard bullets at nearby ground targets. -unit.bryde.description = Fires long-range artillery shells and missiles at enemies. -unit.sei.description = Fires a barrage of missiles and armor-piercing bullets at enemies. -unit.omura.description = Fires a long-range piercing railgun bolt at enemies. Constructs flare units. -unit.alpha.description = Defends the Shard core from enemies. Builds structures. -unit.beta.description = Defends the Foundation core from enemies. Builds structures. -unit.gamma.description = Defends the Nucleus core from enemies. Builds structures. From 51f7858b78a3da8cdf4693f5d0b963ca69b6f66e Mon Sep 17 00:00:00 2001 From: BlueTechno <69437358+BlueThecno@users.noreply.github.com> Date: Fri, 5 Mar 2021 12:30:45 -0400 Subject: [PATCH 402/426] Added "armor" and "buildingdamage" stats (#4794) Also fixed the description of the separator (so it matches the english description) --- core/assets/bundles/bundle_es.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index ffe4a20976..e9d0f796e3 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -678,6 +678,7 @@ stat.drillspeed = Velocidad del Taladro stat.boosteffect = Efecto de Potenciador stat.maxunits = Máximo de Unidades Activas stat.health = Vida +stat.armor = Armadura stat.buildtime = Tiempo de construcción stat.maxconsecutive = Máximo consecutivo stat.buildcost = Coste de construcción @@ -745,6 +746,7 @@ bullet.sapping = [stat]Oxidante bullet.homing = [stat]Rastreadora bullet.shock = [stat]Electrizante bullet.frag = [stat]De fragmentación +bullet.buildingdamage = [stat]{0}%[lightgray]daño a estructuras bullet.knockback = [stat]{0}[lightgray] Empuje bullet.pierce = [stat]{0}[lightgray]x penetración bullet.infinitepierce = [stat]Penetrante @@ -1337,7 +1339,7 @@ block.cryofluid-mixer.description = Combina agua y titanio en líquido criogéni block.blast-mixer.description = Usa esporas para transformar pirotita en un objeto menos inflamable pero más explosivo: el compuesto explosivo. block.pyratite-mixer.description = Mezcla carbón, plomo y arena en pirotita altamente inflamable. block.melter.description = Calienta chatarra a temperaturas muy altas para obtener magma. -block.separator.description = Expone piedra a la presión del agua para obtener diversos minerales contenidos en la piedra. +block.separator.description = Separa el magma en sus componentes minerales. block.spore-press.description = Comprime esporas en petróleo. block.pulverizer.description = Despedaza la chatarra en arena. Útil cuando no hay arena natural. block.coal-centrifuge.description = Solidifica petróleo en piezas de carbón. From 0ec71750b76017da24589324b8c5644026560565 Mon Sep 17 00:00:00 2001 From: YellOw139 <70975516+YellOw139@users.noreply.github.com> Date: Fri, 5 Mar 2021 18:30:55 +0200 Subject: [PATCH 403/426] [Bundle][RO] Update (#4750) * [Bundle][RO] Update This PR was tested in-game and is ready to merge at any time. Changelog: - New strings/changes up to commit f78719afc0e9799a385fde2db9ec4650f3f3fb39 - Typo fixes & various other improvements * WIP * typo * Speaking logically * Update core/assets/bundles/bundle_ro.properties Co-authored-by: MLGTASTICa <61350382+MLGTASTICa@users.noreply.github.com> * Opted for a better term: controlor, not controller * double-tap * Times joined & kicked Co-authored-by: MLGTASTICa <61350382+MLGTASTICa@users.noreply.github.com> --- core/assets/bundles/bundle_ro.properties | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index d8372d10eb..9656c15111 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -216,9 +216,11 @@ server.hidden = Ascunse trace = Urmărește Jucător trace.playername = Nume jucător: [accent]{0} trace.ip = IP: [accent]{0} -trace.id = ID unic: [accent]{0} +trace.id = ID: [accent]{0} trace.mobile = Client Mobil: [accent]{0} trace.modclient = Client Personalizat: [accent]{0} +trace.times.joined = A Intrat: de [accent]{0}[] ori +trace.times.kicked = Dat Afară: de [accent]{0}[] ori invalidid = ID client invalid! Raportează bugul. server.bans = Interziși server.bans.none = Nu s-au găsit jucători intreziși! @@ -800,6 +802,7 @@ setting.logichints.name = Indicii Procesoare Logice setting.flow.name = Afișează Rata de Curgere a lichidelor setting.buildautopause.name = Autopauză de la Construit setting.backgroundpause.name = Pune Pauză în Fundal +setting.doubletapmine.name = Dublu-Click pt a Mina setting.modcrashdisable.name = Dezactivează Modurile în Cazul unui Crash la Pornire setting.animatedwater.name = Suprafețe Animate setting.animatedshields.name = Scuturi Animate @@ -1537,16 +1540,22 @@ lst.unitcontrol = Controlează unitatea controlată de procesor. lst.unitradar = Localizează unitățile din jurul unității controlate de procesor. lst.unitlocate = Localizează o poziție/clădire specifică oriunde pe hartă.\nNecesită o unitate controlată de procesor. +logic.nounitbuild = [red]Nu ai voie să construiești cu unitățile folosind procesoare. + lenum.type = Tipul clădirii/unității.\nde ex.: pt orice Router, va returna [accent]@router[].\nNu e un șir de caractere. lenum.shoot = Lovește către o locație. lenum.shootp = Lovește către o unitate/clădire. Anticipează viteza țintei și a proiectilului. -lenum.configure = Configurașia clădirii, de ex. materialul selectat pt Sortator. +lenum.configure = Configurația clădirii, de ex. materialul selectat pt Sortator. lenum.enabled = Specifică dacă clădirea este pornită. laccess.color = Culoarea iluminatorului. +laccess.controller = Controlorul unității. Dacă e controlată de procesor, returnează procesorul.\nDacă e într-o formație, returnează liderul.\nAltfel, returnează unitatea însăși. +laccess.dead = Specifică dacă o unitate sau clădire a murit/nu mai e validă. +laccess.controlled = Returnează:\n[accent]@ctrlProcessor[] dacă controlorul unității e procesor\n[accent]@ctrlPlayer[] dacă controlorul unității/clădirii e jucător\n[accent]@ctrlFormation[] dacă unitatea e într-o formație\nAltfel dă 0. +laccess.commanded = [red]Învechit. Se va șterge![]\nFolosește [accent]controlled[]. graphicstype.clear = Umple monitorul cu o culoare. -graphicstype.color = Setează culoarea pt următoarea instrucțiune Draw. +graphicstype.color = Setează culoarea pt următoarele instrucțiuni Draw. graphicstype.stroke = Setează grosimea liniei. graphicstype.line = Desenează un segment de linie. graphicstype.rect = Desenează un dreptunghi. @@ -1579,7 +1588,7 @@ lenum.sin = Sinus în grade. lenum.cos = Cosinus în grade. lenum.tan = Tangentă în grade. #cea de mai jos nu-i o greșeală, caută pe net notarea intervalelor în matematică -lenum.rand = Număr aleatoriu în intervalul [0, val). +lenum.rand = Număr natural aleatoriu în intervalul [0, val). lenum.log = Logaritm natural (ln). lenum.log10 = Logaritm în baza 10. lenum.noise = 2D simplex noise. @@ -1637,6 +1646,7 @@ unitlocate.outx = Coordonata X a obiectului detectat. unitlocate.outy = Coordonata Y a obiectului detectat. unitlocate.group = Grupul clădirilor de detectat. +lenum.idle = Nu mișca, dar continuă să construiești/minezi.\nModul prestabilit. lenum.stop = Oprește acțiunea curentă. Nu mișca/mina/construi. lenum.move = Mergi la această poziție. lenum.approach = Apropie-te la o anumită distanță de poziție. From fb2fed7c28c77fb08e331c0ab8e8101a1444d67f Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 11:36:11 -0500 Subject: [PATCH 404/426] mod.multiplayer.compatible RU --- core/assets/bundles/bundle_ru.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index b1e14dcbd2..75d8141d9e 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -126,7 +126,7 @@ mod.installed = [[Установлено] mod.display = [gray]Модификация:[orange] {0} mod.enabled = [lightgray]Включён mod.disabled = [scarlet]Выключен -mod.multiplayercompatable = [gray]Доступен в игре по сети +mod.multiplayer.compatible = [gray]Доступен в игре по сети mod.disable = Выкл. mod.content = Содержимое: mod.delete.error = Невозможно удалить модификацию. Возможно, файл используется. From 545b75a091f409d889b31356f7740c90c04f27a1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 11:38:57 -0500 Subject: [PATCH 405/426] =?UTF-8?q?[=D0=9C=D0=BE=D0=B4=D0=B8=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=D1=86=D0=B8=D1=8F]=20=D0=94=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=83=D0=BF=D0=B5=D0=BD=20->=20=D0=94=D0=BE=D1=81=D1=82=D1=83?= =?UTF-8?q?=D0=BF=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/assets/bundles/bundle_ru.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 75d8141d9e..6c04b75855 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -126,7 +126,7 @@ mod.installed = [[Установлено] mod.display = [gray]Модификация:[orange] {0} mod.enabled = [lightgray]Включён mod.disabled = [scarlet]Выключен -mod.multiplayer.compatible = [gray]Доступен в игре по сети +mod.multiplayer.compatible = [gray]Доступна в игре по сети mod.disable = Выкл. mod.content = Содержимое: mod.delete.error = Невозможно удалить модификацию. Возможно, файл используется. From d6f00a5d2da3be73214aab9df655c393b40c1a81 Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Fri, 5 Mar 2021 11:59:44 -0500 Subject: [PATCH 406/426] Remove dead servers from v5 server list (#4858) From what I can see, atnanner is the only network that still hosts any v5 servers, all the others are either on v6 or are offline. --- servers.json | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/servers.json b/servers.json index 49e3ddf346..fa12fdd56f 100644 --- a/servers.json +++ b/servers.json @@ -1,34 +1,4 @@ [ - { - "address": "mindustry.indielm.com:1101" - }, - { - "address": "mindustry.indielm.com" - }, - { - "address": "v5.mindustry.nydus.app:6565" - }, - { - "address": "mindustry.ru" - }, - { - "address": "mindustry.ru:7000" - }, - { - "address": "Mindustry.pl" - }, - { - "address": "aamindustry.play.ai" - }, - { - "address": "aamindustry.play.ai:6568" - }, - { - "address": "aamindustry.play.ai:6569" - }, - { - "address": "aamindustry.play.ai:6570" - }, { "address": "mindustry.atannergaming.com" }, @@ -40,23 +10,5 @@ }, { "address": "mindustry.atannergaming.com:6800" - }, - { - "address": "mindustry.kbni.net.au:6567" - }, - { - "address": "mindustry.kbni.net.au:6568" - }, - { - "address": "twsmindustry.24x7.hk" - }, - { - "address": "twsmindustry.24x7.hk:6568" - }, - { - "address": "mindustryranked.ddns.net" - }, - { - "address": "attack.pearkin.net" } ] From dce79a621a82f701604f3c0c7c644fe295c50e19 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 12:06:40 -0500 Subject: [PATCH 407/426] Close connections immediately on kick --- core/src/mindustry/net/NetConnection.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/net/NetConnection.java b/core/src/mindustry/net/NetConnection.java index 02b1c1649d..be2455c53a 100644 --- a/core/src/mindustry/net/NetConnection.java +++ b/core/src/mindustry/net/NetConnection.java @@ -49,7 +49,7 @@ public abstract class NetConnection{ Call.kick(this, reason); - Time.runTask(2f, this::close); + close(); netServer.admins.save(); kicked = true; @@ -70,7 +70,7 @@ public abstract class NetConnection{ Call.kick(this, reason); - Time.runTask(2f, this::close); + close(); netServer.admins.save(); kicked = true; From 4690aae19781374a2ee6f95a5b5b8f33d0abc1b5 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 14:00:53 -0500 Subject: [PATCH 408/426] Fixed cores being replaceable --- core/src/mindustry/entities/comp/BuildingComp.java | 2 +- core/src/mindustry/entities/comp/UnitComp.java | 6 +++++- core/src/mindustry/logic/GlobalConstants.java | 8 +++++--- core/src/mindustry/world/Block.java | 4 +++- core/src/mindustry/world/blocks/storage/CoreBlock.java | 1 + gradle.properties | 2 +- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index dfa7fd75cc..694611fed3 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1325,7 +1325,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored(); case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity(); case enabled -> enabled ? 1 : 0; - case controlled -> this instanceof ControlBlock c && c.isControlled() ? 2 : 0; + case controlled -> this instanceof ControlBlock c && c.isControlled() ? GlobalConstants.ctrlPlayer : 0; case payloadCount -> getPayload() != null ? 1 : 0; case size -> block.size; default -> Float.NaN; //gets converted to null in logic diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index bd251d4d3b..1db14dcc41 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -139,7 +139,11 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case mineX -> mining() ? mineTile.x : -1; case mineY -> mining() ? mineTile.y : -1; case flag -> flag; - case controlled -> !isValid() ? 0 : controller instanceof LogicAI ? 1 : controller instanceof Player ? 2 : controller instanceof FormationAI ? 3 : 0; + case controlled -> !isValid() ? 0 : + controller instanceof LogicAI ? GlobalConstants.ctrlProcessor : + controller instanceof Player ? GlobalConstants.ctrlPlayer : + controller instanceof FormationAI ? GlobalConstants.ctrlFormation : + 0; case commanded -> controller instanceof FormationAI && isValid() ? 1 : 0; case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; case size -> hitSize / tilesize; diff --git a/core/src/mindustry/logic/GlobalConstants.java b/core/src/mindustry/logic/GlobalConstants.java index be0500bc77..b13c658611 100644 --- a/core/src/mindustry/logic/GlobalConstants.java +++ b/core/src/mindustry/logic/GlobalConstants.java @@ -9,6 +9,8 @@ import mindustry.world.*; /** Stores global constants for logic processors. */ public class GlobalConstants{ + public static final int ctrlProcessor = 1, ctrlPlayer = 2, ctrlFormation = 3; + private ObjectIntMap namesToIds = new ObjectIntMap<>(); private Seq vars = new Seq<>(Var.class); @@ -21,9 +23,9 @@ public class GlobalConstants{ //special enums - put("@ctrlProcessor", 1); - put("@ctrlPlayer", 2); - put("@ctrlFormation", 3); + put("@ctrlProcessor", ctrlProcessor); + put("@ctrlPlayer", ctrlPlayer); + put("@ctrlFormation", ctrlFormation); //store base content diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index e40fdbca45..613411e6e0 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -123,6 +123,8 @@ public class Block extends UnlockableContent{ public boolean fillsTile = true; /** whether this block can be replaced in all cases */ public boolean alwaysReplace = false; + /** if false, this block can never be replaced. */ + public boolean replaceable = true; /** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */ public BlockGroup group = BlockGroup.none; /** List of block flags. Used for AI indexing. */ @@ -410,7 +412,7 @@ public class Block extends UnlockableContent{ public boolean canReplace(Block other){ if(other.alwaysReplace) return true; - return (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group && + return other.replaceable && (other != this || rotate) && this.group != BlockGroup.none && other.group == this.group && (size == other.size || (size >= other.size && ((subclass != null && subclass == other.subclass) || group.anyReplace))); } diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index 087ba838fd..45b2ce32d1 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -52,6 +52,7 @@ public class CoreBlock extends StorageBlock{ loopSoundVolume = 1f; drawDisabled = false; canOverdrive = false; + replaceable = false; } @Remote(called = Loc.server) diff --git a/gradle.properties b/gradle.properties index 8d7da5a740..75a3570010 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=e270ac561e10cbc1dc1f13907d75d614e2d51be0 +archash=1b24d685ea94dd40244be869e70671080e950825 From 830fe03898721d726870f1cc39dab5890040ce31 Mon Sep 17 00:00:00 2001 From: Joshua Fan Date: Fri, 5 Mar 2021 11:09:46 -0800 Subject: [PATCH 409/426] Add buildSpeedMultiplier status effect (#4816) * Make disarmed status effect prevent building * Revert disarmed changes, add buildSpeedMultiplier status * Add buildSpeedMultiplier to StatusComp --- core/src/mindustry/entities/comp/BuilderComp.java | 10 +++++----- core/src/mindustry/entities/comp/StatusComp.java | 5 +++-- core/src/mindustry/type/StatusEffect.java | 4 +++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index 12f5428324..c9984f8ea4 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -26,10 +26,10 @@ import java.util.*; import static mindustry.Vars.*; @Component -abstract class BuilderComp implements Posc, Teamc, Rotc{ +abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()}; - @Import float x, y, rotation; + @Import float x, y, rotation, buildSpeedMultiplier; @Import UnitType type; @Import Team team; @@ -41,7 +41,7 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ private transient float buildAlpha = 0f; public boolean canBuild(){ - return type.buildSpeed > 0; + return type.buildSpeed > 0 && buildSpeedMultiplier > 0; } @Override @@ -126,9 +126,9 @@ abstract class BuilderComp implements Posc, Teamc, Rotc{ //otherwise, update it. if(current.breaking){ - entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier); + entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeedMultiplier); }else{ - entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier, current.config); + entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeedMultiplier, current.config); } current.stuck = Mathf.equal(current.progress, entity.progress); diff --git a/core/src/mindustry/entities/comp/StatusComp.java b/core/src/mindustry/entities/comp/StatusComp.java index 58177c5fdb..bce8444361 100644 --- a/core/src/mindustry/entities/comp/StatusComp.java +++ b/core/src/mindustry/entities/comp/StatusComp.java @@ -19,7 +19,7 @@ abstract class StatusComp implements Posc, Flyingc{ private Seq statuses = new Seq<>(); private transient Bits applied = new Bits(content.getBy(ContentType.status).size); - @ReadOnly transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1; + @ReadOnly transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1, buildSpeedMultiplier = 1; @ReadOnly transient boolean disarmed = false; @Import UnitType type; @@ -111,7 +111,7 @@ abstract class StatusComp implements Posc, Flyingc{ } applied.clear(); - speedMultiplier = damageMultiplier = healthMultiplier = reloadMultiplier = 1f; + speedMultiplier = damageMultiplier = healthMultiplier = reloadMultiplier = buildSpeedMultiplier = 1f; disarmed = false; if(statuses.isEmpty()) return; @@ -134,6 +134,7 @@ abstract class StatusComp implements Posc, Flyingc{ healthMultiplier *= entry.effect.healthMultiplier; damageMultiplier *= entry.effect.damageMultiplier; reloadMultiplier *= entry.effect.reloadMultiplier; + buildSpeedMultiplier *= entry.effect.buildSpeedMultiplier; disarmed |= entry.effect.disarm; diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index 2355cbbcaa..3e260bb975 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -15,10 +15,12 @@ public class StatusEffect extends MappableContent{ public float damageMultiplier = 1f; /** Unit health multiplier. */ public float healthMultiplier = 1f; - /** Unit speed multiplier */ + /** Unit speed multiplier. */ public float speedMultiplier = 1f; /** Unit reload multiplier. */ public float reloadMultiplier = 1f; + /** Unit build speed multiplier. */ + public float buildSpeedMultiplier = 1f; /** Unit weapon(s) disabled. */ public boolean disarm = false; /** Damage per frame. */ From 24195dac81c2a9b353b4483351afba6c3064a253 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 14:27:15 -0500 Subject: [PATCH 410/426] Added Voz-Duh's large launch pad sprite (#4861) --- .../blocks/campaign/launch-pad-large.png | Bin 7938 -> 4244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/core/assets-raw/sprites/blocks/campaign/launch-pad-large.png b/core/assets-raw/sprites/blocks/campaign/launch-pad-large.png index ac77dbe43c5d8a1ab3c8e8ac1a22a20d3b775cc7..5eee3591911e0fb069dd4bf8b925677de7f5a1b7 100644 GIT binary patch literal 4244 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

BB+Gcq5Gj9y5u;D6> zbsPs~1&Fs=n8ZaM@ylslzQ;F9@f+K^rkBYgf-%Akrp>J@uJH@p4b|!EE)bDVUh!Od z2UnWd<<1AI7}jW(7IvIwOSDf?pZ0m`XBO#=<^`f>^p*)7EM<%+j+l_OyD`jQ?Y5?B z;pn;Yg<1Q(V$_04>LuB_mAJ3TQtr8ICwA~OYr^3bryb^O zVmRWbQ=o3y;hL8!xcU~?>o3wSAH*1M7`zG+Sgymcar@ieIFU1#4b__dGdpK)bKDZB Sro+I%z~JfX=d#Wzp$P!2c{9NP literal 7938 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4mJh`hQoG=rx_T;k5`36lmsP~D-;yvr)B1( zDwI?fq$;FVWTr7NRNPuSE3-(&I;Z9TXAwK5?@ujalxvvf@5gV7vYj-~rPCaE=)^q{{K4v_#bwA%bht%TBh6Q=-O{Q`pi0iRc+n8@bt%jf4{u&_s`QEmGuuT zMJjmDAKw%Iyu5F@z4(+LR(AX3%v1Nh3ywE0dM|x{{sQ&ae_!wUwJY$$`NHqNa&Eoe zC1>yZ{OkSm*K^~||NpZT>)9yuo%`Mo*_aJ~)>e5{{44LP{P!!s;$>yN^B(s*=eHTZ z-+sU6d)@c5W!v`mwXa`hV7A}y#QmHvR_`utfBf*T#Q#*6cjqVXubH^5+WO1xx91|i z&iQ+0-SM8Kn<{-@C2M_`Rp;}Oe3v@&{-OUzeizkC@1LsaXS40Yvj^o;*XJC+b=-A( zO!@J*zpd`3bX?5u-?{g@u=eYSqkqnxR}gpkyX&!cM&itXk4KJVHy-|HD^@=L_Pft& zlVi#(&wc5eeX{%i4^w;DKl}ge%P;9$@OsYL{AfcxeIH|THjhb%w@tXMu_k*DU;`nFvXdu`O`-+ac|_2lC$@1k=>pCsgZZvQN~ zbGy9W=6m@5nIiwg>pt(VJa?k>zx+JoqPwSy|9`p79~b>MZAyXc5{)UoxfTMqrD~rF z-kvdg`7_H`lG)21F`c(i?A?3m&hB+W59HQ)8b6&Z89(`O)RP})md)Mf{CM@m+N{S3 zPIGp;zlgYW?!xQNxj&uj4L|zNd{cQg{iSZ-%~T)ec02ilK3`Y%MI64f_SxLD?NYaI zYJQ!3Dej)!{JGL=Bhu<6JiS+bJDk$x`Si)eOH!7++uh6d$~sKAwyMhM+3GD$YtHa$ zU)^xMQ-HbGnae*Y@f{gkG?T^CGyAGT%__mf2}f$4N0C~@a@sHJ9n1J zT%MJ8+|pa^NRMrHZqBXnmwy}HUz&Ebz32YNjdMG{=Xj(W_J)MrwoaRWoAXYsu0gf0 z+l8ukRlRHaH*cwJ`0_b3bo<-63zr<)9`3VdMns+d8u8x#vZQH-$K{r<3pwzVWoBvX zq&;`bew^y~c|w9?!al9O0~eLA@4RdC=zZuM&Lhbdl20D>PEL<&|Nc2;-Oa1zPRrL_ z{kx)W&cyQ^5ox9Ggnux6p%T)7RyP_N{a`QW}8+$?6i94 z+{I>QAnj;x+34YUxFt66n}|qVs)_0$leboxbDlM=`SE5}gs-sveT=i#e`*l%guh_ll-rB7lEthNpdF$A(uysZE?w;`JyxOAQuWVV4tax8~SaY@4&hC0UOJH_>LXlDQjcGTZUHIMZTzRU1y}RYw#?|BV9^@9q5%^S1b_>)N;Kx7gg9&L!PBvuV%n z#d@|nH|AL>bQfiBJS4HFwIh4ym7PY1<4hklDRNH~d=OKcFSaveb2jiY;2273M*DTx-z3Y?vaCqVf(?DV!4KS3<{6)KDl0a8~bX)md)CXr=yw- zgjiD^i*z2y(TREfjOEc2aq(`x=o`hy?U(P~du+|a<-uoP-(hpiyEI9OCu)XE#2Kl( zVn-$^Nk2OG)T7?^gC@fjPOa5XDkdD?H#y(wXn~8zI_`f5oo?hFeQ9u@Res%tul!Yo z^5uCKdSo_sKAglO8F(yr#>!JW9CQz!JIZ~0QF;#h0k^5Qr$0Dq+quX$@1DzxkSOK1 z!haq1PmmYXxbsNE>+(Ut;WWUEB}=05(+Wy|z_&j~KcwrZVKmBNAyriolW zNAGtmx}tiDT~*uhU4%NL(XYcN4{p`Dkg(E6hv)Ewg~kcfrv7+)P+@M&#BVbWK7PTu zcfsloSDAwW+>_6TlnAC?^f;fv>8mnR#f|goe4cp@aTD!5J}s%-H`8-tM|^CaidUQ6 z^)!vR3GX%`GtOL#-)H{6?9li3##0!M zEEaK)u(cAZ%zP)I;>*TRtfFBq=k4|RgP+KZ#0i~!O&nA1J@*uvq+#Gyme%84_~G1H zVcmlVTEw(A9x2q9zLfR0Jd$O@t1U~ccM7jOZolZ7a@1OF?vw5Oh6ZQpq?&_Lzl&LfFMPkp>Dct1++ zPd&O;SN*vI9;dJVeUdr+<4zg1fZ0|RJG5nYl?XPZysm z(sq-XUO6;aL@n9RHD}@Pv&APLe_-YMV(?<#X30qwr$4&qPL}pPZPc?<_MUt|;|fRQ<}IGOKla>MUudIZh?ZP6tX{ zVHCe|Hgf;{^d0vZZU$}L{3mqkL$ev8%}RflHBXlRbsmb0F3rNZv;Y-FvpJM=xI(c%7YEnhba_p41A+oA%pvnT6` zn-wiFU-CMknKykXgRE8P<^c6%e48`HJe3u{i67P8@$+ba>}AZ6F&uA zXZwEtMN-)di*DZowv!aDX0+T@5fm3?NH=mYiFqe52PZEMBhS>aoW=n62fS=+usd+FG-ZHD{Lg`yair zJ&Gsb3D?};Ik#>3{`6|_Xa`6IAE@hme*UNHxBu0aZP#_A9Nc1#3a?d}dX`zBPahTr#-p8GdJIDLFKy%LGO;(0gkBsCqmaOK}uk~M^#&GDf;hMAWKRD@5>iBXs?9`EG zuXGZN*SNemb8{ij;$@jmf47Nrr>yqkeHG`WkioKw_vqB8&v&kj`xu}$vG~KU8~L1N z0Xc@j$COzQyO>RK6L`(@{c3JUpHzX4NZ5_}0wFC5PLGXUXXwjJ-0UTKU$uehBww$y zpi%9l2{&dP-|;f|D0{}nRkPw>US8tKw%ki6OykQW-MfcmYEPYr;}*X1&ExfrH?F}+ z7VBhqt~eAeC{dG4e-Ei-uSK&>aPZOo|eKTji zGPGW>>;ZfE!|YPc*eUTR`%k^iPCxV~Gf-vI>PMGTjWYHda`Ccyy;{(-P33;2;?28! zoR51?UD7)Bq32@5>~}`Hs@}cr(s}g5M(Oo5ueZlI&dvB_5VoQ5jiOFYWQzZh-50ew zYNMx$7rnf4CI7l|P(h?mWa!m*@y5a519U4?Qq!I;yT`FzGSTQoy>?)e2?n)$EQ<^QzA`1q}lu8W%U&l5F&m~FW3cf-VK^VnRr2G}j? zF8EZ{_@K!>P;%3uO)jcmRBclC>3(1OjZ1{%$r6rfHuK+#S4Y3@-V?SWF5&3LupW=I zE&<=1L;W2O2`u>Dbo;^O7MtUu=hi-+GdD|llI6l%lG~fz7PVgx3bgwzYw~X2J~!3s zdAz;8GfswbJh6+`3VD{xDca3-f#tWs>1#)er5YI*Y5jQX?91j6#~W(8?ox=zjn|); zYCZ>LFvSHfjum3=)2g;LnQmsbR3g}Vt>M0<;zzFqv@6Pn1Rt1w_`XxzRhegXC+{zr z;`^e*Lgd_Z3y$YiD>=owzpb3J=;!3hgtC!APnYL?kjL((J4t+n{)xSN|30*9-%~3L1Hjgtpfhk4sc|{M4 z+gYv--&U?IZbE;2T54Zhs<&HxVAj3bjF%28oxWOEALW@Nm=LVCGpUU`MeWpA{xfSn zcd8ufR;lxqTCXC0*L}xq`A4#sdzK#M`M!P6!hQA+u6Q4Za=+Jw;cqP;ryn z?zz9rwcgstPu+8F^1)>bH(9KD88Ut1p*L4|n`bIpFPmiMceRGeRVLKc`fpYw@3&>a zyw{%luDQE(QkDDfiE8<8mz&(&_wCJ=33KkbJ!RG3T9lo;S(~-_={2LjZ`s8ROs;hv ze&&Byu=CNC^bO5kvmJuxGbAz^Hy(RBTT#rbjzfTJ;fLRs`!7wdcoul9OY7s7Lq44s zl+PSiQM)x+hAI8KW78k@dwGgiFNU4biTV5TP3#tnU)oN|Z5s7gO6NNVweC>4rge#H zQSH|#K8ab6i?_cIapPmveti2^hV9nLJ3@4n%B7|H@St{TxQe~T2jUNbV44#>%2+dpZ6V~ z-p1~@SncO|Ug2VE*^Tjx3sj@`6l1{v-Zf{8dsS|MmQM`gil%uGaYb zvZr6T=m=|8+;0C=&)~?Sce=Rb0zByteK3<%q!3 z-(+__YkN2SMC^8<_-r1h^>*G}DV zIqLl7EdlQ{^hDC$MEM@poHYMfH;35|w|xQgnR!F`Lyg|+ow~C{B;ZI`SB0kPw|N@X z?NTa-X0KZL^sIaPvZ`a3=O0k5|C*lKap36Z+mkJ}ELm{H>E_BSNo%D{69sio>=5Ps ze)EI;Rmp8m%eJX)ZQGRn^Z1dLQ;nVy^JVu%Gxb${*zuTWa>}wB5tbVt>0NZs@t?kL zp~S`hB`X`AD7W^ zXj%UJ{c1*~ZvWk@hEwyFd`&NGRgt=qIP<44!e+@2X8bp*WR?9wkA>xB`TsWbUET66dj5~+W*;x7T-3Ot|0_50 z*{mniPxSl8ne7j~-1w=yhi3x+am;Q z^CN!er_ZRje|lT;)bF^}P5$47T719oCtcxBVOLZ*x7~G4e~mlSJFjCGjOJh7*LR8i zQ(V=$?hT4R7A!q_I(oLp%Cw-&j))b(P5*7J-Ur=ao5*y-U)$)JXqNuY>f6hzPG0>r zoAbh{sQ?pflyiQ$S;Id$9z}nzyQL6`{k-^NKvX6Pc_SdBOy}n*3$mY4b za`raEX+9C@UvvV!8UwaIF}Skl&dq?E8If}jasTIb-nr}haZlZoA3VLiUP=8~;G%Ql z*Q(g8=H*tUZF8h%S*@DayhYS`hM$!4>^Vyer)-=cvDVvf!T%lJdzf6T)jM84KDp!; z)5SAwEdtuNmOT2Ey3}Zy@|Beu6D@xK7F+e5PisPBT^^_JOJ=9;sD@wjYa&c?&&>OM zH~-<*uBlJ&e7XLK-)dj9yN~qKt)(u%do~|>b-PV4d%mu+WA9eWch4p%o&A$)dY~qX zPvgawrJ?_C$A7qRsqPgQ!{e=8f4BeDOFLIuo_FC~K}S6WIQhcy7bPfBwsGc3aC-N=f{G6pfZJWM&?#~5hepT%FBAF1z z?|4_B{q3FDvUZUPVxRc+Rs^(){874|6&$f*f>7m;8BgkRD+||psk2{Rz*}>r;L%%N^LfdIP@YeAuaRnN4*S>#Jp=JIaEN3d$|nmhG8)b=Qj6_0 zR%k8?nPRWJqjY{*#k(3KZX>sJib&Lb@OcXx9Oa}*Ph%jd8KCKi`)GB*W0hM zTKjE&wByzU0I+cD@_^CraCE4v2o2Y+oD9enZ|Ph~)&o&Ye4AdOSCFuoP6s z21#yEH=g7%QDmi}_4_v&Djz>ioTTycrv3N#`^wXe;`OXNfBt=z{N?B2f77fZ^XJR5G> zl-4RlBr&dV{U+Ma=%lSv@Q~@3gGEmHvSugo6rO}mUW04-sV818W|&^Zut7$6hk#+j zaTZ~AhaO%Tj$99o%AXtVmM;Cwv3hm>#pm*U^Ska{kBfWtcgmXUs~3Hp{YIg{=i=+H zt5z_6KmPi~XY=rQPeFNY|4-4Dx#zEXb1MJVIFQUBaVsjZ@w3tI{c9uY?IVtFV3@(U z|a5>Ec= ze$H5QY(>D&JF)wUw^!`>@i+W?{rled)ny5*?B18_>-~Pxc6@qxD#N)48}2twV~H;J z41e{Rq05ztV+lin*n^eE>KtxpqpyHNG&#=jE>9IXTyGFY3YJi7i` z^rt|eD1%?`>7~}$V(hv1QzRDjXZ6Zn&HCN6tZ(M542DBKn?FS}bbKpgd%<-2^X&e# zZ%Cex@RUdB5i0 z>NsXPFa3@+)KNf9+mY)-tQB?MIMzF_UI|U#7h@!vfE)_21Vo+V?N-;|yDO z{ktFTy!UM6z4dSR(d6&<>;C-w`*BzG-uk2G8J1_%^KdK=wOVy_R#2;h^{l2<-p9Ts z|CJ1`5fwkc%aVCCn0eupN0y@gR$Lx)H?>A?*AKKSHA>B_oU!f5uQ&fHe7EgyD3OS$ zcAH?`9d`Jf`m0{mq|XcjVhvF}Tapa!H*fJYx_mOlE8=XY@Y}~#TX`mQ=e(Qh^!Bj# zOPk{w%sgkUqffEVnAP)?`N$X1BGG!in9~Qu*8bn)cjxs#0q3(Z8vLYoqtOiWRUG zuw@)ywCCJ82EDb62R`v7a+mh6W93uEQ%(m<^KK1w6 zK8qvzSAKClZ%s0n4ba&4?4DKjHUE|C1A;b0@8L7kxEOvwei{zfXU`JyrO{ zqUnMQehJF5K9LbmFLZIp{Ci0}ai*Q}if@6dbz?G(FQ@#Cu-B}uvUpZK!OU}0!^_`H zOBxqEoKf}aH&au~Bf}28ovM>>nO?Ej^zHAvqc1uWSMn$rG8Aakt$3WpxbR!#(Usao znhgRbTJt9H8aOOiP?!IMMuDbutK9|SL6RVk5icY*NC}W;p z%=zWj>{*8+gSWS5+t0rKXs-L_Ti5!3%JUxI=KOl`SH8r{-&wD)IrY8|zArAYMD+Z| zN9u2-cD&;{p}XBgzJZ6~)+fdtjSF%)XEAXsY6Qf!Z{PArSuJlZEnUqcYEs(Lw!38cwS5UUm6qs7NC~ekR}E)8P_y#| z-)-6KrCT-j#mm2}+4oH1z^q5n3{0mr686RT`27rf{c3l!x?T>$f)qw?v7@o+uN)># zWqfv;wcEPD@EMa=L&C*hx*Ho_Xeh9=*sIU^SM*VPtH9B{=8V7o+SmOS|MG7_0pIFS z)<(^zSHtSoTJafbh;skXI56Q$qr=3BCdIF}hhJATJHW)q!|*OM&a?8yeY4V2oNO%T z|JD5dUjC+iMO(!sG1D-)P|J|FhoqEU^yQd;*f7NS-Cm-3r%~+n@rWhcA{ZVo>wdh2sqbO6VJpbwXAqi}dGS}W&Ie|dRT^nGC&^kdFfcH9y85}Sb4q9e00AaW AbN~PV From fce30e6ae562ca4ae8dcbe699bf5f44ac47c574c Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 17:22:44 -0500 Subject: [PATCH 411/426] Sync based on system time --- core/src/mindustry/core/NetServer.java | 10 ++++++---- core/src/mindustry/entities/comp/UnitComp.java | 1 - core/src/mindustry/net/NetConnection.java | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 565134b9a9..bead4b8a92 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -35,8 +35,8 @@ import static mindustry.Vars.*; public class NetServer implements ApplicationListener{ /** note that snapshots are compressed, so the max snapshot size here is above the typical UDP safe limit */ - private static final int maxSnapshotSize = 800, timerBlockSync = 0; - private static final float serverSyncTime = 12, blockSyncTime = 60 * 6; + private static final int maxSnapshotSize = 800, timerBlockSync = 0, serverSyncTime = 200; + private static final float blockSyncTime = 60 * 6; private static final FloatBuffer fbuffer = FloatBuffer.allocate(20); private static final Vec2 vector = new Vec2(); private static final Rect viewport = new Rect(); @@ -967,9 +967,11 @@ public class NetServer implements ApplicationListener{ return; } - NetConnection connection = player.con; + var connection = player.con; - if(!player.timer(0, serverSyncTime) || !connection.hasConnected) return; + if(Time.timeSinceMillis(connection.syncTime) < serverSyncTime || !connection.hasConnected) return; + + connection.syncTime = Time.millis(); try{ writeEntitySnapshot(player); diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 1db14dcc41..18c04df545 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -164,7 +164,6 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I pay.payloads().peek() instanceof BuildPayload p2 ? p2.block() : null) : null; default -> noSensed; }; - } @Override diff --git a/core/src/mindustry/net/NetConnection.java b/core/src/mindustry/net/NetConnection.java index be2455c53a..1d5cec3143 100644 --- a/core/src/mindustry/net/NetConnection.java +++ b/core/src/mindustry/net/NetConnection.java @@ -18,6 +18,7 @@ public abstract class NetConnection{ public boolean mobile, modclient; public @Nullable Player player; public boolean kicked = false; + public long syncTime; /** When this connection was established. */ public long connectTime = Time.millis(); From 07d11f02d836960bc1fbb05863589fec1c846df2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 22:16:29 -0500 Subject: [PATCH 412/426] Fixed #4869 --- core/src/mindustry/core/NetClient.java | 2 +- core/src/mindustry/mod/ContentParser.java | 10 ++++++++++ fastlane/metadata/android/en-US/changelogs/29831.txt | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/29831.txt diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index b9fc8037de..2433da07a4 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -190,7 +190,7 @@ public class NetClient implements ApplicationListener{ public static void sendChatMessage(Player player, String message){ //do not receive chat messages from clients that are too young or not registered - if(Time.timeSinceMillis(player.con.connectTime) < 500 || !player.con.hasConnected || !player.isAdded()) return; + if(net.server() && player != null && (Time.timeSinceMillis(player.con.connectTime) < 500 || !player.con.hasConnected || !player.isAdded())) return; if(message.length() > maxTextLength){ throw new ValidateException(player, "Player has sent a message above the text limit."); diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index ae8ea58056..b46227e662 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -92,6 +92,16 @@ public class ContentParser{ readFields(result, data); return result; }); + put(Weather.class, (type, data) -> { + if(data.isString()){ + return field(Weathers.class, data); + } + var bc = resolve(data.getString("type", ""), ParticleWeather.class); + data.remove("type"); + Weather result = make(bc); + readFields(result, data); + return result; + }); put(DrawBlock.class, (type, data) -> { if(data.isString()){ //try to instantiate diff --git a/fastlane/metadata/android/en-US/changelogs/29831.txt b/fastlane/metadata/android/en-US/changelogs/29831.txt new file mode 100644 index 0000000000..bc650d80c5 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29831.txt @@ -0,0 +1,9 @@ +[This is a truncated changelog, see Github for full notes] +- Various minor bugfixes +- Made water extractor use metaglass for building, to be consistent with pumps +- Added automatic conveyor/conduit bridging over obstacles +- Added 'defender' AI for Oct; follows nearby units +- Cores can now replace most transport blocks; turrets can now replace each other +- Improved bridge & power node linking previews +- Buffed Segment & Vela +- Logic: More hints From 5c85ba84dbbf817d9c3754704958ac534e47388b Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 5 Mar 2021 23:20:19 -0500 Subject: [PATCH 413/426] Actual JSON weather (?) --- core/src/mindustry/mod/ContentParser.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index b46227e662..b81190aa7c 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -92,16 +92,6 @@ public class ContentParser{ readFields(result, data); return result; }); - put(Weather.class, (type, data) -> { - if(data.isString()){ - return field(Weathers.class, data); - } - var bc = resolve(data.getString("type", ""), ParticleWeather.class); - data.remove("type"); - Weather result = make(bc); - readFields(result, data); - return result; - }); put(DrawBlock.class, (type, data) -> { if(data.isString()){ //try to instantiate @@ -327,7 +317,7 @@ public class ContentParser{ readBundle(ContentType.weather, name, value); }else{ readBundle(ContentType.weather, name, value); - item = make(resolve(getType(value), ParticleWeather.class)); + item = make(resolve(getType(value), ParticleWeather.class), name); } currentContent = item; read(() -> readFields(item, value)); From 0d3be917b2ae7c73ad9f3b2c026b25d35856608f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 6 Mar 2021 00:05:15 -0500 Subject: [PATCH 414/426] Extra checks for crash fix --- core/src/mindustry/core/NetClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index 2433da07a4..e307c2f5a0 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -190,7 +190,7 @@ public class NetClient implements ApplicationListener{ public static void sendChatMessage(Player player, String message){ //do not receive chat messages from clients that are too young or not registered - if(net.server() && player != null && (Time.timeSinceMillis(player.con.connectTime) < 500 || !player.con.hasConnected || !player.isAdded())) return; + if(net.server() && player != null && player.con != null && (Time.timeSinceMillis(player.con.connectTime) < 500 || !player.con.hasConnected || !player.isAdded())) return; if(message.length() > maxTextLength){ throw new ValidateException(player, "Player has sent a message above the text limit."); From f7e8412b4bc73ad8981681aff36afea4f36d8cd8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 6 Mar 2021 10:41:31 -0500 Subject: [PATCH 415/426] Fixed #4875 --- core/src/mindustry/input/Placement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/input/Placement.java b/core/src/mindustry/input/Placement.java index 21532f21c7..99091fc7ef 100644 --- a/core/src/mindustry/input/Placement.java +++ b/core/src/mindustry/input/Placement.java @@ -110,7 +110,7 @@ public class Placement{ public static void calculateBridges(Seq plans, ItemBridge bridge){ //check for orthogonal placement + unlocked state - if(!(plans.first().x == plans.peek().x || plans.first().y == plans.peek().y || !bridge.unlockedNow())){ + if(!(plans.first().x == plans.peek().x || plans.first().y == plans.peek().y) || !bridge.unlockedNow()){ return; } From 7c7c57c64e314cf03c3ec0382f5840807beea3de Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 6 Mar 2021 11:10:32 -0500 Subject: [PATCH 416/426] Various parsing bugfixes --- core/src/mindustry/mod/ContentParser.java | 3 ++- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index b81190aa7c..257b20188a 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -317,7 +317,8 @@ public class ContentParser{ readBundle(ContentType.weather, name, value); }else{ readBundle(ContentType.weather, name, value); - item = make(resolve(getType(value), ParticleWeather.class), name); + item = make(resolve(getType(value), ParticleWeather.class), mod + "-" + name); + value.remove("type"); } currentContent = item; read(() -> readFields(item, value)); diff --git a/gradle.properties b/gradle.properties index 75a3570010..90a92974a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=1b24d685ea94dd40244be869e70671080e950825 +archash=d1e1f3fe8803c6688182301cbf61b1bcfe39160a From 8474c921ec5675f4bafada5cc371954f4339a23a Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Sat, 6 Mar 2021 11:11:17 -0500 Subject: [PATCH 417/426] Fix indentation (#4877) Indents are 4 spaces not 3 --- core/src/mindustry/input/MobileInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 1624beedef..6958e3fa0b 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -722,7 +722,7 @@ public class MobileInput extends InputHandler implements GestureListener{ //When in line mode, pan when near screen edges automatically if(Core.input.isTouched(0)){ - autoPan(); + autoPan(); } int lx = tileX(Core.input.mouseX()), ly = tileY(Core.input.mouseY()); From 18c669ae3eafab0f153b2e95bad862f72e5aaf0b Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 6 Mar 2021 14:23:10 -0500 Subject: [PATCH 418/426] Fixed #4879 / Fixed server speed validation check --- core/src/mindustry/core/NetServer.java | 3 --- core/src/mindustry/entities/comp/CommanderComp.java | 3 ++- core/src/mindustry/entities/comp/PlayerComp.java | 4 ++++ core/src/mindustry/mod/ContentParser.java | 1 + gradle.properties | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index bead4b8a92..92509ec2e8 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -656,9 +656,6 @@ public class NetServer implements ApplicationListener{ long elapsed = Time.timeSinceMillis(con.lastReceivedClientTime); float maxSpeed = unit.realSpeed(); - if(unit.isGrounded()){ - maxSpeed *= unit.floorSpeedMultiplier(); - } float maxMove = elapsed / 1000f * 60f * maxSpeed * 1.2f; diff --git a/core/src/mindustry/entities/comp/CommanderComp.java b/core/src/mindustry/entities/comp/CommanderComp.java index 2842e5cc9c..92a86e12c2 100644 --- a/core/src/mindustry/entities/comp/CommanderComp.java +++ b/core/src/mindustry/entities/comp/CommanderComp.java @@ -4,6 +4,7 @@ import arc.func.*; import arc.math.geom.*; import arc.struct.*; import arc.util.*; +import mindustry.*; import mindustry.ai.formations.*; import mindustry.ai.types.*; import mindustry.annotations.Annotations.*; @@ -29,7 +30,7 @@ abstract class CommanderComp implements Entityc, Posc{ transient float minFormationSpeed; public void update(){ - if(controlling.isEmpty()){ + if(controlling.isEmpty() && !Vars.net.client()){ formation = null; } diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index ccfa3089ba..a44c8d0ff4 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -110,8 +110,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra unit.aim(mouseX, mouseY); //this is only necessary when the thing being controlled isn't synced unit.controlWeapons(shooting, shooting); + //save previous formation to prevent reset + var formation = unit.formation; //extra precaution, necessary for non-synced things unit.controller(this); + //keep previous formation + unit.formation = formation; } @Override diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 257b20188a..11bd9d0416 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -436,6 +436,7 @@ public class ContentParser{ try{ run.run(); }catch(Throwable t){ + Log.err(t); //don't overwrite double errors markError(currentContent, t); } diff --git a/gradle.properties b/gradle.properties index 90a92974a5..5010365e45 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=d1e1f3fe8803c6688182301cbf61b1bcfe39160a +archash=e318a6e39bf0497df62b2b3110dc24692d993d33 From b51d34e8931d22615b6ac10b0372f4dcb275d197 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 6 Mar 2021 17:25:03 -0500 Subject: [PATCH 419/426] Fixed #4882 --- core/src/mindustry/world/blocks/payloads/UnitPayload.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/mindustry/world/blocks/payloads/UnitPayload.java b/core/src/mindustry/world/blocks/payloads/UnitPayload.java index 2dd7125083..ee090b0a68 100644 --- a/core/src/mindustry/world/blocks/payloads/UnitPayload.java +++ b/core/src/mindustry/world/blocks/payloads/UnitPayload.java @@ -50,6 +50,9 @@ public class UnitPayload implements Payload{ @Override public boolean dump(){ + //TODO should not happen + if(unit.type == null) return true; + if(!Units.canCreate(unit.team, unit.type)){ deactiveTime = 1f; return false; @@ -81,6 +84,9 @@ public class UnitPayload implements Payload{ @Override public void draw(){ + //TODO should not happen + if(unit.type == null) return; + Drawf.shadow(unit.x, unit.y, 20); Draw.rect(unit.type.icon(Cicon.full), unit.x, unit.y, unit.rotation - 90); unit.type.drawCell(unit); From a2c7c38a3ec30503ce902606c29b4e8e98b31234 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 7 Mar 2021 09:32:52 -0500 Subject: [PATCH 420/426] Reduced Nova range --- core/src/mindustry/content/UnitTypes.java | 2 +- fastlane/metadata/android/en-US/changelogs/29834.txt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/29834.txt diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index ed966e869d..35b3cb719f 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -292,7 +292,7 @@ public class UnitTypes implements ContentList{ shootSound = Sounds.lasershoot; bullet = new LaserBoltBulletType(5.2f, 14){{ - lifetime = 37f; + lifetime = 32f; healPercent = 5f; collidesTeam = true; backColor = Pal.heal; diff --git a/fastlane/metadata/android/en-US/changelogs/29834.txt b/fastlane/metadata/android/en-US/changelogs/29834.txt new file mode 100644 index 0000000000..d49dd23886 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/29834.txt @@ -0,0 +1,3 @@ +[This is a truncated changelog, see Github for full notes] +- Fixed crash when using chat as server host +- Added support for parsing weather JSON From cccb8d6d198a018696698c29e5f1601e2cabf26c Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 7 Mar 2021 15:45:28 -0500 Subject: [PATCH 421/426] Fixed #4890 --- core/src/mindustry/core/NetClient.java | 2 +- core/src/mindustry/world/consumers/ConsumeLiquid.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index e307c2f5a0..7cd14828f5 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -209,7 +209,7 @@ public class NetClient implements ApplicationListener{ //special case; graphical server needs to see its message if(!headless){ - sendMessage(message, colorizeName(player.id(), player.name), player); + sendMessage(message, colorizeName(player.id, player.name), player); } //server console logging diff --git a/core/src/mindustry/world/consumers/ConsumeLiquid.java b/core/src/mindustry/world/consumers/ConsumeLiquid.java index 9a0f637ecd..6a4f765edb 100644 --- a/core/src/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/mindustry/world/consumers/ConsumeLiquid.java @@ -41,7 +41,7 @@ public class ConsumeLiquid extends ConsumeLiquidBase{ @Override public boolean valid(Building entity){ - return entity != null && entity.liquids != null && entity.liquids.get(liquid) >= amount * entity.edelta(); + return entity != null && entity.liquids != null && entity.liquids.get(liquid) >= amount * entity.delta(); } @Override From 6151ebf71621a0c8958dc7d6f34039d091db25df Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Sun, 7 Mar 2021 16:35:04 -0500 Subject: [PATCH 422/426] Fix button background (#4892) This button had a black background which stuck out from everything else on the page, this fixes that. --- core/src/mindustry/ui/dialogs/ModsDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/mindustry/ui/dialogs/ModsDialog.java b/core/src/mindustry/ui/dialogs/ModsDialog.java index 012dc54af8..bf84e34ce3 100644 --- a/core/src/mindustry/ui/dialogs/ModsDialog.java +++ b/core/src/mindustry/ui/dialogs/ModsDialog.java @@ -307,7 +307,7 @@ public class ModsDialog extends BaseDialog{ if(steam && !mod.hasSteamID()){ right.row(); - right.button(Icon.export, Styles.clearTransi, () -> { + right.button(Icon.export, Styles.clearPartiali, () -> { platform.publish(mod); }).size(50f); } From a60772a81ec277b330e6b41f6213c858920e6161 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 7 Mar 2021 17:54:43 -0500 Subject: [PATCH 423/426] Fixed #4891 --- core/src/mindustry/io/TypeIO.java | 20 +++++- .../world/blocks/logic/LogicBlock.java | 65 +++++++++++++------ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index e91ebedb6f..6e1ee0bd36 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -92,6 +92,9 @@ public class TypeIO{ }else if(object instanceof UnitCommand c){ write.b((byte)15); write.b(c.ordinal()); + }else if(object instanceof BuildingBox b){ + write.b(12); + write.i(b.pos); }else{ throw new IllegalArgumentException("Unknown object type: " + object.getClass()); } @@ -99,6 +102,12 @@ public class TypeIO{ @Nullable public static Object readObject(Reads read){ + return readObjectBoxed(read, false); + } + + /** Reads an object, but boxes buildings. */ + @Nullable + public static Object readObjectBoxed(Reads read, boolean box){ byte type = read.b(); switch(type){ case 0: return null; @@ -113,7 +122,7 @@ public class TypeIO{ case 9: return TechTree.getNotNull(content.getByID(ContentType.all[read.b()], read.s())); case 10: return read.bool(); case 11: return read.d(); - case 12: return world.build(read.i()); + case 12: return !box ? world.build(read.i()) : new BuildingBox(read.i()); case 13: return LAccess.all[read.s()]; case 14: int blen = read.i(); byte[] bytes = new byte[blen]; read.b(bytes); return bytes; case 15: return UnitCommand.all[read.b()]; @@ -600,4 +609,13 @@ public class TypeIO{ return null; } } + + /** Representes a building that has not been resolved yet. */ + public static class BuildingBox{ + public int pos; + + public BuildingBox(int pos){ + this.pos = pos; + } + } } diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index dace504cae..7cd1d031c6 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -1,5 +1,6 @@ package mindustry.world.blocks.logic; +import arc.*; import arc.func.*; import arc.math.geom.*; import arc.scene.ui.layout.*; @@ -13,6 +14,7 @@ import mindustry.core.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.io.*; +import mindustry.io.TypeIO.*; import mindustry.logic.*; import mindustry.logic.LAssembler.*; import mindustry.logic.LExecutor.*; @@ -195,7 +197,7 @@ public class LogicBlock extends Block{ public LExecutor executor = new LExecutor(); public float accumulator = 0; public Seq links = new Seq<>(); - public boolean checkedDuplicates = false; + public boolean checkedDuplicates = false, unboxed = false; public void readCompressed(byte[] data, boolean relative){ DataInputStream stream = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data))); @@ -237,7 +239,7 @@ public class LogicBlock extends Block{ } } - links.add(new LogicLink(x, y, name, validLink(world.build(x, y)))); + links.add(new LogicLink(x, y, name, false)); } } @@ -247,6 +249,21 @@ public class LogicBlock extends Block{ } } + @Override + public void onProximityAdded(){ + super.onProximityAdded(); + + //unbox buildings after reading + if(!unboxed){ + for(var v : executor.vars){ + if(v.objval instanceof BuildingBox b){ + v.objval = world.build(b.pos); + } + } + unboxed = true; + } + } + public String findLinkName(Block block){ String bname = getLinkName(block); Bits taken = new Bits(links.size); @@ -300,6 +317,7 @@ public class LogicBlock extends Block{ //store link objects executor.links = new Building[links.count(l -> l.valid && l.active)]; executor.linkIds.clear(); + int index = 0; for(LogicLink link : links){ if(link.active && link.valid){ @@ -378,30 +396,35 @@ public class LogicBlock extends Block{ } //check for previously invalid links to add after configuration - boolean changed = false; + boolean changed = false, updates = true; - for(int i = 0; i < links.size; i++){ - LogicLink l = links.get(i); + while(updates){ + updates = false; - if(!l.active) continue; + for(int i = 0; i < links.size; i++){ + LogicLink l = links.get(i); - boolean valid = validLink(world.build(l.x, l.y)); - if(valid != l.valid){ - changed = true; - l.valid = valid; - if(valid){ - Building lbuild = world.build(l.x, l.y); + if(!l.active) continue; - //this prevents conflicts - l.name = ""; - //finds a new matching name after toggling - l.name = findLinkName(lbuild.block); + boolean valid = validLink(world.build(l.x, l.y)); + if(valid != l.valid){ + changed = true; + l.valid = valid; + if(valid){ + Building lbuild = world.build(l.x, l.y); - //remove redundant links - links.removeAll(o -> world.build(o.x, o.y) == lbuild && o != l); + //this prevents conflicts + l.name = ""; + //finds a new matching name after toggling + l.name = findLinkName(lbuild.block); - //break to prevent concurrent modification - break; + //remove redundant links + links.removeAll(o -> world.build(o.x, o.y) == lbuild && o != l); + + //break to prevent concurrent modification + updates = true; + break; + } } } } @@ -555,7 +578,7 @@ public class LogicBlock extends Block{ for(int i = 0; i < varcount; i++){ String name = read.str(); - Object value = TypeIO.readObject(read); + Object value = TypeIO.readObjectBoxed(read, true); names[i] = name; values[i] = value; From e1b0e07f3c89ee2285f553974416f280258689f3 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 8 Mar 2021 09:52:36 -0500 Subject: [PATCH 424/426] Return 1 for sensing `dead` in null objects --- core/src/mindustry/logic/LExecutor.java | 5 +++++ core/src/mindustry/world/blocks/logic/LogicBlock.java | 11 ++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index c7082e4cb1..2e636cf4cd 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -636,6 +636,11 @@ public class LExecutor{ Object target = exec.obj(from); Object sense = exec.obj(type); + if(target == null && sense == LAccess.dead){ + exec.setnum(to, 1); + return; + } + //note that remote units/buildings can be sensed as well if(target instanceof Senseable se){ if(sense instanceof Content co){ diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index 7cd1d031c6..ac597fa1e7 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -197,7 +197,7 @@ public class LogicBlock extends Block{ public LExecutor executor = new LExecutor(); public float accumulator = 0; public Seq links = new Seq<>(); - public boolean checkedDuplicates = false, unboxed = false; + public boolean checkedDuplicates = false; public void readCompressed(byte[] data, boolean relative){ DataInputStream stream = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data))); @@ -254,13 +254,10 @@ public class LogicBlock extends Block{ super.onProximityAdded(); //unbox buildings after reading - if(!unboxed){ - for(var v : executor.vars){ - if(v.objval instanceof BuildingBox b){ - v.objval = world.build(b.pos); - } + for(var v : executor.vars){ + if(v.objval instanceof BuildingBox b){ + v.objval = world.build(b.pos); } - unboxed = true; } } From f6925953ada4ed889410c08447ec3f129f7f983c Mon Sep 17 00:00:00 2001 From: CxZxRainzz <78591136+CxZxRainzz@users.noreply.github.com> Date: Mon, 8 Mar 2021 20:05:26 +0000 Subject: [PATCH 425/426] Update servers_v6.json (#4901) add PvP server for CxZx --- servers_v6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers_v6.json b/servers_v6.json index da0b3cbd65..231345ba0b 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -61,7 +61,7 @@ }, { "name": "CxZx", - "address": ["frfr1.quackhost.uk:20060", "frfr1.quackhost.uk:20185", "defr2.forcehost.net:1069"] + "address": ["frfr1.quackhost.uk:20060", "frfr1.quackhost.uk:20185", "defr2.forcehost.net:1069", "fifr3.quackhost.uk:26453"] }, { "name": "Korea", From 25c61590d1daa664bbe2d90c43a3ce05a7b75a7c Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 8 Mar 2021 17:12:53 -0500 Subject: [PATCH 426/426] Minor cleanup / Another slight vela buff --- core/src/mindustry/content/UnitTypes.java | 6 +++--- core/src/mindustry/entities/comp/UnitComp.java | 7 ++++--- core/src/mindustry/ui/Fonts.java | 1 - 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 35b3cb719f..87e0612dae 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -411,7 +411,7 @@ public class UnitTypes implements ContentList{ mechStepShake = 0.15f; ammoType = AmmoTypes.powerHigh; - speed = 0.38f; + speed = 0.39f; boostMultiplier = 2.2f; engineOffset = 12f; engineSize = 6f; @@ -442,7 +442,7 @@ public class UnitTypes implements ContentList{ cooldownTime = 200f; bullet = new ContinuousLaserBulletType(){{ - damage = 28f; + damage = 30f; length = 175f; hitEffect = Fx.hitMeltHeal; drawSize = 420f; @@ -453,7 +453,7 @@ public class UnitTypes implements ContentList{ shootEffect = Fx.greenLaserChargeSmall; - incendChance = 0.09f; + incendChance = 0.1f; incendSpread = 5f; incendAmount = 1; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 18c04df545..9efd20f9fc 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -28,6 +28,7 @@ import mindustry.world.blocks.environment.*; import mindustry.world.blocks.payloads.*; import static mindustry.Vars.*; +import static mindustry.logic.GlobalConstants.*; @Component(base = true) abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{ @@ -140,9 +141,9 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case mineY -> mining() ? mineTile.y : -1; case flag -> flag; case controlled -> !isValid() ? 0 : - controller instanceof LogicAI ? GlobalConstants.ctrlProcessor : - controller instanceof Player ? GlobalConstants.ctrlPlayer : - controller instanceof FormationAI ? GlobalConstants.ctrlFormation : + controller instanceof LogicAI ? ctrlProcessor : + controller instanceof Player ? ctrlPlayer : + controller instanceof FormationAI ? ctrlFormation : 0; case commanded -> controller instanceof FormationAI && isValid() ? 1 : 0; case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; diff --git a/core/src/mindustry/ui/Fonts.java b/core/src/mindustry/ui/Fonts.java index 35c6f1bcd9..6bd969fe4b 100644 --- a/core/src/mindustry/ui/Fonts.java +++ b/core/src/mindustry/ui/Fonts.java @@ -117,7 +117,6 @@ public class Fonts{ if(region.texture != uitex){ continue; - //throw new IllegalArgumentException("Font icon '" + texture + "' is not in the UI texture."); } unicodeIcons.put(nametex[0], ch);