Added mend projector

This commit is contained in:
Anuken 2018-08-26 23:03:02 -04:00
parent 9059238aee
commit 2f7f16daff
17 changed files with 867 additions and 915 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

After

Width:  |  Height:  |  Size: 249 B

View File

@ -577,6 +577,8 @@ block.thermal-pump.name=Thermal Pump
block.dagger-pad.name=Dagger Pad
block.titan-pad.name=Titan Pad
block.thermal-generator.name=Thermal Generator
block.alloy-smelter.name=Alloy Smtler
block.mend-projector.name=Mend Projector
unit.alpha-drone.name=Alpha Drone
unit.drone.name=Drone

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

@ -29,6 +29,9 @@ public class Recipes implements ContentList{
new Recipe(defense, DefenseBlocks.door, new ItemStack(Items.densealloy, 12), new ItemStack(Items.silicon, 8));
new Recipe(defense, DefenseBlocks.doorLarge, new ItemStack(Items.densealloy, 12 * 4), new ItemStack(Items.silicon, 8 * 4));
//cores
new Recipe(defense, DefenseBlocks.mendProjector, new ItemStack(Items.lead, 200), new ItemStack(Items.densealloy, 150), new ItemStack(Items.titanium, 150), new ItemStack(Items.silicon, 250));
//TURRETS
new Recipe(weapon, TurretBlocks.duo, new ItemStack(Items.copper, 40));
new Recipe(weapon, TurretBlocks.scorch, new ItemStack(Items.copper, 50), new ItemStack(Items.densealloy, 20));

View File

@ -207,7 +207,7 @@ public class CraftingBlocks extends BlockList implements ContentList{
itemCapacity = 50;
craftTime = 25f;
outputLiquid = Liquids.oil;
outputLiquidAmount = 1.2f;
outputLiquidAmount = 1.4f;
size = 2;
health = 320;
hasLiquids = true;

View File

@ -1,15 +1,17 @@
package io.anuke.mindustry.content.blocks;
import io.anuke.mindustry.content.Items;
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.Wall;
import io.anuke.mindustry.world.blocks.defense.DeflectorWall;
import io.anuke.mindustry.world.blocks.defense.Door;
import io.anuke.mindustry.world.blocks.defense.MendProjector;
public class DefenseBlocks extends BlockList implements ContentList{
public static Block copperWall, copperWallLarge, compositeWall, compositeWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, deflectorwall, deflectorwalllarge,
phaseWall, phaseWallLarge;
phaseWall, phaseWallLarge, mendProjector;
@Override
public void load(){
@ -70,5 +72,12 @@ public class DefenseBlocks extends BlockList implements ContentList{
health = 100 * 4 * wallHealthMultiplier;
size = 2;
}};
mendProjector = new MendProjector("mend-projector"){{
consumes.power(0.25f);
health = 100 * 4 * wallHealthMultiplier;
size = 2;
consumes.item(Items.phasematter).optional(true);
}};
}
}

View File

@ -19,7 +19,7 @@ public class BlockFx extends FxList implements ContentList{
public static Effect reactorsmoke, nuclearsmoke, nuclearcloud, redgeneratespark, generatespark, fuelburn, plasticburn,
pulverize, pulverizeRed, pulverizeRedder, pulverizeSmall, pulverizeMedium, producesmoke, smeltsmoke, formsmoke, blastsmoke,
lava, dooropen, doorclose, dooropenlarge, doorcloselarge, purify, purifyoil, purifystone, generate, mine, mineBig, mineHuge,
smelt, teleportActivate, teleport, teleportOut, ripple, bubble, commandSend, healBlock;
smelt, teleportActivate, teleport, teleportOut, ripple, bubble, commandSend, healBlock, healBlockFull;
@Override
public void load(){
@ -291,5 +291,12 @@ public class BlockFx extends FxList implements ContentList{
Lines.square(e.x, e.y, 1f + (e.fin() * e.rotation * tilesize/2f-1f));
Draw.color();
});
healBlockFull = new Effect(20, e -> {
Draw.color(e.color);
Draw.alpha(e.fout());
Fill.square(e.x, e.y, e.rotation * tilesize);
Draw.color();
});
}
}

