it is done

This commit is contained in:
Anuken
2019-12-25 01:39:38 -05:00
parent 5b21873f3c
commit 514d4817c8
488 changed files with 4572 additions and 4574 deletions

View File

@@ -0,0 +1,49 @@
package mindustry.entities.bullet;
import arc.graphics.g2d.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.Effects.*;
import mindustry.entities.type.Bullet;
import mindustry.gen.*;
//TODO scale velocity depending on fslope()
public class ArtilleryBulletType extends BasicBulletType{
protected Effect trailEffect = Fx.artilleryTrail;
public ArtilleryBulletType(float speed, float damage, String bulletSprite){
super(speed, damage, bulletSprite);
collidesTiles = false;
collides = false;
collidesAir = false;
hitShake = 1f;
hitSound = Sounds.explosion;
}
public ArtilleryBulletType(){
this(1f, 1f, "shell");
}
@Override
public void update(mindustry.entities.type.Bullet b){
super.update(b);
if(b.timer.get(0, 3 + b.fslope() * 2f)){
Effects.effect(trailEffect, backColor, b.x, b.y, b.fslope() * 4f);
}
}
@Override
public void draw(Bullet b){
float baseScale = 0.7f;
float scale = (baseScale + b.fslope() * (1f - baseScale));
float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout());
Draw.color(backColor);
Draw.rect(backRegion, b.x, b.y, bulletWidth * scale, height * scale, b.rot() - 90);
Draw.color(frontColor);
Draw.rect(frontRegion, b.x, b.y, bulletWidth * scale, height * scale, b.rot() - 90);
Draw.color();
}
}

View File

@@ -0,0 +1,46 @@
package mindustry.entities.bullet;
import arc.Core;
import arc.graphics.Color;
import arc.graphics.g2d.Draw;
import arc.graphics.g2d.TextureRegion;
import mindustry.entities.type.Bullet;
import mindustry.graphics.Pal;
/** An extended BulletType for most ammo-based bullets shot from turrets and units. */
public class BasicBulletType extends BulletType{
public Color backColor = Pal.bulletYellowBack, frontColor = Pal.bulletYellow;
public float bulletWidth = 5f, bulletHeight = 7f;
public float bulletShrink = 0.5f;
public String bulletSprite;
public TextureRegion backRegion;
public TextureRegion frontRegion;
public BasicBulletType(float speed, float damage, String bulletSprite){
super(speed, damage);
this.bulletSprite = bulletSprite;
}
/** For mods. */
public BasicBulletType(){
this(1f, 1f, "bullet");
}
@Override
public void load(){
backRegion = Core.atlas.find(bulletSprite + "-back");
frontRegion = Core.atlas.find(bulletSprite);
}
@Override
public void draw(Bullet b){
float height = bulletHeight * ((1f - bulletShrink) + bulletShrink * b.fout());
Draw.color(backColor);
Draw.rect(backRegion, b.x, b.y, bulletWidth, height, b.rot() - 90);
Draw.color(frontColor);
Draw.rect(frontRegion, b.x, b.y, bulletWidth, height, b.rot() - 90);
Draw.color();
}
}

View File

@@ -0,0 +1,24 @@
package mindustry.entities.bullet;
import mindustry.gen.*;
public class BombBulletType extends BasicBulletType{
public BombBulletType(float damage, float radius, String sprite){
super(0.7f, 0, sprite);
splashDamageRadius = radius;
splashDamage = damage;
collidesTiles = false;
collides = false;
bulletShrink = 0.7f;
lifetime = 30f;
drag = 0.05f;
keepVelocity = false;
collidesAir = false;
hitSound = Sounds.explosion;
}
public BombBulletType(){
this(1f, 1f, "shell");
}
}

View File

