Merge branch 'crater' of https://github.com/Quezler/Mindustry into Quezler-crater
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
BIN
core/assets-raw/sprites/ui/crater.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
|
|
@ -958,6 +958,7 @@ block.hail.name = Hail
|
|||
block.lancer.name = Lancer
|
||||
block.conveyor.name = Conveyor
|
||||
block.titanium-conveyor.name = Titanium Conveyor
|
||||
block.plastanium-conveyor.name = Plastanium Conveyor
|
||||
block.armored-conveyor.name = Armored Conveyor
|
||||
block.armored-conveyor.description = Moves items at the same speed as titanium conveyors, but possesses more armor. Does not accept inputs from the sides from anything but other conveyor belts.
|
||||
block.junction.name = Junction
|
||||
|
|
@ -1193,6 +1194,7 @@ block.force-projector.description = Creates a hexagonal force field around itsel
|
|||
block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy.
|
||||
block.conveyor.description = Basic item transport block. Moves items forward and automatically deposits them into blocks. Rotatable.
|
||||
block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors.
|
||||
block.plastanium-conveyor.description = The \uf818 moves items in batches.\nOnly accepts items at the back.\nLoads & unloads on all 3 sides.
|
||||
block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations.
|
||||
block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building.
|
||||
block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles.
|
||||
|
|
|
|||
|
|
@ -228,3 +228,5 @@
|
|||
63516=legacy-command-center|block-legacy-command-center-medium
|
||||
63515=block-forge|block-block-forge-medium
|
||||
63514=block-launcher|block-block-launcher-medium
|
||||
63513=plastanium-conveyor|block-plastanium-conveyor-medium
|
||||
63512=crater|crater
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 717 B |
|
Before Width: | Height: | Size: 761 KiB After Width: | Height: | Size: 762 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 279 KiB After Width: | Height: | Size: 828 KiB |
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 252 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 821 KiB After Width: | Height: | Size: 226 KiB |
|
|
@ -57,8 +57,8 @@ public class Blocks implements ContentList{
|
|||
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
|
||||
|
||||
//transport
|
||||
conveyor, titaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router, overflowGate,
|
||||
underflowGate, massDriver, massConveyor,
|
||||
conveyor, titaniumConveyor, plastaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router,
|
||||
overflowGate, underflowGate, massDriver, massConveyor,
|
||||
|
||||
//liquid
|
||||
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
|
||||
|
|
@ -910,6 +910,13 @@ public class Blocks implements ContentList{
|
|||
displayedSpeed = 10f;
|
||||
}};
|
||||
|
||||
plastaniumConveyor = new CraterConveyor("plastanium-conveyor"){{
|
||||
requirements(Category.distribution, ItemStack.with(Items.plastanium, 1, Items.silicon, 1, Items.graphite, 1));
|
||||
health = 75;
|
||||
speed = 0.04f;
|
||||
recharge = 4f;
|
||||
}};
|
||||
|
||||
armoredConveyor = new ArmoredConveyor("armored-conveyor"){{
|
||||
requirements(Category.distribution, ItemStack.with(Items.plastanium, 1, Items.thorium, 1, Items.metaglass, 1));
|
||||
health = 180;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ public class TechTree implements ContentList{
|
|||
});
|
||||
});
|
||||
|
||||
node(plastaniumConveyor, () -> {
|
||||
|
||||
});
|
||||
|
||||
node(armoredConveyor, () -> {
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||
}
|
||||
|
||||
public void dumpLiquid(Liquid liquid){
|
||||
int dump = rotation();
|
||||
int dump = rotation() / block.dumpIncrement;
|
||||
|
||||
for(int i = 0; i < proximity.size; i++){
|
||||
incrementDump(proximity.size);
|
||||
|
|
@ -455,7 +455,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||
*/
|
||||
public void offloadNear(Item item){
|
||||
Array<Tilec> proximity = proximity();
|
||||
int dump = rotation();
|
||||
int dump = rotation() / block.dumpIncrement;
|
||||
useContent(item);
|
||||
|
||||
for(int i = 0; i < proximity.size; i++){
|
||||
|
|
@ -483,7 +483,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||
if(!block.hasItems || items.total() == 0 || (todump != null && !items.has(todump))) return false;
|
||||
|
||||
Array<Tilec> proximity = proximity();
|
||||
int dump = rotation();
|
||||
int dump = rotation() / block.dumpIncrement;
|
||||
|
||||
if(proximity.size == 0) return false;
|
||||
|
||||
|
|
@ -518,7 +518,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||
}
|
||||
|
||||
public void incrementDump(int prox){
|
||||
rotation((byte)((rotation() + 1) % prox));
|
||||
rotation((byte)((rotation() + block.dumpIncrement) % (prox * block.dumpIncrement)));
|
||||
}
|
||||
|
||||
/** Used for dumping items. */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public class Block extends UnlockableContent{
|
|||
public int itemCapacity = 10;
|
||||
public float liquidCapacity = 10f;
|
||||
public float liquidPressure = 1f;
|
||||
public int dumpIncrement = 1;
|
||||
|
||||
public final BlockStats stats = new BlockStats();
|
||||
public final BlockBars bars = new BlockBars();
|
||||
|
|
|
|||
|
|
@ -49,8 +49,10 @@ public class Conveyor extends Block implements Autotiler{
|
|||
@Override
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
|
||||
//have to add a custom calculated speed, since the actual movement speed is apparently not linear
|
||||
stats.add(BlockStat.itemsMoved, displayedSpeed, StatUnit.itemsSecond);
|
||||
stats.add(BlockStat.boostEffect, "$blocks.itemsmoved");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
279
core/src/mindustry/world/blocks/distribution/CraterConveyor.java
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
package mindustry.world.blocks.distribution;
|
||||
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class CraterConveyor extends Block implements Autotiler{
|
||||
private TextureRegion[] regions = new TextureRegion[8];
|
||||
|
||||
public float speed = 0f;
|
||||
public float recharge = 4f;
|
||||
|
||||
public CraterConveyor(String name){
|
||||
super(name);
|
||||
|
||||
rotate = true;
|
||||
update = true;
|
||||
group = BlockGroup.transportation;
|
||||
hasItems = true;
|
||||
itemCapacity = 8;
|
||||
conveyorPlacement = true;
|
||||
entityType = CraterConveyorEntity::new;
|
||||
|
||||
idleSound = Sounds.conveyor;
|
||||
idleSoundVolume = 0.004f;
|
||||
unloadable = false;
|
||||
dumpIncrement = 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
for(int i = 0; i < regions.length; i++){
|
||||
regions[i] = Core.atlas.find(name + "-" + i + "-" + 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion[] generateIcons(){
|
||||
return new TextureRegion[]{Core.atlas.find(name + "-0-0")};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStats(){
|
||||
super.setStats();
|
||||
|
||||
stats.add(BlockStat.itemsMoved, speed * 60, StatUnit.perSecond);
|
||||
stats.add(BlockStat.boostEffect, "$blocks.itemcapacity");
|
||||
}
|
||||
|
||||
@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) && otherblock instanceof CraterConveyor; // blend with nothing but crater conveyors
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRequestRegion(BuildRequest req, Eachable<BuildRequest> list){
|
||||
int[] bits = getTiling(req, list);
|
||||
|
||||
if(bits == null) return;
|
||||
|
||||
TextureRegion region = regions[bits[0]];
|
||||
Draw.rect(region, req.drawx(), req.drawy(), region.getWidth() * bits[1] * Draw.scl * req.animScale, region.getHeight() * bits[2] * Draw.scl * req.animScale, req.rotation * 90);
|
||||
}
|
||||
|
||||
class CraterConveyorEntity extends TileEntity{
|
||||
|
||||
int blendbit1, blendbit2;
|
||||
int blendsclx, blendscly;
|
||||
|
||||
int link = -1;
|
||||
float cooldown;
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(regions[Mathf.clamp(blendbit1, 0, regions.length - 1)], x, y, tilesize * blendsclx, tilesize * blendscly, rotation() * 90);
|
||||
if(blendbit2 != 0) Draw.rect(regions[Mathf.clamp(blendbit2, 0, regions.length - 1)], x, y, tilesize * blendsclx, tilesize * blendscly, rotation() * 90);;
|
||||
|
||||
Draw.z(Layer.blockOver);
|
||||
|
||||
if(link == -1) return;
|
||||
|
||||
// offset
|
||||
Tile from = world.tile(link);
|
||||
Tmp.v1.set(from);
|
||||
Tmp.v2.set(tile);
|
||||
Tmp.v1.interpolate(Tmp.v2, 1f - cooldown, Interpolation.linear);
|
||||
|
||||
// fixme
|
||||
float a = (from.rotation()%4) * 90;
|
||||
float b = (tile.rotation()%4) * 90;
|
||||
if((from.rotation()%4) == 3 && (tile.rotation()%4) == 0) a = -1 * 90;
|
||||
if((from.rotation()%4) == 0 && (tile.rotation()%4) == 3) a = 4 * 90;
|
||||
|
||||
// crater
|
||||
Draw.rect(regions[7], Tmp.v1.x, Tmp.v1.y, Mathf.lerp(a, b, Interpolation.smooth.apply(1f - Mathf.clamp(cooldown * 2, 0f, 1f))));
|
||||
|
||||
// item
|
||||
float size = itemSize * Mathf.lerp(Math.min((float)items.total() / itemCapacity, 1), 1f, 0.4f);
|
||||
Drawf.shadow(Tmp.v1.x, Tmp.v1.y, size * 1.2f);
|
||||
Draw.rect(items.first().icon(Cicon.medium), Tmp.v1.x, Tmp.v1.y, size, size, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProximityUpdate(){
|
||||
super.onProximityUpdate();
|
||||
|
||||
int[] bits = buildBlending(tile, tile.rotation(), null, true);
|
||||
|
||||
blendbit2 = 0;
|
||||
if(bits[0] == 0 && blends(tile, tile.rotation(), 0) && !blends(tile, tile.rotation(), 2)) blendbit2 = 5; // a 0 that faces into a crater conveyor with none behind it
|
||||
if(bits[0] == 0 && !blends(tile, tile.rotation(), 0) && blends(tile, tile.rotation(), 2)) blendbit2 = 6; // a 0 that faces into none with a crater conveyor behind it
|
||||
|
||||
blendbit1 = bits[0];
|
||||
blendsclx = bits[1];
|
||||
blendscly = bits[2];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
// reel in crater
|
||||
if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed, 0f, recharge);
|
||||
|
||||
// sleep when idle
|
||||
if(link == -1){
|
||||
if(cooldown == 0f) sleep();
|
||||
return;
|
||||
}
|
||||
|
||||
// crater needs to be centered
|
||||
if(cooldown > 0f) return;
|
||||
|
||||
if(blendbit2 == 6){
|
||||
while(dump()) if(items.total() == 0) poofOut();
|
||||
}
|
||||
|
||||
/* unload */ else /* transfer */
|
||||
|
||||
if(blendbit2 != 5 || (items.total() >= getMaximumAccepted(items.first()))){
|
||||
if(front() != null
|
||||
&& front().team() == team()
|
||||
&& front().block() instanceof CraterConveyor){
|
||||
CraterConveyorEntity e = (CraterConveyorEntity)tile.front();
|
||||
|
||||
// sleep if its occupied
|
||||
if(e.link != -1){
|
||||
sleep();
|
||||
}else{
|
||||
e.items.addAll(items);
|
||||
e.link = tile.pos();
|
||||
// ▲ new | old ▼
|
||||
link = -1;
|
||||
items.clear();
|
||||
|
||||
cooldown = recharge;
|
||||
e.cooldown = 1;
|
||||
e.noSleep();
|
||||
bump();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaximumAccepted(Item item){
|
||||
return Mathf.round(super.getMaximumAccepted(item) * timeScale); // increased item capacity while boosted
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIdleSound(){
|
||||
return false; // has no moving parts;
|
||||
}
|
||||
|
||||
private void poofIn(){
|
||||
link = tile.pos();
|
||||
Fx.plasticburn.at(this);
|
||||
tile.entity.noSleep();
|
||||
}
|
||||
|
||||
private void poofOut(){
|
||||
Fx.plasticburn.at(this);
|
||||
link = -1;
|
||||
bump();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleItem(Tilec source, Item item){
|
||||
if(items.total() == 0) poofIn();
|
||||
super.handleItem(source, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStack(Item item, int amount, Teamc source){
|
||||
if(items.total() == 0) poofIn();
|
||||
super.handleStack(item, amount, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeStack(Item item, int amount){
|
||||
try{
|
||||
return super.removeStack(item, amount);
|
||||
}finally{
|
||||
if(items.total() == 0) poofOut();
|
||||
}
|
||||
}
|
||||
|
||||
// crater conveyor tiles that input into this one
|
||||
private void upstream(Cons<CraterConveyorEntity> cons){
|
||||
|
||||
if(blendbit1 == 0 && !(back() instanceof CraterConveyorEntity)) return;
|
||||
|
||||
if( blendbit1 == 0 // 1 input from the back, 0 from the sides
|
||||
|| blendbit1 == 2 // 1 input from the back, 1 from the sides
|
||||
|| blendbit1 == 3 // 1 input from the back, 2 from the sides
|
||||
) cons.get((CraterConveyorEntity)back());
|
||||
|
||||
if( blendbit1 == 3 // 1 input from the back, 2 from the sides
|
||||
|| blendbit1 == 4 // 0 input from the back, 2 from the sides
|
||||
||(blendbit1 == 1 && blendscly == -1) // side is open
|
||||
||(blendbit1 == 2 && blendscly == +1) // side is open
|
||||
) cons.get((CraterConveyorEntity)right());
|
||||
|
||||
if( blendbit1 == 3 // 1 input from the back, 2 from the sides
|
||||
|| blendbit1 == 4 // 0 input from the back, 2 from the sides
|
||||
||(blendbit1 == 1 && blendscly == +1) // side is open
|
||||
||(blendbit1 == 2 && blendscly == -1) // side is open
|
||||
) cons.get((CraterConveyorEntity)left());
|
||||
}
|
||||
|
||||
// awaken inputting conveyors
|
||||
private void bump(){
|
||||
upstream(t -> {
|
||||
if(t == null || !t.sleeping || t.items().total() <= 0) return;
|
||||
t.noSleep();
|
||||
t.bump();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptItem(Tilec source, Item item){
|
||||
if (this == source) return true; // player threw items
|
||||
if (cooldown > recharge - 1f) return false; // still cooling down
|
||||
return!((blendbit2 != 5) // not a loading dock
|
||||
|| (items.total() > 0 && !items.has(item)) // incompatible items
|
||||
|| (items.total() >= getMaximumAccepted(item)) // filled to capacity
|
||||
|| (tile.front() == source));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Writes write){
|
||||
super.write(write);
|
||||
|
||||
write.i(link);
|
||||
write.f(cooldown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Reads read, byte revision){
|
||||
super.read(read, revision);
|
||||
|
||||
link = read.i();
|
||||
cooldown = read.f();
|
||||
}
|
||||
}
|
||||
}
|
||||