View File

@ -11,7 +11,7 @@ import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class UnitFx extends FxList implements ContentList{
public static Effect vtolHover, unitDrop, unitPickup, unitLand, pickup, healWave, heal;
public static Effect vtolHover, unitDrop, unitPickup, unitLand, pickup, healWave, healWaveMend, heal;
@Override
public void load(){
@ -61,6 +61,13 @@ public class UnitFx extends FxList implements ContentList{
Draw.color();
});
healWaveMend = new Effect(40, e -> {
Draw.color(e.color);
Lines.stroke(e.fout() * 2f);
Lines.poly(e.x, e.y, 30, e.finpow() * e.rotation);
Draw.color();
});
heal = new Effect(11, e -> {
Draw.color(Palette.heal);
Lines.stroke(e.fout() * 2f);

View File

@ -24,6 +24,7 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.BaseEntity;
import io.anuke.ucore.entities.trait.HealthTrait;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
@ -34,7 +35,7 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.tileGroup;
import static io.anuke.mindustry.Vars.world;
public class TileEntity extends BaseEntity implements TargetTrait{
public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
public static final float timeToSleep = 60f * 4; //4 seconds to fall asleep
private static final ObjectSet<Tile> tmpTiles = new ObjectSet<>();
/**This value is only used for debugging.*/
@ -118,18 +119,6 @@ public class TileEntity extends BaseEntity implements TargetTrait{
public void read(DataInputStream stream) throws IOException{
}
private void onDeath(){
if(!dead){
dead = true;
Block block = tile.block();
block.onDestroyed(tile);
world.removeBlock(tile);
block.afterDestroyed(tile, this);
remove();
}
}
public boolean collide(Bullet other){
return true;
}
@ -206,6 +195,39 @@ public class TileEntity extends BaseEntity implements TargetTrait{
return proximity;
}
@Override
public void health(float health){
this.health = health;
}
@Override
public float health(){
return health;
}
@Override
public float maxHealth(){
return tile.block().health;
}
@Override
public void setDead(boolean dead){
this.dead = dead;
}
@Override
public void onDeath(){
if(!dead){
dead = true;
Block block = tile.block();
block.onDestroyed(tile);
world.removeBlock(tile);
block.afterDestroyed(tile, this);
remove();
}
}
@Override
public Team getTeam(){
return tile.getTeam();

View File

@ -1,93 +0,0 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.math.Interpolation;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.defense.ShieldBlock;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.impl.BaseEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.util.Mathf;
//todo re-implement
public class Shield extends BaseEntity implements DrawTrait{
private final Tile tile;
public boolean active;
public boolean hitPlayers = false;
public float radius = 0f;
private float uptime = 0f;
public Shield(Tile tile){
this.tile = tile;
this.x = tile.worldx();
this.y = tile.worldy();
}
public float drawSize(){
return 150;
}
@Override
public void update(){
float alpha = 0.1f;
Interpolation interp = Interpolation.fade;
if(active){
uptime = interp.apply(uptime, 1f, alpha * Timers.delta());
}else{
uptime = interp.apply(uptime, 0f, alpha * Timers.delta());
if(uptime <= 0.05f)
remove();
}
uptime = Mathf.clamp(uptime);
if(!(tile.block() instanceof ShieldBlock)){
remove();
return;
}
ShieldBlock block = (ShieldBlock) tile.block();
/*
Entities.getNearby(bulletGroup, x, y, block.shieldRadius * 2*uptime + 10, entity->{
BulletEntity bullet = (BulletEntity)entity;
if((bullet.owner instanceof BaseUnit || hitPlayers)){
float dst = entity.distanceTo(this);
if(dst < drawRadius()/2f){
((ShieldBlock)tile.block()).handleBullet(tile, bullet);
}
}
});*/
}
@Override
public void draw(){
if(!(tile.block() instanceof ShieldBlock) || radius <= 1f){
return;
}
Fill.circle(x, y, drawRadius());
}
float drawRadius(){
return (radius + Mathf.sin(Timers.time(), 25f, 1f));
}
public void removeDelay(){
active = false;
}
@Override
public void added(){
active = true;
}
@Override
public void removed(){
active = false;
uptime = 0f;
}
}

View File

@ -48,7 +48,7 @@ public abstract class BaseBlock{
}
public int getMaximumAccepted(Tile tile, Item item){
return itemCapacity - tile.entity.items.total();
return itemCapacity - (tile.entity.items.total() - tile.entity.items.get(item));
}
/**

View File

@ -0,0 +1,131 @@
package io.anuke.mindustry.world.blocks.defense;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class MendProjector extends Block{
private static Color color = Color.valueOf("84f491");
private static Color phase = Color.valueOf("ffd59e");
private static IntSet healed = new IntSet();
protected int timerUse = timers ++;
protected TextureRegion topRegion;
protected float reload = 250f;
protected float range = 50f;
protected float healPercent = 6f;
protected float phaseBoost = 12f;
protected float useTime = 340f;
public MendProjector(String name){
super(name);
solid = true;
update = true;
hasPower = true;
hasItems = true;
itemCapacity = 10;
}
@Override
public void load(){
super.load();
topRegion = Draw.region(name + "-top");
}
@Override
public void update(Tile tile){
MendEntity entity = tile.entity();
entity.heat = Mathf.lerpDelta(entity.heat, entity.cons.valid() ? 1f : 0f, 0.08f);
entity.charge += entity.heat * Timers.delta();
entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, (float)entity.items.get(consumes.item()) / itemCapacity, 0.1f);
if(entity.timer.get(timerUse, useTime) && entity.items.total() > 0){
entity.items.remove(consumes.item(), 1);
}
if(entity.charge >= reload){
float realRange = range + entity.phaseHeat * 20f;
Effects.effect(UnitFx.healWaveMend, Hue.mix(color, phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange);
entity.charge = 0f;
Timers.run(10f, () -> {
int tileRange = (int)(realRange / tilesize);
healed.clear();
for(int x = -tileRange + tile.x; x <= tileRange + tile.x; x++){
for(int y = -tileRange + tile.y; y <= tileRange + tile.y; y++){
if(Vector2.dst(x, y, tile.x, tile.y) > realRange) continue;
Tile other = world.tile(x, y);
if(other == null) continue;
other = other.target();
if(!healed.contains(other.packedPosition()) && other.entity != null && other.entity.health < other.entity.maxHealth()){
other.entity.healBy(other.entity.maxHealth() * (healPercent + entity.phaseHeat*phaseBoost)/100f);
Effects.effect(BlockFx.healBlockFull, Hue.mix(color, phase, entity.phaseHeat), other.drawx(), other.drawy(), other.block().size);
healed.add(other.packedPosition());
}
}
}
});
}
}
@Override
public void drawSelect(Tile tile){
Draw.color(color);
Lines.dashCircle(tile.drawx(), tile.drawy() - 1f, range);
Draw.color();
}
@Override
public void draw(Tile tile){
super.draw(tile);
MendEntity entity = tile.entity();
float f = 1f - (Timers.time() / 100f) % 1f;
Draw.color(color, phase, entity.phaseHeat);
Draw.alpha(entity.heat * Mathf.absin(Timers.time(), 10f, 1f) * 0.5f);
Graphics.setAdditiveBlending();
Draw.rect(topRegion, tile.drawx(), tile.drawy());
Graphics.setNormalBlending();
Draw.alpha(1f);
Lines.stroke((2f * f + 0.2f)* entity.heat);
Lines.circle(tile.drawx(), tile.drawy(), (1f-f) * 9f);
Draw.reset();
}
@Override
public TileEntity getEntity(){
return new MendEntity();
}
class MendEntity extends TileEntity{
float heat;
float charge;
float phaseHeat;
}
}

View File

@ -1,81 +0,0 @@
package io.anuke.mindustry.world.blocks.defense;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.impl.BulletEntity;
import io.anuke.ucore.util.Mathf;
//TODO remove
public class ShieldBlock extends PowerBlock{
public float shieldRadius = 40f;
public float powerDrain = 0.005f;
public float powerPerDamage = 0.06f;
public float maxRadius = 40f;
public float radiusScale = 300f;
public ShieldBlock(String name){
super(name);
powerCapacity = 80f;
}
@Override
public void setStats(){
super.setStats();
//stats.add("powersecond", Strings.toFixed(powerDrain*60, 2));
//stats.add("powerdraindamage", Strings.toFixed(powerPerDamage, 2));
//stats.add("shieldradius", (int)shieldRadius);
}
@Override
public void update(Tile tile){
ShieldEntity entity = tile.entity();
if(entity.shield == null){
entity.shield = new Shield(tile);
if(Vars.infiniteAmmo && Vars.debug)
entity.shield.add();
}
if(entity.power.amount > powerPerDamage){
if(!entity.shield.active){
entity.shield.add();
}
entity.power.amount -= powerDrain * Timers.delta();
}else{
if(entity.shield.active && !(Vars.infiniteAmmo && Vars.debug)){
entity.shield.removeDelay();
}
}
entity.shield.radius = Mathf.lerp(entity.shield.radius, Math.min(entity.power.amount / powerCapacity * radiusScale, maxRadius), Timers.delta() * 0.05f);
}
@Override
public TileEntity getEntity(){
return new ShieldEntity();
}
public void handleBullet(Tile tile, BulletEntity bullet){
ShieldEntity entity = tile.entity();
if(entity.power.amount < bullet.getDamage() * powerPerDamage){
return;
}
bullet.remove();
//Effects.effect(bullet.damage > 5 ? BulletFx.shieldhit : BulletFx.laserhit, bullet);
//if(!headless) renderer.addShieldHit(bullet.x, bullet.y);
entity.power.amount -= bullet.getDamage() * powerPerDamage;
}
static class ShieldEntity extends TileEntity{
Shield shield;
}
}

View File

@ -1,76 +0,0 @@
package io.anuke.mindustry.world.blocks.defense;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import static io.anuke.mindustry.Vars.tilesize;
//TODO remove
public class ShieldedWallBlock extends PowerBlock{
static final float hitTime = 18f;
static final Color hitColor = Color.SKY.cpy().mul(1.2f);
public float powerPerDamage = 0.08f;
public ShieldedWallBlock(String name){
super(name);
destructible = true;
update = false;
}
@Override
public float handleDamage(Tile tile, float amount){
float drain = amount * powerPerDamage;
ShieldedWallEntity entity = tile.entity();
if(entity.power.amount > drain){
entity.power.amount -= drain;
entity.hit = hitTime;
return 0;
}else if(entity.power.amount > 0){
int reduction = (int) (entity.power.amount / powerPerDamage);
entity.power.amount = 0;
return amount - reduction;
}
return amount;
}
@Override
public void setStats(){
super.setStats();
//stats.add("powerdraindamage", Strings.toFixed(powerPerDamage, 2));
}
@Override
public void draw(Tile tile){
super.draw(tile);
ShieldedWallEntity entity = tile.entity();
if(entity.power.amount > powerPerDamage){
//renderer.addShield(() -> Draw.rect("blank", tile.worldx(), tile.worldy(), tilesize, tilesize));
}
Draw.color(hitColor);
Draw.alpha(entity.hit / hitTime * 0.9f);
Draw.rect("blank", tile.worldx(), tile.worldy(), tilesize, tilesize);
Draw.reset();
entity.hit -= Timers.delta();
entity.hit = Math.max(entity.hit, 0);
}
@Override
public TileEntity getEntity(){
return new ShieldedWallEntity();
}
static class ShieldedWallEntity extends TileEntity{
public float hit;
}
}