@@ -0,0 +1,165 @@
package mindustry.entities.bullet;
import arc.audio.*;
import arc.math.*;
import mindustry.content.*;
import mindustry.ctype.Content;
import mindustry.ctype.ContentType;
import mindustry.entities.*;
import mindustry.entities.Effects.*;
import mindustry.entities.effect.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
public abstract class BulletType extends Content{
public float lifetime;
public float speed;
public float damage;
public float hitSize = 4;
public float drawSize = 40f;
public float drag = 0f;
public boolean pierce;
public Effect hitEffect, despawnEffect;
/** Effect created when shooting. */
public Effect shootEffect = Fx.shootSmall;
/** Extra smoke effect created when shooting. */
public Effect smokeEffect = Fx.shootSmallSmoke;
/** Sound made when hitting something or getting removed.*/
public Sound hitSound = Sounds.none;
/** Extra inaccuracy when firing. */
public float inaccuracy = 0f;
/** How many bullets get created per ammo item/liquid. */
public float ammoMultiplier = 2f;
/** Multiplied by turret reload speed to get final shoot speed. */
public float reloadMultiplier = 1f;
/** Recoil from shooter entities. */
public float recoil;
public float splashDamage = 0f;
/** Knockback in velocity. */
public float knockback;
/** Whether this bullet hits tiles. */
public boolean hitTiles = true;
/** Status effect applied on hit. */
public StatusEffect status = StatusEffects.none;
/** Intensity of applied status effect in terms of duration. */
public float statusDuration = 60 * 10f;
/** Whether this bullet type collides with tiles. */
public boolean collidesTiles = true;
/** Whether this bullet type collides with tiles that are of the same team. */
public boolean collidesTeam = false;
/** Whether this bullet type collides with air units. */
public boolean collidesAir = true;
/** Whether this bullet types collides with anything at all. */
public boolean collides = true;
/** Whether velocity is inherited from the shooter. */
public boolean keepVelocity = true;
//additional effects
public int fragBullets = 9;
public float fragVelocityMin = 0.2f, fragVelocityMax = 1f;
public BulletType fragBullet = null;
/** Use a negative value to disable splash damage. */
public float splashDamageRadius = -1f;
public int incendAmount = 0;
public float incendSpread = 8f;
public float incendChance = 1f;
public float homingPower = 0f;
public float homingRange = 50f;
public int lightining;
public int lightningLength = 5;
public float hitShake = 0f;
public BulletType(float speed, float damage){
this.speed = speed;
this.damage = damage;
lifetime = 40f;
hitEffect = Fx.hitBulletSmall;
despawnEffect = Fx.hitBulletSmall;
}
/** Returns maximum distance the bullet this bullet type has can travel. */
public float range(){
return speed * lifetime * (1f - drag);
}
public boolean collides(Bullet bullet, Tile tile){
return true;
}
public void hitTile(Bullet b, Tile tile){
hit(b);
}
public void hit(Bullet b){
hit(b, b.x, b.y);
}
public void hit(Bullet b, float x, float y){
Effects.effect(hitEffect, x, y, b.rot());
hitSound.at(b);
Effects.shake(hitShake, hitShake, b);
if(fragBullet != null){
for(int i = 0; i < fragBullets; i++){
float len = Mathf.random(1f, 7f);
float a = Mathf.random(360f);
Bullet.create(fragBullet, b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax));
}
}
if(Mathf.chance(incendChance)){
Damage.createIncend(x, y, incendSpread, incendAmount);
}
if(splashDamageRadius > 0){
Damage.damage(b.getTeam(), x, y, splashDamageRadius, splashDamage * b.damageMultiplier());
}
}
public void despawned(Bullet b){
Effects.effect(despawnEffect, b.x, b.y, b.rot());
hitSound.at(b);
if(fragBullet != null || splashDamageRadius > 0){
hit(b);
}
for(int i = 0; i < lightining; i++){
Lightning.createLighting(Lightning.nextSeed(), b.getTeam(), Pal.surge, damage, b.x, b.y, Mathf.random(360f), lightningLength);
}
}
public void draw(Bullet b){
}
public void init(Bullet b){
}
public void update(Bullet b){
if(homingPower > 0.0001f){
TargetTrait target = Units.closestTarget(b.getTeam(), b.x, b.y, homingRange, e -> !e.isFlying() || collidesAir);
if(target != null){
b.velocity().setAngle(Mathf.slerpDelta(b.velocity().angle(), b.angleTo(target), 0.08f));
}
}
}
@Override
public ContentType getContentType(){
return ContentType.bullet;
}
}

View File

