New generators, projectors, status system, sprites renamed

This commit is contained in:
Anuken
2018-06-18 14:27:50 -04:00
parent 84d80525fa
commit ee2cba89d5
59 changed files with 1716 additions and 2296 deletions

View File

Before

Width:  |  Height:  |  Size: 635 B

After

Width:  |  Height:  |  Size: 635 B

View File

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 304 B

View File

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 180 B

View File

Before

Width:  |  Height:  |  Size: 333 B

After

Width:  |  Height:  |  Size: 333 B

View File

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 295 B

View File

Before

Width:  |  Height:  |  Size: 310 B

After

Width:  |  Height:  |  Size: 310 B

View File

Before

Width:  |  Height:  |  Size: 288 B

After

Width:  |  Height:  |  Size: 288 B

View File

Before

Width:  |  Height:  |  Size: 977 B

After

Width:  |  Height:  |  Size: 977 B

View File

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

View File

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

View File

Before

Width:  |  Height:  |  Size: 536 B

After

Width:  |  Height:  |  Size: 536 B

View File

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

View File

Before

Width:  |  Height:  |  Size: 617 B

After

Width:  |  Height:  |  Size: 617 B

View File

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

View File

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 258 B

View File

Before

Width:  |  Height:  |  Size: 307 B

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

View File

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

