diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 4d5e3040c6..fa1d1c3e04 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -1,4 +1,4 @@ -text.credits.text = Создатель [ROYAL] Anuken. - [SKY]anukendev@gmail.com[][]\n\nЕсть недороботки в переводе?\nПишите в офф. discord-сервер mindustry в канал #русский.\n\nПереводчики на русский язык:\n[YELLOW]Prosta4ok_ua\n[GREEN]xga\n[BLACK]XZimur +text.credits.text = Создатель [ROYAL] Anuken. - [SKY]anukendev@gmail.com[][]\n\nЕсть недоработки в переводе?\nПишите в офф. discord-сервер mindustry в канал #русский.\n\nПереводчики на русский язык:\n[YELLOW]Prosta4ok_ua\n[GREEN]xga\n[BLACK]XZimur text.credits = Авторы text.contributors = Переводчики и контрибьюторы text.discord = Присоединяйтесь к нашему Discord! @@ -12,7 +12,7 @@ text.link.wiki.description = Официальная вики Mindustry(англ. text.linkfail = Не удалось открыть ссылку!\nURL-адрес был скопирован в буфер обмена. text.gameover = Игра окончена text.gameover.pvp = [accent] {0}[] команда победила! -text.sector.gameover = Этот сектор потерян. Высадится повторно? +text.sector.gameover = Этот сектор потерян. Высадиться повторно? text.sector.retry = Повторить попытку text.highscore = [YELLOW]Новый рекорд! text.wave.lasted = Вы продержались до [accent]{0}[]-ой волны. @@ -49,9 +49,9 @@ text.mission.main = Главная мисия:[LIGHT_GRAY] {0} text.mission.info = Информация о миссии text.mission.complete = Миссия выполнена! text.mission.complete.body = Сектор {0},{1} был завоёван. -text.mission.wave = Осталось[accent] {0}[] волн из[accent] {1}[]\nВолна через {2} -text.mission.wave.enemies = Осталось[accent] {0}/{1}[] волн:\n{2} враг. -text.mission.wave.enemy = Осталось[accent] {0}/{1}[] волн\n{2} враг +text.mission.wave = Волна[accent] {0}[] из[accent] {1}[]\nВолна через {2} +text.mission.wave.enemies = Волна[accent] {0} из {1}[]\n{2} враг. +text.mission.wave.enemy = Волна[accent] {0} из {1}[]\n{2} враг text.mission.wave.menu = Пережить[accent] {0} []волн text.mission.battle = Уничтожьте ядро противника. text.mission.resource.menu = Добыть {0} х{1} @@ -266,7 +266,7 @@ text.error.invalidaddress = Некорректный адрес. text.error.timedout = Время ожидания истекло!\nУбедитесь, что хост настроен для перенаправления портов и адрес корректный! text.error.mismatch = Ошибка пакета:\nвозможное несоответствие версии клиента/сервера. \nУбедитесь, что у Вас и у владельца сервера установлена последняя версия Mindustry! text.error.alreadyconnected = Вы уже подключены. -text.error.mapnotfound = Map file not found! +text.error.mapnotfound = Не найден файл карты! text.error.any = Неизвестная сетевая ошибка. text.settings.language = Язык text.settings.reset = Сбросить по умолчанию @@ -345,7 +345,7 @@ text.category.power = Энергия text.category.liquids = Жидкости text.category.items = Предметы text.category.crafting = Создание -text.category.shooting = Cтрельба +text.category.shooting = Стрельба text.category.optional = Дополнительные улучшения setting.autotarget.name = Авто-цель setting.fpscap.name = Макс. FPS @@ -407,8 +407,8 @@ mode.waves.name = Волны mode.waves.description = Обычный режим. В режиме "Волны" надо самим добывать ресурсы и сами волны идут безостановочно. mode.sandbox.name = Песочница mode.sandbox.description = Бесконечные ресурсы и нет таймера для волн, но можно самим вызвать волну. -mode.freebuild.name = Cвободная\nстрой -mode.freebuild.description = ограниченные ресурсы и нет таймера для волн. +mode.freebuild.name = Свободная\nстройка +mode.freebuild.description = Ограниченные ресурсы и нет таймера для волн. mode.pvp.name = Противо-\nстояние mode.pvp.description = боритесь против других игроков. content.item.name = Предметы @@ -435,7 +435,7 @@ item.silicon.description = Очень полезный полупроводни item.plastanium.name = Пластиний item.plastanium.description = Легкий, пластичный материал, используемый в современных самолетах и боеприпасах для фрагментации. item.phase-fabric.name = Фазовая ткань -item.phase-fabric.description = Невесомое вещество, используемое в современной электронике и технологии самовосстановления. +item.phase-fabric.description = Невесомое вещество, используемое в современной электронике и технологии самовосстановления. Непригодна для вышивания. item.surge-alloy.name = Высокопрочный сплав item.surge-alloy.description = Передовой сплав с уникальными электрическими свойствами. item.biomatter.name = Биоматерия @@ -461,7 +461,7 @@ mech.delta-mech.description = Быстрый, легкобронированны mech.tau-mech.name = Тау mech.tau-mech.weapon = Восстановительный лазер mech.tau-mech.ability = Регенирирующая вспышка -mech.tau-mech.description = Мех поддержки. Исцеляет союзные блоки, стреляя в них. Может исцелить союзников радиусом с его способностью восстанавления. +mech.tau-mech.description = Мех поддержки. Чинит союзные блоки, стреляя в них. Может исцелить союзников радиусом с его способностью восстанавления. mech.omega-mech.name = Омега mech.omega-mech.weapon = Ракетомётный пулемётконфигурация mech.omega-mech.ability = Защитная @@ -498,7 +498,7 @@ block.constructing = {0}[LIGHT_GRAY](В процессе) block.spawn.name = Точка появления врагов block.core.name = Ядро block.space.name = Пустота -block.metalfloor.name = Мeталичeский пoл +block.metalfloor.name = Металлическая плита block.deepwater.name = Глубоководье block.water.name = Вода block.lava.name = Лава @@ -731,8 +731,8 @@ block.solar-panel-large.description = Зелёная энергия. Больш block.thorium-reactor.description = Производит энергию в большом количестве. Может взорваться. Требуется торий и жидкость для охлаждения (вода или криогенная). block.rtg-generator.description = Радиоизотопный термоэлектрический генератор, который не требует охлаждения, но обеспечивает меньшую мощность, чем ториевый реактор. block.unloader.description = Выгружает из ядра или хранилища верхний левый предмет. -block.container.description = Хранит небольшое количество предметов(250). Используйте его для создания буферов, когда существует непостоянная потребность в материалах. [LIGHT_GRAY] Разгрузчик[] можно использовать для извлечения элементов из хранилища. -block.vault.description = Хранит большое количество предметов(1000). Используйте его для создания буферов, когда существует непостоянная потребность в материалах.[LIGHT_GRAY] Разгрузчик[] можно использовать для извлечения элементов из хранилища. +block.container.description = Хранит небольшое количество предметов(200). Используйте его для создания буферов, когда существует непостоянная потребность в материалах. [LIGHT_GRAY] Разгрузчик[] можно использовать для извлечения элементов из хранилища. +block.vault.description = Хранит большое количество предметов(900). Используйте его для создания буферов, когда существует непостоянная потребность в материалах.[LIGHT_GRAY] Разгрузчик[] можно использовать для извлечения элементов из хранилища. block.mechanical-drill.description = Самый первый доступный бур. \n\nДобывает медь, свинец, уголь, песок. \n\nМожно подвести к нему [BLUE] воду[] для увеличения скорости сверления. block.pneumatic-drill.description = Улучшенная версия механического бура.\n\nДобывает тоже самое, что и механический бур. Также может добывать титан и камень.\n\nМожно подвести к нему[BLUE] воду[] для увеличения скорости сверления. block.laser-drill.description = Улучшенная версия пневматического бура.\n\nДобывает тоже самое, что и пневматический бур. Также может добывать торий.\n\nМожно подвести к нему[BLUE] воду[] для увеличения скорости сверления. diff --git a/core/src/io/anuke/mindustry/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index a19a2a4048..8c1d7064db 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -83,7 +83,7 @@ public class Items implements ContentList{ }}; biomatter = new Item("biomatter", Color.valueOf("648b55")){{ - flammability = 0.4f; + flammability = 0.55f; fluxiness = 0.3f; }}; diff --git a/core/src/io/anuke/mindustry/content/Liquids.java b/core/src/io/anuke/mindustry/content/Liquids.java index f2e8ec6c0f..fc8bb44bfb 100644 --- a/core/src/io/anuke/mindustry/content/Liquids.java +++ b/core/src/io/anuke/mindustry/content/Liquids.java @@ -26,7 +26,7 @@ public class Liquids implements ContentList{ lava = new Liquid("lava", Color.valueOf("e37341")){ { - temperature = 0.8f; + temperature = 1f; viscosity = 0.8f; tier = 2; effect = StatusEffects.melting; diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index 88fb7b6a9e..589ef08b95 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -123,6 +123,7 @@ public class Mechs implements ContentList{ speed = 0.44f; drag = 0.35f; boostSpeed = 0.8f; + canHeal = true; weapon = Weapons.healBlaster; armor = 15f; trailColorTo = Palette.heal; @@ -287,8 +288,8 @@ public class Mechs implements ContentList{ trident = new Mech("trident-ship", true){ { drillPower = 2; - speed = 0.12f; - drag = 0.035f; + speed = 0.14f; + drag = 0.034f; mass = 2.5f; turnCursor = false; armor = 20f; diff --git a/core/src/io/anuke/mindustry/content/Weapons.java b/core/src/io/anuke/mindustry/content/Weapons.java index bc77a1e784..480c8988bf 100644 --- a/core/src/io/anuke/mindustry/content/Weapons.java +++ b/core/src/io/anuke/mindustry/content/Weapons.java @@ -152,7 +152,7 @@ public class Weapons implements ContentList{ bomberTrident = new Weapon("bomber"){{ length = 0f; width = 2f; - reload = 9f; + reload = 8f; shots = 2; roundrobin = true; ejectEffect = Fx.none; diff --git a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java index 86bb512d71..62471352da 100644 --- a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java @@ -192,9 +192,9 @@ public class CraftingBlocks extends BlockList implements ContentList{ biomatterCompressor = new Compressor("biomattercompressor"){{ liquidCapacity = 60f; itemCapacity = 50; - craftTime = 25f; + craftTime = 20f; outputLiquid = Liquids.oil; - outputLiquidAmount = 1.5f; + outputLiquidAmount = 2.5f; size = 2; health = 320; hasLiquids = true; diff --git a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java index 2e68c38b99..b4930a4647 100644 --- a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java @@ -99,13 +99,13 @@ public class ProductionBlocks extends BlockList implements ContentList{ cultivator = new Cultivator("cultivator"){{ result = Items.biomatter; - drillTime = 260; + drillTime = 200; size = 2; hasLiquids = true; hasPower = true; consumes.powerDirect(0.08f); - consumes.liquid(Liquids.water, 0.2f); + consumes.liquid(Liquids.water, 0.15f); }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java index a4519d04cb..9972317a99 100644 --- a/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/StorageBlocks.java @@ -27,7 +27,7 @@ public class StorageBlocks extends BlockList implements ContentList{ }}; unloader = new SortedUnloader("unloader"){{ - speed = 12f; + speed = 7f; }}; } } diff --git a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java index 48359ac757..86b7890a48 100644 --- a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java @@ -69,7 +69,7 @@ public class TurretBlocks extends BlockList implements ContentList{ inaccuracy = 5f; shootCone = 50f; shootEffect = ShootFx.shootLiquid; - range = 70f; + range = 90f; health = 360; drawer = (tile, entity) -> { diff --git a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java index 3b356f3251..1ec5252b02 100644 --- a/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java +++ b/core/src/io/anuke/mindustry/content/bullets/TurretBullets.java @@ -334,7 +334,7 @@ public class TurretBullets extends BulletList implements ContentList{ lifetime = 200f; despawneffect = BlockFx.smeltsmoke; hiteffect = BulletFx.hitBulletBig; - drag = 0.01f; + drag = 0.005f; } @Override diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index e70562a1db..c4708c9951 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -645,7 +645,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } protected void updateFlying(){ - if(Units.invalidateTarget(target, this)){ + if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team && + mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){ target = null; } @@ -726,11 +727,22 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra isShooting = false; if(Settings.getBool("autotarget")){ target = Units.getClosestTarget(team, x, y, getWeapon().getAmmo().getRange()); + + if(mech.canHeal && target == null){ + target = Geometry.findClosest(x, y, world.indexer.getDamaged(Team.blue)); + if(target != null && distanceTo(target) > getWeapon().getAmmo().getRange()){ + target = null; + }else if(target != null){ + target = ((Tile)target).entity; + } + } + if(target != null){ setMineTile(null); } } - }else if(target.isValid()){ + }else if(target.isValid() || (target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team && + mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){ //rotate toward and shoot the target if(mech.turnCursor){ rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f); diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index 8e021d53d7..926f033fc9 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.entities.traits; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Queue; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.blocks.Blocks; @@ -29,9 +30,7 @@ import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.graphics.Shapes; import io.anuke.ucore.util.Angles; -import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.util.Translator; import java.io.DataInput; import java.io.DataOutput; @@ -47,6 +46,7 @@ public interface BuilderTrait extends Entity{ //these are not instance variables! float placeDistance = 150f; float mineDistance = 70f; + Array removal = new Array<>(); /**Returns the queue for storing build requests.*/ Queue getPlaceQueue(); @@ -171,6 +171,19 @@ public interface BuilderTrait extends Entity{ * This includes mining. */ default void updateBuilding(Unit unit){ + //remove already completed build requests + removal.clear(); + for(BuildRequest request : getPlaceQueue()){ + if((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) || + (!request.breaking && world.tile(request.x, request.y).block() == request.recipe.result)){ + removal.add(request); + } + } + + for(BuildRequest req : removal){ + getPlaceQueue().removeValue(req, true); + } + BuildRequest current = getCurrentRequest(); //update mining here @@ -373,5 +386,18 @@ public interface BuilderTrait extends Entity{ this.recipe = Recipe.getByResult(world.tile(x, y).block()); this.breaking = true; } + + @Override + public String toString(){ + return "BuildRequest{" + + "x=" + x + + ", y=" + y + + ", rotation=" + rotation + + ", recipe=" + recipe + + ", breaking=" + breaking + + ", progress=" + progress + + ", initialized=" + initialized + + '}'; + } } } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/units/types/Drone.java index b0adfeb4d5..b47215d4ea 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Drone.java @@ -352,7 +352,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{ @Override public boolean canCreateBlocks(){ - return false; + return true; } @Override diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index 9379b8c917..f4272a40cb 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -96,6 +96,9 @@ public class MobileInput extends InputHandler implements GestureListener{ TileEntity entity = tile.entity; player.setMineTile(null); player.target = entity; + }else if(tile != null && player.mech.canHeal && tile.entity != null && tile.getTeam() == player.getTeam() && tile.entity.damaged()){ + player.setMineTile(null); + player.target = tile.entity; } } } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index c6706a43a7..c13fe96662 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -14,7 +14,7 @@ import java.util.zip.InflaterInputStream; import static io.anuke.mindustry.Vars.*; public class SaveIO{ - public static final IntArray breakingVersions = IntArray.with(47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58); + public static final IntArray breakingVersions = IntArray.with(47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 63); public static final IntMap versions = new IntMap<>(); public static final Array versionArray = Array.with( new Save16() diff --git a/core/src/io/anuke/mindustry/type/Mech.java b/core/src/io/anuke/mindustry/type/Mech.java index f075f1c2e1..744bf11be1 100644 --- a/core/src/io/anuke/mindustry/type/Mech.java +++ b/core/src/io/anuke/mindustry/type/Mech.java @@ -34,6 +34,7 @@ public class Mech extends UnlockableContent{ public Color trailColorTo = Palette.boostTo; public int itemCapacity = 30; public boolean turnCursor = true; + public boolean canHeal = false; public float weaponOffsetX, weaponOffsetY; public Weapon weapon = Weapons.blaster; diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index 6ffab178db..991f747387 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -45,9 +45,9 @@ public class Build{ for(int dx = 0; dx < previous.size; dx++){ for(int dy = 0; dy < previous.size; dy++){ - int worldx = dx + offsetx + x; - int worldy = dy + offsety + y; - if(!(worldx == x && worldy == y)){ + int worldx = dx + offsetx + tile.x; + int worldy = dy + offsety + tile.y; + if(!(worldx == tile.x && worldy == tile.y)){ Tile toplace = world.tile(worldx, worldy); if(toplace != null){ toplace.setLinked((byte) (dx + offsetx), (byte) (dy + offsety)); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java index 84ec99523e..c73ab0d2d0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidTank.java @@ -1,16 +1,8 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.Tile; - public class LiquidTank extends LiquidRouter{ public LiquidTank(String name){ super(name); } - - @Override - public boolean canDumpLiquid(Tile tile, Tile to, Liquid liquid){ - return super.canDumpLiquid(tile, to, liquid) && !(to.block() instanceof LiquidTank); - } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index 8a42b10828..86f39a786b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -46,7 +46,8 @@ public class PowerNode extends PowerBlock{ @Remote(targets = Loc.both, called = Loc.server, forward = true) public static void linkPowerNodes(Player player, Tile tile, Tile other){ - if(tile.entity.power == null || !((PowerNode)tile.block()).linkValid(tile, other)) return; + if(tile.entity.power == null || !((PowerNode)tile.block()).linkValid(tile, other) + || tile.entity.power.links.size >= ((PowerNode)tile.block()).maxNodes) return; TileEntity entity = tile.entity(); diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index 9845480b31..b690f63880 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -5,21 +5,22 @@ import com.badlogic.gdx.math.GridPoint2; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.UnitTypes; -import io.anuke.mindustry.content.blocks.Blocks; -import io.anuke.mindustry.content.blocks.CraftingBlocks; -import io.anuke.mindustry.content.blocks.PowerBlocks; -import io.anuke.mindustry.content.blocks.StorageBlocks; +import io.anuke.mindustry.content.blocks.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.Logic; import io.anuke.mindustry.core.NetServer; import io.anuke.mindustry.core.World; +import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.units.BaseUnit; +import io.anuke.mindustry.entities.units.types.Spirit; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.BundleLoader; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.Map; +import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Edges; import io.anuke.mindustry.world.Tile; @@ -229,6 +230,70 @@ public class ApplicationTests{ assertEquals(8, edges2.length); } + @Test + void buildingOverlap(){ + initBuilding(); + + Spirit d1 = (Spirit) UnitTypes.spirit.create(Team.blue); + Spirit d2 = (Spirit) UnitTypes.spirit.create(Team.blue); + + d1.set(10f, 20f); + d2.set(10f, 20f); + + d1.addBuildRequest(new BuildRequest(0, 0, 0, Recipe.getByResult(DefenseBlocks.copperWallLarge))); + d2.addBuildRequest(new BuildRequest(1, 1, 0, Recipe.getByResult(DefenseBlocks.copperWallLarge))); + + Timers.setDeltaProvider(() -> 9999999f); + d1.updateBuilding(d1); + d2.updateBuilding(d2); + + assertEquals(DefenseBlocks.copperWallLarge, world.tile(0, 0).block()); + assertEquals(Blocks.air, world.tile(2, 2).block()); + assertEquals(Blocks.blockpart, world.tile(1, 1).block()); + } + + @Test + void buildingDestruction(){ + initBuilding(); + + Spirit d1 = (Spirit) UnitTypes.spirit.create(Team.blue); + Spirit d2 = (Spirit) UnitTypes.spirit.create(Team.blue); + + d1.set(10f, 20f); + d2.set(10f, 20f); + + d1.addBuildRequest(new BuildRequest(0, 0, 0, Recipe.getByResult(DefenseBlocks.copperWallLarge))); + d2.addBuildRequest(new BuildRequest(1, 1)); + + Timers.setDeltaProvider(() -> 3f); + d1.updateBuilding(d1); + Timers.setDeltaProvider(() -> 1f); + d2.updateBuilding(d2); + + assertEquals(content.getByName(ContentType.block, "build2"), world.tile(0, 0).block()); + + Timers.setDeltaProvider(() -> 9999f); + + d1.updateBuilding(d1); + d2.updateBuilding(d2); + + assertEquals(Blocks.air, world.tile(0, 0).block()); + assertEquals(Blocks.air, world.tile(2, 2).block()); + assertEquals(Blocks.air, world.tile(1, 1).block()); + } + + void initBuilding(){ + createMap(); + + Tile core = world.tile(5, 5); + world.setBlock(core, StorageBlocks.core, Team.blue); + for(Item item : content.items()){ + core.entity.items.set(item, 3000); + } + + assertEquals(core, state.teams.get(Team.blue).cores.first()); + } + void depositTest(Block block, Item item){ BaseUnit unit = UnitTypes.alphaDrone.create(Team.none); Tile tile = new Tile(0, 0, Blocks.air.id, block.id);