Fixed logic config() called in clients / JSON-compatible effects
This commit is contained in:
@@ -21,11 +21,14 @@ public class Effect{
|
|||||||
private static final EffectContainer container = new EffectContainer();
|
private static final EffectContainer container = new EffectContainer();
|
||||||
private static final Seq<Effect> all = new Seq<>();
|
private static final Seq<Effect> all = new Seq<>();
|
||||||
|
|
||||||
|
private boolean initialized;
|
||||||
|
|
||||||
public final int id;
|
public final int id;
|
||||||
public final Cons<EffectContainer> renderer;
|
|
||||||
public final float lifetime;
|
public Cons<EffectContainer> renderer = e -> {};
|
||||||
|
public float lifetime = 50f;
|
||||||
/** Clip size. */
|
/** Clip size. */
|
||||||
public float size;
|
public float clip;
|
||||||
|
|
||||||
public float layer = Layer.effect;
|
public float layer = Layer.effect;
|
||||||
public float layerDuration;
|
public float layerDuration;
|
||||||
@@ -34,14 +37,22 @@ public class Effect{
|
|||||||
this.id = all.size;
|
this.id = all.size;
|
||||||
this.lifetime = life;
|
this.lifetime = life;
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.size = clipsize;
|
this.clip = clipsize;
|
||||||
all.add(this);
|
all.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Effect(float life, Cons<EffectContainer> renderer){
|
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){
|
public Effect layer(float l){
|
||||||
layer = l;
|
layer = l;
|
||||||
return this;
|
return this;
|
||||||
@@ -89,12 +100,16 @@ public class Effect{
|
|||||||
container.set(id, color, life, lifetime, rotation, x, y, data);
|
container.set(id, color, life, lifetime, rotation, x, y, data);
|
||||||
Draw.z(layer);
|
Draw.z(layer);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
renderer.get(container);
|
render(container);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
return container.lifetime;
|
return container.lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void render(EffectContainer e){
|
||||||
|
renderer.get(e);
|
||||||
|
}
|
||||||
|
|
||||||
public static @Nullable Effect get(int id){
|
public static @Nullable Effect get(int id){
|
||||||
return id >= all.size || id < 0 ? null : all.get(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(headless || effect == Fx.none) return;
|
||||||
if(Core.settings.getBool("effects")){
|
if(Core.settings.getBool("effects")){
|
||||||
Rect view = Core.camera.bounds(Tmp.r1);
|
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(view.overlaps(pos)){
|
||||||
|
if(!effect.initialized){
|
||||||
|
effect.initialized = true;
|
||||||
|
effect.init();
|
||||||
|
}
|
||||||
|
|
||||||
EffectState entity = EffectState.create();
|
EffectState entity = EffectState.create();
|
||||||
entity.effect = effect;
|
entity.effect = effect;
|
||||||
entity.rotation = rotation;
|
entity.rotation = rotation;
|
||||||
|
|||||||
@@ -1319,7 +1319,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void control(LAccess type, Object p1, double p2, double p3, double p4){
|
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
|
//change config only if it's new
|
||||||
Object prev = senseObject(LAccess.config);
|
Object prev = senseObject(LAccess.config);
|
||||||
if(prev != p1){
|
if(prev != p1){
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ abstract class EffectStateComp implements Posc, Drawc, Timedc, Rotc, Childc{
|
|||||||
|
|
||||||
@Replace
|
@Replace
|
||||||
public float clipSize(){
|
public float clipSize(){
|
||||||
return effect.size;
|
return effect.clip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
core/src/mindustry/entities/effect/MultiEffect.java
Normal file
32
core/src/mindustry/entities/effect/MultiEffect.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
core/src/mindustry/entities/effect/ParticleEffect.java
Normal file
55
core/src/mindustry/entities/effect/ParticleEffect.java
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
core/src/mindustry/entities/effect/WaveEffect.java
Normal file
33
core/src/mindustry/entities/effect/WaveEffect.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import arc.files.*;
|
|||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.mock.*;
|
import arc.mock.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -19,6 +20,7 @@ import mindustry.content.TechTree.*;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
|
import mindustry.entities.effect.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Objectives.*;
|
import mindustry.game.Objectives.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -41,7 +43,17 @@ public class ContentParser{
|
|||||||
ObjectSet<Class<?>> implicitNullable = ObjectSet.with(TextureRegion.class, TextureRegion[].class, TextureRegion[][].class);
|
ObjectSet<Class<?>> implicitNullable = ObjectSet.with(TextureRegion.class, TextureRegion[].class, TextureRegion[][].class);
|
||||||
|
|
||||||
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
|
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
|
||||||
put(Effect.class, (type, data) -> field(Fx.class, data));
|
put(Effect.class, (type, data) -> {
|
||||||
|
if(data.isString()){
|
||||||
|
return field(Fx.class, data);
|
||||||
|
}
|
||||||
|
Class<? extends Effect> bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.effect") : ParticleEffect.class;
|
||||||
|
data.remove("type");
|
||||||
|
Effect result = make(bc);
|
||||||
|
readFields(result, data);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
put(Interp.class, (type, data) -> field(Interp.class, data));
|
||||||
put(Schematic.class, (type, data) -> {
|
put(Schematic.class, (type, data) -> {
|
||||||
Object result = fieldOpt(Loadouts.class, data);
|
Object result = fieldOpt(Loadouts.class, data);
|
||||||
if(result != null){
|
if(result != null){
|
||||||
|
|||||||
@@ -468,6 +468,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
shouldHide = false;
|
shouldHide = false;
|
||||||
Sector from = findLauncher(sector);
|
Sector from = findLauncher(sector);
|
||||||
if(from == null){
|
if(from == null){
|
||||||
|
//clear loadout information, so only the basic loadout gets used
|
||||||
|
universe.clearLoadoutInfo();
|
||||||
//free launch.
|
//free launch.
|
||||||
control.playSector(sector);
|
control.playSector(sector);
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
Reference in New Issue
Block a user