Added many new block types, changed land unit AI, bugfixes

This commit is contained in:
Anuken
2018-03-26 20:26:36 -04:00
parent f049706539
commit 707e57e72d
83 changed files with 1054 additions and 672 deletions

View File

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 199 B

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 228 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 257 B

View File

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 243 B

View File

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 225 B

View File

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

View File

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 159 B

View File

Before

Width:  |  Height:  |  Size: 256 B

After

Width:  |  Height:  |  Size: 256 B

View File

Before

Width:  |  Height:  |  Size: 613 B

After

Width:  |  Height:  |  Size: 613 B

View File

Before

Width:  |  Height:  |  Size: 196 B

After

Width:  |  Height:  |  Size: 196 B

View File

Before

Width:  |  Height:  |  Size: 188 B

After

Width:  |  Height:  |  Size: 188 B

View File

Before

Width:  |  Height:  |  Size: 296 B

After

Width:  |  Height:  |  Size: 296 B

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 219 B

View File

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

View File

Before

Width:  |  Height:  |  Size: 226 B

After

Width:  |  Height:  |  Size: 226 B

View File

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 276 B

View File

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 248 B

View File

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 234 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 168 B

After

Width:  |  Height:  |  Size: 168 B

View File

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

View File

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

View File

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

View File

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

View File

Before

Width:  |  Height:  |  Size: 310 B

After

Width:  |  Height:  |  Size: 310 B

View File

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 306 B

View File

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -1,7 +1,7 @@
#Autogenerated file. Do not modify. #Autogenerated file. Do not modify.
#Sun Mar 25 23:37:47 EDT 2018 #Mon Mar 26 20:24:57 EDT 2018
version=release version=release
androidBuildCode=657 androidBuildCode=662
name=Mindustry name=Mindustry
code=3.4 code=3.4
build=custom build build=custom build

View File

@@ -53,17 +53,18 @@ public class Recipes {
new Recipe(weapon, WeaponBlocks.missileturret, stack(Items.steel, 70), stack(Items.titanium, 50), stack(Items.densealloy, 55)), new Recipe(weapon, WeaponBlocks.missileturret, stack(Items.steel, 70), stack(Items.titanium, 50), stack(Items.densealloy, 55)),
new Recipe(weapon, WeaponBlocks.fornaxcannon, stack(Items.steel, 70), stack(Items.titanium, 50), stack(Items.densealloy, 55)), new Recipe(weapon, WeaponBlocks.fornaxcannon, stack(Items.steel, 70), stack(Items.titanium, 50), stack(Items.densealloy, 55)),
new Recipe(crafting, ProductionBlocks.smelter, stack(Items.iron, 40)), new Recipe(crafting, CraftingBlocks.smelter, stack(Items.iron, 40)),
new Recipe(crafting, ProductionBlocks.alloysmelter, stack(Items.titanium, 50), stack(Items.steel, 50)), new Recipe(crafting, CraftingBlocks.alloysmelter, stack(Items.titanium, 50), stack(Items.steel, 50)),
new Recipe(crafting, ProductionBlocks.coalextractor, stack(Items.steel, 10), stack(Items.iron, 10)), new Recipe(crafting, CraftingBlocks.powersmelter, stack(Items.steel, 30), stack(Items.iron, 30)),
new Recipe(crafting, ProductionBlocks.titaniumextractor, stack(Items.steel, 30), stack(Items.iron, 30)), new Recipe(crafting, CraftingBlocks.extractor, stack(Items.steel, 10), stack(Items.iron, 10)),
new Recipe(crafting, ProductionBlocks.oilrefinery, stack(Items.steel, 15), stack(Items.iron, 15)), new Recipe(crafting, CraftingBlocks.separator, stack(Items.steel, 30), stack(Items.iron, 30)),
new Recipe(crafting, ProductionBlocks.stoneformer, stack(Items.steel, 10), stack(Items.iron, 10)), new Recipe(crafting, CraftingBlocks.centrifuge, stack(Items.steel, 30), stack(Items.iron, 30)),
new Recipe(crafting, ProductionBlocks.lavasmelter, stack(Items.steel, 30), stack(Items.titanium, 15)), new Recipe(crafting, CraftingBlocks.oilRefinery, stack(Items.steel, 15), stack(Items.iron, 15)),
new Recipe(crafting, ProductionBlocks.siliconextractor, stack(Items.steel, 30), stack(Items.titanium, 15)), new Recipe(crafting, CraftingBlocks.biomassCompressor, stack(Items.steel, 15), stack(Items.iron, 15)),
new Recipe(crafting, ProductionBlocks.cryofluidmixer, stack(Items.steel, 30), stack(Items.titanium, 15)), new Recipe(crafting, CraftingBlocks.stoneFormer, stack(Items.steel, 10), stack(Items.iron, 10)),
new Recipe(crafting, ProductionBlocks.weaponFactory, stack(Items.steel, 60), stack(Items.iron, 60)).setDesktop(), new Recipe(crafting, CraftingBlocks.plasticFormer, stack(Items.steel, 30), stack(Items.titanium, 15)),
//new Recipe(crafting, ProductionBlocks.centrifuge, stack(Item.steel, 30), stack(Item.iron, 30)), new Recipe(crafting, CraftingBlocks.cryofluidmixer, stack(Items.steel, 30), stack(Items.titanium, 15)),
new Recipe(crafting, CraftingBlocks.weaponFactory, stack(Items.steel, 60), stack(Items.iron, 60)).setDesktop(),
//new Recipe(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)), //new Recipe(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)),
new Recipe(production, ProductionBlocks.irondrill, stack(Items.iron, 25)), new Recipe(production, ProductionBlocks.irondrill, stack(Items.iron, 25)),
@@ -106,6 +107,9 @@ public class Recipes {
new Recipe(liquid, LiquidBlocks.fluxpump, stack(Items.steel, 10), stack(Items.densealloy, 5)), new Recipe(liquid, LiquidBlocks.fluxpump, stack(Items.steel, 10), stack(Items.densealloy, 5)),
new Recipe(units, UnitBlocks.flierFactory, stack(Items.steel, 10)), new Recipe(units, UnitBlocks.flierFactory, stack(Items.steel, 10)),
new Recipe(units, UnitBlocks.walkerFactory, stack(Items.steel, 10)),
new Recipe(units, DebugBlocks.itemSource, stack(Items.steel, 10)).setDebug(),
new Recipe(units, DebugBlocks.powerVoid, stack(Items.steel, 10)).setDebug(), new Recipe(units, DebugBlocks.powerVoid, stack(Items.steel, 10)).setDebug(),
new Recipe(units, DebugBlocks.powerInfinite, stack(Items.steel, 10), stack(Items.densealloy, 5)).setDebug() new Recipe(units, DebugBlocks.powerInfinite, stack(Items.steel, 10), stack(Items.densealloy, 5)).setDebug()
); );

