1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2025-03-13 19:39:04 +07:00

Partial liquid turret implementation / Status effects

This commit is contained in:
Anuken 2018-04-05 21:37:54 -04:00
parent ddf39461fb
commit 7cd96e379e
29 changed files with 875 additions and 514 deletions

Binary file not shown.

Before

(image error) Size: 191 B

After

(image error) Size: 192 B

Binary file not shown.

After

(image error) Size: 189 B

Binary file not shown.

Before

(image error) Size: 325 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

(image error) Size: 102 KiB

After

(image error) Size: 103 KiB

View File

@ -1,7 +1,7 @@
#Autogenerated file. Do not modify.
#Thu Apr 05 17:29:03 EDT 2018
#Thu Apr 05 21:32:39 EDT 2018
version=release
androidBuildCode=846
androidBuildCode=851
name=Mindustry
code=3.4
build=custom build

View File

@ -14,5 +14,13 @@ public class AmmoTypes {
basicLeadFrag = new AmmoType(Items.lead, TurretBullets.basicLeadFragShell, 1, 0.8f),
lancerLaser = new AmmoType(TurretBullets.lancerLaser);
lancerLaser = new AmmoType(TurretBullets.lancerLaser),
oil = new AmmoType(Liquids.oil, TurretBullets.oilShot, 0.3f, 1f),
water = new AmmoType(Liquids.water, TurretBullets.waterShot, 0.3f, 1f),
lava = new AmmoType(Liquids.lava, TurretBullets.lavaShot, 0.3f, 1f),
cryofluid = new AmmoType(Liquids.cryofluid, TurretBullets.cryoShot, 0.3f, 1f);
}

View File

@ -47,7 +47,7 @@ public class Recipes {
new Recipe(weapon, WeaponBlocks.laserturret, stack(Items.steel, 12), stack(Items.titanium, 12)),
new Recipe(weapon, WeaponBlocks.flakturret, stack(Items.steel, 25), stack(Items.titanium, 15)),
new Recipe(weapon, WeaponBlocks.teslaturret, stack(Items.steel, 20), stack(Items.titanium, 25), stack(Items.densealloy, 15)),
new Recipe(weapon, WeaponBlocks.magmaturret, stack(Items.steel, 80), stack(Items.titanium, 70), stack(Items.densealloy, 60)),
new Recipe(weapon, WeaponBlocks.liquidturret, stack(Items.steel, 80), stack(Items.titanium, 70), stack(Items.densealloy, 60)),
new Recipe(weapon, WeaponBlocks.chainturret, stack(Items.steel, 50), stack(Items.titanium, 25), stack(Items.densealloy, 40)),
new Recipe(weapon, WeaponBlocks.titanturret, stack(Items.steel, 70), stack(Items.titanium, 50), stack(Items.densealloy, 55)),
new Recipe(weapon, WeaponBlocks.missileturret, stack(Items.steel, 70), stack(Items.titanium, 50), stack(Items.densealloy, 55)),

View File

@ -0,0 +1,98 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.entities.StatusController.TransitionResult;
import io.anuke.mindustry.entities.StatusEffect;
import io.anuke.mindustry.entities.Unit;
import io.anuke.ucore.core.Timers;
public class StatusEffects {
public static final StatusEffect
none = new StatusEffect(0),
burning = new StatusEffect(4*60f){
{
oppositeScale = 0.5f;
}
@Override
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result){
if(to == oiled){
return result.set(this, Math.min(time + newTime, baseDuration + oiled.baseDuration));
}
return super.getTransition(unit, to, time, newTime, result);
}
@Override
public void update(Unit unit, float time){
unit.damage(0.04f * Timers.delta());
}
},
freezing = new StatusEffect(5*60f){
{
oppositeScale = 0.4f;
}
@Override
public void update(Unit unit, float time){
unit.velocity.scl(0.6f);
}
},
wet = new StatusEffect(3*60f){
{
oppositeScale = 0.5f;
}
@Override
public void update(Unit unit, float time){
unit.velocity.scl(0.999f);
}
},
melting = new StatusEffect(5*60f){
{
oppositeScale = 0.2f;
}
@Override
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result){
if(to == oiled){
return result.set(this, Math.min(time + newTime/2f, baseDuration));
}
return super.getTransition(unit, to, time, newTime, result);
}
@Override
public void update(Unit unit, float time){
unit.velocity.scl(0.8f);
unit.damage(0.1f * Timers.delta());
}
},
oiled = new StatusEffect(4*60f){
@Override
public void update(Unit unit, float time){
unit.velocity.scl(1.001f);
}
@Override
public TransitionResult getTransition(Unit unit, StatusEffect to, float time, float newTime, TransitionResult result){
if(to == melting || to == burning){
return result.set(to, newTime + time);
}
return result.set(to, newTime);
}
};
static{
melting.setOpposites(wet, freezing);
wet.setOpposites(burning);
freezing.setOpposites(burning, melting);
burning.setOpposites(wet, freezing);
}
}

