diff --git a/core/assets/baseparts/1603214918168.msch b/core/assets/baseparts/1603214918168.msch
new file mode 100644
index 0000000000..6d69a2c362
--- /dev/null
+++ b/core/assets/baseparts/1603214918168.msch
@@ -0,0 +1,2 @@
+mschxœ5�Ë
+!E¯Ïy-J·ý‡ù(q¤£Gú÷�„ââä&'›„Î.<Zl.Çž®Vª{lG¸|�ŸK4ÌíúÙðü{»/ùßR±ÅÒ~•^=ÝùäÐ“kÑïG�ç	àzRPm!&ÆÌX+ ÉÓ†4©¨²¼H}E“y$9’À˜’¢XQÜÔü‰æd8ZQŠ¡†acf,Œê˜ã"
\ No newline at end of file
diff --git a/core/assets/baseparts/1603214945791.msch b/core/assets/baseparts/1603214945791.msch
new file mode 100644
index 0000000000..1508bec770
--- /dev/null
+++ b/core/assets/baseparts/1603214945791.msch
@@ -0,0 +1,2 @@
+mschxœ5�AÂ E¿JkêÊStã��˜I
+4”šx{¡ðòÿ¼¸vÐÑÂ½pq‘�°—”Ý›^˜Ú}æ­pŠ€ÆÄ…Â¼§#{Âã¯Ï>Å}SÆm‹tWØÏKæuÅXGÅq¤àY¬z\P?E½:�ÅYŽ
ªÍÎ¤ÅÔ¢h)�(¦%UDK½”½(¶.©%Ð#èV0F¨­N#Ô
\ No newline at end of file
diff --git a/core/assets/baseparts/1603214967392.msch b/core/assets/baseparts/1603214967392.msch
new file mode 100644
index 0000000000..0e30b20a82
--- /dev/null
+++ b/core/assets/baseparts/1603214967392.msch
@@ -0,0 +1 @@
+mschxœ%ÍAƒ …á§€ÖZc\ô.z$ƒÓdƒÐ¤·/täƒ?“3†ÚoŽ`Þù¢Æ�.ùL< ±$N›çìVü‡¾!b>=e·%¶ëù80r"·^!GKÐu€g9è€¦Ð×{S_@+±•¨$jÁ�ÐWê\oJSÀMú Ü…±¢0ý?ÂCâTŠªhÁÔqW
\ No newline at end of file
diff --git a/core/assets/baseparts/1603214996033.msch b/core/assets/baseparts/1603214996033.msch
new file mode 100644
index 0000000000..83690987ae
--- /dev/null
+++ b/core/assets/baseparts/1603214996033.msch
@@ -0,0 +1,3 @@
+mschxœ%�Á
+Ã ƒÓªmic×½C/{£bU‡ÕÁÞ~¦ÿA>“ˆ·:nÁÁ¼ëé^XvwÚì?Å§<Š/[ô5¬6Å¯û¥Œû'º¶âíºgX|qa=SÍÖAsCNµ¸àÙNÛA×0ðÞQ½˜=Mb‚¢9óMID‰Ò’ÔÑb‰Q§ÆÆAÑ˜ÙŸZ¯}<ò™ê
+sFŠ£†‘©U.Œ‚ÖüBIÙ
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215024189.msch b/core/assets/baseparts/1603215024189.msch
new file mode 100644
index 0000000000..75d8474c96
Binary files /dev/null and b/core/assets/baseparts/1603215024189.msch differ
diff --git a/core/assets/baseparts/1603215113546.msch b/core/assets/baseparts/1603215113546.msch
new file mode 100644
index 0000000000..bf1020f89f
--- /dev/null
+++ b/core/assets/baseparts/1603215113546.msch
@@ -0,0 +1,2 @@
+mschxœ%Ð[nÃ ÐøA×}¨ê"òÙ
t'‘C$¤ØŽˆ]©»ï÷Ã
Ìcð…ÑÀ.—9ÂÝögüF¸Æç”ÓcKë8XÝÆ¸¥í²¤}>OëòÿÖŸ×}‹Ãc‰û|ÙÒt¾æt¿#¤-Îççºç)øäƒ‘Åd©qPÒ’Žr$½b¤@ê*bÙÅ2r¡ôtÒ³RZÒ‘@Ž¤W<»x©“Æ^oWÊµ5Ïj=+SjÔ0³Ñq•@Ê€­¦XÁ:À—�RÚ±´“?¨”
+•,#G<©ICZÒ‘@Ž¤''%H³òZ…žœÈ@^ôÅG<©ICZÍÉ+y#ïäC>órá#³
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215171294.msch b/core/assets/baseparts/1603215171294.msch
new file mode 100644
index 0000000000..eaef917ff3
--- /dev/null
+++ b/core/assets/baseparts/1603215171294.msch
@@ -0,0 +1,2 @@
+mschxœ%�áŽƒ „A±ú£ißƒ‡âpïB¢`ÛøîM®»
+!ß0;060É/û»oäKÀ8ÑJ\kÌ	èa|­Tk~Sq)O-Éûšh_|�ÁM%Î35VŸâ¾¸�Ó‹Ž\ðØòì‹[}¢Ù±ú#Œ±Òâ¶¼—@0ò-€'hhÅ0½†úÿ@Á —WÝ@†JÐCi4bjœÛp´…2gã„½Ð_¸]ä¡ŽEÓ±°-ÎK+¾–þ·.é
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215272794.msch b/core/assets/baseparts/1603215272794.msch
new file mode 100644
index 0000000000..b2351a3857
--- /dev/null
+++ b/core/assets/baseparts/1603215272794.msch
@@ -0,0 +1 @@
+mschxœM�KnÄ DŒ1±£ÉÌ²æPÈ&#$¶ó9yv™tCYÀë_Ñ%ðŒ«„Jnõ˜ÞÎÝo®Äè>1-~ŸKØŽ�ð„i?ËÝÛ#øBIŽ®ØÍ%q;ÂáR8W;çôî¿rÁË–ü¹º#Ìv)!F\7ÖÙ”oIy÷¸ý{â¯4…Ã¯vÏg™=›�!;®ú^é`4èE�ä`¨–õ
ºah¨:I:!ê¬�Òu0hRFCåÇ7†Ç½¨:«T›W0tƒá=÷z*] %wX ›#ÝéæH7Gºé4}mWW³À0¸3õÄ®§æbÀÈ6
eòÀ>
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215345320.msch b/core/assets/baseparts/1603215345320.msch
new file mode 100644
index 0000000000..8c97534bdf
--- /dev/null
+++ b/core/assets/baseparts/1603215345320.msch
@@ -0,0 +1,4 @@
+mschxœEÏën‚@àÃÅ\EíÕôøÛ÷!ºdÍ²´éÃ:ÃiÒ�øqvfÇØ§È‡öæP^¦Ñ]|ˆ°g7žBw��€
+¹Vpˆ]l‡nº5'?|¹`»ènÍè§pr°};ºÐœC×÷0ÁOÑìïþ[vMß†«Œ½¼4÷vpýß‘'¡‰Ú*á¿àHäY~2dJNVÄ(©�¦BµL¦­r ­+bH¡èw-cKM™¤52e«ó*þWÅR!K²L–{XÝ#SAJR‘5±dC¶¤V6r]m`Ët~Ìóü��Œ´ÔHÁè¦µRv™¾ÓX
+2H©ÉNk{Þ8�'òL^È+y#ï
+p”U%%%JAJ$¿æ?M
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215415778.msch b/core/assets/baseparts/1603215415778.msch
new file mode 100644
index 0000000000..6f7f75ab97
--- /dev/null
+++ b/core/assets/baseparts/1603215415778.msch
@@ -0,0 +1,2 @@
+mschxœ-‹k
+1„ÇMÅîÑƒôPÅ
²PÛÒ®èÕEdM¬?’o2“Á€cý�1e_BðÏš‚/g®—²äuI08åôàâbšÙI~eŒõ.p«ú°RöÚÆù×wÙGÿO`�ÁÁîÑmÈ¾adh{ÑN²Þ‚:õŒ‚Ä'Õ"IZ}Ã¤°í²z}‰o)"
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215454977.msch b/core/assets/baseparts/1603215454977.msch
new file mode 100644
index 0000000000..c0a53057ed
Binary files /dev/null and b/core/assets/baseparts/1603215454977.msch differ
diff --git a/core/assets/baseparts/1603215491407.msch b/core/assets/baseparts/1603215491407.msch
new file mode 100644
index 0000000000..ba578a4a55
--- /dev/null
+++ b/core/assets/baseparts/1603215491407.msch
@@ -0,0 +1,2 @@
+mschxœ5ÏáŠƒ0à1µµmjï9äàÞ(h~ÔHŒÂ½ýeÁ�ufCÄn
+Õj‡Ç¶ÍÅÝÎgøA7¹}Œ~K>¬@
}ÚcNè“OvõÇ2Œa=ÝoˆÐ×Úc�ƒ�\Dç“[†=qt0ÛêŽÅ&?Sôóà(Ð (p=òR¤$Ñ‚’ôJ T&ge¦Öù âªJ¬IM¡Ê´Ò*´ü~#÷”d÷|ÚEE4©I#t¹©„FxpzpzÊ¤3% hù¹'³›/™4ol¸`¸`¸`¸ðæÂ›SÏfÏfÏfÏìÃæG¦?J
(,
\ No newline at end of file
diff --git a/core/assets/baseparts/1603215563717.msch b/core/assets/baseparts/1603215563717.msch
new file mode 100644
index 0000000000..460c1d9f8b
Binary files /dev/null and b/core/assets/baseparts/1603215563717.msch differ
diff --git a/core/assets/baseparts/1603215697527.msch b/core/assets/baseparts/1603215697527.msch
new file mode 100644
index 0000000000..427e52f671
Binary files /dev/null and b/core/assets/baseparts/1603215697527.msch differ
diff --git a/core/assets/baseparts/1603215771822.msch b/core/assets/baseparts/1603215771822.msch
new file mode 100644
index 0000000000..68ee586ea5
Binary files /dev/null and b/core/assets/baseparts/1603215771822.msch differ
diff --git a/core/assets/baseparts/1603215801163.msch b/core/assets/baseparts/1603215801163.msch
new file mode 100644
index 0000000000..09b9033d84
--- /dev/null
+++ b/core/assets/baseparts/1603215801163.msch
@@ -0,0 +1 @@
+mschxœ-Œ[ƒ D�J¬JŸaQ¤’ÆÄMÓµ÷£½�~�¹g&—3—åíÓ1å°ÚdS²oôìò=-q[‚‡Ž[íL´Þ­FÒÃq�áå’ñav£ó.0[ñÀ
š”äŠSA/ÿ¤é‡†îû‘é�ciFÑ(ädPD­~Ã+ï
\ No newline at end of file
diff --git a/core/assets/baseparts/1603216038407.msch b/core/assets/baseparts/1603216038407.msch
new file mode 100644
index 0000000000..85865ba123
Binary files /dev/null and b/core/assets/baseparts/1603216038407.msch differ
diff --git a/core/assets/baseparts/1603216102310.msch b/core/assets/baseparts/1603216102310.msch
new file mode 100644
index 0000000000..a05dbc61ed
--- /dev/null
+++ b/core/assets/baseparts/1603216102310.msch
@@ -0,0 +1 @@
+mschxœ%Ž[jÄ0EoœØ“©K¡]†e2¢58Ö ;SºûJI]¡">¶–OÂ}ü°ô\_Œø ~HyŽÂ
¸!öK¾)
þ%QÁ5KzæF±æN’RªŠ2èL�/9Ÿ£ŒÜÊu¦ƒÛ‹þX„¯¡ü¼|iÀíX˜9u+8¬–¬ØpózÝà­Áà&Ö‰mÂOh!¼>àt^m1ì÷‰·‰ˆ%(ÞMí6´A—ýÖe)“
\ No newline at end of file
diff --git a/core/assets/baseparts/1603216240041.msch b/core/assets/baseparts/1603216240041.msch
new file mode 100644
index 0000000000..c0960c09d5
--- /dev/null
+++ b/core/assets/baseparts/1603216240041.msch
@@ -0,0 +1,3 @@
+mschxœM‘IRÃ0E¿åÙJâk.àcp—£
+*<aK¡85;lB·:Råzý{øRZxÂA!™ºÑ ÚœéÆeþ4+ôÙlýjgç	ØAo~½˜Ö…b=šþ­›lß
íâÇûÅ›iûy:{ëÐlóÐ­íÒMfh)ºƒm;ÍgsÏèÁ~x{n]7½£êýàìµsóŠý½°ÎÞÑa�³ÔbýÈöWóõ¯c›ýÚd÷Î:Ü¿½˜É¬Á	x¥e¡n7h¼ Œ"DœRALAJ*Ir	�F��c®ÆR�¹JË¤‚Œ‘’KÅª@”JD9[#œ@¾ŒX@As­�–Bæ
+žã8ÔJ®q*¨ŠUIP)ÝŠò•äµti¾/ƒŽa‚RP	4bE�v< °µuuU‹ªEEE5¢^NE ­±J³ÊDåüoj£_ƒ½Ãïí›Þâ™Ø@h±ŒD�	èú	¡*¢Û
(<Ê¢Nüp9!¬ôÄ+e•ˆJEe¢rQ´Ù?Ç]­
\ No newline at end of file
diff --git a/core/assets/baseparts/1603216539888.msch b/core/assets/baseparts/1603216539888.msch
new file mode 100644
index 0000000000..53d2ffb720
Binary files /dev/null and b/core/assets/baseparts/1603216539888.msch differ
diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java
index 60908d8337..056b94d27b 100644
--- a/core/src/mindustry/content/Blocks.java
+++ b/core/src/mindustry/content/Blocks.java
@@ -1652,7 +1652,7 @@ public class Blocks implements ContentList{
             }},
             Items.titanium, new ShrapnelBulletType(){{
                 length = brange;
-                damage = 65f;
+                damage = 66f;
                 ammoMultiplier = 4f;
                 width = 17f;
                 reloadMultiplier = 1.3f;
diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java
index 45b1042660..87518c35ef 100644
--- a/core/src/mindustry/entities/comp/BuildingComp.java
+++ b/core/src/mindustry/entities/comp/BuildingComp.java
@@ -911,7 +911,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
     /** Called when arbitrary configuration is applied to a tile. */
     public void configured(@Nullable Unit builder, @Nullable Object value){
         //null is of type void.class; anonymous classes use their superclass.
-        Class<?> type = value == null ? void.class : value.getClass().isAnonymousClass() ? value.getClass().getSuperclass() : value.getClass();
+        Class<?> type = value == null ? void.class : value.getClass().isAnonymousClass() || value.getClass().getSimpleName().startsWith("adapter") ? value.getClass().getSuperclass() : value.getClass();
 
         if(builder != null && builder.isPlayer()){
             lastAccessed = builder.getPlayer().name;
diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java
index e2cbd581fd..6b4f9ced0a 100644
--- a/core/src/mindustry/logic/LExecutor.java
+++ b/core/src/mindustry/logic/LExecutor.java
@@ -47,6 +47,7 @@ public class LExecutor{
     public LongSeq graphicsBuffer = new LongSeq();
     public StringBuilder textBuffer = new StringBuilder();
     public Building[] links = {};
+    public IntSet linkIds = new IntSet();
     public Team team = Team.derelict;
 
     public boolean initialized(){
@@ -212,9 +213,9 @@ public class LExecutor{
         public LLocate locate = LLocate.building;
         public BlockFlag flag = BlockFlag.core;
         public int enemy, ore;
-        public int outX, outY, outFound;
+        public int outX, outY, outFound, outBuild;
 
-        public UnitLocateI(LLocate locate, BlockFlag flag, int enemy, int ore, int outX, int outY, int outFound){
+        public UnitLocateI(LLocate locate, BlockFlag flag, int enemy, int ore, int outX, int outY, int outFound, int outBuild){
             this.locate = locate;
             this.flag = flag;
             this.enemy = enemy;
@@ -271,6 +272,7 @@ public class LExecutor{
                         cache.found = false;
                         exec.setnum(outFound, 0);
                     }
+                    exec.setobj(outFound, res != null && res.build != null && res.build.team == exec.team ? res.build : null);
                 }else{
                     exec.setbool(outFound, cache.found);
                     exec.setnum(outX, cache.x);
@@ -446,13 +448,13 @@ public class LExecutor{
                         float range = Math.max(unit.range(), buildingRange);
                         if(!unit.within(x1, y1, range)){
                             exec.setobj(p3, null);
-                            exec.setnum(p4, 0);
+                            exec.setobj(p4, null);
                         }else{
                             Tile tile = world.tileWorld(x1, y1);
                             //any environmental solid block is returned as StoneWall, aka "@solid"
                             Block block = tile == null ? null : !tile.synthetic() ? (tile.solid() ? Blocks.stoneWall : Blocks.air) : tile.block();
                             exec.setobj(p3, block);
-                            exec.setnum(p4, tile != null && tile.build != null ? tile.build.rotation : 0);
+                            exec.setobj(p4, tile != null && tile.build != null ? tile.build : null);
                         }
                     }
                     case itemDrop -> {
@@ -510,11 +512,11 @@ public class LExecutor{
         @Override
         public void run(LExecutor exec){
             Object obj = exec.obj(target);
-            if(obj instanceof Controllable cont && cont.team() == exec.team){
+            if(obj instanceof Building b && b.team == exec.team && exec.linkIds.contains(b.id)){
                 if(type.isObj){
-                    cont.control(type, exec.obj(p1), exec.num(p2), exec.num(p3), exec.num(p4));
+                    b.control(type, exec.obj(p1), exec.num(p2), exec.num(p3), exec.num(p4));
                 }else{
-                    cont.control(type, exec.num(p1), exec.num(p2), exec.num(p3), exec.num(p4));
+                    b.control(type, exec.num(p1), exec.num(p2), exec.num(p3), exec.num(p4));
                 }
             }
         }
@@ -607,6 +609,7 @@ public class LExecutor{
             Object target = exec.obj(from);
             Object sense = exec.obj(type);
 
+            //TODO should remote enemy buildings be senseable?
             if(target instanceof Senseable se){
                 if(sense instanceof Content){
                     exec.setnum(to, se.sense(((Content)sense)));
diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java
index ba4d31e9a1..57adbdb7fe 100644
--- a/core/src/mindustry/logic/LStatements.java
+++ b/core/src/mindustry/logic/LStatements.java
@@ -819,7 +819,7 @@ public class LStatements{
         public LLocate locate = LLocate.building;
         public BlockFlag flag = BlockFlag.core;
         public String enemy = "true", ore = "@copper";
-        public String outX = "outx", outY = "outy", outFound = "found";
+        public String outX = "outx", outY = "outy", outFound = "found", outBuild = "building";
 
         @Override
         public void build(Table table){
@@ -905,6 +905,8 @@ public class LStatements{
             table.add(" found ").left();
             fields(table, outFound, str -> outFound = str);
 
+            table.add(" building ").left();
+            fields(table, outBuild, str -> outBuild = str);
 
         }
 
@@ -915,7 +917,7 @@ public class LStatements{
 
         @Override
         public LInstruction build(LAssembler builder){
-            return new UnitLocateI(locate, flag, builder.var(enemy), builder.var(ore), builder.var(outX), builder.var(outY), builder.var(outFound));
+            return new UnitLocateI(locate, flag, builder.var(enemy), builder.var(ore), builder.var(outX), builder.var(outY), builder.var(outFound), builder.var(outBuild));
         }
     }
 }
diff --git a/core/src/mindustry/logic/LUnitControl.java b/core/src/mindustry/logic/LUnitControl.java
index 2166b00690..b4c7f8254c 100644
--- a/core/src/mindustry/logic/LUnitControl.java
+++ b/core/src/mindustry/logic/LUnitControl.java
@@ -15,7 +15,7 @@ public enum LUnitControl{
     mine("x", "y"),
     flag("value"),
     build("x", "y", "block", "rotation"),
-    getBlock("x", "y", "result", "resRot"),
+    getBlock("x", "y", "type", "building"),
     within("x", "y", "radius", "result");
 
     public final String[] params;
diff --git a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java
index 15716b4a94..25725cd0a9 100644
--- a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java
+++ b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java
@@ -37,6 +37,10 @@ public class LiquidTurret extends Turret{
         super.setStats();
 
         stats.add(Stat.ammo, new AmmoListValue<>(ammoTypes));
+    }
+
+    @Override
+    public void init(){
         consumes.add(new ConsumeLiquidFilter(i -> ammoTypes.containsKey(i), 1f){
             @Override
             public boolean valid(Building entity){
@@ -53,6 +57,8 @@ public class LiquidTurret extends Turret{
 
             }
         });
+
+        super.init();
     }
 
     public class LiquidTurretBuild extends TurretBuild{
diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java
index 2361c429af..58abb26b12 100644
--- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java
+++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java
@@ -24,7 +24,6 @@ import mindustry.type.*;
 import mindustry.world.blocks.*;
 import mindustry.world.consumers.*;
 import mindustry.world.meta.*;
-import mindustry.world.meta.values.*;
 
 import static mindustry.Vars.*;
 
@@ -60,7 +59,6 @@ public abstract class Turret extends ReloadTurret{
     public boolean alternate = false;
     public boolean targetAir = true;
     public boolean targetGround = true;
-    public boolean acceptCoolant = true;
 
     public Sortf unitSort = Unit::dst2;
 
@@ -105,10 +103,6 @@ public abstract class Turret extends ReloadTurret{
         stats.add(Stat.reload, 60f / reloadTime * shots, StatUnit.none);
         stats.add(Stat.targetsAir, targetAir);
         stats.add(Stat.targetsGround, targetGround);
-
-        if(acceptCoolant){
-            stats.add(Stat.booster, new BoosterListValue(reloadTime, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id)));
-        }
     }
 
     @Override
diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java
index e1b5c857e4..488c44604d 100644
--- a/core/src/mindustry/world/blocks/logic/LogicBlock.java
+++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java
@@ -279,10 +279,13 @@ public class LogicBlock extends Block{
 
                     //store link objects
                     executor.links = new Building[links.count(l -> l.valid && l.active)];
+                    executor.linkIds.clear();
                     int index = 0;
                     for(LogicLink link : links){
                         if(link.active && link.valid){
-                            executor.links[index ++] = world.build(link.x, link.y);
+                            Building build = world.build(link.x, link.y);
+                            executor.links[index ++] = build;
+                            if(build != null) executor.linkIds.add(build.id);
                         }
                     }
 
