This commit is contained in:
Anuken
2020-03-05 23:23:10 -05:00
parent 2e19504b65
commit 1c48c1a43e
85 changed files with 2074 additions and 2389 deletions

View File

@@ -156,11 +156,11 @@ public class BlockIndexer{
return flagMap[team.id][type.ordinal()];
}
public boolean eachBlock(Teamc team, float range, Boolf<Tile> pred, Cons<Tile> cons){
public boolean eachBlock(Teamc team, float range, Boolf<Tilec> pred, Cons<Tilec> cons){
return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons);
}
public boolean eachBlock(Team team, float wx, float wy, float range, Boolf<Tile> pred, Cons<Tile> cons){
public boolean eachBlock(Team team, float wx, float wy, float range, Boolf<Tilec> pred, Cons<Tilec> cons){
intSet.clear();
int tx = world.toTile(wx);
@@ -174,11 +174,11 @@ public class BlockIndexer{
for(int y = -tileRange + ty; y <= tileRange + ty; y++){
if(!Mathf.within(x * tilesize, y * tilesize, wx, wy, range)) continue;
Tile other = world.ltile(x, y);
Tilec other = world.ent(x, y);
if(other == null) continue;
if(other.team() == team && !intSet.contains(other.pos()) && other.entity != null && pred.get(other)){
if(other.team() == team && !intSet.contains(other.pos()) && pred.get(other)){
cons.get(other);
any = true;
intSet.add(other.pos());
@@ -214,7 +214,7 @@ public class BlockIndexer{
set.add(entity.tile());
}
public Tilec findEnemyTile(Team team, float x, float y, float range, Boolf<Tile> pred){
public Tilec findEnemyTile(Team team, float x, float y, float range, Boolf<Tilec> pred){
for(Team enemy : activeTeams){
if(!team.isEnemy(enemy)) continue;
@@ -227,11 +227,11 @@ public class BlockIndexer{
return null;
}
public Tilec findTile(Team team, float x, float y, float range, Boolf<Tile> pred){
public Tilec findTile(Team team, float x, float y, float range, Boolf<Tilec> pred){
return findTile(team, x, y, range, pred, false);
}
public Tilec findTile(Team team, float x, float y, float range, Boolf<Tile> pred, boolean usePriority){
public Tilec findTile(Team team, float x, float y, float range, Boolf<Tilec> pred, boolean usePriority){
Tilec closest = null;
float dst = 0;
float range2 = range*range;
@@ -243,15 +243,13 @@ public class BlockIndexer{
for(int tx = rx * quadrantSize; tx < (rx + 1) * quadrantSize && tx < world.width(); tx++){
for(int ty = ry * quadrantSize; ty < (ry + 1) * quadrantSize && ty < world.height(); ty++){
Tile other = world.ltile(tx, ty);
Tilec e = world.ent(tx, ty);
if(other == null) continue;
if(e == null) continue;
if(other.entity == null || other.team() != team || !pred.get(other) || !other.block().targetable)
if(e.team() != team || !pred.get(e) || !e.block().targetable)
continue;
Tilec e = other.entity;
float ndst = e.dst2(x, y);
if(ndst < range2 && (closest == null ||
//this one is closer, and it is at least of equal priority
@@ -365,9 +363,9 @@ public class BlockIndexer{
outer:
for(int x = quadrantX * quadrantSize; x < world.width() && x < (quadrantX + 1) * quadrantSize; x++){
for(int y = quadrantY * quadrantSize; y < world.height() && y < (quadrantY + 1) * quadrantSize; y++){
Tile result = world.ltile(x, y);
Tilec result = world.ent(x, y);
//when a targetable block is found, mark this quadrant as occupied and stop searching
if(result.entity != null && result.team() == team){
if(result!= null && result.team() == team){
bits.set(quadrantX, quadrantY);
break outer;
}

View File

@@ -8,7 +8,6 @@ import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.ctype.*;
import mindustry.entities.AllDefs.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.gen.*;
@@ -29,7 +28,6 @@ import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.units.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.modules.*;
public class Blocks implements ContentList{
public static Block
@@ -588,21 +586,19 @@ public class Blocks implements ContentList{
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name + "-top")};
drawer = tile -> {
LiquidModule mod = tile.entity.liquids();
drawer = entity -> {
int rotation = rotate ? entity.rotation() * 90 : 0;
int rotation = rotate ? tile.rotation() * 90 : 0;
Draw.rect(reg(bottomRegion), entity.x(), entity.y(), rotation);
Draw.rect(reg(bottomRegion), tile.drawx(), tile.drawy(), rotation);
if(mod.total() > 0.001f){
if(entity.liquids().total() > 0.001f){
Draw.color(outputLiquid.liquid.color);
Draw.alpha(mod.get(outputLiquid.liquid) / liquidCapacity);
Draw.rect(reg(liquidRegion), tile.drawx(), tile.drawy(), rotation);
Draw.alpha(entity.liquids().get(outputLiquid.liquid) / liquidCapacity);
Draw.rect(reg(liquidRegion), entity.x(), entity.y(), rotation);
Draw.color();
}
Draw.rect(reg(topRegion), tile.drawx(), tile.drawy(), rotation);
Draw.rect(reg(topRegion), entity.x(), entity.y(), rotation);
};
}};
@@ -680,15 +676,13 @@ public class Blocks implements ContentList{
int topRegion = reg("-top");
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")};
drawer = tile -> {
GenericCrafterEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.rect(reg(frameRegions[(int)Mathf.absin(entity.totalProgress, 5f, 2.999f)]), tile.drawx(), tile.drawy());
Draw.color(Color.clear, tile.entity.liquids().current().color, tile.entity.liquids().total() / liquidCapacity);
Draw.rect(reg(liquidRegion), tile.drawx(), tile.drawy());
drawer = entity -> {
Draw.rect(region, entity.x(), entity.y());
Draw.rect(reg(frameRegions[(int)Mathf.absin(entity.totalProgress, 5f, 2.999f)]), entity.x(), entity.y());
Draw.color(Color.clear, entity.liquids().current().color, entity.liquids().total() / liquidCapacity);
Draw.rect(reg(liquidRegion), entity.x(), entity.y());
Draw.color();
Draw.rect(reg(topRegion), tile.drawx(), tile.drawy());
Draw.rect(reg(topRegion), entity.x(), entity.y());
};
}};
@@ -707,11 +701,9 @@ public class Blocks implements ContentList{
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator")};
drawer = tile -> {
GenericCrafterEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.rect(reg(rotatorRegion), tile.drawx(), tile.drawy(), entity.totalProgress * 2f);
drawer = entity -> {
Draw.rect(region, entity.x(), entity.y());
Draw.rect(reg(rotatorRegion), entity.x(), entity.y(), entity.totalProgress * 2f);
};
}};
@@ -1340,7 +1332,7 @@ public class Blocks implements ContentList{
Items.pyratite, Bullets.standardIncendiary,
Items.silicon, Bullets.standardHoming
);
reload = 20f;
reloadTime = 20f;
restitution = 0.03f;
range = 100;
shootCone = 15f;
@@ -1357,14 +1349,14 @@ public class Blocks implements ContentList{
Items.lead, Bullets.flakLead,
Items.metaglass, Bullets.flakGlass
);
reload = 18f;
reloadTime = 18f;
range = 170f;
size = 2;
burstSpacing = 5f;
shots = 2;
targetGround = false;
recoil = 2f;
recoilAmount = 2f;
rotatespeed = 15f;
inaccuracy = 17f;
shootCone = 35f;
@@ -1379,8 +1371,8 @@ public class Blocks implements ContentList{
Items.coal, Bullets.basicFlame,
Items.pyratite, Bullets.pyraFlame
);
recoil = 0f;
reload = 5f;
recoilAmount = 0f;
reloadTime = 5f;
coolantMultiplier = 2f;
range = 60f;
shootCone = 50f;
@@ -1397,8 +1389,8 @@ public class Blocks implements ContentList{
Items.silicon, Bullets.artilleryHoming,
Items.pyratite, Bullets.artilleryIncendiary
);
reload = 60f;
recoil = 2f;
reloadTime = 60f;
recoilAmount = 2f;
range = 230f;
inaccuracy = 1f;
shootCone = 10f;
@@ -1415,8 +1407,8 @@ public class Blocks implements ContentList{
Liquids.oil, Bullets.oilShot
);
size = 2;
recoil = 0f;
reload = 2f;
recoilAmount = 0f;
reloadTime = 2f;
inaccuracy = 5f;
shootCone = 50f;
shootEffect = Fx.shootLiquid;
@@ -1432,8 +1424,8 @@ public class Blocks implements ContentList{
chargeMaxDelay = 30f;
chargeEffects = 7;
shootType = Bullets.lancerLaser;
recoil = 2f;
reload = 90f;
recoilAmount = 2f;
reloadTime = 90f;
cooldown = 0.03f;
powerUse = 2.5f;
shootShake = 2f;
@@ -1451,7 +1443,7 @@ public class Blocks implements ContentList{
arc = new PowerTurret("arc"){{
requirements(Category.turret, ItemStack.with(Items.copper, 35, Items.lead, 50));
shootType = Bullets.arc;
reload = 35f;
reloadTime = 35f;
shootCone = 40f;
rotatespeed = 8f;
powerUse = 1.5f;
@@ -1459,7 +1451,7 @@ public class Blocks implements ContentList{
range = 90f;
shootEffect = Fx.lightningShoot;
heatColor = Color.red;
recoil = 1f;
recoilAmount = 1f;
size = 1;
health = 260;
shootSound = Sounds.spark;
@@ -1472,7 +1464,7 @@ public class Blocks implements ContentList{
Items.pyratite, Bullets.missileIncendiary,
Items.surgealloy, Bullets.missileSurge
);
reload = 40f;
reloadTime = 40f;
shots = 4;
burstSpacing = 5;
inaccuracy = 10f;
@@ -1495,11 +1487,11 @@ public class Blocks implements ContentList{
size = 2;
range = 150f;
reload = 38f;
reloadTime = 38f;
restitution = 0.03f;
ammoEjectBack = 3f;
cooldown = 0.03f;
recoil = 3f;
recoilAmount = 3f;
shootShake = 2f;
burstSpacing = 3f;
shots = 4;
@@ -1511,10 +1503,10 @@ public class Blocks implements ContentList{
fuse = new ItemTurret("fuse"){{
requirements(Category.turret, ItemStack.with(Items.copper, 225, Items.graphite, 225, Items.thorium, 100));
reload = 35f;
reloadTime = 35f;
shootShake = 4f;
range = 90f;
recoil = 5f;
recoilAmount = 5f;
shots = 3;
spread = 20f;
restitution = 0.1f;
@@ -1573,13 +1565,13 @@ public class Blocks implements ContentList{
size = 3;
shots = 4;
inaccuracy = 12f;
reload = 60f;
reloadTime = 60f;
ammoEjectBack = 5f;
ammoUseEffect = Fx.shellEjectBig;
cooldown = 0.03f;
velocityInaccuracy = 0.2f;
restitution = 0.02f;
recoil = 6f;
recoilAmount = 6f;
shootShake = 2f;
range = 290f;
@@ -1596,10 +1588,10 @@ public class Blocks implements ContentList{
Items.surgealloy, Bullets.flakSurge
);
xRand = 4f;
reload = 6f;
reloadTime = 6f;
range = 200f;
size = 3;
recoil = 3f;
recoilAmount = 3f;
rotatespeed = 10f;
inaccuracy = 10f;
shootCone = 30f;
@@ -1615,13 +1607,13 @@ public class Blocks implements ContentList{
Items.pyratite, Bullets.standardIncendiaryBig,
Items.thorium, Bullets.standardThoriumBig
);
reload = 6f;
reloadTime = 6f;
coolantMultiplier = 0.5f;
restitution = 0.1f;
ammoUseEffect = Fx.shellEjectBig;
range = 200f;
inaccuracy = 3f;
recoil = 3f;
recoilAmount = 3f;
xRand = 3f;
shotWidth = 4f;
shootShake = 2f;
@@ -1639,11 +1631,11 @@ public class Blocks implements ContentList{
shootType = Bullets.meltdownLaser;
shootEffect = Fx.shootBigSmoke2;
shootCone = 40f;
recoil = 4f;
recoilAmount = 4f;
size = 4;
shootShake = 2f;
range = 190f;
reload = 80f;
reloadTime = 80f;
firingMoveFract = 0.5f;
shootDuration = 220f;
powerUse = 14f;

View File

@@ -26,7 +26,7 @@ class AllDefs{
}
@GroupDef(Tilec.class)
class tile{
class gtile{
}

View File

@@ -551,10 +551,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
public void drawSelect(){
}
/** Drawn when you are placing a block. */
public void drawPlace(int x, int y, int rotation, boolean valid){
}
public float drawPlaceText(String text, int x, int y, boolean valid){
if(renderer.pixelator.enabled()) return 0;

View File

@@ -134,7 +134,7 @@ public class MinimapRenderer implements Disposable{
texture.draw(pixmap, 0, 0);
}
public void updateTile(){
public void update(Tile tile){
int color = colorFor(world.tile(tile.x, tile.y));
pixmap.draw(tile.x, pixmap.getHeight() - 1 - tile.y, color);

View File

@@ -187,6 +187,10 @@ public class Block extends UnlockableContent{
}
}
/** Drawn when you are placing a block. */
public void drawPlace(int x, int y, int rotation, boolean valid){
}
/** @return a custom minimap color for this or 0 to use default colors. */
public int minimapColor(Tile tile){
return 0;
@@ -334,7 +338,7 @@ public class Block extends UnlockableContent{
}
/** Listen for a config by class type. */
public <T> void config(Class<T> type, Cons2<Tile, T> config){
public <T> void config(Class<T> type, Cons2<Tilec, T> config){
configurations.put(type, config);
}

View File

@@ -99,10 +99,10 @@ public class Tile implements Position{
if(entity != null) Call.onTileConfig(null, entity, value);
}
//@SuppressWarnings("unchecked")
//public <T extends TileEntity> T ent(){
// return (T)entity;
//}
@SuppressWarnings("unchecked")
public <T extends TileEntity> T ent(){
return (T)entity;
}
public float worldx(){
return x * tilesize;

View File

@@ -37,7 +37,7 @@ public interface Autotiler{
return buildBlending(req.tile(), req.rotation, directionals, req.worldContext);
}
default int[] buildBlending(Tile tile, int rotation, BuildRequest[] directional, boolean world){
default int[] buildBlending(int rotation, BuildRequest[] directional, boolean world){
int[] blendresult = AutotilerHolder.blendresult;
blendresult[0] = 0;
blendresult[1] = blendresult[2] = 1;
@@ -71,7 +71,7 @@ public interface Autotiler{
}
}
default boolean blends(Tile tile, int rotation, @Nullable BuildRequest[] directional, int direction, boolean checkWorld){
default boolean blends(int rotation, @Nullable BuildRequest[] directional, int direction, boolean checkWorld){
int realDir = Mathf.mod(rotation - direction, 4);
if(directional != null && directional[realDir] != null){
BuildRequest req = directional[realDir];
@@ -82,21 +82,21 @@ public interface Autotiler{
return checkWorld && blends(tile, rotation, direction);
}
default boolean blends(Tile tile, int rotation, int direction){
default boolean blends(int rotation, int direction){
Tilec other = tile.getNearbyEntity(Mathf.mod(rotation - direction, 4));
return other != null && other.team() == tile.team() && blends(tile, rotation, other.tileX(), other.tileY(), other.rotation(), other.block());
return other != null && other.team() == team && blends(tile, rotation, other.tileX(), other.tileY(), other.rotation(), other.block());
}
default boolean blendsArmored(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
default boolean blendsArmored(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery)
|| ((!otherblock.rotate && Edges.getFacingEdge(otherblock, otherx, othery, tile) != null &&
Edges.getFacingEdge(otherblock, otherx, othery, tile).relativeTo(tile) == rotation) || (otherblock.rotate && Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y))));
}
default boolean lookingAt(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
default boolean lookingAt(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return (Point2.equals(tile.x + Geometry.d4(rotation).x, tile.y + Geometry.d4(rotation).y, otherx, othery)
|| (!otherblock.rotate || Point2.equals(otherx + Geometry.d4(otherrot).x, othery + Geometry.d4(otherrot).y, tile.x, tile.y)));
}
boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock);
boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock);
}

View File

@@ -39,9 +39,7 @@ public class BuildBlock extends Block{
layer = Layer.placement;
consumesTap = true;
solidifes = true;
entityType = BuildEntity::new;
buildBlocks[size - 1] = this;
buildBlocks[size - 1] = this;
}
/** Returns a BuildBlock by size. */
@@ -51,27 +49,27 @@ public class BuildBlock extends Block{
}
@Remote(called = Loc.server)
public static void onDeconstructFinish(Tile tile, Block block, int builderID){
Team team = tile.team();
Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size);
public static void onDeconstructFinish(Block block, int builderID){
Team team = team;
Fx.breakBlock.at(x, y, block.size);
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, true));
tile.remove();
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
}
@Remote(called = Loc.server)
public static void onConstructFinish(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
public static void onConstructFinish(Block block, int builderID, byte rotation, Team team, boolean skipConfig){
if(tile == null) return;
float healthf = tile.entity.healthf();
float healthf = tile.healthf();
tile.setBlock(block, team, (int)rotation);
tile.entity.health(block.health * healthf);
tile.health(block.health * healthf);
//last builder was this local client player, call placed()
if(!headless && builderID == player.unit().id()){
if(!skipConfig){
tile.entity.playerPlaced();
tile.playerPlaced();
}
}
Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size);
Fx.placeBlock.at(x, y, block.size);
}
static boolean shouldPlay(){
@@ -98,9 +96,9 @@ public class BuildBlock extends Block{
}
}
public static void constructed(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
public static void constructed(Block block, int builderID, byte rotation, Team team, boolean skipConfig){
Call.onConstructFinish(tile, block, builderID, rotation, team, skipConfig);
tile.entity.placed();
tile.placed();
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
@@ -166,7 +164,7 @@ public class BuildBlock extends Block{
Fx.blockExplosionSmoke.at(tile);
if(!tile.floor().solid && !tile.floor().isLiquid){
Effects.rubble(tile.drawx(), tile.drawy(), size);
Effects.rubble(x, y, size);
}
}
@@ -180,7 +178,7 @@ public class BuildBlock extends Block{
if(previous == null || cblock == null) return;
if(Core.atlas.isFound(previous.icon(Cicon.full))){
Draw.rect(previous.icon(Cicon.full), tile.drawx(), tile.drawy(), previous.rotate ? tile.rotation() * 90 : 0);
Draw.rect(previous.icon(Cicon.full), x, y, previous.rotate ? tile.rotation() * 90 : 0);
}
}
@@ -196,7 +194,7 @@ public class BuildBlock extends Block{
Shaders.blockbuild.region = region;
Shaders.blockbuild.progress = progress;
Draw.rect(region, tile.drawx(), tile.drawy(), target.rotate ? tile.rotation() * 90 : 0);
Draw.rect(region, x, y, target.rotate ? tile.rotation() * 90 : 0);
Draw.flush();
}
}

View File

@@ -6,7 +6,6 @@ import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.gen.*;
import mindustry.world.*;
import static mindustry.Vars.tilesize;
@@ -19,63 +18,60 @@ public class DeflectorWall extends Wall{
public DeflectorWall(String name){
super(name);
entityType = DeflectorEntity::new;
}
@Override
public void draw(){
super.draw(tile);
DeflectorEntity entity = tile.ent();
if(entity.hit < 0.0001f) return;
Draw.color(Color.white);
Draw.alpha(entity.hit * 0.5f);
Draw.blend(Blending.additive);
Fill.rect(tile.drawx(), tile.drawy(), tilesize * size, tilesize * size);
Draw.blend();
Draw.reset();
entity.hit = Mathf.clamp(entity.hit - Time.delta() / hitTime);
}
@Override
public void handleBulletHit(Tilec entity, Bulletc bullet){
super.handleBulletHit(entity, bullet);
//TODO fix and test
//doesn't reflect powerful bullets
if(bullet.damage() > maxDamageDeflect) return;
float penX = Math.abs(entity.getX() - bullet.x()), penY = Math.abs(entity.getY() - bullet.y());
bullet.hitbox(rect2);
Vec2 position = Geometry.raycastRect(bullet.x() - bullet.vel().x*Time.delta(), bullet.y() - bullet.vel().y*Time.delta(), bullet.x() + bullet.vel().x*Time.delta(), bullet.y() + bullet.vel().y*Time.delta(),
rect.setSize(size * tilesize + rect2.width*2 + rect2.height*2).setCenter(entity.getX(), entity.getY()));
if(position != null){
bullet.set(position.x, position.y);
}
if(penX > penY){
bullet.vel().x *= -1;
}else{
bullet.vel().y *= -1;
}
//bullet.updateVelocity();
bullet.owner(entity);
bullet.team(entity.team());
bullet.time(bullet.time() + 1f);
//TODO deflect
//bullet.deflect();
((DeflectorEntity)entity).hit = 1f;
}
public static class DeflectorEntity extends TileEntity{
public class DeflectorEntity extends TileEntity{
public float hit;
@Override
public void draw(){
super.draw();
if(hit < 0.0001f) return;
Draw.color(Color.white);
Draw.alpha(hit * 0.5f);
Draw.blend(Blending.additive);
Fill.rect(x, y, tilesize * size, tilesize * size);
Draw.blend();
Draw.reset();
hit = Mathf.clamp(hit - Time.delta() / hitTime);
}
@Override
public void collision(Bulletc bullet){
super.collision(bullet);
//TODO fix and test
//doesn't reflect powerful bullets
if(bullet.damage() > maxDamageDeflect) return;
float penX = Math.abs(getX() - bullet.x()), penY = Math.abs(getY() - bullet.y());
bullet.hitbox(rect2);
Vec2 position = Geometry.raycastRect(bullet.x() - bullet.vel().x*Time.delta(), bullet.y() - bullet.vel().y*Time.delta(), bullet.x() + bullet.vel().x*Time.delta(), bullet.y() + bullet.vel().y*Time.delta(),
rect.setSize(size * tilesize + rect2.width*2 + rect2.height*2).setCenter(getX(), getY()));
if(position != null){
bullet.set(position.x, position.y);
}
if(penX > penY){
bullet.vel().x *= -1;
}else{
bullet.vel().y *= -1;
}
//bullet.updateVelocity();
bullet.owner(this);
bullet.team(team());
bullet.time(bullet.time() + 1f);
//TODO deflect
//bullet.deflect();
hit = 1f;
}
}
}

View File

@@ -11,7 +11,6 @@ import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.world.*;
import static mindustry.Vars.pathfinder;
@@ -29,19 +28,12 @@ public class Door extends Wall{
solid = false;
solidifes = true;
consumesTap = true;
entityType = DoorEntity::new;
config(Boolean.class, (tile, open) -> {
DoorEntity entity = tile.ent();
entity.open = open;
pathfinder.updateTile(tile);
if(!entity.open){
openfx.at(tile.drawx(), tile.drawy());
}else{
closefx.at(tile.drawx(), tile.drawy());
}
Sounds.door.at(tile);
config(Boolean.class, (entity, open) -> {
DoorEntity door = (DoorEntity)entity;
door.open = open;
pathfinder.updateTile(door.tile());
(open ? closefx : openfx).at(door);
Sounds.door.at(door);
});
}
@@ -51,42 +43,38 @@ public class Door extends Wall{
openRegion = Core.atlas.find(name + "-open");
}
@Override
public void draw(){
DoorEntity entity = tile.ent();
Draw.rect(entity.open ? openRegion : region, tile.drawx(), tile.drawy());
}
@Override
public TextureRegion getRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
return req.config == Boolean.TRUE ? openRegion : region;
}
@Override
public Cursor getCursor(Tile tile){
return SystemCursor.hand;
}
@Override
public boolean isSolidFor(Tile tile){
DoorEntity entity = tile.ent();
return !entity.open;
}
@Override
public void tapped(Tile tile, Playerc player){
DoorEntity entity = tile.ent();
if((Units.anyEntities(tile) && entity.open) || !tile.entity.timer(timerToggle, 30f)){
return;
}
tile.configure(!entity.open);
}
public class DoorEntity extends TileEntity{
public boolean open = false;
@Override
public void draw(){
Draw.rect(open ? openRegion : region, x, y);
}
@Override
public Cursor getCursor(){
return SystemCursor.hand;
}
@Override
public boolean checkSolid(){
return !open;
}
@Override
public void tapped(Playerc player){
if((Units.anyEntities(tile) && open) || !timer(timerToggle, 30f)){
return;
}
tile.configure(!open);
}
@Override
public Boolean config(){
return open;

View File

@@ -5,7 +5,6 @@ import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.content.*;
@@ -15,8 +14,6 @@ import mindustry.world.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import java.io.*;
import static mindustry.Vars.tilesize;
public class ForceProjector extends Block{
@@ -34,14 +31,16 @@ public class ForceProjector extends Block{
private static Tile paramTile;
private static ForceProjector paramBlock;
private static ForceEntity paramEntity;
private static ForceProjectorEntity paramEntity;
private static Cons<Shielderc> shieldConsumer = trait -> {
if(trait.team() != paramTile.team() && Intersector.isInsideHexagon(trait.x(), trait.y(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
//TODO implement
/*
if(trait.team() != paramteam && Intersector.isInsideHexagon(trait.x(), trait.y(), paramEntity.realRadius() * 2f, paramx, paramy)){
trait.absorb();
Fx.absorb.at(trait);
paramEntity.hit = 1f;
paramEntity.buildup += trait.damage() * paramEntity.warmup;
}
paramhit = 1f;
parambuildup += trait.damage() * paramwarmup;
}*/
};
public ForceProjector(String name){
@@ -53,7 +52,6 @@ public class ForceProjector extends Block{
hasLiquids = true;
hasItems = true;
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).boost().update(false);
entityType = ForceEntity::new;
}
@Override
@@ -85,84 +83,7 @@ public class ForceProjector extends Block{
Draw.color();
}
@Override
public void updateTile(){
ForceEntity entity = tile.ent();
if(entity.shield == null){
//TODO implement
//entity.shield = new ShieldEntity(tile);
//entity.shield.add();
}
boolean phaseValid = consumes.get(ConsumeType.item).valid(tile.entity);
entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, Mathf.num(phaseValid), 0.1f);
if(phaseValid && !entity.broken && entity.timer(timerUse, phaseUseTime) && entity.efficiency() > 0){
entity.consume();
}
entity.radscl = Mathf.lerpDelta(entity.radscl, entity.broken ? 0f : entity.warmup, 0.05f);
if(Mathf.chance(Time.delta() * entity.buildup / breakage * 0.1f)){
Fx.reactorsmoke.at(tile.drawx() + Mathf.range(tilesize / 2f), tile.drawy() + Mathf.range(tilesize / 2f));
}
entity.warmup = Mathf.lerpDelta(entity.warmup, entity.efficiency(), 0.1f);
if(entity.buildup > 0){
float scale = !entity.broken ? cooldownNormal : cooldownBrokenBase;
ConsumeLiquidFilter cons = consumes.get(ConsumeType.liquid);
if(cons.valid(entity)){
cons.update(entity);
scale *= (cooldownLiquid * (1f + (entity.liquids().current().heatCapacity - 0.4f) * 0.9f));
}
entity.buildup -= Time.delta() * scale;
}
if(entity.broken && entity.buildup <= 0){
entity.broken = false;
}
if(entity.buildup >= breakage && !entity.broken){
entity.broken = true;
entity.buildup = breakage;
Fx.shieldBreak.at(tile.drawx(), tile.drawy(), radius);
}
if(entity.hit > 0f){
entity.hit -= 1f / 5f * Time.delta();
}
float realRadius = realRadius(entity);
paramTile = tile;
paramEntity = entity;
paramBlock = this;
Groups.bullet.intersect(tile.drawx() - realRadius, tile.drawy() - realRadius, realRadius*2f, realRadius * 2f, shieldConsumer);
}
float realRadius(ForceEntity entity){
return (radius + entity.phaseHeat * phaseRadiusBoost) * entity.radscl;
}
@Override
public void draw(){
super.draw(tile);
ForceEntity entity = tile.ent();
if(entity.buildup <= 0f) return;
Draw.alpha(entity.buildup / breakage * 0.75f);
Draw.blend(Blending.additive);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.blend();
Draw.reset();
}
class ForceEntity extends TileEntity{
public class ForceProjectorEntity extends TileEntity{
ShieldEntity shield;
boolean broken = true;
float buildup = 0f;
@@ -171,6 +92,79 @@ public class ForceProjector extends Block{
float warmup;
float phaseHeat;
@Override
public void updateTile(){
if(shield == null){
//TODO implement
//shield = new ShieldEntity(tile);
//shield.add();
}
boolean phaseValid = consumes.get(ConsumeType.item).valid(tile.entity);
phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(phaseValid), 0.1f);
if(phaseValid && !broken && timer(timerUse, phaseUseTime) && efficiency() > 0){
consume();
}
radscl = Mathf.lerpDelta(radscl, broken ? 0f : warmup, 0.05f);
if(Mathf.chance(Time.delta() * buildup / breakage * 0.1f)){
Fx.reactorsmoke.at(x + Mathf.range(tilesize / 2f), y + Mathf.range(tilesize / 2f));
}
warmup = Mathf.lerpDelta(warmup, efficiency(), 0.1f);
if(buildup > 0){
float scale = !broken ? cooldownNormal : cooldownBrokenBase;
ConsumeLiquidFilter cons = consumes.get(ConsumeType.liquid);
if(cons.valid(this)){
cons.update(this);
scale *= (cooldownLiquid * (1f + (liquids.current().heatCapacity - 0.4f) * 0.9f));
}
buildup -= Time.delta() * scale;
}
if(broken && buildup <= 0){
broken = false;
}
if(buildup >= breakage && !broken){
broken = true;
buildup = breakage;
Fx.shieldBreak.at(x, y, radius);
}
if(hit > 0f){
hit -= 1f / 5f * Time.delta();
}
float realRadius = realRadius();
paramTile = tile;
paramEntity = this;
paramBlock = ForceProjector.this;
Groups.bullet.intersect(x - realRadius, y - realRadius, realRadius*2f, realRadius * 2f, shieldConsumer);
}
float realRadius(){
return (radius + phaseHeat * phaseRadiusBoost) * radscl;
}
@Override
public void draw(){
super.draw();
if(buildup <= 0f) return;
Draw.alpha(buildup / breakage * 0.75f);
Draw.blend(Blending.additive);
Draw.rect(topRegion, x, y);
Draw.blend();
Draw.reset();
}
@Override
public void write(Writes write){
super.write(write);
@@ -203,14 +197,14 @@ public class ForceProjector extends Block{
public class ShieldEntity extends BaseEntity implements DrawTrait{
final ForceEntity entity;
public ShieldEntity(Tile tile){
public ShieldEntity(){
this.entity = tile.ent();
set(tile.drawx(), tile.drawy());
set(x, y);
}
@Override
public void update(){
if(entity.isDead() || !entity.isAdded()){
if(isDead() || !isAdded()){
remove();
}
}
@@ -228,10 +222,10 @@ public class ForceProjector extends Block{
}
public void drawOver(){
if(entity.hit <= 0f) return;
if(hit <= 0f) return;
Draw.color(Color.white);
Draw.alpha(entity.hit);
Draw.alpha(hit);
Fill.poly(x, y, 6, realRadius(entity));
Draw.color();
}
@@ -243,7 +237,7 @@ public class ForceProjector extends Block{
Draw.color(Pal.accent);
Lines.stroke(1.5f);
Draw.alpha(0.09f + 0.08f * entity.hit);
Draw.alpha(0.09f + 0.08f * hit);
Fill.poly(x, y, 6, rad);
Draw.alpha(1f);
Lines.poly(x, y, 6, rad);

View File

@@ -35,7 +35,6 @@ public class MendProjector extends Block{
update = true;
hasPower = true;
hasItems = true;
entityType = MendEntity::new;
}
@Override
@@ -60,70 +59,67 @@ public class MendProjector extends Block{
stats.add(BlockStat.boostEffect, (phaseBoost + healPercent) / healPercent, StatUnit.timesSpeed);
}
@Override
public void updateTile(){
MendEntity entity = tile.ent();
entity.heat = Mathf.lerpDelta(entity.heat, entity.consValid() || tile.isEnemyCheat() ? 1f : 0f, 0.08f);
entity.charge += entity.heat * entity.delta();
entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, Mathf.num(entity.cons().optionalValid()), 0.1f);
if(entity.cons().optionalValid() && entity.timer(timerUse, useTime) && entity.efficiency() > 0){
entity.consume();
}
if(entity.charge >= reload){
float realRange = range + entity.phaseHeat * phaseRangeBoost;
entity.charge = 0f;
indexer.eachBlock(entity, realRange, other -> other.entity.damaged(), other -> {
other.entity.heal(other.entity.maxHealth() * (healPercent + entity.phaseHeat * phaseBoost) / 100f * entity.efficiency());
Fx.healBlockFull.at(other.drawx(), other.drawy(), other.block().size, Tmp.c1.set(baseColor).lerp(phaseColor, entity.phaseHeat));
});
}
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Drawf.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range, Pal.accent);
}
@Override
public void drawSelect(Tile tile){
MendEntity entity = tile.ent();
float realRange = range + entity.phaseHeat * phaseRangeBoost;
Drawf.dashCircle(tile.drawx(), tile.drawy(), realRange, baseColor);
}
@Override
public void draw(){
super.draw(tile);
MendEntity entity = tile.ent();
float f = 1f - (Time.time() / 100f) % 1f;
Draw.color(baseColor, phaseColor, entity.phaseHeat);
Draw.alpha(entity.heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.alpha(1f);
Lines.stroke((2f * f + 0.2f) * entity.heat);
Lines.square(tile.drawx(), tile.drawy(), ((1f - f) * 8f) * size / 2f);
Draw.reset();
}
@Override
public void drawLight(Tile tile){
renderer.lights.add(tile.drawx(), tile.drawy(), 50f * tile.entity.efficiency(), baseColor, 0.7f * tile.entity.efficiency());
}
class MendEntity extends TileEntity{
public class MendEntity extends TileEntity{
float heat;
float charge = Mathf.random(reload);
float phaseHeat;
@Override
public void updateTile(){
heat = Mathf.lerpDelta(heat, consValid() || tile.isEnemyCheat() ? 1f : 0f, 0.08f);
charge += heat * delta();
phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(cons().optionalValid()), 0.1f);
if(cons().optionalValid() && timer(timerUse, useTime) && efficiency() > 0){
consume();
}
if(charge >= reload){
float realRange = range + phaseHeat * phaseRangeBoost;
charge = 0f;
indexer.eachBlock(this, realRange, other -> other.damaged(), other -> {
other.heal(other.maxHealth() * (healPercent + phaseHeat * phaseBoost) / 100f * efficiency());
Fx.healBlockFull.at(other.x(), other.y(), other.block().size, Tmp.c1.set(baseColor).lerp(phaseColor, phaseHeat));
});
}
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Drawf.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range, Pal.accent);
}
@Override
public void drawSelect(){
float realRange = range + phaseHeat * phaseRangeBoost;
Drawf.dashCircle(x, y, realRange, baseColor);
}
@Override
public void draw(){
super.draw();
float f = 1f - (Time.time() / 100f) % 1f;
Draw.color(baseColor, phaseColor, phaseHeat);
Draw.alpha(heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f);
Draw.rect(topRegion, x, y);
Draw.alpha(1f);
Lines.stroke((2f * f + 0.2f) * heat);
Lines.square(x, y, ((1f - f) * 8f) * size / 2f);
Draw.reset();
}
@Override
public void drawLight(){
renderer.lights.add(x, y, 50f * efficiency(), baseColor, 0.7f * efficiency());
}
@Override
public void write(Writes write){
super.write(write);

View File

@@ -36,7 +36,6 @@ public class OverdriveProjector extends Block{
hasPower = true;
hasItems = true;
canOverdrive = false;
entityType = OverdriveEntity::new;
}
@Override
@@ -66,62 +65,59 @@ public class OverdriveProjector extends Block{
stats.add(BlockStat.boostEffect, (int)((speedBoost + speedBoostPhase) * 100f), StatUnit.percent);
}
@Override
public void drawLight(Tile tile){
renderer.lights.add(tile.drawx(), tile.drawy(), 50f * tile.entity.efficiency(), baseColor, 0.7f * tile.entity.efficiency());
}
@Override
public void updateTile(){
OverdriveEntity entity = tile.ent();
entity.heat = Mathf.lerpDelta(entity.heat, entity.consValid() ? 1f : 0f, 0.08f);
entity.charge += entity.heat * Time.delta();
entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, Mathf.num(entity.cons().optionalValid()), 0.1f);
if(entity.timer(timerUse, useTime) && entity.efficiency() > 0){
entity.consume();
}
if(entity.charge >= reload){
float realRange = range + entity.phaseHeat * phaseRangeBoost;
float realBoost = (speedBoost + entity.phaseHeat * speedBoostPhase) * entity.efficiency();
entity.charge = 0f;
indexer.eachBlock(entity, realRange, other -> other.entity.timeScale() < realBoost, other -> other.entity.applyBoost(realBoost, reload + 1f));
}
}
@Override
public void drawSelect(Tile tile){
OverdriveEntity entity = tile.ent();
float realRange = range + entity.phaseHeat * phaseRangeBoost;
Drawf.dashCircle(tile.drawx(), tile.drawy(), realRange, baseColor);
}
@Override
public void draw(){
super.draw(tile);
OverdriveEntity entity = tile.ent();
float f = 1f - (Time.time() / 100f) % 1f;
Draw.color(baseColor, phaseColor, entity.phaseHeat);
Draw.alpha(entity.heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.alpha(1f);
Lines.stroke((2f * f + 0.2f) * entity.heat);
Lines.square(tile.drawx(), tile.drawy(), (1f - f) * 8f);
Draw.reset();
}
class OverdriveEntity extends TileEntity{
public class OverdriveEntity extends TileEntity{
float heat;
float charge = Mathf.random(reload);
float phaseHeat;
@Override
public void drawLight(){
renderer.lights.add(x, y, 50f * efficiency(), baseColor, 0.7f * efficiency());
}
@Override
public void updateTile(){
heat = Mathf.lerpDelta(heat, consValid() ? 1f : 0f, 0.08f);
charge += heat * Time.delta();
phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(cons().optionalValid()), 0.1f);
if(timer(timerUse, useTime) && efficiency() > 0){
consume();
}
if(charge >= reload){
float realRange = range + phaseHeat * phaseRangeBoost;
float realBoost = (speedBoost + phaseHeat * speedBoostPhase) * efficiency();
charge = 0f;
indexer.eachBlock(this, realRange, other -> other.timeScale() < realBoost, other -> other.applyBoost(realBoost, reload + 1f));
}
}
@Override
public void drawSelect(){
float realRange = range + phaseHeat * phaseRangeBoost;
Drawf.dashCircle(x, y, realRange, baseColor);
}
@Override
public void draw(){
super.draw();
float f = 1f - (Time.time() / 100f) % 1f;
Draw.color(baseColor, phaseColor, phaseHeat);
Draw.alpha(heat * Mathf.absin(Time.time(), 10f, 1f) * 0.5f);
Draw.rect(topRegion, x, y);
Draw.alpha(1f);
Lines.stroke((2f * f + 0.2f) * heat);
Lines.square(x, y, (1f - f) * 8f);
Draw.reset();
}
@Override
public void write(Writes write){
super.write(write);

View File

@@ -26,32 +26,35 @@ public class ShockMine extends Block{
rebuildable = false;
}
@Override
public void drawLayer(Tile tile){
super.draw(tile);
Draw.color(tile.team().color);
Draw.alpha(0.22f);
Fill.rect(tile.drawx(), tile.drawy(), 2f, 2f);
Draw.color();
}
public class ShockMineEntity extends TileEntity{
@Override
public void drawTeam(Tile tile){
//no
}
@Override
public void drawLayer(){
super.draw();
Draw.color(team.color);
Draw.alpha(0.22f);
Fill.rect(x, y, 2f, 2f);
Draw.color();
}
@Override
public void draw(){
//nope
}
@Override
public void drawTeam(){
//no
}
@Override
public void unitOn(Tile tile, Unitc unit){
if(unit.team() != tile.team() && tile.entity.timer(timerDamage, cooldown)){
for(int i = 0; i < tendrils; i++){
Lightning.create(tile.team(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length);
@Override
public void draw(){
//nope
}
@Override
public void unitOn(Unitc unit){
if(unit.team() != team && timer(timerDamage, cooldown)){
for(int i = 0; i < tendrils; i++){
Lightning.create(team, Pal.lancerLaser, damage, x, y, Mathf.random(360f), length);
}
damage(tileDamage);
}
tile.entity.damage(tileDamage);
}
}
}

View File

@@ -14,11 +14,13 @@ public class SurgeWall extends Wall{
super(name);
}
@Override
public void handleBulletHit(Tilec entity, Bulletc bullet){
super.handleBulletHit(entity, bullet);
if(Mathf.chance(lightningChance)){
Lightning.create(entity.team(), Pal.surge, lightningDamage, bullet.x(), bullet.y(), bullet.rotation() + 180f, lightningLength);
public class SurgeEntity extends TileEntity{
@Override
public void collision(Bulletc bullet){
super.collision(bullet);
if(Mathf.chance(lightningChance)){
Lightning.create(team(), Pal.surge, lightningDamage, bullet.x(), bullet.y(), bullet.rotation() + 180f, lightningLength);
}
}
}
}

View File

@@ -1,12 +1,11 @@
package mindustry.world.blocks.defense;
import arc.Core;
import arc.graphics.g2d.Draw;
import arc.graphics.g2d.TextureRegion;
import arc.math.Mathf;
import mindustry.world.Block;
import mindustry.world.Tile;
import mindustry.world.meta.BlockGroup;
import arc.*;
import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.gen.*;
import mindustry.world.*;
import mindustry.world.meta.*;
public class Wall extends Block{
public int variants = 0;
@@ -33,15 +32,6 @@ public class Wall extends Block{
}
}
@Override
public void draw(){
if(variants == 0){
Draw.rect(region, tile.drawx(), tile.drawy());
}else{
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.drawx(), tile.drawy());
}
}
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")};
@@ -51,4 +41,16 @@ public class Wall extends Block{
public boolean canReplace(Block other){
return super.canReplace(other) && health > other.health;
}
public class WallEntity extends TileEntity{
@Override
public void draw(){
if(variants == 0){
Draw.rect(region, x, y);
}else{
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], x, y);
}
}
}
}

View File

@@ -1,10 +1,9 @@
package mindustry.world.blocks.defense.turrets;
import arc.math.Mathf;
import arc.math.geom.Vec2;
import mindustry.entities.Predict;
import mindustry.entities.bullet.BulletType;
import mindustry.world.Tile;
import arc.math.*;
import arc.math.geom.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import static mindustry.Vars.tilesize;
@@ -19,28 +18,28 @@ public class ArtilleryTurret extends ItemTurret{
targetAir = false;
}
@Override
protected void shoot(Tile tile, BulletType ammo){
TurretEntity entity = tile.ent();
public class ArtilleryTurretEntity extends ItemTurretEntity{
@Override
protected void shoot(BulletType ammo){
recoil = recoilAmount;
heat = 1f;
entity.recoil = recoil;
entity.heat = 1f;
BulletType type = peekAmmo();
BulletType type = peekAmmo(tile);
tr.trns(rotation, size * tilesize / 2);
tr.trns(entity.rotation, size * tilesize / 2);
Vec2 predict = Predict.intercept(tile, target, type.speed);
Vec2 predict = Predict.intercept(tile, entity.target, type.speed);
float dst = dst(predict.x, predict.y);
float maxTraveled = type.lifetime * type.speed;
float dst = entity.dst(predict.x, predict.y);
float maxTraveled = type.lifetime * type.speed;
for(int i = 0; i < shots; i++){
ammo.create(tile.entity, team, x + tr.x, y + tr.y,
rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
}
for(int i = 0; i < shots; i++){
ammo.create(tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y,
entity.rotation + Mathf.range(inaccuracy + type.inaccuracy), 1f + Mathf.range(velocityInaccuracy), (dst / maxTraveled));
effects();
useAmmo();
}
effects(tile);
useAmmo(tile);
}
}

View File

@@ -1,9 +1,8 @@
package mindustry.world.blocks.defense.turrets;
import arc.math.Mathf;
import arc.util.Time;
import mindustry.entities.bullet.BulletType;
import mindustry.world.Tile;
import arc.math.*;
import arc.util.*;
import mindustry.entities.bullet.*;
import static mindustry.Vars.tilesize;
@@ -14,24 +13,25 @@ public class BurstTurret extends ItemTurret{
super(name);
}
@Override
protected void shoot(Tile tile, BulletType ammo){
TurretEntity entity = tile.ent();
public class BurstTurretEntity extends ItemTurretEntity{
entity.heat = 1f;
@Override
protected void shoot(BulletType ammo){
heat = 1f;
for(int i = 0; i < shots; i++){
Time.run(burstSpacing * i, () -> {
if(!(tile.entity instanceof TurretEntity) ||
!hasAmmo(tile)) return;
for(int i = 0; i < shots; i++){
Time.run(burstSpacing * i, () -> {
if(!(tile.entity instanceof TurretEntity) ||
!hasAmmo()) return;
entity.recoil = recoil;
recoil = recoilAmount;
tr.trns(entity.rotation, size * tilesize / 2, Mathf.range(xRand));
bullet(tile, ammo, entity.rotation + Mathf.range(inaccuracy));
effects(tile);
useAmmo(tile);
});
tr.trns(rotation, size * tilesize / 2, Mathf.range(xRand));
bullet(ammo, rotation + Mathf.range(inaccuracy));
effects();
useAmmo();
});
}
}
}
}

View File

@@ -4,9 +4,7 @@ import arc.math.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.Effects.*;
import mindustry.entities.bullet.*;
import mindustry.world.*;
import static mindustry.Vars.tilesize;
@@ -20,46 +18,42 @@ public class ChargeTurret extends PowerTurret{
public ChargeTurret(String name){
super(name);
entityType = LaserTurretEntity::new;
}
@Override
public void shoot(Tile tile, BulletType ammo){
LaserTurretEntity entity = tile.ent();
public class ChargeTurretEntity extends PowerTurretEntity{
public boolean shooting;
useAmmo(tile);
@Override
public void shoot(BulletType ammo){
useAmmo();
tr.trns(entity.rotation, size * tilesize / 2);
chargeBeginEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
tr.trns(rotation, size * tilesize / 2);
chargeBeginEffect.at(x + tr.x, y + tr.y, rotation);
for(int i = 0; i < chargeEffects; i++){
Time.run(Mathf.random(chargeMaxDelay), () -> {
if(!isTurret(tile)) return;
tr.trns(entity.rotation, size * tilesize / 2);
chargeEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
for(int i = 0; i < chargeEffects; i++){
Time.run(Mathf.random(chargeMaxDelay), () -> {
if(!isValid()) return;
tr.trns(rotation, size * tilesize / 2);
chargeEffect.at(x + tr.x, y + tr.y, rotation);
});
}
shooting = true;
Time.run(chargeTime, () -> {
if(!isValid()) return;
tr.trns(rotation, size * tilesize / 2);
recoil = recoilAmount;
heat = 1f;
bullet(ammo, rotation + Mathf.range(inaccuracy));
effects();
shooting = false;
});
}
entity.shooting = true;
Time.run(chargeTime, () -> {
if(!isTurret(tile)) return;
tr.trns(entity.rotation, size * tilesize / 2);
entity.recoil = recoil;
entity.heat = 1f;
bullet(tile, ammo, entity.rotation + Mathf.range(inaccuracy));
effects(tile);
entity.shooting = false;
});
}
@Override
public boolean shouldTurn(Tile tile){
LaserTurretEntity entity = tile.ent();
return !entity.shooting;
}
public class LaserTurretEntity extends TurretEntity{
public boolean shooting;
@Override
public boolean shouldTurn(){
return !shooting;
}
}
}

View File

@@ -6,8 +6,8 @@ import arc.util.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.meta.values.*;
@@ -31,33 +31,36 @@ public class CooledTurret extends Turret{
public void setStats(){
super.setStats();
stats.add(BlockStat.booster, new BoosterListValue(reload, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id)));
stats.add(BlockStat.booster, new BoosterListValue(reloadTime, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id)));
}
@Override
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
if(tile.entity.liquids().currentAmount() <= 0.001f){
Events.fire(Trigger.turretCool);
public class CooledTurretEntity extends TurretEntity{
@Override
public void handleLiquid(Tilec source, Liquid liquid, float amount){
if(liquids.currentAmount() <= 0.001f){
Events.fire(Trigger.turretCool);
}
super.handleLiquid(source, liquid, amount);
}
super.handleLiquid(tile, source, liquid, amount);
}
@Override
protected void updateShooting(){
super.updateShooting();
@Override
protected void updateShooting(Tile tile){
super.updateShooting(tile);
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
Liquid liquid = liquids.current();
TurretEntity entity = tile.ent();
Liquid liquid = entity.liquids().current();
float used = Math.min(Math.min(liquids.get(liquid), maxUsed * Time.delta()), Math.max(0, ((reloadTime - reload) / coolantMultiplier) / liquid.heatCapacity)) * baseReloadSpeed();
reload += used * liquid.heatCapacity * coolantMultiplier;
liquids.remove(liquid, used);
float used = Math.min(Math.min(entity.liquids().get(liquid), maxUsed * Time.delta()), Math.max(0, ((reload - entity.reload) / coolantMultiplier) / liquid.heatCapacity)) * baseReloadSpeed(tile);
entity.reload += used * liquid.heatCapacity * coolantMultiplier;
entity.liquids().remove(liquid, used);
if(Mathf.chance(0.06 * used)){
coolEffect.at(tile.drawx() + Mathf.range(size * tilesize / 2f), tile.drawy() + Mathf.range(size * tilesize / 2f));
if(Mathf.chance(0.06 * used)){
coolEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f));
}
}
}
}

View File

@@ -1,10 +1,8 @@
package mindustry.world.blocks.defense.turrets;
import arc.math.Mathf;
import mindustry.entities.bullet.BulletType;
import mindustry.world.Tile;
import mindustry.world.meta.BlockStat;
import mindustry.world.meta.StatUnit;
import arc.math.*;
import mindustry.entities.bullet.*;
import mindustry.world.meta.*;
import static mindustry.Vars.tilesize;
@@ -21,21 +19,22 @@ public class DoubleTurret extends ItemTurret{
super.setStats();
stats.remove(BlockStat.reload);
stats.add(BlockStat.reload, 60f / reload, StatUnit.none);
stats.add(BlockStat.reload, 60f / reloadTime, StatUnit.none);
}
@Override
protected void shoot(Tile tile, BulletType ammo){
TurretEntity entity = tile.ent();
entity.shots++;
entity.heat = 1f;
public class DoubleTurretEntity extends ItemTurretEntity{
@Override
protected void shoot(BulletType ammo){
shots++;
heat = 1f;
int i = Mathf.signs[entity.shots % 2];
int i = Mathf.signs[shots % 2];
tr.trns(entity.rotation - 90, shotWidth * i, size * tilesize / 2);
bullet(tile, ammo, entity.rotation + Mathf.range(inaccuracy));
tr.trns(rotation - 90, shotWidth * i, size * tilesize / 2);
bullet(ammo, rotation + Mathf.range(inaccuracy));
effects(tile);
useAmmo(tile);
effects();
useAmmo();
}
}
}

View File

@@ -1,19 +1,17 @@
package mindustry.world.blocks.defense.turrets;
import arc.*;
import arc.struct.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.io.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.entities.bullet.*;
import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.ui.Cicon;
import mindustry.world.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.meta.values.*;
@@ -22,17 +20,16 @@ import static mindustry.Vars.*;
public class ItemTurret extends CooledTurret{
public int maxAmmo = 30;
public ObjectMap<Item, BulletType> ammo = new ObjectMap<>();
public ObjectMap<Item, BulletType> ammoTypes = new ObjectMap<>();
public ItemTurret(String name){
super(name);
hasItems = true;
entityType = ItemTurretEntity::new;
}
/** Initializes accepted ammo map. Format: [item1, bullet1, item2, bullet2...] */
protected void ammo(Object... objects){
ammo = OrderedMap.of(objects);
ammoTypes = OrderedMap.of(objects);
}
@Override
@@ -40,13 +37,13 @@ public class ItemTurret extends CooledTurret{
super.setStats();
stats.remove(BlockStat.itemCapacity);
stats.add(BlockStat.ammo, new AmmoListValue<>(ammo));
consumes.add(new ConsumeItemFilter(i -> ammo.containsKey(i)){
stats.add(BlockStat.ammo, new AmmoListValue<>(ammoTypes));
consumes.add(new ConsumeItemFilter(i -> ammoTypes.containsKey(i)){
@Override
public void build(Tilec tile, Table table){
MultiReqImage image = new MultiReqImage();
content.items().each(i -> filter.get(i) && (!state.isCampaign() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium)),
() -> tile.entity != null && !((ItemTurretEntity)tile.entity).ammo.isEmpty() && ((ItemEntry)tile.<ItemTurretEntity>ent().ammo.peek()).item == item)));
() -> tile != null && !((ItemTurretEntity)tile).ammo.isEmpty() && ((ItemEntry)((ItemTurretEntity)tile).ammo.peek()).item == item)));
table.add(image).size(8 * 4);
}
@@ -64,91 +61,83 @@ public class ItemTurret extends CooledTurret{
});
}
@Override
public void onProximityAdded(Tile tile){
super.onProximityAdded(tile);
public class ItemTurretEntity extends TurretEntity{
@Override
public void onProximityAdded(){
super.onProximityAdded();
//add first ammo item to cheaty blocks so they can shoot properly
if(tile.isEnemyCheat() && ammo.size > 0){
handleItem(tile, tile, ammo.entries().next().key);
}
}
@Override
public void displayBars(Tile tile, Table bars){
super.displayBars(tile, bars);
TurretEntity entity = tile.ent();
bars.add(new Bar("blocks.ammo", Pal.ammo, () -> (float)entity.totalAmmo / maxAmmo)).growX();
bars.row();
}
@Override
public int acceptStack(Tile tile, Item item, int amount, Teamc source){
TurretEntity entity = tile.ent();
BulletType type = ammo.get(item);
if(type == null) return 0;
return Math.min((int)((maxAmmo - entity.totalAmmo) / ammo.get(item).ammoMultiplier), amount);
}
@Override
public void handleStack(Tile tile, Item item, int amount, Teamc source){
for(int i = 0; i < amount; i++){
handleItem(tile, null, item);
}
}
//currently can't remove items from turrets.
@Override
public int removeStack(Tile tile, Item item, int amount){
return 0;
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
TurretEntity entity = tile.ent();
if(entity == null) return;
if(item == Items.pyratite){
Events.fire(Trigger.flameAmmo);
}
BulletType type = ammo.get(item);
entity.totalAmmo += type.ammoMultiplier;
//find ammo entry by type
for(int i = 0; i < entity.ammo.size; i++){
ItemEntry entry = (ItemEntry)entity.ammo.get(i);
//if found, put it to the right
if(entry.item == item){
entry.amount += type.ammoMultiplier;
entity.ammo.swap(i, entity.ammo.size - 1);
return;
//add first ammo item to cheaty blocks so they can shoot properly
if(tile.isEnemyCheat() && ammo.size > 0){
handleItem(this, ammoTypes.entries().next().key);
}
}
//must not be found
entity.ammo.add(new ItemEntry(item, (int)type.ammoMultiplier));
@Override
public void displayBars(Table bars){
super.displayBars(bars);
//fire events for the tutorial
if(state.rules.tutorial){
Events.fire(new TurretAmmoDeliverEvent());
bars.add(new Bar("blocks.ammo", Pal.ammo, () -> (float)totalAmmo / maxAmmo)).growX();
bars.row();
}
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
TurretEntity entity = tile.ent();
@Override
public int acceptStack(Item item, int amount, Teamc source){
BulletType type = ammoTypes.get(item);
return ammo != null && ammo.get(item) != null && entity.totalAmmo + ammo.get(item).ammoMultiplier <= maxAmmo;
}
if(type == null) return 0;
return Math.min((int)((maxAmmo - totalAmmo) / ammoTypes.get(item).ammoMultiplier), amount);
}
@Override
public void handleStack(Item item, int amount, Teamc source){
for(int i = 0; i < amount; i++){
handleItem(null, item);
}
}
//currently can't remove items from turrets.
@Override
public int removeStack(Item item, int amount){
return 0;
}
@Override
public void handleItem(Tilec source, Item item){
if(item == Items.pyratite){
Events.fire(Trigger.flameAmmo);
}
BulletType type = ammoTypes.get(item);
totalAmmo += type.ammoMultiplier;
//find ammo entry by type
for(int i = 0; i < ammo.size; i++){
ItemEntry entry = (ItemEntry)ammo.get(i);
//if found, put it to the right
if(entry.item == item){
entry.amount += type.ammoMultiplier;
ammo.swap(i, ammo.size - 1);
return;
}
}
//must not be found
ammo.add(new ItemEntry(item, (int)type.ammoMultiplier));
//fire events for the tutorial
if(state.rules.tutorial){
Events.fire(new TurretAmmoDeliverEvent());
}
}
@Override
public boolean acceptItem(Tilec source, Item item){
return ammoTypes.get(item) != null && totalAmmo + ammoTypes.get(item).ammoMultiplier <= maxAmmo;
}
public class ItemTurretEntity extends TurretEntity{
@Override
public void write(Writes write){
super.write(write);
@@ -183,7 +172,7 @@ public class ItemTurret extends CooledTurret{
@Override
public BulletType type(){
return ammo.get(item);
return ammoTypes.get(item);
}
}
}

View File

@@ -5,7 +5,6 @@ import arc.util.*;
import mindustry.entities.bullet.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.meta.values.*;
@@ -22,7 +21,6 @@ public class LaserTurret extends PowerTurret{
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.01f)).update(false);
coolantMultiplier = 1f;
entityType = LaserTurretEntity::new;
}
@Override
@@ -30,84 +28,74 @@ public class LaserTurret extends PowerTurret{
super.setStats();
stats.remove(BlockStat.booster);
stats.add(BlockStat.input, new BoosterListValue(reload, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, false, l -> consumes.liquidfilters.get(l.id)));
stats.add(BlockStat.input, new BoosterListValue(reloadTime, consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount, coolantMultiplier, false, l -> consumes.liquidfilters.get(l.id)));
stats.remove(BlockStat.damage);
//damages every 5 ticks, at least in meltdown's case
stats.add(BlockStat.damage, shootType.damage * 60f / 5f, StatUnit.perSecond);
}
@Override
public void updateTile(){
super.update(tile);
LaserTurretEntity entity = tile.ent();
if(entity.bulletLife > 0 && entity.bullet != null){
tr.trns(entity.rotation, size * tilesize / 2f, 0f);
entity.bullet.rotation(entity.rotation);
entity.bullet.set(tile.drawx() + tr.x, tile.drawy() + tr.y);
entity.bullet.time(0f);
entity.heat = 1f;
entity.recoil = recoil;
entity.bulletLife -= Time.delta();
if(entity.bulletLife <= 0f){
entity.bullet = null;
}
}
}
@Override
protected void updateShooting(Tile tile){
LaserTurretEntity entity = tile.ent();
if(entity.bulletLife > 0 && entity.bullet != null){
return;
}
if(entity.reload >= reload && (entity.consValid() || tile.isEnemyCheat())){
BulletType type = peekAmmo(tile);
shoot(tile, type);
entity.reload = 0f;
}else{
Liquid liquid = entity.liquids().current();
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
float used = baseReloadSpeed(tile) * (tile.isEnemyCheat() ? maxUsed : Math.min(entity.liquids().get(liquid), maxUsed * Time.delta())) * liquid.heatCapacity * coolantMultiplier;
entity.reload += used;
entity.liquids().remove(liquid, used);
if(Mathf.chance(0.06 * used)){
coolEffect.at(tile.drawx() + Mathf.range(size * tilesize / 2f), tile.drawy() + Mathf.range(size * tilesize / 2f));
}
}
}
@Override
protected void turnToTarget(Tile tile, float targetRot){
LaserTurretEntity entity = tile.ent();
entity.rotation = Angles.moveToward(entity.rotation, targetRot, rotatespeed * entity.delta() * (entity.bulletLife > 0f ? firingMoveFract : 1f));
}
@Override
protected void bullet(Tile tile, BulletType type, float angle){
LaserTurretEntity entity = tile.ent();
entity.bullet = type.create(tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
entity.bulletLife = shootDuration;
}
@Override
public boolean shouldActiveSound(Tile tile){
LaserTurretEntity entity = tile.ent();
return entity.bulletLife > 0 && entity.bullet != null;
}
class LaserTurretEntity extends TurretEntity{
public class LaserTurretEntity extends PowerTurretEntity{
Bulletc bullet;
float bulletLife;
@Override
public void updateTile(){
super.updateTile();
if(bulletLife > 0 && bullet != null){
tr.trns(rotation, size * tilesize / 2f, 0f);
bullet.rotation(rotation);
bullet.set(x + tr.x, y + tr.y);
bullet.time(0f);
heat = 1f;
recoil = recoilAmount;
bulletLife -= Time.delta();
if(bulletLife <= 0f){
bullet = null;
}
}
}
@Override
protected void updateShooting(){
if(bulletLife > 0 && bullet != null){
return;
}
if(reload >= reloadTime && (consValid() || tile.isEnemyCheat())){
BulletType type = peekAmmo();
shoot(type);
reload = 0f;
}else{
Liquid liquid = liquids().current();
float maxUsed = consumes.<ConsumeLiquidBase>get(ConsumeType.liquid).amount;
float used = baseReloadSpeed() * (tile.isEnemyCheat() ? maxUsed : Math.min(liquids().get(liquid), maxUsed * Time.delta())) * liquid.heatCapacity * coolantMultiplier;
reload += used;
liquids().remove(liquid, used);
if(Mathf.chance(0.06 * used)){
coolEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f));
}
}
}
@Override
protected void turnToTarget(float targetRot){
rotation = Angles.moveToward(rotation, targetRot, rotatespeed * delta() * (bulletLife > 0f ? firingMoveFract : 1f));
}
@Override
protected void bullet(BulletType type, float angle){
bullet = type.create(tile.entity, team, x + tr.x, y + tr.y, angle);
bulletLife = shootDuration;
}
@Override
public boolean shouldActiveSound(){
return bulletLife > 0 && bullet != null;
}
}
}

View File

@@ -7,15 +7,14 @@ import mindustry.entities.*;
import mindustry.entities.bullet.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.meta.values.*;
import static mindustry.Vars.*;
import static mindustry.Vars.tilesize;
public class LiquidTurret extends Turret{
public ObjectMap<Liquid, BulletType> ammo = new ObjectMap<>();
public ObjectMap<Liquid, BulletType> ammoTypes = new ObjectMap<>();
public int liquidRegion;
public LiquidTurret(String name){
@@ -27,28 +26,15 @@ public class LiquidTurret extends Turret{
/** Initializes accepted ammo map. Format: [liquid1, bullet1, liquid2, bullet2...] */
protected void ammo(Object... objects){
ammo = OrderedMap.of(objects);
}
@Override
public void drawLayer(Tile tile){
super.drawLayer(tile);
TurretEntity entity = tile.ent();
if(Core.atlas.isFound(reg(liquidRegion))){
Draw.color(entity.liquids().current().color);
Draw.alpha(entity.liquids().total() / liquidCapacity);
Draw.rect(reg(liquidRegion), tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
Draw.color();
}
ammoTypes = OrderedMap.of(objects);
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.ammo, new AmmoListValue<>(ammo));
consumes.add(new ConsumeLiquidFilter(i -> ammo.containsKey(i), 1f){
stats.add(BlockStat.ammo, new AmmoListValue<>(ammoTypes));
consumes.add(new ConsumeLiquidFilter(i -> ammoTypes.containsKey(i), 1f){
@Override
public boolean valid(Tilec entity){
return !((TurretEntity)entity).ammo.isEmpty();
@@ -61,76 +47,85 @@ public class LiquidTurret extends Turret{
});
}
@Override
public boolean shouldActiveSound(Tile tile){
TurretEntity entity = tile.ent();
return entity.target != null && hasAmmo(tile);
}
public class LiquidTurretEntity extends TurretEntity{
@Override
protected void findTarget(Tile tile){
TurretEntity entity = tile.ent();
if(entity.liquids().current().canExtinguish()){
int tr = (int)(range / tilesize);
for(int x = -tr; x <= tr; x++){
for(int y = -tr; y <= tr; y++){
if(Fires.has(x + tile.x, y + tile.y)){
entity.target = Fires.get(x + tile.x, y + tile.y);
return;
}
}
@Override
public void drawLayer(){
super.drawLayer();
if(Core.atlas.isFound(reg(liquidRegion))){
Draw.color(liquids.current().color);
Draw.alpha(liquids.total() / liquidCapacity);
Draw.rect(reg(liquidRegion), x + tr2.x, y + tr2.y, rotation - 90);
Draw.color();
}
}
super.findTarget(tile);
}
@Override
protected void effects(Tile tile){
BulletType type = peekAmmo(tile);
TurretEntity entity = tile.ent();
type.shootEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color);
type.smokeEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation, entity.liquids().current().color);
shootSound.at(tile);
if(shootShake > 0){
Effects.shake(shootShake, shootShake, tile.entity);
@Override
public boolean shouldActiveSound(){
return target != null && hasAmmo();
}
entity.recoil = recoil;
}
@Override
protected void findTarget(){
if(liquids.current().canExtinguish()){
int tr = (int)(range / tilesize);
for(int x = -tr; x <= tr; x++){
for(int y = -tr; y <= tr; y++){
if(Fires.has(x + tile.x, y + tile.y)){
target = Fires.get(x + tile.x, y + tile.y);
return;
}
}
}
}
@Override
public BulletType useAmmo(Tile tile){
TurretEntity entity = tile.ent();
if(tile.isEnemyCheat()) return ammo.get(entity.liquids().current());
BulletType type = ammo.get(entity.liquids().current());
entity.liquids().remove(entity.liquids().current(), type.ammoMultiplier);
return type;
}
super.findTarget();
}
@Override
public BulletType peekAmmo(Tile tile){
return ammo.get(tile.entity.liquids().current());
}
@Override
protected void effects(){
BulletType type = peekAmmo();
@Override
public boolean hasAmmo(Tile tile){
TurretEntity entity = tile.ent();
return ammo.get(entity.liquids().current()) != null && entity.liquids().total() >= ammo.get(entity.liquids().current()).ammoMultiplier;
}
type.shootEffect.at(x + tr.x, y + tr.y, rotation, liquids.current().color);
type.smokeEffect.at(x + tr.x, y + tr.y, rotation, liquids.current().color);
shootSound.at(tile);
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
return false;
}
if(shootShake > 0){
Effects.shake(shootShake, shootShake, tile.entity);
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return ammo.get(liquid) != null
&& (tile.entity.liquids().current() == liquid || (ammo.containsKey(tile.entity.liquids().current()) && tile.entity.liquids().get(tile.entity.liquids().current()) <= ammo.get(tile.entity.liquids().current()).ammoMultiplier + 0.001f));
}
recoil = recoilAmount;
}
@Override
public BulletType useAmmo(){
if(tile.isEnemyCheat()) return ammoTypes.get(liquids.current());
BulletType type = ammoTypes.get(liquids.current());
liquids.remove(liquids.current(), type.ammoMultiplier);
return type;
}
@Override
public BulletType peekAmmo(){
return ammoTypes.get(liquids.current());
}
@Override
public boolean hasAmmo(){
return ammoTypes.get(liquids.current()) != null && liquids.total() >= ammoTypes.get(liquids.current()).ammoMultiplier;
}
@Override
public boolean acceptItem(Tilec source, Item item){
return false;
}
@Override
public boolean acceptLiquid(Tilec source, Liquid liquid, float amount){
return ammoTypes.get(liquid) != null
&& (liquids.current() == liquid || (ammoTypes.containsKey(liquids.current())
&& liquids.get(liquids.current()) <= ammoTypes.get(liquids.current()).ammoMultiplier + 0.001f));
}
}
}

View File

@@ -1,10 +1,8 @@
package mindustry.world.blocks.defense.turrets;
import arc.util.ArcAnnotate.*;
import mindustry.entities.bullet.BulletType;
import mindustry.world.Tile;
import mindustry.world.meta.BlockStat;
import mindustry.world.meta.StatUnit;
import mindustry.entities.bullet.*;
import mindustry.world.meta.*;
public class PowerTurret extends CooledTurret{
public @NonNull BulletType shootType;
@@ -28,25 +26,28 @@ public class PowerTurret extends CooledTurret{
super.init();
}
@Override
public BulletType useAmmo(Tile tile){
//nothing used directly
return shootType;
}
public class PowerTurretEntity extends CooledTurretEntity{
@Override
public boolean hasAmmo(Tile tile){
//you can always rotate, but never shoot if there's no power
return true;
}
@Override
public BulletType useAmmo(){
//nothing used directly
return shootType;
}
@Override
public BulletType peekAmmo(Tile tile){
return shootType;
}
@Override
public boolean hasAmmo(){
//you can always rotate, but never shoot if there's no power
return true;
}
@Override
protected float baseReloadSpeed(Tile tile){
return tile.isEnemyCheat() ? 1f : tile.entity.power().status;
@Override
public BulletType peekAmmo(){
return shootType;
}
@Override
protected float baseReloadSpeed(){
return tile.isEnemyCheat() ? 1f : power.status;
}
}
}

View File

@@ -33,11 +33,11 @@ public abstract class Turret extends Block{
public int ammoPerShot = 1;
public float ammoEjectBack = 1f;
public float range = 50f;
public float reload = 10f;
public float reloadTime = 10f;
public float inaccuracy = 0f;
public int shots = 1;
public float spread = 4f;
public float recoil = 1f;
public float recoilAmount = 1f;
public float restitution = 0.02f;
public float cooldown = 0.02f;
public float rotatespeed = 5f; //in degrees per tick
@@ -52,12 +52,12 @@ public abstract class Turret extends Block{
public TextureRegion baseRegion, heatRegion;
public Cons2<Tile, TurretEntity> drawer = (tile, entity) -> Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
public Cons2<Tile, TurretEntity> heatDrawer = (tile, entity) -> {
if(entity.heat <= 0.00001f) return;
Draw.color(heatColor, entity.heat);
public Cons<TurretEntity> drawer = tile -> Draw.rect(region, tile.x() + tr2.x, tile.y() + tr2.y, tile.rotation - 90);
public Cons<TurretEntity> heatDrawer = tile -> {
if(tile.heat <= 0.00001f) return;
Draw.color(heatColor, tile.heat);
Draw.blend(Blending.additive);
Draw.rect(heatRegion, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
Draw.rect(heatRegion, tile.x() + tr2.x, tile.y() + tr2.y, tile.rotation - 90);
Draw.blend();
Draw.color();
};
@@ -71,7 +71,6 @@ public abstract class Turret extends Block{
group = BlockGroup.turrets;
flags = EnumSet.of(BlockFlag.turret);
outlineIcon = true;
entityType = TurretEntity::new;
}
@Override
@@ -94,217 +93,29 @@ public abstract class Turret extends Block{
stats.add(BlockStat.shootRange, range / tilesize, StatUnit.blocks);
stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
stats.add(BlockStat.reload, 60f / reload, StatUnit.none);
stats.add(BlockStat.reload, 60f / reloadTime, StatUnit.none);
stats.add(BlockStat.shots, shots, StatUnit.none);
stats.add(BlockStat.targetsAir, targetAir);
stats.add(BlockStat.targetsGround, targetGround);
}
@Override
public void draw(){
Draw.rect(baseRegion, tile.drawx(), tile.drawy());
Draw.color();
}
@Override
public void drawLayer(Tile tile){
TurretEntity entity = tile.ent();
tr2.trns(entity.rotation, -entity.recoil);
drawer.get(tile, entity);
if(heatRegion != Core.atlas.find("error")){
heatDrawer.get(tile, entity);
}
}
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find("block-" + size), Core.atlas.find(name)};
}
@Override
public void drawSelect(Tile tile){
Drawf.dashCircle(tile.drawx(), tile.drawy(), range, tile.team().color);
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Drawf.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range, Pal.placing);
}
@Override
public void updateTile(){
TurretEntity entity = tile.ent();
if(!validateTarget(tile)) entity.target = null;
entity.recoil = Mathf.lerpDelta(entity.recoil, 0f, restitution);
entity.heat = Mathf.lerpDelta(entity.heat, 0f, cooldown);
if(hasAmmo(tile)){
if(entity.timer(timerTarget, targetInterval)){
findTarget(tile);
}
if(validateTarget(tile)){
BulletType type = peekAmmo(tile);
float speed = type.speed;
if(speed < 0.1f) speed = 9999999f;
Vec2 result = Predict.intercept(entity, entity.target, speed);
if(result.isZero()){
result.set(entity.target.getX(), entity.target.getY());
}
float targetRot = result.sub(tile.drawx(), tile.drawy()).angle();
if(Float.isNaN(entity.rotation)){
entity.rotation = 0;
}
if(shouldTurn(tile)){
turnToTarget(tile, targetRot);
}
if(Angles.angleDist(entity.rotation, targetRot) < shootCone){
updateShooting(tile);
}
}
}
}
protected boolean validateTarget(Tile tile){
TurretEntity entity = tile.ent();
return !Units.invalidateTarget(entity.target, tile.team(), tile.drawx(), tile.drawy());
}
protected void findTarget(Tile tile){
TurretEntity entity = tile.ent();
if(targetAir && !targetGround){
entity.target = Units.closestEnemy(tile.team(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && !e.isGrounded());
}else{
entity.target = Units.closestTarget(tile.team(), tile.drawx(), tile.drawy(), range, e -> !e.dead() && (e.isGrounded() || targetAir) && (!e.isGrounded() || targetGround));
}
}
protected void turnToTarget(Tile tile, float targetRot){
TurretEntity entity = tile.ent();
entity.rotation = Angles.moveToward(entity.rotation, targetRot, rotatespeed * entity.delta() * baseReloadSpeed(tile));
}
public boolean shouldTurn(Tile tile){
return true;
}
/** Consume ammo and return a type. */
public BulletType useAmmo(Tile tile){
if(tile.isEnemyCheat()) return peekAmmo(tile);
TurretEntity entity = tile.ent();
AmmoEntry entry = entity.ammo.peek();
entry.amount -= ammoPerShot;
if(entry.amount == 0) entity.ammo.pop();
entity.totalAmmo -= ammoPerShot;
Time.run(reload / 2f, () -> ejectEffects(tile));
return entry.type();
}
/**
* Get the ammo type that will be returned if useAmmo is called.
*/
public BulletType peekAmmo(Tile tile){
TurretEntity entity = tile.ent();
return entity.ammo.peek().type();
}
/**
* Returns whether the turret has ammo.
*/
public boolean hasAmmo(Tile tile){
TurretEntity entity = tile.ent();
return entity.ammo.size > 0 && entity.ammo.peek().amount >= ammoPerShot;
}
protected void updateShooting(Tile tile){
TurretEntity entity = tile.ent();
if(entity.reload >= reload){
BulletType type = peekAmmo(tile);
shoot(tile, type);
entity.reload = 0f;
}else{
entity.reload += tile.entity.delta() * peekAmmo(tile).reloadMultiplier * baseReloadSpeed(tile);
}
}
protected void shoot(Tile tile, BulletType type){
TurretEntity entity = tile.ent();
entity.recoil = recoil;
entity.heat = 1f;
tr.trns(entity.rotation, size * tilesize / 2f, Mathf.range(xRand));
for(int i = 0; i < shots; i++){
bullet(tile, type, entity.rotation + Mathf.range(inaccuracy + type.inaccuracy) + (i - shots / 2) * spread);
}
effects(tile);
useAmmo(tile);
}
protected void bullet(Tile tile, BulletType type, float angle){
type.create(tile.entity, tile.team(), tile.drawx() + tr.x, tile.drawy() + tr.y, angle);
}
protected void effects(Tile tile){
Effect shootEffect = this.shootEffect == Fx.none ? peekAmmo(tile).shootEffect : this.shootEffect;
Effect smokeEffect = this.smokeEffect == Fx.none ? peekAmmo(tile).smokeEffect : this.smokeEffect;
TurretEntity entity = tile.ent();
shootEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
smokeEffect.at(tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
shootSound.at(tile, Mathf.random(0.9f, 1.1f));
if(shootShake > 0){
Effects.shake(shootShake, shootShake, tile.entity);
}
entity.recoil = recoil;
}
protected void ejectEffects(Tile tile){
if(!isTurret(tile)) return;
TurretEntity entity = tile.ent();
ammoUseEffect.at(tile.drawx() - Angles.trnsx(entity.rotation, ammoEjectBack),
tile.drawy() - Angles.trnsy(entity.rotation, ammoEjectBack), entity.rotation);
}
protected float baseReloadSpeed(Tile tile){
return 1f;
}
protected boolean isTurret(Tile tile){
return (tile.entity instanceof TurretEntity);
}
public static abstract class AmmoEntry{
public int amount;
public abstract BulletType type();
}
public static class TurretEntity extends TileEntity{
public class TurretEntity extends TileEntity{
public Array<AmmoEntry> ammo = new Array<>();
public int totalAmmo;
public float reload;
@@ -314,6 +125,171 @@ public abstract class Turret extends Block{
public int shots;
public Posc target;
@Override
public void draw(){
Draw.rect(baseRegion, x, y);
Draw.color();
}
@Override
public void drawLayer(){
tr2.trns(rotation, -recoil);
drawer.get(this);
if(heatRegion != Core.atlas.find("error")){
heatDrawer.get(this);
}
}
@Override
public void updateTile(){
if(!validateTarget()) target = null;
recoil = Mathf.lerpDelta(recoil, 0f, restitution);
heat = Mathf.lerpDelta(heat, 0f, cooldown);
if(hasAmmo()){
if(timer(timerTarget, targetInterval)){
findTarget();
}
if(validateTarget()){
BulletType type = peekAmmo();
float speed = type.speed;
if(speed < 0.1f) speed = 9999999f;
Vec2 result = Predict.intercept(this, target, speed);
if(result.isZero()){
result.set(target.getX(), target.getY());
}
float targetRot = result.sub(x, y).angle();
if(Float.isNaN(rotation)){
rotation = 0;
}
if(shouldTurn()){
turnToTarget(targetRot);
}
if(Angles.angleDist(rotation, targetRot) < shootCone){
updateShooting();
}
}
}
}
@Override
public void drawSelect(){
Drawf.dashCircle(x, y, range, team.color);
}
protected boolean validateTarget(){
return !Units.invalidateTarget(target, team, x, y);
}
protected void findTarget(){
if(targetAir && !targetGround){
target = Units.closestEnemy(team, x, y, range, e -> !e.dead() && !e.isGrounded());
}else{
target = Units.closestTarget(team, x, y, range, e -> !e.dead() && (e.isGrounded() || targetAir) && (!e.isGrounded() || targetGround));
}
}
protected void turnToTarget(float targetRot){
rotation = Angles.moveToward(rotation, targetRot, rotatespeed * delta() * baseReloadSpeed());
}
public boolean shouldTurn(){
return true;
}
/** Consume ammo and return a type. */
public BulletType useAmmo(){
if(tile.isEnemyCheat()) return peekAmmo();
AmmoEntry entry = ammo.peek();
entry.amount -= ammoPerShot;
if(entry.amount == 0) ammo.pop();
totalAmmo -= ammoPerShot;
Time.run(reload / 2f, () -> ejectEffects());
return entry.type();
}
/**
* Get the ammo type that will be returned if useAmmo is called.
*/
public BulletType peekAmmo(){
return ammo.peek().type();
}
/**
* Returns whether the turret has ammo.
*/
public boolean hasAmmo(){
return ammo.size > 0 && ammo.peek().amount >= ammoPerShot;
}
protected void updateShooting(){
if(reload >= reload){
BulletType type = peekAmmo();
shoot(type);
reload = 0f;
}else{
reload += delta() * peekAmmo().reloadMultiplier * baseReloadSpeed();
}
}
protected void shoot(BulletType type){
recoil = recoilAmount;
heat = 1f;
tr.trns(rotation, size * tilesize / 2f, Mathf.range(xRand));
for(int i = 0; i < shots; i++){
bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy) + (i - shots / 2) * spread);
}
effects();
useAmmo();
}
protected void bullet(BulletType type, float angle){
type.create(this, team, x + tr.x, y + tr.y, angle);
}
protected void effects(){
Effect fshootEffect = shootEffect == Fx.none ? peekAmmo().shootEffect : shootEffect;
Effect fsmokeEffect = smokeEffect == Fx.none ? peekAmmo().smokeEffect : smokeEffect;
fshootEffect.at(x + tr.x, y + tr.y, rotation);
fsmokeEffect.at(x + tr.x, y + tr.y, rotation);
shootSound.at(tile, Mathf.random(0.9f, 1.1f));
if(shootShake > 0){
Effects.shake(shootShake, shootShake, this);
}
recoil = recoilAmount;
}
protected void ejectEffects(){
if(!isValid()) return;
ammoUseEffect.at(x - Angles.trnsx(rotation, ammoEjectBack), y - Angles.trnsy(rotation, ammoEjectBack), rotation);
}
protected float baseReloadSpeed(){
return 1f;
}
@Override
public void write(Writes write){
super.write(write);

View File

@@ -1,5 +1,6 @@
package mindustry.world.blocks.distribution;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
@@ -10,12 +11,14 @@ public class ArmoredConveyor extends Conveyor{
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
return super.acceptItem(tile, source, item) && (source.block() instanceof Conveyor || Edges.getFacingEdge(source, tile).relativeTo(tile) == tile.rotation());
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock) {
return otherblock.outputsItems() && blendsArmored(rotation, otherx, othery, otherrot, otherblock);
}
@Override
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock) {
return otherblock.outputsItems() && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock);
public class ArmoredConveyorEntity extends ConveyorEntity{
@Override
public boolean acceptItem(Tilec source, Item item){
return super.acceptItem(source, item) && (source.block() instanceof Conveyor || Edges.getFacingEdge(source.tile(), tile).relativeTo(tile) == tile.rotation());
}
}
}

View File

@@ -2,6 +2,7 @@ package mindustry.world.blocks.distribution;
import arc.math.*;
import arc.util.io.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
@@ -15,30 +16,27 @@ public class BufferedItemBridge extends ExtendingItemBridge{
super(name);
hasPower = false;
hasItems = true;
entityType = BufferedItemBridgeEntity::new;
}
@Override
public void updateTransport(Tile tile, Tile other){
BufferedItemBridgeEntity entity = tile.ent();
if(entity.buffer.accepts() && entity.items().total() > 0){
entity.buffer.accept(entity.items().take());
}
Item item = entity.buffer.poll();
if(entity.timer(timerAccept, 4) && item != null && other.block().acceptItem(other, tile, item)){
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 4f, 0.05f);
other.block().handleItem(other, tile, item);
entity.buffer.remove();
}else{
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 0f, 0.008f);
}
}
class BufferedItemBridgeEntity extends ItemBridgeEntity{
public class BufferedItemBridgeEntity extends ItemBridgeEntity{
ItemBuffer buffer = new ItemBuffer(bufferCapacity, speed);
@Override
public void updateTransport(Tilec other){
if(buffer.accepts() && items.total() > 0){
buffer.accept(items.take());
}
Item item = buffer.poll();
if(timer(timerAccept, 4) && item != null && other.acceptItem(this, item)){
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f);
other.handleItem(this, item);
buffer.remove();
}else{
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 0f, 0.008f);
}
}
@Override
public void write(Writes write){
super.write(write);

View File

@@ -76,8 +76,8 @@ public class Conveyor extends Block implements Autotiler{
}
@Override
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.outputsItems() && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock);
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.outputsItems() && lookingAt(rotation, otherx, othery, otherrot, otherblock);
}
@Override
@@ -125,7 +125,7 @@ public class Conveyor extends Block implements Autotiler{
public void draw(){
byte rotation = tile.rotation();
int frame = clogHeat <= 0.5f ? (int)(((Time.time() * speed * 8f * timeScale())) % 4) : 0;
Draw.rect(regions[Mathf.clamp(blendbits, 0, regions.length - 1)][Mathf.clamp(frame, 0, regions[0].length - 1)], tile.drawx(), tile.drawy(),
Draw.rect(regions[Mathf.clamp(blendbits, 0, regions.length - 1)][Mathf.clamp(frame, 0, regions[0].length - 1)], x, y,
tilesize * blendsclx, tilesize * blendscly, rotation * 90);
}
@@ -138,14 +138,14 @@ public class Conveyor extends Block implements Autotiler{
public void onProximityUpdate(){
super.onProximityUpdate();
int[] bits = buildBlending(tile, rotation(), null, true);
int[] bits = buildBlending(rotation(), null, true);
blendbits = bits[0];
blendsclx = bits[1];
blendscly = bits[2];
if(tile.front() != null && tile.front() != null){
next = tile.front();
nextc = next instanceof ConveyorEntity && next.team() == tile.team() ? (ConveyorEntity)next : null;
nextc = next instanceof ConveyorEntity && next.team() == team ? (ConveyorEntity)next : null;
aligned = nextc != null && tile.rotation() == next.tile().rotation();
}
}

View File

@@ -16,10 +16,8 @@ public class ExtendingItemBridge extends ItemBridge{
}
@Override
public void drawLayer(Tile tile){
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
public void drawLayer(){
Tile other = world.tile(link);
if(!linkValid(tile, other)) return;
int i = tile.absoluteRelativeTo(other.x, other.y);
@@ -27,7 +25,7 @@ public class ExtendingItemBridge extends ItemBridge{
float ex = other.worldx() - tile.worldx() - Geometry.d4[i].x * tilesize / 2f,
ey = other.worldy() - tile.worldy() - Geometry.d4[i].y * tilesize / 2f;
float uptime = state.isEditor() ? 1f : entity.uptime;
float uptime = state.isEditor() ? 1f : uptime;
ex *= uptime;
ey *= uptime;
@@ -43,7 +41,7 @@ public class ExtendingItemBridge extends ItemBridge{
tile.worldx() + ex,
tile.worldy() + ey, CapStyle.none, 0f);
Draw.rect(endRegion, tile.drawx(), tile.drawy(), i * 90 + 90);
Draw.rect(endRegion, x, y, i * 90 + 90);
Draw.rect(endRegion,
tile.worldx() + ex + Geometry.d4[i].x * tilesize / 2f,
tile.worldy() + ey + Geometry.d4[i].y * tilesize / 2f, i * 90 + 270);
@@ -55,7 +53,7 @@ public class ExtendingItemBridge extends ItemBridge{
Draw.color();
for(int a = 0; a < arrows; a++){
Draw.alpha(Mathf.absin(a / (float)arrows - entity.time / 100f, 0.1f, 1f) * uptime * opacity);
Draw.alpha(Mathf.absin(a / (float)arrows - time / 100f, 0.1f, 1f) * uptime * opacity);
Draw.rect(arrowRegion,
tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 6f + 2) * uptime,
tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 6f + 2) * uptime, i * 90f);

View File

@@ -39,12 +39,10 @@ public class ItemBridge extends Block{
hasItems = true;
unloadable = false;
group = BlockGroup.transportation;
entityType = ItemBridgeEntity::new;
//point2 config is relative
config(Point2.class, (tile, i) -> tile.<ItemBridgeEntity>ent().link = Point2.pack(i.x + tile.x, i.y + tile.y));
//point2 config is relative
config(Point2.class, (tile, i) -> ((ItemBridgeEntity)tile).link = Point2.pack(i.x + tile.tileX(), i.y + tile.tileY()));
//integer is not
config(Integer.class, (tile, i) -> tile.<ItemBridgeEntity>ent().link = i);
config(Integer.class, (tile, i) -> ((ItemBridgeEntity)tile).link = i);
}
@Override
@@ -77,23 +75,6 @@ public class ItemBridge extends Block{
Angles.angle(req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy()));
}
@Override
public void playerPlaced(Tile tile){
Tile link = findLink(tile.x, tile.y);
if(linkValid(tile, link)){
link.configure(tile.pos());
}
lastPlaced = tile.pos();
}
public Tile findLink(int x, int y){
if(world.tiles.in(x, y) && linkValid(world.tile(x, y), world.tile(lastPlaced)) && lastPlaced != Point2.pack(x, y)){
return world.tile(lastPlaced);
}
return null;
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Tile link = findLink(x, y);
@@ -122,226 +103,6 @@ public class ItemBridge extends Block{
Draw.reset();
}
@Override
public void drawConfigure(Tile tile){
ItemBridgeEntity entity = tile.ent();
Draw.color(Pal.accent);
Lines.stroke(1f);
Lines.square(tile.drawx(), tile.drawy(),
tile.block().size * tilesize / 2f + 1f);
for(int i = 1; i <= range; i++){
for(int j = 0; j < 4; j++){
Tile other = tile.getNearby(Geometry.d4[j].x * i, Geometry.d4[j].y * i);
if(linkValid(tile, other)){
boolean linked = other.pos() == entity.link;
Draw.color(linked ? Pal.place : Pal.breakInvalid);
Lines.square(other.drawx(), other.drawy(),
other.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Time.time(), 4f, 1f)));
}
}
}
Draw.reset();
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
ItemBridgeEntity entity = tile.ent();
if(linkValid(tile, other)){
if(entity.link == other.pos()){
tile.configure(-1);
}else{
tile.configure(other.pos());
}
return false;
}
return true;
}
@Override
public void updateTile(){
ItemBridgeEntity entity = tile.ent();
entity.time += entity.cycleSpeed * entity.delta();
entity.time2 += (entity.cycleSpeed - 1f) * entity.delta();
IntSetIterator it = entity.incoming.iterator();
while(it.hasNext){
int i = it.next();
Tile other = world.tile(i);
if(!linkValid(tile, other, false) || other.<ItemBridgeEntity>ent().link != tile.pos()){
it.remove();
}
}
Tile other = world.tile(entity.link);
if(!linkValid(tile, other)){
tryDump(tile);
entity.uptime = 0f;
}else{
((ItemBridgeEntity)world.tile(entity.link).entity).incoming.add(tile.pos());
if(entity.consValid() && Mathf.zero(1f - entity.efficiency())){
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f);
}else{
entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f);
}
updateTransport(tile, other);
}
}
public void updateTransport(Tile tile, Tile other){
ItemBridgeEntity entity = tile.ent();
if(entity.uptime >= 0.5f && entity.timer(timerTransport, transportTime)){
Item item = entity.items().take();
if(item != null && other.block().acceptItem(other, tile, item)){
other.block().handleItem(other, tile, item);
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 4f, 0.05f);
}else{
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 1f, 0.01f);
if(item != null) entity.items().add(item, 1);
}
}
}
@Override
public void drawLayer(Tile tile){
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
if(!linkValid(tile, other)) return;
float opacity = Core.settings.getInt("bridgeopacity") / 100f;
if(Mathf.zero(opacity)) return;
int i = tile.absoluteRelativeTo(other.x, other.y);
Draw.color(Color.white, Color.black, Mathf.absin(Time.time(), 6f, 0.07f));
Draw.alpha(Math.max(entity.uptime, 0.25f) * opacity);
Draw.rect(endRegion, tile.drawx(), tile.drawy(), i * 90 + 90);
Draw.rect(endRegion, other.drawx(), other.drawy(), i * 90 + 270);
Lines.stroke(8f);
Lines.line(bridgeRegion,
tile.worldx(),
tile.worldy(),
other.worldx(),
other.worldy(), CapStyle.none, -tilesize / 2f);
int dist = Math.max(Math.abs(other.x - tile.x), Math.abs(other.y - tile.y));
float time = entity.time2 / 1.7f;
int arrows = (dist) * tilesize / 4 - 2;
Draw.color();
for(int a = 0; a < arrows; a++){
Draw.alpha(Mathf.absin(a / (float)arrows - entity.time / 100f, 0.1f, 1f) * entity.uptime * opacity);
Draw.rect(arrowRegion,
tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 4f + time % 4f),
tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 4f + time % 4f), i * 90f);
}
Draw.reset();
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
if(tile.team() != source.team()) return false;
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
if(linkValid(tile, other)){
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(source.x, source.y);
if(rel == rel2) return false;
}else{
return source.block() instanceof ItemBridge && source.<ItemBridgeEntity>ent().link == tile.pos() && tile.entity.items().total() < itemCapacity;
}
return tile.entity.items().total() < itemCapacity;
}
@Override
public boolean canDumpLiquid(Tile tile, Tile to, Liquid liquid){
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
if(!linkValid(tile, other)){
Tile edge = Edges.getFacingEdge(to, tile);
int i = tile.absoluteRelativeTo(edge.x, edge.y);
IntSetIterator it = entity.incoming.iterator();
while(it.hasNext){
int v = it.next();
if(tile.absoluteRelativeTo(Point2.x(v), Point2.y(v)) == i){
return false;
}
}
return true;
}
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(to.x, to.y);
return rel != rel2;
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
if(tile.team() != source.team() || !hasLiquids) return false;
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
if(linkValid(tile, other)){
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(source.x, source.y);
if(rel == rel2) return false;
}else if(!(source.block() instanceof ItemBridge && source.<ItemBridgeEntity>ent().link == tile.pos())){
return false;
}
return tile.entity.liquids().get(liquid) + amount < liquidCapacity && (tile.entity.liquids().current() == liquid || tile.entity.liquids().get(tile.entity.liquids().current()) < 0.2f);
}
@Override
public boolean canDump(Tile tile, Tile to, Item item){
ItemBridgeEntity entity = tile.ent();
Tile other = world.tile(entity.link);
if(!linkValid(tile, other)){
Tile edge = Edges.getFacingEdge(to, tile);
int i = tile.absoluteRelativeTo(edge.x, edge.y);
IntSetIterator it = entity.incoming.iterator();
while(it.hasNext){
int v = it.next();
if(tile.absoluteRelativeTo(Point2.x(v), Point2.y(v)) == i){
return false;
}
}
return true;
}
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(to.x, to.y);
return rel != rel2;
}
public boolean linkValid(Tile tile, Tile other){
return linkValid(tile, other, true);
}
@@ -359,7 +120,14 @@ public class ItemBridge extends Block{
return other.block() == this && (!checkDouble || other.<ItemBridgeEntity>ent().link != tile.pos());
}
public static class ItemBridgeEntity extends TileEntity{
public Tile findLink(int x, int y){
if(world.tiles.in(x, y) && linkValid(world.tile(x, y), world.tile(lastPlaced)) && lastPlaced != Point2.pack(x, y)){
return world.tile(lastPlaced);
}
return null;
}
public class ItemBridgeEntity extends TileEntity{
public int link = -1;
public IntSet incoming = new IntSet();
public float uptime;
@@ -367,6 +135,220 @@ public class ItemBridge extends Block{
public float time2;
public float cycleSpeed = 1f;
@Override
public void playerPlaced(){
Tile link = findLink(tile.x, tile.y);
if(linkValid(tile, link)){
link.configure(tile.pos());
}
lastPlaced = tile.pos();
}
@Override
public void drawConfigure(){
Draw.color(Pal.accent);
Lines.stroke(1f);
Lines.square(x, y,
tile.block().size * tilesize / 2f + 1f);
for(int i = 1; i <= range; i++){
for(int j = 0; j < 4; j++){
Tile other = tile.getNearby(Geometry.d4[j].x * i, Geometry.d4[j].y * i);
if(linkValid(tile, other)){
boolean linked = other.pos() == link;
Draw.color(linked ? Pal.place : Pal.breakInvalid);
Lines.square(other.drawx(), other.drawy(),
other.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Time.time(), 4f, 1f)));
}
}
}
Draw.reset();
}
@Override
public boolean onConfigureTileTapped(Tilec other){
if(linkValid(tile, other)){
if(link == other.pos()){
tile.configure(-1);
}else{
tile.configure(other.pos());
}
return false;
}
return true;
}
@Override
public void updateTile(){
time += cycleSpeed * delta();
time2 += (cycleSpeed - 1f) * delta();
IntSetIterator it = incoming.iterator();
while(it.hasNext){
int i = it.next();
Tile other = world.tile(i);
if(!linkValid(tile, other, false) || other.<ItemBridgeEntity>ent().link != tile.pos()){
it.remove();
}
}
Tilec other = world.tile(link);
if(!linkValid(tile, other)){
dump(tile);
uptime = 0f;
}else{
((ItemBridgeEntity)world.tile(link).entity).incoming.add(tile.pos());
if(consValid() && Mathf.zero(1f - efficiency())){
uptime = Mathf.lerpDelta(uptime, 1f, 0.04f);
}else{
uptime = Mathf.lerpDelta(uptime, 0f, 0.02f);
}
updateTransport(other);
}
}
public void updateTransport(Tilec other){
if(uptime >= 0.5f && timer(timerTransport, transportTime)){
Item item = items.take();
if(item != null && other.acceptItem(this, item)){
other.handleItem(this, item);
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f);
}else{
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f);
if(item != null) items.add(item, 1);
}
}
}
@Override
public void drawLayer(){
Tile other = world.tile(link);
if(!linkValid(tile, other)) return;
float opacity = Core.settings.getInt("bridgeopacity") / 100f;
if(Mathf.zero(opacity)) return;
int i = tile.absoluteRelativeTo(other.x, other.y);
Draw.color(Color.white, Color.black, Mathf.absin(Time.time(), 6f, 0.07f));
Draw.alpha(Math.max(uptime, 0.25f) * opacity);
Draw.rect(endRegion, x, y, i * 90 + 90);
Draw.rect(endRegion, other.drawx(), other.drawy(), i * 90 + 270);
Lines.stroke(8f);
Lines.line(bridgeRegion,
tile.worldx(),
tile.worldy(),
other.worldx(),
other.worldy(), CapStyle.none, -tilesize / 2f);
int dist = Math.max(Math.abs(other.x - tile.x), Math.abs(other.y - tile.y));
float time = time2 / 1.7f;
int arrows = (dist) * tilesize / 4 - 2;
Draw.color();
for(int a = 0; a < arrows; a++){
Draw.alpha(Mathf.absin(a / (float)arrows - time / 100f, 0.1f, 1f) * uptime * opacity);
Draw.rect(arrowRegion,
tile.worldx() + Geometry.d4[i].x * (tilesize / 2f + a * 4f + time % 4f),
tile.worldy() + Geometry.d4[i].y * (tilesize / 2f + a * 4f + time % 4f), i * 90f);
}
Draw.reset();
}
@Override
public boolean acceptItem(Tilec source, Item item){
if(team != source.team()) return false;
Tile other = world.tile(link);
if(linkValid(tile, other)){
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(source.tileX(), source.tileY());
if(rel == rel2) return false;
}else{
return source.block() instanceof ItemBridge && source.<ItemBridgeEntity>ent().link == tile.pos() && items.total() < itemCapacity;
}
return items.total() < itemCapacity;
}
@Override
public boolean canDumpLiquid(Tilec to, Liquid liquid){
Tile other = world.tile(link);
if(!linkValid(tile, other)){
Tile edge = Edges.getFacingEdge(to.tile(), tile);
int i = tile.absoluteRelativeTo(edge.x, edge.y);
IntSetIterator it = incoming.iterator();
while(it.hasNext){
int v = it.next();
if(tile.absoluteRelativeTo(Point2.x(v), Point2.y(v)) == i){
return false;
}
}
return true;
}
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(to.tileX(), to.tileY());
return rel != rel2;
}
@Override
public boolean acceptLiquid(Tilec source, Liquid liquid, float amount){
if(team != source.team() || !hasLiquids) return false;
Tile other = world.tile(link);
if(linkValid(tile, other)){
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(source.tileX(), source.tileY());
if(rel == rel2) return false;
}else if(!(source.block() instanceof ItemBridge && source.<ItemBridgeEntity>ent().link == tile.pos())){
return false;
}
return liquids.get(liquid) + amount < liquidCapacity && (liquids.current() == liquid || liquids.get(liquids.current()) < 0.2f);
}
@Override
public boolean canDump(Tilec to, Item item){
Tile other = world.tile(link);
if(!linkValid(tile, other)){
Tile edge = Edges.getFacingEdge(to, tile);
int i = tile.absoluteRelativeTo(edge.x, edge.y);
IntSetIterator it = incoming.iterator();
while(it.hasNext){
int v = it.next();
if(tile.absoluteRelativeTo(Point2.x(v), Point2.y(v)) == i){
return false;
}
}
return true;
}
int rel = tile.absoluteRelativeTo(other.x, other.y);
int rel2 = tile.relativeTo(to.tileX(), to.tileY());
return rel != rel2;
}
@Override
public Point2 config(){
return Point2.unpack(link).sub(tile.x, tile.y);

View File

@@ -22,12 +22,6 @@ public class Junction extends Block{
solid = true;
group = BlockGroup.transportation;
unloadable = false;
entityType = JunctionEntity::new;
}
@Override
public int acceptStack(Tile tile, Item item, int amount, Teamc source){
return 0;
}
@Override
@@ -35,55 +29,56 @@ public class Junction extends Block{
return true;
}
@Override
public void updateTile(){
JunctionEntity entity = tile.ent();
DirectionalItemBuffer buffer = entity.buffer;
public class JunctionEntity extends TileEntity{
DirectionalItemBuffer buffer = new DirectionalItemBuffer(capacity, speed);
for(int i = 0; i < 4; i++){
if(buffer.indexes[i] > 0){
if(buffer.indexes[i] > capacity) buffer.indexes[i] = capacity;
long l = buffer.buffers[i][0];
float time = BufferItem.time(l);
@Override
public int acceptStack(Item item, int amount, Teamc source){
return 0;
}
if(Time.time() >= time + speed || Time.time() < time){
@Override
public void updateTile(){
Item item = content.item(BufferItem.item(l));
Tile dest = tile.getNearby(i);
if(dest != null) dest = dest.link();
for(int i = 0; i < 4; i++){
if(buffer.indexes[i] > 0){
if(buffer.indexes[i] > capacity) buffer.indexes[i] = capacity;
long l = buffer.buffers[i][0];
float time = BufferItem.time(l);
//skip blocks that don't want the item, keep waiting until they do
if(dest == null || !dest.block().acceptItem(dest, tile, item) || dest.team() != tile.team()){
continue;
if(Time.time() >= time + speed || Time.time() < time){
Item item = content.item(BufferItem.item(l));
Tile dest = tile.getNearby(i);
if(dest != null) dest = dest.link();
//skip blocks that don't want the item, keep waiting until they do
if(dest == null || !dest.block().acceptItem(dest, tile, item) || dest.team() != team){
continue;
}
dest.block().handleItem(dest, tile, item);
System.arraycopy(buffer.buffers[i], 1, buffer.buffers[i], 0, buffer.indexes[i] - 1);
buffer.indexes[i] --;
}
dest.block().handleItem(dest, tile, item);
System.arraycopy(buffer.buffers[i], 1, buffer.buffers[i], 0, buffer.indexes[i] - 1);
buffer.indexes[i] --;
}
}
}
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
JunctionEntity entity = tile.ent();
int relative = source.relativeTo(tile.x, tile.y);
entity.buffer.accept(relative, item);
}
@Override
public void handleItem(Tile source, Item item){
int relative = source.relativeTo(tile.x, tile.y);
buffer.accept(relative, item);
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
JunctionEntity entity = tile.ent();
int relative = source.relativeTo(tile.x, tile.y);
@Override
public boolean acceptItem(Tile source, Item item){
int relative = source.relativeTo(tile.x, tile.y);
if(entity == null || relative == -1 || !entity.buffer.accepts(relative)) return false;
Tile to = tile.getNearby(relative);
return to != null && to.link().entity != null && to.team() == tile.team();
}
class JunctionEntity extends TileEntity{
DirectionalItemBuffer buffer = new DirectionalItemBuffer(capacity, speed);
if(relative == -1 || !buffer.accepts(relative)) return false;
Tile to = tile.getNearby(relative);
return to != null && to.link().entity != null && to.team() == team;
}
@Override
public void write(Writes write){

View File

@@ -40,9 +40,7 @@ public class MassDriver extends Block{
layer = Layer.turret;
hasPower = true;
outlineIcon = true;
entityType = MassDriverEntity::new;
//point2 is relative
//point2 is relative
config(Point2.class, (tile, point) -> tile.<MassDriverEntity>ent().link = Point2.pack(point.x + tile.x, point.y + tile.y));
config(Integer.class, (tile, point) -> tile.<MassDriverEntity>ent().link = point);
}
@@ -61,80 +59,79 @@ public class MassDriver extends Block{
@Override
public void updateTile(){
MassDriverEntity entity = tile.ent();
Tile link = world.tile(entity.link);
Tile link = world.tile(link);
boolean hasLink = linkValid(tile);
//reload regardless of state
if(entity.reload > 0f){
entity.reload = Mathf.clamp(entity.reload - entity.delta() / reloadTime * entity.efficiency());
if(reload > 0f){
reload = Mathf.clamp(reload - delta() / reloadTime * efficiency());
}
//cleanup waiting shooters that are not valid
if(!shooterValid(tile, entity.currentShooter())){
entity.waitingShooters.remove(entity.currentShooter());
if(!shooterValid(tile, currentShooter())){
waitingShooters.remove(currentShooter());
}
//switch states
if(entity.state == DriverState.idle){
if(state == DriverState.idle){
//start accepting when idle and there's space
if(!entity.waitingShooters.isEmpty() && (itemCapacity - entity.items().total() >= minDistribute)){
entity.state = DriverState.accepting;
if(!waitingShooters.isEmpty() && (itemCapacity - items.total() >= minDistribute)){
state = DriverState.accepting;
}else if(hasLink){ //switch to shooting if there's a valid link.
entity.state = DriverState.shooting;
state = DriverState.shooting;
}
}
//dump when idle or accepting
if(entity.state == DriverState.idle || entity.state == DriverState.accepting){
if(state == DriverState.idle || state == DriverState.accepting){
tryDump(tile);
}
//skip when there's no power
if(!entity.consValid()){
if(!consValid()){
return;
}
if(entity.state == DriverState.accepting){
if(state == DriverState.accepting){
//if there's nothing shooting at this, bail - OR, items full
if(entity.currentShooter() == null || (itemCapacity - entity.items().total() < minDistribute)){
entity.state = DriverState.idle;
if(currentShooter() == null || (itemCapacity - items.total() < minDistribute)){
state = DriverState.idle;
return;
}
//align to shooter rotation
entity.rotation = Mathf.slerpDelta(entity.rotation, tile.angleTo(entity.currentShooter()), rotateSpeed * entity.efficiency());
}else if(entity.state == DriverState.shooting){
rotation = Mathf.slerpDelta(rotation, tile.angleTo(currentShooter()), rotateSpeed * efficiency());
}else if(state == DriverState.shooting){
//if there's nothing to shoot at OR someone wants to shoot at this thing, bail
if(!hasLink || (!entity.waitingShooters.isEmpty() && (itemCapacity - entity.items().total() >= minDistribute))){
entity.state = DriverState.idle;
if(!hasLink || (!waitingShooters.isEmpty() && (itemCapacity - items.total() >= minDistribute))){
state = DriverState.idle;
return;
}
float targetRotation = tile.angleTo(link);
if(
tile.entity.items().total() >= minDistribute && //must shoot minimum amount of items
link.block().itemCapacity - link.entity.items().total() >= minDistribute //must have minimum amount of space
tile.items.total() >= minDistribute && //must shoot minimum amount of items
link.block().itemCapacity - link.items.total() >= minDistribute //must have minimum amount of space
){
MassDriverEntity other = link.ent();
other.waitingShooters.add(tile);
if(entity.reload <= 0.0001f){
if(reload <= 0.0001f){
//align to target location
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRotation, rotateSpeed * entity.efficiency());
rotation = Mathf.slerpDelta(rotation, targetRotation, rotateSpeed * efficiency());
//fire when it's the first in the queue and angles are ready.
if(other.currentShooter() == tile &&
other.state == DriverState.accepting &&
Angles.near(entity.rotation, targetRotation, 2f) && Angles.near(other.rotation, targetRotation + 180f, 2f)){
Angles.near(rotation, targetRotation, 2f) && Angles.near(other.rotation, targetRotation + 180f, 2f)){
//actually fire
fire(tile, link);
//remove waiting shooters, it's done firing
other.waitingShooters.remove(tile);
//set both states to idle
entity.state = DriverState.idle;
state = DriverState.idle;
other.state = DriverState.idle;
}
}
@@ -144,16 +141,14 @@ public class MassDriver extends Block{
@Override
public void draw(){
Draw.rect(baseRegion, tile.drawx(), tile.drawy());
Draw.rect(baseRegion, x, y);
}
@Override
public void drawLayer(Tile tile){
MassDriverEntity entity = tile.ent();
public void drawLayer(){
Draw.rect(region,
tile.drawx() + Angles.trnsx(entity.rotation + 180f, entity.reload * knockback),
tile.drawy() + Angles.trnsy(entity.rotation + 180f, entity.reload * knockback), entity.rotation - 90);
x + Angles.trnsx(rotation + 180f, reload * knockback),
y + Angles.trnsy(rotation + 180f, reload * knockback), rotation - 90);
}
@Override
@@ -180,39 +175,35 @@ public class MassDriver extends Block{
}
@Override
public void drawConfigure(Tile tile){
public void drawConfigure(){
float sin = Mathf.absin(Time.time(), 6f, 1f);
Draw.color(Pal.accent);
Lines.stroke(1f);
Drawf.circles(tile.drawx(), tile.drawy(), (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent);
Drawf.circles(x, y, (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent);
MassDriverEntity entity = tile.ent();
for(Tile shooter : entity.waitingShooters){
for(Tile shooter : waitingShooters){
Drawf.circles(shooter.drawx(), shooter.drawy(), (tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place);
Drawf.arrow(shooter.drawx(), shooter.drawy(), tile.drawx(), tile.drawy(), size * tilesize + sin, 4f + sin, Pal.place);
Drawf.arrow(shooter.drawx(), shooter.drawy(), x, y, size * tilesize + sin, 4f + sin, Pal.place);
}
if(linkValid(tile)){
Tile target = world.tile(entity.link);
Tile target = world.tile(link);
Drawf.circles(target.drawx(), target.drawy(), (target.block().size / 2f + 1) * tilesize + sin - 2f, Pal.place);
Drawf.arrow(tile.drawx(), tile.drawy(), target.drawx(), target.drawy(), size * tilesize + sin, 4f + sin);
Drawf.arrow(x, y, target.drawx(), target.drawy(), size * tilesize + sin, 4f + sin);
}
Drawf.dashCircle(tile.drawx(), tile.drawy(), range, Pal.accent);
Drawf.dashCircle(x, y, range, Pal.accent);
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
public boolean onConfigureTileTapped(Tile other){
if(tile == other) return false;
MassDriverEntity entity = tile.ent();
if(entity.link == other.pos()){
if(link == other.pos()){
tile.configure(-1);
return false;
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.team() == tile.team()){
}else if(other.block() instanceof MassDriver && other.dst(tile) <= range && other.team() == team){
tile.configure(other.pos());
return false;
}
@@ -221,51 +212,50 @@ public class MassDriver extends Block{
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
public boolean acceptItem(Tile source, Item item){
//mass drivers that ouput only cannot accept items
return tile.entity.items().total() < itemCapacity && linkValid(tile);
return tile.items.total() < itemCapacity && linkValid(tile);
}
protected void fire(Tile tile, Tile target){
MassDriverEntity entity = tile.ent();
protected void fire(Tile target){
MassDriverEntity other = target.ent();
//reset reload, use power.
entity.reload = 1f;
reload = 1f;
DriverBulletData data = Pools.obtain(DriverBulletData.class, DriverBulletData::new);
data.from = entity;
data.to = other;
int totalUsed = 0;
for(int i = 0; i < content.items().size; i++){
int maxTransfer = Math.min(entity.items().get(content.item(i)), ((MassDriver)tile.block()).itemCapacity - totalUsed);
int maxTransfer = Math.min(items.get(content.item(i)), ((MassDriver)tile.block()).itemCapacity - totalUsed);
data.items[i] = maxTransfer;
totalUsed += maxTransfer;
entity.items().remove(content.item(i), maxTransfer);
items.remove(content.item(i), maxTransfer);
}
float angle = tile.angleTo(target);
Bullets.driverBolt.create(entity, entity.team(),
tile.drawx() + Angles.trnsx(angle, translation), tile.drawy() + Angles.trnsy(angle, translation),
Bullets.driverBolt.create(entity, team(),
x + Angles.trnsx(angle, translation), y + Angles.trnsy(angle, translation),
angle, -1f, 1f, 1f, data);
shootEffect.at(tile.drawx() + Angles.trnsx(angle, translation),
tile.drawy() + Angles.trnsy(angle, translation), angle);
shootEffect.at(x + Angles.trnsx(angle, translation),
y + Angles.trnsy(angle, translation), angle);
smokeEffect.at(tile.drawx() + Angles.trnsx(angle, translation),
tile.drawy() + Angles.trnsy(angle, translation), angle);
smokeEffect.at(x + Angles.trnsx(angle, translation),
y + Angles.trnsy(angle, translation), angle);
Effects.shake(shake, shake, entity);
}
protected void handlePayload(MassDriverEntity entity, Bulletc bullet, DriverBulletData data){
int totalItems = entity.items().total();
int totalItems = items.total();
//add all the items possible
for(int i = 0; i < data.items.length; i++){
int maxAdd = Math.min(data.items[i], itemCapacity * 2 - totalItems);
entity.items().add(content.item(i), maxAdd);
items.add(content.item(i), maxAdd);
data.items[i] -= maxAdd;
totalItems += maxAdd;
@@ -277,28 +267,27 @@ public class MassDriver extends Block{
Effects.shake(shake, shake, entity);
recieveEffect.at(bullet);
entity.reload = 1f;
reload = 1f;
bullet.remove();
}
protected boolean shooterValid(Tile tile, Tile other){
protected boolean shooterValid(Tile other){
if(other == null) return true;
if(!(other.block() instanceof MassDriver)) return false;
MassDriverEntity entity = other.ent();
return entity.link == tile.pos() && tile.dst(other) <= range;
return link == tile.pos() && tile.dst(other) <= range;
}
protected boolean linkValid(Tile tile){
protected boolean linkValid(){
if(tile == null) return false;
MassDriverEntity entity = tile.ent();
if(entity == null || entity.link == -1) return false;
Tile link = world.tile(entity.link);
if(entity == null || link == -1) return false;
Tile link = world.tile(link);
return link != null && link.block() instanceof MassDriver && link.team() == tile.team() && tile.dst(link) <= range;
return link != null && link.block() instanceof MassDriver && link.team() == team && tile.dst(link) <= range;
}
public static class DriverBulletData implements Poolable{
public class DriverBulletData implements Poolable{
public MassDriverEntity from, to;
public int[] items = new int[content.items().size];

View File

@@ -21,7 +21,6 @@ public class OverflowGate extends Block{
update = true;
group = BlockGroup.transportation;
unloadable = false;
entityType = OverflowGateEntity::new;
}
@Override
@@ -30,77 +29,71 @@ public class OverflowGate extends Block{
}
@Override
public int acceptStack(Tile tile, Item item, int amount, Teamc source){
public int acceptStack(Item item, int amount, Teamc source){
return 0;
}
@Override
public int removeStack(Tile tile, Item item, int amount){
OverflowGateEntity entity = tile.ent();
public int removeStack(Item item, int amount){
int result = super.removeStack(tile, item, amount);
if(result != 0 && item == entity.lastItem){
entity.lastItem = null;
if(result != 0 && item == lastItem){
lastItem = null;
}
return result;
}
@Override
public void updateTile(){
OverflowGateEntity entity = tile.ent();
if(entity.lastItem == null && entity.items().total() > 0){
entity.items().clear();
if(lastItem == null && items.total() > 0){
items.clear();
}
if(entity.lastItem != null){
if(entity.lastInput == null){
entity.lastItem = null;
if(lastItem != null){
if(lastInput == null){
lastItem = null;
return;
}
entity.time += 1f / speed * Time.delta();
Tile target = getTileTarget(tile, entity.lastItem, entity.lastInput, false);
time += 1f / speed * Time.delta();
Tile target = getTileTarget(tile, lastItem, lastInput, false);
if(target != null && (entity.time >= 1f)){
getTileTarget(tile, entity.lastItem, entity.lastInput, true);
target.block().handleItem(target, Edges.getFacingEdge(tile, target), entity.lastItem);
entity.items().remove(entity.lastItem, 1);
entity.lastItem = null;
if(target != null && (time >= 1f)){
getTileTarget(tile, lastItem, lastInput, true);
target.block().handleItem(target, Edges.getFacingEdge(tile, target), lastItem);
items.remove(lastItem, 1);
lastItem = null;
}
}
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
OverflowGateEntity entity = tile.ent();
return tile.team() == source.team() && entity.lastItem == null && entity.items().total() == 0;
public boolean acceptItem(Tile source, Item item){
return team == source.team() && lastItem == null && items.total() == 0;
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
OverflowGateEntity entity = tile.ent();
entity.items().add(item, 1);
entity.lastItem = item;
entity.time = 0f;
entity.lastInput = source;
public void handleItem(Tile source, Item item){
items.add(item, 1);
lastItem = item;
time = 0f;
lastInput = source;
update(tile);
}
public Tile getTileTarget(Tile tile, Item item, Tile src, boolean flip){
public Tile getTileTarget(Item item, Tile src, boolean flip){
int from = tile.relativeTo(src.x, src.y);
if(from == -1) return null;
Tile to = tile.getNearby((from + 2) % 4);
if(to == null) return null;
Tile edge = Edges.getFacingEdge(tile, to);
boolean canForward = to.block().acceptItem(to, edge, item) && to.team() == tile.team() && !(to.block() instanceof OverflowGate);
boolean canForward = to.block().acceptItem(to, edge, item) && to.team() == team && !(to.block() instanceof OverflowGate);
if(!canForward || invert){
Tile a = tile.getNearby(Mathf.mod(from - 1, 4));
Tile b = tile.getNearby(Mathf.mod(from + 1, 4));
boolean ac = a != null && a.block().acceptItem(a, edge, item) && !(a.block() instanceof OverflowGate) && a.team() == tile.team();
boolean bc = b != null && b.block().acceptItem(b, edge, item) && !(b.block() instanceof OverflowGate) && b.team() == tile.team();
boolean ac = a != null && a.block().acceptItem(a, edge, item) && !(a.block() instanceof OverflowGate) && a.team() == team;
boolean bc = b != null && b.block().acceptItem(b, edge, item) && !(b.block() instanceof OverflowGate) && b.team() == team;
if(!ac && !bc){
return invert && canForward ? to : null;

View File

@@ -19,48 +19,42 @@ public class Router extends Block{
itemCapacity = 1;
group = BlockGroup.transportation;
unloadable = false;
entityType = RouterEntity::new;
}
@Override
public void updateTile(){
RouterEntity entity = tile.ent();
if(entity.lastItem == null && entity.items().total() > 0){
entity.items().clear();
if(lastItem == null && items.total() > 0){
items.clear();
}
if(entity.lastItem != null){
entity.time += 1f / speed * Time.delta();
Tile target = getTileTarget(tile, entity.lastItem, entity.lastInput, false);
if(lastItem != null){
time += 1f / speed * Time.delta();
Tile target = getTileTarget(tile, lastItem, lastInput, false);
if(target != null && (entity.time >= 1f || !(target.block() instanceof Router))){
getTileTarget(tile, entity.lastItem, entity.lastInput, true);
target.block().handleItem(target, Edges.getFacingEdge(tile, target), entity.lastItem);
entity.items().remove(entity.lastItem, 1);
entity.lastItem = null;
if(target != null && (time >= 1f || !(target.block() instanceof Router))){
getTileTarget(tile, lastItem, lastInput, true);
target.block().handleItem(target, Edges.getFacingEdge(tile, target), lastItem);
items.remove(lastItem, 1);
lastItem = null;
}
}
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
RouterEntity entity = tile.ent();
return tile.team() == source.team() && entity.lastItem == null && entity.items().total() == 0;
public boolean acceptItem(Tile source, Item item){
return team == source.team() && lastItem == null && items.total() == 0;
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
RouterEntity entity = tile.ent();
entity.items().add(item, 1);
entity.lastItem = item;
entity.time = 0f;
entity.lastInput = source;
public void handleItem(Tile source, Item item){
items.add(item, 1);
lastItem = item;
time = 0f;
lastInput = source;
}
Tile getTileTarget(Tile tile, Item item, Tile from, boolean set){
Array<Tile> proximity = tile.entity.proximity();
Tile getTileTarget(Item item, Tile from, boolean set){
Array<Tile> proximity = tile.proximity();
int counter = tile.rotation();
for(int i = 0; i < proximity.size; i++){
Tile other = proximity.get((i + counter) % proximity.size);
@@ -74,11 +68,10 @@ public class Router extends Block{
}
@Override
public int removeStack(Tile tile, Item item, int amount){
RouterEntity entity = tile.ent();
public int removeStack(Item item, int amount){
int result = super.removeStack(tile, item, amount);
if(result != 0 && item == entity.lastItem){
entity.lastItem = null;
if(result != 0 && item == lastItem){
lastItem = null;
}
return result;
}

View File

@@ -27,9 +27,7 @@ public class Sorter extends Block{
group = BlockGroup.transportation;
configurable = true;
unloadable = false;
entityType = SorterEntity::new;
config(Item.class, (tile, item) -> tile.<SorterEntity>ent().sortItem = item);
config(Item.class, (tile, item) -> tile.<SorterEntity>ent().sortItem = item);
configClear(tile -> tile.<SorterEntity>ent().sortItem = null);
}
@@ -39,14 +37,14 @@ public class Sorter extends Block{
}
@Override
public void playerPlaced(Tile tile){
public void playerPlaced(){
if(lastItem != null){
tile.configure(lastItem);
}
}
@Override
public void configured(Tile tile, Playerc player, Object value){
public void configured(Playerc player, Object value){
super.configured(tile, player, value);
if(!headless){
@@ -61,36 +59,35 @@ public class Sorter extends Block{
@Override
public void draw(){
super.draw(tile);
super.draw();
SorterEntity entity = tile.ent();
if(entity.sortItem == null) return;
if(sortItem == null) return;
Draw.color(entity.sortItem.color);
Draw.color(sortItem.color);
Draw.rect("center", tile.worldx(), tile.worldy());
Draw.color();
}
@Override
public int minimapColor(Tile tile){
public int minimapColor(){
return tile.<SorterEntity>ent().sortItem == null ? 0 : tile.<SorterEntity>ent().sortItem.color.rgba();
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
public boolean acceptItem(Tile source, Item item){
Tile to = getTileTarget(item, tile, source, false);
return to != null && to.block().acceptItem(to, tile, item) && to.team() == tile.team();
return to != null && to.block().acceptItem(to, tile, item) && to.team() == team;
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
public void handleItem(Tile source, Item item){
Tile to = getTileTarget(item, tile, source, true);
to.block().handleItem(to, tile, item);
}
boolean isSame(Tile tile, Tile other){
boolean isSame(Tile other){
//uncomment comment below to prevent sorter/gate chaining (hacky)
return other != null && (other.block() instanceof Sorter/* || other.block() instanceof OverflowGate */);
}
@@ -102,7 +99,7 @@ public class Sorter extends Block{
if(dir == -1) return null;
Tile to;
if((item == entity.sortItem) != invert){
if((item == sortItem) != invert){
//prevent 3-chains
if(isSame(dest, source) && isSame(dest, dest.getNearby(dir))){
return null;
@@ -137,9 +134,8 @@ public class Sorter extends Block{
}
@Override
public void buildConfiguration(Tile tile, Table table){
SorterEntity entity = tile.ent();
ItemSelection.buildTable(table, content.items(), () -> entity.sortItem, item -> tile.configure(lastItem = item));
public void buildConfiguration(Table table){
ItemSelection.buildTable(table, content.items(), () -> sortItem, item -> tile.configure(lastItem = item));
}
public class SorterEntity extends TileEntity{

View File

@@ -17,7 +17,7 @@ public class Cliff extends Block{
}
@Override
public void drawBase(Tile tile){
public void drawBase(){
int r = tile.rotation();
for(int i = 0; i < 8; i++){
if((r & (1 << i)) != 0){
@@ -30,7 +30,7 @@ public class Cliff extends Block{
}
@Override
public int minimapColor(Tile tile){
public int minimapColor(){
return Tmp.c1.set(tile.floor().mapColor).mul(1.2f).rgba();
}
}

View File

@@ -153,7 +153,7 @@ public class Floor extends Block{
}
@Override
public void drawBase(Tile tile){
public void drawBase(){
Mathf.random.setSeed(tile.pos());
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
@@ -170,17 +170,17 @@ public class Floor extends Block{
return drownTime > 0;
}
public void drawNonLayer(Tile tile){
public void drawNonLayer(){
Mathf.random.setSeed(tile.pos());
drawEdges(tile, true);
}
protected void drawEdges(Tile tile){
protected void drawEdges(){
drawEdges(tile, false);
}
protected void drawEdges(Tile tile, boolean sameLayer){
protected void drawEdges(boolean sameLayer){
blenders.clear();
blended.clear();
eq = 0;
@@ -216,7 +216,7 @@ public class Floor extends Block{
}
//'new' style of edges with shadows instead of colors, not used currently
protected void drawEdgesFlat(Tile tile, boolean sameLayer){
protected void drawEdgesFlat(boolean sameLayer){
for(int i = 0; i < 4; i++){
Tile other = tile.getNearby(i);
if(other != null && doEdge(other.floor(), sameLayer)){

View File

@@ -79,7 +79,7 @@ public class OreBlock extends OverlayFloor{
}
@Override
public String getDisplayName(Tile tile){
public String getDisplayName(){
return itemDrop.localizedName;
}
}

View File

@@ -12,7 +12,7 @@ public class OverlayFloor extends Floor{
}
@Override
public void drawBase(Tile tile){
public void drawBase(){
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
}
}

View File

@@ -13,7 +13,7 @@ public class StaticTree extends StaticWall{
}
@Override
public void drawBase(Tile tile){
public void drawBase(){
TextureRegion r = Tmp.tr1;
r.set(region);
int crop = (region.getWidth() - tilesize*4) / 2;
@@ -38,6 +38,6 @@ public class StaticTree extends StaticWall{
}
}
}
Draw.rect(r, tile.drawx() + ox * Draw.scl, tile.drawy() + oy * Draw.scl);
Draw.rect(r, x + ox * Draw.scl, y + oy * Draw.scl);
}
}

View File

@@ -22,7 +22,7 @@ public class StaticWall extends Rock{
}
@Override
public void drawBase(Tile tile){
public void drawBase(){
int rx = tile.x / 2 * 2;
int ry = tile.y / 2 * 2;

View File

@@ -16,10 +16,10 @@ public class TreeBlock extends Block{
}
@Override
public void drawBase(Tile tile){}
public void drawBase(){}
@Override
public void drawLayer(Tile tile){
Draw.rect(region, tile.drawx(), tile.drawy(), Mathf.randomSeed(tile.pos(), 0, 4) * 90);
public void drawLayer(){
Draw.rect(region, x, y, Mathf.randomSeed(tile.pos(), 0, 4) * 90);
}
}

View File

@@ -22,22 +22,22 @@ public class ArmoredConduit extends Conduit{
@Override
public void draw(){
super.draw(tile);
super.draw();
// draw the cap when a conduit would normally leak
Tile next = tile.front();
if(next != null && next.team() == tile.team() && next.block().hasLiquids) return;
if(next != null && next.team() == team && next.block().hasLiquids) return;
Draw.rect(capRegion, tile.drawx(), tile.drawy(), tile.rotation() * 90);
Draw.rect(capRegion, x, y, tile.rotation() * 90);
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
public boolean acceptLiquid(Tile source, Liquid liquid, float amount){
return super.acceptLiquid(tile, source, liquid, amount) && (source.block() instanceof Conduit) || Edges.getFacingEdge(source, tile).relativeTo(tile) == tile.rotation();
}
@Override
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.outputsLiquid && blendsArmored(tile, rotation, otherx, othery, otherrot, otherblock);
}
}

View File

@@ -28,7 +28,6 @@ public class Conduit extends LiquidBlock implements Autotiler{
solid = false;
floating = true;
conveyorPlacement = true;
entityType = ConduitEntity::new;
}
@Override
@@ -75,7 +74,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
}
@Override
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
public boolean blends(int rotation, int otherx, int othery, int otherrot, Block otherblock){
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock);
}
@@ -93,14 +92,14 @@ public class Conduit extends LiquidBlock implements Autotiler{
int rotation = rotation() * 90;
Draw.colorl(0.34f);
Draw.rect(botRegions[blendbits], tile.drawx(), tile.drawy(), rotation);
Draw.rect(botRegions[blendbits], x, y, rotation);
Draw.color(liquids.current().color);
Draw.alpha(smoothLiquid);
Draw.rect(botRegions[blendbits], tile.drawx(), tile.drawy(), rotation);
Draw.rect(botRegions[blendbits], x, y, rotation);
Draw.color();
Draw.rect(topRegions[blendbits], tile.drawx(), tile.drawy(), rotation);
Draw.rect(topRegions[blendbits], x, y, rotation);
}
@Override

View File

@@ -22,40 +22,38 @@ public class LiquidBridge extends ItemBridge{
@Override
public void updateTile(){
ItemBridgeEntity entity = tile.ent();
time += cycleSpeed * Time.delta();
time2 += (cycleSpeed - 1f) * Time.delta();
entity.time += entity.cycleSpeed * Time.delta();
entity.time2 += (entity.cycleSpeed - 1f) * Time.delta();
Tile other = world.tile(entity.link);
Tile other = world.tile(link);
if(!linkValid(tile, other)){
tryDumpLiquid(tile, entity.liquids().current());
tryDumpLiquid(tile, liquids.current());
}else{
((ItemBridgeEntity)world.tile(entity.link).entity).incoming.add(tile.pos());
((ItemBridgeEntity)world.tile(link).entity).incoming.add(tile.pos());
if(entity.consValid()){
if(consValid()){
float alpha = 0.04f;
if(hasPower){
alpha *= entity.efficiency(); // Exceed boot time unless power is at max.
alpha *= efficiency(); // Exceed boot time unless power is at max.
}
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, alpha);
uptime = Mathf.lerpDelta(uptime, 1f, alpha);
}else{
entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f);
uptime = Mathf.lerpDelta(uptime, 0f, 0.02f);
}
if(entity.uptime >= 0.5f){
if(uptime >= 0.5f){
if(tryMoveLiquid(tile, other, false, entity.liquids().current()) > 0.1f){
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 4f, 0.05f);
if(tryMoveLiquid(tile, other, false, liquids.current()) > 0.1f){
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f);
}else{
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 1f, 0.01f);
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f);
}
}
}
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
public boolean acceptItem(Tile source, Item item){
return false;
}
}

View File

@@ -22,35 +22,33 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{
@Override
public void updateTile(){
ItemBridgeEntity entity = tile.ent();
time += cycleSpeed * Time.delta();
time2 += (cycleSpeed - 1f) * Time.delta();
entity.time += entity.cycleSpeed * Time.delta();
entity.time2 += (entity.cycleSpeed - 1f) * Time.delta();
Tile other = world.tile(entity.link);
Tile other = world.tile(link);
if(!linkValid(tile, other)){
tryDumpLiquid(tile, entity.liquids().current());
tryDumpLiquid(tile, liquids.current());
}else{
((ItemBridgeEntity)world.tile(entity.link).entity).incoming.add(tile.pos());
((ItemBridgeEntity)world.tile(link).entity).incoming.add(tile.pos());
if(entity.consValid()){
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f);
if(consValid()){
uptime = Mathf.lerpDelta(uptime, 1f, 0.04f);
}else{
entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f);
uptime = Mathf.lerpDelta(uptime, 0f, 0.02f);
}
if(entity.uptime >= 0.5f){
if(tryMoveLiquid(tile, other, false, entity.liquids().current()) > 0.1f){
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 4f, 0.05f);
if(uptime >= 0.5f){
if(tryMoveLiquid(tile, other, false, liquids.current()) > 0.1f){
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 4f, 0.05f);
}else{
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 1f, 0.01f);
cycleSpeed = Mathf.lerpDelta(cycleSpeed, 1f, 0.01f);
}
}
}
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
public boolean acceptItem(Tile source, Item item){
return false;
}
}

View File

@@ -36,7 +36,7 @@ public class LiquidJunction extends LiquidBlock{
}
@Override
public Tile getLiquidDestination(Tile tile, Tile source, Liquid liquid){
public Tile getLiquidDestination(Tile source, Liquid liquid){
int dir = source.relativeTo(tile.x, tile.y);
dir = (dir + 4) % 4;
Tile next = tile.getNearbyLink(dir);

View File

@@ -1,10 +0,0 @@
package mindustry.world.blocks.logic;
import mindustry.world.Block;
public class LogicBlock extends Block{
public LogicBlock(String name){
super(name);
}
}

View File

@@ -28,15 +28,14 @@ public class MessageBlock extends Block{
configurable = true;
solid = true;
destructible = true;
entityType = MessageBlockEntity::new;
config(String.class, (tile, text) -> {
MessageBlockEntity entity = (MessageBlockEntity)tile;
if(net.server() && text.length() > maxTextLength){
throw new ValidateException(player, "Player has gone above text limit.");
}
MessageBlockEntity entity = tile.ent();
StringBuilder result = new StringBuilder(text.length());
text = text.trim();
int count = 0;
@@ -57,86 +56,83 @@ public class MessageBlock extends Block{
});
}
@Override
public void drawSelect(Tile tile){
MessageBlockEntity entity = tile.ent();
BitmapFont font = Fonts.outline;
GlyphLayout l = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
boolean ints = font.usesIntegerPositions();
font.getData().setScale(1 / 4f / Scl.scl(1f));
font.setUseIntegerPositions(false);
String text = entity.message == null || entity.message.isEmpty() ? "[lightgray]" + Core.bundle.get("empty") : entity.message;
l.setText(font, text, Color.white, 90f, Align.left, true);
float offset = 1f;
Draw.color(0f, 0f, 0f, 0.2f);
Fill.rect(tile.drawx(), tile.drawy() - tilesize/2f - l.height/2f - offset, l.width + offset*2f, l.height + offset*2f);
Draw.color();
font.setColor(Color.white);
font.draw(text, tile.drawx() - l.width/2f, tile.drawy() - tilesize/2f - offset, 90f, Align.left, true);
font.setUseIntegerPositions(ints);
font.getData().setScale(1f);
Pools.free(l);
}
@Override
public void buildConfiguration(Tile tile, Table table){
MessageBlockEntity entity = tile.ent();
table.addImageButton(Icon.pencil, () -> {
if(mobile){
Core.input.getTextInput(new TextInput(){{
text = entity.message;
multiline = true;
maxLength = maxTextLength;
accepted = tile::configure;
}});
}else{
FloatingDialog dialog = new FloatingDialog("$editmessage");
dialog.setFillParent(false);
TextArea a = dialog.cont.add(new TextArea(entity.message.replace("\n", "\r"))).size(380f, 160f).get();
a.setFilter((textField, c) -> {
if(c == '\n' || c == '\r'){
int count = 0;
for(int i = 0; i < textField.getText().length(); i++){
if(textField.getText().charAt(i) == '\n' || textField.getText().charAt(i) == '\r'){
count++;
}
}
return count < maxNewlines;
}
return true;
});
a.setMaxLength(maxTextLength);
dialog.buttons.addButton("$ok", () -> {
tile.configure(a.getText());
dialog.hide();
}).size(130f, 60f);
dialog.update(() -> {
if(tile.block() != this){
dialog.hide();
}
});
dialog.show();
}
control.input.frag.config.hideConfig();
}).size(40f);
}
@Override
public void updateTableAlign(Tile tile, Table table){
Vec2 pos = Core.input.mouseScreen(tile.drawx(), tile.drawy() + tile.block().size * tilesize / 2f + 1);
table.setPosition(pos.x, pos.y, Align.bottom);
}
public class MessageBlockEntity extends TileEntity{
public String message = "";
public String[] lines = {""};
@Override
public void drawSelect(){
BitmapFont font = Fonts.outline;
GlyphLayout l = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
boolean ints = font.usesIntegerPositions();
font.getData().setScale(1 / 4f / Scl.scl(1f));
font.setUseIntegerPositions(false);
String text = message == null || message.isEmpty() ? "[lightgray]" + Core.bundle.get("empty") : message;
l.setText(font, text, Color.white, 90f, Align.left, true);
float offset = 1f;
Draw.color(0f, 0f, 0f, 0.2f);
Fill.rect(x, y - tilesize/2f - l.height/2f - offset, l.width + offset*2f, l.height + offset*2f);
Draw.color();
font.setColor(Color.white);
font.draw(text, x - l.width/2f, y - tilesize/2f - offset, 90f, Align.left, true);
font.setUseIntegerPositions(ints);
font.getData().setScale(1f);
Pools.free(l);
}
@Override
public void buildConfiguration(Table table){
table.addImageButton(Icon.pencil, () -> {
if(mobile){
Core.input.getTextInput(new TextInput(){{
text = message;
multiline = true;
maxLength = maxTextLength;
accepted = tile::configure;
}});
}else{
FloatingDialog dialog = new FloatingDialog("$editmessage");
dialog.setFillParent(false);
TextArea a = dialog.cont.add(new TextArea(message.replace("\n", "\r"))).size(380f, 160f).get();
a.setFilter((textField, c) -> {
if(c == '\n' || c == '\r'){
int count = 0;
for(int i = 0; i < textField.getText().length(); i++){
if(textField.getText().charAt(i) == '\n' || textField.getText().charAt(i) == '\r'){
count++;
}
}
return count < maxNewlines;
}
return true;
});
a.setMaxLength(maxTextLength);
dialog.buttons.addButton("$ok", () -> {
tile.configure(a.getText());
dialog.hide();
}).size(130f, 60f);
dialog.update(() -> {
if(tile.block() != MessageBlock.this){
dialog.hide();
}
});
dialog.show();
}
control.input.frag.config.hideConfig();
}).size(40f);
}
@Override
public void updateTableAlign(Table table){
Vec2 pos = Core.input.mouseScreen(x, y + size * tilesize / 2f + 1);
table.setPosition(pos.x, pos.y, Align.bottom);
}
@Override
public String config(){
return message;

View File

@@ -20,10 +20,10 @@ public class Battery extends PowerDistributor{
@Override
public void draw(){
Draw.color(emptyLightColor, fullLightColor, tile.entity.power().status);
Fill.square(tile.drawx(), tile.drawy(), tilesize * size / 2f - 1);
Draw.color(emptyLightColor, fullLightColor, tile.power.status);
Fill.square(x, y, tilesize * size / 2f - 1);
Draw.color();
Draw.rect(reg(topRegion), tile.drawx(), tile.drawy());
Draw.rect(reg(topRegion), x, y);
}
}

View File

@@ -39,9 +39,7 @@ public class ImpactReactor extends PowerGenerator{
liquidCapacity = 30f;
hasItems = true;
outputsPower = consumesPower = true;
entityType = FusionReactorEntity::new;
bottomRegion = reg("-bottom");
bottomRegion = reg("-bottom");
plasmaRegions = new int[plasmas];
for(int i = 0; i < plasmas; i++){
plasmaRegions[i] = reg("-plasma-" + i);
@@ -54,7 +52,7 @@ public class ImpactReactor extends PowerGenerator{
bars.add("poweroutput", entity -> new Bar(() ->
Core.bundle.format("bar.poweroutput",
Strings.fixed(Math.max(entity.block().getPowerProduction(entity.tile()) - consumes.getPower().usage, 0) * 60 * entity.timeScale(), 1)),
Strings.fixed(Math.max(block().getPowerProduction(tile()) - consumes.getPower().usage, 0) * 60 * timeScale(), 1)),
() -> Pal.powerBar,
() -> ((GeneratorEntity)entity).productionEfficiency));
}
@@ -70,57 +68,53 @@ public class ImpactReactor extends PowerGenerator{
@Override
public void updateTile(){
FusionReactorEntity entity = tile.ent();
if(entity.consValid() && entity.power().status >= 0.99f){
if(consValid() && power.status >= 0.99f){
boolean prevOut = getPowerProduction(tile) <= consumes.getPower().requestedPower(entity);
entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, warmupSpeed);
if(Mathf.equal(entity.warmup, 1f, 0.001f)){
entity.warmup = 1f;
warmup = Mathf.lerpDelta(warmup, 1f, warmupSpeed);
if(Mathf.equal(warmup, 1f, 0.001f)){
warmup = 1f;
}
if(!prevOut && (getPowerProduction(tile) > consumes.getPower().requestedPower(entity))){
Events.fire(Trigger.impactPower);
}
if(entity.timer(timerUse, itemDuration / entity.timeScale())){
entity.consume();
if(timer(timerUse, itemDuration / timeScale())){
consume();
}
}else{
entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.01f);
warmup = Mathf.lerpDelta(warmup, 0f, 0.01f);
}
entity.productionEfficiency = Mathf.pow(entity.warmup, 5f);
productionEfficiency = Mathf.pow(warmup, 5f);
}
@Override
public void draw(){
FusionReactorEntity entity = tile.ent();
Draw.rect(reg(bottomRegion), tile.drawx(), tile.drawy());
Draw.rect(reg(bottomRegion), x, y);
for(int i = 0; i < plasmas; i++){
float r = 29f + Mathf.absin(Time.time(), 2f + i * 1f, 5f - i * 0.5f);
Draw.color(plasma1, plasma2, (float)i / plasmas);
Draw.alpha((0.3f + Mathf.absin(Time.time(), 2f + i * 2f, 0.3f + i * 0.05f)) * entity.warmup);
Draw.alpha((0.3f + Mathf.absin(Time.time(), 2f + i * 2f, 0.3f + i * 0.05f)) * warmup);
Draw.blend(Blending.additive);
Draw.rect(reg(plasmaRegions[i]), tile.drawx(), tile.drawy(), r, r, Time.time() * (12 + i * 6f) * entity.warmup);
Draw.rect(reg(plasmaRegions[i]), x, y, r, r, Time.time() * (12 + i * 6f) * warmup);
Draw.blend();
}
Draw.color();
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.rect(region, x, y);
Draw.color();
}
@Override
public void drawLight(Tile tile){
public void drawLight(){
float fract = tile.<FusionReactorEntity>ent().warmup;
renderer.lights.add(tile.drawx(), tile.drawy(), (110f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(plasma2).lerp(plasma1, Mathf.absin(7f, 0.2f)), 0.8f * fract);
renderer.lights.add(x, y, (110f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(plasma2).lerp(plasma1, Mathf.absin(7f, 0.2f)), 0.8f * fract);
}
@Override
@@ -129,12 +123,10 @@ public class ImpactReactor extends PowerGenerator{
}
@Override
public void onDestroyed(Tile tile){
super.onDestroyed(tile);
public void onDestroyed(){
super.onDestroyed();
FusionReactorEntity entity = tile.ent();
if(entity.warmup < 0.4f || !state.rules.reactorExplosions) return;
if(warmup < 0.4f || !state.rules.reactorExplosions) return;
Sounds.explosionbig.at(tile);
@@ -162,7 +154,7 @@ public class ImpactReactor extends PowerGenerator{
}
}
public static class FusionReactorEntity extends GeneratorEntity{
public class FusionReactorEntity extends GeneratorEntity{
public float warmup;
@Override

View File

@@ -85,98 +85,91 @@ public class ItemLiquidGenerator extends PowerGenerator{
}
@Override
public boolean productionValid(Tile tile){
ItemLiquidGeneratorEntity entity = tile.ent();
return entity.generateTime > 0;
public boolean productionValid(){
return generateTime > 0;
}
@Override
public void updateTile(){
ItemLiquidGeneratorEntity entity = tile.ent();
//Note: Do not use this delta when calculating the amount of power or the power efficiency, but use it for resource consumption if necessary.
//Power amount is delta'd by PowerGraph class already.
float calculationDelta = entity.delta();
float calculationDelta = delta();
if(!entity.consValid()){
entity.productionEfficiency = 0.0f;
if(!consValid()){
productionEfficiency = 0.0f;
return;
}
Liquid liquid = null;
for(Liquid other : content.liquids()){
if(hasLiquids && entity.liquids().get(other) >= 0.001f && getLiquidEfficiency(other) >= minLiquidEfficiency){
if(hasLiquids && liquids.get(other) >= 0.001f && getLiquidEfficiency(other) >= minLiquidEfficiency){
liquid = other;
break;
}
}
entity.heat = Mathf.lerpDelta(entity.heat, entity.generateTime >= 0.001f ? 1f : 0f, 0.05f);
heat = Mathf.lerpDelta(heat, generateTime >= 0.001f ? 1f : 0f, 0.05f);
//liquid takes priority over solids
if(hasLiquids && liquid != null && entity.liquids().get(liquid) >= 0.001f){
if(hasLiquids && liquid != null && liquids.get(liquid) >= 0.001f){
float baseLiquidEfficiency = getLiquidEfficiency(liquid);
float maximumPossible = maxLiquidGenerate * calculationDelta;
float used = Math.min(entity.liquids().get(liquid) * calculationDelta, maximumPossible);
float used = Math.min(liquids.get(liquid) * calculationDelta, maximumPossible);
entity.liquids().remove(liquid, used * entity.power().graph.getUsageFraction());
entity.productionEfficiency = baseLiquidEfficiency * used / maximumPossible;
liquids.remove(liquid, used * power.graph.getUsageFraction());
productionEfficiency = baseLiquidEfficiency * used / maximumPossible;
if(used > 0.001f && Mathf.chance(0.05 * entity.delta())){
generateEffect.at(tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f));
if(used > 0.001f && Mathf.chance(0.05 * delta())){
generateEffect.at(x + Mathf.range(3f), y + Mathf.range(3f));
}
}else if(hasItems){
// No liquids accepted or none supplied, try using items if accepted
if(entity.generateTime <= 0f && entity.items().total() > 0){
if(generateTime <= 0f && items.total() > 0){
generateEffect.at(tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f));
Item item = entity.items().take();
entity.productionEfficiency = getItemEfficiency(item);
entity.explosiveness = item.explosiveness;
entity.generateTime = 1f;
Item item = items.take();
productionEfficiency = getItemEfficiency(item);
explosiveness = item.explosiveness;
generateTime = 1f;
}
if(entity.generateTime > 0f){
entity.generateTime -= Math.min(1f / itemDuration * entity.delta() * entity.power().graph.getUsageFraction(), entity.generateTime);
if(generateTime > 0f){
generateTime -= Math.min(1f / itemDuration * delta() * power.graph.getUsageFraction(), generateTime);
if(randomlyExplode && state.rules.reactorExplosions && Mathf.chance(entity.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.5f))){
if(randomlyExplode && state.rules.reactorExplosions && Mathf.chance(delta() * 0.06 * Mathf.clamp(explosiveness - 0.5f))){
//this block is run last so that in the event of a block destruction, no code relies on the block type
Core.app.post(() -> {
entity.damage(Mathf.random(11f));
damage(Mathf.random(11f));
explodeEffect.at(tile.worldx() + Mathf.range(size * tilesize / 2f), tile.worldy() + Mathf.range(size * tilesize / 2f));
});
}
}else{
entity.productionEfficiency = 0.0f;
productionEfficiency = 0.0f;
}
}
}
@Override
public void draw(){
super.draw(tile);
ItemLiquidGeneratorEntity entity = tile.ent();
super.draw();
if(hasItems){
Draw.color(heatColor);
Draw.alpha(entity.heat * 0.4f + Mathf.absin(Time.time(), 8f, 0.6f) * entity.heat);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.alpha(heat * 0.4f + Mathf.absin(Time.time(), 8f, 0.6f) * heat);
Draw.rect(topRegion, x, y);
Draw.reset();
}
if(hasLiquids){
Draw.color(entity.liquids().current().color);
Draw.alpha(entity.liquids().currentAmount() / liquidCapacity);
Draw.rect(liquidRegion, tile.drawx(), tile.drawy());
Draw.color(liquids.current().color);
Draw.alpha(liquids.currentAmount() / liquidCapacity);
Draw.rect(liquidRegion, x, y);
Draw.color();
}
}
@Override
public void drawLight(Tile tile){
ItemLiquidGeneratorEntity entity = tile.ent();
renderer.lights.add(tile.drawx(), tile.drawy(), (60f + Mathf.absin(10f, 5f)) * entity.productionEfficiency * size, Color.orange, 0.5f);
public void drawLight(){
renderer.lights.add(x, y, (60f + Mathf.absin(10f, 5f)) * productionEfficiency * size, Color.orange, 0.5f);
}
protected float getItemEfficiency(Item item){
@@ -187,7 +180,7 @@ public class ItemLiquidGenerator extends PowerGenerator{
return 0.0f;
}
public static class ItemLiquidGeneratorEntity extends GeneratorEntity{
public class ItemLiquidGeneratorEntity extends GeneratorEntity{
public float explosiveness;
public float heat;
}

View File

@@ -24,13 +24,11 @@ public class LightBlock extends Block{
update = true;
topRegion = reg("-top");
configurable = true;
entityType = LightEntity::new;
config(Integer.class, (tile, value) -> tile.<LightEntity>ent().color = value);
config(Integer.class, (tile, value) -> tile.<LightEntity>ent().color = value);
}
@Override
public void playerPlaced(Tile tile){
public void playerPlaced(){
if(lastColor != 0){
tile.configure(lastColor);
}
@@ -38,33 +36,28 @@ public class LightBlock extends Block{
@Override
public void draw(){
super.draw(tile);
LightEntity entity = tile.ent();
super.draw();
Draw.blend(Blending.additive);
Draw.color(Tmp.c1.set(entity.color), entity.efficiency() * 0.3f);
Draw.rect(reg(topRegion), tile.drawx(), tile.drawy());
Draw.color(Tmp.c1.set(color), efficiency() * 0.3f);
Draw.rect(reg(topRegion), x, y);
Draw.color();
Draw.blend();
}
@Override
public void buildConfiguration(Tile tile, Table table){
LightEntity entity = tile.ent();
public void buildConfiguration(Table table){
table.addImageButton(Icon.pencil, () -> {
ui.picker.show(Tmp.c1.set(entity.color).a(0.5f), false, res -> {
entity.color = res.rgba();
lastColor = entity.color;
ui.picker.show(Tmp.c1.set(color).a(0.5f), false, res -> {
color = res.rgba();
lastColor = color;
});
control.input.frag.config.hideConfig();
}).size(40f);
}
@Override
public void drawLight(Tile tile){
LightEntity entity = tile.ent();
renderer.lights.add(tile.drawx(), tile.drawy(), radius, Tmp.c1.set(entity.color), brightness * tile.entity.efficiency());
public void drawLight(){
renderer.lights.add(x, y, radius, Tmp.c1.set(color), brightness * tile.efficiency());
}
public class LightEntity extends TileEntity{

View File

@@ -46,8 +46,7 @@ public class NuclearReactor extends PowerGenerator{
liquidCapacity = 30;
hasItems = true;
hasLiquids = true;
entityType = NuclearReactorEntity::new;
rebuildable = false;
rebuildable = false;
}
@Override
@@ -75,58 +74,54 @@ public class NuclearReactor extends PowerGenerator{
@Override
public void updateTile(){
NuclearReactorEntity entity = tile.ent();
ConsumeLiquid cliquid = consumes.get(ConsumeType.liquid);
Item item = consumes.<ConsumeItems>get(ConsumeType.item).items[0].item;
int fuel = entity.items().get(item);
int fuel = items.get(item);
float fullness = (float)fuel / itemCapacity;
entity.productionEfficiency = fullness;
productionEfficiency = fullness;
if(fuel > 0){
entity.heat += fullness * heating * Math.min(entity.delta(), 4f);
heat += fullness * heating * Math.min(delta(), 4f);
if(entity.timer(timerFuel, itemDuration / entity.timeScale())){
entity.consume();
if(timer(timerFuel, itemDuration / timeScale())){
consume();
}
}
Liquid liquid = cliquid.liquid;
if(entity.heat > 0){
float maxUsed = Math.min(entity.liquids().get(liquid), entity.heat / coolantPower);
entity.heat -= maxUsed * coolantPower;
entity.liquids().remove(liquid, maxUsed);
if(heat > 0){
float maxUsed = Math.min(liquids.get(liquid), heat / coolantPower);
heat -= maxUsed * coolantPower;
liquids.remove(liquid, maxUsed);
}
if(entity.heat > smokeThreshold){
float smoke = 1.0f + (entity.heat - smokeThreshold) / (1f - smokeThreshold); //ranges from 1.0 to 2.0
if(Mathf.chance(smoke / 20.0 * entity.delta())){
if(heat > smokeThreshold){
float smoke = 1.0f + (heat - smokeThreshold) / (1f - smokeThreshold); //ranges from 1.0 to 2.0
if(Mathf.chance(smoke / 20.0 * delta())){
Fx.reactorsmoke.at(tile.worldx() + Mathf.range(size * tilesize / 2f),
tile.worldy() + Mathf.random(size * tilesize / 2f));
}
}
entity.heat = Mathf.clamp(entity.heat);
heat = Mathf.clamp(heat);
if(entity.heat >= 0.999f){
if(heat >= 0.999f){
Events.fire(Trigger.thoriumReactorOverheat);
entity.kill();
kill();
}
}
@Override
public void onDestroyed(Tile tile){
super.onDestroyed(tile);
public void onDestroyed(){
super.onDestroyed();
Sounds.explosionbig.at(tile);
NuclearReactorEntity entity = tile.ent();
int fuel = items.get(consumes.<ConsumeItems>get(ConsumeType.item).items[0].item);
int fuel = entity.items().get(consumes.<ConsumeItems>get(ConsumeType.item).items[0].item);
if((fuel < 5 && entity.heat < 0.5f) || !state.rules.reactorExplosions) return;
if((fuel < 5 && heat < 0.5f) || !state.rules.reactorExplosions) return;
Effects.shake(6f, 16f, tile.worldx(), tile.worldy());
Fx.nuclearShockwave.at(tile.worldx(), tile.worldy());
@@ -152,37 +147,34 @@ public class NuclearReactor extends PowerGenerator{
}
@Override
public void drawLight(Tile tile){
NuclearReactorEntity entity = tile.ent();
float fract = entity.productionEfficiency;
renderer.lights.add(tile.drawx(), tile.drawy(), (90f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(lightColor).lerp(Color.scarlet, entity.heat), 0.6f * fract);
public void drawLight(){
float fract = productionEfficiency;
renderer.lights.add(x, y, (90f + Mathf.absin(5, 5f)) * fract, Tmp.c1.set(lightColor).lerp(Color.scarlet, heat), 0.6f * fract);
}
@Override
public void draw(){
super.draw(tile);
super.draw();
NuclearReactorEntity entity = tile.ent();
Draw.color(coolColor, hotColor, heat);
Fill.rect(x, y, size * tilesize, size * tilesize);
Draw.color(coolColor, hotColor, entity.heat);
Fill.rect(tile.drawx(), tile.drawy(), size * tilesize, size * tilesize);
Draw.color(liquids.current().color);
Draw.alpha(liquids.currentAmount() / liquidCapacity);
Draw.rect(topRegion, x, y);
Draw.color(entity.liquids().current().color);
Draw.alpha(entity.liquids().currentAmount() / liquidCapacity);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
if(entity.heat > flashThreshold){
float flash = 1f + ((entity.heat - flashThreshold) / (1f - flashThreshold)) * 5.4f;
entity.flash += flash * Time.delta();
Draw.color(Color.red, Color.yellow, Mathf.absin(entity.flash, 9f, 1f));
if(heat > flashThreshold){
float flash = 1f + ((heat - flashThreshold) / (1f - flashThreshold)) * 5.4f;
flash += flash * Time.delta();
Draw.color(Color.red, Color.yellow, Mathf.absin(flash, 9f, 1f));
Draw.alpha(0.6f);
Draw.rect(lightsRegion, tile.drawx(), tile.drawy());
Draw.rect(lightsRegion, x, y);
}
Draw.reset();
}
public static class NuclearReactorEntity extends GeneratorEntity{
public class NuclearReactorEntity extends GeneratorEntity{
public float heat;
public float flash;

View File

@@ -25,12 +25,12 @@ public class PowerDiode extends Block{
@Override
public void updateTile(){
super.update(tile);
super.updateTile();
if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().team() != tile.front().team()) return;
PowerGraph backGraph = tile.back().entity.power().graph;
PowerGraph frontGraph = tile.front().entity.power().graph;
PowerGraph backGraph = tile.back().power.graph;
PowerGraph frontGraph = tile.front().power.graph;
if(backGraph == frontGraph) return;
// 0f - 1f of battery capacity in use
@@ -50,16 +50,16 @@ public class PowerDiode extends Block{
}
// battery % of the graph on either side, defaults to zero
public float bar(Tile tile){
return (tile != null && tile.block().hasPower) ? tile.entity.power().graph.getBatteryStored() / tile.entity.power().graph.getTotalBatteryCapacity() : 0f;
public float bar(){
return (tile != null && tile.block().hasPower) ? tile.power.graph.getBatteryStored() / tile.power.graph.getTotalBatteryCapacity() : 0f;
}
@Override
public void setBars(){
super.setBars();
bars.add("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(entity.tile().back())));
bars.add("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(entity.tile().front())));
bars.add("back", entity -> new Bar("bar.input", Pal.powerBar, () -> bar(tile().back())));
bars.add("front", entity -> new Bar("bar.output", Pal.powerBar, () -> bar(tile().front())));
}
@Override
@@ -70,8 +70,8 @@ public class PowerDiode extends Block{
@Override
public void draw(){
Draw.rect(region, tile.drawx(), tile.drawy(), 0);
Draw.rect(arrow, tile.drawx(), tile.drawy(), rotate ? tile.rotation() * 90 : 0);
Draw.rect(region, x, y, 0);
Draw.rect(arrow, x, y, rotate ? tile.rotation() * 90 : 0);
}
@Override

View File

@@ -22,7 +22,6 @@ public class PowerGenerator extends PowerDistributor{
sync = true;
baseExplosiveness = 5f;
flags = EnumSet.of(BlockFlag.producer);
entityType = GeneratorEntity::new;
}
@Override
@@ -38,14 +37,14 @@ public class PowerGenerator extends PowerDistributor{
if(hasPower && outputsPower && !consumes.hasPower()){
bars.add("power", entity -> new Bar(() ->
Core.bundle.format("bar.poweroutput",
Strings.fixed(entity.block().getPowerProduction(entity.tile()) * 60 * entity.timeScale(), 1)),
Strings.fixed(block().getPowerProduction(tile()) * 60 * timeScale(), 1)),
() -> Pal.powerBar,
() -> ((GeneratorEntity)entity).productionEfficiency));
}
}
@Override
public float getPowerProduction(Tile tile){
public float getPowerProduction(){
return powerProduction * tile.<GeneratorEntity>ent().productionEfficiency;
}
@@ -54,7 +53,7 @@ public class PowerGenerator extends PowerDistributor{
return false;
}
public static class GeneratorEntity extends TileEntity{
public class GeneratorEntity extends TileEntity{
public float generateTime;
/** The efficiency of the producer. An efficiency of 1.0 means 100% */
public float productionEfficiency = 0.0f;

View File

@@ -36,51 +36,49 @@ public class PowerNode extends PowerBlock{
configurable = true;
consumesPower = false;
outputsPower = false;
entityType = PowerNodeEntity::new;
config(Integer.class, (tile, value) -> {
config(Integer.class, (tile, value) -> {
Tilec entity = tile.entity;
Tile other = world.tile(value);
boolean contains = entity.power().links.contains(value), valid = other != null && other.entity != null && other.entity.power() != null;
boolean contains = power.links.contains(value), valid = other != null && other.entity != null && other.power != null;
if(contains){
//unlink
entity.power().links.removeValue(value);
if(valid) other.entity.power().links.removeValue(tile.pos());
power.links.removeValue(value);
if(valid) other.power.links.removeValue(tile.pos());
PowerGraph newgraph = new PowerGraph();
//reflow from this point, covering all tiles on this side
newgraph.reflow(tile);
if(valid && other.entity.power().graph != newgraph){
if(valid && other.power.graph != newgraph){
//create new graph for other end
PowerGraph og = new PowerGraph();
//reflow from other end
og.reflow(other);
}
}else if(linkValid(tile, other) && valid && entity.power().links.size < maxNodes){
}else if(linkValid(tile, other) && valid && power.links.size < maxNodes){
if(!entity.power().links.contains(other.pos())){
entity.power().links.add(other.pos());
if(!power.links.contains(other.pos())){
power.links.add(other.pos());
}
if(other.getTeamID() == tile.getTeamID()){
if(!other.entity.power().links.contains(tile.pos())){
other.entity.power().links.add(tile.pos());
if(!other.power.links.contains(tile.pos())){
other.power.links.add(tile.pos());
}
}
entity.power().graph.add(other.entity.power().graph);
power.graph.add(other.power.graph);
}
});
config(Point2[].class, (tile, value) -> {
tile.entity.power().links.clear();
tile.power.links.clear();
for(Point2 p : value){
if(tile.entity.power().links.size < maxNodes){
tile.entity.power().links.add(Point2.pack(p.x + tile.x, p.y + tile.y));
if(tile.power.links.size < maxNodes){
tile.power.links.add(Point2.pack(p.x + tile.x, p.y + tile.y));
}
}
});
@@ -99,23 +97,23 @@ public class PowerNode extends PowerBlock{
super.setBars();
bars.add("power", entity -> new Bar(() ->
Core.bundle.format("bar.powerbalance",
((entity.power().graph.getPowerBalance() >= 0 ? "+" : "") + Strings.fixed(entity.power().graph.getPowerBalance() * 60, 1))),
((power.graph.getPowerBalance() >= 0 ? "+" : "") + Strings.fixed(power.graph.getPowerBalance() * 60, 1))),
() -> Pal.powerBar,
() -> Mathf.clamp(entity.power().graph.getLastPowerProduced() / entity.power().graph.getLastPowerNeeded())));
() -> Mathf.clamp(power.graph.getLastPowerProduced() / power.graph.getLastPowerNeeded())));
bars.add("batteries", entity -> new Bar(() ->
Core.bundle.format("bar.powerstored",
(ui.formatAmount((int)entity.power().graph.getBatteryStored())), ui.formatAmount((int)entity.power().graph.getTotalBatteryCapacity())),
(ui.formatAmount((int)power.graph.getBatteryStored())), ui.formatAmount((int)power.graph.getTotalBatteryCapacity())),
() -> Pal.powerBar,
() -> Mathf.clamp(entity.power().graph.getBatteryStored() / entity.power().graph.getTotalBatteryCapacity())));
() -> Mathf.clamp(power.graph.getBatteryStored() / power.graph.getTotalBatteryCapacity())));
}
@Override
public void placed(Tile tile){
public void placed(){
if(net.client()) return;
Boolf<Tile> valid = other -> other != null && other != tile && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(tile, other)
&& !other.entity.proximity().contains(tile) && other.entity.power().graph != tile.entity.power().graph;
&& !other.proximity().contains(tile) && other.power.graph != tile.power.graph;
tempTiles.clear();
Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> {
@@ -133,19 +131,19 @@ public class PowerNode extends PowerBlock{
return Float.compare(a.dst2(tile), b.dst2(tile));
});
tempTiles.each(valid, other -> {
if(!tile.entity.power().links.contains(other.pos())){
if(!tile.power.links.contains(other.pos())){
tile.configureAny(other.pos());
}
});
super.placed(tile);
super.placed();
}
private void getPotentialLinks(Tile tile, Cons<Tile> others){
Boolf<Tile> valid = other -> other != null && other != tile && other.entity != null && other.entity.power() != null &&
private void getPotentialLinks(Cons<Tile> others){
Boolf<Tile> valid = other -> other != null && other != tile && other.entity != null && other.power != null &&
((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) &&
overlaps(tile.x * tilesize + offset(), tile.y * tilesize + offset(), other, laserRange * tilesize) && other.team() == player.team()
&& !other.entity.proximity().contains(tile) && !graphs.contains(other.entity.power().graph);
&& !other.proximity().contains(tile) && !graphs.contains(other.power.graph);
tempTiles.clear();
graphs.clear();
@@ -162,7 +160,7 @@ public class PowerNode extends PowerBlock{
return Float.compare(a.dst2(tile), b.dst2(tile));
});
tempTiles.each(valid, t -> {
graphs.add(t.entity.power().graph);
graphs.add(t.power.graph);
others.get(t);
});
}
@@ -177,11 +175,11 @@ public class PowerNode extends PowerBlock{
@Override
public void updateTile(){
tile.entity.power().graph.update();
tile.power.graph.update();
}
@Override
public boolean onConfigureTileTapped(Tile tile, Tile other){
public boolean onConfigureTileTapped(Tile other){
Tilec entity = tile.ent();
other = other.link();
@@ -191,7 +189,7 @@ public class PowerNode extends PowerBlock{
}
if(tile == other){
if(other.entity.power().links.size == 0){
if(other.power.links.size == 0){
int[] total = {0};
getPotentialLinks(tile, link -> {
if(!insulated(tile, link) && total[0]++ < maxNodes){
@@ -199,8 +197,8 @@ public class PowerNode extends PowerBlock{
}
});
}else{
while(entity.power().links.size > 0){
tile.configure(entity.power().links.get(0));
while(power.links.size > 0){
tile.configure(power.links.get(0));
}
}
return false;
@@ -210,26 +208,26 @@ public class PowerNode extends PowerBlock{
}
@Override
public void drawSelect(Tile tile){
super.drawSelect(tile);
public void drawSelect(){
super.drawSelect();
Lines.stroke(1f);
Draw.color(Pal.accent);
Drawf.circles(tile.drawx(), tile.drawy(), laserRange * tilesize);
Drawf.circles(x, y, laserRange * tilesize);
Draw.reset();
}
@Override
public void drawConfigure(Tile tile){
public void drawConfigure(){
Draw.color(Pal.accent);
Lines.stroke(1.5f);
Lines.circle(tile.drawx(), tile.drawy(),
Lines.circle(x, y,
tile.block().size * tilesize / 2f + 1f + Mathf.absin(Time.time(), 4f, 1f));
Drawf.circles(tile.drawx(), tile.drawy(), laserRange * tilesize);
Drawf.circles(x, y, laserRange * tilesize);
Lines.stroke(1.5f);
@@ -272,13 +270,13 @@ public class PowerNode extends PowerBlock{
}
@Override
public void drawLayer(Tile tile){
public void drawLayer(){
if(Core.settings.getInt("lasersopacity") == 0) return;
Tilec entity = tile.ent();
for(int i = 0; i < entity.power().links.size; i++){
Tile link = world.tile(entity.power().links.get(i));
for(int i = 0; i < power.links.size; i++){
Tile link = world.tile(power.links.get(i));
if(!linkValid(tile, link)) continue;
@@ -308,8 +306,8 @@ public class PowerNode extends PowerBlock{
}
}
protected boolean linked(Tile tile, Tile other){
return tile.entity.power().links.contains(other.pos());
protected boolean linked(Tile other){
return tile.power.links.contains(other.pos());
}
public boolean linkValid(Tilec tile, Tilec link){
@@ -317,11 +315,11 @@ public class PowerNode extends PowerBlock{
}
public boolean linkValid(Tilec tile, Tilec link, boolean checkMaxNodes){
if(tile == link || link == null || !link.block().hasPower || tile.team() != link.team()) return false;
if(tile == link || link == null || !link.block().hasPower || team != link.team()) return false;
if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, link.<PowerNode>cblock().laserRange * tilesize))){
if(checkMaxNodes && link.block() instanceof PowerNode){
return link.entity.power().links.size < link.<PowerNode>cblock().maxNodes || link.entity.power().links.contains(tile.pos());
return link.power.links.size < link.<PowerNode>cblock().maxNodes || link.power.links.contains(tile.pos());
}
return true;
}
@@ -341,8 +339,8 @@ public class PowerNode extends PowerBlock{
return Intersector.overlaps(Tmp.cr1.set(src.worldx() + offset(), src.worldy() + offset(), laserRange * tilesize), Tmp.r1.setSize(size * tilesize).setCenter(other.worldx() + offset(), other.worldy() + offset()));
}
protected void drawLaser(Tile tile, Tile target){
drawLaser(tile.drawx(), tile.drawy(), target.drawx(), target.drawy(), tile.entity.power().graph.getSatisfaction(), size, target.block().size);
protected void drawLaser(Tile target){
drawLaser(x, y, target.drawx(), target.drawy(), tile.power.graph.getSatisfaction(), size, target.block().size);
}
protected void drawLaser(float x1, float y1, float x2, float y2, float satisfaction, int size1, int size2){

View File

@@ -12,7 +12,6 @@ public class SolarGenerator extends PowerGenerator{
super(name);
// Remove the BlockFlag.producer flag to make this a lower priority target than other generators.
flags = EnumSet.of();
entityType = GeneratorEntity::new;
}
@Override

View File

@@ -28,10 +28,8 @@ public class ThermalGenerator extends PowerGenerator{
@Override
public void updateTile(){
GeneratorEntity entity = tile.ent();
if(entity.productionEfficiency > 0.1f && Mathf.chance(0.05 * entity.delta())){
generateEffect.at(tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f));
if(productionEfficiency > 0.1f && Mathf.chance(0.05 * delta())){
generateEffect.at(x + Mathf.range(3f), y + Mathf.range(3f));
}
}
@@ -41,28 +39,26 @@ public class ThermalGenerator extends PowerGenerator{
}
@Override
public void drawLight(Tile tile){
GeneratorEntity entity = tile.ent();
renderer.lights.add(tile.drawx(), tile.drawy(), (40f + Mathf.absin(10f, 5f)) * entity.productionEfficiency * size, Color.scarlet, 0.4f);
public void drawLight(){
renderer.lights.add(x, y, (40f + Mathf.absin(10f, 5f)) * productionEfficiency * size, Color.scarlet, 0.4f);
}
@Override
public void onProximityAdded(Tile tile){
super.onProximityAdded(tile);
public void onProximityAdded(){
super.onProximityAdded();
GeneratorEntity entity = tile.ent();
entity.productionEfficiency = sumAttribute(attribute, tile.x, tile.y);
productionEfficiency = sumAttribute(attribute, tile.x, tile.y);
}
@Override
public float getPowerProduction(Tile tile){
public float getPowerProduction(){
//in this case, productionEfficiency means 'total heat'
//thus, it may be greater than 1.0
return powerProduction * tile.<GeneratorEntity>ent().productionEfficiency;
}
@Override
public boolean canPlaceOn(Tile tile){
public boolean canPlaceOn(){
//make sure there's heat at this location
return tile.getLinkedTilesAs(this, tempTiles).sumf(other -> other.floor().attributes.get(attribute)) > 0.01f;
}

View File

@@ -28,7 +28,6 @@ public class Cultivator extends GenericCrafter{
public Cultivator(String name){
super(name);
craftEffect = Fx.none;
entityType = CultivatorEntity::new;
}
@Override
@@ -41,10 +40,9 @@ public class Cultivator extends GenericCrafter{
@Override
public void updateTile(){
super.update(tile);
super.updateTile();
CultivatorEntity entity = tile.ent();
entity.warmup = Mathf.lerpDelta(entity.warmup, entity.consValid() ? 1f : 0f, 0.015f);
warmup = Mathf.lerpDelta(warmup, consValid() ? 1f : 0f, 0.015f);
}
@Override
@@ -71,15 +69,13 @@ public class Cultivator extends GenericCrafter{
@Override
public void draw(){
CultivatorEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.rect(region, x, y);
Draw.color(plantColor);
Draw.alpha(entity.warmup);
Draw.rect(middleRegion, tile.drawx(), tile.drawy());
Draw.alpha(warmup);
Draw.rect(middleRegion, x, y);
Draw.color(bottomColor, plantColorLight, entity.warmup);
Draw.color(bottomColor, plantColorLight, warmup);
random.setSeed(tile.pos());
for(int i = 0; i < 12; i++){
@@ -88,13 +84,13 @@ public class Cultivator extends GenericCrafter{
float life = 1f - (((Time.time() + offset) / 50f) % recurrence);
if(life > 0){
Lines.stroke(entity.warmup * (life * 1f + 0.2f));
Lines.poly(tile.drawx() + x, tile.drawy() + y, 8, (1f - life) * 3f);
Lines.stroke(warmup * (life * 1f + 0.2f));
Lines.poly(x + x, y + y, 8, (1f - life) * 3f);
}
}
Draw.color();
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.rect(topRegion, x, y);
}
@Override
@@ -103,11 +99,10 @@ public class Cultivator extends GenericCrafter{
}
@Override
public void onProximityAdded(Tile tile){
super.onProximityAdded(tile);
public void onProximityAdded(){
super.onProximityAdded();
CultivatorEntity entity = tile.ent();
entity.boost = sumAttribute(attribute, tile.x, tile.y);
boost = sumAttribute(attribute, tile.x, tile.y);
}
@Override
@@ -116,7 +111,7 @@ public class Cultivator extends GenericCrafter{
return super.getProgressIncrease(entity, baseTime) * (1f + c.boost);
}
public static class CultivatorEntity extends GenericCrafterEntity{
public class CultivatorEntity extends GenericCrafterEntity{
public float warmup;
public float boost;

View File

@@ -62,9 +62,7 @@ public class Drill extends Block{
hasLiquids = true;
liquidCapacity = 5f;
hasItems = true;
entityType = DrillEntity::new;
idleSound = Sounds.drill;
idleSound = Sounds.drill;
idleSoundVolume = 0.003f;
}
@@ -75,7 +73,7 @@ public class Drill extends Block{
bars.add("drillspeed", e -> {
DrillEntity entity = (DrillEntity)e;
return new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(entity.lastDrillSpeed * 60 * entity.timeScale(), 2)), () -> Pal.ammo, () -> entity.warmup);
return new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(lastDrillSpeed * 60 * timeScale(), 2)), () -> Pal.ammo, () -> warmup);
});
}
@@ -88,34 +86,32 @@ public class Drill extends Block{
}
@Override
public void drawCracks(Tile tile){}
public void drawCracks(){}
@Override
public void draw(){
float s = 0.3f;
float ts = 0.6f;
DrillEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy());
super.drawCracks(tile);
Draw.rect(region, x, y);
super.drawCracks();
if(drawRim){
Draw.color(heatColor);
Draw.alpha(entity.warmup * ts * (1f - s + Mathf.absin(Time.time(), 3f, s)));
Draw.alpha(warmup * ts * (1f - s + Mathf.absin(Time.time(), 3f, s)));
Draw.blend(Blending.additive);
Draw.rect(rimRegion, tile.drawx(), tile.drawy());
Draw.rect(rimRegion, x, y);
Draw.blend();
Draw.color();
}
Draw.rect(rotatorRegion, tile.drawx(), tile.drawy(), entity.drillTime * rotateSpeed);
Draw.rect(rotatorRegion, x, y, drillTime * rotateSpeed);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.rect(topRegion, x, y);
if(entity.dominantItem != null && drawMineItem){
Draw.color(entity.dominantItem.color);
Draw.rect("drill-top", tile.drawx(), tile.drawy(), 1f);
if(dominantItem != null && drawMineItem){
Draw.color(dominantItem.color);
Draw.rect("drill-top", x, y, 1f);
Draw.color();
}
}
@@ -126,13 +122,13 @@ public class Drill extends Block{
}
@Override
public boolean shouldConsume(Tile tile){
return tile.entity.items().total() < itemCapacity;
public boolean shouldConsume(){
return tile.items.total() < itemCapacity;
}
@Override
public boolean shouldIdleSound(Tile tile){
return tile.entity.efficiency() > 0.01f;
public boolean shouldIdleSound(){
return tile.efficiency() > 0.01f;
}
@Override
@@ -159,15 +155,13 @@ public class Drill extends Block{
}
@Override
public void drawSelect(Tile tile){
DrillEntity entity = tile.ent();
if(entity.dominantItem != null){
float dx = tile.drawx() - size * tilesize/2f, dy = tile.drawy() + size * tilesize/2f;
public void drawSelect(){
if(dominantItem != null){
float dx = x - size * tilesize/2f, dy = y + size * tilesize/2f;
Draw.mixcol(Color.darkGray, 1f);
Draw.rect(entity.dominantItem.icon(Cicon.small), dx, dy - 1);
Draw.rect(dominantItem.icon(Cicon.small), dx, dy - 1);
Draw.reset();
Draw.rect(entity.dominantItem.icon(Cicon.small), dx, dy);
Draw.rect(dominantItem.icon(Cicon.small), dx, dy);
}
}
@@ -201,7 +195,7 @@ public class Drill extends Block{
}
}
void countOre(Tile tile){
void countOre(){
returnItem = null;
returnCount = 0;
@@ -235,66 +229,62 @@ public class Drill extends Block{
}
@Override
public void onProximityUpdate(Tile tile){
DrillEntity entity = tile.ent();
public void onProximityUpdate(){
countOre(tile);
entity.dominantItem = returnItem;
entity.dominantItems = returnCount;
dominantItem = returnItem;
dominantItems = returnCount;
}
@Override
public void updateTile(){
DrillEntity entity = tile.ent();
if(entity.dominantItem == null){
if(dominantItem == null){
return;
}
if(entity.timer(timerDump, dumpTime)){
tryDump(tile, entity.dominantItem);
if(timer(timerDump, dumpTime)){
tryDump(tile, dominantItem);
}
entity.drillTime += entity.warmup * entity.delta();
drillTime += warmup * delta();
if(entity.items().total() < itemCapacity && entity.dominantItems > 0 && entity.consValid()){
if(items.total() < itemCapacity && dominantItems > 0 && consValid()){
float speed = 1f;
if(entity.cons().optionalValid()){
if(cons().optionalValid()){
speed = liquidBoostIntensity;
}
speed *= entity.efficiency(); // Drill slower when not at full power
speed *= efficiency(); // Drill slower when not at full power
entity.lastDrillSpeed = (speed * entity.dominantItems * entity.warmup) / (drillTime + hardnessDrillMultiplier * entity.dominantItem.hardness);
entity.warmup = Mathf.lerpDelta(entity.warmup, speed, warmupSpeed);
entity.progress += entity.delta()
* entity.dominantItems * speed * entity.warmup;
lastDrillSpeed = (speed * dominantItems * warmup) / (drillTime + hardnessDrillMultiplier * dominantItem.hardness);
warmup = Mathf.lerpDelta(warmup, speed, warmupSpeed);
progress += delta()
* dominantItems * speed * warmup;
if(Mathf.chance(Time.delta() * updateEffectChance * entity.warmup))
updateEffect.at(entity.getX() + Mathf.range(size * 2f), entity.getY() + Mathf.range(size * 2f));
if(Mathf.chance(Time.delta() * updateEffectChance * warmup))
updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f));
}else{
entity.lastDrillSpeed = 0f;
entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, warmupSpeed);
lastDrillSpeed = 0f;
warmup = Mathf.lerpDelta(warmup, 0f, warmupSpeed);
return;
}
if(entity.dominantItems > 0 && entity.progress >= drillTime + hardnessDrillMultiplier * entity.dominantItem.hardness && tile.entity.items().total() < itemCapacity){
if(dominantItems > 0 && progress >= drillTime + hardnessDrillMultiplier * dominantItem.hardness && tile.items.total() < itemCapacity){
offloadNear(tile, entity.dominantItem);
offloadNear(tile, dominantItem);
useContent(tile, entity.dominantItem);
useContent(tile, dominantItem);
entity.index++;
entity.progress = 0f;
index++;
progress = 0f;
drillEffect.at(entity.getX() + Mathf.range(size), entity.getY() + Mathf.range(size), entity.dominantItem.color);
drillEffect.at(getX() + Mathf.range(size), getY() + Mathf.range(size), dominantItem.color);
}
}
@Override
public boolean canPlaceOn(Tile tile){
public boolean canPlaceOn(){
if(isMultiblock()){
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
if(isValid(other)){
@@ -311,17 +301,17 @@ public class Drill extends Block{
return tier;
}
public Item getDrop(Tile tile){
public Item getDrop(){
return tile.drop();
}
public boolean isValid(Tile tile){
public boolean isValid(){
if(tile == null) return false;
Item drops = tile.drop();
return drops != null && drops.hardness <= tier;
}
public static class DrillEntity extends TileEntity{
public class DrillEntity extends TileEntity{
float progress;
int index;
float warmup;

View File

@@ -15,7 +15,6 @@ public class Fracker extends SolidPump{
public Fracker(String name){
super(name);
hasItems = true;
entityType = FrackerEntity::new;
}
@Override
@@ -40,27 +39,25 @@ public class Fracker extends SolidPump{
}
@Override
public void drawCracks(Tile tile){}
public void drawCracks(){}
@Override
public boolean shouldConsume(Tile tile){
return tile.entity.liquids().get(result) < liquidCapacity - 0.01f;
public boolean shouldConsume(){
return tile.liquids.get(result) < liquidCapacity - 0.01f;
}
@Override
public void draw(){
FrackerEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy());
super.drawCracks(tile);
Draw.rect(region, x, y);
super.drawCracks();
Draw.color(result.color);
Draw.alpha(tile.entity.liquids().get(result) / liquidCapacity);
Draw.rect(liquidRegion, tile.drawx(), tile.drawy());
Draw.alpha(tile.liquids.get(result) / liquidCapacity);
Draw.rect(liquidRegion, x, y);
Draw.color();
Draw.rect(rotatorRegion, tile.drawx(), tile.drawy(), entity.pumpTime);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.rect(rotatorRegion, x, y, pumpTime);
Draw.rect(topRegion, x, y);
}
@Override
@@ -70,27 +67,25 @@ public class Fracker extends SolidPump{
@Override
public void updateTile(){
FrackerEntity entity = tile.ent();
if(entity.consValid()){
if(entity.accumulator >= itemUseTime){
entity.consume();
entity.accumulator -= itemUseTime;
if(consValid()){
if(accumulator >= itemUseTime){
consume();
accumulator -= itemUseTime;
}
super.update(tile);
entity.accumulator += entity.delta() * entity.efficiency();
super.updateTile();
accumulator += delta() * efficiency();
}else{
tryDumpLiquid(tile, result);
}
}
@Override
public float typeLiquid(Tile tile){
return tile.entity.liquids().get(result);
public float typeLiquid(){
return tile.liquids.get(result);
}
public static class FrackerEntity extends SolidPumpEntity{
public class FrackerEntity extends SolidPumpEntity{
public float accumulator;
}
}

View File

@@ -35,7 +35,6 @@ public class GenericCrafter extends Block{
idleSound = Sounds.machine;
sync = true;
idleSoundVolume = 0.03f;
entityType = GenericCrafterEntity::new;
}
@Override
@@ -71,7 +70,7 @@ public class GenericCrafter extends Block{
@Override
public void draw(){
if(drawer == null){
super.draw(tile);
super.draw();
}else{
drawer.get(tile);
}
@@ -84,23 +83,21 @@ public class GenericCrafter extends Block{
@Override
public void updateTile(){
GenericCrafterEntity entity = tile.ent();
if(consValid()){
if(entity.consValid()){
entity.progress += getProgressIncrease(entity, craftTime);
entity.totalProgress += entity.delta();
entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f);
progress += getProgressIncrease(entity, craftTime);
totalProgress += delta();
warmup = Mathf.lerpDelta(warmup, 1f, 0.02f);
if(Mathf.chance(Time.delta() * updateEffectChance)){
updateEffect.at(entity.getX() + Mathf.range(size * 4f), entity.getY() + Mathf.range(size * 4));
updateEffect.at(getX() + Mathf.range(size * 4f), getY() + Mathf.range(size * 4));
}
}else{
entity.warmup = Mathf.lerp(entity.warmup, 0f, 0.02f);
warmup = Mathf.lerp(warmup, 0f, 0.02f);
}
if(entity.progress >= 1f){
entity.consume();
if(progress >= 1f){
consume();
if(outputItem != null){
useContent(tile, outputItem.item);
@@ -114,11 +111,11 @@ public class GenericCrafter extends Block{
handleLiquid(tile, tile, outputLiquid.liquid, outputLiquid.amount);
}
craftEffect.at(tile.drawx(), tile.drawy());
entity.progress = 0f;
craftEffect.at(x, y);
progress = 0f;
}
if(outputItem != null && tile.entity.timer(timerDump, dumpTime)){
if(outputItem != null && timer(timerDump, dumpTime)){
tryDump(tile, outputItem.item);
}
@@ -133,19 +130,19 @@ public class GenericCrafter extends Block{
}
@Override
public boolean shouldConsume(Tile tile){
if(outputItem != null && tile.entity.items().get(outputItem.item) >= itemCapacity){
public boolean shouldConsume(){
if(outputItem != null && tile.items.get(outputItem.item) >= itemCapacity){
return false;
}
return outputLiquid == null || !(tile.entity.liquids().get(outputLiquid.liquid) >= liquidCapacity - 0.001f);
return outputLiquid == null || !(tile.liquids.get(outputLiquid.liquid) >= liquidCapacity - 0.001f);
}
@Override
public int getMaximumAccepted(Tile tile, Item item){
public int getMaximumAccepted(Item item){
return itemCapacity;
}
public static class GenericCrafterEntity extends TileEntity{
public class GenericCrafterEntity extends TileEntity{
public float progress;
public float totalProgress;
public float warmup;

View File

@@ -26,32 +26,28 @@ public class GenericSmelter extends GenericCrafter{
@Override
public void draw(){
super.draw(tile);
GenericCrafterEntity entity = tile.ent();
super.draw();
//draw glowing center
if(entity.warmup > 0f && flameColor.a > 0.001f){
if(warmup > 0f && flameColor.a > 0.001f){
float g = 0.3f;
float r = 0.06f;
float cr = Mathf.random(0.1f);
Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * entity.warmup);
Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * warmup);
Draw.tint(flameColor);
Fill.circle(tile.drawx(), tile.drawy(), 3f + Mathf.absin(Time.time(), 5f, 2f) + cr);
Draw.color(1f, 1f, 1f, entity.warmup);
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Fill.circle(tile.drawx(), tile.drawy(), 1.9f + Mathf.absin(Time.time(), 5f, 1f) + cr);
Fill.circle(x, y, 3f + Mathf.absin(Time.time(), 5f, 2f) + cr);
Draw.color(1f, 1f, 1f, warmup);
Draw.rect(topRegion, x, y);
Fill.circle(x, y, 1.9f + Mathf.absin(Time.time(), 5f, 1f) + cr);
Draw.color();
}
}
@Override
public void drawLight(Tile tile){
GenericCrafterEntity entity = tile.ent();
renderer.lights.add(tile.drawx(), tile.drawy(), (60f + Mathf.absin(10f, 5f)) * entity.warmup * size, flameColor, 0.65f);
public void drawLight(){
renderer.lights.add(x, y, (60f + Mathf.absin(10f, 5f)) * warmup * size, flameColor, 0.65f);
}
}

View File

@@ -23,68 +23,61 @@ public class Incinerator extends Block{
hasLiquids = true;
update = true;
solid = true;
entityType = IncineratorEntity::new;
}
@Override
public void updateTile(){
IncineratorEntity entity = tile.ent();
if(entity.consValid()){
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.04f);
if(consValid()){
heat = Mathf.lerpDelta(heat, 1f, 0.04f);
}else{
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.02f);
heat = Mathf.lerpDelta(heat, 0f, 0.02f);
}
}
@Override
public void draw(){
super.draw(tile);
super.draw();
IncineratorEntity entity = tile.ent();
if(entity.heat > 0f){
if(heat > 0f){
float g = 0.3f;
float r = 0.06f;
Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * entity.heat);
Draw.alpha(((1f - g) + Mathf.absin(Time.time(), 8f, g) + Mathf.random(r) - r) * heat);
Draw.tint(flameColor);
Fill.circle(tile.drawx(), tile.drawy(), 2f);
Draw.color(1f, 1f, 1f, entity.heat);
Fill.circle(tile.drawx(), tile.drawy(), 1f);
Fill.circle(x, y, 2f);
Draw.color(1f, 1f, 1f, heat);
Fill.circle(x, y, 1f);
Draw.color();
}
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
public void handleItem(Tile source, Item item){
if(Mathf.chance(0.3)){
effect.at(tile.drawx(), tile.drawy());
effect.at(x, y);
}
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
IncineratorEntity entity = tile.ent();
return entity.heat > 0.5f;
public boolean acceptItem(Tile source, Item item){
return heat > 0.5f;
}
@Override
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
public void handleLiquid(Tile source, Liquid liquid, float amount){
if(Mathf.chance(0.02)){
effect.at(tile.drawx(), tile.drawy());
effect.at(x, y);
}
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
IncineratorEntity entity = tile.ent();
return entity.heat > 0.5f;
public boolean acceptLiquid(Tile source, Liquid liquid, float amount){
return heat > 0.5f;
}
public static class IncineratorEntity extends TileEntity{
public class IncineratorEntity extends TileEntity{
public float heat;
}
}

View File

@@ -33,26 +33,25 @@ public class LiquidConverter extends GenericCrafter{
}
@Override
public void drawLight(Tile tile){
public void drawLight(){
if(hasLiquids && drawLiquidLight && outputLiquid.liquid.lightColor.a > 0.001f){
drawLiquidLight(tile, outputLiquid.liquid, tile.entity.liquids().get(outputLiquid.liquid));
drawLiquidLight(tile, outputLiquid.liquid, tile.liquids.get(outputLiquid.liquid));
}
}
@Override
public void updateTile(){
GenericCrafterEntity entity = tile.ent();
ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid);
if(tile.entity.cons().valid()){
float use = Math.min(cl.amount * entity.delta(), liquidCapacity - entity.liquids().get(outputLiquid.liquid)) * entity.efficiency();
if(tile.cons().valid()){
float use = Math.min(cl.amount * delta(), liquidCapacity - liquids.get(outputLiquid.liquid)) * efficiency();
useContent(tile, outputLiquid.liquid);
entity.progress += use / cl.amount / craftTime;
entity.liquids().add(outputLiquid.liquid, use);
if(entity.progress >= 1f){
entity.consume();
entity.progress = 0f;
progress += use / cl.amount / craftTime;
liquids.add(outputLiquid.liquid, use);
if(progress >= 1f){
consume();
progress = 0f;
}
}

View File

@@ -46,11 +46,11 @@ public class Pump extends LiquidBlock{
@Override
public void draw(){
Draw.rect(name, tile.drawx(), tile.drawy());
Draw.rect(name, x, y);
Draw.color(tile.entity.liquids().current().color);
Draw.alpha(tile.entity.liquids().total() / liquidCapacity);
Draw.rect(liquidRegion, tile.drawx(), tile.drawy());
Draw.color(tile.liquids.current().color);
Draw.alpha(tile.liquids.total() / liquidCapacity);
Draw.rect(liquidRegion, x, y);
Draw.color();
}
@@ -85,7 +85,7 @@ public class Pump extends LiquidBlock{
}
@Override
public boolean canPlaceOn(Tile tile){
public boolean canPlaceOn(){
if(isMultiblock()){
Liquid last = null;
for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){
@@ -118,19 +118,19 @@ public class Pump extends LiquidBlock{
liquidDrop = tile.floor().liquidDrop;
}
if(tile.entity.cons().valid() && liquidDrop != null){
float maxPump = Math.min(liquidCapacity - tile.entity.liquids().total(), tiles * pumpAmount * tile.entity.delta() / size / size) * tile.entity.efficiency();
tile.entity.liquids().add(liquidDrop, maxPump);
if(tile.cons().valid() && liquidDrop != null){
float maxPump = Math.min(liquidCapacity - tile.liquids.total(), tiles * pumpAmount * tile.delta() / size / size) * tile.efficiency();
tile.liquids.add(liquidDrop, maxPump);
}
if(tile.entity.liquids().currentAmount() > 0f && tile.entity.timer(timerContentCheck, 10)){
useContent(tile, tile.entity.liquids().current());
if(tile.liquids.currentAmount() > 0f && timer(timerContentCheck, 10)){
useContent(tile, tile.liquids.current());
}
tryDumpLiquid(tile, tile.entity.liquids().current());
tryDumpLiquid(tile, tile.liquids.current());
}
protected boolean isValid(Tile tile){
protected boolean isValid(){
return tile != null && tile.floor().liquidDrop != null;
}

View File

@@ -30,7 +30,6 @@ public class Separator extends Block{
liquidRegion = reg("-liquid");
spinnerRegion = reg("-spinner");
entityType = GenericCrafterEntity::new;
}
@Override
@@ -53,41 +52,37 @@ public class Separator extends Block{
}
@Override
public boolean shouldConsume(Tile tile){
return tile.entity.items().total() < itemCapacity;
public boolean shouldConsume(){
return tile.items.total() < itemCapacity;
}
@Override
public void draw(){
super.draw(tile);
super.draw();
GenericCrafterEntity entity = tile.ent();
Draw.color(tile.entity.liquids().current().color);
Draw.alpha(tile.entity.liquids().total() / liquidCapacity);
Draw.rect(reg(liquidRegion), tile.drawx(), tile.drawy());
Draw.color(tile.liquids.current().color);
Draw.alpha(tile.liquids.total() / liquidCapacity);
Draw.rect(reg(liquidRegion), x, y);
Draw.reset();
if(Core.atlas.isFound(reg(spinnerRegion))){
Draw.rect(reg(spinnerRegion), tile.drawx(), tile.drawy(), entity.totalProgress * spinnerSpeed);
Draw.rect(reg(spinnerRegion), x, y, totalProgress * spinnerSpeed);
}
}
@Override
public void updateTile(){
GenericCrafterEntity entity = tile.ent();
totalProgress += warmup * delta();
entity.totalProgress += entity.warmup * entity.delta();
if(entity.consValid()){
entity.progress += getProgressIncrease(entity, craftTime);
entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f);
if(consValid()){
progress += getProgressIncrease(entity, craftTime);
warmup = Mathf.lerpDelta(warmup, 1f, 0.02f);
}else{
entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.02f);
warmup = Mathf.lerpDelta(warmup, 0f, 0.02f);
}
if(entity.progress >= 1f){
entity.progress = 0f;
if(progress >= 1f){
progress = 0f;
int sum = 0;
for(ItemStack stack : results) sum += stack.amount;
@@ -104,15 +99,15 @@ public class Separator extends Block{
count += stack.amount;
}
entity.consume();
consume();
if(item != null && entity.items().get(item) < itemCapacity){
if(item != null && items.get(item) < itemCapacity){
useContent(tile, item);
offloadNear(tile, item);
}
}
if(entity.timer(timerDump, dumpTime)){
if(timer(timerDump, dumpTime)){
tryDump(tile);
}
}

View File

@@ -31,7 +31,6 @@ public class SolidPump extends Pump{
public SolidPump(String name){
super(name);
hasPower = true;
entityType = SolidPumpEntity::new;
}
@Override
@@ -71,15 +70,13 @@ public class SolidPump extends Pump{
@Override
public void draw(){
SolidPumpEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.color(tile.entity.liquids().current().color);
Draw.alpha(tile.entity.liquids().total() / liquidCapacity);
Draw.rect(liquidRegion, tile.drawx(), tile.drawy());
Draw.rect(region, x, y);
Draw.color(tile.liquids.current().color);
Draw.alpha(tile.liquids.total() / liquidCapacity);
Draw.rect(liquidRegion, x, y);
Draw.color();
Draw.rect(name + "-rotator", tile.drawx(), tile.drawy(), entity.pumpTime * rotateSpeed);
Draw.rect(name + "-top", tile.drawx(), tile.drawy());
Draw.rect(name + "-rotator", x, y, pumpTime * rotateSpeed);
Draw.rect(name + "-top", x, y);
}
@Override
@@ -89,8 +86,6 @@ public class SolidPump extends Pump{
@Override
public void updateTile(){
SolidPumpEntity entity = tile.ent();
float fraction = 0f;
if(isMultiblock()){
@@ -103,28 +98,28 @@ public class SolidPump extends Pump{
if(isValid(tile)) fraction = 1f;
}
fraction += entity.boost;
fraction += boost;
if(tile.entity.cons().valid() && typeLiquid(tile) < liquidCapacity - 0.001f){
float maxPump = Math.min(liquidCapacity - typeLiquid(tile), pumpAmount * entity.delta() * fraction * entity.efficiency());
tile.entity.liquids().add(result, maxPump);
entity.lastPump = maxPump;
entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f);
if(tile.entity.timer(timerContentCheck, 10)) useContent(tile, result);
if(Mathf.chance(entity.delta() * updateEffectChance))
updateEffect.at(entity.getX() + Mathf.range(size * 2f), entity.getY() + Mathf.range(size * 2f));
if(tile.cons().valid() && typeLiquid(tile) < liquidCapacity - 0.001f){
float maxPump = Math.min(liquidCapacity - typeLiquid(tile), pumpAmount * delta() * fraction * efficiency());
tile.liquids.add(result, maxPump);
lastPump = maxPump;
warmup = Mathf.lerpDelta(warmup, 1f, 0.02f);
if(timer(timerContentCheck, 10)) useContent(tile, result);
if(Mathf.chance(delta() * updateEffectChance))
updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f));
}else{
entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.02f);
entity.lastPump = 0f;
warmup = Mathf.lerpDelta(warmup, 0f, 0.02f);
lastPump = 0f;
}
entity.pumpTime += entity.warmup * entity.delta();
pumpTime += warmup * delta();
tryDumpLiquid(tile, result);
}
@Override
public boolean canPlaceOn(Tile tile){
public boolean canPlaceOn(){
if(isMultiblock()){
for(Tile other : tile.getLinkedTilesAs(this, drawTiles)){
if(isValid(other)){
@@ -138,25 +133,24 @@ public class SolidPump extends Pump{
}
@Override
protected boolean isValid(Tile tile){
protected boolean isValid(){
return tile != null && !tile.floor().isLiquid;
}
@Override
public void onProximityAdded(Tile tile){
super.onProximityAdded(tile);
public void onProximityAdded(){
super.onProximityAdded();
if(attribute != null){
SolidPumpEntity entity = tile.ent();
entity.boost = sumAttribute(attribute, tile.x, tile.y);
boost = sumAttribute(attribute, tile.x, tile.y);
}
}
public float typeLiquid(Tile tile){
return tile.entity.liquids().total();
public float typeLiquid(){
return tile.liquids.total();
}
public static class SolidPumpEntity extends TileEntity{
public class SolidPumpEntity extends TileEntity{
public float warmup;
public float pumpTime;
public float boost;

View File

@@ -24,14 +24,12 @@ public class ItemSource extends Block{
solid = true;
group = BlockGroup.transportation;
configurable = true;
entityType = ItemSourceEntity::new;
config(Item.class, (tile, item) -> tile.<ItemSourceEntity>ent().outputItem = item);
config(Item.class, (tile, item) -> tile.<ItemSourceEntity>ent().outputItem = item);
configClear(tile -> tile.<ItemSourceEntity>ent().outputItem = null);
}
@Override
public void playerPlaced(Tile tile){
public void playerPlaced(){
if(lastItem != null){
Core.app.post(() -> tile.configure(lastItem));
}
@@ -55,34 +53,31 @@ public class ItemSource extends Block{
@Override
public void draw(){
super.draw(tile);
super.draw();
ItemSourceEntity entity = tile.ent();
if(entity.outputItem == null) return;
if(outputItem == null) return;
Draw.color(entity.outputItem.color);
Draw.color(outputItem.color);
Draw.rect("center", tile.worldx(), tile.worldy());
Draw.color();
}
@Override
public void updateTile(){
ItemSourceEntity entity = tile.ent();
if(entity.outputItem == null) return;
if(outputItem == null) return;
entity.items().set(entity.outputItem, 1);
tryDump(tile, entity.outputItem);
entity.items().set(entity.outputItem, 0);
items.set(outputItem, 1);
tryDump(tile, outputItem);
items.set(outputItem, 0);
}
@Override
public void buildConfiguration(Tile tile, Table table){
ItemSourceEntity entity = tile.ent();
ItemSelection.buildTable(table, content.items(), () -> entity.outputItem, item -> tile.configure(lastItem = item));
public void buildConfiguration(Table table){
ItemSelection.buildTable(table, content.items(), () -> outputItem, item -> tile.configure(lastItem = item));
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
public boolean acceptItem(Tile source, Item item){
return false;
}

View File

@@ -12,11 +12,11 @@ public class ItemVoid extends Block{
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
public void handleItem(Tile source, Item item){
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
public boolean acceptItem(Tile source, Item item){
return true;
}
}

View File

@@ -26,14 +26,12 @@ public class LiquidSource extends Block{
liquidCapacity = 100f;
configurable = true;
outputsLiquid = true;
entityType = LiquidSourceEntity::new;
config(Liquid.class, (tile, l) -> tile.<LiquidSourceEntity>ent().source = l);
config(Liquid.class, (tile, l) -> tile.<LiquidSourceEntity>ent().source = l);
configClear(tile -> tile.<LiquidSourceEntity>ent().source = null);
}
@Override
public void playerPlaced(Tile tile){
public void playerPlaced(){
if(lastLiquid != null){
Core.app.post(() -> tile.configure(lastLiquid));
}
@@ -48,13 +46,11 @@ public class LiquidSource extends Block{
@Override
public void updateTile(){
LiquidSourceEntity entity = tile.ent();
if(entity.source == null){
tile.entity.liquids().clear();
if(source == null){
tile.liquids.clear();
}else{
tile.entity.liquids().add(entity.source, liquidCapacity);
tryDumpLiquid(tile, entity.source);
tile.liquids.add(source, liquidCapacity);
tryDumpLiquid(tile, source);
}
}
@@ -65,22 +61,18 @@ public class LiquidSource extends Block{
@Override
public void draw(){
super.draw(tile);
super.draw();
LiquidSourceEntity entity = tile.ent();
if(entity.source != null){
Draw.color(entity.source.color);
if(source != null){
Draw.color(source.color);
Draw.rect("center", tile.worldx(), tile.worldy());
Draw.color();
}
}
@Override
public void buildConfiguration(Tile tile, Table table){
LiquidSourceEntity entity = tile.ent();
ItemSelection.buildTable(table, content.liquids(), () -> entity.source, liquid -> tile.configure(lastLiquid = liquid));
public void buildConfiguration(Table table){
ItemSelection.buildTable(table, content.liquids(), () -> source, liquid -> tile.configure(lastLiquid = liquid));
}
class LiquidSourceEntity extends TileEntity{

View File

@@ -19,11 +19,11 @@ public class LiquidVoid extends Block{
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
public boolean acceptLiquid(Tile source, Liquid liquid, float amount){
return true;
}
@Override
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){}
public void handleLiquid(Tile source, Liquid liquid, float amount){}
}

View File

@@ -13,7 +13,7 @@ public class PowerSource extends PowerNode{
}
@Override
public float getPowerProduction(Tile tile){
public float getPowerProduction(){
return 10000f;
}

View File

@@ -32,22 +32,20 @@ public class CoreBlock extends StorageBlock{
activeSound = Sounds.respawning;
activeSoundVolume = 1f;
layer = Layer.overlay;
entityType = CoreEntity::new;
}
@Remote(called = Loc.server)
public static void onUnitRespawn(Tile tile, Playerc player){
public static void onUnitRespawn(Playerc player){
if(player == null || tile.entity == null) return;
//TODO really fix
CoreEntity entity = tile.ent();
Fx.spawn.at(entity);
//entity.progress = 0;
//entity.spawnPlayer = player;
//progress = 0;
//spawnPlayer = player;
//TODO fix
//entity.spawnPlayer.onRespawn(tile);
//entity.spawnPlayer.applyImpulse(0, 8f);
//entity.spawnPlayer = null;
//spawnPlayer.onRespawn(tile);
//spawnPlayer.applyImpulse(0, 8f);
//spawnPlayer = null;
}
@Override
@@ -63,56 +61,53 @@ public class CoreBlock extends StorageBlock{
}
@Override
public void drawLight(Tile tile){
renderer.lights.add(tile.drawx(), tile.drawy(), 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f));
public void drawLight(){
renderer.lights.add(x, y, 30f * size, Pal.accent, 0.5f + Mathf.absin(20f, 0.1f));
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
return tile.entity.items().get(item) < getMaximumAccepted(tile, item);
public boolean acceptItem(Tile source, Item item){
return tile.items.get(item) < getMaximumAccepted(tile, item);
}
@Override
public int getMaximumAccepted(Tile tile, Item item){
CoreEntity entity = tile.ent();
return item.type == ItemType.material ? entity.storageCapacity : 0;
public int getMaximumAccepted(Item item){
return item.type == ItemType.material ? storageCapacity : 0;
}
@Override
public void onProximityUpdate(Tile tile){
CoreEntity entity = tile.ent();
for(Tilec other : state.teams.cores(tile.team())){
public void onProximityUpdate(){
for(Tilec other : state.teams.cores(team)){
if(other.tile() != tile){
entity.items(other.items());
items(other.items());
}
}
state.teams.registerCore(entity);
entity.storageCapacity = itemCapacity + entity.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
entity.proximity().each(this::isContainer, t -> {
t.entity.items(entity.items());
storageCapacity = itemCapacity + proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
proximity().each(this::isContainer, t -> {
t.items(items);
t.<StorageBlockEntity>ent().linkedCore = tile;
});
for(Tilec other : state.teams.cores(tile.team())){
for(Tilec other : state.teams.cores(team)){
if(other.tile() == tile) continue;
entity.storageCapacity += other.block().itemCapacity + other.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
storageCapacity += other.block().itemCapacity + other.proximity().sum(e -> isContainer(e) ? e.block().itemCapacity : 0);
}
if(!world.isGenerating()){
for(Item item : content.items()){
entity.items().set(item, Math.min(entity.items().get(item), entity.storageCapacity));
items.set(item, Math.min(items.get(item), storageCapacity));
}
}
for(CoreEntity other : state.teams.cores(tile.team())){
other.storageCapacity = entity.storageCapacity;
for(CoreEntity other : state.teams.cores(team)){
other.storageCapacity = storageCapacity;
}
}
@Override
public void drawSelect(Tile tile){
public void drawSelect(){
Lines.stroke(1f, Pal.accent);
Cons<Tile> outline = t -> {
for(int i = 0; i < 4; i++){
@@ -121,77 +116,73 @@ public class CoreBlock extends StorageBlock{
Draw.rect("block-select", t.drawx() + offset * p.x, t.drawy() + offset * p.y, i * 90);
}
};
if(tile.entity.proximity().contains(e -> isContainer(e) && e.entity.items() == tile.entity.items())){
if(tile.proximity().contains(e -> isContainer(e) && e.items == tile.items)){
outline.get(tile);
}
tile.entity.proximity().each(e -> isContainer(e) && e.entity.items() == tile.entity.items(), outline);
tile.proximity().each(e -> isContainer(e) && e.items == tile.items, outline);
Draw.reset();
}
public boolean isContainer(Tile tile){
public boolean isContainer(){
return tile.entity instanceof StorageBlockEntity;
}
@Override
public float handleDamage(Tile tile, float amount){
if(player != null && tile.team() == player.team()){
public float handleDamage(float amount){
if(player != null && team == player.team()){
Events.fire(Trigger.teamCoreDamage);
}
return amount;
}
@Override
public boolean canBreak(Tile tile){
public boolean canBreak(){
return false;
}
@Override
public void removed(Tile tile){
CoreEntity entity = tile.ent();
int total = tile.entity.proximity().count(e -> e.entity != null && e.entity.items() != null && e.entity.items() == tile.entity.items());
float fract = 1f / total / state.teams.cores(tile.team()).size;
public void removed(){
int total = tile.proximity().count(e -> e.entity != null && e.items != null && e.items == tile.items);
float fract = 1f / total / state.teams.cores(team).size;
tile.entity.proximity().each(e -> isContainer(e) && e.entity.items() == tile.entity.items(), t -> {
tile.proximity().each(e -> isContainer(e) && e.items == tile.items, t -> {
StorageBlockEntity ent = (StorageBlockEntity)t.entity;
ent.linkedCore = null;
ent.items(new ItemModule());
for(Item item : content.items()){
ent.items().set(item, (int)(fract * tile.entity.items().get(item)));
ent.items().set(item, (int)(fract * tile.items.get(item)));
}
});
state.teams.unregisterCore(entity);
int max = itemCapacity * state.teams.cores(tile.team()).size;
int max = itemCapacity * state.teams.cores(team).size;
for(Item item : content.items()){
tile.entity.items().set(item, Math.min(tile.entity.items().get(item), max));
tile.items.set(item, Math.min(tile.items.get(item), max));
}
for(CoreEntity other : state.teams.cores(tile.team())){
for(CoreEntity other : state.teams.cores(team)){
other.block().onProximityUpdate(other.tile());
}
}
@Override
public void placed(Tile tile){
super.placed(tile);
CoreEntity entity = tile.ent();
public void placed(){
super.placed();
state.teams.registerCore(entity);
}
@Override
public void drawLayer(Tile tile){
CoreEntity entity = tile.ent();
if(entity.heat > 0.001f){
public void drawLayer(){
if(heat > 0.001f){
//TODO implement
//RespawnBlock.drawRespawn(tile, entity.heat, entity.progress, entity.time, entity.spawnPlayer, mech);
//RespawnBlock.drawRespawn(tile, heat, progress, time, spawnPlayer, mech);
}
}
@Override
public void handleItem(Tile tile, Tile source, Item item){
public void handleItem(Tile source, Item item){
if(net.server() || !net.active()){
super.handleItem(tile, source, item);
if(state.rules.tutorial){
@@ -202,34 +193,30 @@ public class CoreBlock extends StorageBlock{
@Override
public void updateTile(){
CoreEntity entity = tile.ent();
//TODO implement
/*
if(entity.spawnPlayer != null){
if(!entity.spawnPlayer.dead() || !entity.spawnPlayer.isAdded()){
entity.spawnPlayer = null;
if(spawnPlayer != null){
if(!spawnPlayer.dead() || !spawnPlayer.isAdded()){
spawnPlayer = null;
return;
}
entity.spawnPlayer.set(tile.drawx(), tile.drawy());
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
entity.time += entity.delta();
entity.progress += 1f / state.rules.respawnTime * entity.delta();
spawnPlayer.set(x, y);
heat = Mathf.lerpDelta(heat, 1f, 0.1f);
time += delta();
progress += 1f / state.rules.respawnTime * delta();
if(entity.progress >= 1f){
Call.onUnitRespawn(tile, entity.spawnPlayer);
if(progress >= 1f){
Call.onUnitRespawn(tile, spawnPlayer);
}
}else{
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.1f);
heat = Mathf.lerpDelta(heat, 0f, 0.1f);
}*/
}
@Override
public boolean shouldActiveSound(Tile tile){
CoreEntity entity = tile.ent();
return entity.spawnPlayer != null;
public boolean shouldActiveSound(){
return spawnPlayer != null;
}
public class CoreEntity extends TileEntity{

View File

@@ -38,30 +38,30 @@ public class LaunchPad extends StorageBlock{
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
return item.type == ItemType.material && tile.entity.items().total() < itemCapacity;
public boolean acceptItem(Tile source, Item item){
return item.type == ItemType.material && tile.items.total() < itemCapacity;
}
@Override
public void draw(){
super.draw(tile);
super.draw();
//TODO broken
float progress = Mathf.clamp(Mathf.clamp((tile.entity.items().total() / (float)itemCapacity)) * ((tile.entity.timer().getTime(timerLaunch) / (launchTime / tile.entity.timeScale()))));
float progress = Mathf.clamp(Mathf.clamp((tile.items.total() / (float)itemCapacity)) * ((timer().getTime(timerLaunch) / (launchTime / tile.timeScale()))));
float scale = size / 3f;
Lines.stroke(2f);
Draw.color(Pal.accentBack);
Lines.poly(tile.drawx(), tile.drawy(), 4, scale * 10f * (1f - progress), 45 + 360f * progress);
Lines.poly(x, y, 4, scale * 10f * (1f - progress), 45 + 360f * progress);
Draw.color(Pal.accent);
if(tile.entity.cons().valid()){
if(tile.cons().valid()){
for(int i = 0; i < 3; i++){
float f = (Time.time() / 200f + i * 0.5f) % 1f;
Lines.stroke(((2f * (2f - Math.abs(0.5f - f) * 2f)) - 2f + 0.2f));
Lines.poly(tile.drawx(), tile.drawy(), 4, (1f - f) * 10f * scale);
Lines.poly(x, y, 4, (1f - f) * 10f * scale);
}
}
@@ -72,13 +72,13 @@ public class LaunchPad extends StorageBlock{
public void updateTile(){
Tilec entity = tile.entity;
if(state.isCampaign() && entity.consValid() && entity.items().total() >= itemCapacity && entity.timer(timerLaunch, launchTime / entity.timeScale())){
if(state.isCampaign() && consValid() && items.total() >= itemCapacity && timer(timerLaunch, launchTime / timeScale())){
for(Item item : Vars.content.items()){
Events.fire(Trigger.itemLaunch);
Fx.padlaunch.at(tile);
int used = Math.min(entity.items().get(item), itemCapacity);
int used = Math.min(items.get(item), itemCapacity);
data.addItem(item, used);
entity.items().remove(item, used);
items.remove(item, used);
Events.fire(new LaunchItemEvent(item, used));
}
}

View File

@@ -11,25 +11,22 @@ public abstract class StorageBlock extends Block{
public StorageBlock(String name){
super(name);
hasItems = true;
entityType = StorageBlockEntity::new;
}
@Override
public boolean acceptItem(Tile tile, Tile source, Item item){
StorageBlockEntity entity = tile.ent();
return entity.linkedCore != null ? entity.linkedCore.block().acceptItem(entity.linkedCore, source, item) : tile.entity.items().get(item) < getMaximumAccepted(tile, item);
public boolean acceptItem(Tile source, Item item){
return linkedCore != null ? linkedCore.block().acceptItem(linkedCore, source, item) : tile.items.get(item) < getMaximumAccepted(tile, item);
}
@Override
public int getMaximumAccepted(Tile tile, Item item){
public int getMaximumAccepted(Item item){
return itemCapacity;
}
@Override
public void drawSelect(Tile tile){
StorageBlockEntity entity = tile.ent();
if(entity.linkedCore != null){
entity.linkedCore.block().drawSelect(entity.linkedCore);
public void drawSelect(){
if(linkedCore != null){
linkedCore.block().drawSelect(linkedCore);
}
}
@@ -42,14 +39,14 @@ public abstract class StorageBlock extends Block{
* Removes an item and returns it. If item is not null, it should return the item.
* Returns null if no items are there.
*/
public Item removeItem(Tile tile, Item item){
public Item removeItem(Item item){
Tilec entity = tile.entity;
if(item == null){
return entity.items().take();
return items.take();
}else{
if(entity.items().has(item)){
entity.items().remove(item, 1);
if(items.has(item)){
items.remove(item, 1);
return item;
}
@@ -61,12 +58,12 @@ public abstract class StorageBlock extends Block{
* Returns whether this storage block has the specified item.
* If the item is null, it should return whether it has ANY items.
*/
public boolean hasItem(Tile tile, Item item){
public boolean hasItem(Item item){
Tilec entity = tile.entity;
if(item == null){
return entity.items().total() > 0;
return items.total() > 0;
}else{
return entity.items().has(item);
return items.has(item);
}
}

View File

@@ -26,10 +26,8 @@ public class Unloader extends Block{
health = 70;
hasItems = true;
configurable = true;
entityType = UnloaderEntity::new;
config(Item.class, (tile, item) -> {
tile.entity.items().clear();
config(Item.class, (tile, item) -> {
tile.items.clear();
tile.<UnloaderEntity>ent().sortItem = item;
});
@@ -42,7 +40,7 @@ public class Unloader extends Block{
}
@Override
public boolean canDump(Tile tile, Tile to, Item item){
public boolean canDump(Tile to, Item item){
return !(to.block() instanceof StorageBlock);
}
@@ -53,7 +51,7 @@ public class Unloader extends Block{
}
@Override
public void playerPlaced(Tile tile){
public void playerPlaced(){
if(lastItem != null){
tile.configure(lastItem);
}
@@ -61,18 +59,16 @@ public class Unloader extends Block{
@Override
public void updateTile(){
UnloaderEntity entity = tile.ent();
if(tile.entity.timer(timerUnload, speed / entity.timeScale()) && tile.entity.items().total() == 0){
for(Tile other : tile.entity.proximity()){
if(other.interactable(tile.team()) && other.block().unloadable && other.block().hasItems && entity.items().total() == 0 &&
((entity.sortItem == null && other.entity.items().total() > 0) || hasItem(other, entity.sortItem))){
offloadNear(tile, removeItem(other, entity.sortItem));
if(timer(timerUnload, speed / timeScale()) && tile.items.total() == 0){
for(Tile other : tile.proximity()){
if(other.interactable(team) && other.block().unloadable && other.block().hasItems && items.total() == 0 &&
((sortItem == null && other.items.total() > 0) || hasItem(other, sortItem))){
offloadNear(tile, removeItem(other, sortItem));
}
}
}
if(entity.items().total() > 0){
if(items.total() > 0){
tryDump(tile);
}
}
@@ -81,14 +77,14 @@ public class Unloader extends Block{
* Removes an item and returns it. If item is not null, it should return the item.
* Returns null if no items are there.
*/
private Item removeItem(Tile tile, Item item){
private Item removeItem(Item item){
Tilec entity = tile.entity;
if(item == null){
return entity.items().take();
return items.take();
}else{
if(entity.items().has(item)){
entity.items().remove(item, 1);
if(items.has(item)){
items.remove(item, 1);
return item;
}
@@ -100,32 +96,30 @@ public class Unloader extends Block{
* Returns whether this storage block has the specified item.
* If the item is null, it should return whether it has ANY items.
*/
private boolean hasItem(Tile tile, Item item){
private boolean hasItem(Item item){
Tilec entity = tile.entity;
if(item == null){
return entity.items().total() > 0;
return items.total() > 0;
}else{
return entity.items().has(item);
return items.has(item);
}
}
@Override
public void draw(){
super.draw(tile);
super.draw();
UnloaderEntity entity = tile.ent();
Draw.color(entity.sortItem == null ? Color.clear : entity.sortItem.color);
Draw.color(sortItem == null ? Color.clear : sortItem.color);
Draw.rect("unloader-center", tile.worldx(), tile.worldy());
Draw.color();
}
@Override
public void buildConfiguration(Tile tile, Table table){
public void buildConfiguration(Table table){
ItemSelection.buildTable(table, content.items(), () -> tile.<UnloaderEntity>ent().sortItem, item -> tile.configure(lastItem = item));
}
public static class UnloaderEntity extends TileEntity{
public class UnloaderEntity extends TileEntity{
public Item sortItem = null;
@Override

View File

@@ -34,44 +34,41 @@ public class CommandCenter extends Block{
destructible = true;
solid = true;
configurable = true;
entityType = CommandCenterEntity::new;
config(Integer.class, (tile, value) -> {
config(Integer.class, (tile, value) -> {
UnitCommand command = UnitCommand.all[value];
((CommandCenter)tile.block()).effect.at(tile);
for(Tile center : indexer.getAllied(tile.team(), BlockFlag.comandCenter)){
for(Tile center : indexer.getAllied(team, BlockFlag.comandCenter)){
if(center.block() instanceof CommandCenter){
CommandCenterEntity entity = center.ent();
entity.command = command;
command = command;
}
}
Groups.unit.each(t -> t.team() == tile.team(), u -> u.controller().command(command));
Groups.unit.each(t -> t.team() == team, u -> u.controller().command(command));
Events.fire(new CommandIssueEvent(tile, command));
});
}
@Override
public void placed(Tile tile){
super.placed(tile);
ObjectSet<Tile> set = indexer.getAllied(tile.team(), BlockFlag.comandCenter);
public void placed(){
super.placed();
ObjectSet<Tile> set = indexer.getAllied(team, BlockFlag.comandCenter);
if(set.size > 0){
CommandCenterEntity entity = tile.ent();
CommandCenterEntity oe = set.first().ent();
entity.command = oe.command;
CommandCenterEntity oe = set.first().ent();
command = oe.command;
}
}
@Override
public void removed(Tile tile){
super.removed(tile);
public void removed(){
super.removed();
ObjectSet<Tile> set = indexer.getAllied(tile.team(), BlockFlag.comandCenter);
ObjectSet<Tile> set = indexer.getAllied(team, BlockFlag.comandCenter);
if(set.size == 1){
Groups.unit.each(t -> t.team() == tile.team(), u -> u.controller().command(UnitCommand.all[0]));
Groups.unit.each(t -> t.team() == team, u -> u.controller().command(UnitCommand.all[0]));
}
}
@@ -88,31 +85,29 @@ public class CommandCenter extends Block{
@Override
public void draw(){
CommandCenterEntity entity = tile.ent();
super.draw(tile);
super.draw();
float size = 6f;
Draw.color(bottomColor);
Draw.rect(commandRegions[entity.command.ordinal()].getRegion(), tile.drawx(), tile.drawy() - 1, size, size);
Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y - 1, size, size);
Draw.color(topColor);
Draw.rect(commandRegions[entity.command.ordinal()].getRegion(), tile.drawx(), tile.drawy(), size, size);
Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y, size, size);
Draw.color();
}
@Override
public void buildConfiguration(Tile tile, Table table){
CommandCenterEntity entity = tile.ent();
public void buildConfiguration(Table table){
ButtonGroup<ImageButton> group = new ButtonGroup<>();
Table buttons = new Table();
for(UnitCommand cmd : UnitCommand.all){
buttons.addImageButton(commandRegions[cmd.ordinal()], Styles.clearToggleTransi, () -> tile.configure(cmd.ordinal()))
.size(44).group(group).update(b -> b.setChecked(entity.command == cmd));
.size(44).group(group).update(b -> b.setChecked(command == cmd));
}
table.add(buttons);
table.row();
table.label(() -> entity.command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center);
table.label(() -> command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center);
}
public class CommandCenterEntity extends TileEntity{

View File

@@ -31,7 +31,6 @@ public class MechPad extends Block{
hasPower = true;
layer = Layer.overlay;
flags = EnumSet.of(BlockFlag.mechPad);
entityType = MechFactoryEntity::new;
}
@Override
@@ -45,59 +44,52 @@ public class MechPad extends Block{
public static void onMechFactoryTap(Playerc player, Tile tile){
if(player == null || tile == null || !(tile.block() instanceof MechPad) || !checkValidTap(tile, player)) return;
MechFactoryEntity entity = tile.ent();
if(!entity.consValid()) return;
if(!consValid()) return;
//player.beginRespawning(entity);
entity.sameMech = false;
sameMech = false;
}
@Remote(called = Loc.server)
public static void onMechFactoryDone(Tile tile){
public static void onMechFactoryDone(){
if(!(tile.entity instanceof MechFactoryEntity)) return;
MechFactoryEntity entity = tile.ent();
Fx.spawn.at(entity);
if(entity.player == null) return;
if(player == null) return;
//Mech mech = ((MechPad)tile.block()).mech;
//boolean resetSpawner = !entity.sameMech && entity.player.mech == mech;
//entity.player.mech = !entity.sameMech && entity.player.mech == mech ? UnitTypes.starter : mech;
//boolean resetSpawner = !sameMech && player.mech == mech;
//player.mech = !sameMech && player.mech == mech ? UnitTypes.starter : mech;
Playerc player = entity.player;
Playerc player = player;
//entity.progress = 0;
//entity.player.onRespawn(tile);
//if(resetSpawner) entity.player.lastSpawner = null;
//entity.player = null;
//progress = 0;
//player.onRespawn(tile);
//if(resetSpawner) player.lastSpawner = null;
//player = null;
//Events.fire(new MechChangeEvent(player, player.mech));
}
protected static boolean checkValidTap(Tile tile, Playerc player){
MechFactoryEntity entity = tile.ent();
return false;//!player.dead() && tile.interactable(player.team()) && Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize &&
//Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize && entity.consValid() && entity.player == null;
protected static boolean checkValidTap(Playerc player){
return false;//!player.dead() && tile.interactable(player.team()) && Math.abs(player.x - x) <= tile.block().size * tilesize &&
//Math.abs(player.y - y) <= tile.block().size * tilesize && consValid() && player == null;
}
@Override
public void drawSelect(Tile tile){
public void drawSelect(){
Draw.color(Pal.accent);
for(int i = 0; i < 4; i++){
float length = tilesize * size / 2f + 3 + Mathf.absin(Time.time(), 5f, 2f);
Draw.rect("transfer-arrow", tile.drawx() + Geometry.d4[i].x * length, tile.drawy() + Geometry.d4[i].y * length, (i + 2) * 90);
Draw.rect("transfer-arrow", x + Geometry.d4[i].x * length, y + Geometry.d4[i].y * length, (i + 2) * 90);
}
Draw.color();
}
@Override
public void tapped(Tile tile, Playerc player){
MechFactoryEntity entity = tile.ent();
public void tapped(Playerc player){
if(checkValidTap(tile, player)){
Call.onMechFactoryTap(player, tile);
}else if(player.isLocal() && mobile && !player.dead() && entity.consValid() && entity.player == null){
}else if(player.isLocal() && mobile && !player.dead() && consValid() && player == null){
//deselect on double taps
//TODO remove
//player.moveTarget = player.moveTarget == tile.entity ? null : tile.entity;
@@ -105,31 +97,27 @@ public class MechPad extends Block{
}
@Override
public void drawLayer(Tile tile){
MechFactoryEntity entity = tile.ent();
if(entity.player != null){
public void drawLayer(){
if(player != null){
//TODO remove
//RespawnBlock.drawRespawn(tile, entity.heat, entity.progress, entity.time, entity.player, (!entity.sameMech && entity.player.mech == mech ? UnitTypes.starter : mech));
//RespawnBlock.drawRespawn(tile, heat, progress, time, player, (!sameMech && player.mech == mech ? UnitTypes.starter : mech));
}
}
@Override
public void updateTile(){
MechFactoryEntity entity = tile.ent();
if(player != null){
player.set(x, y);
heat = Mathf.lerpDelta(heat, 1f, 0.1f);
progress += 1f / buildTime * delta();
if(entity.player != null){
entity.player.set(tile.drawx(), tile.drawy());
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
entity.progress += 1f / buildTime * entity.delta();
time += 0.5f * delta();
entity.time += 0.5f * entity.delta();
if(entity.progress >= 1f){
if(progress >= 1f){
Call.onMechFactoryDone(tile);
}
}else{
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.1f);
heat = Mathf.lerpDelta(heat, 0f, 0.1f);
}
}

View File

@@ -37,7 +37,6 @@ public class RepairPoint extends Block{
layer2 = Layer.power;
hasPower = true;
outlineIcon = true;
entityType = RepairPointEntity::new;
}
@Override
@@ -62,8 +61,8 @@ public class RepairPoint extends Block{
}
@Override
public void drawSelect(Tile tile){
Drawf.dashCircle(tile.drawx(), tile.drawy(), repairRadius, Pal.accent);
public void drawSelect(){
Drawf.dashCircle(x, y, repairRadius, Pal.accent);
}
@Override
@@ -73,29 +72,25 @@ public class RepairPoint extends Block{
@Override
public void draw(){
Draw.rect(baseRegion, tile.drawx(), tile.drawy());
Draw.rect(baseRegion, x, y);
}
@Override
public void drawLayer(Tile tile){
RepairPointEntity entity = tile.ent();
Draw.rect(region, tile.drawx(), tile.drawy(), entity.rotation - 90);
public void drawLayer(){
Draw.rect(region, x, y, rotation - 90);
}
@Override
public void drawLayer2(Tile tile){
RepairPointEntity entity = tile.ent();
if(entity.target != null &&
Angles.angleDist(entity.angleTo(entity.target), entity.rotation) < 30f){
float ang = entity.angleTo(entity.target);
public void drawLayer2(){
if(target != null &&
Angles.angleDist(angleTo(target), rotation) < 30f){
float ang = angleTo(target);
float len = 5f;
Draw.color(Color.valueOf("e8ffd7"));
Drawf.laser(laser, laserEnd,
tile.drawx() + Angles.trnsx(ang, len), tile.drawy() + Angles.trnsy(ang, len),
entity.target.x(), entity.target.y(), entity.strength);
x + Angles.trnsx(ang, len), y + Angles.trnsy(ang, len),
target.x(), target.y(), strength);
Draw.color();
}
}
@@ -107,34 +102,30 @@ public class RepairPoint extends Block{
@Override
public void updateTile(){
RepairPointEntity entity = tile.ent();
boolean targetIsBeingRepaired = false;
if(entity.target != null && (entity.target.dead() || entity.target.dst(tile) > repairRadius || entity.target.health() >= entity.target.maxHealth())){
entity.target = null;
}else if(entity.target != null && entity.consValid()){
entity.target.heal(repairSpeed * Time.delta() * entity.strength * entity.efficiency());
entity.rotation = Mathf.slerpDelta(entity.rotation, entity.angleTo(entity.target), 0.5f);
if(target != null && (target.dead() || target.dst(tile) > repairRadius || target.health() >= target.maxHealth())){
target = null;
}else if(target != null && consValid()){
target.heal(repairSpeed * Time.delta() * strength * efficiency());
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.5f);
targetIsBeingRepaired = true;
}
if(entity.target != null && targetIsBeingRepaired){
entity.strength = Mathf.lerpDelta(entity.strength, 1f, 0.08f * Time.delta());
if(target != null && targetIsBeingRepaired){
strength = Mathf.lerpDelta(strength, 1f, 0.08f * Time.delta());
}else{
entity.strength = Mathf.lerpDelta(entity.strength, 0f, 0.07f * Time.delta());
strength = Mathf.lerpDelta(strength, 0f, 0.07f * Time.delta());
}
if(entity.timer(timerTarget, 20)){
rect.setSize(repairRadius * 2).setCenter(tile.drawx(), tile.drawy());
entity.target = Units.closest(tile.team(), tile.drawx(), tile.drawy(), repairRadius, Unitc::damaged);
if(timer(timerTarget, 20)){
rect.setSize(repairRadius * 2).setCenter(x, y);
target = Units.closest(team, x, y, repairRadius, Unitc::damaged);
}
}
@Override
public boolean shouldConsume(Tile tile){
RepairPointEntity entity = tile.ent();
return entity.target != null;
public boolean shouldConsume(){
return target != null;
}
public class RepairPointEntity extends TileEntity{

View File

@@ -13,19 +13,19 @@ import static mindustry.Vars.net;
//TODO remove ?
public class RespawnBlock{
public static void drawRespawn(Tile tile, float heat, float progress, float time, Playerc player, UnitType to){
public static void drawRespawn(float heat, float progress, float time, Playerc player, UnitType to){
progress = Mathf.clamp(progress);
Draw.color(Pal.darkMetal);
Lines.stroke(2f * heat);
Fill.poly(tile.drawx(), tile.drawy(), 4, 10f * heat);
Fill.poly(x, y, 4, 10f * heat);
Draw.reset();
if(player != null){
TextureRegion region = to.icon(Cicon.full);
Draw.color(0f, 0f, 0f, 0.4f * progress);
Draw.rect("circle-shadow", tile.drawx(), tile.drawy(), region.getWidth() / 3f, region.getWidth() / 3f);
Draw.rect("circle-shadow", x, y, region.getWidth() / 3f, region.getWidth() / 3f);
Draw.color();
Shaders.build.region = region;
@@ -34,14 +34,14 @@ public class RespawnBlock{
Shaders.build.time = -time / 10f;
Draw.shader(Shaders.build, true);
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.rect(region, x, y);
Draw.shader();
Draw.color(Pal.accentBack);
float pos = Mathf.sin(time, 6f, 8f);
Lines.lineAngleCenter(tile.drawx() + pos, tile.drawy(), 90, 16f - Math.abs(pos) * 2f);
Lines.lineAngleCenter(x + pos, y, 90, 16f - Math.abs(pos) * 2f);
Draw.reset();
}
@@ -49,26 +49,26 @@ public class RespawnBlock{
Lines.stroke(2f * heat);
Draw.color(Pal.accentBack);
Lines.poly(tile.drawx(), tile.drawy(), 4, 8f * heat);
Lines.poly(x, y, 4, 8f * heat);
float oy = -7f, len = 6f * heat;
Lines.stroke(5f);
Draw.color(Pal.darkMetal);
Lines.line(tile.drawx() - len, tile.drawy() + oy, tile.drawx() + len, tile.drawy() + oy, CapStyle.none);
Lines.line(x - len, y + oy, x + len, y + oy, CapStyle.none);
for(int i : Mathf.signs){
Fill.tri(tile.drawx() + len * i, tile.drawy() + oy - Lines.getStroke()/2f, tile.drawx() + len * i, tile.drawy() + oy + Lines.getStroke()/2f, tile.drawx() + (len + Lines.getStroke() * heat) * i, tile.drawy() + oy);
Fill.tri(x + len * i, y + oy - Lines.getStroke()/2f, x + len * i, y + oy + Lines.getStroke()/2f, x + (len + Lines.getStroke() * heat) * i, y + oy);
}
Lines.stroke(3f);
Draw.color(Pal.accent);
Lines.line(tile.drawx() - len, tile.drawy() + oy, tile.drawx() - len + len*2 * progress, tile.drawy() + oy, CapStyle.none);
Lines.line(x - len, y + oy, x - len + len*2 * progress, y + oy, CapStyle.none);
for(int i : Mathf.signs){
Fill.tri(tile.drawx() + len * i, tile.drawy() + oy - Lines.getStroke()/2f, tile.drawx() + len * i, tile.drawy() + oy + Lines.getStroke()/2f, tile.drawx() + (len + Lines.getStroke() * heat) * i, tile.drawy() + oy);
Fill.tri(x + len * i, y + oy - Lines.getStroke()/2f, x + len * i, y + oy + Lines.getStroke()/2f, x + (len + Lines.getStroke() * heat) * i, y + oy);
}
Draw.reset();
if(net.active() && player != null){
tile.block().drawPlaceText(player.name(), tile.x, tile.y - (Math.max((tile.block().size-1)/2, 0)), true);
tile.drawPlaceText(player.name(), tile.x, tile.y - (Math.max((tile.block().size-1)/2, 0)), true);
}
}
}

View File

@@ -37,25 +37,23 @@ public class UnitFactory extends Block{
hasItems = true;
solid = false;
flags = EnumSet.of(BlockFlag.producer);
entityType = UnitFactoryEntity::new;
}
@Remote(called = Loc.server)
public static void onUnitFactorySpawn(Tile tile, int spawns){
public static void onUnitFactorySpawn(int spawns){
if(!(tile.entity instanceof UnitFactoryEntity) || !(tile.block() instanceof UnitFactory)) return;
UnitFactoryEntity entity = tile.ent();
UnitFactory factory = (UnitFactory)tile.block();
entity.buildTime = 0f;
entity.spawned = spawns;
buildTime = 0f;
spawned = spawns;
Effects.shake(2f, 3f, entity);
Fx.producesmoke.at(tile.drawx(), tile.drawy());
Fx.producesmoke.at(x, y);
if(!net.client()){
Unitc unit = factory.unitType.create(tile.team());
unit.set(tile.drawx() + Mathf.range(4), tile.drawy() + Mathf.range(4));
Unitc unit = factory.unitType.create(team);
unit.set(x + Mathf.range(4), y + Mathf.range(4));
unit.add();
unit.vel().y = factory.launchVelocity;
Events.fire(new UnitCreateEvent(unit));
@@ -104,10 +102,9 @@ public class UnitFactory extends Block{
}
@Override
public void unitRemoved(Tile tile, Unitc unit){
UnitFactoryEntity entity = tile.ent();
entity.spawned--;
entity.spawned = Math.max(entity.spawned, 0);
public void unitRemoved(Unitc unit){
spawned--;
spawned = Math.max(spawned, 0);
}
@Override
@@ -117,73 +114,69 @@ public class UnitFactory extends Block{
@Override
public void draw(){
UnitFactoryEntity entity = tile.ent();
TextureRegion region = unitType.icon(Cicon.full);
Draw.rect(name, tile.drawx(), tile.drawy());
Draw.rect(name, x, y);
Shaders.build.region = region;
Shaders.build.progress = entity.buildTime / produceTime;
Shaders.build.progress = buildTime / produceTime;
Shaders.build.color.set(Pal.accent);
Shaders.build.color.a = entity.speedScl;
Shaders.build.time = -entity.time / 20f;
Shaders.build.color.a = speedScl;
Shaders.build.time = -time / 20f;
Draw.shader(Shaders.build);
Draw.rect(region, tile.drawx(), tile.drawy());
Draw.rect(region, x, y);
Draw.shader();
Draw.color(Pal.accent);
Draw.alpha(entity.speedScl);
Draw.alpha(speedScl);
Lines.lineAngleCenter(
tile.drawx() + Mathf.sin(entity.time, 20f, Vars.tilesize / 2f * size - 2f),
tile.drawy(),
x + Mathf.sin(time, 20f, Vars.tilesize / 2f * size - 2f),
y,
90,
size * Vars.tilesize - 4f);
Draw.reset();
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Draw.rect(topRegion, x, y);
}
@Override
public void updateTile(){
UnitFactoryEntity entity = tile.ent();
if(entity.spawned >= maxSpawn){
if(spawned >= maxSpawn){
return;
}
if(entity.consValid() || tile.isEnemyCheat()){
entity.time += entity.delta() * entity.speedScl * Vars.state.rules.unitBuildSpeedMultiplier * entity.efficiency();
entity.buildTime += entity.delta() * entity.efficiency() * Vars.state.rules.unitBuildSpeedMultiplier;
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.05f);
if(consValid() || tile.isEnemyCheat()){
time += delta() * speedScl * Vars.state.rules.unitBuildSpeedMultiplier * efficiency();
buildTime += delta() * efficiency() * Vars.state.rules.unitBuildSpeedMultiplier;
speedScl = Mathf.lerpDelta(speedScl, 1f, 0.05f);
}else{
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 0f, 0.05f);
speedScl = Mathf.lerpDelta(speedScl, 0f, 0.05f);
}
if(entity.buildTime >= produceTime){
entity.buildTime = 0f;
if(buildTime >= produceTime){
buildTime = 0f;
Call.onUnitFactorySpawn(tile, entity.spawned + 1);
Call.onUnitFactorySpawn(tile, spawned + 1);
useContent(tile, unitType);
entity.consume();
consume();
}
}
@Override
public int getMaximumAccepted(Tile tile, Item item){
public int getMaximumAccepted(Item item){
return capacities[item.id];
}
@Override
public boolean shouldConsume(Tile tile){
UnitFactoryEntity entity = tile.ent();
return entity.spawned < maxSpawn;
public boolean shouldConsume(){
return spawned < maxSpawn;
}
public static class UnitFactoryEntity extends TileEntity{
public class UnitFactoryEntity extends TileEntity{
float buildTime;
float time;
float speedScl;