View File

@@ -0,0 +1,150 @@
package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.production.*;
public class CraftingBlocks {
public static final Block
smelter = new Smelter("smelter") {{
health = 70;
inputs = new Item[]{Items.iron};
fuel = Items.coal;
result = Items.steel;
craftTime = 25f;
}},
alloysmelter = new Smelter("alloysmelter") {{
health = 90;
inputs = new Item[]{Items.titanium, Items.steel};
fuel = Items.coal;
result = Items.densealloy;
burnDuration = 45f;
craftTime = 25f;
}},
powersmelter = new PowerSmelter("powersmelter") {{
health = 90;
inputs = new ItemStack[]{new ItemStack(Items.titanium, 4), new ItemStack(Items.thorium, 4)};
result = Items.densealloy;
burnDuration = 45f;
craftTime = 25f;
size = 2;
}},
cryofluidmixer = new LiquidMixer("cryofluidmixer") {{
health = 200;
inputLiquid = Liquids.water;
outputLiquid = Liquids.cryofluid;
inputItem = Items.titanium;
liquidPerItem = 50f;
itemCapacity = 50;
powerUse = 0.1f;
size = 2;
}},
//TODO implement melter
melter = new LiquidMixer("melter") {{
health = 200;
inputLiquid = Liquids.water;
outputLiquid = Liquids.cryofluid;
inputItem = Items.titanium;
liquidPerItem = 50f;
itemCapacity = 50;
powerUse = 0.1f;
size = 2;
}},
separator = new Filtrator("separator") {{
liquid = Liquids.water;
item = Items.stone;
results = new Item[]{
null, null, null, null, null,
Items.stone, Items.stone, Items.stone, Items.stone,
Items.iron, Items.iron, Items.iron,
Items.lead, Items.lead,
Items.coal, Items.coal,
Items.titanium
};
liquidUse = 0.1f;
filterTime = 40f;
health = 50;
}},
extractor = new GenericCrafter("extractor") {{
inputItem = new ItemStack(Items.stone, 6);
inputLiquid = Liquids.water;
liquidUse = 0.1f;
output = Items.coal;
health = 50;
craftTime = 50;
hasInventory = hasLiquids = true;
}},
centrifuge = new GenericCrafter("centrifuge") {{
inputItem = new ItemStack(Items.stone, 6);
inputLiquid = Liquids.water;
liquidUse = 0.1f;
output = Items.coal;
health = 50;
craftTime = 50;
hasInventory = hasLiquids = true;
size = 2;
}},
plasticFormer = new GenericCrafter("plasticformer") {{
inputLiquid = Liquids.oil;
liquidUse = 0.1f;
liquidCapacity = 60f;
powerUse = 0.05f;
craftTime = 70f;
output = Items.plastic;
size = 2;
health = 320;
hasPower = hasLiquids = true;
}},
biomassCompressor = new PowerCrafter("biomasscompressor") {{
input = new ItemStack(Items.biomatter, 1);
liquidCapacity = 60f;
powerUse = 0.05f;
craftTime = 10f;
outputLiquid = Liquids.oil;
outputLiquidAmount = 0.4f;
size = 2;
health = 320;
hasLiquids = true;
}},
oilRefinery = new GenericCrafter("oilrefinery") {{
inputLiquid = Liquids.oil;
liquidUse = 0.1f;
liquidCapacity = 56f;
output = Items.coal;
health = 80;
craftEffect = Fx.purifyoil;
hasInventory = hasLiquids = true;
}},
stoneFormer = new GenericCrafter("stoneformer") {{
inputLiquid = Liquids.lava;
liquidUse = 0.1f;
liquidCapacity = 21f;
craftTime = 12;
output = Items.stone;
health = 80;
craftEffect = Fx.purifystone;
}},
weaponFactory = new WeaponFactory("weaponfactory") {{
size = 2;
health = 250;
}};
}

View File

@@ -1,8 +1,10 @@
package io.anuke.mindustry.content.blocks; package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock; import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.mindustry.world.blocks.types.distribution.Sorter;
import io.anuke.mindustry.world.blocks.types.power.PowerDistributor; import io.anuke.mindustry.world.blocks.types.power.PowerDistributor;
public class DebugBlocks { public class DebugBlocks {
@@ -24,5 +26,19 @@ public class DebugBlocks {
super.update(tile); super.update(tile);
tile.entity.power.amount = powerCapacity; tile.entity.power.amount = powerCapacity;
} }
},
itemSource = new Sorter("itemsource"){
@Override
public void update(Tile tile) {
SorterEntity entity = tile.entity();
entity.inventory.items[entity.sortItem.id] = 1;
tryDump(tile, entity.sortItem);
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
return false;
}
}; };
} }

View File

