New generators, projectors, status system, sprites renamed
This commit is contained in:
@@ -47,6 +47,7 @@ public class Items implements ContentList{
|
||||
type = ItemType.material;
|
||||
explosiveness = 0.1f;
|
||||
hardness = 4;
|
||||
radioactivity = 0.5f;
|
||||
}};
|
||||
|
||||
silicon = new Item("silicon", Color.valueOf("53565c")) {{
|
||||
|
||||
@@ -37,7 +37,7 @@ public class Liquids implements ContentList {
|
||||
flammability = 0.6f;
|
||||
explosiveness = 0.6f;
|
||||
tier = 1;
|
||||
effect = StatusEffects.oiled;
|
||||
effect = StatusEffects.tarred;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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.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.combustiongenerator, new ItemStack(Items.iron, 30));
|
||||
new Recipe(power, PowerBlocks.liquidcombustiongenerator, new ItemStack(Items.iron, 30));
|
||||
new Recipe(power, PowerBlocks.thermalgenerator, new ItemStack(Items.steel, 30));
|
||||
new Recipe(power, PowerBlocks.rtgenerator, new ItemStack(Items.titanium, 20), new ItemStack(Items.steel, 20));
|
||||
new Recipe(power, PowerBlocks.combustiongenerator, new ItemStack(Items.iron, 1));
|
||||
new Recipe(power, PowerBlocks.turbinegenerator, new ItemStack(Items.iron, 1));
|
||||
new Recipe(power, PowerBlocks.thermalgenerator, new ItemStack(Items.steel, 1));
|
||||
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.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.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(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.pulseconduit, new ItemStack(Items.titanium, 1), new ItemStack(Items.steel, 1));
|
||||
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.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.droneFactory, new ItemStack(Items.steel, 10));
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.anuke.mindustry.content;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
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.type.StatusEffect;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
@@ -12,7 +12,7 @@ import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
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
|
||||
public void load() {
|
||||
@@ -25,11 +25,11 @@ public class StatusEffects implements ContentList {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result) {
|
||||
if (to == oiled) {
|
||||
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
|
||||
if (to == tarred) {
|
||||
unit.damage(1f);
|
||||
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);
|
||||
@@ -49,11 +49,11 @@ public class StatusEffects implements ContentList {
|
||||
freezing = new StatusEffect(5 * 60f) {
|
||||
{
|
||||
oppositeScale = 0.4f;
|
||||
speedMultiplier = 0.7f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Unit unit, float time) {
|
||||
unit.getVelocity().scl(0.7f);
|
||||
|
||||
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));
|
||||
@@ -64,6 +64,7 @@ public class StatusEffects implements ContentList {
|
||||
wet = new StatusEffect(3 * 60f) {
|
||||
{
|
||||
oppositeScale = 0.5f;
|
||||
speedMultiplier = 0.999f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,19 +72,19 @@ public class StatusEffects implements ContentList {
|
||||
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));
|
||||
}
|
||||
|
||||
unit.getVelocity().scl(0.999f);
|
||||
}
|
||||
};
|
||||
|
||||
melting = new StatusEffect(5 * 60f) {
|
||||
{
|
||||
oppositeScale = 0.2f;
|
||||
speedMultiplier = 0.8f;
|
||||
armorMultiplier = 0.8f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result) {
|
||||
if (to == oiled) {
|
||||
public StatusEntry getTransition(Unit unit, StatusEffect to, float time, float newTime, StatusEntry result) {
|
||||
if (to == tarred) {
|
||||
return result.set(this, Math.min(time + newTime / 2f, baseDuration));
|
||||
}
|
||||
|
||||
@@ -92,7 +93,6 @@ public class StatusEffects implements ContentList {
|
||||
|
||||
@Override
|
||||
public void update(Unit unit, float time) {
|
||||
unit.getVelocity().scl(0.8f);
|
||||
unit.damagePeriodic(0.1f);
|
||||
|
||||
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
|
||||
public void update(Unit unit, float time) {
|
||||
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));
|
||||
}
|
||||
|
||||
unit.getVelocity().scl(0.6f);
|
||||
}
|
||||
|
||||
@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) {
|
||||
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);
|
||||
wet.setOpposites(burning);
|
||||
freezing.setOpposites(burning, melting);
|
||||
|
||||
@@ -86,7 +86,7 @@ public class Blocks extends BlockList implements ContentList{
|
||||
oil = new Floor("oil") {{
|
||||
placeableOn = false;
|
||||
liquidColor = Color.valueOf("292929");
|
||||
status = StatusEffects.oiled;
|
||||
status = StatusEffects.tarred;
|
||||
statusIntensity = 1f;
|
||||
speedMultiplier = 0.2f;
|
||||
variants = 0;
|
||||
|
||||
@@ -50,6 +50,9 @@ public class DebugBlocks extends BlockList implements ContentList{
|
||||
};
|
||||
|
||||
itemSource = new Sorter("itemsource") {
|
||||
{
|
||||
hasItems = true;
|
||||
}
|
||||
@Override
|
||||
public void update(Tile tile) {
|
||||
SorterEntity entity = tile.entity();
|
||||
|
||||
@@ -3,93 +3,73 @@ package io.anuke.mindustry.content.blocks;
|
||||
import io.anuke.mindustry.content.fx.BlockFx;
|
||||
import io.anuke.mindustry.type.ContentList;
|
||||
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.power.*;
|
||||
|
||||
public class PowerBlocks extends BlockList implements ContentList {
|
||||
public static Block combustiongenerator, thermalgenerator, liquidcombustiongenerator, rtgenerator, solarpanel, largesolarpanel,
|
||||
nuclearReactor, fusionReactor, repairturret, megarepairturret, shieldgenerator, battery, batteryLarge, powernode, powernodelarge, warpgate;
|
||||
public static Block combustiongenerator, thermalgenerator, turbinegenerator, rtgenerator, solarpanel, largesolarpanel,
|
||||
nuclearReactor, fusionReactor, battery, batteryLarge, powernode, powernodelarge, warpgate;
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
combustiongenerator = new BurnerGenerator("combustiongenerator") {{
|
||||
combustiongenerator = new BurnerGenerator("combustion-generator") {{
|
||||
powerOutput = 0.04f;
|
||||
powerCapacity = 40f;
|
||||
}};
|
||||
|
||||
thermalgenerator = new LiquidHeatGenerator("thermalgenerator") {{
|
||||
thermalgenerator = new LiquidHeatGenerator("thermal-generator") {{
|
||||
maxLiquidGenerate = 0.5f;
|
||||
powerPerLiquid = 0.08f;
|
||||
powerCapacity = 40f;
|
||||
generateEffect = BlockFx.redgeneratespark;
|
||||
size = 2;
|
||||
}};
|
||||
|
||||
liquidcombustiongenerator = new LiquidBurnerGenerator("liquidcombustiongenerator") {{
|
||||
maxLiquidGenerate = 0.4f;
|
||||
powerPerLiquid = 0.12f;
|
||||
turbinegenerator = new TurbineGenerator("turbine-generator") {{
|
||||
powerOutput = 0.04f;
|
||||
powerCapacity = 40f;
|
||||
size = 2;
|
||||
}};
|
||||
|
||||
rtgenerator = new DecayGenerator("rtgenerator") {{
|
||||
rtgenerator = new DecayGenerator("rtg-generator") {{
|
||||
powerCapacity = 40f;
|
||||
powerOutput = 0.02f;
|
||||
itemDuration = 500f;
|
||||
}};
|
||||
|
||||
solarpanel = new SolarGenerator("solarpanel") {{
|
||||
solarpanel = new SolarGenerator("solar-panel") {{
|
||||
generation = 0.003f;
|
||||
}};
|
||||
|
||||
largesolarpanel = new SolarGenerator("largesolarpanel") {{
|
||||
largesolarpanel = new SolarGenerator("large-solar-panel") {{
|
||||
size = 3;
|
||||
generation = 0.012f;
|
||||
}};
|
||||
|
||||
nuclearReactor = new NuclearReactor("nuclearreactor") {{
|
||||
nuclearReactor = new NuclearReactor("nuclear-reactor") {{
|
||||
size = 3;
|
||||
health = 600;
|
||||
}};
|
||||
|
||||
fusionReactor = new FusionReactor("fusionreactor") {{
|
||||
fusionReactor = new FusionReactor("fusion-reactor") {{
|
||||
size = 4;
|
||||
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") {{
|
||||
powerCapacity = 320f;
|
||||
}};
|
||||
|
||||
batteryLarge = new PowerGenerator("batterylarge") {{
|
||||
batteryLarge = new PowerGenerator("battery-large") {{
|
||||
size = 3;
|
||||
powerCapacity = 2000f;
|
||||
}};
|
||||
|
||||
powernode = new PowerDistributor("powernode") {{
|
||||
powernode = new PowerDistributor("power-node") {{
|
||||
shadow = "shadow-round-1";
|
||||
}};
|
||||
|
||||
powernodelarge = new PowerDistributor("powernodelarge") {{
|
||||
powernodelarge = new PowerDistributor("power-node-large") {{
|
||||
size = 2;
|
||||
powerSpeed = 1f;
|
||||
maxNodes = 5;
|
||||
|
||||
@@ -156,7 +156,7 @@ public class TurretBullets extends BulletList implements ContentList {
|
||||
{
|
||||
speed = 2f;
|
||||
drag = 0.03f;
|
||||
status = StatusEffects.oiled;
|
||||
status = StatusEffects.tarred;
|
||||
statusIntensity = 0.5f;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -142,7 +142,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
|
||||
@Override
|
||||
public float getArmor() {
|
||||
return 0f;
|
||||
return mech.armor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,7 +172,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
|
||||
@Override
|
||||
public void damage(float amount){
|
||||
CallEntity.onPlayerDamage(this, amount);
|
||||
CallEntity.onPlayerDamage(this, calculateDamage(amount));
|
||||
|
||||
if(health <= 0 && !dead && isLocal){
|
||||
CallEntity.onPlayerDeath(this);
|
||||
|
||||
@@ -1,69 +1,136 @@
|
||||
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.entities.traits.Saveable;
|
||||
import io.anuke.mindustry.type.StatusEffect;
|
||||
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.*/
|
||||
public class StatusController {
|
||||
private static final TransitionResult globalResult = new TransitionResult();
|
||||
public class StatusController implements Saveable{
|
||||
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 float time;
|
||||
private Array<StatusEntry> statuses = new Array<>();
|
||||
|
||||
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
|
||||
|
||||
float newTime = effect.baseDuration*intensity;
|
||||
|
||||
if(effect == current){
|
||||
time = Math.max(time, newTime);
|
||||
}else {
|
||||
if(statuses.size > 0){
|
||||
//check for opposite effects
|
||||
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);
|
||||
time = globalResult.time;
|
||||
if (globalResult.effect != entry.effect) {
|
||||
entry.effect.onTransition(unit, globalResult.effect);
|
||||
entry.effect = globalResult.effect;
|
||||
}
|
||||
|
||||
if (globalResult.result != current) {
|
||||
current.onTransition(unit, globalResult.result);
|
||||
current = globalResult.result;
|
||||
//stop looking when one is found
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, no opposites found, add direct effect
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class);
|
||||
entry.set(effect, newTime);
|
||||
statuses.add(entry);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
current = StatusEffects.none;
|
||||
time = 0f;
|
||||
statuses.clear();
|
||||
}
|
||||
|
||||
public void update(Unit unit){
|
||||
time = Math.max(time - Timers.delta(), 0);
|
||||
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
||||
|
||||
if(time <= 0){
|
||||
current = StatusEffects.none;
|
||||
}else{
|
||||
current.update(unit, time);
|
||||
if(statuses.size == 0) return;
|
||||
|
||||
removals.clear();
|
||||
|
||||
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){
|
||||
this.current = current;
|
||||
this.time = time;
|
||||
public float getSpeedMultiplier(){
|
||||
return speedMultiplier;
|
||||
}
|
||||
|
||||
public io.anuke.mindustry.type.StatusEffect current() {
|
||||
return current;
|
||||
public float getDamageMultiplier(){
|
||||
return damageMultiplier;
|
||||
}
|
||||
|
||||
public float getTime() {
|
||||
return time;
|
||||
public float getArmorMultiplier() {
|
||||
return armorMultiplier;
|
||||
}
|
||||
|
||||
public static class TransitionResult{
|
||||
public io.anuke.mindustry.type.StatusEffect result;
|
||||
public boolean hasEffect(StatusEffect effect){
|
||||
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 TransitionResult set(StatusEffect effect, float time){
|
||||
this.result = effect;
|
||||
public StatusEntry set(StatusEffect effect, float time){
|
||||
this.effect = effect;
|
||||
this.time = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
|
||||
@Override
|
||||
public void damage(float amount){
|
||||
super.damage(amount * Mathf.clamp(1f-getArmor()/100f));
|
||||
super.damage(calculateDamage(amount));
|
||||
hitTime = hitDuration;
|
||||
}
|
||||
|
||||
@@ -117,17 +117,15 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
byte yv = stream.readByte();
|
||||
float rotation = stream.readShort()/2f;
|
||||
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.health = health;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.velocity.set(xv / velocityPercision, yv / velocityPercision);
|
||||
this.rotation = rotation;
|
||||
this.status.set(StatusEffect.getByID(effect), etime);
|
||||
}
|
||||
|
||||
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.writeShort((short)(rotation*2));
|
||||
stream.writeShort((short)health);
|
||||
stream.writeByte(status.current().id);
|
||||
stream.writeShort((short)(status.getTime()*2));
|
||||
inventory.write(stream);
|
||||
status.writeSave(stream);
|
||||
inventory.writeSave(stream);
|
||||
}
|
||||
|
||||
public StatusEffect getStatus(){
|
||||
return status.current();
|
||||
public float calculateDamage(float amount){
|
||||
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(){
|
||||
@@ -178,10 +183,10 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
Floor floor = getFloorOn();
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
|
||||
velocity.limit(maxVelocity);
|
||||
|
||||
status.update(this);
|
||||
|
||||
velocity.limit(maxVelocity).scl(status.getSpeedMultiplier());
|
||||
|
||||
if(isFlying()) {
|
||||
x += velocity.x / getMass() * Timers.delta();
|
||||
y += velocity.y / getMass() * Timers.delta();
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.entities.traits.Saveable;
|
||||
import io.anuke.mindustry.type.AmmoEntry;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
@@ -9,7 +10,7 @@ import io.anuke.mindustry.type.ItemStack;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class UnitInventory {
|
||||
public class UnitInventory implements Saveable{
|
||||
private Array<AmmoEntry> ammos = new Array<>();
|
||||
private int totalAmmo;
|
||||
private ItemStack item = new ItemStack(Items.stone, 0);
|
||||
@@ -30,7 +31,8 @@ public class UnitInventory {
|
||||
infiniteAmmo = infinite;
|
||||
}
|
||||
|
||||
public void write(DataOutput stream) throws IOException {
|
||||
@Override
|
||||
public void writeSave(DataOutput stream) throws IOException {
|
||||
stream.writeShort(item.amount);
|
||||
stream.writeByte(item.item.id);
|
||||
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();
|
||||
byte iid = stream.readByte();
|
||||
infiniteAmmo = stream.readBoolean();
|
||||
|
||||
@@ -100,6 +100,15 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDamage(){
|
||||
if(owner instanceof Unit){
|
||||
return super.getDamage() * ((Unit) owner).getDamageMultipler();
|
||||
}
|
||||
|
||||
return super.getDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeID() {
|
||||
return typeID;
|
||||
|
||||
@@ -89,7 +89,7 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait{
|
||||
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
|
||||
float result = damage;
|
||||
|
||||
if(entity.getStatus() == StatusEffects.wet)
|
||||
if(entity.hasEffect(StatusEffects.wet))
|
||||
result = (result * wetDamageMultiplier);
|
||||
|
||||
entity.damage(result);
|
||||
|
||||
@@ -2,12 +2,6 @@ package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import io.anuke.ucore.entities.trait.Entity;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**Marks an entity as serializable.*/
|
||||
public interface SaveTrait extends Entity, TypeTrait{
|
||||
void writeSave(DataOutput stream) throws IOException;
|
||||
void readSave(DataInput stream) throws IOException;
|
||||
public interface SaveTrait extends Entity, TypeTrait, Saveable{
|
||||
}
|
||||
|
||||
10
core/src/io/anuke/mindustry/entities/traits/Saveable.java
Normal file
10
core/src/io/anuke/mindustry/entities/traits/Saveable.java
Normal 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;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ public class Mech extends Upgrade {
|
||||
public float mass = 1f;
|
||||
public int drillPower = -1;
|
||||
public float carryWeight = 1f;
|
||||
public float armor = 1f;
|
||||
public Weapon weapon = Weapons.blaster;
|
||||
|
||||
public TextureRegion baseRegion, legRegion, region;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.anuke.mindustry.type;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
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.game.Content;
|
||||
|
||||
@@ -14,6 +14,10 @@ public class StatusEffect implements Content{
|
||||
public final float baseDuration;
|
||||
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.*/
|
||||
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.*/
|
||||
@@ -33,7 +37,7 @@ public class StatusEffect implements Content{
|
||||
* @param to The state to transition to
|
||||
* @param time The current status effect time
|
||||
* @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)){
|
||||
time -= newTime*oppositeScale;
|
||||
if(time > 0) {
|
||||
@@ -47,6 +51,10 @@ public class StatusEffect implements Content{
|
||||
/**Called when this effect transitions to a new status effect.*/
|
||||
public void onTransition(Unit unit, StatusEffect to){}
|
||||
|
||||
public boolean isOpposite(StatusEffect other){
|
||||
return opposites.size > 0 && opposites.contains(other);
|
||||
}
|
||||
|
||||
public void setOpposites(StatusEffect... effects){
|
||||
for(StatusEffect e : effects){
|
||||
opposites.add(e);
|
||||
|
||||
@@ -59,6 +59,10 @@ public abstract class BaseBlock {
|
||||
&& (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){
|
||||
tile.entity.liquids.liquid = liquid;
|
||||
tile.entity.liquids.amount += amount;
|
||||
@@ -118,31 +122,36 @@ public abstract class BaseBlock {
|
||||
next = next.target();
|
||||
|
||||
if(next.block().hasLiquids && tile.entity.liquids.amount > 0f){
|
||||
float ofract = next.entity.liquids.amount / next.block().liquidCapacity;
|
||||
float fract = tile.entity.liquids.amount / liquidCapacity;
|
||||
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(next.entity.liquids.liquid == tile.entity.liquids.liquid) {
|
||||
float ofract = next.entity.liquids.amount / next.block().liquidCapacity;
|
||||
float fract = tile.entity.liquids.amount / liquidCapacity;
|
||||
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)){
|
||||
next.block().handleLiquid(next, tile, tile.entity.liquids.liquid, flow);
|
||||
tile.entity.liquids.amount -= flow;
|
||||
return flow;
|
||||
}else if(ofract > 0.1f && fract > 0.1f){
|
||||
Liquid liquid = tile.entity.liquids.liquid, other = next.entity.liquids.liquid;
|
||||
if((other.flammability > 0.3f && liquid.temperature > 0.7f) ||
|
||||
(liquid.flammability > 0.3f && other.temperature > 0.7f)){
|
||||
tile.entity.damage(1 * Timers.delta());
|
||||
next.entity.damage(1 * Timers.delta());
|
||||
if(Mathf.chance(0.1 * Timers.delta())){
|
||||
Effects.effect(EnvironmentFx.fire, (tile.worldx() + next.worldx())/2f, (tile.worldy() + next.worldy())/2f);
|
||||
}
|
||||
}else if((liquid.temperature > 0.7f && other.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());
|
||||
if(Mathf.chance(0.2f * Timers.delta())){
|
||||
Effects.effect(EnvironmentFx.steam, (tile.worldx() + next.worldx())/2f, (tile.worldy() + next.worldy())/2f);
|
||||
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);
|
||||
tile.entity.liquids.amount -= flow;
|
||||
return flow;
|
||||
} else if (ofract > 0.1f && fract > 0.1f) {
|
||||
Liquid liquid = tile.entity.liquids.liquid, other = next.entity.liquids.liquid;
|
||||
if ((other.flammability > 0.3f && liquid.temperature > 0.7f) ||
|
||||
(liquid.flammability > 0.3f && other.temperature > 0.7f)) {
|
||||
tile.entity.damage(1 * Timers.delta());
|
||||
next.entity.damage(1 * Timers.delta());
|
||||
if (Mathf.chance(0.1 * Timers.delta())) {
|
||||
Effects.effect(EnvironmentFx.fire, (tile.worldx() + next.worldx()) / 2f, (tile.worldy() + next.worldy()) / 2f);
|
||||
}
|
||||
} else if ((liquid.temperature > 0.7f && other.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());
|
||||
if (Mathf.chance(0.2f * Timers.delta())) {
|
||||
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){
|
||||
float leakAmount = Math.min(tile.entity.liquids.amount, tile.entity.liquids.amount/1.5f);
|
||||
|
||||
@@ -1,120 +1,21 @@
|
||||
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 io.anuke.mindustry.type.Liquid;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
public class BurnerGenerator extends ItemLiquidGenerator {
|
||||
|
||||
public class BurnerGenerator extends PowerGenerator {
|
||||
protected float minEfficiency = 0.2f;
|
||||
protected float powerOutput;
|
||||
protected float itemDuration = 70f;
|
||||
protected Effect generateEffect = BlockFx.generatespark;
|
||||
protected Color heatColor = Color.valueOf("ff9b59");
|
||||
public BurnerGenerator(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public BurnerGenerator(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 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 getLiquidEfficiency(Liquid liquid) {
|
||||
return liquid.flammability;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getItemEfficiency(Item item) {
|
||||
return item.flammability;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ package io.anuke.mindustry.world.blocks.power;
|
||||
|
||||
import io.anuke.mindustry.type.Item;
|
||||
|
||||
public class DecayGenerator extends BurnerGenerator {
|
||||
public class DecayGenerator extends ItemGenerator {
|
||||
|
||||
public DecayGenerator(String name) {
|
||||
super(name);
|
||||
hasItems = true;
|
||||
hasLiquids = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -4,34 +4,26 @@ import io.anuke.mindustry.content.fx.BlockFx;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
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.Effect;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
//TODO remove this class
|
||||
public class LiquidBurnerGenerator extends PowerGenerator {
|
||||
public abstract class LiquidGenerator extends PowerGenerator {
|
||||
protected float minEfficiency = 0.2f;
|
||||
protected float powerPerLiquid = 0.13f;
|
||||
/**Maximum liquid used per frame.*/
|
||||
protected float maxLiquidGenerate = 0.4f;
|
||||
protected Effect generateEffect = BlockFx.generatespark;
|
||||
|
||||
public LiquidBurnerGenerator(String name) {
|
||||
public LiquidGenerator(String name) {
|
||||
super(name);
|
||||
liquidCapacity = 30f;
|
||||
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
|
||||
public void draw(Tile tile){
|
||||
super.draw(tile);
|
||||
@@ -75,10 +67,11 @@ public class LiquidBurnerGenerator extends PowerGenerator {
|
||||
|
||||
@Override
|
||||
public TileEntity getEntity() {
|
||||
return new BurnerEntity();
|
||||
return new ItemGeneratorEntity();
|
||||
}
|
||||
|
||||
protected float getEfficiency(Liquid liquid){
|
||||
return liquid.flammability;
|
||||
}
|
||||
/**Returns an efficiency value for the specified liquid.
|
||||
* 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);
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.power;
|
||||
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
|
||||
public class LiquidHeatGenerator extends LiquidBurnerGenerator {
|
||||
public class LiquidHeatGenerator extends LiquidGenerator {
|
||||
|
||||
public LiquidHeatGenerator(String name) {
|
||||
super(name);
|
||||
@@ -10,6 +10,6 @@ public class LiquidHeatGenerator extends LiquidBurnerGenerator {
|
||||
|
||||
@Override
|
||||
protected float getEfficiency(Liquid liquid){
|
||||
return liquid.flammability;
|
||||
return liquid.temperature-0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.tilesize;
|
||||
|
||||
public class NuclearReactor extends LiquidBurnerGenerator {
|
||||
public class NuclearReactor extends PowerGenerator {
|
||||
protected final int timerFuel = timers++;
|
||||
|
||||
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
|
||||
public void onDestroyed(Tile tile){
|
||||
super.onDestroyed(tile);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -33,27 +33,30 @@ public class LiquidMixer extends LiquidBlock{
|
||||
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
|
||||
public boolean acceptItem(Item item, Tile tile, Tile source) {
|
||||
return item == inputItem && tile.entity.items.getItem(item) < itemCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
|
||||
return liquid == inputLiquid && tile.entity.liquids.amount + amount <= liquidCapacity &&
|
||||
tile.entity.items.hasItem(inputItem, (int)((tile.<LiquidMixerEntity>entity().accumulator + amount)/amount)) &&
|
||||
tile.entity.power.amount >= powerUse;
|
||||
public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) {
|
||||
LiquidMixerEntity entity = tile.entity();
|
||||
|
||||
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
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package io.anuke.mindustry.world.blocks.units;
|
||||
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
|
||||
public class OverdriveProjector extends Projector {
|
||||
|
||||
public OverdriveProjector(String name) {
|
||||
super(name);
|
||||
|
||||
status = StatusEffects.overdrive;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
package io.anuke.mindustry.world.blocks.units;
|
||||
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.StatusEffect;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
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 {
|
||||
protected final int timerApply = timers++;
|
||||
protected final float applyTime = 4f;
|
||||
|
||||
protected float powerUse = 0.01f;
|
||||
protected float range = 40f;
|
||||
protected float range = 80f;
|
||||
|
||||
protected StatusEffect status;
|
||||
protected float intensity;
|
||||
protected float intensity = 1f;
|
||||
|
||||
public Projector(String name) {
|
||||
super(name);
|
||||
@@ -23,12 +28,39 @@ public abstract class Projector extends Block {
|
||||
solid = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSelect(Tile tile){
|
||||
Draw.color(Palette.accent);
|
||||
Lines.dashCircle(tile.drawx(), tile.drawy(), range);
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
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 -> {
|
||||
unit.applyEffect(status, intensity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity getEntity() {
|
||||
return new ProjectorEntity();
|
||||
}
|
||||
|
||||
public class ProjectorEntity extends TileEntity{
|
||||
public float heat;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
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 ShieldProjector(String name) {
|
||||
super(name);
|
||||
hasPower = true;
|
||||
|
||||
status = StatusEffects.shielded;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user