From 603c871e6e51e31e5fd078af41eb5bcf222bc550 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 28 Sep 2021 18:52:48 -0400 Subject: [PATCH 01/12] apparently the --illegal-access flag is still needed --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index dd8fe4d610..310fedd629 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ org.gradle.daemon=true -org.gradle.jvmargs=-Xms256m -Xmx1024m \ +org.gradle.jvmargs=-Xms256m -Xmx1024m --illegal-access=permit \ --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \ --add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \ From 01d6aee754259d4f8ea73399afac11062e16e868 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 28 Sep 2021 21:43:40 -0300 Subject: [PATCH 02/12] Add MindustryBR network (#6074) Come to Brazil --- servers_v6.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servers_v6.json b/servers_v6.json index 986f1965d3..bdd00b390b 100644 --- a/servers_v6.json +++ b/servers_v6.json @@ -114,5 +114,9 @@ { "name": "NukeDustry", "address": ["nukedustry.tk", "nukedustry.tk:6568"] + }, + { + "name": "MindustryBR", + "address": ["mindustryptbr.ddns.net", "mindustryptbr.myddns.me", "mindustryptbr.myddns.me:6566"] } ] From a04b385f56efb8832319bcce982b4fab479b1876 Mon Sep 17 00:00:00 2001 From: Matthew Peng <54301439+MEEPofFaith@users.noreply.github.com> Date: Wed, 29 Sep 2021 05:38:51 -0700 Subject: [PATCH 03/12] Fix spread + burst turrets (#6069) * Fix spread + burst turrets * spread is 4 by default set salvo spread to 0 * damnit --- core/src/mindustry/content/Blocks.java | 1 + core/src/mindustry/world/blocks/defense/turrets/Turret.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 295977b2ed..c2697d7487 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1675,6 +1675,7 @@ public class Blocks implements ContentList{ recoilAmount = 3f; shootShake = 1f; burstSpacing = 3f; + spread = 0f; shots = 4; ammoUseEffect = Fx.casing2; health = 240 * size * size; diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 99412528dc..fc64c37c7d 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -426,13 +426,14 @@ public class Turret extends ReloadTurret{ //when burst spacing is enabled, use the burst pattern }else if(burstSpacing > 0.0001f){ for(int i = 0; i < shots; i++){ + int ii = i; Time.run(burstSpacing * i, () -> { if(!isValid() || !hasAmmo()) return; recoil = recoilAmount; tr.trns(rotation, shootLength, Mathf.range(xRand)); - bullet(type, rotation + Mathf.range(inaccuracy)); + bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy) + (ii - (int)(shots / 2f)) * spread); effects(); useAmmo(); recoil = recoilAmount; From efb9df7b1b62adab6396abb2573a2885ca0f9c28 Mon Sep 17 00:00:00 2001 From: EyeOfDarkness <64228877+EyeOfDarkness@users.noreply.github.com> Date: Thu, 30 Sep 2021 07:35:47 +0800 Subject: [PATCH 04/12] Recoil Time and Improved Alternating (#6073) * Revamped recoil, and improved alternating * i might have to make this more complicated later * hhhhhhhhh * proper description. --- .../mindustry/entities/units/WeaponMount.java | 2 ++ core/src/mindustry/type/UnitType.java | 5 +++- core/src/mindustry/type/Weapon.java | 24 +++++++++++-------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/core/src/mindustry/entities/units/WeaponMount.java b/core/src/mindustry/entities/units/WeaponMount.java index 8254c8ca2f..bd8b5d73e4 100644 --- a/core/src/mindustry/entities/units/WeaponMount.java +++ b/core/src/mindustry/entities/units/WeaponMount.java @@ -12,6 +12,8 @@ public class WeaponMount{ public float reload; /** rotation relative to the unit this mount is on */ public float rotation; + /** weapon recoil */ + public float recoil; /** destination rotation; do not modify! */ public float targetRotation; /** current heat, 0 to 1*/ diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 7d7357b871..f9fcf6b078 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -375,6 +375,7 @@ public class UnitType extends UnlockableContent{ //add mirrored weapon variants Seq mapped = new Seq<>(); for(Weapon w : weapons){ + if(w.recoilTime < 0) w.recoilTime = w.reload; mapped.add(w); //mirrors are copies with X values negated @@ -385,7 +386,9 @@ public class UnitType extends UnlockableContent{ copy.flipSprite = !copy.flipSprite; mapped.add(copy); - //since there are now two weapons, the reload time must be doubled + //since there are now two weapons, the reload and recoil time must be doubled + w.recoilTime *= 2f; + copy.recoilTime *= 2f; w.reload *= 2f; copy.reload *= 2f; diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index c96482d15d..f472f7a03a 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -67,6 +67,8 @@ public class Weapon implements Cloneable{ public float shake = 0f; /** visual weapon knockback. */ public float recoil = 1.5f; + /** the time it returns back to its original position in ticks. uses reload time by default */ + public float recoilTime = -1f; /** projectile/effect offsets from center of weapon */ public float shootX = 0f, shootY = 3f; /** offsets of weapon position on unit */ @@ -144,9 +146,8 @@ public class Weapon implements Cloneable{ float rotation = unit.rotation - 90, weaponRotation = rotation + (rotate ? mount.rotation : 0), - recoil = -((mount.reload) / reload * this.recoil), - wx = unit.x + Angles.trnsx(rotation, x, y) + Angles.trnsx(weaponRotation, 0, recoil), - wy = unit.y + Angles.trnsy(rotation, x, y) + Angles.trnsy(weaponRotation, 0, recoil); + wx = unit.x + Angles.trnsx(rotation, x, y) + Angles.trnsx(weaponRotation, 0, -mount.recoil), + wy = unit.y + Angles.trnsy(rotation, x, y) + Angles.trnsy(weaponRotation, 0, -mount.recoil); if(outlineRegion.found()){ Draw.rect(outlineRegion, @@ -161,9 +162,8 @@ public class Weapon implements Cloneable{ float rotation = unit.rotation - 90, weaponRotation = rotation + (rotate ? mount.rotation : 0), - recoil = -((mount.reload) / reload * this.recoil), - wx = unit.x + Angles.trnsx(rotation, x, y) + Angles.trnsx(weaponRotation, 0, recoil), - wy = unit.y + Angles.trnsy(rotation, x, y) + Angles.trnsy(weaponRotation, 0, recoil); + wx = unit.x + Angles.trnsx(rotation, x, y) + Angles.trnsx(weaponRotation, 0, -mount.recoil), + wy = unit.y + Angles.trnsy(rotation, x, y) + Angles.trnsy(weaponRotation, 0, -mount.recoil); if(shadow > 0){ Drawf.shadow(wx, wy, shadow); @@ -198,7 +198,9 @@ public class Weapon implements Cloneable{ public void update(Unit unit, WeaponMount mount){ boolean can = unit.canShoot(); + float lastReload = mount.reload; mount.reload = Math.max(mount.reload - Time.delta * unit.reloadMultiplier, 0); + mount.recoil = Math.max(mount.recoil - (Time.delta * recoil * unit.reloadMultiplier) / recoilTime, 0); //rotate if applicable if(rotate && (mount.rotate || mount.shoot) && can){ @@ -260,6 +262,7 @@ public class Weapon implements Cloneable{ mount.bullet.rotation(weaponRotation + 90); mount.bullet.set(bulletX, bulletY); mount.reload = reload; + mount.recoil = recoil; unit.vel.add(Tmp.v1.trns(unit.rotation + 180f, mount.bullet.type.recoil)); if(shootSound != Sounds.none && !headless){ if(mount.sound == null) mount.sound = new SoundLoop(shootSound, 1f); @@ -275,9 +278,9 @@ public class Weapon implements Cloneable{ } } - //flip weapon shoot side for alternating weapons at half reload - if(otherSide != -1 && alternate && mount.side == flipSprite && - mount.reload + Time.delta * unit.reloadMultiplier > reload/2f && mount.reload <= reload/2f){ + //flip weapon shoot side for alternating weapons + boolean wasFlipped = mount.side; + if(otherSide != -1 && alternate && mount.side == flipSprite && mount.reload <= reload / 2f && lastReload > reload / 2f){ unit.mounts[otherSide].side = !unit.mounts[otherSide].side; mount.side = !mount.side; } @@ -286,7 +289,7 @@ public class Weapon implements Cloneable{ if(mount.shoot && //must be shooting can && //must be able to shoot (!useAmmo || unit.ammo > 0 || !state.rules.unitAmmo || unit.team.rules().infiniteAmmo) && //check ammo - (!alternate || mount.side == flipSprite) && + (!alternate || wasFlipped == flipSprite) && unit.vel.len() >= minShootVelocity && //check velocity requirements mount.reload <= 0.0001f && //reload has to be 0 Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, shootCone) //has to be within the cone @@ -354,6 +357,7 @@ public class Weapon implements Cloneable{ mount.heat = 1f; } + mount.recoil = recoil; ejectEffect.at(mountX, mountY, rotation * side); ammo.shootEffect.at(shootX, shootY, rotation, parentize ? unit : null); ammo.smokeEffect.at(shootX, shootY, rotation, parentize ? unit : null); From 6f6590d5bb9fd2b9510e0bab284f667559e29f40 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 29 Sep 2021 22:39:33 -0400 Subject: [PATCH 05/12] chargeShootEffect / Effect startDelay --- core/src/mindustry/core/Platform.java | 2 +- core/src/mindustry/entities/Effect.java | 37 +++++++++++++------ .../mindustry/entities/bullet/BulletType.java | 2 + .../maps/generators/PlanetGenerator.java | 4 +- core/src/mindustry/type/Weapon.java | 1 + gradle.properties | 2 +- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/core/src/mindustry/core/Platform.java b/core/src/mindustry/core/Platform.java index bbceee8a64..cf115e3b40 100644 --- a/core/src/mindustry/core/Platform.java +++ b/core/src/mindustry/core/Platform.java @@ -120,7 +120,7 @@ public interface Platform{ }else{ ui.loadAnd(() -> { try{ - Fi result = Core.files.local(name+ "." + extension); + Fi result = Core.files.local(name + "." + extension); writer.write(result); platform.shareFile(result); }catch(Throwable e){ diff --git a/core/src/mindustry/entities/Effect.java b/core/src/mindustry/entities/Effect.java index 4d298eb40f..4a8961d8f4 100644 --- a/core/src/mindustry/entities/Effect.java +++ b/core/src/mindustry/entities/Effect.java @@ -30,6 +30,8 @@ public class Effect{ public float lifetime = 50f; /** Clip size. */ public float clip; + /** Time delay before the effect starts */ + public float startDelay; /** Amount added to rotation */ public float baseRotation; /** If true, parent unit is data are followed. */ @@ -58,6 +60,11 @@ public class Effect{ all.add(this); } + public Effect startDelay(float d){ + startDelay = d; + return this; + } + public void init(){} public Effect followParent(boolean follow){ @@ -168,21 +175,29 @@ public class Effect{ effect.init(); } - EffectState entity = EffectState.create(); - entity.effect = effect; - entity.rotation = effect.baseRotation + rotation; - entity.data = data; - entity.lifetime = effect.lifetime; - entity.set(x, y); - entity.color.set(color); - if(effect.followParent && data instanceof Posc p){ - entity.parent = p; - entity.rotWithParent = effect.rotWithParent; + if(effect.startDelay <= 0f){ + inst(effect, x, y, rotation, color, data); + }else{ + Time.runTask(effect.startDelay, () -> inst(effect, x, y, rotation, color, data)); } - entity.add(); } } + private static void inst(Effect effect, float x, float y, float rotation, Color color, Object data){ + EffectState entity = EffectState.create(); + entity.effect = effect; + entity.rotation = effect.baseRotation + rotation; + entity.data = data; + entity.lifetime = effect.lifetime; + entity.set(x, y); + entity.color.set(color); + if(effect.followParent && data instanceof Posc p){ + entity.parent = p; + entity.rotWithParent = effect.rotWithParent; + } + entity.add(); + } + public static void decal(TextureRegion region, float x, float y, float rotation){ decal(region, x, y, rotation, 3600f, Pal.rubble); } diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 062c8cc965..7e515281bb 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -49,6 +49,8 @@ public class BulletType extends Content implements Cloneable{ public Effect despawnEffect = Fx.hitBulletSmall; /** Effect created when shooting. */ public Effect shootEffect = Fx.shootSmall; + /** Effect created when charging completes; only usable in single-shot weapons with a firstShotDelay / shotDelay. */ + public Effect chargeShootEffect = Fx.none; /** Extra smoke effect created when shooting. */ public Effect smokeEffect = Fx.shootSmallSmoke; /** Sound made when hitting something or getting removed.*/ diff --git a/core/src/mindustry/maps/generators/PlanetGenerator.java b/core/src/mindustry/maps/generators/PlanetGenerator.java index a8f0e00e26..3533943b19 100644 --- a/core/src/mindustry/maps/generators/PlanetGenerator.java +++ b/core/src/mindustry/maps/generators/PlanetGenerator.java @@ -76,7 +76,7 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe //sort counts in descending order Seq> entries = floorc.entries().toArray(); entries.sort(e -> -e.value); - //remove all blocks occuring < 30 times - unimportant + //remove all blocks occurring < 30 times - unimportant entries.removeAll(e -> e.value < 30); Block[] floors = new Block[entries.size]; @@ -84,7 +84,7 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe floors[i] = entries.get(i).key; } - //TODO bad code + //bad contains() code, but will likely never be fixed boolean hasSnow = floors.length > 0 && (floors[0].name.contains("ice") || floors[0].name.contains("snow")); boolean hasRain = floors.length > 0 && !hasSnow && content.contains(Liquids.water) && !floors[0].name.contains("sand"); boolean hasDesert = floors.length > 0 && !hasSnow && !hasRain && floors[0] == Blocks.sand; diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index f472f7a03a..fe3bbda604 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -350,6 +350,7 @@ public class Weapon implements Cloneable{ if(!continuous){ shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); } + ammo.chargeShootEffect.at(shootX + unit.x - baseX, shootY + unit.y - baseY, rotation, parentize ? unit : null); }); }else{ unit.vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil)); diff --git a/gradle.properties b/gradle.properties index 310fedd629..d9b8a9312d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,4 +24,4 @@ android.useAndroidX=true #used for slow jitpack builds; TODO see if this actually works org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 -archash=57b15a1b73cf0d6f19a50d2111f43d993e57c7f1 +archash=6a2c848995763acaaf4e5ee2d589f53f49c7c4c1 From 78a4572388f0cefe4f5b710eff1d5c5e9c9ad45d Mon Sep 17 00:00:00 2001 From: buthed010203 Date: Thu, 30 Sep 2021 13:01:52 -0400 Subject: [PATCH 06/12] Add "infotable" name to hudfrag (#6082) In another attempt to make my client more compatible with mods, I am adding this so it can be found by name rather than by index --- core/src/mindustry/ui/fragments/HudFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index cf54cb6eae..bfe976d3f3 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -778,6 +778,7 @@ public class HudFragment extends Fragment{ } private void addInfoTable(Table table){ + table.name = "infotable"; table.left(); var count = new float[]{-1}; From 558fb26dcb03862fca9c53575a1ebb8a81d9144e Mon Sep 17 00:00:00 2001 From: Yuri Polyakov <86189625+Kowkodivka@users.noreply.github.com> Date: Fri, 1 Oct 2021 00:03:28 +0700 Subject: [PATCH 07/12] Update bundle_ru.properties (#6078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit б --- core/assets/bundles/bundle_ru.properties | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index b1b4f83362..4aefb5a02d 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -445,7 +445,7 @@ editor.overwrite = [accent]Внимание!\nЭто перезапишет уж editor.overwrite.confirm = [scarlet]Осторожно![] Карта с таким названием уже существует. Вы действительно хотите её перезаписать?\n«[accent]{0}[]» editor.exists = Карта с таким именем уже существует. editor.selectmap = Выберите карту для загрузки: -editor.cliffs = Стены на скалы +editor.cliffs = Создать скалы из стен toolmode.replace = Заменить toolmode.replace.description = Рисует только\nна сплошных блоках. @@ -540,6 +540,7 @@ configure = Конфигурация выгрузки loadout = Груз resources = Ресурсы bannedblocks = Запрещённые блоки +bannedunits = Запрещённые единицы addall = Добавить всё launch.from = Запуск из: [accent]{0} launch.destination = Место назначения: {0} @@ -564,10 +565,13 @@ weather.sandstorm.name = Пыльная буря weather.sporestorm.name = Споровая буря weather.fog.name = Туман +sectorlist = Секторы +sectorlist.attacked = {0} под атакой sectors.unexplored = [lightgray]Не исследовано sectors.resources = Ресурсы: sectors.production = Производит: sectors.export = Экспорт: +sectors.import = Импорт: sectors.time = Время: sectors.threat = Угроза: sectors.wave = Волна: @@ -995,6 +999,7 @@ mode.attack.name = Атака mode.attack.description = Уничтожьте вражескую базу.\n[gray]Для игры требуется красное ядро на карте. mode.custom = Пользовательские правила +rules.cleanupdeadteams = Очистка строений побежденных команд (PvP) rules.infiniteresources = Бесконечные ресурсы (Игрок) rules.reactorexplosions = Взрывы реакторов rules.coreincinerates = Ядро сжигает избыток ресурсов @@ -1009,6 +1014,7 @@ rules.enemyCheat = Бесконечные ресурсы ИИ (красная к rules.blockhealthmultiplier = Множитель прочности блоков rules.blockdamagemultiplier = Множитель урона блоков rules.unitbuildspeedmultiplier = Множитель скорости производства боев. ед. +rules.aitier = Уровень ИИ rules.unithealthmultiplier = Множитель прочности боев. ед. rules.unitdamagemultiplier = Множитель урона боев. ед. rules.unitcapvariable = Ядра увеличивают лимит единиц @@ -1030,6 +1036,8 @@ rules.title.environment = Окружение rules.lighting = Освещение rules.enemyLights = Вражеские огни rules.fire = Огонь +rules.enemyteam = Команда Врагов +rules.playerteam = Команда Игрока rules.explosions = Урон от взрывов блоков/единиц rules.ambientlight = Окружающий свет rules.weather = Погода From e0b1c49e0b108b255873babeba51f35c85e270c7 Mon Sep 17 00:00:00 2001 From: Matthew Peng <54301439+MEEPofFaith@users.noreply.github.com> Date: Thu, 30 Sep 2021 14:01:24 -0700 Subject: [PATCH 08/12] Fix weapon recoiling (#6083) Weapons recoil when the begin charging --- core/src/mindustry/type/Weapon.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index fe3bbda604..43b1091312 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -346,6 +346,7 @@ public class Weapon implements Cloneable{ unit.vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil)); Effect.shake(shake, shake, shootX, shootY); + mount.recoil = recoil; mount.heat = 1f; if(!continuous){ shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); @@ -355,10 +356,10 @@ public class Weapon implements Cloneable{ }else{ unit.vel.add(Tmp.v1.trns(rotation + 180f, ammo.recoil)); Effect.shake(shake, shake, shootX, shootY); + mount.recoil = recoil; mount.heat = 1f; } - mount.recoil = recoil; ejectEffect.at(mountX, mountY, rotation * side); ammo.shootEffect.at(shootX, shootY, rotation, parentize ? unit : null); ammo.smokeEffect.at(shootX, shootY, rotation, parentize ? unit : null); From c2261276487c3dc52990c1f603fa757c0d0cded0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 30 Sep 2021 17:33:17 -0400 Subject: [PATCH 09/12] Display jump statement destination --- core/src/mindustry/logic/LCanvas.java | 12 +++++++++++- core/src/mindustry/logic/LStatements.java | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index da604532cb..2537296566 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -217,6 +217,7 @@ public class LCanvas extends Table{ e.setSize(width, e.getPrefHeight()); e.setPosition(0, height - cy, Align.topLeft); + ((StatementElem)e).updateAddress(i); cy += e.getPrefHeight() + space; seq.add(e); @@ -316,6 +317,8 @@ public class LCanvas extends Table{ public class StatementElem extends Table{ public LStatement st; + public int index; + Label addressLabel; public StatementElem(LStatement st){ this.st = st; @@ -333,9 +336,11 @@ public class LCanvas extends Table{ t.margin(6f); t.touchable = Touchable.enabled; - t.add(st.name()).style(Styles.outlineLabel).color(color).padRight(8); + t.add(st.name()).style(Styles.outlineLabel).name("statement-name").color(color).padRight(8); t.add().growX(); + addressLabel = t.add(index + "").style(Styles.outlineLabel).color(color).padRight(8).get(); + t.button(Icon.copy, Styles.logici, () -> { }).size(24f).padRight(6).get().tapped(this::copy); @@ -395,6 +400,11 @@ public class LCanvas extends Table{ marginBottom(7); } + public void updateAddress(int index){ + this.index = index; + addressLabel.setText(index + ""); + } + public void copy(){ st.saveUI(); LStatement copy = st.copy(); diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 1d04b21052..1dd2313baf 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -1,5 +1,6 @@ package mindustry.logic; +import arc.*; import arc.func.*; import arc.graphics.*; import arc.scene.style.*; @@ -758,6 +759,20 @@ public class LStatements{ table.add().growX(); table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8); + + String name = name(); + + //hack way of finding the title label... + Core.app.post(() -> { + //must be delayed because parent is added later + if(table.parent != null){ + Label title = table.parent.find("statement-name"); + if(title != null){ + title.update(() -> title.setText((dest != null ? name + " -> " + dest.index : name))); + } + } + }); + } void rebuild(Table table){ From 0483e3f900e397b05572b57ac4f663f0c605b6e2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 30 Sep 2021 18:22:50 -0400 Subject: [PATCH 10/12] Serpulo naval wave support --- core/src/mindustry/game/Waves.java | 12 ++ .../maps/planet/SerpuloPlanetGenerator.java | 148 +++++++++++++++--- core/src/mindustry/type/UnitType.java | 3 +- .../world/blocks/environment/Floor.java | 2 + .../blocks/environment/ShallowLiquid.java | 1 + 5 files changed, 139 insertions(+), 27 deletions(-) diff --git a/core/src/mindustry/game/Waves.java b/core/src/mindustry/game/Waves.java index 8e7bf7a63c..848b4ecf96 100644 --- a/core/src/mindustry/game/Waves.java +++ b/core/src/mindustry/game/Waves.java @@ -265,10 +265,16 @@ public class Waves{ } public static Seq generate(float difficulty, Rand rand, boolean attack, boolean airOnly){ + return generate(difficulty, rand, attack, airOnly, false); + } + + public static Seq generate(float difficulty, Rand rand, boolean attack, boolean airOnly, boolean naval){ UnitType[][] species = { {dagger, mace, fortress, scepter, reign}, {nova, pulsar, quasar, vela, corvus}, {crawler, atrax, spiroct, arkyid, toxopid}, + {risso, minke, bryde, sei, omura}, + {risso, oxynoe, cyerce, aegires, navanax}, //retusa intentionally left out as it cannot damage the core properly {flare, horizon, zenith, rand.chance(0.5) ? quad : antumbra, rand.chance(0.1) ? quad : eclipse} }; @@ -276,6 +282,12 @@ public class Waves{ species = Structs.filter(UnitType[].class, species, v -> v[0].flying); } + if(naval){ + species = Structs.filter(UnitType[].class, species, v -> v[0].flying || v[0].naval); + }else{ + species = Structs.filter(UnitType[].class, species, v -> v[0].flying && !v[0].naval); + } + UnitType[][] fspec = species; //required progression: diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java index adcc67c603..23047fd503 100644 --- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java @@ -14,6 +14,7 @@ import mindustry.graphics.g3d.PlanetGrid.*; import mindustry.maps.generators.*; import mindustry.type.*; import mindustry.world.*; +import mindustry.world.blocks.environment.*; import static mindustry.Vars.*; @@ -165,14 +166,14 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ connected.add(this); } - void con(int x1, int y1, int x2, int y2){ + void join(int x1, int y1, int x2, int y2){ float nscl = rand.random(100f, 140f) * 6f; int stroke = rand.random(3, 9); brush(pathfind(x1, y1, x2, y2, tile -> (tile.solid() ? 50f : 0f) + noise(tile.x, tile.y, 2, 0.4f, 1f / nscl) * 500, Astar.manhattan), stroke); } void connect(Room to){ - if(!connected.add(to)) return; + if(!connected.add(to) || to == this) return; Vec2 midpoint = Tmp.v1.set(to.x, to.y).add(x, y).scl(0.5f); rand.nextFloat(); @@ -188,8 +189,52 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ int mx = (int)midpoint.x, my = (int)midpoint.y; - con(x, y, mx, my); - con(mx, my, to.x, to.y); + join(x, y, mx, my); + join(mx, my, to.x, to.y); + } + + void joinLiquid(int x1, int y1, int x2, int y2){ + float nscl = rand.random(100f, 140f) * 6f; + int rad = rand.random(5, 10); + int avoid = 2 + rad; + var path = pathfind(x1, y1, x2, y2, tile -> (tile.solid() || !tile.floor().isLiquid ? 70f : 0f) + noise(tile.x, tile.y, 2, 0.4f, 1f / nscl) * 500, Astar.manhattan); + path.each(t -> { + //don't place liquid paths near the core + if(Mathf.dst2(t.x, t.y, x2, y2) <= avoid * avoid){ + return; + } + + for(int x = -rad; x <= rad; x++){ + for(int y = -rad; y <= rad; y++){ + int wx = t.x + x, wy = t.y + y; + if(Structs.inBounds(wx, wy, width, height) && Mathf.within(x, y, rad)){ + Tile other = tiles.getn(wx, wy); + other.setBlock(Blocks.air); + if(Mathf.within(x, y, rad - 1) && !other.floor().isLiquid){ + Floor floor = other.floor(); + //TODO does not respect tainted floors + other.setFloor((Floor)(floor == Blocks.sand || floor == Blocks.salt ? Blocks.sandWater : Blocks.darksandTaintedWater)); + } + } + } + } + }); + } + + void connectLiquid(Room to){ + if(to == this) return; + + Vec2 midpoint = Tmp.v1.set(to.x, to.y).add(x, y).scl(0.5f); + rand.nextFloat(); + + //add randomized offset to avoid straight lines + midpoint.add(Tmp.v2.setToRandomDirection(rand).scl(Tmp.v1.dst(x, y))); + midpoint.sub(width/2f, height/2f).limit(width / 2f / Mathf.sqrt3).add(width/2f, height/2f); + + int mx = (int)midpoint.x, my = (int)midpoint.y; + + joinLiquid(x, y, mx, my); + joinLiquid(mx, my, to.x, to.y); } } @@ -250,10 +295,12 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ } } + //clear radius around each room for(Room room : roomseq){ erase(room.x, room.y, room.radius); } + //randomly connect rooms together int connections = rand.random(Math.max(rooms - 1, 1), rooms + 3); for(int i = 0; i < connections; i++){ roomseq.random(rand).connect(roomseq.random(rand)); @@ -267,30 +314,29 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ cells(1); - //shoreline setup - int deepRadius = 4; + int tlen = tiles.width * tiles.height; + int total = 0, waters = 0; - pass((x, y) -> { - if(floor.asFloor().isLiquid && !floor.asFloor().isDeep()){ - - for(int cx = -deepRadius; cx <= deepRadius; cx++){ - for(int cy = -deepRadius; cy <= deepRadius; cy++){ - - if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){ - int wx = cx + x, wy = cy + y; - - Tile tile = tiles.get(wx, wy); - if(tile != null && (!tile.floor().isLiquid || tile.block() != Blocks.air)){ - //found something solid, skip replacing anything - return; - } - } - } + for(int i = 0; i < tlen; i++){ + Tile tile = tiles.geti(i); + if(tile.block() == Blocks.air){ + total ++; + if(tile.floor().liquidDrop == Liquids.water){ + waters ++; } - - floor = floor == Blocks.darksandTaintedWater ? Blocks.taintedWater : Blocks.water; } - }); + } + + boolean naval = (float)waters / total >= 0.28f; + + Log.info(waters + " " + total ); + + //create water pathway if the map is flooded + if(naval){ + for(Room room : enemies){ + room.connectLiquid(spawn); + } + } distort(10f, 6f); @@ -318,6 +364,56 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ } }); + //shoreline setup + pass((x, y) -> { + int deepRadius = 3; + + if(floor.asFloor().isLiquid && floor.asFloor().shallow){ + + for(int cx = -deepRadius; cx <= deepRadius; cx++){ + for(int cy = -deepRadius; cy <= deepRadius; cy++){ + if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){ + int wx = cx + x, wy = cy + y; + + Tile tile = tiles.get(wx, wy); + if(tile != null && (!tile.floor().isLiquid || tile.block() != Blocks.air)){ + //found something solid, skip replacing anything + return; + } + } + } + } + + floor = floor == Blocks.darksandTaintedWater ? Blocks.taintedWater : Blocks.water; + } + }); + + if(naval){ + int deepRadius = 2; + + //TODO code is very similar, but annoying to extract into a separate function + pass((x, y) -> { + if(floor.asFloor().isLiquid && !floor.asFloor().isDeep() && !floor.asFloor().shallow){ + + for(int cx = -deepRadius; cx <= deepRadius; cx++){ + for(int cy = -deepRadius; cy <= deepRadius; cy++){ + if((cx) * (cx) + (cy) * (cy) <= deepRadius * deepRadius){ + int wx = cx + x, wy = cy + y; + + Tile tile = tiles.get(wx, wy); + if(tile != null && (tile.floor().shallow || !tile.floor().isLiquid)){ + //found something shallow, skip replacing anything + return; + } + } + } + } + + floor = floor == Blocks.water ? Blocks.deepwater : Blocks.deepTaintedWater; + } + }); + } + Seq ores = Seq.with(Blocks.oreCopper, Blocks.oreLead); float poles = Math.abs(sector.tile.v.y); float nmag = 0.5f; @@ -555,7 +651,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ state.rules.enemyCoreBuildRadius = 600f; //spawn air only when spawn is blocked - state.rules.spawns = Waves.generate(difficulty, new Rand(sector.id), state.rules.attackMode, state.rules.attackMode && spawner.countGroundSpawns() == 0); + state.rules.spawns = Waves.generate(difficulty, new Rand(sector.id), state.rules.attackMode, state.rules.attackMode && spawner.countGroundSpawns() == 0, naval); } @Override diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index f9fcf6b078..895fcc1f15 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -111,7 +111,7 @@ public class UnitType extends UnlockableContent{ /** This is a VERY ROUGH estimate of unit DPS. */ public float dpsEstimate = -1; public float clipSize = -1; - public boolean canDrown = true; + public boolean canDrown = true, naval = false; public float engineOffset = 5f, engineSize = 2.5f; public float strafePenalty = 0.5f; public float hitSize = 6f; @@ -314,6 +314,7 @@ public class UnitType extends UnlockableContent{ //water preset if(example instanceof WaterMovec){ + naval = true; canDrown = false; omniMovement = false; immunities.add(StatusEffects.wet); diff --git a/core/src/mindustry/world/blocks/environment/Floor.java b/core/src/mindustry/world/blocks/environment/Floor.java index c2fa4c1165..ddad7804b3 100644 --- a/core/src/mindustry/world/blocks/environment/Floor.java +++ b/core/src/mindustry/world/blocks/environment/Floor.java @@ -48,6 +48,8 @@ public class Floor extends Block{ public float liquidMultiplier = 1f; /** whether this block is liquid. */ public boolean isLiquid; + /** shallow water flag used for generation */ + public boolean shallow = false; /** if true, this block cannot be mined by players. useful for annoying things like sand. */ public boolean playerUnmineable = false; /** Group of blocks that this block does not draw edges on. */ diff --git a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java index bea6797f37..4ab54e1086 100644 --- a/core/src/mindustry/world/blocks/environment/ShallowLiquid.java +++ b/core/src/mindustry/world/blocks/environment/ShallowLiquid.java @@ -24,5 +24,6 @@ public class ShallowLiquid extends Floor{ status = liquidBase.status; liquidDrop = liquidBase.liquidDrop; cacheLayer = liquidBase.cacheLayer; + shallow = true; } } From ee26f51d7adb2d50869feeade2a0fc0bc350ae81 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 30 Sep 2021 18:32:31 -0400 Subject: [PATCH 11/12] Cleanup --- core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java index 23047fd503..48962fea7a 100644 --- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java @@ -327,9 +327,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ } } - boolean naval = (float)waters / total >= 0.28f; - - Log.info(waters + " " + total ); + boolean naval = (float)waters / total >= 0.26f; //create water pathway if the map is flooded if(naval){ From b265ddac03e6cd434811ead1a4d037f5e17ea3e0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 1 Oct 2021 09:28:23 -0400 Subject: [PATCH 12/12] Don't suggest changing the mod disable option --- 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 3dab21b6e4..7f111740ff 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -122,7 +122,7 @@ committingchanges = Committing Changes done = Done feature.unsupported = Your device does not support this feature. -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.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.[] mods = Mods mods.none = [lightgray]No mods found! mods.guide = Modding Guide