@@ -2,118 +2,14 @@ package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.production.*; import io.anuke.mindustry.world.blocks.types.production.Drill;
import io.anuke.mindustry.world.blocks.types.production.GenericDrill;
import io.anuke.mindustry.world.blocks.types.production.SolidPump;
public class ProductionBlocks { public class ProductionBlocks {
public static final Block public static final Block
smelter = new Smelter("smelter") {{
health = 70;
inputs = new Item[]{Items.iron};
fuel = Items.coal;
result = Items.steel;
craftTime = 25f;
}},
alloysmelter = new Smelter("alloysmelter") {{
health = 90;
inputs = new Item[]{Items.titanium, Items.steel};
fuel = Items.coal;
result = Items.densealloy;
burnDuration = 45f;
craftTime = 25f;
}},
powersmelter = new PowerSmelter("powersmelter") {{
/*
health = 90;
inputs = new Item[]{Item.titanium, Item.steel};
fuel = Item.coal;
results = Item.dirium;
burnDuration = 45f;
craftTime = 25f;
size = 2;*/
}},
cryofluidmixer = new LiquidMixer("cryofluidmixer") {{
health = 200;
inputLiquid = Liquids.water;
outputLiquid = Liquids.cryofluid;
inputItem = Items.titanium;
liquidPerItem = 50f;
itemCapacity = 50;
powerUse = 0.1f;
size = 2;
}},
coalextractor = new LiquidCrafter("coalextractor") {{
input = Items.stone;
inputAmount = 6;
inputLiquid = Liquids.water;
liquidAmount = 19f;
output = Items.coal;
health = 50;
purifyTime = 50;
health = 60;
}},
titaniumextractor = new LiquidCrafter("titaniumextractor") {{
input = Items.stone;
inputAmount = 8;
inputLiquid = Liquids.water;
liquidAmount = 40f;
liquidCapacity = 41f;
purifyTime = 60;
output = Items.titanium;
health = 70;
}},
oilrefinery = new LiquidCrafter("oilrefinery") {{
inputLiquid = Liquids.oil;
liquidAmount = 55f;
liquidCapacity = 56f;
purifyTime = 65;
output = Items.coal;
health = 80;
craftEffect = Fx.purifyoil;
}},
stoneformer = new LiquidCrafter("stoneformer") {{
input = null;
inputLiquid = Liquids.lava;
liquidAmount = 16f;
liquidCapacity = 21f;
purifyTime = 12;
output = Items.stone;
health = 80;
craftEffect = Fx.purifystone;
}},
lavasmelter = new LiquidCrafter("lavasmelter") {{
input = Items.iron;
inputAmount = 1;
inputLiquid = Liquids.lava;
liquidAmount = 40f;
liquidCapacity = 41f;
purifyTime = 30;
output = Items.steel;
health = 80;
craftEffect = Fx.purifystone;
}},
siliconextractor = new LiquidCrafter("siliconextractor") {{
input = Items.stone;
inputAmount = 5;
inputLiquid = Liquids.water;
liquidAmount = 18.99f;
output = Items.silicon;
health = 50;
purifyTime = 50;
}},
stonedrill = new Drill("stonedrill") {{ stonedrill = new Drill("stonedrill") {{
resource = Blocks.stone; resource = Blocks.stone;
result = Items.stone; result = Items.stone;
@@ -206,10 +102,5 @@ public class ProductionBlocks {
size = 2; size = 2;
hasLiquids = true; hasLiquids = true;
hasPower = true; hasPower = true;
}},
weaponFactory = new WeaponFactory("weaponfactory") {{
size = 2;
health = 250;
}}; }};
} }

View File

@@ -16,5 +16,14 @@ public class UnitBlocks {
requirements = new ItemStack[]{ requirements = new ItemStack[]{
new ItemStack(Items.stone, 5) new ItemStack(Items.stone, 5)
}; };
}},
walkerFactory = new UnitFactory("walkerfactory"){{
type = UnitTypes.scout;
produceTime = 20;
size = 2;
requirements = new ItemStack[]{
new ItemStack(Items.stone, 1)
};
}}; }};
} }

View File

@@ -27,6 +27,7 @@ public class ContentLoader {
new StorageBlocks(), new StorageBlocks(),
new UnitBlocks(), new UnitBlocks(),
new PowerBlocks(), new PowerBlocks(),
new CraftingBlocks(),
//items //items
new Items(), new Items(),

View File

@@ -32,12 +32,12 @@ public class NetCommon extends Module {
Net.handle(BlockTapPacket.class, (packet) -> { Net.handle(BlockTapPacket.class, (packet) -> {
Tile tile = world.tile(packet.position); Tile tile = world.tile(packet.position);
tile.block().tapped(tile); threads.run(() -> tile.block().tapped(tile));
}); });
Net.handle(BlockConfigPacket.class, (packet) -> { Net.handle(BlockConfigPacket.class, (packet) -> {
Tile tile = world.tile(packet.position); Tile tile = world.tile(packet.position);
if (tile != null) tile.block().configure(tile, packet.data); if (tile != null) threads.run(() -> tile.block().configure(tile, packet.data));
}); });
} }

View File

@@ -192,7 +192,7 @@ public class NetServer extends Module{
Recipe recipe = Recipes.getByResult(block); Recipe recipe = Recipes.getByResult(block);
if(recipe == null) return; if(recipe == null || recipe.debugOnly != debug) return;
state.inventory.removeItems(recipe.requirements); state.inventory.removeItems(recipe.requirements);

View File

@@ -2,20 +2,17 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.ai.Pathfind; import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.blocks.ProductionBlocks;
import io.anuke.mindustry.io.Map; import io.anuke.mindustry.io.Map;
import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.io.MapIO;
import io.anuke.mindustry.io.Maps; import io.anuke.mindustry.io.Maps;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.WorldGenerator; import io.anuke.mindustry.world.WorldGenerator;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.blocks.ProductionBlocks;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.modules.Module; import io.anuke.ucore.modules.Module;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
@@ -199,40 +196,6 @@ public class World extends Module{
} }
} }
public TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){
Entity closest = null;
float dst = 0;
int rad = (int)(range/tilesize)+1;
int tilex = Mathf.scl2(x, tilesize);
int tiley = Mathf.scl2(y, tilesize);
for(int rx = -rad; rx <= rad; rx ++){
for(int ry = -rad; ry <= rad; ry ++){
Tile other = tile(rx+tilex, ry+tiley);
if(other != null && other.getLinked() != null){
other = other.getLinked();
}
if(other == null || other.entity == null || (tile != null && other.entity == tile.entity)) continue;
TileEntity e = other.entity;
if(damaged && e.health >= e.tile.block().health)
continue;
float ndst = Vector2.dst(x, y, e.x, e.y);
if(ndst < range && (closest == null || ndst < dst)){
dst = ndst;
closest = e;
}
}
}
return (TileEntity) closest;
}
/**Raycast, but with world coordinates.*/ /**Raycast, but with world coordinates.*/
public GridPoint2 raycastWorld(float x, float y, float x2, float y2){ public GridPoint2 raycastWorld(float x, float y, float x2, float y2){
return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize), return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize),

View File