@@ -0,0 +1,46 @@
package mindustry.entities.bullet;
import arc.math.geom.Rectangle;
import arc.util.Time;
import mindustry.content.Fx;
import mindustry.entities.Units;
import mindustry.entities.type.Bullet;
public class FlakBulletType extends BasicBulletType{
protected static Rectangle rect = new Rectangle();
protected float explodeRange = 30f;
public FlakBulletType(float speed, float damage){
super(speed, damage, "shell");
splashDamage = 15f;
splashDamageRadius = 34f;
hitEffect = Fx.flakExplosionBig;
bulletWidth = 8f;
bulletHeight = 10f;
}
public FlakBulletType(){
this(1f, 1f);
}
@Override
public void update(Bullet b){
super.update(b);
if(b.getData() instanceof Integer) return;
if(b.timer.get(2, 6)){
Units.nearbyEnemies(b.getTeam(), rect.setSize(explodeRange * 2f).setCenter(b.x, b.y), unit -> {
if(b.getData() instanceof Float) return;
if(unit.dst(b) < explodeRange){
b.setData(0);
Time.run(5f, () -> {
if(b.getData() instanceof Integer){
b.time(b.lifetime());
}
});
}
});
}
}
}

View File

@@ -0,0 +1,54 @@
package mindustry.entities.bullet;
import arc.graphics.*;
import arc.graphics.g2d.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.type.*;
import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
public class HealBulletType extends BulletType{
protected float healPercent = 3f;
public HealBulletType(float speed, float damage){
super(speed, damage);
shootEffect = Fx.shootHeal;
smokeEffect = Fx.hitLaser;
hitEffect = Fx.hitLaser;
despawnEffect = Fx.hitLaser;
collidesTeam = true;
}
public HealBulletType(){
this(1f, 1f);
}
@Override
public boolean collides(Bullet b, Tile tile){
return tile.getTeam() != b.getTeam() || tile.entity.healthf() < 1f;
}
@Override
public void draw(Bullet b){
Draw.color(Pal.heal);
Lines.stroke(2f);
Lines.lineAngleCenter(b.x, b.y, b.rot(), 7f);
Draw.color(Color.white);
Lines.lineAngleCenter(b.x, b.y, b.rot(), 3f);
Draw.reset();
}
@Override
public void hitTile(Bullet b, Tile tile){
super.hit(b);
tile = tile.link();
if(tile.entity != null && tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){
Effects.effect(Fx.healBlockFull, Pal.heal, tile.drawx(), tile.drawy(), tile.block().size);
tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth());
}
}
}

View File

@@ -0,0 +1,81 @@
package mindustry.entities.bullet;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.entities.type.Bullet;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.*;
public class LiquidBulletType extends BulletType{
public @NonNull Liquid liquid;
public float puddleSize = 5f;
public LiquidBulletType(@Nullable Liquid liquid){
super(3.5f, 0);
if(liquid != null){
this.liquid = liquid;
this.status = liquid.effect;
}
lifetime = 74f;
statusDuration = 90f;
despawnEffect = Fx.none;
hitEffect = Fx.hitLiquid;
smokeEffect = Fx.none;
shootEffect = Fx.none;
drag = 0.009f;
knockback = 0.55f;
}
public LiquidBulletType(){
this(null);
}
@Override
public float range(){
return speed * lifetime / 2f;
}
@Override
public void update(Bullet b){
super.update(b);
if(liquid.canExtinguish()){
Tile tile = world.tileWorld(b.x, b.y);
if(tile != null && Fire.has(tile.x, tile.y)){
Fire.extinguish(tile, 100f);
b.remove();
hit(b);
}
}
}
@Override
public void draw(Bullet b){
Draw.color(liquid.color, Color.white, b.fout() / 100f);
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);
Puddle.deposit(world.tileWorld(hitx, hity), liquid, puddleSize);
if(liquid.temperature <= 0.5f && liquid.flammability < 0.3f){
float intensity = 400f;
Fire.extinguish(world.tileWorld(hitx, hity), intensity);
for(Point2 p : Geometry.d4){
Fire.extinguish(world.tileWorld(hitx + p.x * tilesize, hity + p.y * tilesize), intensity);
}
}
}
}

View File