View File

@ -1,7 +1,7 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.resource.Weapon;
public class Weapons {
@ -9,7 +9,7 @@ public class Weapons {
blaster = new Weapon("blaster", 12, TurretBullets.basicIron) {
{
effect = BulletFx.shootSmall;
effect = ShootFx.shootSmall;
length = 2f;
}
};

View File

@ -2,7 +2,7 @@ package io.anuke.mindustry.content.blocks;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
@ -19,9 +19,9 @@ public class WeaponBlocks{
ammoTypes = new AmmoType[]{AmmoTypes.basicIron};
reload = 25f;
restitution = 0.03f;
shootEffect = BulletFx.shootSmall;
smokeEffect = BulletFx.shootSmallSmoke;
ammoUseEffect = BulletFx.shellEjectSmall;
shootEffect = ShootFx.shootSmall;
smokeEffect = ShootFx.shootSmallSmoke;
ammoUseEffect = ShootFx.shellEjectSmall;
}},
gatlingturret = new BurstTurret("gatlingturret") {{
@ -32,9 +32,9 @@ public class WeaponBlocks{
restitution = 0.03f;
recoil = 1.5f;
burstSpacing = 6f;
shootEffect = BulletFx.shootSmall;
smokeEffect = BulletFx.shootSmallSmoke;
ammoUseEffect = BulletFx.shellEjectSmall;
shootEffect = ShootFx.shootSmall;
smokeEffect = ShootFx.shootSmallSmoke;
ammoUseEffect = ShootFx.shellEjectSmall;
}},
flameturret = new LiquidTurret("flameturret"){{
@ -42,8 +42,8 @@ public class WeaponBlocks{
recoil = 0f;
reload = 5f;
shootCone = 50f;
shootEffect = BulletFx.shootSmallFlame;
ammoUseEffect = BulletFx.shellEjectSmall;
shootEffect = ShootFx.shootSmallFlame;
ammoUseEffect = ShootFx.shellEjectSmall;
drawer = (tile, entity) -> {
Draw.rect(entity.target != null ? name + "-shoot" : name, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
@ -58,9 +58,9 @@ public class WeaponBlocks{
ammoEjectBack = 2f;
recoil = 3f;
shootShake = 2f;
shootEffect = BulletFx.shootBig;
smokeEffect = BulletFx.shootBigSmoke;
ammoUseEffect = BulletFx.shellEjectMedium;
shootEffect = ShootFx.shootBig;
smokeEffect = ShootFx.shootBigSmoke;
ammoUseEffect = ShootFx.shellEjectMedium;
}},
flakturret = new ItemTurret("flakturret"){{
@ -73,9 +73,9 @@ public class WeaponBlocks{
cooldown = 0.03f;
recoil = 3f;
shootShake = 2f;
shootEffect = BulletFx.shootBig2;
smokeEffect = BulletFx.shootBigSmoke2;
ammoUseEffect = BulletFx.shellEjectBig;
shootEffect = ShootFx.shootBig2;
smokeEffect = ShootFx.shootBigSmoke2;
ammoUseEffect = ShootFx.shellEjectBig;
drawer = (tile, entity) -> {
Draw.rect(name, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
@ -100,24 +100,36 @@ public class WeaponBlocks{
recoil = 2f;
reload = 130f;
cooldown = 0.03f;
shootEffect = BulletFx.lancerLaserShoot;
smokeEffect = BulletFx.lancerLaserShootSmoke;
chargeEffect = BulletFx.lancerLaserCharge;
chargeBeginEffect = BulletFx.lancerLaserChargeBegin;
shootEffect = ShootFx.lancerLaserShoot;
smokeEffect = ShootFx.lancerLaserShootSmoke;
chargeEffect = ShootFx.lancerLaserCharge;
chargeBeginEffect = ShootFx.lancerLaserChargeBegin;
heatColor = Color.RED;
}},
teslaturret = new PowerTurret("teslaturret"){
teslaturret = new PowerTurret("teslaturret"){{
},
magmaturret = new LiquidTurret("magmaturret") {{
ammoTypes = new AmmoType[]{AmmoTypes.basicFlame};
}},
plasmaturret = new Turret("plasmaturret"){
liquidturret = new LiquidTurret("liquidturret") {{
ammoTypes = new AmmoType[]{AmmoTypes.water, AmmoTypes.lava, AmmoTypes.cryofluid, AmmoTypes.oil};
size = 2;
recoil = 0f;
reload = 4f;
inaccuracy = 5f;
shootCone = 50f;
shootEffect = ShootFx.shootLiquid;
range = 70f;
},
drawer = (tile, entity) -> {
Draw.rect(name, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
Draw.color(entity.liquid.liquid.color);
Draw.alpha(entity.liquid.amount/liquidCapacity);
Draw.rect(name + "-liquid", tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90);
Draw.color();
};
}},
chainturret = new Turret("chainturret"){

View File

@ -1,13 +1,18 @@
package io.anuke.mindustry.content.bullets;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.effect.DamageArea;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
@ -20,7 +25,7 @@ public class TurretBullets {
@Override
public void draw(Bullet b) {
drawBullet(Palette.bulletYellow, Palette.bulletYellowBack,
"bullet", b.x, b.y, 9f, 5f + b.fract()*7f, b.angle() - 90);
"bullet", b.x, b.y, 9f, 5f + b.fout()*7f, b.angle() - 90);
}
},
@ -33,7 +38,7 @@ public class TurretBullets {
@Override
public void draw(Bullet b) {
drawBullet(Palette.bulletYellow, Palette.bulletYellowBack,
"bullet", b.x, b.y, 11f, 9f + b.fract()*8f, b.angle() - 90);
"bullet", b.x, b.y, 11f, 9f + b.fout()*8f, b.angle() - 90);
}
},
@ -82,7 +87,7 @@ public class TurretBullets {
@Override
public void draw(Bullet b) {
drawBullet(Palette.bulletYellow, Palette.bulletYellowBack,
"bullet", b.x, b.y, 7f + b.fract()*3f, 1f + b.fract()*11f, b.angle() - 90);
"bullet", b.x, b.y, 7f + b.fout()*3f, 1f + b.fout()*11f, b.angle() - 90);
}
},
@ -125,12 +130,42 @@ public class TurretBullets {
for(int s = 0; s < 3; s ++) {
Draw.color(colors[s]);
for (int i = 0; i < tscales.length; i++) {
Lines.stroke(7f * b.fract() * (s == 0 ? 1.5f : s == 1 ? 1f : 0.3f) * tscales[i]);
Lines.stroke(7f * b.fout() * (s == 0 ? 1.5f : s == 1 ? 1f : 0.3f) * tscales[i]);
Lines.lineAngle(b.x, b.y, b.angle(), length * lenscales[i]);
}
}
Draw.reset();
}
},
waterShot = new LiquidShot(Liquids.water) {
{
status = StatusEffects.wet;
statusIntensity = 0.5f;
}
},
cryoShot = new LiquidShot(Liquids.cryofluid) {
{
status = StatusEffects.freezing;
statusIntensity = 0.5f;
}
},
lavaShot = new LiquidShot(Liquids.lava) {
{
damage = 4;
speed = 1.9f;
drag = 0.03f;
status = StatusEffects.melting;
statusIntensity = 0.5f;
}
},
oilShot = new LiquidShot(Liquids.oil) {
{
speed = 2f;
drag = 0.03f;
status = StatusEffects.oiled;
statusIntensity = 0.5f;
}
};
private static void drawBullet(Color first, Color second, String name, float x, float y, float w, float h, float rot){
@ -140,4 +175,31 @@ public class TurretBullets {
Draw.rect(name, x, y, w, h, rot);
Draw.color();
}
private abstract static class LiquidShot extends BulletType{
Liquid liquid;
public LiquidShot(Liquid liquid) {
super(2.5f, 0);
this.liquid = liquid;
lifetime = 70f;
despawneffect = Fx.none;
hiteffect = BulletFx.hitLiquid;
drag = 0.01f;
knockback = 0.65f;
}
@Override
public void draw(Bullet b) {
Draw.color(liquid.color, Color.WHITE, b.fout() / 100f + Mathf.randomSeedRange(b.id, 0.1f));
Fill.circle(b.x, b.y, 0.5f + b.fout()*2.5f);
}
@Override
public void hit(Bullet b, float hitx, float hity) {
Effects.effect(hiteffect, liquid.color, hitx, hity);
}
}
}

View File

@ -1,147 +1,17 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.effect.StaticEffectEntity.StaticEffect;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class BulletFx {
public static final Effect
shootSmall = new Effect(8, e -> {
Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin());
float w = 1f + 5 * e.fout();
Shapes.tri(e.x, e.y, w, 15f * e.fout(), e.rotation);
Shapes.tri(e.x, e.y, w, 3f * e.fout(), e.rotation + 180f);
Draw.reset();
}),
shootSmallSmoke = new Effect(20f, e -> {
Draw.color(Palette.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 5, e.finpow()*6f, e.rotation, 20f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*1.5f);
});
Draw.reset();
}),
shootBig = new Effect(9, e -> {
Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin());
float w = 1.2f + 7 * e.fout();
Shapes.tri(e.x, e.y, w, 25f * e.fout(), e.rotation);
Shapes.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
Draw.reset();
}),
shootBig2 = new Effect(10, e -> {
Draw.color(Palette.lightOrange, Color.GRAY, e.fin());
float w = 1.2f + 8 * e.fout();
Shapes.tri(e.x, e.y, w, 29f * e.fout(), e.rotation);
Shapes.tri(e.x, e.y, w, 5f * e.fout(), e.rotation + 180f);
Draw.reset();
}),
shootBigSmoke = new Effect(17f, e -> {
Draw.color(Palette.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 8, e.finpow()*19f, e.rotation, 10f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*2f + 0.2f);
});
Draw.reset();
}),
shootBigSmoke2 = new Effect(18f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 9, e.finpow()*23f, e.rotation, 20f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*2.4f + 0.2f);
});
Draw.reset();
}),
shootSmallFlame = new Effect(30f, e -> {
Draw.color(Palette.lightFlame, Palette.darkFlame, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 8, e.finpow()*26f, e.rotation, 10f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, 0.65f + e.fout()*1.5f);
});
Draw.reset();
}),
shellEjectSmall = new StaticEffect(30f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f;
for(int i : Mathf.signs){
float len = (2f + e.finpow()*6f) * i;
float lr = rot + e.fin()*30f*i;
Draw.rect("white",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
1f, 2f, rot + e.fin()*50f*i);
}
Draw.color();
}),
shellEjectMedium = new StaticEffect(34f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f;
for(int i : Mathf.signs){
float len = (2f + e.finpow()*10f) * i;
float lr = rot + e.fin()*20f*i;
Draw.rect("casing",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
2f, 3f, rot);
}
Draw.color(Color.LIGHT_GRAY, Color.GRAY, e.fin());
for(int i : Mathf.signs){
Angles.randLenVectors(e.id, 4, 1f + e.finpow()*11f, e.rotation + 90f*i, 20f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*1.5f);
});
}
Draw.color();
}),
shellEjectBig = new StaticEffect(22f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f;
for(int i : Mathf.signs){
float len = (4f + e.finpow()*8f) * i;
float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin())*i;
Draw.rect("casing",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
2.5f, 4f,
rot+ e.fin()*30f*i + Mathf.randomSeedRange(e.id + i + 9, 40f * e.fin()));
}
Draw.color(Color.LIGHT_GRAY);
for(int i : Mathf.signs){
Angles.randLenVectors(e.id, 4, -e.finpow()*15f, e.rotation + 90f*i, 25f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*2f);
});
}
Draw.color();
}),
hitBulletSmall = new Effect(14, e -> {
Draw.color(Color.WHITE, Palette.lightOrange, e.fin());
Lines.stroke(0.5f + e.fout());
@ -178,6 +48,16 @@ public class BulletFx {
Draw.reset();
}),
hitLiquid = new Effect(16, e -> {
Draw.color(e.color);
Angles.randLenVectors(e.id, 5, e.fin()*15f, e.rotation + 180f, 60f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout() * 2f);
});
Draw.reset();
}),
hitLancer = new Effect(12, e -> {
Draw.color(Color.WHITE);
Lines.stroke(e.fout()*1.5f);
@ -224,43 +104,6 @@ public class BulletFx {
});
Draw.reset();
}),
});
lancerLaserShoot = new Effect(21f, e -> {
Draw.color(Palette.lancerLaser);
for(int i : Mathf.signs){
Shapes.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f*i);
}
Draw.reset();
}),
lancerLaserShootSmoke = new Effect(26f, e -> {
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 7, 80f, e.rotation, 0f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fout()*9f);
});
Draw.reset();
}),
lancerLaserCharge = new Effect(38f, e -> {
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fslope()*3f + 1f);
});
Draw.reset();
}),
lancerLaserChargeBegin = new Effect(71f, e -> {
Draw.color(Palette.lancerLaser);
Fill.circle(e.x, e.y, e.fin() * 3f);
Draw.color();
Fill.circle(e.x, e.y, e.fin() * 2f);
});
}

