diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea0a1f6872..99086e0da2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ Do not submit something without at least running the game to see if it compiles. If you are submitting a new block, make sure it has a name and description, and that it works correctly in-game. If you are changing existing block mechanics, test them out first. ### Do not make large changes before discussing them first. -If you are interested in adding a large mechanic/feature or changing large amounts of code, first contact me (Anuken) via [Discord](https://discord.gg/mindustry) (preferred method) or via e-mail (*anukendev@gmail.com*). +If you are interested in adding a large mechanic/feature or changing large amounts of code, first contact me (Anuken) via [Discord](https://discord.gg/mindustry) - either via PM or by posting in the `#pulls` channel. For most changes, this should not be necessary. I just want to know if you're doing something big so I can offer advice and/or make sure you're not wasting your time on it. ### Do not make formatting PRs. diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index 4c879bdc23..2a6ce0a0d9 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -589,7 +589,7 @@ sectors.unexplored = [lightgray]Inexploré sectors.resources = Ressources : sectors.production = Production : sectors.export = Exporter : -sectors.import = Import: +sectors.import = Importer : sectors.time = Temps de jeu : sectors.threat = Menace : sectors.wave = Vague : @@ -823,7 +823,7 @@ 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.homing = [stat]autoguidé -bullet.frags = [stat]{0}[lightgray]x frag bullets: +bullet.frags = [stat]{0}[lightgray]x Balle à fragmentation : bullet.lightning = [stat]{0}[lightgray]x foudre ~ [stat]{1}[lightgray] dégâts bullet.buildingdamage = [stat]{0}%[lightgray] des dégâts aux bâtiments bullet.knockback = [stat]{0}[lightgray] recul @@ -1036,7 +1036,7 @@ rules.wavetimer = Compte à rebours des vagues rules.waves = Vagues rules.attack = Mode « Attaque » rules.buildai = Constructions de l'IA -rules.aitier = AI Tier +rules.aitier = IA Tier rules.cleanupdeadteams = Détruire les structures des équipes vaincues (JcJ) rules.corecapture = Capture du Noyau lors de sa Destruction rules.polygoncoreprotection = Protection du noyau polygonal @@ -1056,15 +1056,15 @@ rules.deconstructrefundmultiplier = Multiplicateur du remboursement lors de la d 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.enemyteam = Enemy Team -rules.playerteam = Player Team +rules.enemyteam = Équipe ennemie +rules.playerteam = Équipe du joueur rules.title.waves = Vagues rules.title.resourcesbuilding = Resources & Construction rules.title.enemy = Ennemis rules.title.unit = Unités rules.title.experimental = Expérimental rules.title.environment = Environnement -rules.title.teams = Teams +rules.title.teams = Équipes rules.lighting = Éclairage rules.enemyLights = Éclairage ennemi rules.fire = Feu @@ -1479,9 +1479,9 @@ block.incinerator.description = Incinère ou vaporise n'importe quel objet ou li 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-void.description = Désintègre n'importe quel objet qui va à l'intérieur. Bac à sable uniquement. +block.item-void.description = Détruit les objets introduits. 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.liquid-void.description = Détruit les liquides introduits. Bac à sable uniquement. block.payload-source.description = Produit des charges utiles à l'infini. Bac à sable uniquement. block.payload-void.description = Détruit toutes les charges utiles. 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. diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 5269a0dc6b..7c3712c53b 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -288,7 +288,7 @@ save.corrupted = 此存檔無效或已損毀! empty = 〈空白〉 on = 開啟 off = 關閉 -save.search = Search saved games... +save.search = 搜尋儲存的遊戲…… save.autosave = 自動存檔:{0} save.map = 地圖:{0} save.wave = 波次:{0} @@ -380,13 +380,13 @@ editor.ingame = 在遊戲中編輯 editor.publish.workshop = 在工作坊上發佈 editor.newmap = 新地圖 editor.center = 中心 -editor.search = 尋找地圖... +editor.search = 尋找地圖… editor.filters = 篩選地圖 -editor.filters.mode = Gamemodes: -editor.filters.type = Map Type: -editor.filters.search = Search In: -editor.filters.author = Author -editor.filters.description = Description +editor.filters.mode = 遊戲模式: +editor.filters.type = 地圖種類: +editor.filters.search = 搜尋的資料夾: +editor.filters.author = 作者 +editor.filters.description = 描述 workshop = 工作坊 waves.title = 波次 waves.remove = 移除 @@ -420,7 +420,7 @@ wavemode.health = 生命值 editor.default = [lightgray](預設) details = 詳細資訊…… edit = 編輯…… -variables = Vars +variables = 變數 editor.name = 名稱: editor.spawn = 重生單位 editor.removeunit = 移除單位 @@ -1301,7 +1301,7 @@ block.plated-conduit.name = 裝甲管線 block.phase-conduit.name = 相織管線 block.liquid-router.name = 液體分配器 block.liquid-tank.name = 液體儲存槽 -block.liquid-container.name = Liquid Container +block.liquid-container.name = 液體容器 block.liquid-junction.name = 液體樞紐 block.bridge-conduit.name = 管線橋 block.rotary-pump.name = 迴旋泵 @@ -1348,16 +1348,16 @@ block.disassembler.name = 還原機 block.silicon-crucible.name = 矽爐 block.overdrive-dome.name = 高速拱頂 block.interplanetary-accelerator.name = 星際加速站 -block.constructor.name = Constructor -block.constructor.description = Fabricates structures up to 2x2 tiles in size. -block.large-constructor.name = Large Constructor -block.large-constructor.description = Fabricates structures up to 4x4 tiles in size. -block.deconstructor.name = Deconstructor -block.deconstructor.description = Deconstructs structures and units. Returns 100% of build cost. -block.payload-loader.name = Payload Loader -block.payload-loader.description = Load liquids and items into blocks. -block.payload-unloader.name = Payload Unloader -block.payload-unloader.description = Unloads liquids and items from blocks. +block.constructor.name = 建造器 +block.constructor.description = 建造達 2x2 的方塊。 +block.large-constructor.name = 大型建造器 +block.large-constructor.description = 建造達 4x4 的方塊。 +block.deconstructor.name = 拆解器 +block.deconstructor.description = 拆解方塊和單位,返還所有建造花費。 +block.payload-loader.name = 載物裝入器 +block.payload-loader.description = 將物品或是液體裝入方塊。 +block.payload-unloader.name = 載物取出器 +block.payload-unloader.description = 將物品或是液體從方塊取出。 block.switch.name = 按鈕 block.micro-processor.name = 微處理器 @@ -1468,7 +1468,7 @@ block.incinerator.description = 銷毀所有接收的物品或液體。 block.power-void.description = 銷毀所有輸入的能量。僅限沙盒。 block.power-source.description = 無限輸出能量。僅限沙盒。 block.item-source.description = 無限輸出物品。僅限沙盒。 -block.item-void.description = 不使用能量銷毀任何進入它的物品。僅限沙盒。 +block.item-void.description = 銷毀所有進入的物品。僅限沙盒。 block.liquid-source.description = 無限輸出液體。僅限沙盒。 block.liquid-void.description = 銷毀所有輸入的液體。僅限沙盒。 block.payload-source.description = 無限輸出原料。僅限沙盒。 @@ -1513,7 +1513,7 @@ block.conduit.description = 基本液體運輸方塊。將液體往前輸送。 block.pulse-conduit.description = 高級的液體運輸方塊。比標準管線更快地輸送並儲存更多液體。 block.plated-conduit.description = 用和脈衝管線相同的速率運送液體,但有更強的裝甲。除了其他管線以外,不會接受來自側面的其他液體\n比較不會漏液。 block.liquid-router.description = 接受來自一個方向的液體並將它們平均輸出到最多3個其他方向。可以儲存一定量的液體。用於將液體從一個來源分成多個目標。 -block.liquid-container.description = Stores a sizeable amount of liquid. Outputs to all sides, similarly to a liquid router. +block.liquid-container.description = 儲存可觀的液體。由四邊輸出,與液體分配器雷同。 block.liquid-tank.description = 儲存大量液體。當液體需求非恆定時,使用它來創建緩衝或作為冷卻重要方塊的保障。 block.liquid-junction.description = 作為兩個交叉管線的橋樑。適用於兩條不同管線將不同液體運送到不同位置的情況。 block.bridge-conduit.description = 高級的液體運輸方塊。允許跨過最多3個任何地形或建築物的方塊運輸液體。 @@ -1778,7 +1778,7 @@ lenum.itemdrop = 放下物品 lenum.itemtake = 從建築拿取物品 lenum.paydrop = 放下拾取的負載 lenum.paytake = 拾取船身下方的單位/建築 -lenum.payenter = Enter/land on the payload block the unit is on. +lenum.payenter = 進入/降落到載重方塊 lenum.flag = 單位編號(可異) lenum.mine = 挖指定位置的礦物 lenum.build = 建造一個建築 diff --git a/core/assets/contributors b/core/assets/contributors index cf8d54cf74..a46d54ee98 100644 --- a/core/assets/contributors +++ b/core/assets/contributors @@ -115,7 +115,7 @@ younggam simba-fs RedRadiation Marko Zajc -CPX MC +PCX-LK (CPX MC) Phinner BTA_Susideur nilq diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index bcc2247d9f..da5b114267 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -199,3 +199,5 @@ const ResizeEvent = Packages.mindustry.game.EventType.ResizeEvent const LoseEvent = Packages.mindustry.game.EventType.LoseEvent const WinEvent = Packages.mindustry.game.EventType.WinEvent const Trigger = Packages.mindustry.game.EventType.Trigger +const PlayerConnectionConfirmed = Packages.mindustry.game.EventType.PlayerConnectionConfirmed +const AdminRequestEvent = Packages.mindustry.game.EventType.AdminRequestEvent diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index a256483cea..98939b1056 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -2040,6 +2040,7 @@ public class UnitTypes implements ContentList{ weaveMag = 4; weaveScale = 4; lifetime = 60f; + keepVelocity = false; shootEffect = Fx.shootHeal; smokeEffect = Fx.hitLaser; splashDamage = 13f; diff --git a/core/src/mindustry/core/ContentLoader.java b/core/src/mindustry/core/ContentLoader.java index 7d738135cd..8dd4357817 100644 --- a/core/src/mindustry/core/ContentLoader.java +++ b/core/src/mindustry/core/ContentLoader.java @@ -48,7 +48,7 @@ public class ContentLoader{ clear(); } - /** Clears all initialized content.*/ + /** Clears all initialized content. */ public void clear(){ contentNameMap = new ObjectMap[ContentType.all.length]; contentMap = new Seq[ContentType.all.length]; @@ -75,7 +75,7 @@ public class ContentLoader{ } } - /** Logs content statistics.*/ + /** Logs content statistics. */ public void logContent(){ //check up ID mapping, make sure it's linear (debug only) for(Seq arr : contentMap){ @@ -95,14 +95,14 @@ public class ContentLoader{ Log.debug("-------------------"); } - /** Calls Content#init() on everything. Use only after all modules have been created.*/ + /** Calls Content#init() on everything. Use only after all modules have been created. */ public void init(){ initialize(Content::init); if(constants != null) constants.init(); Events.fire(new ContentInitEvent()); } - /** Calls Content#load() on everything. Use only after all modules have been created on the client.*/ + /** Calls Content#loadIcon() and Content#load() on everything. Use only after all modules have been created on the client. */ public void load(){ initialize(Content::loadIcon); initialize(Content::load); @@ -323,4 +323,4 @@ public class ContentLoader{ public Planet planet(String name){ return getByName(ContentType.planet, name); } -} \ No newline at end of file +} diff --git a/core/src/mindustry/ctype/Content.java b/core/src/mindustry/ctype/Content.java index fb0679bf9b..bea224683e 100644 --- a/core/src/mindustry/ctype/Content.java +++ b/core/src/mindustry/ctype/Content.java @@ -31,7 +31,7 @@ public abstract class Content implements Comparable{ */ public void load(){} - /** Called right after load(). */ + /** Called right before load(). */ public void loadIcon(){} /** @return whether an error occurred during mod loading. */ diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 262c53d414..5847ef8966 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1249,6 +1249,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, return self() != other; } + /** + * Called when this block's config menu is closed + */ + public void onConfigureClosed(){} + /** Returns whether this config menu should show when the specified player taps it. */ public boolean shouldShowConfigure(Player player){ return true; diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 0bcc17727e..c283e516f3 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -1269,19 +1269,24 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } int endRotation = -1; + var start = world.build(startX, startY); + var end = world.build(endX, endY); if(diagonal){ - var start = world.build(startX, startY); - var end = world.build(endX, endY); if(block != null && start instanceof ChainedBuilding && end instanceof ChainedBuilding && block.canReplace(end.block) && block.canReplace(start.block)){ points = Placement.upgradeLine(startX, startY, endX, endY); - endRotation = end.rotation; }else{ points = Placement.pathfindLine(block != null && block.conveyorPlacement, startX, startY, endX, endY); } }else{ points = Placement.normalizeLine(startX, startY, endX, endY); } + if(points.size > 1 && end instanceof ChainedBuilding){ + Point2 secondToLast = points.get(points.size - 2); + if (!(world.build(secondToLast.x, secondToLast.y) instanceof ChainedBuilding)){ + endRotation = end.rotation; + } + } if(block != null){ block.changePlacementPath(points, rotation); diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index ea864a0064..afd051dd97 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -589,6 +589,30 @@ public class SettingsMenuDialog extends BaseDialog{ rebuild(); } + public void textPref(String name, String def){ + list.add(new TextSetting(name, def, null)); + settings.defaults(name, def); + rebuild(); + } + + public void textPref(String name, String def, Cons changed){ + list.add(new TextSetting(name, def, changed)); + settings.defaults(name, def); + rebuild(); + } + + public void areaTextPref(String name, String def){ + list.add(new AreaTextSetting(name, def, null)); + settings.defaults(name, def); + rebuild(); + } + + public void areaTextPref(String name, String def, Cons changed){ + list.add(new AreaTextSetting(name, def, changed)); + settings.defaults(name, def); + rebuild(); + } + public void rebuild(){ clearChildren(); @@ -704,6 +728,67 @@ public class SettingsMenuDialog extends BaseDialog{ table.row(); } } + + public static class TextSetting extends Setting{ + String def; + Cons changed; + public TextSetting(String name, String def, Cons changed){ + super(name); + this.def = def; + this.changed = changed; + } + + @Override + public void add(SettingsTable table){ + TextField field = new TextField(); + + field.update(() -> field.setText(settings.getString(name))); + + field.changed(() -> { + settings.put(name, field.getText()); + if(changed != null){ + changed.get(field.getText()); + } + }); + + Table prefTable = table.table().left().padTop(3f).get(); + prefTable.add(field); + prefTable.label(() -> title); + addDesc(prefTable); + table.row(); + } + } + + public static class AreaTextSetting extends TextSetting{ + String def; + Cons changed; + + public AreaTextSetting(String name, String def, Cons changed){ + super(name, def, changed); + } + + @Override + public void add(SettingsTable table){ + TextArea area = new TextArea(""); + area.setPrefRows(5); + + area.update(() -> { + area.setText(settings.getString(name)); + area.setWidth(table.getWidth()); + }); + + area.changed(() -> { + settings.put(name, area.getText()); + if(changed != null){ + changed.get(area.getText()); + } + }); + + addDesc(table.label(() -> title).left().padTop(3f).get()); + table.row().add(area).left(); + table.row(); + } + } } } diff --git a/core/src/mindustry/ui/fragments/BlockConfigFragment.java b/core/src/mindustry/ui/fragments/BlockConfigFragment.java index 1523508aa4..10cd46f6ef 100644 --- a/core/src/mindustry/ui/fragments/BlockConfigFragment.java +++ b/core/src/mindustry/ui/fragments/BlockConfigFragment.java @@ -49,6 +49,7 @@ public class BlockConfigFragment extends Fragment{ } public void showConfig(Building tile){ + if(configTile != null) configTile.onConfigureClosed(); if(tile.configTapped()){ configTile = tile; @@ -82,6 +83,7 @@ public class BlockConfigFragment extends Fragment{ } public void hideConfig(){ + if(configTile != null) configTile.onConfigureClosed(); configTile = null; table.actions(Actions.scaleTo(0f, 1f, 0.06f, Interp.pow3Out), Actions.visible(false)); } diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 666f80305a..2a3a9ea12c 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -395,7 +395,7 @@ public class Block extends UnlockableContent{ return hasItems; } - /** Returns whether or not this block can be place on the specified */ + /** @return whether or not this block can be placed on the specified tile. */ public boolean canPlaceOn(Tile tile, Team team, int rotation){ return canPlaceOn(tile, team); } diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 4c59a84174..2e89a47fca 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -84,8 +84,6 @@ public class PowerNode extends PowerBlock{ }); config(Point2[].class, (tile, value) -> { - tile.power.links.clear(); - IntSeq old = new IntSeq(tile.power.links); //clear old diff --git a/core/src/mindustry/world/blocks/production/LiquidConverter.java b/core/src/mindustry/world/blocks/production/LiquidConverter.java index c01dbfbc36..ed6d57915d 100644 --- a/core/src/mindustry/world/blocks/production/LiquidConverter.java +++ b/core/src/mindustry/world/blocks/production/LiquidConverter.java @@ -24,7 +24,6 @@ public class LiquidConverter extends GenericCrafter{ ConsumeLiquid cl = consumes.get(ConsumeType.liquid); cl.update(false); - outputLiquid.amount = cl.amount; super.init(); } diff --git a/servers_be.json b/servers_be.json index 6097ace2ae..9245f93cec 100644 --- a/servers_be.json +++ b/servers_be.json @@ -10,5 +10,8 @@ }, { "address": "c-n.ddns.net:6567" + }, + { + "address": "xpdustry.fr:8000" } ] diff --git a/servers_v6.json b/servers_v6.json index 75db78dd16..81cc6c2e7e 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -1,15 +1,19 @@ [ { - "name": "Infection", - "address": ["plague-continued.ml:5555", "plague-continued.ml:5004"] + "name": "{AA}", + "address": ["recessive.net"] + }, + { + "name": "Yeet Hosting", + "address": ["n3.mindustry.me:5004"] }, { "name": "RCM", "address": ["185.104.248.61", "easyplay.su"] }, - { - "name": "{AA}", - "address": ["aamindustry.play.ai", "aamindustry.play.ai:6571", "aamindustry.play.ai:6572", "aamindustry.play.ai:6573", "aamindustry.play.ai:6574"] + { + "name": "Tendhost", + "address": ["tendhost.ddns.net"] }, { "name": "Atanner", @@ -57,7 +61,7 @@ }, { "name": "Omega", - "address": ["yeeth.mindustry.me:6568","yeeth.mindustry.me:5002"] + "address": ["omegav.mindustry.me:6572"] }, { "name": "Obvilion Network", @@ -101,7 +105,7 @@ }, { "name": "Mindustry Español", - "address": ["yeeth.mindustry.me:6578", "yeeth.mindustry.me:6573", "yeeth.mindustry.me:6577", "yeeth.mindustry.me:6576"] + "address": ["n4.mindustry.me:6578", "n4.mindustry.me:6573", "n4.mindustry.me:6577", "n4.mindustry.me:6576"] }, { "name": "CreateDustry", diff --git a/servers_v7.json b/servers_v7.json index 70b071417b..c485a7278b 100644 --- a/servers_v7.json +++ b/servers_v7.json @@ -17,7 +17,7 @@ }, { "name": "Omega", - "address": ["n3.mindustry.me:5002", "n3.mindustry.me:5003", "n3.mindustry.me:5004","n3.mindustry.me:5005", "n3.mindustry.me:5006", "n3.mindustry.me:5007", "n3.mindustry.me", "n3.mindustry.me:4006"] + "address": ["omegam.mindustry.me:5002", "omegam.mindustry.me:5003", "omegam.mindustry.me:5005", "omegam.mindustry.me:5006", "omegam.mindustry.me:5007", "omegam.mindustry.me", "omegam.mindustry.me:4006"] }, { "name": "MeowLand", @@ -33,7 +33,7 @@ }, { "name": "XCore", - "address": ["node.procord.vip:2707", "eu-fsn-01.vapur.host:24603"] + "address": ["node.procord.vip:2707", "de14.halexnodes.net:40036"] }, { "name": "Obvilion Network", @@ -51,10 +51,6 @@ "name": "SubZero", "address": ["minty-server.ddns.net"] }, - { - "name": "Shiza Minigames", - "address": ["shizashizashiza.ml"] - }, { "name": "Phoenix Network", "address": ["172.104.253.198"]