@@ -0,0 +1,107 @@
package mindustry.entities.bullet;
import arc.graphics.Color;
import arc.graphics.g2d.Draw;
import arc.math.Angles;
import arc.math.Mathf;
import mindustry.content.Fx;
import mindustry.entities.Effects;
import mindustry.entities.type.Bullet;
import mindustry.graphics.Pal;
import mindustry.world.blocks.distribution.MassDriver.DriverBulletData;
import static mindustry.Vars.content;
public class MassDriverBolt extends BulletType{
public MassDriverBolt(){
super(5.3f, 50);
collidesTiles = false;
lifetime = 200f;
despawnEffect = Fx.smeltsmoke;
hitEffect = Fx.hitBulletBig;
drag = 0.005f;
}
@Override
public void draw(mindustry.entities.type.Bullet b){
float w = 11f, h = 13f;
Draw.color(Pal.bulletYellowBack);
Draw.rect("shell-back", b.x, b.y, w, h, b.rot() + 90);
Draw.color(Pal.bulletYellow);
Draw.rect("shell", b.x, b.y, w, h, b.rot() + 90);
Draw.reset();
}
@Override
public void update(mindustry.entities.type.Bullet b){
//data MUST be an instance of DriverBulletData
if(!(b.getData() instanceof DriverBulletData)){
hit(b);
return;
}
float hitDst = 7f;
DriverBulletData data = (DriverBulletData)b.getData();
//if the target is dead, just keep flying until the bullet explodes
if(data.to.isDead()){
return;
}
float baseDst = data.from.dst(data.to);
float dst1 = b.dst(data.from);
float dst2 = b.dst(data.to);
boolean intersect = false;
//bullet has gone past the destination point: but did it intersect it?
if(dst1 > baseDst){
float angleTo = b.angleTo(data.to);
float baseAngle = data.to.angleTo(data.from);
//if angles are nearby, then yes, it did
if(Angles.near(angleTo, baseAngle, 2f)){
intersect = true;
//snap bullet position back; this is used for low-FPS situations
b.set(data.to.x + Angles.trnsx(baseAngle, hitDst), data.to.y + Angles.trnsy(baseAngle, hitDst));
}
}
//if on course and it's in range of the target
if(Math.abs(dst1 + dst2 - baseDst) < 4f && dst2 <= hitDst){
intersect = true;
} //else, bullet has gone off course, does not get recieved.
if(intersect){
data.to.handlePayload(b, data);
}
}
@Override
public void despawned(mindustry.entities.type.Bullet b){
super.despawned(b);
if(!(b.getData() instanceof DriverBulletData)) return;
DriverBulletData data = (DriverBulletData)b.getData();
for(int i = 0; i < data.items.length; i++){
int amountDropped = Mathf.random(0, data.items[i]);
if(amountDropped > 0){
float angle = b.rot() + Mathf.range(100f);
Effects.effect(Fx.dropItem, Color.white, b.x, b.y, angle, content.item(i));
}
}
}
@Override
public void hit(Bullet b, float hitx, float hity){
super.hit(b, hitx, hity);
despawned(b);
}
}

View File

@@ -0,0 +1,42 @@
package mindustry.entities.bullet;
import arc.graphics.Color;
import arc.math.Mathf;
import arc.util.Time;
import mindustry.content.Fx;
import mindustry.entities.Effects;
import mindustry.entities.type.Bullet;
import mindustry.gen.*;
import mindustry.graphics.Pal;
public class MissileBulletType extends BasicBulletType{
protected Color trailColor = Pal.missileYellowBack;
protected float weaveScale = 0f;
protected float weaveMag = -1f;
public MissileBulletType(float speed, float damage, String bulletSprite){
super(speed, damage, bulletSprite);
backColor = Pal.missileYellowBack;
frontColor = Pal.missileYellow;
homingPower = 7f;
hitSound = Sounds.explosion;
}
public MissileBulletType(){
this(1f, 1f, "missile");
}
@Override
public void update(Bullet b){
super.update(b);
if(Mathf.chance(Time.delta() * 0.2)){
Effects.effect(Fx.missileTrail, trailColor, b.x, b.y, 2f);
}
if(weaveMag > 0){
b.velocity().rotate(Mathf.sin(Time.time() + b.id * 4422, weaveScale, weaveMag) * Time.delta());
}
}
}