Compare commits

..

59 Commits
v127 ... v127.2

Author SHA1 Message Date
RebornTrack970
4dcac119d8 Updated TR Bundle to the latest V7 prealpha (#5505)
* Updated TR Bundle to the latest V7 prealpha

* Update bundle_tr.properties
2021-06-30 13:24:52 -04:00
Anuken
f9dfd5b0b5 Commented out separator revision until 128 release 2021-06-30 13:08:19 -04:00
Patrick 'Quezler' Mounier
10dcd9cb2d outlaw separator desycning (#5516)
* Seed separators

* Sync separators

* Seed from tile position
2021-06-30 12:59:09 -04:00
Anuken
c80e800ac9 Merge remote-tracking branch 'origin/master' 2021-06-30 10:49:29 -04:00
Anuken
eafcbf0914 Minor unit balancing 2021-06-30 10:28:05 -04:00
ulwepo
4f561a3875 Update servers_v6.json (#5515)
Sakura is a Japanese server.
I add attack mode.
Thank you.
2021-06-30 08:34:18 -04:00
Thomas Widyantoko
5cc92506c9 [ID] Updates Indonesian V7 translation (#5513)
* Indonesian bundle update

lenum.controller description and Tar Fields map

* translation bundle sync

* Indonesian translation standardization

* healing status effect

* Indonesian translation for V7

bit confused on line 1611

* [ID] WIP polygonal core protection

* [ID] Updates Indonesian V7 translation

Logic wait & content look up instructions
2021-06-30 08:34:08 -04:00
Arik
2c8eb1e5b8 Conveyor Upgrade End Rotation (#5512) 2021-06-30 08:29:35 -04:00
Anuken
6c18634b0d Minor logic unit rotation fix / Core capture unit derelict tareting 2021-06-29 16:26:02 -04:00
Anuken
c7bd9dd0fa Merge remote-tracking branch 'origin/master' 2021-06-29 12:21:56 -04:00
Anuken
d8ec231a5e Fixed #5508 2021-06-29 12:21:42 -04:00
Arik
5c803594fb Fix WaveGraph Lineup (#5503) 2021-06-29 09:03:56 -04:00
Minxyzgo
cececa190a Update WaterMoveComp.java (#5504) 2021-06-29 08:54:10 -04:00
OSP
38a3f1839e Change ip XCore, and add new server (#5502) 2021-06-28 18:58:39 -04:00
Anuken
2eb57ab680 Minor repair turret nerf 2021-06-28 18:57:13 -04:00
Anuken
f6f1ddb826 Fixed non-existent fire being targeted 2021-06-28 13:30:54 -04:00
Anuken
fcdbd4b117 Fixed liquid turrets not targeting closest fire 2021-06-28 11:35:46 -04:00
Anuken
a5c44e7998 #5055 2021-06-28 10:50:04 -04:00
Anuken
8afea88023 Fixed #5500 2021-06-28 10:15:54 -04:00
Anuken
75443e4dfc Clear commanding units on sync 2021-06-28 09:56:49 -04:00
Anuken
fbfb491dca Merge remote-tracking branch 'origin/master' 2021-06-28 09:25:48 -04:00
Anuken
082c17da85 Fixed #5498 2021-06-28 09:25:38 -04:00
thedimas3007
88ebf4f9db Updated (#5497) 2021-06-28 09:12:25 -04:00
OSP
18825b1697 Change IP XCore (#5494)
the old hosting is broken.
2021-06-27 18:47:11 -04:00
BasedUser
551b11877d CRAPPY DDNS IS GONE 🦀🦀🦀 (#5495) 2021-06-27 18:47:01 -04:00
Anuken
0bd1b4eedc Skip loading team regions for teams without palettes 2021-06-27 12:28:40 -04:00
Anuken
d401d7838c Gradle 7.1 2021-06-27 11:10:07 -04:00
Anuken
8b2e273d41 Merge remote-tracking branch 'origin/master' 2021-06-27 09:34:59 -04:00
Anuken
bdff6f9560 Repair turret nerf 2021-06-27 09:34:54 -04:00
Fatonndev
bb500a53ef Add attack v7 server (#5490) 2021-06-27 09:13:22 -04:00
Volas171
7ff0811764 retire mindustry reborn from v6 (#5487) 2021-06-27 09:13:03 -04:00
Anuken
36b49b6d8b Fixed #5488 / Fixed #5489 2021-06-27 09:12:35 -04:00
Anuken
e8edfb1170 Merge remote-tracking branch 'origin/master' 2021-06-26 20:55:59 -04:00
Anuken
bc6fcbc86d Fixed more flaky tests 2021-06-26 20:55:52 -04:00
OSP
8853ca303e Add XCore server to the v7 global list (#5486)
My server, 1 mode - the siege.There will be more servers in the future.
2021-06-26 15:46:19 -04:00
L0615T1C5-216AC-9437
914a6fc89b Add Chaotic Neutral to the V7 Server List (#5484) 2021-06-26 14:07:02 -04:00
UnCaughT
028be85468 Add HexPvP to V7 (#5483) 2021-06-26 14:06:56 -04:00
Darkness6030
5ffc285e1c Add mindurka to V7 list (#5471)
* Add mindurka to V7 list

* Update servers_v7.json

Co-authored-by: Patrick 'Quezler' Mounier <Quezler@me.com>

* Update servers_v7.json

Co-authored-by: Patrick 'Quezler' Mounier <Quezler@me.com>
Co-authored-by: Anuken <arnukren@gmail.com>
2021-06-26 12:29:56 -04:00
Anuken
604e6f8c47 Catch NoClassDefFoundErrors on ClientLoad 2021-06-26 11:11:27 -04:00
Anuken
4ac4f10ea0 Log mismatch errors for net buffers 2021-06-26 11:08:45 -04:00
Anuken
4c07733857 Fixed #5481 2021-06-26 11:04:03 -04:00
Anuken
7dc0f4dbc5 Merge remote-tracking branch 'origin/master' 2021-06-26 10:12:04 -04:00
Anuken
22f64fa2a5 Revert naval balance changes for now 2021-06-26 10:11:59 -04:00
KotMilkMeoW
5b0f1b5c03 Server upgrade to v7 (#5480) 2021-06-26 09:54:18 -04:00
Anuken
c6e0292d03 Fixed clientside physics jitter 2021-06-26 09:52:03 -04:00
Anuken
17eee61a93 Fixed #5478 2021-06-26 09:34:25 -04:00
Anuken
3817b159cf Reduced jittery interpolation 2021-06-26 00:19:23 -04:00
Anuken
331cf2e269 arc 2021-06-25 22:58:30 -04:00
Anuken
96622848d9 Hide outdated lobbies on Steam 2021-06-25 19:49:53 -04:00
Anuken
bcdc8867e6 Merge remote-tracking branch 'origin/master' 2021-06-25 19:36:07 -04:00
Anuken
eaeb67b91f Fixed #5474 2021-06-25 19:35:34 -04:00
Catchears
ebd444cc5f final v7 german translation (#5473) 2021-06-25 16:57:20 -04:00
L0615T1C5-216AC-9437
ff1ab9dd42 Add Chaotic Neutral Survival to BE Server List (#5435)
Co-authored-by: Anuken <arnukren@gmail.com>
2021-06-25 16:22:11 -04:00
Ilya246
7e2c830f9c Add .pl to 7.0 serverlist (#5466)
* Add .pl to 7.0 serverlist

.pl will move to 7.0 once b127 is out
Somka currently can't make a PR by himself so i asked him whether i should and, after a positive answer, did it for him

* Update servers_v7.json
2021-06-25 16:01:38 -04:00
Volas171
0cc2214951 Add Mindustry Reborn to V7 Alpha list (#5470)
* v7

* be removal

* formatting

Co-authored-by: Anuken <arnukren@gmail.com>
2021-06-25 14:41:24 -04:00
Anuken
47443d5ae7 Merge remote-tracking branch 'origin/master' 2021-06-25 14:37:36 -04:00
Anuken
cd2c605036 Suppress certain mod errors on client load 2021-06-25 14:37:32 -04:00
RebornTrack970
847e46d270 Add Beta 2r2t to V7 (#5468)
* Add Beta 2r2t to V7

Other Omega Servers will likely get updated to V7 too, for now, only 2r2t has a Beta.

* Update servers_v7.json

* Update servers_v7.json

Co-authored-by: Patrick 'Quezler' Mounier <Quezler@me.com>

* Update servers_be.json

Co-authored-by: Patrick 'Quezler' Mounier <Quezler@me.com>
2021-06-25 14:26:54 -04:00
Anuken
3d6cfcafd0 Don't assign players to derelict 2021-06-25 14:11:36 -04:00
47 changed files with 235 additions and 107 deletions

View File

@@ -84,9 +84,9 @@ public class AndroidLauncher extends AndroidApplication{
try{ try{
//try to load own class first //try to load own class first
loadedClass = findClass(name); loadedClass = findClass(name);
}catch(ClassNotFoundException e){ }catch(ClassNotFoundException | NoClassDefFoundError e){
//use parent if not found //use parent if not found
loadedClass = super.loadClass(name, resolve); return parent.loadClass(name);
} }
} }

View File

@@ -143,7 +143,8 @@ public class EntityIO{
if(sl) cont("if(!islocal)"); if(sl) cont("if(!islocal)");
if(sf){ if(sf){
st(field.name + lastSuf + " = this." + field.name + targetSuf); //TODO adding + targetSuf to the assignment fixes units being interpolated incorrectly during physics, but makes interpolation snap instead.
st(field.name + lastSuf + " = this." + field.name);
} }
io(field.type, "this." + (sf ? field.name + targetSuf : field.name) + " = "); io(field.type, "this." + (sf ? field.name + targetSuf : field.name) + " = ");

View File

@@ -460,6 +460,7 @@ toolmode.drawteams = Teams zeichnen
toolmode.drawteams.description = Zeichnet Teams statt Blöcke. toolmode.drawteams.description = Zeichnet Teams statt Blöcke.
filters.empty = [lightgray]Keine Filter! Füge einen mit dem unteren Knopf hinzu. filters.empty = [lightgray]Keine Filter! Füge einen mit dem unteren Knopf hinzu.
filter.distort = Verzerren filter.distort = Verzerren
filter.noise = Rauschen filter.noise = Rauschen
filter.enemyspawn = Gegnerischer Spawn Auswahl filter.enemyspawn = Gegnerischer Spawn Auswahl
@@ -476,6 +477,7 @@ filter.clear = Löschen
filter.option.ignore = Ignorieren filter.option.ignore = Ignorieren
filter.scatter = Streuen filter.scatter = Streuen
filter.terrain = Landschaft filter.terrain = Landschaft
filter.option.scale = Skalierung filter.option.scale = Skalierung
filter.option.chance = Wahrscheinlichkeit filter.option.chance = Wahrscheinlichkeit
filter.option.mag = Größe filter.option.mag = Größe
@@ -490,6 +492,7 @@ filter.option.block = Block
filter.option.floor = Boden filter.option.floor = Boden
filter.option.flooronto = Zielboden filter.option.flooronto = Zielboden
filter.option.target = Ziel filter.option.target = Ziel
filter.option.replacement = Ersatz
filter.option.wall = Wand filter.option.wall = Wand
filter.option.ore = Erz filter.option.ore = Erz
filter.option.floor2 = Sekundärer Boden filter.option.floor2 = Sekundärer Boden
@@ -675,6 +678,7 @@ unit.nobuild = [scarlet]Einheit kann nicht bauen!
lastaccessed = [lightgray]Zuletzt konfiguriert: {0} lastaccessed = [lightgray]Zuletzt konfiguriert: {0}
block.unknown = [lightgray]??? block.unknown = [lightgray]???
stat.showinmap = <öffne Spiel um zu zeigen>
stat.description = Beschreibung stat.description = Beschreibung
stat.input = Eingang stat.input = Eingang
stat.output = Ausgang stat.output = Ausgang
@@ -991,6 +995,7 @@ rules.waves = Wellen
rules.attack = Angriff-Modus rules.attack = Angriff-Modus
rules.buildai = KI kann bauen rules.buildai = KI kann bauen
rules.corecapture = Kern nach Zerstörung einnehmen rules.corecapture = Kern nach Zerstörung einnehmen
rules.polygoncoreprotection = Polygonaler Kernschutz
rules.enemyCheat = Unbegrenzte Ressourcen für die KI (Rotes Team) rules.enemyCheat = Unbegrenzte Ressourcen für die KI (Rotes Team)
rules.blockhealthmultiplier = Block-Lebenspunkte-Multiplikator rules.blockhealthmultiplier = Block-Lebenspunkte-Multiplikator
rules.blockdamagemultiplier = Block-Schaden-Multiplikator rules.blockdamagemultiplier = Block-Schaden-Multiplikator
@@ -1161,6 +1166,7 @@ block.spore-cluster.name = Sporen-Cluster
block.metal-floor.name = Metallboden 1 block.metal-floor.name = Metallboden 1
block.metal-floor-2.name = Metallboden 2 block.metal-floor-2.name = Metallboden 2
block.metal-floor-3.name = Metallboden 3 block.metal-floor-3.name = Metallboden 3
block.metal-floor-4.name = Metallboden 4
block.metal-floor-5.name = Metallboden 5 block.metal-floor-5.name = Metallboden 5
block.metal-floor-damaged.name = beschädigter Metallboden block.metal-floor-damaged.name = beschädigter Metallboden
block.dark-panel-1.name = Dunkles Panel 1 block.dark-panel-1.name = Dunkles Panel 1
@@ -1585,6 +1591,8 @@ lst.sensor = Gibt Daten über einen Block oder eine Einheit wieder.
lst.set = Setzt eine Variable fest. lst.set = Setzt eine Variable fest.
lst.operation = Verändert eine Variable. lst.operation = Verändert eine Variable.
lst.end = Springt wieder nach oben. lst.end = Springt wieder nach oben.
lst.wait = Wartet eine bestimmte Zeit.
lst.lookup = Sucht ein Item, eine Flüssigkeit, eine Einheit oder einen Block.\nGesamtmengen von jeder Sache können mit \n[accent]@unitCount[] / [accent]@itemCount[] / [accent]@liquidCount[] / [accent]@blockCount[]\nabgerufen werden.
lst.jump = Falls die Bedingung erfüllt ist, wird woanders weitergemacht. lst.jump = Falls die Bedingung erfüllt ist, wird woanders weitergemacht.
lst.unitbind = Speichert eine Einheit einer Sorte als [accent]@unit[]. lst.unitbind = Speichert eine Einheit einer Sorte als [accent]@unit[].
lst.unitcontrol = Steuert [accent]@unit[]. lst.unitcontrol = Steuert [accent]@unit[].

View File

@@ -1591,6 +1591,8 @@ lst.sensor = Mengambil data dari bangunan atau unit.
lst.set = Menentukan sebuah variabel. lst.set = Menentukan sebuah variabel.
lst.operation = Melakukan operasi pada 1-2 variabel. lst.operation = Melakukan operasi pada 1-2 variabel.
lst.end = Loncati ke awal dari tumpukan perintah. lst.end = Loncati ke awal dari tumpukan perintah.
lst.wait = Memberi jeda dalam detik yang ditentukan.
lst.lookup = Mencari tipe barang/cairan/unit/blok dengan ID.\nJumlah hitungan dari setiap tipe dapat dilihat dengan:\n[accent]@unitCount[] / [accent]@itemCount[] / [accent]@liquidCount[] / [accent]@blockCount[]
lst.jump = Loncati secara bersyarat ke pernyataan berikutnya. lst.jump = Loncati secara bersyarat ke pernyataan berikutnya.
lst.unitbind = Menautkan ke unit jenis berikutnya, dan menyimpannya di [accent]@unit[]. lst.unitbind = Menautkan ke unit jenis berikutnya, dan menyimpannya di [accent]@unit[].
lst.unitcontrol = Mengendalikan unit yang saat ini dihubungkan. lst.unitcontrol = Mengendalikan unit yang saat ini dihubungkan.

View File

@@ -460,6 +460,7 @@ toolmode.drawteams = Takım Çiz
toolmode.drawteams.description = Bloklar yerine takımları çizer.. toolmode.drawteams.description = Bloklar yerine takımları çizer..
filters.empty = [lightgray]Hiç filtre yok! Aşağıdaki butonla bir adet ekleyin. filters.empty = [lightgray]Hiç filtre yok! Aşağıdaki butonla bir adet ekleyin.
filter.distort = Çarpıt filter.distort = Çarpıt
filter.noise = Gürültü filter.noise = Gürültü
filter.enemyspawn = Düşman Doğma Alanı Seçimi filter.enemyspawn = Düşman Doğma Alanı Seçimi
@@ -476,6 +477,7 @@ filter.clear = Temizle
filter.option.ignore = Yoksay filter.option.ignore = Yoksay
filter.scatter = Saç filter.scatter = Saç
filter.terrain = Arazi filter.terrain = Arazi
filter.option.scale = Ölçek filter.option.scale = Ölçek
filter.option.chance = Şans filter.option.chance = Şans
filter.option.mag = Genlik filter.option.mag = Genlik
@@ -490,6 +492,7 @@ filter.option.block = Blok
filter.option.floor = Zemin filter.option.floor = Zemin
filter.option.flooronto = Hedef Zemin filter.option.flooronto = Hedef Zemin
filter.option.target = Target filter.option.target = Target
filter.option.replacement = Değiştirme
filter.option.wall = Duvar filter.option.wall = Duvar
filter.option.ore = Maden filter.option.ore = Maden
filter.option.floor2 = İkincil Duvar filter.option.floor2 = İkincil Duvar
@@ -675,6 +678,7 @@ unit.nobuild = [scarlet]Birlik inşa edemiyor
lastaccessed = [lightgray]Son Erişme: {0} lastaccessed = [lightgray]Son Erişme: {0}
block.unknown = [lightgray]??? block.unknown = [lightgray]???
stat.showinmap = <görüntülenecek haritayı yükle>
stat.description = Amaç stat.description = Amaç
stat.input = Giriş stat.input = Giriş
stat.output = Çıkış stat.output = Çıkış
@@ -991,6 +995,7 @@ rules.waves = Dalgalar
rules.attack = Saldırı Modu rules.attack = Saldırı Modu
rules.buildai = Yapay Zeka İnşası rules.buildai = Yapay Zeka İnşası
rules.corecapture = Yıkımca Çekirdeği Elegeçir rules.corecapture = Yıkımca Çekirdeği Elegeçir
rules.polygoncoreprotection = Çokgenli Çekirdek Koruması
rules.enemyCheat = Sonsuz AI (Kırmızı Takım) Kaynakları rules.enemyCheat = Sonsuz AI (Kırmızı Takım) Kaynakları
rules.blockhealthmultiplier = Blok Canı Çarpanı rules.blockhealthmultiplier = Blok Canı Çarpanı
rules.blockdamagemultiplier = Blok Hasarı Çarpanı rules.blockdamagemultiplier = Blok Hasarı Çarpanı
@@ -1161,7 +1166,8 @@ block.spore-cluster.name = Spor Kümesi
block.metal-floor.name = Metal Zemin 1 block.metal-floor.name = Metal Zemin 1
block.metal-floor-2.name = Metal Zemin 2 block.metal-floor-2.name = Metal Zemin 2
block.metal-floor-3.name = Metal Zemin 3 block.metal-floor-3.name = Metal Zemin 3
block.metal-floor-5.name = Metal Zemin 4 block.metal-floor-4.name = Metal Zemin 4
block.metal-floor-5.name = Metal Zemin 5
block.metal-floor-damaged.name = Hasarlı Metal Zemin block.metal-floor-damaged.name = Hasarlı Metal Zemin
block.dark-panel-1.name = Kara Panel 1 block.dark-panel-1.name = Kara Panel 1
block.dark-panel-2.name = Kara Panel 2 block.dark-panel-2.name = Kara Panel 2

Binary file not shown.

View File

@@ -149,7 +149,16 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
} }
mods.eachClass(Mod::init); mods.eachClass(Mod::init);
finished = true; finished = true;
Events.fire(new ClientLoadEvent()); var event = new ClientLoadEvent();
//a temporary measure for compatibility with certain mods
Events.fireWrap(event.getClass(), event, listener -> {
try{
listener.get(event);
}catch(NoSuchFieldError | NoSuchMethodError | NoClassDefFoundError error){
Log.err(error);
}
});
clientLoaded = true; clientLoaded = true;
super.resize(graphics.getWidth(), graphics.getHeight()); super.resize(graphics.getWidth(), graphics.getHeight());
app.post(() -> app.post(() -> app.post(() -> app.post(() -> { app.post(() -> app.post(() -> app.post(() -> app.post(() -> {

View File

@@ -148,6 +148,8 @@ public class Vars implements Loadable{
public static int maxTextureSize = 2048; public static int maxTextureSize = 2048;
/** Whether to show the core landing animation. */ /** Whether to show the core landing animation. */
public static boolean showLandAnimation = true; public static boolean showLandAnimation = true;
/** Whether to check for memory use before taking screenshots. */
public static boolean checkScreenshotMemory = true;
/** Whether to prompt the user to confirm exiting. */ /** Whether to prompt the user to confirm exiting. */
public static boolean confirmExit = true; public static boolean confirmExit = true;
/** if true, UI is not drawn */ /** if true, UI is not drawn */

View File

@@ -285,7 +285,7 @@ public class BlockIndexer{
for(int i = 0; i < activeTeams.size; i++){ for(int i = 0; i < activeTeams.size; i++){
Team enemy = activeTeams.items[i]; Team enemy = activeTeams.items[i];
if(enemy == team || team == Team.derelict) continue; if(enemy == team || (team == Team.derelict && !state.rules.coreCapture)) continue;
Building entity = indexer.findTile(enemy, x, y, range, pred, true); Building entity = indexer.findTile(enemy, x, y, range, pred, true);
if(entity != null){ if(entity != null){
@@ -360,7 +360,7 @@ public class BlockIndexer{
private void process(Tile tile){ private void process(Tile tile){
var team = tile.team(); var team = tile.team();
//only process entity changes with centered tiles //only process entity changes with centered tiles
if(tile.isCenter() && team != Team.derelict){ if(tile.isCenter() && tile.build != null){
var data = team.data(); var data = team.data();
if(tile.block().flags.size() > 0 && tile.isCenter()){ if(tile.block().flags.size() > 0 && tile.isCenter()){
TileArray[] map = getFlagged(team); TileArray[] map = getFlagged(team);

View File

@@ -119,9 +119,11 @@ public class Pathfinder implements Runnable{
} }
} }
int tid = tile.getTeamID();
return PathTile.get( return PathTile.get(
tile.build == null || !solid || tile.block() instanceof CoreBlock ? 0 : Math.min((int)(tile.build.health / 40), 80), tile.build == null || !solid || tile.block() instanceof CoreBlock ? 0 : Math.min((int)(tile.build.health / 40), 80),
tile.getTeamID(), tid == 0 && tile.build != null && state.rules.coreCapture ? 255 : tid, //use teamid = 255 when core capture is enabled to mark out derelict structures
solid, solid,
tile.floor().isLiquid, tile.floor().isLiquid,
tile.staticDarkness() >= 2 || (tile.floor().solid && tile.block() == Blocks.air), tile.staticDarkness() >= 2 || (tile.floor().solid && tile.block() == Blocks.air),

View File

@@ -104,7 +104,7 @@ public class LogicAI extends AIController{
//look where moving if there's nothing to aim at //look where moving if there's nothing to aim at
if(!shoot){ if(!shoot){
unit.lookAt(unit.prefRotation()); unit.lookAt(unit.prefRotation());
}else if(unit.hasWeapons() && unit.mounts.length > 0){ //if there is, look at the object }else if(unit.hasWeapons() && unit.mounts.length > 0 && !unit.mounts[0].weapon.ignoreRotation){ //if there is, look at the object
unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY); unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY);
} }
} }

View File

@@ -24,6 +24,7 @@ public class PhysicsProcess implements AsyncProcess{
@Override @Override
public void begin(){ public void begin(){
if(physics == null) return; if(physics == null) return;
boolean local = !Vars.net.client();
//remove stale entities //remove stale entities
refs.removeAll(ref -> { refs.removeAll(ref -> {
@@ -60,8 +61,9 @@ public class PhysicsProcess implements AsyncProcess{
ref.body.layer = ref.body.layer =
entity.type.allowLegStep ? layerLegs : entity.type.allowLegStep ? layerLegs :
entity.isGrounded() ? layerGround : layerFlying; entity.isGrounded() ? layerGround : layerFlying;
ref.x = entity.x(); ref.x = entity.x;
ref.y = entity.y(); ref.y = entity.y;
ref.body.local = local || entity.isLocal();
} }
} }
@@ -156,6 +158,10 @@ public class PhysicsProcess implements AsyncProcess{
for(int i = 0; i < bodies.size; i++){ for(int i = 0; i < bodies.size; i++){
PhysicsBody body = bodies.items[i]; PhysicsBody body = bodies.items[i];
//for clients, the only body that collides is the local one; all other physics simulations are handled by the server.
if(!body.local) continue;
body.hitbox(rect); body.hitbox(rect);
seq.size = 0; seq.size = 0;
@@ -174,12 +180,16 @@ public class PhysicsProcess implements AsyncProcess{
float ms = body.mass + other.mass; float ms = body.mass + other.mass;
float m1 = other.mass / ms, m2 = body.mass / ms; float m1 = other.mass / ms, m2 = body.mass / ms;
//first body is always local due to guard check above
body.x += vec.x * m1 / scl; body.x += vec.x * m1 / scl;
body.y += vec.y * m1 / scl; body.y += vec.y * m1 / scl;
if(other.local){
other.x -= vec.x * m2 / scl; other.x -= vec.x * m2 / scl;
other.y -= vec.y * m2 / scl; other.y -= vec.y * m2 / scl;
} }
} }
}
body.collided = true; body.collided = true;
} }
} }
@@ -187,7 +197,7 @@ public class PhysicsProcess implements AsyncProcess{
public static class PhysicsBody implements QuadTreeObject{ public static class PhysicsBody implements QuadTreeObject{
public float x, y, radius, mass; public float x, y, radius, mass;
public int layer = 0; public int layer = 0;
public boolean collided = false; public boolean collided = false, local = true;
@Override @Override
public void hitbox(Rect out){ public void hitbox(Rect out){

View File

@@ -51,7 +51,7 @@ public class Blocks implements ContentList{
melter, separator, disassembler, sporePress, pulverizer, incinerator, coalCentrifuge, melter, separator, disassembler, sporePress, pulverizer, incinerator, coalCentrifuge,
//sandbox //sandbox
powerSource, powerVoid, itemSource, itemVoid, liquidSource, liquidVoid, payloadVoid, payloadSource, illuminator, powerSource, powerVoid, itemSource, itemVoid, liquidSource, liquidVoid, payloadSource, payloadVoid, illuminator,
//defense //defense
copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge,
@@ -1589,13 +1589,13 @@ public class Blocks implements ContentList{
shots = 4; shots = 4;
burstSpacing = 5; burstSpacing = 5;
inaccuracy = 10f; inaccuracy = 10f;
range = 210f; range = 215f;
xRand = 6f; xRand = 6f;
size = 2; size = 2;
health = 300 * size * size; health = 300 * size * size;
shootSound = Sounds.missile; shootSound = Sounds.missile;
limitRange(2f); limitRange(5f);
}}; }};
salvo = new ItemTurret("salvo"){{ salvo = new ItemTurret("salvo"){{
@@ -1610,7 +1610,7 @@ public class Blocks implements ContentList{
size = 2; size = 2;
range = 190f; range = 190f;
reloadTime = 34f; reloadTime = 31f;
restitution = 0.03f; restitution = 0.03f;
ammoEjectBack = 3f; ammoEjectBack = 3f;
cooldown = 0.03f; cooldown = 0.03f;
@@ -1978,7 +1978,7 @@ public class Blocks implements ContentList{
}}; }};
repairPoint = new RepairPoint("repair-point"){{ repairPoint = new RepairPoint("repair-point"){{
requirements(Category.units, with(Items.lead, 20, Items.copper, 20, Items.silicon, 15)); requirements(Category.units, with(Items.lead, 25, Items.copper, 25, Items.silicon, 20));
repairSpeed = 0.5f; repairSpeed = 0.5f;
repairRadius = 65f; repairRadius = 65f;
beamWidth = 0.73f; beamWidth = 0.73f;
@@ -1987,16 +1987,16 @@ public class Blocks implements ContentList{
}}; }};
repairTurret = new RepairPoint("repair-turret"){{ repairTurret = new RepairPoint("repair-turret"){{
requirements(Category.units, with(Items.silicon, 70, Items.thorium, 60, Items.plastanium, 60)); requirements(Category.units, with(Items.silicon, 90, Items.thorium, 80, Items.plastanium, 80));
size = 2; size = 2;
length = 6f; length = 6f;
repairSpeed = 4f; repairSpeed = 3f;
repairRadius = 140f; repairRadius = 140f;
powerUse = 5f; powerUse = 5f;
beamWidth = 1.1f; beamWidth = 1.1f;
pulseRadius = 6.1f; pulseRadius = 6.1f;
coolantUse = 0.15f; coolantUse = 0.16f;
coolantMultiplier = 1.7f; coolantMultiplier = 1.5f;
acceptCoolant = true; acceptCoolant = true;
}}; }};
@@ -2068,12 +2068,12 @@ public class Blocks implements ContentList{
alwaysUnlocked = true; alwaysUnlocked = true;
}}; }};
payloadVoid = new PayloadVoid("payload-void"){{ payloadSource = new PayloadSource("payload-source"){{
requirements(Category.units, BuildVisibility.sandboxOnly, with()); requirements(Category.units, BuildVisibility.sandboxOnly, with());
size = 5; size = 5;
}}; }};
payloadSource = new PayloadSource("payload-source"){{ payloadVoid = new PayloadVoid("payload-void"){{
requirements(Category.units, BuildVisibility.sandboxOnly, with()); requirements(Category.units, BuildVisibility.sandboxOnly, with());
size = 5; size = 5;
}}; }};

View File

@@ -257,7 +257,6 @@ public class Bullets implements ContentList{
width = 8f; width = 8f;
height = 8f; height = 8f;
shrinkY = 0f; shrinkY = 0f;
drag = -0.01f;
splashDamageRadius = 30f; splashDamageRadius = 30f;
splashDamage = 30f * 1.5f; splashDamage = 30f * 1.5f;
ammoMultiplier = 5f; ammoMultiplier = 5f;
@@ -274,7 +273,6 @@ public class Bullets implements ContentList{
width = 7f; width = 7f;
height = 8f; height = 8f;
shrinkY = 0f; shrinkY = 0f;
drag = -0.01f;
homingPower = 0.08f; homingPower = 0.08f;
splashDamageRadius = 20f; splashDamageRadius = 20f;
splashDamage = 20f * 1.5f; splashDamage = 20f * 1.5f;
@@ -288,7 +286,6 @@ public class Bullets implements ContentList{
width = 8f; width = 8f;
height = 8f; height = 8f;
shrinkY = 0f; shrinkY = 0f;
drag = -0.01f;
splashDamageRadius = 25f; splashDamageRadius = 25f;
splashDamage = 25f * 1.4f; splashDamage = 25f * 1.4f;
hitEffect = Fx.blastExplosion; hitEffect = Fx.blastExplosion;

View File

@@ -854,7 +854,7 @@ public class Fx{
fireRemove = new Effect(70f, e -> { fireRemove = new Effect(70f, e -> {
if(Fire.regions[0] == null) return; if(Fire.regions[0] == null) return;
alpha(e.fout()); alpha(e.fout());
rect(Fire.regions[((int)(e.rotation + e.fin() * Fire.frames)) % Fire.frames], e.x, e.y); rect(Fire.regions[((int)(e.rotation + e.fin() * Fire.frames)) % Fire.frames], e.x + Mathf.randomSeedRange((int)e.y, 2), e.y + Mathf.randomSeedRange((int)e.x, 2));
Drawf.light(e.x, e.y, 50f + Mathf.absin(5f, 5f), Pal.lightFlame, 0.6f * e.fout()); Drawf.light(e.x, e.y, 50f + Mathf.absin(5f, 5f), Pal.lightFlame, 0.6f * e.fout());
}), }),

View File

@@ -87,7 +87,7 @@ public class UnitTypes implements ContentList{
mace = new UnitType("mace"){{ mace = new UnitType("mace"){{
speed = 0.45f; speed = 0.45f;
hitSize = 10f; hitSize = 10f;
health = 530; health = 540;
armor = 4f; armor = 4f;
immunities.add(StatusEffects.burning); immunities.add(StatusEffects.burning);
@@ -96,7 +96,7 @@ public class UnitTypes implements ContentList{
top = false; top = false;
shootSound = Sounds.flame; shootSound = Sounds.flame;
shootY = 2f; shootY = 2f;
reload = 12f; reload = 11f;
recoil = 1f; recoil = 1f;
ejectEffect = Fx.none; ejectEffect = Fx.none;
bullet = new BulletType(4.1f, 32f){{ bullet = new BulletType(4.1f, 32f){{
@@ -572,7 +572,7 @@ public class UnitTypes implements ContentList{
speed = 1f; speed = 1f;
splashDamageRadius = 60f; splashDamageRadius = 60f;
instantDisappear = true; instantDisappear = true;
splashDamage = 88f; splashDamage = 90f;
killShooter = true; killShooter = true;
hittable = false; hittable = false;
collidesAir = true; collidesAir = true;
@@ -581,7 +581,7 @@ public class UnitTypes implements ContentList{
}}; }};
atrax = new UnitType("atrax"){{ atrax = new UnitType("atrax"){{
speed = 0.5f; speed = 0.54f;
drag = 0.4f; drag = 0.4f;
hitSize = 13f; hitSize = 13f;
rotateSpeed = 3f; rotateSpeed = 3f;
@@ -621,7 +621,7 @@ public class UnitTypes implements ContentList{
}}; }};
spiroct = new UnitType("spiroct"){{ spiroct = new UnitType("spiroct"){{
speed = 0.45f; speed = 0.48f;
drag = 0.4f; drag = 0.4f;
hitSize = 15f; hitSize = 15f;
rotateSpeed = 3f; rotateSpeed = 3f;
@@ -1125,10 +1125,10 @@ public class UnitTypes implements ContentList{
BulletType fragBullet = new FlakBulletType(4f, 5){{ BulletType fragBullet = new FlakBulletType(4f, 5){{
shootEffect = Fx.shootBig; shootEffect = Fx.shootBig;
ammoMultiplier = 4f; ammoMultiplier = 4f;
splashDamage = 50f; splashDamage = 60f;
splashDamageRadius = 25f; splashDamageRadius = 25f;
collidesGround = true; collidesGround = true;
lifetime = 38f; lifetime = 47f;
status = StatusEffects.blasted; status = StatusEffects.blasted;
statusDuration = 60f; statusDuration = 60f;
@@ -1148,12 +1148,12 @@ public class UnitTypes implements ContentList{
rotate = true; rotate = true;
bullet = new LaserBulletType(){{ bullet = new LaserBulletType(){{
damage = 100f; damage = 110f;
sideAngle = 20f; sideAngle = 20f;
sideWidth = 1.5f; sideWidth = 1.5f;
sideLength = 80f; sideLength = 80f;
width = 25f; width = 25f;
length = 200f; length = 230f;
shootEffect = Fx.shockwave; shootEffect = Fx.shockwave;
colors = new Color[]{Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.white}; colors = new Color[]{Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.white};
}}; }};
@@ -2113,7 +2113,7 @@ public class UnitTypes implements ContentList{
bullet = new ContinuousLaserBulletType(){{ bullet = new ContinuousLaserBulletType(){{
maxRange = 90f; maxRange = 90f;
damage = 26f; damage = 27f;
length = 95f; length = 95f;
hitEffect = Fx.hitMeltHeal; hitEffect = Fx.hitMeltHeal;
drawSize = 200f; drawSize = 200f;
@@ -2144,7 +2144,7 @@ public class UnitTypes implements ContentList{
x = 70f/4f; x = 70f/4f;
y = -26f/4f; y = -26f/4f;
reload = 70f; reload = 65f;
shake = 3f; shake = 3f;
rotateSpeed = 2f; rotateSpeed = 2f;
shadow = 30f; shadow = 30f;
@@ -2161,7 +2161,7 @@ public class UnitTypes implements ContentList{
timeIncrease = 3f; timeIncrease = 3f;
timeDuration = 60f * 20f; timeDuration = 60f * 20f;
powerDamageScl = 3f; powerDamageScl = 3f;
damage = 50; damage = 60;
hitColor = lightColor = Pal.heal; hitColor = lightColor = Pal.heal;
lightRadius = 70f; lightRadius = 70f;
clipSize = 250f; clipSize = 250f;
@@ -2177,7 +2177,7 @@ public class UnitTypes implements ContentList{
trailWidth = 6f; trailWidth = 6f;
trailColor = Pal.heal; trailColor = Pal.heal;
trailInterval = 3f; trailInterval = 3f;
splashDamage = 60f; splashDamage = 70f;
splashDamageRadius = rad; splashDamageRadius = rad;
hitShake = 4f; hitShake = 4f;
trailRotation = true; trailRotation = true;

View File

@@ -247,11 +247,11 @@ public class Logic implements ApplicationListener{
Events.fire(new GameOverEvent(state.rules.waveTeam)); Events.fire(new GameOverEvent(state.rules.waveTeam));
}else if(state.rules.attackMode){ }else if(state.rules.attackMode){
//count # of teams alive //count # of teams alive
int countAlive = state.teams.getActive().count(TeamData::hasCore); int countAlive = state.teams.getActive().count(t -> t.hasCore() && t.team != Team.derelict);
if((countAlive <= 1 || (!state.rules.pvp && state.rules.defaultTeam.core() == null)) && !state.gameOver){ if((countAlive <= 1 || (!state.rules.pvp && state.rules.defaultTeam.core() == null)) && !state.gameOver){
//find team that won //find team that won
TeamData left = state.teams.getActive().find(TeamData::hasCore); TeamData left = state.teams.getActive().find(t -> t.hasCore() && t.team != Team.derelict);
Events.fire(new GameOverEvent(left == null ? Team.derelict : left.team)); Events.fire(new GameOverEvent(left == null ? Team.derelict : left.team));
state.gameOver = true; state.gameOver = true;
} }

View File

@@ -48,7 +48,7 @@ public class NetServer implements ApplicationListener{
if(state.rules.pvp){ if(state.rules.pvp){
//find team with minimum amount of players and auto-assign player to that. //find team with minimum amount of players and auto-assign player to that.
TeamData re = state.teams.getActive().min(data -> { TeamData re = state.teams.getActive().min(data -> {
if((state.rules.waveTeam == data.team && state.rules.waves) || !data.team.active()) return Integer.MAX_VALUE; if((state.rules.waveTeam == data.team && state.rules.waves) || !data.team.active() || data.team == Team.derelict) return Integer.MAX_VALUE;
int count = 0; int count = 0;
for(Player other : players){ for(Player other : players){
@@ -472,6 +472,10 @@ public class NetServer implements ApplicationListener{
return; return;
} }
if(!player.dead() && player.unit().isCommanding()){
player.unit().clearCommand();
}
player.getInfo().lastSyncTime = Time.millis(); player.getInfo().lastSyncTime = Time.millis();
Call.worldDataBegin(player.con); Call.worldDataBegin(player.con);
netServer.sendWorldData(player); netServer.sendWorldData(player);

View File

@@ -11,6 +11,7 @@ import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.async.*; import arc.util.async.*;
import mindustry.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -355,7 +356,7 @@ public class Renderer implements ApplicationListener{
int w = world.width() * tilesize, h = world.height() * tilesize; int w = world.width() * tilesize, h = world.height() * tilesize;
int memory = w * h * 4 / 1024 / 1024; int memory = w * h * 4 / 1024 / 1024;
if(memory >= (mobile ? 65 : 120)){ if(Vars.checkScreenshotMemory && memory >= (mobile ? 65 : 120)){
ui.showInfo("@screenshot.invalid"); ui.showInfo("@screenshot.invalid");
return; return;
} }

View File

@@ -53,7 +53,7 @@ public class WaveGraph extends Table{
for(int i = 0; i < values.length; i++){ for(int i = 0; i < values.length; i++){
int val = values[i][type.id]; int val = values[i][type.id];
float cx = graphX + i*spacing, cy = 2f + graphY + val * (graphH - 4f) / max; float cx = graphX + i*spacing, cy = graphY + val * graphH / max;
Lines.linePoint(cx, cy); Lines.linePoint(cx, cy);
} }
@@ -69,7 +69,7 @@ public class WaveGraph extends Table{
sum += values[i][type.id]; sum += values[i][type.id];
} }
float cx = graphX + i*spacing, cy = 2f + graphY + sum * (graphH - 4f) / maxTotal; float cx = graphX + i*spacing, cy = graphY + sum * graphH / maxTotal;
Lines.linePoint(cx, cy); Lines.linePoint(cx, cy);
} }
@@ -84,7 +84,7 @@ public class WaveGraph extends Table{
sum += (type.health) * values[i][type.id]; sum += (type.health) * values[i][type.id];
} }
float cx = graphX + i*spacing, cy = 2f + graphY + sum * (graphH - 4f) / maxHealth; float cx = graphX + i*spacing, cy = graphY + sum * graphH / maxHealth;
Lines.linePoint(cx, cy); Lines.linePoint(cx, cy);
} }
@@ -92,29 +92,29 @@ public class WaveGraph extends Table{
} }
//how many numbers can fit here //how many numbers can fit here
float totalMarks = (height - offsetY - getMarginBottom() *2f - 1f) / (lay.height * 2); float totalMarks = (graphH - getMarginBottom() *2f) / (lay.height * 2);
int markSpace = Math.max(1, Mathf.ceil(max / totalMarks)); int markSpace = Math.max(1, Mathf.ceil(max / totalMarks));
Draw.color(Color.lightGray); Draw.color(Color.lightGray);
for(int i = 0; i < max; i += markSpace){ for(int i = 0; i < max; i += markSpace){
float cy = 2f + y + i * (height - 4f) / max + offsetY, cx = x + offsetX; float cy = graphY + i * graphH / max, cx = graphX;
//Lines.line(cx, cy, cx + len, cy); //Lines.line(cx, cy, cx + len, cy);
lay.setText(font, "" + i); lay.setText(font, "" + i);
font.draw("" + i, cx, cy + lay.height/2f - Scl.scl(3f), Align.right); font.draw("" + i, cx, cy + lay.height/2f, Align.right);
} }
float len = Scl.scl(4f); float len = Scl.scl(4f);
font.setColor(Color.lightGray); font.setColor(Color.lightGray);
for(int i = 0; i < values.length; i++){ for(int i = 0; i < values.length; i++){
float cy = y + fh, cx = x + graphW / (values.length - 1) * i + offsetX; float cy = y + fh, cx = graphX + graphW / (values.length - 1) * i;
Lines.line(cx, cy, cx, cy + len); Lines.line(cx, cy, cx, cy + len);
if(i == values.length/2){ if(i == values.length/2){
font.draw("" + (i + from + 1), cx, cy - 2f, Align.center); font.draw("" + (i + from + 1), cx, cy - Scl.scl(2f), Align.center);
} }
} }
font.setColor(Color.white); font.setColor(Color.white);

View File

@@ -52,22 +52,22 @@ public class Puddles{
Puddle p = map.get(tile.pos()); Puddle p = map.get(tile.pos());
if(p == null){ if(p == null){
Puddle puddle = Puddle.create(); Puddle puddle = Puddle.create();
puddle.tile(tile); puddle.tile = tile;
puddle.liquid(liquid); puddle.liquid = liquid;
puddle.amount(amount); puddle.amount = amount;
puddle.generation(generation); puddle.generation = generation;
puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
puddle.add(); puddle.add();
map.put(tile.pos(), puddle); map.put(tile.pos(), puddle);
}else if(p.liquid() == liquid){ }else if(p.liquid == liquid){
p.accepting(Math.max(amount, p.accepting())); p.accepting = Math.max(amount, p.accepting);
if(generation == 0 && p.lastRipple <= Time.time - 40f && p.amount() >= maxLiquid / 2f){ if(generation == 0 && p.lastRipple <= Time.time - 40f && p.amount >= maxLiquid / 2f){
Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, p.liquid().color); Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, p.liquid.color);
p.lastRipple = Time.time; p.lastRipple = Time.time;
} }
}else{ }else{
p.amount(p.amount() + reactPuddle(p.liquid(), liquid, amount, p.tile(), (p.x() + source.worldx())/2f, (p.y() + source.worldy())/2f)); p.amount += reactPuddle(p.liquid, liquid, amount, p.tile, (p.x + source.worldx())/2f, (p.y + source.worldy())/2f);
} }
} }

View File

@@ -1,6 +1,7 @@
package mindustry.entities.comp; package mindustry.entities.comp;
import arc.math.*; import arc.math.*;
import arc.util.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -24,7 +25,7 @@ abstract class BoundedComp implements Velc, Posc, Healthc, Flyingc{
if(x > world.unitWidth()) dx -= (x - world.unitWidth())/warpDst; if(x > world.unitWidth()) dx -= (x - world.unitWidth())/warpDst;
if(y > world.unitHeight()) dy -= (y - world.unitHeight())/warpDst; if(y > world.unitHeight()) dy -= (y - world.unitHeight())/warpDst;
velAddNet(dx, dy); velAddNet(dx * Time.delta, dy * Time.delta);
} }
//clamp position if not flying //clamp position if not flying

View File

@@ -28,6 +28,7 @@ abstract class FireComp implements Timedc, Posc, Syncc, Drawc{
public static final TextureRegion[] regions = new TextureRegion[frames]; public static final TextureRegion[] regions = new TextureRegion[frames];
@Import float time, lifetime, x, y; @Import float time, lifetime, x, y;
@Import int id;
Tile tile; Tile tile;
private transient Block block; private transient Block block;
@@ -116,7 +117,7 @@ abstract class FireComp implements Timedc, Posc, Syncc, Drawc{
Draw.alpha(Mathf.clamp(warmup / warmupDuration)); Draw.alpha(Mathf.clamp(warmup / warmupDuration));
Draw.z(Layer.effect); Draw.z(Layer.effect);
Draw.rect(regions[Math.min((int)animation, regions.length - 1)], x, y); Draw.rect(regions[Math.min((int)animation, regions.length - 1)], x + Mathf.randomSeedRange((int)y, 2), y + Mathf.randomSeedRange((int)x, 2));
Draw.reset(); Draw.reset();
Drawf.light(x, y, 50f + Mathf.absin(5f, 5f), Pal.lightFlame, 0.6f * Mathf.clamp(warmup / warmupDuration)); Drawf.light(x, y, 50f + Mathf.absin(5f, 5f), Pal.lightFlame, 0.6f * Mathf.clamp(warmup / warmupDuration));

View File

@@ -1,6 +1,5 @@
package mindustry.entities.comp; package mindustry.entities.comp;
import arc.math.*;
import arc.util.*; import arc.util.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -34,7 +33,7 @@ abstract class HealthComp implements Entityc, Posc{
void kill(){ void kill(){
if(dead) return; if(dead) return;
health = 0; health = Math.min(health, 0);
dead = true; dead = true;
killed(); killed();
remove(); remove();
@@ -86,7 +85,7 @@ abstract class HealthComp implements Entityc, Posc{
} }
void clampHealth(){ void clampHealth(){
health = Mathf.clamp(health, 0, maxHealth); health = Math.min(health, maxHealth);
} }
/** Heals by a flat amount. */ /** Heals by a flat amount. */

View File

@@ -397,7 +397,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
//move down //move down
elevation -= type.fallSpeed * Time.delta; elevation -= type.fallSpeed * Time.delta;
if(isGrounded()){ if(isGrounded() || health <= -maxHealth){
Call.unitDestroy(id); Call.unitDestroy(id);
} }
} }
@@ -528,7 +528,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
@Override @Override
public void killed(){ public void killed(){
wasPlayer = isLocal(); wasPlayer = isLocal();
health = 0; health = Math.min(health, 0);
dead = true; dead = true;
//don't waste time when the unit is already on the ground, just destroy it //don't waste time when the unit is already on the ground, just destroy it

View File

@@ -19,7 +19,7 @@ import static mindustry.Vars.*;
@Component @Component
abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{ abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{
@Import float x, y, rotation; @Import float x, y, rotation, speedMultiplier;
@Import UnitType type; @Import UnitType type;
private transient Trail tleft = new Trail(1), tright = new Trail(1); private transient Trail tleft = new Trail(1), tright = new Trail(1);
@@ -74,7 +74,7 @@ abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{
@Replace @Replace
public float floorSpeedMultiplier(){ public float floorSpeedMultiplier(){
Floor on = isFlying() ? Blocks.air.asFloor() : floorOn(); Floor on = isFlying() ? Blocks.air.asFloor() : floorOn();
return on.isDeep() ? 1.3f : 1f; return (on.isDeep() ? 1.3f : 1f) * speedMultiplier;
} }
public boolean onLiquid(){ public boolean onLiquid(){

View File

@@ -97,7 +97,7 @@ public class Team implements Comparable<Team>{
} }
public boolean isEnemy(Team other){ public boolean isEnemy(Team other){
return state.teams.areEnemies(this, other); return this != other;
} }
public Seq<CoreBuild> cores(){ public Seq<CoreBuild> cores(){

View File

@@ -49,7 +49,7 @@ public class Teams{
public boolean eachEnemyCore(Team team, Boolf<CoreBuild> ret){ public boolean eachEnemyCore(Team team, Boolf<CoreBuild> ret){
for(TeamData data : active){ for(TeamData data : active){
if(areEnemies(team, data.team)){ if(team != data.team){
for(CoreBuild tile : data.cores){ for(CoreBuild tile : data.cores){
if(ret.get(tile)){ if(ret.get(tile)){
return true; return true;
@@ -62,7 +62,7 @@ public class Teams{
public void eachEnemyCore(Team team, Cons<Building> ret){ public void eachEnemyCore(Team team, Cons<Building> ret){
for(TeamData data : active){ for(TeamData data : active){
if(areEnemies(team, data.team)){ if(team != data.team){
for(Building tile : data.cores){ for(Building tile : data.cores){
ret.get(tile); ret.get(tile);
} }
@@ -91,11 +91,6 @@ public class Teams{
return get(team).active(); return get(team).active();
} }
/** Returns whether {@param other} is an enemy of {@param #team}. */
public boolean areEnemies(Team team, Team other){
return team != other;
}
public boolean canInteract(Team team, Team other){ public boolean canInteract(Team team, Team other){
return team == other || other == Team.derelict; return team == other || other == Team.derelict;
} }
@@ -216,7 +211,7 @@ public class Teams{
Seq<Team> enemies = new Seq<>(); Seq<Team> enemies = new Seq<>();
for(TeamData other : active){ for(TeamData other : active){
if(areEnemies(data.team, other.team)){ if(data.team != other.team){
enemies.add(other.team); enemies.add(other.team);
} }
} }

View File

@@ -165,6 +165,7 @@ public class BlockRenderer{
darkEvents.each(pos -> { darkEvents.each(pos -> {
var tile = world.tile(pos); var tile = world.tile(pos);
if(tile == null) return;
float darkness = world.getDarkness(tile.x, tile.y); float darkness = world.getDarkness(tile.x, tile.y);
//then draw the shadow //then draw the shadow
Draw.colorl(darkness <= 0f ? 1f : 1f - Math.min((darkness + 0.5f) / 4f, 1f)); Draw.colorl(darkness <= 0f ? 1f : 1f - Math.min((darkness + 0.5f) / 4f, 1f));

View File

@@ -1242,12 +1242,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
diagonal = !diagonal; diagonal = !diagonal;
} }
int endRotation = -1;
if(diagonal){ if(diagonal){
var start = world.build(startX, startY); var start = world.build(startX, startY);
var end = world.build(endX, endY); var end = world.build(endX, endY);
if(block != null && start instanceof ChainedBuilding && end instanceof ChainedBuilding if(block != null && start instanceof ChainedBuilding && end instanceof ChainedBuilding
&& block.canReplace(end.block) && block.canReplace(start.block)){ && block.canReplace(end.block) && block.canReplace(start.block)){
points = Placement.upgradeLine(startX, startY, endX, endY); points = Placement.upgradeLine(startX, startY, endX, endY);
endRotation = end.rotation;
}else{ }else{
points = Placement.pathfindLine(block != null && block.conveyorPlacement, startX, startY, endX, endY); points = Placement.pathfindLine(block != null && block.conveyorPlacement, startX, startY, endX, endY);
} }
@@ -1281,6 +1283,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
int result = baseRotation; int result = baseRotation;
if(next != null){ if(next != null){
result = Tile.relativeTo(point.x, point.y, next.x, next.y); result = Tile.relativeTo(point.x, point.y, next.x, next.y);
}else if(endRotation != -1){
result = endRotation;
}else if(block.conveyorPlacement && i > 0){ }else if(block.conveyorPlacement && i > 0){
Point2 prev = points.get(i - 1); Point2 prev = points.get(i - 1);
result = Tile.relativeTo(prev.x, prev.y, point.x, point.y); result = Tile.relativeTo(prev.x, prev.y, point.x, point.y);

View File

@@ -11,6 +11,10 @@ public class ModClassLoader extends ClassLoader{
} }
}; };
public ModClassLoader(ClassLoader parent){
super(parent);
}
public void addChild(ClassLoader child){ public void addChild(ClassLoader child){
children.add(child); children.add(child);
} }

View File

@@ -39,7 +39,7 @@ public class Mods implements Loadable{
private int totalSprites; private int totalSprites;
private MultiPacker packer; private MultiPacker packer;
private ModClassLoader mainLoader = new ModClassLoader(); private ModClassLoader mainLoader = new ModClassLoader(getClass().getClassLoader());
Seq<LoadedMod> mods = new Seq<>(); Seq<LoadedMod> mods = new Seq<>();
private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>(); private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>();

View File

@@ -391,7 +391,15 @@ public class ArcNetProvider implements NetProvider{
//no compression, copy over buffer //no compression, copy over buffer
if(compression == 0){ if(compression == 0){
buffer.position(0).limit(length); buffer.position(0).limit(length);
if(byteBuffer.hasArray()){
buffer.put(byteBuffer.array(), byteBuffer.position(), length); buffer.put(byteBuffer.array(), byteBuffer.position(), length);
}else{
byte[] readcopy = new byte[length];
int pos = byteBuffer.position();
byteBuffer.get(readcopy);
byteBuffer.position(pos);
buffer.put(readcopy);
}
buffer.position(0); buffer.position(0);
packet.read(reads.get(), length); packet.read(reads.get(), length);
//move read packets forward //move read packets forward

View File

@@ -97,7 +97,7 @@ public class Net{
if(e instanceof BufferUnderflowException || e instanceof BufferOverflowException){ if(e instanceof BufferUnderflowException || e instanceof BufferOverflowException){
error = Core.bundle.get("error.io"); error = Core.bundle.get("error.io");
}else if(error.equals("mismatch")){ }else if(error.equals("mismatch") || (e instanceof IndexOutOfBoundsException && e.getStackTrace()[0].getClassName().contains("java.nio"))){
error = Core.bundle.get("error.mismatch"); error = Core.bundle.get("error.mismatch");
}else if(error.contains("port out of range") || error.contains("invalid argument") || (error.contains("invalid") && error.contains("address")) || Strings.neatError(e).contains("address associated")){ }else if(error.contains("port out of range") || error.contains("invalid argument") || (error.contains("invalid") && error.contains("address")) || Strings.neatError(e).contains("address associated")){
error = Core.bundle.get("error.invalidaddress"); error = Core.bundle.get("error.invalidaddress");

View File

@@ -843,7 +843,7 @@ public class Block extends UnlockableContent{
//load specific team regions //load specific team regions
teamRegions = new TextureRegion[Team.all.length]; teamRegions = new TextureRegion[Team.all.length];
for(Team team : Team.all){ for(Team team : Team.all){
teamRegions[team.id] = teamRegion.found() ? Core.atlas.find(name + "-team-" + team.name, teamRegion) : teamRegion; teamRegions[team.id] = teamRegion.found() && team.hasPalette ? Core.atlas.find(name + "-team-" + team.name, teamRegion) : teamRegion;
} }
if(variants != 0){ if(variants != 0){

View File

@@ -100,18 +100,28 @@ public class LiquidTurret extends Turret{
@Override @Override
protected void findTarget(){ protected void findTarget(){
if(extinguish && liquids.current().canExtinguish()){ if(extinguish && liquids.current().canExtinguish()){
Fire result = null;
float mindst = 0f;
int tr = (int)(range / tilesize); int tr = (int)(range / tilesize);
for(int x = -tr; x <= tr; x++){ for(int x = -tr; x <= tr; x++){
for(int y = -tr; y <= tr; y++){ for(int y = -tr; y <= tr; y++){
Tile other = world.tileWorld(x + tile.x, y + tile.y); Tile other = world.tile(x + tile.x, y + tile.y);
var fire = Fires.get(x + tile.x, y + tile.y);
float dst = fire == null ? 0 : dst2(fire);
//do not extinguish fires on other team blocks //do not extinguish fires on other team blocks
if(other != null && Fires.has(x + tile.x, y + tile.y) && (other.build == null || other.team() == team)){ if(other != null && fire != null && Fires.has(other.x, other.y) && dst <= range * range && (result == null || dst < mindst) && (other.build == null || other.team() == team)){
target = Fires.get(x + tile.x, y + tile.y); result = fire;
mindst = dst;
}
}
}
if(result != null){
target = result;
//don't run standard targeting
return; return;
} }
} }
}
}
super.findTarget(); super.findTarget();
} }

View File

@@ -43,6 +43,10 @@ public class PayloadRouter extends PayloadConveyor{
do{ do{
rotation = (rotation + 1) % 4; rotation = (rotation + 1) % 4;
onProximityUpdate(); onProximityUpdate();
//force update to transfer if necessary
if(next instanceof PayloadConveyorBuild && !(next instanceof PayloadRouterBuild)){
next.updateTile();
}
//this condition intentionally uses "accept from itself" conditions, because payload conveyors only accept during the start //this condition intentionally uses "accept from itself" conditions, because payload conveyors only accept during the start
//"accept from self" conditions are for dropped payloads and are less restrictive //"accept from self" conditions are for dropped payloads and are less restrictive
}while((blocked || next == null || !next.acceptPayload(next, item)) && ++rotations < 4); }while((blocked || next == null || !next.acceptPayload(next, item)) && ++rotations < 4);

View File

@@ -1,6 +1,7 @@
package mindustry.world.blocks.production; package mindustry.world.blocks.production;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
@@ -67,6 +68,8 @@ public class Fracker extends SolidPump{
super.updateTile(); super.updateTile();
accumulator += delta() * efficiency(); accumulator += delta() * efficiency();
}else{ }else{
warmup = Mathf.lerpDelta(warmup, 0f, 0.02f);
lastPump = 0f;
dumpLiquid(result); dumpLiquid(result);
} }
} }

View File

@@ -30,6 +30,7 @@ public class Separator extends Block{
solid = true; solid = true;
hasItems = true; hasItems = true;
hasLiquids = true; hasLiquids = true;
sync = true;
} }
@Override @Override
@@ -45,6 +46,12 @@ public class Separator extends Block{
public float progress; public float progress;
public float totalProgress; public float totalProgress;
public float warmup; public float warmup;
public int seed;
@Override
public void created(){
seed = Mathf.randomSeed(tile.pos(), 0, Integer.MAX_VALUE - 1);
}
@Override @Override
public boolean shouldAmbientSound(){ public boolean shouldAmbientSound(){
@@ -91,7 +98,7 @@ public class Separator extends Block{
int sum = 0; int sum = 0;
for(ItemStack stack : results) sum += stack.amount; for(ItemStack stack : results) sum += stack.amount;
int i = Mathf.random(sum); int i = Mathf.randomSeed(seed++, 0, sum);
int count = 0; int count = 0;
Item item = null; Item item = null;
@@ -121,11 +128,19 @@ public class Separator extends Block{
return !consumes.itemFilters.get(item.id); return !consumes.itemFilters.get(item.id);
} }
//TODO write seed in 128 release, don't write it now for compatibility with 127.x
//@Override
//public byte version(){
// return 1;
//}
@Override @Override
public void write(Writes write){ public void write(Writes write){
super.write(write); super.write(write);
write.f(progress); write.f(progress);
write.f(warmup); write.f(warmup);
//TODO see above
//write.i(seed);
} }
@Override @Override
@@ -133,6 +148,8 @@ public class Separator extends Block{
super.read(read, revision); super.read(read, revision);
progress = read.f(); progress = read.f();
warmup = read.f(); warmup = read.f();
//TODO see above
//if(revision == 1) seed = read.i();
} }
} }
} }

View File

@@ -88,8 +88,12 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
net.handleException(t); net.handleException(t);
} }
} }
}catch(SteamException e){ }catch(Exception e){
if(net.server()){
Log.err(e); Log.err(e);
}else{
net.showError(e);
}
} }
} }
} }
@@ -303,7 +307,8 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback,
try{ try{
SteamID lobby = smat.getLobbyByIndex(i); SteamID lobby = smat.getLobbyByIndex(i);
String mode = smat.getLobbyData(lobby, "gamemode"); String mode = smat.getLobbyData(lobby, "gamemode");
if(mode == null || mode.isEmpty() || Strings.parseInt(smat.getLobbyData(lobby, "version"), -1) == -1) continue; //make sure versions are equal, don't list incompatible lobbies
if(mode == null || mode.isEmpty() || (Version.build != -1 && Strings.parseInt(smat.getLobbyData(lobby, "version"), -1) != Version.build)) continue;
Host out = new Host( Host out = new Host(
-1, //invalid ping -1, //invalid ping
smat.getLobbyData(lobby, "name"), smat.getLobbyData(lobby, "name"),

View File

@@ -10,4 +10,4 @@ kapt.include.compile.classpath=false
kotlin.stdlib.default.dependency=false kotlin.stdlib.default.dependency=false
#needed for android compilation #needed for android compilation
android.useAndroidX=true android.useAndroidX=true
archash=57b86e6bf0312aa8e8bc3b737c7d8f31fbe7a162 archash=1142cfc35b6671c6a2c5566632ff044a46527b82

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -2,9 +2,6 @@
{ {
"address": "be.mindustry.nydus.app:6567" "address": "be.mindustry.nydus.app:6567"
}, },
{
"address": "157.90.180.53:25777"
},
{ {
"address": "mindustry.pl:7777" "address": "mindustry.pl:7777"
}, },
@@ -12,6 +9,6 @@
"address": "v7.mindurka.tk:9999" "address": "v7.mindurka.tk:9999"
}, },
{ {
"address": "mindustry.me:7000" "address": "c-n.ddns.net:6567"
} }
] ]

View File

@@ -21,7 +21,7 @@
}, },
{ {
"name": "C.A.M.S.", "name": "C.A.M.S.",
"address": ["routerchain.ddns.net", "nikochio.ddns.net", "play.thedimas.pp.ua"] "address": ["baseduser.eu.org:6568", "nikochio.ddns.net", "play.thedimas.pp.ua"]
}, },
{ {
"name": "BE6.RUN", "name": "BE6.RUN",
@@ -101,14 +101,10 @@
}, },
{ {
"name": "Sakura", "name": "Sakura",
"address": ["160.16.207.141", "160.16.207.141:21527", "160.16.207.141:31587"] "address": ["160.16.207.141", "160.16.207.141:21527", "160.16.207.141:31587", "160.16.207.141:26810"]
}, },
{ {
"name": "MeowLand", "name": "MeowLand",
"address": ["34.134.111.15"] "address": ["34.134.111.15"]
},
{
"name": "[accent]Mindustry [red]Reborn",
"address": ["mindustry.me", "mindustry.me:1000", "mindustry.me:2000", "mindustry.me:3000"]
} }
] ]

View File

@@ -1,5 +1,45 @@
[ [
{ {
"address": "mindustry.us.to" "address": "mindustry.us.to"
},
{
"name": "mindustry.pl",
"address": ["mindustry.pl:6000", "mindustry.pl:6666", "mindustry.pl:6966"]
},
{
"name": "C.A.M.S.",
"address": ["baseduser.eu.org:6569", "v7.thedimas.pp.ua"]
}
{
"name": "hexpvp.ml",
"address": "hexpvp.ml"
},
{
"name": "[accent]Mindustry [red]Reborn",
"address": "mindustry.me:7000"
},
{
"name": "Omega",
"address": "157.90.180.53:25777"
},
{
"name": "MeowLand",
"address": "34.134.111.15"
},
{
"name": "Mindurka",
"address": ["mindurka.tk", "mindurka.tk:4000"]
},
{
"name": "Chaotic Neutral",
"address": ["c-n.ddns.net:5555", "c-n.ddns.net:6666"]
},
{
"name": "XCore",
"address": ["35.202.253.94" , "35.202.253.94:2000"]
},
{
"name": "Obvilion Network",
"address": "obvilionnetwork.ru:7004"
} }
] ]

View File

@@ -24,7 +24,7 @@ public class ModTestBM extends GenericModTest{
assertNotNull(type, "A mod block must be loaded."); assertNotNull(type, "A mod block must be loaded.");
assertSame(type.buildVisibility, BuildVisibility.shown, "A mod block must be buildable."); assertSame(type.buildVisibility, BuildVisibility.shown, "A mod block must be buildable.");
world.loadMap(ApplicationTests.testMap); world.loadMap(maps.loadInternalMap("groundZero"));
Tile t = world.tile(3, 3); Tile t = world.tile(3, 3);
t.setBlock(type); t.setBlock(type);

View File

@@ -4,6 +4,7 @@ import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import static mindustry.Vars.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
//grabs a version-locked Heavy Armaments Industries commit and makes sure it initializes correctly //grabs a version-locked Heavy Armaments Industries commit and makes sure it initializes correctly
@@ -22,7 +23,7 @@ public class ModTestHAI extends GenericModTest{
assertNotNull(type, "A mod unit must be loaded."); assertNotNull(type, "A mod unit must be loaded.");
assertTrue(type.weapons.size > 0, "A mod unit must have a weapon."); assertTrue(type.weapons.size > 0, "A mod unit must have a weapon.");
Vars.world.loadMap(ApplicationTests.testMap); Vars.world.loadMap(maps.loadInternalMap("groundZero"));
Unit unit = type.spawn(0, 0); Unit unit = type.spawn(0, 0);