Fixed logic config() called in clients / JSON-compatible effects

This commit is contained in:
Anuken
2020-11-01 10:30:30 -05:00
parent 187cb79265
commit d786c8668e
8 changed files with 165 additions and 10 deletions

View File

@@ -21,11 +21,14 @@ public class Effect{
private static final EffectContainer container = new EffectContainer();
private static final Seq<Effect> all = new Seq<>();
private boolean initialized;
public final int id;
public final Cons<EffectContainer> renderer;
public final float lifetime;
public Cons<EffectContainer> renderer = e -> {};
public float lifetime = 50f;
/** Clip size. */
public float size;
public float clip;
public float layer = Layer.effect;
public float layerDuration;
@@ -34,14 +37,22 @@ public class Effect{
this.id = all.size;
this.lifetime = life;
this.renderer = renderer;
this.size = clipsize;
this.clip = clipsize;
all.add(this);
}
public Effect(float life, Cons<EffectContainer> renderer){
this(life,50f, renderer);
this(life, 50f, renderer);
}
//for custom implementations
public Effect(){
this.id = all.size;
all.add(this);
}
public void init(){}
public Effect layer(float l){
layer = l;
return this;
@@ -89,12 +100,16 @@ public class Effect{
container.set(id, color, life, lifetime, rotation, x, y, data);
Draw.z(layer);
Draw.reset();
renderer.get(container);
render(container);
Draw.reset();
return container.lifetime;
}
public void render(EffectContainer e){
renderer.get(e);
}
public static @Nullable Effect get(int id){
return id >= all.size || id < 0 ? null : all.get(id);
}
@@ -122,9 +137,14 @@ public class Effect{
if(headless || effect == Fx.none) return;
if(Core.settings.getBool("effects")){
Rect view = Core.camera.bounds(Tmp.r1);
Rect pos = Tmp.r2.setSize(effect.size).setCenter(x, y);
Rect pos = Tmp.r2.setSize(effect.clip).setCenter(x, y);
if(view.overlaps(pos)){
if(!effect.initialized){
effect.initialized = true;
effect.init();
}
EffectState entity = EffectState.create();
entity.effect = effect;
entity.rotation = rotation;

View File

@@ -1319,7 +1319,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
@Override
public void control(LAccess type, Object p1, double p2, double p3, double p4){
if(type == LAccess.configure && block.logicConfigurable){
//don't execute configure instructions as the client
if(type == LAccess.configure && block.logicConfigurable && !net.client()){
//change config only if it's new
Object prev = senseObject(LAccess.config);
if(prev != p1){

View File

@@ -22,6 +22,6 @@ abstract class EffectStateComp implements Posc, Drawc, Timedc, Rotc, Childc{
@Replace
public float clipSize(){
return effect.size;
return effect.clip;
}
}

View File

@@ -0,0 +1,32 @@
package mindustry.entities.effect;
import mindustry.entities.*;
/** Renders multiple particle effects at once. */
public class MultiEffect extends Effect{
public Effect[] effects = {};
public MultiEffect(){
clip = 100f;
}
public MultiEffect(Effect... effects){
this();
this.effects = effects;
}
@Override
public void init(){
for(Effect f : effects){
clip = Math.max(clip, f.clip);
}
}
@Override
public void render(EffectContainer e){
for(Effect f : effects){
e.scaled(f.lifetime, f::render);
clip = Math.max(clip, f.clip);
}
}
}

View File

@@ -0,0 +1,55 @@
package mindustry.entities.effect;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
import mindustry.entities.*;
/** The most essential effect class. Can create particles in various shapes. */
public class ParticleEffect extends Effect{
public Color colorFrom = Color.white.cpy(), colorTo = Color.white.cpy();
public int particles = 6;
public float cone = 180f, length = 20f, baseLength = 0f;
public Interp interp = Interp.linear;
//region only
public float sizeFrom = 2f, sizeTo = 0f;
public String region = "circle";
//line only
public boolean line;
public float strokeFrom = 2f, strokeTo = 0f, lenFrom = 4f, lenTo = 2f;
private @Nullable TextureRegion tex;
@Override
public void init(){
clip = Math.max(clip, length + Math.max(sizeFrom, sizeTo));
}
@Override
public void render(EffectContainer e){
if(tex == null) tex = Core.atlas.find(region);
float rawfin = e.fin();
float fin = e.fin(interp);
float rad = interp.apply(sizeFrom, sizeTo, rawfin) * 2;
Draw.color(colorFrom, colorTo, fin);
if(line){
Lines.stroke(interp.apply(strokeFrom, strokeTo, rawfin));
float len = interp.apply(lenFrom, lenTo, rawfin);
Angles.randLenVectors(e.id, particles, length * fin + baseLength, e.rotation, cone, (x, y) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), len);
});
}else{
Angles.randLenVectors(e.id, particles, length * fin + baseLength, e.rotation, cone, (x, y) -> {
Draw.rect(tex, e.x + x, e.y + y, rad, rad);
});
}
}
}

View File

@@ -0,0 +1,33 @@
package mindustry.entities.effect;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.entities.*;
/** Effect that renders a basic shockwave. */
public class WaveEffect extends Effect{
public Color colorFrom = Color.white.cpy(), colorTo = Color.white.cpy();
public float sizeFrom = 0f, sizeTo = 100f;
public int sides = -1;
public float rotation = 0f;
public float strokeFrom = 2f, strokeTo = 0f;
public Interp interp = Interp.linear;
@Override
public void init(){
clip = Math.max(clip, Math.max(sizeFrom, sizeTo) + Math.max(strokeFrom, strokeTo));
}
@Override
public void render(EffectContainer e){
float fin = e.fin();
float ifin = e.fin(interp);
Draw.color(colorFrom, colorTo, ifin);
Lines.stroke(interp.apply(strokeFrom, strokeTo, fin));
float rad = interp.apply(sizeFrom, sizeTo, fin);
Lines.poly(e.x, e.y, sides <= 0 ? Lines.circleVertices(rad) : sides, rad, rotation + e.rotation);
}
}