View File

@ -0,0 +1,190 @@
package io.anuke.mindustry.content.fx;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.entities.effect.StaticEffectEntity.StaticEffect;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class ShootFx {
public static final Effect
shootSmall = new Effect(8, e -> {
Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin());
float w = 1f + 5 * e.fout();
Shapes.tri(e.x, e.y, w, 15f * e.fout(), e.rotation);
Shapes.tri(e.x, e.y, w, 3f * e.fout(), e.rotation + 180f);
Draw.reset();
}),
shootSmallSmoke = new Effect(20f, e -> {
Draw.color(Palette.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 5, e.finpow()*6f, e.rotation, 20f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*1.5f);
});
Draw.reset();
}),
shootBig = new Effect(9, e -> {
Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin());
float w = 1.2f + 7 * e.fout();
Shapes.tri(e.x, e.y, w, 25f * e.fout(), e.rotation);
Shapes.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
Draw.reset();
}),
shootBig2 = new Effect(10, e -> {
Draw.color(Palette.lightOrange, Color.GRAY, e.fin());
float w = 1.2f + 8 * e.fout();
Shapes.tri(e.x, e.y, w, 29f * e.fout(), e.rotation);
Shapes.tri(e.x, e.y, w, 5f * e.fout(), e.rotation + 180f);
Draw.reset();
}),
shootBigSmoke = new Effect(17f, e -> {
Draw.color(Palette.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 8, e.finpow()*19f, e.rotation, 10f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*2f + 0.2f);
});
Draw.reset();
}),
shootBigSmoke2 = new Effect(18f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 9, e.finpow()*23f, e.rotation, 20f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*2.4f + 0.2f);
});
Draw.reset();
}),
shootSmallFlame = new Effect(30f, e -> {
Draw.color(Palette.lightFlame, Palette.darkFlame, Color.GRAY, e.fin());
Angles.randLenVectors(e.id, 8, e.finpow()*26f, e.rotation, 10f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, 0.65f + e.fout()*1.5f);
});
Draw.reset();
}),
shootLiquid = new Effect(40f, e -> {
Draw.color(e.color, Color.WHITE, e.fout()/6f + Mathf.randomSeedRange(e.id, 0.1f));
Angles.randLenVectors(e.id, 6, e.finpow()*60f, e.rotation, 11f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, 0.5f + e.fout()*2.5f);
});
Draw.reset();
}),
shellEjectSmall = new StaticEffect(30f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f;
for(int i : Mathf.signs){
float len = (2f + e.finpow()*6f) * i;
float lr = rot + e.fin()*30f*i;
Draw.rect("white",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
1f, 2f, rot + e.fin()*50f*i);
}
Draw.color();
}),
shellEjectMedium = new StaticEffect(34f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f;
for(int i : Mathf.signs){
float len = (2f + e.finpow()*10f) * i;
float lr = rot + e.fin()*20f*i;
Draw.rect("casing",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
2f, 3f, rot);
}
Draw.color(Color.LIGHT_GRAY, Color.GRAY, e.fin());
for(int i : Mathf.signs){
Angles.randLenVectors(e.id, 4, 1f + e.finpow()*11f, e.rotation + 90f*i, 20f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*1.5f);
});
}
Draw.color();
}),
shellEjectBig = new StaticEffect(22f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f;
for(int i : Mathf.signs){
float len = (4f + e.finpow()*8f) * i;
float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin())*i;
Draw.rect("casing",
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
2.5f, 4f,
rot+ e.fin()*30f*i + Mathf.randomSeedRange(e.id + i + 9, 40f * e.fin()));
}
Draw.color(Color.LIGHT_GRAY);
for(int i : Mathf.signs){
Angles.randLenVectors(e.id, 4, -e.finpow()*15f, e.rotation + 90f*i, 25f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout()*2f);
});
}
Draw.color();
}),
lancerLaserShoot = new Effect(21f, e -> {
Draw.color(Palette.lancerLaser);
for(int i : Mathf.signs){
Shapes.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f*i);
}
Draw.reset();
}),
lancerLaserShootSmoke = new Effect(26f, e -> {
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 7, 80f, e.rotation, 0f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fout()*9f);
});
Draw.reset();
}),
lancerLaserCharge = new Effect(38f, e -> {
Draw.color(Palette.lancerLaser);
Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), e.fslope()*3f + 1f);
});
Draw.reset();
}),
lancerLaserChargeBegin = new Effect(71f, e -> {
Draw.color(Palette.lancerLaser);
Fill.circle(e.x, e.y, e.fin() * 3f);
Draw.color();
Fill.circle(e.x, e.y, e.fin() * 2f);
});
}