@@ -2,7 +2,6 @@ package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import io.anuke.mindustry.io.MapTileData; import io.anuke.mindustry.io.MapTileData;
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -15,7 +14,7 @@ public class DrawOperation implements Disposable{
* packed data TO (use TileDataMarker's read/write methods) * packed data TO (use TileDataMarker's read/write methods)
*/ */
ByteBuffer operation; ByteBuffer operation;
TileDataMarker writer = new TileDataMarker(); //TileDataMarker writer = new TileDataMarker();
public DrawOperation(MapTileData data){ public DrawOperation(MapTileData data){
this.data = data; this.data = data;

View File

@@ -35,10 +35,10 @@ public class MapRenderer {
} }
} }
chunks = new IndexedRenderer[width/chunksize][height/chunksize]; chunks = new IndexedRenderer[(int)Math.ceil((float)width/chunksize)][(int)Math.ceil((float)height/chunksize )];
for(int x = 0; x < width/chunksize; x ++){ for(int x = 0; x < chunks.length; x ++){
for(int y = 0; y < height/chunksize; y ++){ for(int y = 0; y < chunks[0].length; y ++){
chunks[x][y] = new IndexedRenderer(chunksize*chunksize*2); chunks[x][y] = new IndexedRenderer(chunksize*chunksize*2);
} }
} }
@@ -60,8 +60,8 @@ public class MapRenderer {
} }
updates.clear(); updates.clear();
for(int x = 0; x < width/chunksize; x ++){ for(int x = 0; x < chunks.length; x ++){
for(int y = 0; y < height/chunksize; y ++){ for(int y = 0; y < chunks[0].length; y ++){
IndexedRenderer mesh = chunks[x][y]; IndexedRenderer mesh = chunks[x][y];
mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize), mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize),

View File

@@ -5,10 +5,13 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ObjectSet; import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate; import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -16,6 +19,43 @@ import static io.anuke.mindustry.Vars.*;
public class Units { public class Units {
private static Rectangle rect = new Rectangle(); private static Rectangle rect = new Rectangle();
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return findTile(x, y, range, tile -> !state.teams.areEnemies(team, tile.getTeam()) && pred.test(tile));
}
public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return findTile(x, y, range, tile -> state.teams.areEnemies(team, tile.getTeam()) && pred.test(tile));
}
public static TileEntity findTile(float x, float y, float range, Predicate<Tile> pred){
Entity closest = null;
float dst = 0;
int rad = (int)(range/tilesize)+1;
int tilex = Mathf.scl2(x, tilesize);
int tiley = Mathf.scl2(y, tilesize);
for(int rx = -rad; rx <= rad; rx ++){
for(int ry = -rad; ry <= rad; ry ++){
Tile other = world.tile(rx+tilex, ry+tiley);
if(other != null) other = other.target();
if(other == null || other.entity == null || !pred.test(other)) continue;
TileEntity e = other.entity;
float ndst = Vector2.dst(x, y, e.x, e.y);
if(ndst < range && (closest == null || ndst < dst)){
dst = ndst;
closest = e;
}
}
}
return (TileEntity) closest;
}
/**Iterates over all units on all teams, including players.*/ /**Iterates over all units on all teams, including players.*/
public static void allUnits(Consumer<Unit> cons){ public static void allUnits(Consumer<Unit> cons){
//check all unit groups first //check all unit groups first

View File

@@ -4,7 +4,6 @@ import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -35,7 +34,6 @@ public class BaseUnit extends Unit {
@Override @Override
public void move(float x, float y){ public void move(float x, float y){
walkTime += Timers.delta();
baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed); baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed);
super.move(x, y); super.move(x, y);
} }

View File

@@ -53,6 +53,7 @@ public class FlyingUnitType extends UnitType {
vec.set(unit.target.x - unit.x, unit.target.y - unit.y); vec.set(unit.target.x - unit.x, unit.target.y - unit.y);
float ang = vec.angle(); float ang = vec.angle();
float len = vec.len();
float circleLength = 40f; float circleLength = 40f;
@@ -64,7 +65,7 @@ public class FlyingUnitType extends UnitType {
unit.velocity.add(vec); //TODO clamp it so it doesn't glitch out at low fps unit.velocity.add(vec); //TODO clamp it so it doesn't glitch out at low fps
if(unit.timer.get(timerReload, reload)){ if(unit.timer.get(timerReload, reload) && len < range){
shoot(unit, BulletType.shot, ang, 4f); shoot(unit, BulletType.shot, ang, 4f);
} }
} }

View File

@@ -1,25 +1,45 @@
package io.anuke.mindustry.entities.units; package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator; import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.state;
public abstract class GroundUnitType extends UnitType{ public abstract class GroundUnitType extends UnitType{
//only use for drawing! //only use for drawing!
protected Translator tr1 = new Translator(); protected Translator tr1 = new Translator();
//only use for updating! //only use for updating!
protected Translator tr2 = new Translator(); protected Translator tr2 = new Translator();
protected float stopDistance = 30f;
public GroundUnitType(String name) { public GroundUnitType(String name) {
super(name); super(name);
maxVelocity = 2f;
speed = 0.05f;
}
@Override
public void update(BaseUnit unit) {
super.update(unit);
unit.rotation = unit.velocity.angle();
} }
@Override @Override
public void draw(BaseUnit unit) { public void draw(BaseUnit unit) {
Draw.alpha(unit.hitTime / Unit.hitDuration); Draw.alpha(unit.hitTime / Unit.hitDuration);
float walktime = unit.walkTime; //TODO! float walktime = unit.walkTime;
float ft = Mathf.sin(walktime, 6f, 2f); float ft = Mathf.sin(walktime, 6f, 2f);
@@ -36,10 +56,50 @@ public abstract class GroundUnitType extends UnitType{
} }
@Override @Override
public void behavior(BaseUnit unit) { public void updateTargeting(BaseUnit unit) {
tr2.set(unit.target.x, unit.target.y).sub(unit.x, unit.y).limit(speed); if(!unit.timer.get(timerTarget, 20)) return;
unit.move(tr2.x, tr2.y); unit.target = Units.findEnemyTile(unit.team, unit.x, unit.y, range, t -> true);
unit.rotate(tr2.angle());
if(unit.target != null) return;
ObjectSet<TeamData> teams = state.teams.enemyDataOf(unit.team);
Tile closest = null;
float cdist = 0f;
for(TeamData data : teams){
for(Tile tile : data.cores){
float dist = Vector2.dst(unit.x, unit.y, tile.drawx(), tile.drawy());
if(closest == null || dist < cdist){
closest = tile;
cdist = dist;
}
}
}
if(closest != null){
unit.target = closest.entity;
}else{
unit.target = null;
}
}
@Override
public void behavior(BaseUnit unit) {
//TODO actually pathfind
tr2.set(unit.target.x, unit.target.y).sub(unit.x, unit.y);
if(tr2.len() > stopDistance){
tr2.limit(speed);
unit.walkTime += Timers.delta();
unit.velocity.add(tr2);
}
if(unit.timer.get(timerReload, reload)){
shoot(unit, BulletType.shot, tr2.angle(), 4f);
}
} }
} }

View File

@@ -75,8 +75,12 @@ public abstract class UnitType {
//TODO logic //TODO logic
unit.velocity.limit(maxVelocity); unit.velocity.limit(maxVelocity);
unit.x += unit.velocity.x / mass; if(isFlying) {
unit.y += unit.velocity.y / mass; unit.x += unit.velocity.x / mass;
unit.y += unit.velocity.y / mass;
}else{
unit.move(unit.velocity.x / mass, unit.velocity.y / mass);
}
unit.velocity.scl(Mathf.clamp(1f-drag* Timers.delta())); unit.velocity.scl(Mathf.clamp(1f-drag* Timers.delta()));

View File

@@ -0,0 +1,12 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.FlyingUnitType;
public class Drone extends FlyingUnitType {
public Drone(String name) {
super(name);
}
}

View File

@@ -546,7 +546,7 @@ public class Tutorial{
canBack = false; canBack = false;
blockPlaceX = 0; blockPlaceX = 0;
blockPlaceY = -7; blockPlaceY = -7;
targetBlock = ProductionBlocks.smelter; //targetBlock = ProductionBlocks.smelter;
} }
void onSwitch(){ void onSwitch(){

View File

@@ -4,13 +4,14 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.utils.IntIntMap;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectMap.Entry; import com.badlogic.gdx.utils.ObjectMap.Entry;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.io.MapTileData.TileDataMarker; import io.anuke.mindustry.io.MapTileData.TileDataMarker;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.ColorMapper;
import io.anuke.mindustry.world.ColorMapper.BlockPair; import io.anuke.mindustry.world.ColorMapper.BlockPair;
import io.anuke.mindustry.content.blocks.Blocks;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -25,6 +26,14 @@ import static io.anuke.mindustry.Vars.mapExtension;
//TODO map header that maps block names to IDs for backwards compatibility //TODO map header that maps block names to IDs for backwards compatibility
public class MapIO { public class MapIO {
private static final int version = 0; private static final int version = 0;
private static final IntIntMap defaultBlockMap = new IntIntMap();
static{
for(Block block : Block.getAllBlocks()){
defaultBlockMap.put(block.id, block.id);
}
}
public static Pixmap generatePixmap(MapTileData data){ public static Pixmap generatePixmap(MapTileData data){
Pixmap pixmap = new Pixmap(data.width(), data.height(), Format.RGBA8888); Pixmap pixmap = new Pixmap(data.width(), data.height(), Format.RGBA8888);
@@ -69,7 +78,7 @@ public class MapIO {
} }
public static void writeMap(FileHandle file, ObjectMap<String, String> tags, MapTileData data) throws IOException{ public static void writeMap(FileHandle file, ObjectMap<String, String> tags, MapTileData data) throws IOException{
MapMeta meta = new MapMeta(version, tags, data.width(), data.height()); MapMeta meta = new MapMeta(version, tags, data.width(), data.height(), defaultBlockMap);
DataOutputStream ds = new DataOutputStream(file.write(false)); DataOutputStream ds = new DataOutputStream(file.write(false));
@@ -82,16 +91,14 @@ public class MapIO {
/**Reads tile data, skipping meta.*/ /**Reads tile data, skipping meta.*/
public static MapTileData readTileData(DataInputStream stream) throws IOException { public static MapTileData readTileData(DataInputStream stream) throws IOException {
MapMeta meta = readMapMeta(stream); MapMeta meta = readMapMeta(stream);
byte[] bytes = new byte[stream.available()]; return readTileData(stream, meta);
stream.read(bytes);
return new MapTileData(bytes, meta.width, meta.height);
} }
/**Does not skip meta. Call after reading meta.*/ /**Does not skip meta. Call after reading meta.*/
public static MapTileData readTileData(DataInputStream stream, MapMeta meta) throws IOException { public static MapTileData readTileData(DataInputStream stream, MapMeta meta) throws IOException {
byte[] bytes = new byte[stream.available()]; byte[] bytes = new byte[stream.available()];
stream.read(bytes); stream.read(bytes);
return new MapTileData(bytes, meta.width, meta.height); return new MapTileData(bytes, meta.width, meta.height, meta.blockMap);
} }
/**Reads tile data, skipping meta tags.*/ /**Reads tile data, skipping meta tags.*/
@@ -116,6 +123,7 @@ public class MapIO {
public static MapMeta readMapMeta(DataInputStream stream) throws IOException{ public static MapMeta readMapMeta(DataInputStream stream) throws IOException{
ObjectMap<String, String> tags = new ObjectMap<>(); ObjectMap<String, String> tags = new ObjectMap<>();
IntIntMap map = new IntIntMap();
int version = stream.readInt(); int version = stream.readInt();
@@ -127,10 +135,17 @@ public class MapIO {
tags.put(name, value); tags.put(name, value);
} }
short blocks = stream.readShort();
for(int i = 0; i < blocks; i ++){
Block block = Block.getByName(stream.readUTF());
if(block == null) block = Blocks.air;
map.put(stream.readShort(), block.id);
}
int width = stream.readShort(); int width = stream.readShort();
int height = stream.readShort(); int height = stream.readShort();
return new MapMeta(version, tags, width, height); return new MapMeta(version, tags, width, height, map);
} }
public static void writeMapMeta(DataOutputStream stream, MapMeta meta) throws IOException{ public static void writeMapMeta(DataOutputStream stream, MapMeta meta) throws IOException{
@@ -142,6 +157,12 @@ public class MapIO {
stream.writeUTF(entry.value); stream.writeUTF(entry.value);
} }
stream.writeShort(Block.getAllBlocks().size);
for(Block block : Block.getAllBlocks()){
stream.writeShort(block.id);
stream.writeUTF(block.name);
}
stream.writeShort(meta.width); stream.writeShort(meta.width);
stream.writeShort(meta.height); stream.writeShort(meta.height);
} }

View File

@@ -1,17 +1,20 @@
package io.anuke.mindustry.io; package io.anuke.mindustry.io;
import com.badlogic.gdx.utils.IntIntMap;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
public class MapMeta { public class MapMeta {
public final int version; public final int version;
public final ObjectMap<String, String> tags; public final ObjectMap<String, String> tags;
public final int width, height; public final int width, height;
public final IntIntMap blockMap;
public MapMeta(int version, ObjectMap<String, String> tags, int width, int height) { public MapMeta(int version, ObjectMap<String, String> tags, int width, int height, IntIntMap blockMap) {
this.version = version; this.version = version;
this.tags = tags; this.tags = tags;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.blockMap = blockMap;
} }
public String author(){ public String author(){

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.io; package io.anuke.mindustry.io;
import com.badlogic.gdx.utils.IntIntMap;
import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.Bits;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -15,16 +16,20 @@ public class MapTileData {
private final TileDataMarker tile = new TileDataMarker(); private final TileDataMarker tile = new TileDataMarker();
private final int width, height; private final int width, height;
private final IntIntMap map;
public MapTileData(int width, int height){ public MapTileData(int width, int height){
this.width = width; this.width = width;
this.height = height; this.height = height;
this.map = null;
buffer = ByteBuffer.allocate(width * height * TILE_SIZE); buffer = ByteBuffer.allocate(width * height * TILE_SIZE);
} }
public MapTileData(byte[] bytes, int width, int height){ public MapTileData(byte[] bytes, int width, int height, IntIntMap mapping){
buffer = ByteBuffer.wrap(bytes); buffer = ByteBuffer.wrap(bytes);
this.width = width; this.width = width;
this.height = height; this.height = height;
this.map = mapping;
} }
public byte[] toArray(){ public byte[] toArray(){
@@ -72,7 +77,7 @@ public class MapTileData {
buffer.position((x + width * y) * TILE_SIZE); buffer.position((x + width * y) * TILE_SIZE);
} }
public static class TileDataMarker { public class TileDataMarker {
public byte floor, wall; public byte floor, wall;
public byte rotation; public byte rotation;
public byte team; public byte team;
@@ -83,6 +88,11 @@ public class MapTileData {
byte rt = buffer.get(); byte rt = buffer.get();
rotation = Bits.getLeftByte(rt); rotation = Bits.getLeftByte(rt);
team = Bits.getRightByte(rt); team = Bits.getRightByte(rt);
if(map != null){
floor = (byte)map.get(floor, floor);
wall = (byte)map.get(wall, wall);
}
} }
public void write(ByteBuffer buffer){ public void write(ByteBuffer buffer){

View File

@@ -100,7 +100,7 @@ public class LoadDialog extends FloatingDialog{
button.defaults().padBottom(3); button.defaults().padBottom(3);
button.row(); button.row();
button.add(Bundles.format("text.save.map", color+slot.getMap().meta.name())); button.add(Bundles.format("text.save.map", color+ (slot.getMap() == null ? "Unknown" : slot.getMap().meta.name())));
button.row(); button.row();
button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode()); button.add(Bundles.get("text.level.mode") + " " +color+ slot.getMode());
button.row(); button.row();

View File

@@ -47,6 +47,8 @@ public abstract class BaseBlock {
} }
public void tryDumpLiquid(Tile tile){ public void tryDumpLiquid(Tile tile){
if(tile.entity.liquid.amount < 0.001f) return;
int size = tile.block().size; int size = tile.block().size;
GridPoint2[] nearby = Edges.getEdges(size); GridPoint2[] nearby = Edges.getEdges(size);

View File

@@ -2,6 +2,7 @@ package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.world.Layer; import io.anuke.mindustry.world.Layer;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
@@ -12,8 +13,6 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.world;
public class RepairTurret extends PowerTurret{ public class RepairTurret extends PowerTurret{
protected float repairFrac = 1f / 135f; protected float repairFrac = 1f / 135f;
@@ -43,7 +42,8 @@ public class RepairTurret extends PowerTurret{
} }
if(entity.timer.get(timerTarget, targetInterval)){ if(entity.timer.get(timerTarget, targetInterval)){
entity.blockTarget = world.findTileTarget(tile.worldx(), tile.worldy(), tile, range, true); entity.blockTarget = Units.findAllyTile(tile.getTeam(),tile.worldx(), tile.worldy(), range,
test -> test != tile && test.entity.health < test.block().health);
} }
if(entity.blockTarget != null){ if(entity.blockTarget != null){

View File

@@ -25,9 +25,9 @@ public class Conveyor extends Block{
private static ItemPos drawpos = new ItemPos(); private static ItemPos drawpos = new ItemPos();
private static ItemPos pos1 = new ItemPos(); private static ItemPos pos1 = new ItemPos();
private static ItemPos pos2 = new ItemPos(); private static ItemPos pos2 = new ItemPos();
private static final float itemSpace = 0.135f; private static final float itemSpace = 0.135f * 1.3f;
private static final float offsetScl = 128f*3f; private static final float offsetScl = 128f*3f;
private static final float itemSize = 4f; private static final float itemSize = 5f;
private static final float minmove = 1f / (Short.MAX_VALUE - 2); private static final float minmove = 1f / (Short.MAX_VALUE - 2);
private final Translator tr1 = new Translator(); private final Translator tr1 = new Translator();

View File

@@ -0,0 +1,10 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import io.anuke.mindustry.world.Block;
public class MassDriver extends Block {
public MassDriver(String name) {
super(name);
}
}

View File

@@ -9,7 +9,6 @@ import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock; import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.ButtonGroup; import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.ImageButton; import io.anuke.ucore.scene.ui.ImageButton;
@@ -33,7 +32,7 @@ public class Teleporter extends PowerBlock{
private Array<Tile> removal = new Array<>(); private Array<Tile> removal = new Array<>();
private Array<Tile> returns = new Array<>(); private Array<Tile> returns = new Array<>();
protected float powerPerItem = 0.8f; protected float powerPerItem = 5f;
static{ static{
for(int i = 0; i < colors; i ++){ for(int i = 0; i < colors; i ++){

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.world.blocks.types.modules; package io.anuke.mindustry.world.blocks.types.modules;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.blocks.types.BlockModule; import io.anuke.mindustry.world.blocks.types.BlockModule;
import java.io.DataInputStream; import java.io.DataInputStream;
@@ -39,6 +40,10 @@ public class InventoryModule extends BlockModule{
items[item.id] -= amount; items[item.id] -= amount;
} }
public void removeItem(ItemStack stack){
items[stack.item.id] -= stack.amount;
}
public void clear(){ public void clear(){
Arrays.fill(items, 0); Arrays.fill(items, 0);
} }

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.types.production;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
public class Centrifuge extends LiquidCrafter { public class Centrifuge extends GenericCrafter {
protected float powerUsed = 0.1f; protected float powerUsed = 0.1f;
protected float timeUsed = 360f; protected float timeUsed = 360f;

View File

@@ -0,0 +1,72 @@
package io.anuke.mindustry.world.blocks.types.production;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.production.GenericCrafter.GenericCrafterEntity;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
/**Extracts a random list of items from an input item and an input liquid.*/
public class Filtrator extends Block {
protected final int timerDump = timers ++;
protected Liquid liquid;
protected Item item;
protected Item[] results;
protected float liquidUse;
protected float filterTime;
public Filtrator(String name) {
super(name);
update = true;
solid = true;
hasInventory = true;
hasLiquids = true;
}
//TODO draw with effects such as spinning
@Override
public void update(Tile tile) {
GenericCrafterEntity entity = tile.entity();
float liquidUsed = Math.min(liquidCapacity, liquidUse * Timers.delta());
if(entity.liquid.amount >= liquidUsed && entity.inventory.hasItem(item)){
entity.progress += 1f/filterTime;
}
if(entity.progress >= 1f){
entity.progress = 0f;
Item item = Mathf.select(results);
if(item != null) offloadNear(tile, item);
}
if(entity.timer.get(timerDump, 5)){
tryDump(tile);
}
}
@Override
public boolean canDump(Tile tile, Tile to, Item item) {
return item != this.item;
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
return super.acceptLiquid(tile, source, liquid, amount) && this.liquid == liquid;
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source) {
return this.item == item && tile.entity.inventory.getItem(item) < itemCapacity;
}
@Override
public TileEntity getEntity() {
return new GenericCrafterEntity();
}
}

View File

@@ -0,0 +1,123 @@
package io.anuke.mindustry.world.blocks.types.production;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Strings;
public class GenericCrafter extends Block{
protected final int timerDump = timers++;
/**Can be null. If you use this, make sure to set hasInvetory to true!*/
protected ItemStack inputItem;
/**Can be null. If you use this, make sure to set hasLiquids to true!*/
protected Liquid inputLiquid;
/**Required.*/
protected Item output;
protected float craftTime = 80;
protected float powerUse;
protected float liquidUse;
protected Effect craftEffect = Fx.purify;
public GenericCrafter(String name) {
super(name);
update = true;
rotate = false;
solid = true;
health = 60;
}
@Override
public void setBars(){
super.setBars();
if(inputItem != null) bars.replace(new BlockBar(BarType.inventory, true,
tile -> (float)tile.entity.inventory.getItem(inputItem.item) / itemCapacity));
}
@Override
public void setStats(){
super.setStats();
stats.add("maxitemssecond", Strings.toFixed(60f/craftTime, 1));
if(inputLiquid != null) stats.add("inputliquid", inputLiquid + " x " + (int)(liquidUse * craftTime));
if(inputItem != null) stats.add("inputitem", inputItem + " x " + inputItem.amount);
stats.add("output", output);
}
@Override
public void draw(Tile tile){
Draw.rect(name(), tile.drawx(), tile.drawy());
if(tile.entity.liquid.liquid == null) return;
Draw.color(tile.entity.liquid.liquid.color);
Draw.alpha(tile.entity.liquid.amount / liquidCapacity);
Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2);
Draw.color();
}
@Override
public TextureRegion[] getIcon(){
return new TextureRegion[]{Draw.region(name)};
}
@Override
public void update(Tile tile){
GenericCrafterEntity entity = tile.entity();
float powerUsed = Math.min(powerCapacity, powerUse * Timers.delta());
float liquidUsed = Math.min(liquidCapacity, liquidUse * Timers.delta());
int itemsUsed = (inputItem == null ? 0 : (int)(1 + inputItem.amount * entity.progress));
if((!hasLiquids || liquidUsed > entity.liquid.amount) &&
(!hasPower || powerUsed > entity.power.amount) &&
(!hasInventory || entity.inventory.hasItem(inputItem.item, itemsUsed))){
entity.progress += 1f / craftTime * Timers.delta();
entity.power.amount -= powerUsed;
entity.liquid.amount -= liquidUsed;
}
if(entity.progress >= 1f){
if(inputItem != null) tile.entity.inventory.removeItem(inputItem);
offloadNear(tile, output);
Effects.effect(craftEffect, tile.worldx(), tile.worldy());
}
if(tile.entity.timer.get(timerDump, 5)){
tryDump(tile, output);
}
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid;
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
TileEntity entity = tile.entity();
return inputItem != null && item == inputItem.item && entity.inventory.getItem(inputItem.item) < itemCapacity;
}
@Override
public TileEntity getEntity() {
return new GenericCrafterEntity();
}
public static class GenericCrafterEntity extends TileEntity{
public float progress;
}
}

View File

@@ -1,105 +0,0 @@
package io.anuke.mindustry.world.blocks.types.production;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.LiquidBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Strings;
public class LiquidCrafter extends LiquidBlock{
protected final int timerDump = timers++;
protected final int timerPurify = timers++;
/**Can be null.*/
public Item input = null;
public int inputAmount = 5;
public Liquid inputLiquid = null;
public float liquidAmount = 20f;
public Item output = null;
public int purifyTime = 80;
public Effect craftEffect = Fx.purify;
public LiquidCrafter(String name) {
super(name);
update = true;
rotate = false;
solid = true;
health = 60;
hasInventory = true;
itemCapacity = 90;
liquidCapacity = 20f;
}
@Override
public void setBars(){
super.setBars();
bars.remove(BarType.inventory);
bars.add(new BlockBar(BarType.inventory, true,
tile -> input == null ? -1f : (float)tile.entity.inventory.getItem(input) / itemCapacity));
}
@Override
public void setStats(){
super.setStats();
stats.add("maxitemssecond", Strings.toFixed(60f/purifyTime, 1));
stats.add("inputliquid", inputLiquid + " x " + (int)liquidAmount);
if(input != null) stats.add("itemcapacity", itemCapacity);
if(input != null) stats.add("inputitem", input + " x " + inputAmount);
stats.add("output", output);
}
@Override
public void draw(Tile tile){
Draw.rect(name(), tile.drawx(), tile.drawy());
if(tile.entity.liquid.liquid == null) return;
Draw.color(tile.entity.liquid.liquid.color);
Draw.alpha(tile.entity.liquid.amount / liquidCapacity);
Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2);
Draw.color();
}
@Override
public TextureRegion[] getIcon(){
return new TextureRegion[]{Draw.region(name)};
}
@Override
public void update(Tile tile){
if(tile.entity.timer.get(timerPurify, purifyTime) && tile.entity.liquid.amount >= liquidAmount &&
(input == null || tile.entity.inventory.hasItem(input, inputAmount))){
if(input != null)
tile.entity.inventory.removeItem(input, inputAmount);
tile.entity.liquid.amount -= liquidAmount;
offloadNear(tile, output);
Effects.effect(craftEffect, tile.worldx(), tile.worldy());
}
if(tile.entity.timer.get(timerDump, 15)){
tryDump(tile, output);
}
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid;
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
TileEntity entity = tile.entity();
return input != null && item == input && entity.inventory.getItem(input) < itemCapacity;
}
}

View File

@@ -26,11 +26,11 @@ public class LiquidMixer extends LiquidBlock{
@Override @Override
public void update(Tile tile){ public void update(Tile tile){
if(tile.entity.liquid.amount > 0.001f){ float used = Math.min(Timers.delta() * powerUse, tile.entity.power.amount);
tryDumpLiquid(tile);
}
tile.entity.power.amount -= Math.min(Timers.delta() * powerUse, tile.entity.power.amount); tryDumpLiquid(tile);
if(tile.entity.power.amount > used) tile.entity.power.amount -= used;
} }
@Override @Override

View File

@@ -0,0 +1,66 @@
package io.anuke.mindustry.world.blocks.types.production;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.production.GenericCrafter.GenericCrafterEntity;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf;
public class PowerCrafter extends Block{
protected final int timerDump = timers++;
protected ItemStack input;
/**Optional.*/
protected Item outputItem;
/**Optional. Set hasLiquids to true when using.*/
protected Liquid outputLiquid;
protected float outputLiquidAmount;
protected float powerUse;
protected float craftTime;
public PowerCrafter(String name) {
super(name);
solid = true;
update = true;
}
@Override
public void update(Tile tile) {
GenericCrafterEntity entity = tile.entity();
float powerUsed = Math.min(Timers.delta() * powerUse, tile.entity.power.amount);
int itemsUsed = Mathf.ceil(1 + input.amount * entity.progress);
if(entity.power.amount > powerUsed && entity.inventory.hasItem(input.item, itemsUsed)){
entity.progress += 1f/craftTime;
}
if(entity.progress >= 1f){
entity.inventory.removeItem(input);
if(outputItem != null) offloadNear(tile, outputItem);
if(outputLiquid != null) handleLiquid(tile, tile, outputLiquid, outputLiquidAmount);
}
if(outputItem != null && entity.timer.get(timerDump, 5)){
tryDump(tile, outputItem);
}
if(outputLiquid != null){
tryDumpLiquid(tile);
}
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source) {
return item == input.item && tile.entity.inventory.getItem(input.item) < itemCapacity;
}
@Override
public TileEntity getEntity() {
return new GenericCrafterEntity();
}
}

View File

@@ -1,14 +1,14 @@
package io.anuke.mindustry.world.blocks.types.production; package io.anuke.mindustry.world.blocks.types.production;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar; import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock; import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
@@ -22,7 +22,8 @@ public class PowerSmelter extends PowerBlock {
/**Recipe format: /**Recipe format:
* First item in each array: result * First item in each array: result
* Everything else in each array: requirements. Can have duplicates.*/ * Everything else in each array: requirements. Can have duplicates.*/
protected Item[][] recipes; protected ItemStack[] inputs;
protected Item result;
protected float powerDrain = 0.01f; protected float powerDrain = 0.01f;
protected float heatUpTime = 80f; protected float heatUpTime = 80f;
@@ -46,25 +47,8 @@ public class PowerSmelter extends PowerBlock {
super.setBars(); super.setBars();
bars.remove(BarType.inventory); bars.remove(BarType.inventory);
if(true) return; for(ItemStack item : inputs){
bars.add(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.inventory.getItem(item.item) / capacity));
//TODO
ObjectSet<Item> set = new ObjectSet<>();
for(Item[] items : recipes){
for(int i = 1; i < items.length; i ++) {
set.add(items[i]);
}
}
Array<Item> items = new Array<>();
set.forEach(items::add);
items.sort();
for(Item item : items){
bars.add(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.inventory.getItem(item) / capacity));
} }
} }
@@ -83,7 +67,7 @@ public class PowerSmelter extends PowerBlock {
@Override @Override
public void update(Tile tile){ public void update(Tile tile){
/*
PowerSmelterEntity entity = tile.entity(); PowerSmelterEntity entity = tile.entity();
if(entity.timer.get(timerDump, 5) && entity.inventory.hasItem(result)){ if(entity.timer.get(timerDump, 5) && entity.inventory.hasItem(result)){
@@ -121,24 +105,19 @@ public class PowerSmelter extends PowerBlock {
} }
offloadNear(tile, result); offloadNear(tile, result);
Effects.effect(craftEffect, entity);*/ Effects.effect(craftEffect, entity);
} }
@Override @Override
public boolean acceptItem(Item item, Tile tile, Tile source){ public boolean acceptItem(Item item, Tile tile, Tile source){
boolean isInput = false;
out: for(ItemStack stack : inputs){
for(Item[] items : recipes){ if(stack.item == item){
for(int i = 1; i < items.length; i ++){ return tile.entity.inventory.getItem(item) < capacity;
if(items[i] == item){
isInput = true;
break out;
}
} }
} }
return (isInput && tile.entity.inventory.getItem(item) < capacity); return false;
} }
@Override @Override

View File

@@ -51,7 +51,7 @@ public class UnitFactory extends Block {
@Override @Override
public boolean isSolidFor(Tile tile) { public boolean isSolidFor(Tile tile) {
UnitFactoryEntity entity = tile.entity(); UnitFactoryEntity entity = tile.entity();
return !type.isFlying() || !entity.open; return type.isFlying() || !entity.open;
} }
@Override @Override
@@ -117,6 +117,8 @@ public class UnitFactory extends Block {
if(type.isFlying() || !anyEntities(tile)) { if(type.isFlying() || !anyEntities(tile)) {
entity.open = false; entity.open = false;
entity.openCountdown = -1; entity.openCountdown = -1;
}else{
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 0f, 0.1f);
} }
} }
} }

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.blocks.types.production; package io.anuke.mindustry.world.blocks.types.production;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.net.NetEvents;
@@ -10,12 +11,14 @@ import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Listenable; import io.anuke.ucore.function.Listenable;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.style.TextureRegionDrawable; import io.anuke.ucore.scene.style.TextureRegionDrawable;
import io.anuke.ucore.scene.ui.ImageButton; import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.Tooltip; import io.anuke.ucore.scene.ui.Tooltip;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -27,6 +30,22 @@ public class WeaponFactory extends Block{
destructible = true; destructible = true;
} }
@Override
public void draw(Tile tile) {
super.draw(tile);
for(int i : Mathf.signs){
Draw.color(Color.YELLOW);
Draw.alpha(0.1f + Mathf.absin(Timers.time(), 12f, 0.2f));
Draw.rect("white", tile.drawx() + i*3.5f, tile.drawy(), 1, 8);
Draw.color(Color.ORANGE);
Draw.alpha(0.5f);
Draw.rect("white", tile.drawx() + i*3.5f, tile.drawy() + Mathf.sin(Timers.time() + i *77, 13f, 4f), 1, 2);
}
Draw.reset();
}
@Override @Override
public boolean isConfigurable(Tile tile){ public boolean isConfigurable(Tile tile){
return !Vars.android; return !Vars.android;