Merge remote-tracking branch 'origin/master'

This commit is contained in:
Anuken 2025-11-17 14:00:23 -05:00
commit ef2736b3be
8 changed files with 148 additions and 4 deletions

View file

@ -290,6 +290,7 @@ public class Blocks{
liquidDrop = Liquids.oil;
isLiquid = true;
cacheLayer = CacheLayer.tar;
obstructsLight = true;
}};
cryofluid = new Floor("pooled-cryofluid"){{
@ -308,6 +309,8 @@ public class Blocks{
emitLight = true;
lightRadius = 25f;
lightColor = Color.cyan.cpy().a(0.19f);
obstructsLight = true;
forceDrawLight = true;
}};
slag = new Floor("molten-slag"){{
@ -324,6 +327,8 @@ public class Blocks{
emitLight = true;
lightRadius = 40f;
lightColor = Color.orange.cpy().a(0.38f);
obstructsLight = true;
forceDrawLight = true;
}};
space = new Floor("space"){{
@ -486,6 +491,7 @@ public class Blocks{
drownTime = 200f;
cacheLayer = CacheLayer.arkycite;
albedo = 0.9f;
obstructsLight = true;
}};
arkyicStone = new Floor("arkyic-stone"){{
@ -688,6 +694,7 @@ public class Blocks{
sporeCluster = new Prop("spore-cluster"){{
variants = 3;
breakSound = Sounds.plantBreak;
obstructsLight = false;
}};
redweed = new Seaweed("redweed"){{
@ -765,6 +772,7 @@ public class Blocks{
variants = 3;
customShadow = true;
arkyicStone.asFloor().decoration = this;
obstructsLight = false;
}};
crystalCluster = new TallBlock("crystal-cluster"){{

View file

@ -16,6 +16,7 @@ import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.world.*;
import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.environment.Floor.*;
import mindustry.world.blocks.power.*;
@ -50,6 +51,7 @@ public class BlockRenderer{
private BlockQuadtree blockTree = new BlockQuadtree(new Rect(0, 0, 1, 1));
private BlockLightQuadtree blockLightTree = new BlockLightQuadtree(new Rect(0, 0, 1, 1));
private OverlayQuadtree overlayTree = new OverlayQuadtree(new Rect(0, 0, 1, 1));
private FloorQuadtree floorTree = new FloorQuadtree(new Rect(0, 0, 1, 1));
public BlockRenderer(){
@ -76,13 +78,14 @@ public class BlockRenderer{
});
Events.on(TilePreChangeEvent.class, event -> {
if(blockTree == null || floorTree == null) return;
if(blockTree == null || floorTree == null || overlayTree == null) return;
if(indexBlock(event.tile)){
blockTree.remove(event.tile);
blockLightTree.remove(event.tile);
}
if(indexFloor(event.tile)) floorTree.remove(event.tile);
if(indexOverlay(event.tile)) overlayTree.remove(event.tile);
});
Events.on(TileChangeEvent.class, event -> {
@ -112,6 +115,7 @@ public class BlockRenderer{
public void reload(){
blockTree = new BlockQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
blockLightTree = new BlockLightQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
overlayTree = new OverlayQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
floorTree = new FloorQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
shadowEvents.clear();
@ -233,13 +237,25 @@ public class BlockRenderer{
if(indexFloor(tile)) floorTree.insert(tile);
}
public void removeOverlayIndex(Tile tile){
if(indexOverlay(tile)) overlayTree.remove(tile);
}
public void addOverlayIndex(Tile tile){
if(indexOverlay(tile)) overlayTree.insert(tile);
}
boolean indexBlock(Tile tile){
var block = tile.block();
return tile.isCenter() && block != Blocks.air && block.cacheLayer == CacheLayer.normal;
}
boolean indexOverlay(Tile tile){
return !tile.block().obstructsLight && tile.overlay().emitLight && world.getDarkness(tile.x, tile.y) < 3;
}
boolean indexFloor(Tile tile){
return tile.block() == Blocks.air && tile.floor().emitLight && world.getDarkness(tile.x, tile.y) < 3;
return !tile.block().obstructsLight && tile.floor().emitLight && world.getDarkness(tile.x, tile.y) < 3;
}
void recordIndex(Tile tile){
@ -247,6 +263,7 @@ public class BlockRenderer{
blockTree.insert(tile);
blockLightTree.insert(tile);
}
if(indexOverlay(tile)) overlayTree.insert(tile);
if(indexFloor(tile)) floorTree.insert(tile);
}
@ -399,6 +416,7 @@ public class BlockRenderer{
//draw floor lights
floorTree.intersect(bounds, lightview::add);
overlayTree.intersect(bounds, lightview::add);
blockLightTree.intersect(bounds, tile -> {
if(tile.block().emitLight && (tile.build == null || procLights.add(tile.build.pos()))){
@ -518,8 +536,18 @@ public class BlockRenderer{
entity.drawLight();
}else if(tile.block().emitLight){
tile.block().drawEnvironmentLight(tile);
}else if(tile.floor().emitLight && tile.block() == Blocks.air){ //only draw floor light under non-solid blocks
tile.floor().drawEnvironmentLight(tile);
}
if(!tile.block().obstructsLight){
Floor floor = tile.floor();
Floor overlay = tile.overlay();
if(!floor.obstructsLight && overlay.emitLight){
overlay.drawEnvironmentLight(tile);
}
if(floor.forceDrawLight || (!overlay.obstructsLight && floor.emitLight)){
floor.drawEnvironmentLight(tile);
}
}
}
}
@ -588,6 +616,23 @@ public class BlockRenderer{
}
}
static class OverlayQuadtree extends QuadTree<Tile>{
public OverlayQuadtree(Rect bounds){
super(bounds);
}
@Override
public void hitbox(Tile tile){
var overlay = tile.overlay();
tmp.setCentered(tile.worldx(), tile.worldy(), overlay.lightClipSize, overlay.lightClipSize);
}
@Override
protected QuadTree<Tile> newChild(Rect rect){
return new OverlayQuadtree(rect);
}
}
static class FloorQuadtree extends QuadTree<Tile>{
public FloorQuadtree(Rect bounds){

View file

@ -197,12 +197,62 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
build.items.set(item, amount);
}
@Remote(called = Loc.server, unreliable = true)
public static void setItems(Building build, ItemStack[] items){
if(build == null || build.items == null) return;
for(ItemStack stack : items){
build.items.set(stack.item, stack.amount);
}
}
@Remote(called = Loc.server, unreliable = true)
public static void setTileItems(Item item, int amount, int[] positions){
for(int pos : positions){
Building build = world.build(pos);
if(build != null && build.items != null){
build.items.set(item, amount);
}
}
}
@Remote(called = Loc.server, unreliable = true)
public static void clearItems(Building build){
if(build == null || build.items == null) return;
build.items.clear();
}
@Remote(called = Loc.server, unreliable = true)
public static void setLiquid(Building build, Liquid liquid, float amount){
if(build == null || build.liquids == null) return;
build.liquids.set(liquid, amount);
}
@Remote(called = Loc.server, unreliable = true)
public static void setLiquids(Building build, LiquidStack[] liquids){
if(build == null || build.liquids == null) return;
for(LiquidStack stack : liquids){
build.liquids.set(stack.liquid, stack.amount);
}
}
@Remote(called = Loc.server, unreliable = true)
public static void setTileLiquids(Liquid liquid, float amount, int[] positions){
for(int pos : positions){
Building build = world.build(pos);
if(build != null && build.liquids != null){
build.liquids.set(liquid, amount);
}
}
}
@Remote(called = Loc.server, unreliable = true)
public static void clearLiquids(Building build){
if(build == null || build.liquids == null) return;
build.liquids.clear();
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemTo(@Nullable Unit unit, Item item, int amount, float x, float y, Building build){
if(build == null || build.items == null || item == null) return;

View file

@ -829,6 +829,39 @@ public class TypeIO{
return new ItemStack(readItem(read), read.i());
}
public static void writeItemStacks(Writes write, ItemStack[] stacks){
write.s(stacks.length);
for(ItemStack stack : stacks){
writeItems(write, stack);
}
}
public static ItemStack[] readItemStacks(Reads read){
short count = read.s();
ItemStack[] stacks = new ItemStack[count];
for(int i = 0; i < count; i++)
stacks[i] = readItems(read);
return stacks;
}
public static void writeLiquidStacks(Writes write, LiquidStack[] stacks){
write.s(stacks.length);
for(LiquidStack stack : stacks){
writeLiquid(write, stack.liquid);
write.f(stack.amount);
}
}
public static LiquidStack[] readLiquidStacks(Reads read){
short count = read.s();
LiquidStack[] stacks = new LiquidStack[count];
for(int i = 0; i < count; i++){
Liquid liquid = readLiquid(read);
stacks[i] = new LiquidStack(liquid, read.f());
}
return stacks;
}
public static void writeTeam(Writes write, Team team){
write.b(team == null ? 0 : team.id);
}

View file

@ -321,6 +321,8 @@ public class Block extends UnlockableContent implements Senseable{
public Color lightColor = Color.white.cpy();
/** If true, drawLight() will be called for this block. */
public boolean emitLight = false;
/** If true, this block obstructs light emitted by other blocks. */
public boolean obstructsLight = true;
/** Radius of the light emitted by this block. */
public float lightRadius = 60f;

View file

@ -68,6 +68,8 @@ public class Floor extends Block{
public Block decoration = Blocks.air;
/** Whether units can draw shadows over this. */
public boolean canShadow = true;
/** If true, this floor ignores the obstructsLight flag of overlays. */
public boolean forceDrawLight = false;
/** Whether this overlay needs a surface to be on. False for floating blocks, like spawns. */
public boolean needsSurface = true;
/** If true, cores can be placed on this floor. */
@ -110,6 +112,7 @@ public class Floor extends Block{
allowRectanglePlacement = true;
instantBuild = true;
ignoreBuildDarkness = true;
obstructsLight = false;
placeEffect = Fx.rotateBlock;
}

View file

@ -19,6 +19,7 @@ public class SeaBush extends Prop{
public SeaBush(String name){
super(name);
variants = 0;
obstructsLight = false;
}
@Override

View file

@ -9,6 +9,8 @@ public class Seaweed extends Prop{
public Seaweed(String name){
super(name);
obstructsLight = false;
}
@Override