View File

@ -46,6 +46,9 @@ public class ContentLoader {
//ammotypes
new AmmoTypes(),
//status effects
new StatusEffects(),
};
for(Block block : Block.getAllBlocks()){

View File

@ -11,7 +11,7 @@ import io.anuke.ucore.util.Timer;
import static io.anuke.mindustry.Vars.*;
public class Bullet extends BulletEntity{
public class Bullet extends BulletEntity<BulletType>{
private static Vector2 vector = new Vector2();
public IntSet collided;
@ -73,8 +73,9 @@ public class Bullet extends BulletEntity{
collided.add(other.id);
if(other instanceof Unit){
float k = ((BulletType)type).knockback;
((Unit) other).velocity.add(vector.set(other.x, other.y).sub(x, y).setLength(k));
Unit unit = (Unit)other;
unit.velocity.add(vector.set(other.x, other.y).sub(x, y).setLength(type.knockback / unit.getMass()));
unit.status.handleApply(unit, type.status, type.statusIntensity);
}
}

View File

@ -1,11 +1,14 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.fx.BulletFx;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.entities.BaseBulletType;
public abstract class BulletType extends BaseBulletType<Bullet>{
public float knockback;
public StatusEffect status = StatusEffects.none;
public float statusIntensity = 0.5f;
public BulletType(float speed, int damage){
this.speed = speed;

View File

@ -81,7 +81,7 @@ public class Player extends Unit{
}
@Override
public void damage(int amount){
public void damage(float amount){
if(debug || mech.flying) return;
hitTime = hitDuration;
@ -177,11 +177,9 @@ public class Player extends Unit{
@Override
public void update(){
if(hitTime > 0){
hitTime -= Timers.delta();
}
hitTime = Math.max(0f, hitTime - Timers.delta());
if(hitTime < 0) hitTime = 0;
status.update(this);
if(!isLocal){
interpolate();

View File

@ -0,0 +1,62 @@
package io.anuke.mindustry.entities;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.ucore.core.Timers;
public class StatusController {
private static final TransitionResult globalResult = new TransitionResult();
private StatusEffect current = StatusEffects.none;
private float time;
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 {
current.getTransition(unit, effect, time, newTime, globalResult);
if (globalResult.result != current) {
current.onTransition(unit, globalResult.result);
time = globalResult.time;
current = globalResult.result;
}
}
}
public void update(Unit unit){
if(time > 0){
time = Math.max(time - Timers.delta(), 0);
}
current.update(unit, time);
}
public void set(StatusEffect current, float time){
this.current = current;
this.time = time;
}
public StatusEffect current() {
return current;
}
public float getTime() {
return time;
}
public static class TransitionResult{
public StatusEffect result;
public float time;
public TransitionResult set(StatusEffect effect, float time){
this.result = effect;
this.time = time;
return this;
}
}
}

View File

@ -1,5 +1,58 @@
package io.anuke.mindustry.entities;
public enum StatusEffect{
none;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.mindustry.entities.StatusController.TransitionResult;
public class StatusEffect{
private static final Array<StatusEffect> array = new Array<>();
private static int lastid;
public final float baseDuration;
public final int id;
protected ObjectSet<StatusEffect> opposites = new ObjectSet<>();
protected float oppositeScale = 0.5f;
public StatusEffect(float baseDuration){
this.baseDuration = baseDuration;
id = lastid++;
array.add(this);
}
/**Runs every tick on the affected unit while time is greater than 0.*/
public void update(Unit unit, float time){}
/**Called when transitioning between two status effects.
* @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){
if(opposites.contains(to)){
time -= newTime*oppositeScale;
if(time > 0) {
return result.set(this, time);
}
}
return result.set(to, newTime);
}
/**Called when this effect transitions to a new status effect.*/
public void onTransition(Unit unit, StatusEffect to){}
public void setOpposites(StatusEffect... effects){
for(StatusEffect e : effects){
opposites.add(e);
}
}
public static StatusEffect getByID(int id){
return array.get(id);
}
public static Array<StatusEffect> getAllEffects(){
return array;
}
}

View File

@ -7,6 +7,7 @@ public abstract class Unit extends SyncEntity {
//total duration of hit effect
public static final float hitDuration = 9f;
public StatusController status = new StatusController();
public Team team = Team.blue;
public Vector2 velocity = new Vector2();
public float hitTime;

View File

@ -74,7 +74,7 @@ public class BaseUnit extends Unit {
}
@Override
public void damage(int amount){
public void damage(float amount){
super.damage(amount);
hitTime = hitDuration;
}

View File

@ -74,7 +74,10 @@ public abstract class UnitType {
//TODO logic
unit.status.update(unit);
unit.velocity.limit(maxVelocity);
if(isFlying) {
unit.x += unit.velocity.x / mass;
unit.y += unit.velocity.y / mass;

View File

@ -218,7 +218,7 @@ public class Save16 extends SaveFileVersion {
stream.writeFloat(player.x); //player x/y
stream.writeFloat(player.y);
stream.writeInt(player.health); //player health
stream.writeShort((short)player.health); //player health
stream.writeByte(control.upgrades().getWeapons().size - 1); //amount of weapons
@ -264,7 +264,7 @@ public class Save16 extends SaveFileVersion {
stream.writeByte(unit.type.id); //type
stream.writeFloat(unit.x); //x
stream.writeFloat(unit.y); //y
stream.writeShort(unit.health); //health
stream.writeShort((short)unit.health); //health
}
}

View File

@ -25,7 +25,7 @@ public abstract class BaseBlock {
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
return tile.entity.liquid.amount + amount < liquidCapacity
&& (tile.entity.liquid.liquid == liquid || tile.entity.liquid.amount <= 0.001f);
&& (tile.entity.liquid.liquid == liquid || tile.entity.liquid.amount <= 0.1f);
}
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){

View File

@ -126,7 +126,7 @@ public abstract class Turret extends Block{
public void drawPlace(int x, int y, int rotation, boolean valid){
Draw.color("place");
Lines.stroke(1f);
Lines.dashCircle(x * tilesize, y * tilesize, range);
Lines.dashCircle(x * tilesize + getPlaceOffset().x, y * tilesize + getPlaceOffset().y, range);
}
@Override
@ -237,13 +237,17 @@ public abstract class Turret extends Block{
}
protected void ejectEffects(Tile tile){
if(!(tile.entity instanceof TurretEntity)) return;
if(!isTurret(tile)) return;
TurretEntity entity = tile.entity();
Effects.effect(ammoUseEffect, tile.drawx() - Angles.trnsx(entity.rotation, ammoEjectBack),
tile.drawy() - Angles.trnsy(entity.rotation, ammoEjectBack), entity.rotation);
}
protected boolean isTurret(Tile tile){
return (tile.entity instanceof TurretEntity);
}
@Override
public TileEntity getEntity(){
return new TurretEntity();

View File

@ -33,12 +33,15 @@ public class LaserTurret extends PowerTurret {
for(int i = 0; i < chargeEffects; i ++){
Timers.run(Mathf.random(chargeMaxDelay), () -> {
if(!isTurret(tile)) return;
tr.trns(entity.rotation, size * tilesize / 2);
Effects.effect(chargeEffect, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
});
}
Timers.run(chargeTime, () -> {
if(!isTurret(tile)) return;
tr.trns(entity.rotation, size * tilesize / 2);
entity.recoil = recoil;
entity.heat = 1f;
bullet(tile, ammo.bullet, entity.rotation + Mathf.range(inaccuracy));

View File

@ -8,6 +8,7 @@ import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.Turret;
import io.anuke.ucore.core.Effects;
public abstract class LiquidTurret extends Turret {
protected AmmoType[] ammoTypes;
@ -22,7 +23,23 @@ public abstract class LiquidTurret extends Turret {
public void setBars() {
super.setBars();
bars.remove(BarType.inventory);
bars.add(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquid.amount / liquidCapacity));
bars.replace(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquid.amount / liquidCapacity));
}
@Override
protected void effects(Tile tile){
AmmoType type = peekAmmo(tile);
TurretEntity entity = tile.entity();
Effects.effect(shootEffect, type.liquid.color, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
Effects.effect(smokeEffect, type.liquid.color, tile.drawx() + tr.x, tile.drawy() + tr.y, entity.rotation);
if (shootShake > 0) {
Effects.shake(shootShake, shootShake, tile.entity);
}
entity.recoil = recoil;
}
@Override