it is done
This commit is contained in:
160
core/src/mindustry/entities/effect/Lightning.java
Normal file
160
core/src/mindustry/entities/effect/Lightning.java
Normal file
@@ -0,0 +1,160 @@
|
||||
package mindustry.entities.effect;
|
||||
|
||||
import mindustry.annotations.Annotations.Loc;
|
||||
import mindustry.annotations.Annotations.Remote;
|
||||
import arc.struct.Array;
|
||||
import arc.struct.IntSet;
|
||||
import arc.graphics.Color;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.util.pooling.Pools;
|
||||
import mindustry.content.Bullets;
|
||||
import mindustry.entities.EntityGroup;
|
||||
import mindustry.entities.Units;
|
||||
import mindustry.entities.type.Bullet;
|
||||
import mindustry.entities.type.TimedEntity;
|
||||
import mindustry.entities.traits.DrawTrait;
|
||||
import mindustry.entities.traits.TimeTrait;
|
||||
import mindustry.entities.type.Unit;
|
||||
import mindustry.game.Team;
|
||||
import mindustry.gen.Call;
|
||||
import mindustry.graphics.Pal;
|
||||
import mindustry.world.Tile;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class Lightning extends TimedEntity implements DrawTrait, TimeTrait{
|
||||
public static final float lifetime = 10f;
|
||||
|
||||
private static final RandomXS128 random = new RandomXS128();
|
||||
private static final Rectangle rect = new Rectangle();
|
||||
private static final Array<Unit> entities = new Array<>();
|
||||
private static final IntSet hit = new IntSet();
|
||||
private static final int maxChain = 8;
|
||||
private static final float hitRange = 30f;
|
||||
private static int lastSeed = 0;
|
||||
|
||||
private Array<Vector2> lines = new Array<>();
|
||||
private Color color = Pal.lancerLaser;
|
||||
|
||||
/** For pooling use only. Do not call directly! */
|
||||
public Lightning(){
|
||||
}
|
||||
|
||||
/** Create a lighting branch at a location. Use Team.none to damage everyone. */
|
||||
public static void create(Team team, Color color, float damage, float x, float y, float targetAngle, int length){
|
||||
Call.createLighting(nextSeed(), team, color, damage, x, y, targetAngle, length);
|
||||
}
|
||||
|
||||
public static int nextSeed(){
|
||||
return lastSeed++;
|
||||
}
|
||||
|
||||
/** Do not invoke! */
|
||||
@Remote(called = Loc.server, unreliable = true)
|
||||
public static void createLighting(int seed, Team team, Color color, float damage, float x, float y, float rotation, int length){
|
||||
|
||||
Lightning l = Pools.obtain(Lightning.class, Lightning::new);
|
||||
Float dmg = damage;
|
||||
|
||||
l.x = x;
|
||||
l.y = y;
|
||||
l.color = color;
|
||||
l.add();
|
||||
|
||||
random.setSeed(seed);
|
||||
hit.clear();
|
||||
|
||||
boolean[] bhit = {false};
|
||||
|
||||
for(int i = 0; i < length / 2; i++){
|
||||
Bullet.create(Bullets.damageLightning, l, team, x, y, 0f, 1f, 1f, dmg);
|
||||
l.lines.add(new Vector2(x + Mathf.range(3f), y + Mathf.range(3f)));
|
||||
|
||||
if(l.lines.size > 1){
|
||||
bhit[0] = false;
|
||||
Position from = l.lines.get(l.lines.size - 2);
|
||||
Position to = l.lines.get(l.lines.size - 1);
|
||||
world.raycastEach(world.toTile(from.getX()), world.toTile(from.getY()), world.toTile(to.getX()), world.toTile(to.getY()), (wx, wy) -> {
|
||||
|
||||
Tile tile = world.ltile(wx, wy);
|
||||
if(tile != null && tile.block().insulated){
|
||||
bhit[0] = true;
|
||||
//snap it instead of removing
|
||||
l.lines.get(l.lines.size -1).set(wx * tilesize, wy * tilesize);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if(bhit[0]) break;
|
||||
}
|
||||
|
||||
rect.setSize(hitRange).setCenter(x, y);
|
||||
entities.clear();
|
||||
if(hit.size < maxChain){
|
||||
Units.nearbyEnemies(team, rect, u -> {
|
||||
if(!hit.contains(u.getID())){
|
||||
entities.add(u);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Unit furthest = Geometry.findFurthest(x, y, entities);
|
||||
|
||||
if(furthest != null){
|
||||
hit.add(furthest.getID());
|
||||
x = furthest.x;
|
||||
y = furthest.y;
|
||||
}else{
|
||||
rotation += random.range(20f);
|
||||
|
||||
x += Angles.trnsx(rotation, hitRange / 2f);
|
||||
y += Angles.trnsy(rotation, hitRange / 2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float lifetime(){
|
||||
return lifetime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(){
|
||||
super.reset();
|
||||
color = Pal.lancerLaser;
|
||||
lines.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(){
|
||||
super.removed();
|
||||
Pools.free(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Lines.stroke(3f * fout());
|
||||
Draw.color(color, Color.white, fin());
|
||||
Lines.beginLine();
|
||||
|
||||
Lines.linePoint(x, y);
|
||||
for(Position p : lines){
|
||||
Lines.linePoint(p.getX(), p.getY());
|
||||
}
|
||||
Lines.endLine();
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(Position p : lines){
|
||||
Fill.square(p.getX(), p.getY(), (5f - (float)i++ / lines.size * 2f) * fout(), 45);
|
||||
}
|
||||
Draw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityGroup targetGroup(){
|
||||
return bulletGroup;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user