@@ -47,6 +47,7 @@ public class Items implements ContentList{
type = ItemType.material; type = ItemType.material;
explosiveness = 0.1f; explosiveness = 0.1f;
hardness = 4; hardness = 4;
radioactivity = 0.5f;
}}; }};
silicon = new Item("silicon", Color.valueOf("53565c")) {{ silicon = new Item("silicon", Color.valueOf("53565c")) {{

View File

@@ -37,7 +37,7 @@ public class Liquids implements ContentList {
flammability = 0.6f; flammability = 0.6f;
explosiveness = 0.6f; explosiveness = 0.6f;
tier = 1; tier = 1;
effect = StatusEffects.oiled; effect = StatusEffects.tarred;
} }
}; };

View File

@@ -89,22 +89,17 @@ public class Recipes implements ContentList{
new Recipe(power, PowerBlocks.powernodelarge, new ItemStack(Items.steel, 3), new ItemStack(Items.iron, 3)); new Recipe(power, PowerBlocks.powernodelarge, new ItemStack(Items.steel, 3), new ItemStack(Items.iron, 3));
new Recipe(power, PowerBlocks.battery, new ItemStack(Items.steel, 5), new ItemStack(Items.iron, 5)); new Recipe(power, PowerBlocks.battery, new ItemStack(Items.steel, 5), new ItemStack(Items.iron, 5));
new Recipe(power, PowerBlocks.batteryLarge, new ItemStack(Items.steel, 5), new ItemStack(Items.iron, 5)); new Recipe(power, PowerBlocks.batteryLarge, new ItemStack(Items.steel, 5), new ItemStack(Items.iron, 5));
new Recipe(power, PowerBlocks.combustiongenerator, new ItemStack(Items.iron, 30)); new Recipe(power, PowerBlocks.combustiongenerator, new ItemStack(Items.iron, 1));
new Recipe(power, PowerBlocks.liquidcombustiongenerator, new ItemStack(Items.iron, 30)); new Recipe(power, PowerBlocks.turbinegenerator, new ItemStack(Items.iron, 1));
new Recipe(power, PowerBlocks.thermalgenerator, new ItemStack(Items.steel, 30)); new Recipe(power, PowerBlocks.thermalgenerator, new ItemStack(Items.steel, 1));
new Recipe(power, PowerBlocks.rtgenerator, new ItemStack(Items.titanium, 20), new ItemStack(Items.steel, 20)); new Recipe(power, PowerBlocks.rtgenerator, new ItemStack(Items.titanium, 1), new ItemStack(Items.steel, 1));
new Recipe(power, PowerBlocks.solarpanel, new ItemStack(Items.iron, 30), new ItemStack(Items.silicon, 20)); new Recipe(power, PowerBlocks.solarpanel, new ItemStack(Items.iron, 30), new ItemStack(Items.silicon, 20));
new Recipe(power, PowerBlocks.largesolarpanel, new ItemStack(Items.iron, 30), new ItemStack(Items.silicon, 20)); new Recipe(power, PowerBlocks.largesolarpanel, new ItemStack(Items.iron, 30), new ItemStack(Items.silicon, 20));
new Recipe(power, PowerBlocks.nuclearReactor, new ItemStack(Items.titanium, 40), new ItemStack(Items.surgealloy, 40), new ItemStack(Items.steel, 50)); new Recipe(power, PowerBlocks.nuclearReactor, new ItemStack(Items.titanium, 40), new ItemStack(Items.surgealloy, 40), new ItemStack(Items.steel, 50));
new Recipe(power, PowerBlocks.fusionReactor, new ItemStack(Items.titanium, 40), new ItemStack(Items.surgealloy, 40), new ItemStack(Items.steel, 50)); new Recipe(power, PowerBlocks.fusionReactor, new ItemStack(Items.titanium, 40), new ItemStack(Items.surgealloy, 40), new ItemStack(Items.steel, 50));
new Recipe(power, PowerBlocks.shieldgenerator, new ItemStack(Items.titanium, 30), new ItemStack(Items.surgealloy, 30));
new Recipe(distribution, PowerBlocks.warpgate, new ItemStack(Items.steel, 1)); new Recipe(distribution, PowerBlocks.warpgate, new ItemStack(Items.steel, 1));
new Recipe(power, PowerBlocks.repairturret, new ItemStack(Items.iron, 30));
new Recipe(power, PowerBlocks.megarepairturret, new ItemStack(Items.iron, 20), new ItemStack(Items.steel, 30));
new Recipe(liquid, LiquidBlocks.conduit, new ItemStack(Items.steel, 1)); new Recipe(liquid, LiquidBlocks.conduit, new ItemStack(Items.steel, 1));
new Recipe(liquid, LiquidBlocks.pulseconduit, new ItemStack(Items.titanium, 1), new ItemStack(Items.steel, 1)); new Recipe(liquid, LiquidBlocks.pulseconduit, new ItemStack(Items.titanium, 1), new ItemStack(Items.steel, 1));
new Recipe(liquid, LiquidBlocks.liquidrouter, new ItemStack(Items.steel, 2)); new Recipe(liquid, LiquidBlocks.liquidrouter, new ItemStack(Items.steel, 2));
@@ -124,6 +119,9 @@ public class Recipes implements ContentList{
new Recipe(units, UnitBlocks.droneFactory, new ItemStack(Items.iron, 50)); new Recipe(units, UnitBlocks.droneFactory, new ItemStack(Items.iron, 50));
new Recipe(units, UnitBlocks.reconstructor, new ItemStack(Items.iron, 1)); new Recipe(units, UnitBlocks.reconstructor, new ItemStack(Items.iron, 1));
new Recipe(units, UnitBlocks.overdriveProjector, new ItemStack(Items.iron, 1));
new Recipe(units, UnitBlocks.shieldProjector, new ItemStack(Items.iron, 1));
//new Recipe(units, UnitBlocks.vtolFactory, new ItemStack(Items.steel, 10)); //new Recipe(units, UnitBlocks.vtolFactory, new ItemStack(Items.steel, 10));
//new Recipe(units, UnitBlocks.droneFactory, new ItemStack(Items.steel, 10)); //new Recipe(units, UnitBlocks.droneFactory, new ItemStack(Items.steel, 10));

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.content;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.fx.EnvironmentFx; import io.anuke.mindustry.content.fx.EnvironmentFx;
import io.anuke.mindustry.entities.StatusController.TransitionResult; import io.anuke.mindustry.entities.StatusController.StatusEntry;
import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.type.StatusEffect;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
@@ -12,7 +12,7 @@ import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class StatusEffects implements ContentList { public class StatusEffects implements ContentList {
public static StatusEffect none, burning, freezing, wet, melting, oiled; public static StatusEffect none, burning, freezing, wet, melting, tarred, overdrive, shielded;
@Override @Override
public void load() { public void load() {
@@ -25,11 +25,11 @@ public class StatusEffects implements ContentList {
} }
@Override @Override
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result) { public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
if (to == oiled) { if (to == tarred) {
unit.damage(1f); unit.damage(1f);
Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
return result.set(this, Math.min(time + newTime, baseDuration + oiled.baseDuration)); return result.set(this, Math.min(time + newTime, baseDuration + tarred.baseDuration));
} }
return super.getTransition(unit, to, time, newTime, result); return super.getTransition(unit, to, time, newTime, result);
@@ -49,11 +49,11 @@ public class StatusEffects implements ContentList {
freezing = new StatusEffect(5 * 60f) { freezing = new StatusEffect(5 * 60f) {
{ {
oppositeScale = 0.4f; oppositeScale = 0.4f;
speedMultiplier = 0.7f;
} }
@Override @Override
public void update(Unit unit, float time) { public void update(Unit unit, float time) {
unit.getVelocity().scl(0.7f);
if (Mathf.chance(Timers.delta() * 0.15f)) { if (Mathf.chance(Timers.delta() * 0.15f)) {
Effects.effect(EnvironmentFx.freezing, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); Effects.effect(EnvironmentFx.freezing, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
@@ -64,6 +64,7 @@ public class StatusEffects implements ContentList {
wet = new StatusEffect(3 * 60f) { wet = new StatusEffect(3 * 60f) {
{ {
oppositeScale = 0.5f; oppositeScale = 0.5f;
speedMultiplier = 0.999f;
} }
@Override @Override
@@ -71,19 +72,19 @@ public class StatusEffects implements ContentList {
if (Mathf.chance(Timers.delta() * 0.15f)) { if (Mathf.chance(Timers.delta() * 0.15f)) {
Effects.effect(EnvironmentFx.wet, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); Effects.effect(EnvironmentFx.wet, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
} }
unit.getVelocity().scl(0.999f);
} }
}; };
melting = new StatusEffect(5 * 60f) { melting = new StatusEffect(5 * 60f) {
{ {
oppositeScale = 0.2f; oppositeScale = 0.2f;
speedMultiplier = 0.8f;
armorMultiplier = 0.8f;
} }
@Override @Override
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result) { public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
if (to == oiled) { if (to == tarred) {
return result.set(this, Math.min(time + newTime / 2f, baseDuration)); return result.set(this, Math.min(time + newTime / 2f, baseDuration));
} }
@@ -92,7 +93,6 @@ public class StatusEffects implements ContentList {
@Override @Override
public void update(Unit unit, float time) { public void update(Unit unit, float time) {
unit.getVelocity().scl(0.8f);
unit.damagePeriodic(0.1f); unit.damagePeriodic(0.1f);
if (Mathf.chance(Timers.delta() * 0.2f)) { if (Mathf.chance(Timers.delta() * 0.2f)) {
@@ -101,18 +101,20 @@ public class StatusEffects implements ContentList {
} }
}; };
oiled = new StatusEffect(4 * 60f) { tarred = new StatusEffect(4 * 60f) {
{
speedMultiplier = 0.6f;
}
@Override @Override
public void update(Unit unit, float time) { public void update(Unit unit, float time) {
if (Mathf.chance(Timers.delta() * 0.15f)) { if (Mathf.chance(Timers.delta() * 0.15f)) {
Effects.effect(EnvironmentFx.oily, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f)); Effects.effect(EnvironmentFx.oily, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
} }
unit.getVelocity().scl(0.6f);
} }
@Override @Override
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result) { public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
if (to == melting || to == burning) { if (to == melting || to == burning) {
return result.set(to, newTime + time); return result.set(to, newTime + time);
} }
@@ -121,6 +123,26 @@ public class StatusEffects implements ContentList {
} }
}; };
overdrive = new StatusEffect(6f) {
{
armorMultiplier = 0.95f;
speedMultiplier = 1.4f;
damageMultiplier = 1.4f;
}
@Override
public void update(Unit unit, float time) {
//idle regen boosted
unit.health += 0.01f * Timers.delta();
}
};
shielded = new StatusEffect(6f) {
{
armorMultiplier = 3f;
}
};
melting.setOpposites(wet, freezing); melting.setOpposites(wet, freezing);
wet.setOpposites(burning); wet.setOpposites(burning);
freezing.setOpposites(burning, melting); freezing.setOpposites(burning, melting);

View File

@@ -86,7 +86,7 @@ public class Blocks extends BlockList implements ContentList{
oil = new Floor("oil") {{ oil = new Floor("oil") {{
placeableOn = false; placeableOn = false;
liquidColor = Color.valueOf("292929"); liquidColor = Color.valueOf("292929");
status = StatusEffects.oiled; status = StatusEffects.tarred;
statusIntensity = 1f; statusIntensity = 1f;
speedMultiplier = 0.2f; speedMultiplier = 0.2f;
variants = 0; variants = 0;

View File

@@ -50,6 +50,9 @@ public class DebugBlocks extends BlockList implements ContentList{
}; };
itemSource = new Sorter("itemsource") { itemSource = new Sorter("itemsource") {
{
hasItems = true;
}
@Override @Override
public void update(Tile tile) { public void update(Tile tile) {
SorterEntity entity = tile.entity(); SorterEntity entity = tile.entity();

View File

@@ -3,93 +3,73 @@ package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.ContentList;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.defense.RepairTurret;
import io.anuke.mindustry.world.blocks.defense.ShieldBlock;
import io.anuke.mindustry.world.blocks.distribution.WarpGate; import io.anuke.mindustry.world.blocks.distribution.WarpGate;
import io.anuke.mindustry.world.blocks.power.*; import io.anuke.mindustry.world.blocks.power.*;
public class PowerBlocks extends BlockList implements ContentList { public class PowerBlocks extends BlockList implements ContentList {
public static Block combustiongenerator, thermalgenerator, liquidcombustiongenerator, rtgenerator, solarpanel, largesolarpanel, public static Block combustiongenerator, thermalgenerator, turbinegenerator, rtgenerator, solarpanel, largesolarpanel,
nuclearReactor, fusionReactor, repairturret, megarepairturret, shieldgenerator, battery, batteryLarge, powernode, powernodelarge, warpgate; nuclearReactor, fusionReactor, battery, batteryLarge, powernode, powernodelarge, warpgate;
@Override @Override
public void load() { public void load() {
combustiongenerator = new BurnerGenerator("combustiongenerator") {{ combustiongenerator = new BurnerGenerator("combustion-generator") {{
powerOutput = 0.04f; powerOutput = 0.04f;
powerCapacity = 40f; powerCapacity = 40f;
}}; }};
thermalgenerator = new LiquidHeatGenerator("thermalgenerator") {{ thermalgenerator = new LiquidHeatGenerator("thermal-generator") {{
maxLiquidGenerate = 0.5f; maxLiquidGenerate = 0.5f;
powerPerLiquid = 0.08f; powerPerLiquid = 0.08f;
powerCapacity = 40f; powerCapacity = 40f;
generateEffect = BlockFx.redgeneratespark; generateEffect = BlockFx.redgeneratespark;
size = 2;
}}; }};
liquidcombustiongenerator = new LiquidBurnerGenerator("liquidcombustiongenerator") {{ turbinegenerator = new TurbineGenerator("turbine-generator") {{
maxLiquidGenerate = 0.4f; powerOutput = 0.04f;
powerPerLiquid = 0.12f;
powerCapacity = 40f; powerCapacity = 40f;
size = 2;
}}; }};
rtgenerator = new DecayGenerator("rtgenerator") {{ rtgenerator = new DecayGenerator("rtg-generator") {{
powerCapacity = 40f; powerCapacity = 40f;
powerOutput = 0.02f; powerOutput = 0.02f;
itemDuration = 500f; itemDuration = 500f;
}}; }};
solarpanel = new SolarGenerator("solarpanel") {{ solarpanel = new SolarGenerator("solar-panel") {{
generation = 0.003f; generation = 0.003f;
}}; }};
largesolarpanel = new SolarGenerator("largesolarpanel") {{ largesolarpanel = new SolarGenerator("large-solar-panel") {{
size = 3; size = 3;
generation = 0.012f; generation = 0.012f;
}}; }};
nuclearReactor = new NuclearReactor("nuclearreactor") {{ nuclearReactor = new NuclearReactor("nuclear-reactor") {{
size = 3; size = 3;
health = 600; health = 600;
}}; }};
fusionReactor = new FusionReactor("fusionreactor") {{ fusionReactor = new FusionReactor("fusion-reactor") {{
size = 4; size = 4;
health = 600; health = 600;
}}; }};
repairturret = new RepairTurret("repairturret") {{
range = 30;
reload = 20f;
health = 60;
powerUsed = 0.08f;
}};
megarepairturret = new RepairTurret("megarepairturret") {{
range = 44;
reload = 12f;
health = 90;
powerUsed = 0.13f;
size = 2;
}};
shieldgenerator = new ShieldBlock("shieldgenerator") {{
health = 400;
}};
battery = new PowerGenerator("battery") {{ battery = new PowerGenerator("battery") {{
powerCapacity = 320f; powerCapacity = 320f;
}}; }};
batteryLarge = new PowerGenerator("batterylarge") {{ batteryLarge = new PowerGenerator("battery-large") {{
size = 3; size = 3;
powerCapacity = 2000f; powerCapacity = 2000f;
}}; }};
powernode = new PowerDistributor("powernode") {{ powernode = new PowerDistributor("power-node") {{
shadow = "shadow-round-1"; shadow = "shadow-round-1";
}}; }};
powernodelarge = new PowerDistributor("powernodelarge") {{ powernodelarge = new PowerDistributor("power-node-large") {{
size = 2; size = 2;
powerSpeed = 1f; powerSpeed = 1f;
maxNodes = 5; maxNodes = 5;

View File

@@ -156,7 +156,7 @@ public class TurretBullets extends BulletList implements ContentList {
{ {
speed = 2f; speed = 2f;
drag = 0.03f; drag = 0.03f;
status = StatusEffects.oiled; status = StatusEffects.tarred;
statusIntensity = 0.5f; statusIntensity = 0.5f;
} }
}; };

View File

@@ -142,7 +142,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
@Override @Override
public float getArmor() { public float getArmor() {
return 0f; return mech.armor;
} }
@Override @Override
@@ -172,7 +172,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
@Override @Override
public void damage(float amount){ public void damage(float amount){
CallEntity.onPlayerDamage(this, amount); CallEntity.onPlayerDamage(this, calculateDamage(amount));
if(health <= 0 && !dead && isLocal){ if(health <= 0 && !dead && isLocal){
CallEntity.onPlayerDeath(this); CallEntity.onPlayerDeath(this);

View File

@@ -1,69 +1,136 @@
package io.anuke.mindustry.entities; package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pools;
import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.entities.traits.Saveable;
import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.type.StatusEffect;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**Class for controlling status effects on an entity.*/ /**Class for controlling status effects on an entity.*/
public class StatusController { public class StatusController implements Saveable{
private static final TransitionResult globalResult = new TransitionResult(); private static final StatusEntry globalResult = new StatusEntry();
private static final Array<StatusEntry> removals = new Array<>();
private io.anuke.mindustry.type.StatusEffect current = StatusEffects.none; private Array<StatusEntry> statuses = new Array<>();
private float time;
public void handleApply(Unit unit, io.anuke.mindustry.type.StatusEffect effect, float intensity){ private float speedMultiplier;
private float damageMultiplier;
private float armorMultiplier;
public void handleApply(Unit unit, StatusEffect effect, float intensity){
if(effect == StatusEffects.none) return; //don't apply empty effects if(effect == StatusEffects.none) return; //don't apply empty effects
float newTime = effect.baseDuration*intensity; float newTime = effect.baseDuration*intensity;
if(effect == current){ if(statuses.size > 0){
time = Math.max(time, newTime); //check for opposite effects
}else { for(StatusEntry entry : statuses){
//extend effect
if(entry.effect == effect) {
entry.time = Math.max(entry.time, newTime);
return;
}else if(entry.effect.isOpposite(effect)){ //find opposite
entry.effect.getTransition(unit, effect, entry.time, newTime, globalResult);
entry.time = globalResult.time;
current.getTransition(unit, effect, time, newTime, globalResult); if (globalResult.effect != entry.effect) {
time = globalResult.time; entry.effect.onTransition(unit, globalResult.effect);
entry.effect = globalResult.effect;
}
if (globalResult.result != current) { //stop looking when one is found
current.onTransition(unit, globalResult.result); return;
current = globalResult.result; }
} }
} }
//otherwise, no opposites found, add direct effect
StatusEntry entry = Pools.obtain(StatusEntry.class);
entry.set(effect, newTime);
statuses.add(entry);
} }
public void clear(){ public void clear(){
current = StatusEffects.none; statuses.clear();
time = 0f;
} }
public void update(Unit unit){ public void update(Unit unit){
time = Math.max(time - Timers.delta(), 0); speedMultiplier = damageMultiplier = armorMultiplier = 1f;
if(time <= 0){ if(statuses.size == 0) return;
current = StatusEffects.none;
}else{ removals.clear();
current.update(unit, time);
for(StatusEntry entry : statuses){
entry.time = Math.max(entry.time - Timers.delta(), 0);
if(entry.time <= 0){
Pools.free(entry);
removals.add(entry);
}else{
speedMultiplier *= entry.effect.speedMultiplier;
armorMultiplier *= entry.effect.armorMultiplier;
damageMultiplier *= entry.effect.damageMultiplier;
entry.effect.update(unit, entry.time);
}
}
if(removals.size > 0){
statuses.removeAll(removals, true);
} }
} }
public void set(io.anuke.mindustry.type.StatusEffect current, float time){ public float getSpeedMultiplier(){
this.current = current; return speedMultiplier;
this.time = time;
} }
public io.anuke.mindustry.type.StatusEffect current() { public float getDamageMultiplier(){
return current; return damageMultiplier;
} }
public float getTime() { public float getArmorMultiplier() {
return time; return armorMultiplier;
} }
public static class TransitionResult{ public boolean hasEffect(StatusEffect effect){
public io.anuke.mindustry.type.StatusEffect result; for(StatusEntry entry : statuses){
if(entry.effect == effect) return true;
}
return false;
}
@Override
public void writeSave(DataOutput stream) throws IOException {
stream.writeByte(statuses.size);
for(StatusEntry entry : statuses){
stream.writeByte(entry.effect.id);
stream.writeShort((short)(entry.time * 2));
}
}
@Override
public void readSave(DataInput stream) throws IOException {
byte amount = stream.readByte();
for (int i = 0; i < amount; i++) {
byte id = stream.readByte();
float time = stream.readShort() / 2f;
StatusEntry entry = Pools.obtain(StatusEntry.class);
entry.set(StatusEffect.getByID(id), time);
statuses.add(entry);
}
}
public static class StatusEntry {
public StatusEffect effect;
public float time; public float time;
public TransitionResult set(StatusEffect effect, float time){ public StatusEntry set(StatusEffect effect, float time){
this.result = effect; this.effect = effect;
this.time = time; this.time = time;
return this; return this;
} }

View File

@@ -81,7 +81,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
@Override @Override
public void damage(float amount){ public void damage(float amount){
super.damage(amount * Mathf.clamp(1f-getArmor()/100f)); super.damage(calculateDamage(amount));
hitTime = hitDuration; hitTime = hitDuration;
} }
@@ -117,17 +117,15 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
byte yv = stream.readByte(); byte yv = stream.readByte();
float rotation = stream.readShort()/2f; float rotation = stream.readShort()/2f;
int health = stream.readShort(); int health = stream.readShort();
byte effect = stream.readByte();
float etime = stream.readShort()/2f;
this.inventory.read(stream); this.status.readSave(stream);
this.inventory.readSave(stream);
this.team = Team.values()[team]; this.team = Team.values()[team];
this.health = health; this.health = health;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.velocity.set(xv / velocityPercision, yv / velocityPercision); this.velocity.set(xv / velocityPercision, yv / velocityPercision);
this.rotation = rotation; this.rotation = rotation;
this.status.set(StatusEffect.getByID(effect), etime);
} }
public void writeSave(DataOutput stream, boolean net) throws IOException { public void writeSave(DataOutput stream, boolean net) throws IOException {
@@ -138,13 +136,20 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
stream.writeByte((byte)(Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); stream.writeByte((byte)(Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision));
stream.writeShort((short)(rotation*2)); stream.writeShort((short)(rotation*2));
stream.writeShort((short)health); stream.writeShort((short)health);
stream.writeByte(status.current().id); status.writeSave(stream);
stream.writeShort((short)(status.getTime()*2)); inventory.writeSave(stream);
inventory.write(stream);
} }
public StatusEffect getStatus(){ public float calculateDamage(float amount){
return status.current(); return amount * Mathf.clamp(1f-getArmor()/100f*status.getArmorMultiplier());
}
public float getDamageMultipler(){
return status.getDamageMultiplier();
}
public boolean hasEffect(StatusEffect effect){
return status.hasEffect(effect);
} }
public TileEntity getClosestCore(){ public TileEntity getClosestCore(){
@@ -178,10 +183,10 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
Floor floor = getFloorOn(); Floor floor = getFloorOn();
Tile tile = world.tileWorld(x, y); Tile tile = world.tileWorld(x, y);
velocity.limit(maxVelocity);
status.update(this); status.update(this);
velocity.limit(maxVelocity).scl(status.getSpeedMultiplier());
if(isFlying()) { if(isFlying()) {
x += velocity.x / getMass() * Timers.delta(); x += velocity.x / getMass() * Timers.delta();
y += velocity.y / getMass() * Timers.delta(); y += velocity.y / getMass() * Timers.delta();

View File

@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.traits.Saveable;
import io.anuke.mindustry.type.AmmoEntry; import io.anuke.mindustry.type.AmmoEntry;
import io.anuke.mindustry.type.AmmoType; import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
@@ -9,7 +10,7 @@ import io.anuke.mindustry.type.ItemStack;
import java.io.*; import java.io.*;
public class UnitInventory { public class UnitInventory implements Saveable{
private Array<AmmoEntry> ammos = new Array<>(); private Array<AmmoEntry> ammos = new Array<>();
private int totalAmmo; private int totalAmmo;
private ItemStack item = new ItemStack(Items.stone, 0); private ItemStack item = new ItemStack(Items.stone, 0);
@@ -30,7 +31,8 @@ public class UnitInventory {
infiniteAmmo = infinite; infiniteAmmo = infinite;
} }
public void write(DataOutput stream) throws IOException { @Override
public void writeSave(DataOutput stream) throws IOException {
stream.writeShort(item.amount); stream.writeShort(item.amount);
stream.writeByte(item.item.id); stream.writeByte(item.item.id);
stream.writeBoolean(infiniteAmmo); stream.writeBoolean(infiniteAmmo);
@@ -42,7 +44,8 @@ public class UnitInventory {
} }
} }
public void read(DataInput stream) throws IOException { @Override
public void readSave(DataInput stream) throws IOException {
short iamount = stream.readShort(); short iamount = stream.readShort();
byte iid = stream.readByte(); byte iid = stream.readByte();
infiniteAmmo = stream.readBoolean(); infiniteAmmo = stream.readBoolean();

View File

@@ -100,6 +100,15 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
return data; return data;
} }
@Override
public float getDamage(){
if(owner instanceof Unit){
return super.getDamage() * ((Unit) owner).getDamageMultipler();
}
return super.getDamage();
}
@Override @Override
public int getTypeID() { public int getTypeID() {
return typeID; return typeID;

View File

@@ -89,7 +89,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait{
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){ if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
float result = damage; float result = damage;
if(entity.getStatus() == StatusEffects.wet) if(entity.hasEffect(StatusEffects.wet))
result = (result * wetDamageMultiplier); result = (result * wetDamageMultiplier);
entity.damage(result); entity.damage(result);

View File

@@ -2,12 +2,6 @@ package io.anuke.mindustry.entities.traits;
import io.anuke.ucore.entities.trait.Entity; import io.anuke.ucore.entities.trait.Entity;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**Marks an entity as serializable.*/ /**Marks an entity as serializable.*/
public interface SaveTrait extends Entity, TypeTrait{ public interface SaveTrait extends Entity, TypeTrait, Saveable{
void writeSave(DataOutput stream) throws IOException;
void readSave(DataInput stream) throws IOException;
} }

View File

@@ -0,0 +1,10 @@
package io.anuke.mindustry.entities.traits;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public interface Saveable {
void writeSave(DataOutput stream) throws IOException;
void readSave(DataInput stream) throws IOException;
}

View File

@@ -11,6 +11,7 @@ public class Mech extends Upgrade {
public float mass = 1f; public float mass = 1f;
public int drillPower = -1; public int drillPower = -1;
public float carryWeight = 1f; public float carryWeight = 1f;
public float armor = 1f;
public Weapon weapon = Weapons.blaster; public Weapon weapon = Weapons.blaster;
public TextureRegion baseRegion, legRegion, region; public TextureRegion baseRegion, legRegion, region;

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet; import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.StatusController.TransitionResult; import io.anuke.mindustry.entities.StatusController.StatusEntry;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Content;
@@ -14,6 +14,10 @@ public class StatusEffect implements Content{
public final float baseDuration; public final float baseDuration;
public final int id; public final int id;
public float damageMultiplier; //damage dealt
public float armorMultiplier; //armor points
public float speedMultiplier; //speed
/**Set of 'opposite' effects, which will decrease the duration of this effect when applied.*/ /**Set of 'opposite' effects, which will decrease the duration of this effect when applied.*/
protected ObjectSet<StatusEffect> opposites = new ObjectSet<>(); protected ObjectSet<StatusEffect> opposites = new ObjectSet<>();
/**The strength of time decrease when met with an opposite effect, as a fraction of the other's duration.*/ /**The strength of time decrease when met with an opposite effect, as a fraction of the other's duration.*/
@@ -33,7 +37,7 @@ public class StatusEffect implements Content{
* @param to The state to transition to * @param to The state to transition to
* @param time The current status effect time * @param time The current status effect time
* @param newTime The time that the new status effect will last*/ * @param newTime The time that the new status effect will last*/
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result){ public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result){
if(opposites.contains(to)){ if(opposites.contains(to)){
time -= newTime*oppositeScale; time -= newTime*oppositeScale;
if(time > 0) { if(time > 0) {
@@ -47,6 +51,10 @@ public class StatusEffect implements Content{
/**Called when this effect transitions to a new status effect.*/ /**Called when this effect transitions to a new status effect.*/
public void onTransition(Unit unit, StatusEffect to){} public void onTransition(Unit unit, StatusEffect to){}
public boolean isOpposite(StatusEffect other){
return opposites.size > 0 && opposites.contains(other);
}
public void setOpposites(StatusEffect... effects){ public void setOpposites(StatusEffect... effects){
for(StatusEffect e : effects){ for(StatusEffect e : effects){
opposites.add(e); opposites.add(e);

View File

@@ -59,6 +59,10 @@ public abstract class BaseBlock {
&& (tile.entity.liquids.liquid == liquid || tile.entity.liquids.amount <= 0.1f); && (tile.entity.liquids.liquid == liquid || tile.entity.liquids.amount <= 0.1f);
} }
public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return 0f;
}
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
tile.entity.liquids.liquid = liquid; tile.entity.liquids.liquid = liquid;
tile.entity.liquids.amount += amount; tile.entity.liquids.amount += amount;
@@ -118,31 +122,36 @@ public abstract class BaseBlock {
next = next.target(); next = next.target();
if(next.block().hasLiquids && tile.entity.liquids.amount > 0f){ if(next.block().hasLiquids && tile.entity.liquids.amount > 0f){
float ofract = next.entity.liquids.amount / next.block().liquidCapacity; if(next.entity.liquids.liquid == tile.entity.liquids.liquid) {
float fract = tile.entity.liquids.amount / liquidCapacity; float ofract = next.entity.liquids.amount / next.block().liquidCapacity;
float flow = Math.min(Mathf.clamp((fract - ofract)*(1f)) * (liquidCapacity), tile.entity.liquids.amount); float fract = tile.entity.liquids.amount / liquidCapacity;
flow = Math.min(flow, next.block().liquidCapacity - next.entity.liquids.amount - 0.001f); float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (liquidCapacity), tile.entity.liquids.amount);
flow = Math.min(flow, next.block().liquidCapacity - next.entity.liquids.amount - 0.001f);
if(flow > 0f && ofract <= fract && next.block().acceptLiquid(next, tile, tile.entity.liquids.liquid, flow)){ if (flow > 0f && ofract <= fract && next.block().acceptLiquid(next, tile, tile.entity.liquids.liquid, flow)) {
next.block().handleLiquid(next, tile, tile.entity.liquids.liquid, flow); next.block().handleLiquid(next, tile, tile.entity.liquids.liquid, flow);
tile.entity.liquids.amount -= flow; tile.entity.liquids.amount -= flow;
return flow; return flow;
}else if(ofract > 0.1f && fract > 0.1f){ } else if (ofract > 0.1f && fract > 0.1f) {
Liquid liquid = tile.entity.liquids.liquid, other = next.entity.liquids.liquid; Liquid liquid = tile.entity.liquids.liquid, other = next.entity.liquids.liquid;
if((other.flammability > 0.3f && liquid.temperature > 0.7f) || if ((other.flammability > 0.3f && liquid.temperature > 0.7f) ||
(liquid.flammability > 0.3f && other.temperature > 0.7f)){ (liquid.flammability > 0.3f && other.temperature > 0.7f)) {
tile.entity.damage(1 * Timers.delta()); tile.entity.damage(1 * Timers.delta());
next.entity.damage(1 * Timers.delta()); next.entity.damage(1 * Timers.delta());
if(Mathf.chance(0.1 * Timers.delta())){ if (Mathf.chance(0.1 * Timers.delta())) {
Effects.effect(EnvironmentFx.fire, (tile.worldx() + next.worldx())/2f, (tile.worldy() + next.worldy())/2f); Effects.effect(EnvironmentFx.fire, (tile.worldx() + next.worldx()) / 2f, (tile.worldy() + next.worldy()) / 2f);
} }
}else if((liquid.temperature > 0.7f && other.temperature < 0.55f) || } else if ((liquid.temperature > 0.7f && other.temperature < 0.55f) ||
(other.temperature > 0.7f && liquid.temperature < 0.55f)){ (other.temperature > 0.7f && liquid.temperature < 0.55f)) {
tile.entity.liquids.amount -= Math.min(tile.entity.liquids.amount, 0.7f * Timers.delta()); tile.entity.liquids.amount -= Math.min(tile.entity.liquids.amount, 0.7f * Timers.delta());
if(Mathf.chance(0.2f * Timers.delta())){ if (Mathf.chance(0.2f * Timers.delta())) {
Effects.effect(EnvironmentFx.steam, (tile.worldx() + next.worldx())/2f, (tile.worldy() + next.worldy())/2f); Effects.effect(EnvironmentFx.steam, (tile.worldx() + next.worldx()) / 2f, (tile.worldy() + next.worldy()) / 2f);
}
} }
} }
}else{
float accepted = next.block().handleAuxLiquid(next, tile, tile.entity.liquids.liquid, tile.entity.liquids.amount);
tile.entity.liquids.amount -= accepted;
} }
}else if(leak && !next.block().solid && !next.block().hasLiquids){ }else if(leak && !next.block().solid && !next.block().hasLiquids){
float leakAmount = Math.min(tile.entity.liquids.amount, tile.entity.liquids.amount/1.5f); float leakAmount = Math.min(tile.entity.liquids.amount, tile.entity.liquids.amount/1.5f);

View File

@@ -1,120 +1,21 @@
package io.anuke.mindustry.world.blocks.power; package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
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.Mathf;
import java.io.DataInputStream; public class BurnerGenerator extends ItemLiquidGenerator {
import java.io.DataOutputStream;
import java.io.IOException;
public class BurnerGenerator extends PowerGenerator { public BurnerGenerator(String name) {
protected float minEfficiency = 0.2f; super(name);
protected float powerOutput; }
protected float itemDuration = 70f;
protected Effect generateEffect = BlockFx.generatespark;
protected Color heatColor = Color.valueOf("ff9b59");
public BurnerGenerator(String name) { @Override
super(name); protected float getLiquidEfficiency(Liquid liquid) {
itemCapacity = 20; return liquid.flammability;
hasItems = true; }
}
@Override
public void setBars(){
super.setBars();
bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.totalItems() / itemCapacity));
}
@Override
public void setStats(){
super.setStats();
//TODO both of these depend on the item type, implement later
//stats.add("powergenerationsecond", Strings.toFixed(powerOutput*60f, 2));
//stats.add("generationsecondsitem", Strings.toFixed(itemDuration/60f, 2));
}
@Override
public void draw(Tile tile){
super.draw(tile);
GeneratorEntity entity = tile.entity();
if(entity.generateTime > 0){
Draw.color(heatColor);
float alpha = (entity.items.totalItems() > 0 ? 1f : Mathf.clamp(entity.generateTime));
alpha = alpha * 0.7f + Mathf.absin(Timers.time(), 12f, 0.3f) * alpha;
Draw.alpha(alpha);
Draw.rect(name + "-top", tile.worldx(), tile.worldy());
Draw.reset();
}
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
return getItemEfficiency(item) >= minEfficiency && tile.entity.items.totalItems() < itemCapacity;
}
@Override
public void update(Tile tile){
BurnerEntity entity = tile.entity();
float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta()) * entity.efficiency;
float mfract = maxPower/(powerOutput);
if(entity.generateTime > 0f){
entity.generateTime -= 1f/itemDuration*mfract;
entity.power.amount += maxPower;
entity.generateTime = Mathf.clamp(entity.generateTime);
}
if(entity.generateTime <= 0f && entity.items.totalItems() > 0){
Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f));
for(int i = 0; i < entity.items.items.length; i ++){
if(entity.items.items[i] > 0){
entity.items.items[i] --;
entity.efficiency = getItemEfficiency(Item.getByID(i));
break;
}
}
entity.generateTime = 1f;
}
distributePower(tile);
}
protected float getItemEfficiency(Item item){
return item.flammability;
}
@Override
public TileEntity getEntity() {
return new BurnerEntity();
}
public static class BurnerEntity extends GeneratorEntity{
public float efficiency;
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeFloat(efficiency);
}
@Override
public void read(DataInputStream stream) throws IOException {
efficiency = stream.readFloat();
}
}
@Override
protected float getItemEfficiency(Item item) {
return item.flammability;
}
} }

View File

@@ -2,11 +2,12 @@ package io.anuke.mindustry.world.blocks.power;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
public class DecayGenerator extends BurnerGenerator { public class DecayGenerator extends ItemGenerator {
public DecayGenerator(String name) { public DecayGenerator(String name) {
super(name); super(name);
hasItems = true; hasItems = true;
hasLiquids = false;
} }
@Override @Override

View File

@@ -0,0 +1,110 @@
package io.anuke.mindustry.world.blocks.power;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
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.Mathf;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public abstract class ItemGenerator extends PowerGenerator {
protected float minItemEfficiency = 0.2f;
protected float powerOutput;
protected float itemDuration = 70f;
protected Effect generateEffect = BlockFx.generatespark;
protected Color heatColor = Color.valueOf("ff9b59");
public ItemGenerator(String name) {
super(name);
itemCapacity = 20;
hasItems = true;
}
@Override
public void setBars(){
super.setBars();
bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.totalItems() / itemCapacity));
}
@Override
public void draw(Tile tile){
super.draw(tile);
GeneratorEntity entity = tile.entity();
if(entity.generateTime > 0){
Draw.color(heatColor);
float alpha = (entity.items.totalItems() > 0 ? 1f : Mathf.clamp(entity.generateTime));
alpha = alpha * 0.7f + Mathf.absin(Timers.time(), 12f, 0.3f) * alpha;
Draw.alpha(alpha);
Draw.rect(name + "-top", tile.worldx(), tile.worldy());
Draw.reset();
}
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
return getItemEfficiency(item) >= minItemEfficiency && tile.entity.items.totalItems() < itemCapacity;
}
@Override
public void update(Tile tile){
ItemGeneratorEntity entity = tile.entity();
float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta()) * entity.efficiency;
float mfract = maxPower/(powerOutput);
if(entity.generateTime > 0f){
entity.generateTime -= 1f/itemDuration*mfract;
entity.power.amount += maxPower;
entity.generateTime = Mathf.clamp(entity.generateTime);
}
if(entity.generateTime <= 0f && entity.items.totalItems() > 0){
Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f));
for(int i = 0; i < entity.items.items.length; i ++){
if(entity.items.items[i] > 0){
entity.items.items[i] --;
entity.efficiency = getItemEfficiency(Item.getByID(i));
break;
}
}
entity.generateTime = 1f;
}
distributePower(tile);
}
protected abstract float getItemEfficiency(Item item);
@Override
public TileEntity getEntity() {
return new ItemGeneratorEntity();
}
public static class ItemGeneratorEntity extends GeneratorEntity{
public float efficiency;
@Override
public void write(DataOutputStream stream) throws IOException {
stream.writeFloat(efficiency);
}
@Override
public void read(DataInputStream stream) throws IOException {
efficiency = stream.readFloat();
}
}
}

View File

@@ -0,0 +1,89 @@
package io.anuke.mindustry.world.blocks.power;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
public abstract class ItemLiquidGenerator extends ItemGenerator {
protected float minLiquidEfficiency = 0.2f;
protected float powerPerLiquid = 0.13f;
/**Maximum liquid used per frame.*/
protected float maxLiquidGenerate = 0.4f;
public ItemLiquidGenerator(String name) {
super(name);
hasLiquids = true;
liquidCapacity = 10f;
}
@Override
public void update(Tile tile){
ItemGeneratorEntity entity = tile.entity();
//liquid takes priority over solids
if(entity.liquids.amount >= 0.001f){
float powerPerLiquid = getLiquidEfficiency(entity.liquids.liquid)*this.powerPerLiquid;
float used = Math.min(entity.liquids.amount, maxLiquidGenerate * Timers.delta());
used = Math.min(used, (powerCapacity - entity.power.amount)/powerPerLiquid);
entity.liquids.amount -= used;
entity.power.amount += used * powerPerLiquid;
if(used > 0.001f && Mathf.chance(0.05 * Timers.delta())){
Effects.effect(generateEffect, tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f));
}
}else {
float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * Timers.delta()) * entity.efficiency;
float mfract = maxPower / (powerOutput);
if (entity.generateTime > 0f) {
entity.generateTime -= 1f / itemDuration * mfract;
entity.power.amount += maxPower;
entity.generateTime = Mathf.clamp(entity.generateTime);
}
if (entity.generateTime <= 0f && entity.items.totalItems() > 0) {
Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f));
for (int i = 0; i < entity.items.items.length; i++) {
if (entity.items.items[i] > 0) {
entity.items.items[i]--;
entity.efficiency = getItemEfficiency(Item.getByID(i));
break;
}
}
entity.generateTime = 1f;
}
}
distributePower(tile);
}
@Override
public void draw(Tile tile){
super.draw(tile);
TileEntity entity = tile.entity();
Draw.color(entity.liquids.liquid.color);
Draw.alpha(entity.liquids.amount / liquidCapacity);
drawLiquidCenter(tile);
Draw.color();
}
public void drawLiquidCenter(Tile tile){
Draw.rect("blank", tile.drawx(), tile.drawy(), 2, 2);
}
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return getLiquidEfficiency(liquid) >= minLiquidEfficiency && super.acceptLiquid(tile, source, liquid, amount);
}
protected abstract float getLiquidEfficiency(Liquid liquid);
}

View File

@@ -4,34 +4,26 @@ import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.power.BurnerGenerator.BurnerEntity; import io.anuke.mindustry.world.blocks.power.ItemGenerator.ItemGeneratorEntity;
import io.anuke.ucore.core.Effects; 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;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
//TODO remove this class public abstract class LiquidGenerator extends PowerGenerator {
public class LiquidBurnerGenerator extends PowerGenerator {
protected float minEfficiency = 0.2f; protected float minEfficiency = 0.2f;
protected float powerPerLiquid = 0.13f; protected float powerPerLiquid = 0.13f;
/**Maximum liquid used per frame.*/ /**Maximum liquid used per frame.*/
protected float maxLiquidGenerate = 0.4f; protected float maxLiquidGenerate = 0.4f;
protected Effect generateEffect = BlockFx.generatespark; protected Effect generateEffect = BlockFx.generatespark;
public LiquidBurnerGenerator(String name) { public LiquidGenerator(String name) {
super(name); super(name);
liquidCapacity = 30f; liquidCapacity = 30f;
hasLiquids = true; hasLiquids = true;
} }
@Override
public void setStats(){
super.setStats();
//stats.add("powerliquid", Strings.toFixed(powerPerLiquid, 2) + " power/liquid");
//stats.add("maxliquidsecond", Strings.toFixed(maxLiquidGenerate*60f, 2) + " liquid/s");
}
@Override @Override
public void draw(Tile tile){ public void draw(Tile tile){
super.draw(tile); super.draw(tile);
@@ -75,10 +67,11 @@ public class LiquidBurnerGenerator extends PowerGenerator {
@Override @Override
public TileEntity getEntity() { public TileEntity getEntity() {
return new BurnerEntity(); return new ItemGeneratorEntity();
} }
protected float getEfficiency(Liquid liquid){ /**Returns an efficiency value for the specified liquid.
return liquid.flammability; * Greater efficiency means more power generation.
} * If a liquid's efficiency is below {@link #minEfficiency}, it is not accepted.*/
protected abstract float getEfficiency(Liquid liquid);
} }

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.power;
import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Liquid;
public class LiquidHeatGenerator extends LiquidBurnerGenerator { public class LiquidHeatGenerator extends LiquidGenerator {
public LiquidHeatGenerator(String name) { public LiquidHeatGenerator(String name) {
super(name); super(name);
@@ -10,6 +10,6 @@ public class LiquidHeatGenerator extends LiquidBurnerGenerator {
@Override @Override
protected float getEfficiency(Liquid liquid){ protected float getEfficiency(Liquid liquid){
return liquid.flammability; return liquid.temperature-0.5f;
} }
} }

View File

@@ -24,7 +24,7 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.tilesize;
public class NuclearReactor extends LiquidBurnerGenerator { public class NuclearReactor extends PowerGenerator {
protected final int timerFuel = timers++; protected final int timerFuel = timers++;
protected final Translator tr = new Translator(); protected final Translator tr = new Translator();
@@ -112,11 +112,6 @@ public class NuclearReactor extends LiquidBurnerGenerator {
} }
} }
@Override
public void drawLiquidCenter(Tile tile){
Draw.rect(name + "-center", tile.drawx(), tile.drawy());
}
@Override @Override
public void onDestroyed(Tile tile){ public void onDestroyed(Tile tile){
super.onDestroyed(tile); super.onDestroyed(tile);

View File

@@ -0,0 +1,49 @@
package io.anuke.mindustry.world.blocks.power;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
public class TurbineGenerator extends BurnerGenerator {
protected float auxLiquidUse = 0.1f;
protected Liquid auxLiquid = Liquids.water;
protected float auxLiquidCapacity = 10;
public TurbineGenerator(String name) {
super(name);
}
@Override
public void update(Tile tile) {
TurbineEntity entity = tile.entity();
float used = Math.min(auxLiquidUse * Timers.delta(), auxLiquidCapacity);
if(entity.aux >= used){
super.update(tile);
entity.aux -= used;
}
}
@Override
public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
TurbineEntity entity = tile.entity();
if(liquid == auxLiquid){
float accepted = Math.min(auxLiquidCapacity - entity.aux, amount);
entity.aux += accepted;
return accepted;
}else {
return 0;
}
}
@Override
public TileEntity getEntity() {
return new TurbineEntity();
}
public class TurbineEntity extends ItemGeneratorEntity{
public float aux;
}
}

View File

@@ -33,27 +33,30 @@ public class LiquidMixer extends LiquidBlock{
if(tile.entity.power.amount > used) tile.entity.power.amount -= used; if(tile.entity.power.amount > used) tile.entity.power.amount -= used;
} }
@Override
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
LiquidMixerEntity entity = tile.entity();
entity.accumulator += amount;
int items = (int)(entity.accumulator / liquidPerItem);
entity.items.removeItem(inputItem, items);
entity.accumulator %= liquidPerItem;
entity.liquids.liquid = outputLiquid;
entity.liquids.amount += amount;
}
@Override @Override
public boolean acceptItem(Item item, Tile tile, Tile source) { public boolean acceptItem(Item item, Tile tile, Tile source) {
return item == inputItem && tile.entity.items.getItem(item) < itemCapacity; return item == inputItem && tile.entity.items.getItem(item) < itemCapacity;
} }
@Override @Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
return liquid == inputLiquid && tile.entity.liquids.amount + amount <= liquidCapacity && LiquidMixerEntity entity = tile.entity();
tile.entity.items.hasItem(inputItem, (int)((tile.<LiquidMixerEntity>entity().accumulator + amount)/amount)) &&
tile.entity.power.amount >= powerUse; if(liquid == inputLiquid && tile.entity.items.hasItem(inputItem, (int)((entity.accumulator + amount)/amount)) &&
tile.entity.power.amount >= powerUse){
amount = Math.min(liquidCapacity - tile.entity.liquids.amount, amount);
entity.accumulator += amount;
int items = (int)(entity.accumulator / liquidPerItem);
entity.items.removeItem(inputItem, items);
entity.accumulator %= liquidPerItem;
entity.liquids.liquid = outputLiquid;
entity.liquids.amount += amount;
return amount;
}else{
return 0;
}
} }
@Override @Override

View File

@@ -1,8 +1,12 @@
package io.anuke.mindustry.world.blocks.units; package io.anuke.mindustry.world.blocks.units;
import io.anuke.mindustry.content.StatusEffects;
public class OverdriveProjector extends Projector { public class OverdriveProjector extends Projector {
public OverdriveProjector(String name) { public OverdriveProjector(String name) {
super(name); super(name);
status = StatusEffects.overdrive;
} }
} }

View File

@@ -1,20 +1,25 @@
package io.anuke.mindustry.world.blocks.units; package io.anuke.mindustry.world.blocks.units;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.type.StatusEffect;
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.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
public abstract class Projector extends Block { public abstract class Projector extends Block {
protected final int timerApply = timers++; protected final int timerApply = timers++;
protected final float applyTime = 4f; protected final float applyTime = 4f;
protected float powerUse = 0.01f; protected float powerUse = 0.01f;
protected float range = 40f; protected float range = 80f;
protected StatusEffect status; protected StatusEffect status;
protected float intensity; protected float intensity = 1f;
public Projector(String name) { public Projector(String name) {
super(name); super(name);
@@ -23,12 +28,39 @@ public abstract class Projector extends Block {
solid = true; solid = true;
} }
@Override
public void drawSelect(Tile tile){
Draw.color(Palette.accent);
Lines.dashCircle(tile.drawx(), tile.drawy(), range);
Draw.reset();
}
@Override @Override
public void update(Tile tile) { public void update(Tile tile) {
if(Timers.get(timerApply, applyTime)) { ProjectorEntity entity = tile.entity();
float used = Math.min(powerCapacity, powerUse * Timers.delta());
if(entity.power.amount >= used){
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.01f);
entity.power.amount -= used;
}else{
entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.01f);
}
if(entity.heat > 0.6f && Timers.get(timerApply, applyTime)) {
Units.getNearby(tile.getTeam(), tile.drawx(), tile.drawy(), range, unit -> { Units.getNearby(tile.getTeam(), tile.drawx(), tile.drawy(), range, unit -> {
unit.applyEffect(status, intensity); unit.applyEffect(status, intensity);
}); });
} }
} }
@Override
public TileEntity getEntity() {
return new ProjectorEntity();
}
public class ProjectorEntity extends TileEntity{
public float heat;
}
} }

View File

@@ -1,11 +1,12 @@
package io.anuke.mindustry.world.blocks.units; package io.anuke.mindustry.world.blocks.units;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.content.StatusEffects;
public class ShieldProjector extends Projector { public class ShieldProjector extends Projector {
public ShieldProjector(String name) { public ShieldProjector(String name) {
super(name); super(name);
hasPower = true;
status = StatusEffects.shielded;
} }
} }