New map ore balancing / Reduced item burn rate

This commit is contained in:
Anuken
2019-08-02 18:32:33 -04:00
parent 878af1ea28
commit 438f128e2e
22 changed files with 85 additions and 104 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1056,7 +1056,7 @@ public class Blocks implements ContentList{
combustionGenerator = new BurnerGenerator("combustion-generator"){{
requirements(Category.power, ItemStack.with(Items.copper, 25, Items.lead, 15));
powerProduction = 1f;
itemDuration = 60f;
itemDuration = 120f;
}};
thermalGenerator = new ThermalGenerator("thermal-generator"){{
@ -1069,7 +1069,7 @@ public class Blocks implements ContentList{
turbineGenerator = new BurnerGenerator("turbine-generator"){{
requirements(Category.power, ItemStack.with(Items.copper, 35, Items.graphite, 25, Items.lead, 40, Items.silicon, 30));
powerProduction = 6f;
itemDuration = 40f;
itemDuration = 90f;
consumes.liquid(Liquids.water, 0.05f);
hasLiquids = true;
size = 2;
@ -1078,7 +1078,7 @@ public class Blocks implements ContentList{
differentialGenerator = new SingleTypeGenerator(true, false, "differential-generator"){{
requirements(Category.power, ItemStack.with(Items.copper, 70, Items.titanium, 50, Items.lead, 100, Items.silicon, 65, Items.metaglass, 50));
powerProduction = 16f;
itemDuration = 60f;
itemDuration = 120f;
hasLiquids = true;
size = 3;
@ -1090,7 +1090,7 @@ public class Blocks implements ContentList{
requirements(Category.power, ItemStack.with(Items.lead, 100, Items.silicon, 75, Items.phasefabric, 25, Items.plastanium, 75, Items.thorium, 50));
size = 2;
powerProduction = 3f;
itemDuration = 220f;
itemDuration = 440f;
}};
solarPanel = new SolarGenerator("solar-panel"){{
@ -1108,6 +1108,7 @@ public class Blocks implements ContentList{
requirements(Category.power, ItemStack.with(Items.lead, 300, Items.silicon, 200, Items.graphite, 150, Items.thorium, 150, Items.metaglass, 50));
size = 3;
health = 700;
itemDuration = 360f;
powerProduction = 14f;
consumes.item(Items.thorium);
heating = 0.02f;
@ -1119,7 +1120,7 @@ public class Blocks implements ContentList{
size = 4;
health = 900;
powerProduction = 130f;
itemDuration = 90f;
itemDuration = 140f;
consumes.power(25f);
consumes.item(Items.blastCompound);
consumes.liquid(Liquids.cryofluid, 0.25f);
@ -1618,7 +1619,7 @@ public class Blocks implements ContentList{
size = 2;
maxSpawn = 2;
consumes.power(0.80f);
consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30));
consumes.items(new ItemStack(Items.silicon, 10), new ItemStack(Items.lead, 15));
}};
phantomFactory = new UnitFactory("phantom-factory"){{
@ -1628,7 +1629,7 @@ public class Blocks implements ContentList{
size = 2;
maxSpawn = 2;
consumes.power(2f);
consumes.items(new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80));
consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 20), new ItemStack(Items.titanium, 10));
}};
wraithFactory = new UnitFactory("wraith-factory"){{
@ -1637,7 +1638,7 @@ public class Blocks implements ContentList{
produceTime = 750;
size = 2;
consumes.power(0.6f);
consumes.items(new ItemStack(Items.silicon, 20), new ItemStack(Items.titanium, 10));
consumes.items(new ItemStack(Items.silicon, 10), new ItemStack(Items.titanium, 5));
}};
ghoulFactory = new UnitFactory("ghoul-factory"){{
@ -1646,7 +1647,7 @@ public class Blocks implements ContentList{
produceTime = 1150;
size = 3;
consumes.power(1.2f);
consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.titanium, 20));
consumes.items(new ItemStack(Items.silicon, 15), new ItemStack(Items.titanium, 10));
}};
revenantFactory = new UnitFactory("revenant-factory"){{
@ -1655,7 +1656,7 @@ public class Blocks implements ContentList{
produceTime = 2000;
size = 4;
consumes.power(3f);
consumes.items(new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 80));
consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 30));
}};
daggerFactory = new UnitFactory("dagger-factory"){{
@ -1664,7 +1665,7 @@ public class Blocks implements ContentList{
produceTime = 850;
size = 2;
consumes.power(0.5f);
consumes.items(new ItemStack(Items.silicon, 15));
consumes.items(new ItemStack(Items.silicon, 6));
}};
crawlerFactory = new UnitFactory("crawler-factory"){{
@ -1674,7 +1675,7 @@ public class Blocks implements ContentList{
size = 2;
maxSpawn = 5;
consumes.power(0.5f);
consumes.items(new ItemStack(Items.coal, 5), new ItemStack(Items.silicon, 5));
consumes.items(new ItemStack(Items.coal, 4), new ItemStack(Items.silicon, 4));
}};
titanFactory = new UnitFactory("titan-factory"){{
@ -1683,7 +1684,7 @@ public class Blocks implements ContentList{
produceTime = 1050;
size = 3;
consumes.power(0.60f);
consumes.items(new ItemStack(Items.silicon, 30));
consumes.items(new ItemStack(Items.silicon, 12));
}};
fortressFactory = new UnitFactory("fortress-factory"){{
@ -1693,7 +1694,7 @@ public class Blocks implements ContentList{
size = 3;
maxSpawn = 3;
consumes.power(1.4f);
consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.graphite, 30));
consumes.items(new ItemStack(Items.silicon, 20), new ItemStack(Items.graphite, 10));
}};
repairPoint = new RepairPoint("repair-point"){{

View File

@ -115,7 +115,7 @@ public class Bullets implements ContentList{
lifetime = 70f;
bulletWidth = bulletHeight = 14f;
collidesTiles = false;
ammoMultiplier = 2f;
ammoMultiplier = 4f;
splashDamageRadius = 45f;
splashDamage = 50f;
backColor = Pal.missileYellowBack;
@ -137,7 +137,7 @@ public class Bullets implements ContentList{
flakLead = new FlakBulletType(4.2f, 3){{
lifetime = 60f;
ammoMultiplier = 3f;
ammoMultiplier = 4f;
shootEffect = Fx.shootSmall;
bulletWidth = 6f;
bulletHeight = 8f;
@ -148,7 +148,7 @@ public class Bullets implements ContentList{
flakScrap = new FlakBulletType(4f, 3){{
lifetime = 60f;
ammoMultiplier = 3f;
ammoMultiplier = 5f;
shootEffect = Fx.shootSmall;
reloadMultiplier = 0.5f;
bulletWidth = 6f;
@ -171,7 +171,7 @@ public class Bullets implements ContentList{
flakExplosive = new FlakBulletType(4f, 5){{
//default bullet type, no changes
shootEffect = Fx.shootBig;
ammoMultiplier = 2f;
ammoMultiplier = 4f;
}};
flakSurge = new FlakBulletType(4f, 7){{
@ -188,7 +188,7 @@ public class Bullets implements ContentList{
drag = -0.01f;
splashDamageRadius = 30f;
splashDamage = 30f;
ammoMultiplier = 2f;
ammoMultiplier = 4f;
lifetime = 150f;
hitEffect = Fx.blastExplosion;
despawnEffect = Fx.blastExplosion;
@ -286,14 +286,14 @@ public class Bullets implements ContentList{
lifetime = 60f;
shootEffect = Fx.shootSmall;
smokeEffect = Fx.shootSmallSmoke;
ammoMultiplier = 1;
ammoMultiplier = 2;
}};
standardDense = new BasicBulletType(3.5f, 18, "bullet"){{
bulletWidth = 9f;
bulletHeight = 12f;
reloadMultiplier = 0.6f;
ammoMultiplier = 2;
ammoMultiplier = 4;
lifetime = 60f;
}};
@ -302,7 +302,7 @@ public class Bullets implements ContentList{
bulletHeight = 13f;
shootEffect = Fx.shootBig;
smokeEffect = Fx.shootBigSmoke;
ammoMultiplier = 2;
ammoMultiplier = 4;
lifetime = 60f;
}};
@ -311,7 +311,7 @@ public class Bullets implements ContentList{
bulletHeight = 9f;
homingPower = 5f;
reloadMultiplier = 1.4f;
ammoMultiplier = 3;
ammoMultiplier = 5;
lifetime = 60f;
}};

View File

@ -294,7 +294,7 @@ public class TechTree implements ContentList{
private TechNode node(Block block, Runnable children){
ItemStack[] requirements = new ItemStack[block.buildRequirements.length];
for(int i = 0; i < requirements.length; i++){
requirements[i] = new ItemStack(block.buildRequirements[i].item, block.buildRequirements[i].amount * 5);
requirements[i] = new ItemStack(block.buildRequirements[i].item, block.buildRequirements[i].amount * 3);
}
return new TechNode(block, requirements, children);

View File

@ -20,8 +20,8 @@ public class Zones implements ContentList{
public void load(){
groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{
baseLaunchCost = ItemStack.with(Items.copper, -100);
startingItems = ItemStack.list(Items.copper, 100);
baseLaunchCost = ItemStack.with(Items.copper, -60);
startingItems = ItemStack.list(Items.copper, 60);
alwaysUnlocked = true;
conditionWave = 5;
launchPeriod = 5;
@ -29,7 +29,7 @@ public class Zones implements ContentList{
}};
desertWastes = new Zone("desertWastes", new DesertWastesGenerator(260, 260)){{
startingItems = ItemStack.list(Items.copper, 200);
startingItems = ItemStack.list(Items.copper, 120);
conditionWave = 20;
launchPeriod = 10;
loadout = Loadouts.advancedShard;
@ -78,8 +78,7 @@ public class Zones implements ContentList{
}};
saltFlats = new Zone("saltFlats", new MapGenerator("saltFlats")){{
baseLaunchCost = ItemStack.with(Items.copper, -100);
startingItems = ItemStack.list(Items.copper, 100);
startingItems = ItemStack.list(Items.copper, 200, Items.silicon, 100, Items.lead, 200);
alwaysUnlocked = true;
conditionWave = 5;
launchPeriod = 5;
@ -93,15 +92,15 @@ public class Zones implements ContentList{
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{
loadout = Loadouts.basicFoundation;
baseLaunchCost = ItemStack.with();
startingItems = ItemStack.list(Items.copper, 400);
startingItems = ItemStack.list(Items.copper, 250);
conditionWave = 10;
blockRequirements = new Block[]{Blocks.junction, Blocks.router};
zoneRequirements = ZoneRequirement.with(groundZero, 10);
resources = new Item[]{Items.copper, Items.lead, Items.coal};
}};
craters = new Zone("craters", new MapGenerator("craters", 1).dist(0).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{
startingItems = ItemStack.list(Items.copper, 200);
craters = new Zone("craters", new MapGenerator("craters", 1).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{
startingItems = ItemStack.list(Items.copper, 100);
conditionWave = 10;
zoneRequirements = ZoneRequirement.with(frozenForest, 10);
blockRequirements = new Block[]{Blocks.mender, Blocks.combustionGenerator};
@ -109,7 +108,7 @@ public class Zones implements ContentList{
}};
overgrowth = new Zone("overgrowth", new MapGenerator("overgrowth")){{
startingItems = ItemStack.list(Items.copper, 3000, Items.lead, 2000, Items.silicon, 1000, Items.metaglass, 500);
startingItems = ItemStack.list(Items.copper, 1500, Items.lead, 1000, Items.silicon, 500, Items.metaglass, 250);
conditionWave = 12;
launchPeriod = 4;
loadout = Loadouts.basicNucleus;
@ -118,10 +117,10 @@ public class Zones implements ContentList{
resources = new Item[]{Items.copper, Items.lead, Items.coal, Items.titanium, Items.sand, Items.thorium, Items.scrap};
}};
ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1).dist(3f, true)){{
ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1)){{
loadout = Loadouts.basicFoundation;
baseLaunchCost = ItemStack.with();
startingItems = ItemStack.list(Items.copper, 400);
startingItems = ItemStack.list(Items.copper, 140, Items.lead, 50);
conditionWave = 20;
launchPeriod = 20;
zoneRequirements = ZoneRequirement.with(desertWastes, 20, craters, 15);
@ -130,10 +129,9 @@ public class Zones implements ContentList{
}};
stainedMountains = new Zone("stainedMountains", new MapGenerator("stainedMountains", 2)
.dist(0f, false)
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
loadout = Loadouts.basicFoundation;
startingItems = ItemStack.list(Items.copper, 400, Items.lead, 100);
startingItems = ItemStack.list(Items.copper, 200, Items.lead, 50);
conditionWave = 10;
launchPeriod = 10;
zoneRequirements = ZoneRequirement.with(frozenForest, 15);
@ -142,10 +140,9 @@ public class Zones implements ContentList{
}};
tarFields = new Zone("tarFields", new MapGenerator("tarFields")
.dist(0f, false)
.decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
loadout = Loadouts.basicFoundation;
startingItems = ItemStack.list(Items.copper, 500, Items.lead, 200);
startingItems = ItemStack.list(Items.copper, 250, Items.lead, 100);
conditionWave = 15;
launchPeriod = 10;
zoneRequirements = ZoneRequirement.with(ruinousShores, 20);
@ -153,10 +150,10 @@ public class Zones implements ContentList{
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand};
}};
desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift").dist(2f)){{
desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift")){{
loadout = Loadouts.basicNucleus;
baseLaunchCost = ItemStack.with();
startingItems = ItemStack.list(Items.copper, 2000, Items.lead, 2000, Items.graphite, 500, Items.titanium, 500, Items.silicon, 500);
startingItems = ItemStack.list(Items.copper, 1000, Items.lead, 1000, Items.graphite, 250, Items.titanium, 250, Items.silicon, 250);
conditionWave = 3;
launchPeriod = 2;
zoneRequirements = ZoneRequirement.with(tarFields, 20);
@ -180,7 +177,7 @@ public class Zones implements ContentList{
.decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{
loadout = Loadouts.basicNucleus;
baseLaunchCost = ItemStack.with();
startingItems = ItemStack.list(Items.copper, 2500, Items.lead, 3000, Items.silicon, 800, Items.metaglass, 400);
startingItems = ItemStack.list(Items.copper, 1250, Items.lead, 1500, Items.silicon, 400, Items.metaglass, 250);
conditionWave = 30;
launchPeriod = 15;
zoneRequirements = ZoneRequirement.with(stainedMountains, 20);

View File

@ -365,6 +365,10 @@ public class MapEditorDialog extends Dialog implements Disposable{
return view;
}
public MapGenerateDialog getGenerateDialog(){
return generateDialog;
}
public void resetSaved(){
saved = false;
}

View File

@ -11,7 +11,6 @@ import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.async.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.io.*;
@ -150,16 +149,6 @@ public class MapGenerateDialog extends FloatingDialog{
editor.clearOp();
}
public void addDefaultOres(Array<GenerateFilter> filters){
int index = 0;
for(Block block : new Block[]{Blocks.oreCopper, Blocks.oreLead, Blocks.oreCoal, Blocks.oreTitanium, Blocks.oreThorium}){
OreFilter filter = new OreFilter();
filter.threshold += index ++ * 0.019f;
filter.ore = block;
filters.add(filter);
}
}
void setup(){
if(pixmap != null){
pixmap.dispose();
@ -315,7 +304,7 @@ public class MapGenerateDialog extends FloatingDialog{
}
selection.cont.addButton("$filter.defaultores", () -> {
addDefaultOres(filters);
world.maps.addDefaultOres(filters);
rebuildFilters();
update();
selection.hide();

View File

@ -31,7 +31,7 @@ public abstract class BulletType extends Content{
/** Extra inaccuracy when firing. */
public float inaccuracy = 0f;
/** How many bullets get created per ammo item/liquid. */
public float ammoMultiplier = 1f;
public float ammoMultiplier = 2f;
/** Multiplied by turret reload speed to get final shoot speed. */
public float reloadMultiplier = 1f;
/** Recoil from shooter entities. */

View File

@ -210,13 +210,7 @@ public class Maps implements Disposable{
}}
);
int index = 0;
for(Block block : new Block[]{Blocks.oreCopper, Blocks.oreLead, Blocks.oreCoal, Blocks.oreTitanium, Blocks.oreThorium}){
OreFilter filter = new OreFilter();
filter.threshold += index ++ * 0.019f;
filter.ore = block;
filters.add(filter);
}
addDefaultOres(filters);
return filters;
}else{
@ -224,6 +218,17 @@ public class Maps implements Disposable{
}
}
public void addDefaultOres(Array<GenerateFilter> filters){
int index = 0;
for(Block block : new Block[]{Blocks.oreCopper, Blocks.oreLead, Blocks.oreCoal, Blocks.oreTitanium, Blocks.oreThorium}){
OreFilter filter = new OreFilter();
filter.threshold += index ++ * 0.019f;
filter.scl += index;
filter.ore = block;
filters.add(filter);
}
}
public String writeWaves(Array<SpawnGroup> groups){
if(groups == null){
return "[]";

View File

@ -8,7 +8,7 @@ import static io.anuke.mindustry.maps.filters.FilterOption.BlockOption;
import static io.anuke.mindustry.maps.filters.FilterOption.oresOnly;
public class OreFilter extends GenerateFilter{
public float scl = 40, threshold = 0.75f, octaves = 2f, falloff = 0.4f;
public float scl = 23, threshold = 0.808f, octaves = 2f, falloff = 0.5f;
public Block ore = Blocks.oreCopper;
{

View File

@ -2,15 +2,16 @@ package io.anuke.mindustry.maps.filters;
import io.anuke.arc.collection.*;
import io.anuke.arc.math.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.maps.filters.FilterOption.*;
import io.anuke.mindustry.world.*;
import static io.anuke.mindustry.Vars.content;
public class OreMedianFilter extends GenerateFilter{
float radius = 2;
float percentile = 0.5f;
IntArray blocks = new IntArray();
public float radius = 2;
public float percentile = 0.5f;
private IntArray blocks = new IntArray();
{
buffered = true;
@ -22,13 +23,26 @@ public class OreMedianFilter extends GenerateFilter{
@Override
public void apply(){
if(in.ore == Blocks.spawn) return;
int cx = (in.x / 2) * 2;
int cy = (in.y / 2) * 2;
if(in.ore != Blocks.air){
if(!(in.tile(cx + 1, cy).overlay() == in.ore && in.tile(cx, cy).overlay() == in.ore && in.tile(cx + 1, cy + 1).overlay() == in.ore && in.tile(cx, cy + 1).overlay() == in.ore &&
!in.tile(cx + 1, cy).block().isStatic() && !in.tile(cx, cy).block().isStatic() && !in.tile(cx + 1, cy + 1).block().isStatic() && !in.tile(cx, cy + 1).block().isStatic())){
in.ore = Blocks.air;
}
}
int rad = (int)radius;
blocks.clear();
for(int x = -rad; x <= rad; x++){
for(int y = -rad; y <= rad; y++){
if(Mathf.dst2(x, y) > rad*rad) continue;
Tile tile = in.tile(in.x + x, in.y + y);
if(tile.overlay() != Blocks.spawn)
blocks.add(tile.overlay().id);
}
}
@ -36,8 +50,8 @@ public class OreMedianFilter extends GenerateFilter{
blocks.sort();
int index = Math.min((int)(blocks.size * percentile), blocks.size - 1);
int overlay = blocks.get(index), block = blocks.get(index);
int overlay = blocks.get(index);
in.ore = content.block(overlay);
in.ore = Vars.content.block(overlay);
}
}

View File

@ -4,7 +4,6 @@ import io.anuke.arc.collection.*;
import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.noise.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.io.*;
import io.anuke.mindustry.maps.*;
@ -19,8 +18,6 @@ public class MapGenerator extends Generator{
private Map map;
private String mapName;
private Array<Decoration> decorations = Array.with(new Decoration(Blocks.stone, Blocks.rock, 0.003f));
/** How much the landscape is randomly distorted. */
public float distortion = 3;
/**
* The amount of final enemy spawns used. -1 to use everything in the map.
* This amount of enemy spawns is selected randomly from the map.
@ -43,17 +40,6 @@ public class MapGenerator extends Generator{
return this;
}
public MapGenerator dist(float distortion){
this.distortion = distortion;
return this;
}
public MapGenerator dist(float distortion, boolean floor){
this.distortion = distortion;
this.distortFloor = floor;
return this;
}
{
decor(new Decoration(Blocks.snow, Blocks.snowrock, 0.01), new Decoration(Blocks.ignarock, Blocks.pebbles, 0.03f));
}
@ -100,28 +86,9 @@ public class MapGenerator extends Generator{
}
}
Simplex simplex = new Simplex(Mathf.random(99999));
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
final double scl = 10;
Tile tile = tiles[x][y];
int newX = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x, y) * distortion + x), 0, width - 1);
int newY = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x + 9999, y + 9999) * distortion + y), 0, height - 1);
if(((tile.block() instanceof StaticWall
&& tiles[newX][newY].block() instanceof StaticWall)
|| (tile.block() == Blocks.air && !tiles[newX][newY].block().synthetic())
|| (tiles[newX][newY].block() == Blocks.air && tile.block() instanceof StaticWall))){
tile.setBlock(tiles[newX][newY].block());
}
if(distortFloor){
tile.setFloor(tiles[newX][newY].floor());
if(tiles[newX][newY].overlay() != Blocks.spawn && tile.overlay() != Blocks.spawn){
tile.setOverlay(tiles[newX][newY].overlay());
}
}
for(Decoration decor : decorations){
if(x > 0 && y > 0 && (tiles[x - 1][y].block() == decor.wall || tiles[x][y - 1].block() == decor.wall)){

View File

@ -141,6 +141,10 @@ public class Block extends BlockStorage{
return buildVisibility != invisible;
}
public boolean isStatic(){
return cacheLayer == CacheLayer.walls;
}
public void onProximityRemoved(Tile tile){
if(tile.entity.power != null){
tile.block().powerGraphRemoved(tile);

View File

@ -30,7 +30,7 @@ public class NuclearReactor extends PowerGenerator{
protected Color coolColor = new Color(1, 1, 1, 0f);
protected Color hotColor = Color.valueOf("ff9575a3");
protected int itemDuration = 120; //time to consume 1 fuel
protected float itemDuration = 120; //time to consume 1 fuel
protected float heating = 0.01f; //heating per frame * fullness
protected float smokeThreshold = 0.3f; //threshold at which block starts smoking
protected int explosionRadius = 40;