Merge branch 'master' into crater
# Conflicts: # core/assets/sprites/block_colors.png # core/assets/sprites/sprites.atlas # core/assets/sprites/sprites.png # core/assets/sprites/sprites3.png # core/assets/sprites/sprites5.png # core/src/mindustry/world/modules/ItemModule.java
This commit is contained in:
@@ -39,7 +39,7 @@ public class WaveSpawner{
|
||||
|
||||
/** @return true if the player is near a ground spawn point. */
|
||||
public boolean playerNear(){
|
||||
return groundSpawns.contains(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x, player.y) < state.rules.dropZoneRadius);
|
||||
return groundSpawns.contains(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x, player.y) < state.rules.dropZoneRadius && player.getTeam() != state.rules.waveTeam);
|
||||
}
|
||||
|
||||
public void spawnEnemies(){
|
||||
|
||||
@@ -166,6 +166,13 @@ public class Renderer implements ApplicationListener{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume(){
|
||||
if(settings.getBool("bloom") && bloom != null){
|
||||
bloom.resume();
|
||||
}
|
||||
}
|
||||
|
||||
void setupBloom(){
|
||||
try{
|
||||
if(bloom != null){
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package mindustry.entities;
|
||||
|
||||
import arc.Core;
|
||||
import arc.struct.Array;
|
||||
import arc.func.Cons;
|
||||
import arc.graphics.Color;
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.Mathf;
|
||||
import arc.math.geom.Position;
|
||||
import arc.util.pooling.Pools;
|
||||
import mindustry.entities.type.EffectEntity;
|
||||
import mindustry.entities.traits.ScaleTrait;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.pooling.*;
|
||||
import mindustry.entities.type.*;
|
||||
|
||||
public class Effects{
|
||||
private static final EffectContainer container = new EffectContainer();
|
||||
@@ -126,7 +125,7 @@ public class Effects{
|
||||
}
|
||||
}
|
||||
|
||||
public static class EffectContainer implements ScaleTrait{
|
||||
public static class EffectContainer implements Scaled{
|
||||
public float x, y, time, lifetime, rotation;
|
||||
public Color color;
|
||||
public int id;
|
||||
|
||||
@@ -125,7 +125,7 @@ public class EntityGroup<T extends Entity> implements Iterable<T>{
|
||||
entitiesToAdd.clear();
|
||||
|
||||
for(T e : entitiesToRemove){
|
||||
entityArray.removeValue(e, true);
|
||||
entityArray.remove(e, true);
|
||||
if(map != null){
|
||||
map.remove(e.getID());
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public class EntityGroup<T extends Entity> implements Iterable<T>{
|
||||
}else{ //maybe it's being queued?
|
||||
for(T check : entitiesToAdd){
|
||||
if(check.getID() == id){ //if it is indeed queued, remove it
|
||||
entitiesToAdd.removeValue(check, true);
|
||||
entitiesToAdd.remove(check, true);
|
||||
if(removeListener != null){
|
||||
removeListener.get(check);
|
||||
}
|
||||
|
||||
231
core/src/mindustry/entities/def/EntityComps.java
Normal file
231
core/src/mindustry/entities/def/EntityComps.java
Normal file
@@ -0,0 +1,231 @@
|
||||
package mindustry.entities.def;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.Bits;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.pooling.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.entities.bullet.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static mindustry.Vars.content;
|
||||
|
||||
public class EntityComps{
|
||||
|
||||
@Depends({HealthComp.class, VelComp.class, StatusComp.class})
|
||||
class UnitComp{
|
||||
|
||||
}
|
||||
|
||||
class OwnerComp{
|
||||
Entityc owner;
|
||||
}
|
||||
|
||||
@Depends({TimedComp.class})
|
||||
class BulletComp{
|
||||
BulletType bullet;
|
||||
|
||||
void init(){
|
||||
bullet.init();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TimedComp extends EntityComp implements Scaled{
|
||||
float time, lifetime;
|
||||
|
||||
void update(){
|
||||
time = Math.min(time + Time.delta(), lifetime);
|
||||
|
||||
if(time >= lifetime){
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float fin(){
|
||||
return time / lifetime;
|
||||
}
|
||||
}
|
||||
|
||||
class HealthComp{
|
||||
float health, maxHealth;
|
||||
boolean dead;
|
||||
|
||||
float healthf(){
|
||||
return health / maxHealth;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PosComp implements Position{
|
||||
float x, y;
|
||||
|
||||
void set(float x, float y){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
@Depends(PosComp.class)
|
||||
class VelComp{
|
||||
//transient fields act as imports from any other component clases; these are ignored by the generator
|
||||
transient float x, y;
|
||||
|
||||
final Vec2 vel = new Vec2();
|
||||
|
||||
void update(){
|
||||
x += vel.x;
|
||||
y += vel.y;
|
||||
vel.scl(0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
@Depends(PosComp.class)
|
||||
class HitboxComp{
|
||||
transient float x, y;
|
||||
|
||||
float hitSize;
|
||||
|
||||
boolean collides(Hitboxc other){
|
||||
return Intersector.overlapsRect(x - hitSize/2f, y - hitSize/2f, hitSize, hitSize,
|
||||
other.getX() - other.getHitSize()/2f, other.getY() - other.getHitSize()/2f, other.getHitSize(), other.getHitSize());
|
||||
}
|
||||
}
|
||||
|
||||
@Depends(PosComp.class)
|
||||
class StatusComp{
|
||||
private Array<StatusEntry> statuses = new Array<>();
|
||||
private Bits applied = new Bits(content.getBy(ContentType.status).size);
|
||||
|
||||
private float speedMultiplier;
|
||||
private float damageMultiplier;
|
||||
private float armorMultiplier;
|
||||
|
||||
void apply(StatusEffect effect, float duration){
|
||||
if(effect == StatusEffects.none || effect == null || isImmune(effect)) return; //don't apply empty or immune effects
|
||||
|
||||
if(statuses.size > 0){
|
||||
//check for opposite effects
|
||||
for(StatusEntry entry : statuses){
|
||||
//extend effect
|
||||
if(entry.effect == effect){
|
||||
entry.time = Math.max(entry.time, duration);
|
||||
return;
|
||||
}else if(entry.effect.reactsWith(effect)){ //find opposite
|
||||
StatusEntry.tmp.effect = entry.effect;
|
||||
//TODO unit cannot be null here
|
||||
entry.effect.getTransition(null, effect, entry.time, duration, StatusEntry.tmp);
|
||||
entry.time = StatusEntry.tmp.time;
|
||||
|
||||
if(StatusEntry.tmp.effect != entry.effect){
|
||||
entry.effect = StatusEntry.tmp.effect;
|
||||
}
|
||||
|
||||
//stop looking when one is found
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, no opposites found, add direct effect
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
|
||||
entry.set(effect, duration);
|
||||
statuses.add(entry);
|
||||
}
|
||||
|
||||
boolean isImmune(StatusEffect effect){
|
||||
return false;
|
||||
}
|
||||
|
||||
Color getStatusColor(){
|
||||
if(statuses.size == 0){
|
||||
return Tmp.c1.set(Color.white);
|
||||
}
|
||||
|
||||
float r = 0f, g = 0f, b = 0f;
|
||||
for(StatusEntry entry : statuses){
|
||||
r += entry.effect.color.r;
|
||||
g += entry.effect.color.g;
|
||||
b += entry.effect.color.b;
|
||||
}
|
||||
return Tmp.c1.set(r / statuses.size, g / statuses.size, b / statuses.size, 1f);
|
||||
}
|
||||
|
||||
void update(){
|
||||
applied.clear();
|
||||
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
||||
|
||||
if(statuses.isEmpty()) return;
|
||||
|
||||
statuses.eachFilter(entry -> {
|
||||
entry.time = Math.max(entry.time - Time.delta(), 0);
|
||||
applied.set(entry.effect.id);
|
||||
|
||||
if(entry.time <= 0){
|
||||
Pools.free(entry);
|
||||
return true;
|
||||
}else{
|
||||
speedMultiplier *= entry.effect.speedMultiplier;
|
||||
armorMultiplier *= entry.effect.armorMultiplier;
|
||||
damageMultiplier *= entry.effect.damageMultiplier;
|
||||
//TODO unit can't be null
|
||||
entry.effect.update(null, entry.time);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
boolean hasEffect(StatusEffect effect){
|
||||
return applied.get(effect.id);
|
||||
}
|
||||
|
||||
void writeSave(DataOutput stream) throws IOException{
|
||||
stream.writeByte(statuses.size);
|
||||
for(StatusEntry entry : statuses){
|
||||
stream.writeByte(entry.effect.id);
|
||||
stream.writeFloat(entry.time);
|
||||
}
|
||||
}
|
||||
|
||||
void readSave(DataInput stream, byte version) throws IOException{
|
||||
for(StatusEntry effect : statuses){
|
||||
Pools.free(effect);
|
||||
}
|
||||
|
||||
statuses.clear();
|
||||
|
||||
byte amount = stream.readByte();
|
||||
for(int i = 0; i < amount; i++){
|
||||
byte id = stream.readByte();
|
||||
float time = stream.readFloat();
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
|
||||
entry.set(content.getByID(ContentType.status, id), time);
|
||||
statuses.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BaseComponent
|
||||
class EntityComp{
|
||||
int id;
|
||||
|
||||
void init(){}
|
||||
|
||||
void update(){}
|
||||
|
||||
void remove(){}
|
||||
|
||||
<T> T as(Class<T> type){
|
||||
return (T)this;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
core/src/mindustry/entities/def/EntityDefs.java
Normal file
10
core/src/mindustry/entities/def/EntityDefs.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package mindustry.entities.def;
|
||||
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.def.EntityComps.*;
|
||||
|
||||
class EntityDefs{
|
||||
|
||||
@EntityDef({BulletComp.class, VelComp.class, TimedComp.class})
|
||||
class BulletDef{}
|
||||
}
|
||||
@@ -28,8 +28,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
||||
private Position to;
|
||||
private Runnable done;
|
||||
|
||||
public ItemTransfer(){
|
||||
}
|
||||
public ItemTransfer(){}
|
||||
|
||||
@Remote(called = Loc.server, unreliable = true)
|
||||
public static void transferItemEffect(Item item, float x, float y, Unit to){
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package mindustry.entities.traits;
|
||||
|
||||
import arc.math.Interpolation;
|
||||
|
||||
public interface ScaleTrait{
|
||||
/** 0 to 1. */
|
||||
float fin();
|
||||
|
||||
/** 1 to 0 */
|
||||
default float fout(){
|
||||
return 1f - fin();
|
||||
}
|
||||
|
||||
/** 1 to 0 */
|
||||
default float fout(Interpolation i){
|
||||
return i.apply(fout());
|
||||
}
|
||||
|
||||
/** 1 to 0, ending at the specified margin */
|
||||
default float fout(float margin){
|
||||
float f = fin();
|
||||
if(f >= 1f - margin){
|
||||
return 1f - (f - (1f - margin)) / margin;
|
||||
}else{
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
|
||||
/** 0 to 1 **/
|
||||
default float fin(Interpolation i){
|
||||
return i.apply(fin());
|
||||
}
|
||||
|
||||
/** 0 to 1 */
|
||||
default float finpow(){
|
||||
return Interpolation.pow3Out.apply(fin());
|
||||
}
|
||||
|
||||
/** 0 to 1 to 0 */
|
||||
default float fslope(){
|
||||
return (0.5f - Math.abs(fin() - 0.5f)) * 2f;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package mindustry.entities.traits;
|
||||
|
||||
import arc.math.Mathf;
|
||||
import arc.math.*;
|
||||
import arc.util.Time;
|
||||
|
||||
public interface TimeTrait extends ScaleTrait, Entity{
|
||||
public interface TimeTrait extends Scaled, Entity{
|
||||
|
||||
float lifetime();
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import mindustry.world.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Poolable, DrawTrait, VelocityTrait, TimeTrait, TeamTrait, AbsorbTrait{
|
||||
public class Bullet extends SolidEntity implements DamageTrait, Scaled, Poolable, DrawTrait, VelocityTrait, TimeTrait, TeamTrait, AbsorbTrait{
|
||||
public Interval timer = new Interval(3);
|
||||
|
||||
private float lifeScl;
|
||||
|
||||
@@ -36,7 +36,6 @@ import static mindustry.Vars.*;
|
||||
public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
||||
public static final int timerSync = 2;
|
||||
public static final int timerAbility = 3;
|
||||
public static final int timerTransfer = 4;
|
||||
private static final int timerShootLeft = 0;
|
||||
private static final int timerShootRight = 1;
|
||||
private static final float liftoffBoost = 0.2f;
|
||||
|
||||
@@ -204,7 +204,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
other.block().onProximityUpdate(other);
|
||||
|
||||
if(other.entity != null){
|
||||
other.entity.proximity.removeValue(tile, true);
|
||||
other.entity.proximity.remove(tile, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package mindustry.entities.type;
|
||||
|
||||
import arc.util.pooling.Pool.Poolable;
|
||||
import mindustry.entities.traits.ScaleTrait;
|
||||
import mindustry.entities.traits.TimeTrait;
|
||||
import arc.util.pooling.Pool.*;
|
||||
import mindustry.entities.traits.*;
|
||||
|
||||
public abstract class TimedEntity extends BaseEntity implements ScaleTrait, TimeTrait, Poolable{
|
||||
public abstract class TimedEntity extends BaseEntity implements TimeTrait, Poolable{
|
||||
public float time;
|
||||
|
||||
@Override
|
||||
|
||||
16
core/src/mindustry/entities/units/StatusEntry.java
Normal file
16
core/src/mindustry/entities/units/StatusEntry.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package mindustry.entities.units;
|
||||
|
||||
import mindustry.type.*;
|
||||
|
||||
public class StatusEntry{
|
||||
public static final StatusEntry tmp = new StatusEntry();
|
||||
|
||||
public StatusEffect effect;
|
||||
public float time;
|
||||
|
||||
public StatusEntry set(StatusEffect effect, float time){
|
||||
this.effect = effect;
|
||||
this.time = time;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -147,14 +147,4 @@ public class Statuses implements Saveable{
|
||||
}
|
||||
}
|
||||
|
||||
public static class StatusEntry{
|
||||
public StatusEffect effect;
|
||||
public float time;
|
||||
|
||||
public StatusEntry set(StatusEffect effect, float time){
|
||||
this.effect = effect;
|
||||
this.time = time;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ public class Saves{
|
||||
|
||||
public void delete(){
|
||||
file.delete();
|
||||
saves.removeValue(this, true);
|
||||
saves.remove(this, true);
|
||||
if(this == current){
|
||||
current = null;
|
||||
}
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
package mindustry.graphics;
|
||||
|
||||
import arc.Core;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.Pixmap.Format;
|
||||
import arc.graphics.VertexAttributes.Usage;
|
||||
import arc.graphics.gl.FrameBuffer;
|
||||
import arc.graphics.gl.Shader;
|
||||
|
||||
/**
|
||||
* Bloomlib allow easy but efficient way to add bloom effect as post process
|
||||
* effect
|
||||
*
|
||||
* @author kalle_h
|
||||
*/
|
||||
public class Bloom{
|
||||
/**
|
||||
* To use implement bloom more like a glow. Texture alpha channel can be
|
||||
* used as mask which part are glowing and which are not. see more info at:
|
||||
* http://www.gamasutra.com/view/feature/2107/realtime_glow.php
|
||||
* <p>
|
||||
* NOTE: need to be set before bloom instance is created. After that this
|
||||
* does nothing.
|
||||
*/
|
||||
public static boolean useAlphaChannelAsMask = false;
|
||||
|
||||
/** how many blur pass */
|
||||
public int blurPasses = 1;
|
||||
|
||||
private Shader tresholdShader;
|
||||
private Shader bloomShader;
|
||||
|
||||
private Mesh fullScreenQuad;
|
||||
|
||||
private Texture pingPongTex1;
|
||||
private Texture pingPongTex2;
|
||||
private Texture original;
|
||||
|
||||
private FrameBuffer frameBuffer;
|
||||
private FrameBuffer pingPongBuffer1;
|
||||
private FrameBuffer pingPongBuffer2;
|
||||
|
||||
private Shader blurShader;
|
||||
|
||||
private float bloomIntensity;
|
||||
private float originalIntensity;
|
||||
private float threshold;
|
||||
private int w;
|
||||
private int h;
|
||||
private boolean blending = false;
|
||||
private boolean capturing = false;
|
||||
private float r = 0f;
|
||||
private float g = 0f;
|
||||
private float b = 0f;
|
||||
private float a = 1f;
|
||||
private boolean disposeFBO = true;
|
||||
|
||||
/**
|
||||
* IMPORTANT NOTE CALL THIS WHEN RESUMING
|
||||
*/
|
||||
public void resume(){
|
||||
bloomShader.begin();
|
||||
bloomShader.setUniformi("u_texture0", 0);
|
||||
bloomShader.setUniformi("u_texture1", 1);
|
||||
bloomShader.end();
|
||||
|
||||
setSize(w, h);
|
||||
setThreshold(threshold);
|
||||
setBloomIntesity(bloomIntensity);
|
||||
setOriginalIntesity(originalIntensity);
|
||||
|
||||
original = frameBuffer.getTexture();
|
||||
pingPongTex1 = pingPongBuffer1.getTexture();
|
||||
pingPongTex2 = pingPongBuffer2.getTexture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize bloom class that capsulate original scene capturate,
|
||||
* tresholding, gaussian blurring and blending. Default values: depth = true
|
||||
* blending = false 32bits = true
|
||||
*/
|
||||
public Bloom(){
|
||||
initialize(Core.graphics.getWidth() / 4, Core.graphics.getHeight() / 4, null, false, false, true);
|
||||
}
|
||||
|
||||
public Bloom(boolean useBlending){
|
||||
initialize(Core.graphics.getWidth() / 4, Core.graphics.getHeight() / 4, null, false, useBlending, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize bloom class that capsulate original scene capturate,
|
||||
* tresholding, gaussian blurring and blending.
|
||||
*
|
||||
* @param FBO_W
|
||||
* @param FBO_H how big fbo is used for bloom texture, smaller = more blur and
|
||||
* lot faster but aliasing can be problem
|
||||
* @param hasDepth do rendering need depth buffer
|
||||
* @param useBlending does fbo need alpha channel and is blending enabled when final
|
||||
* image is rendered. This allow to combine background graphics
|
||||
* and only do blooming on certain objects param use32bitFBO does
|
||||
* fbo use higher precision than 16bits.
|
||||
*/
|
||||
public Bloom(int FBO_W, int FBO_H, boolean hasDepth, boolean useBlending, boolean use32bitFBO){
|
||||
initialize(FBO_W, FBO_H, null, hasDepth, useBlending, use32bitFBO);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* EXPERT FUNCTIONALITY. no error checking. Use this only if you know what
|
||||
* you are doing. Remember that bloom.capture() clear the screen so use
|
||||
* continue instead if that is a problem.
|
||||
* <p>
|
||||
* Initialize bloom class that capsulate original scene capturate,
|
||||
* tresholding, gaussian blurring and blending.
|
||||
* <p>
|
||||
* * @param sceneIsCapturedHere diposing is user responsibility.
|
||||
*
|
||||
* @param FBO_W
|
||||
* @param FBO_H how big fbo is used for bloom texture, smaller = more blur and
|
||||
* lot faster but aliasing can be problem
|
||||
* @param useBlending does fbo need alpha channel and is blending enabled when final
|
||||
* image is rendered. This allow to combine background graphics
|
||||
* and only do blooming on certain objects param use32bitFBO does
|
||||
* fbo use higher precision than 16bits.
|
||||
*/
|
||||
public Bloom(int FBO_W, int FBO_H, FrameBuffer sceneIsCapturedHere, boolean useBlending, boolean use32bitFBO){
|
||||
initialize(FBO_W, FBO_H, sceneIsCapturedHere, false, useBlending, use32bitFBO);
|
||||
disposeFBO = false;
|
||||
}
|
||||
|
||||
private void initialize(int FBO_W, int FBO_H, FrameBuffer fbo, boolean hasDepth, boolean useBlending, boolean use32bitFBO){
|
||||
blending = useBlending;
|
||||
Format format;
|
||||
|
||||
if(use32bitFBO){
|
||||
if(useBlending){
|
||||
format = Format.RGBA8888;
|
||||
}else{
|
||||
format = Format.RGB888;
|
||||
}
|
||||
|
||||
}else{
|
||||
if(useBlending){
|
||||
format = Format.RGBA4444;
|
||||
}else{
|
||||
format = Format.RGB565;
|
||||
}
|
||||
}
|
||||
if(fbo == null){
|
||||
frameBuffer = new FrameBuffer(format, Core.graphics.getWidth(), Core.graphics.getHeight(), hasDepth);
|
||||
}else{
|
||||
frameBuffer = fbo;
|
||||
}
|
||||
|
||||
pingPongBuffer1 = new FrameBuffer(format, FBO_W, FBO_H, false);
|
||||
|
||||
pingPongBuffer2 = new FrameBuffer(format, FBO_W, FBO_H, false);
|
||||
|
||||
original = frameBuffer.getTexture();
|
||||
pingPongTex1 = pingPongBuffer1.getTexture();
|
||||
pingPongTex2 = pingPongBuffer2.getTexture();
|
||||
|
||||
fullScreenQuad = createFullScreenQuad();
|
||||
final String alpha = useBlending ? "alpha_" : "";
|
||||
|
||||
bloomShader = createShader("screenspace", alpha + "bloom");
|
||||
|
||||
if(useAlphaChannelAsMask){
|
||||
tresholdShader = createShader("screenspace", "maskedtreshold");
|
||||
}else{
|
||||
tresholdShader = createShader("screenspace", alpha + "threshold");
|
||||
}
|
||||
|
||||
blurShader = createShader("blurspace", alpha + "gaussian");
|
||||
|
||||
setSize(FBO_W, FBO_H);
|
||||
setBloomIntesity(2.5f);
|
||||
setOriginalIntesity(0.8f);
|
||||
setThreshold(0.5f);
|
||||
|
||||
bloomShader.begin();
|
||||
bloomShader.setUniformi("u_texture0", 0);
|
||||
bloomShader.setUniformi("u_texture1", 1);
|
||||
bloomShader.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set clearing color for capturing buffer
|
||||
*
|
||||
* @param r
|
||||
* @param g
|
||||
* @param b
|
||||
* @param a
|
||||
*/
|
||||
public void setClearColor(float r, float g, float b, float a){
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this before rendering scene.
|
||||
*/
|
||||
public void capture(){
|
||||
if(!capturing){
|
||||
capturing = true;
|
||||
frameBuffer.begin();
|
||||
Gl.clearColor(r, g, b, a);
|
||||
Gl.clear(Gl.colorBufferBit);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause capturing to fbo.
|
||||
*/
|
||||
public void capturePause(){
|
||||
if(capturing){
|
||||
capturing = false;
|
||||
frameBuffer.end();
|
||||
}
|
||||
}
|
||||
|
||||
/** Start capturing again after pause, no clearing is done to framebuffer */
|
||||
public void captureContinue(){
|
||||
if(!capturing){
|
||||
capturing = true;
|
||||
frameBuffer.begin();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this after scene. Renders the bloomed scene.
|
||||
*/
|
||||
public void render(){
|
||||
if(capturing){
|
||||
capturing = false;
|
||||
frameBuffer.end();
|
||||
}
|
||||
|
||||
Gl.disable(Gl.blend);
|
||||
Gl.disable(Gl.depthTest);
|
||||
Gl.depthMask(false);
|
||||
|
||||
gaussianBlur();
|
||||
|
||||
if(blending){
|
||||
Gl.enable(Gl.blend);
|
||||
Gl.blendFunc(Gl.srcAlpha, Gl.oneMinusSrcAlpha);
|
||||
}
|
||||
|
||||
pingPongTex1.bind(1);
|
||||
original.bind(0);
|
||||
|
||||
bloomShader.begin();
|
||||
fullScreenQuad.render(bloomShader, Gl.triangleFan);
|
||||
bloomShader.end();
|
||||
|
||||
}
|
||||
|
||||
private void gaussianBlur(){
|
||||
|
||||
// cut bright areas of the picture and blit to smaller fbo
|
||||
|
||||
original.bind(0);
|
||||
pingPongBuffer1.begin();
|
||||
tresholdShader.begin();
|
||||
fullScreenQuad.render(tresholdShader, Gl.triangleFan, 0, 4);
|
||||
tresholdShader.end();
|
||||
pingPongBuffer1.end();
|
||||
|
||||
for(int i = 0; i < blurPasses; i++){
|
||||
|
||||
pingPongTex1.bind(0);
|
||||
|
||||
// horizontal
|
||||
pingPongBuffer2.begin();
|
||||
blurShader.begin();
|
||||
blurShader.setUniformf("dir", 1f, 0f);
|
||||
fullScreenQuad.render(blurShader, Gl.triangleFan, 0, 4);
|
||||
blurShader.end();
|
||||
pingPongBuffer2.end();
|
||||
|
||||
pingPongTex2.bind(0);
|
||||
// vertical
|
||||
pingPongBuffer1.begin();
|
||||
blurShader.begin();
|
||||
blurShader.setUniformf("dir", 0f, 1f);
|
||||
fullScreenQuad.render(blurShader, Gl.triangleFan, 0, 4);
|
||||
blurShader.end();
|
||||
pingPongBuffer1.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set intensity for bloom. higher mean more brightening for spots that are
|
||||
* over threshold
|
||||
*
|
||||
* @param intensity multiplier for blurred texture in combining phase. must be
|
||||
* positive.
|
||||
*/
|
||||
public void setBloomIntesity(float intensity){
|
||||
bloomIntensity = intensity;
|
||||
bloomShader.begin();
|
||||
bloomShader.setUniformf("BloomIntensity", intensity);
|
||||
bloomShader.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* set intensity for original scene. under 1 mean darkening and over 1 means
|
||||
* lightening
|
||||
*
|
||||
* @param intensity multiplier for captured texture in combining phase. must be
|
||||
* positive.
|
||||
*/
|
||||
public void setOriginalIntesity(float intensity){
|
||||
originalIntensity = intensity;
|
||||
bloomShader.begin();
|
||||
bloomShader.setUniformf("OriginalIntensity", intensity);
|
||||
bloomShader.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Treshold for bright parts. everything under threshold is clamped to 0
|
||||
*
|
||||
* @param threshold must be in range 0..1
|
||||
*/
|
||||
public void setThreshold(float threshold){
|
||||
this.threshold = threshold;
|
||||
tresholdShader.begin();
|
||||
tresholdShader.setUniformf("threshold", threshold, 1f / (1 - threshold));
|
||||
tresholdShader.end();
|
||||
}
|
||||
|
||||
private void setSize(int FBO_W, int FBO_H){
|
||||
w = FBO_W;
|
||||
h = FBO_H;
|
||||
blurShader.begin();
|
||||
blurShader.setUniformf("size", FBO_W, FBO_H);
|
||||
blurShader.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when application is exiting.
|
||||
*/
|
||||
public void dispose(){
|
||||
try{
|
||||
if(disposeFBO) frameBuffer.dispose();
|
||||
|
||||
fullScreenQuad.dispose();
|
||||
|
||||
pingPongBuffer1.dispose();
|
||||
pingPongBuffer2.dispose();
|
||||
|
||||
blurShader.dispose();
|
||||
bloomShader.dispose();
|
||||
tresholdShader.dispose();
|
||||
}catch(Throwable ignored){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static Mesh createFullScreenQuad(){
|
||||
float[] verts = {-1, -1, 0, 0, 1, -1, 1, 0, 1, 1, 1, 1, -1, 1, 0, 1};
|
||||
Mesh tmpMesh = new Mesh(true, 4, 0,
|
||||
new VertexAttribute(Usage.position, 2, "a_position"),
|
||||
new VertexAttribute(Usage.textureCoordinates, 2, "a_texCoord0")
|
||||
);
|
||||
|
||||
tmpMesh.setVertices(verts);
|
||||
return tmpMesh;
|
||||
|
||||
}
|
||||
|
||||
private static Shader createShader(String vertexName, String fragmentName){
|
||||
String vertexShader = Core.files.internal("bloomshaders/" + vertexName + ".vertex.glsl").readString();
|
||||
String fragmentShader = Core.files.internal("bloomshaders/" + fragmentName + ".fragment.glsl").readString();
|
||||
return new Shader(vertexShader, fragmentShader);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class OverlayRenderer{
|
||||
if(tile != null && tile.block() != Blocks.air && tile.getTeam() == player.getTeam()){
|
||||
tile.block().drawSelect(tile);
|
||||
|
||||
if(Core.input.keyDown(Binding.rotateplaced) && tile.block().rotate){
|
||||
if(Core.input.keyDown(Binding.rotateplaced) && tile.block().rotate && tile.interactable(player.getTeam())){
|
||||
control.input.drawArrow(tile.block(), tile.x, tile.y, tile.rotation(), true);
|
||||
Draw.color(Pal.accent, 0.3f + Mathf.absin(4f, 0.2f));
|
||||
Fill.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize/2f);
|
||||
|
||||
@@ -222,7 +222,7 @@ public class DesktopInput extends InputHandler{
|
||||
cursorType = ui.unloadCursor;
|
||||
}
|
||||
|
||||
if(!isPlacing() && Math.abs(Core.input.axisTap(Binding.rotate)) > 0 && Core.input.keyDown(Binding.rotateplaced) && cursor.block().rotate){
|
||||
if(cursor.interactable(player.getTeam()) && !isPlacing() && Math.abs(Core.input.axisTap(Binding.rotate)) > 0 && Core.input.keyDown(Binding.rotateplaced) && cursor.block().rotate){
|
||||
Call.rotateBlock(player, cursor, Core.input.axisTap(Binding.rotate) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}
|
||||
|
||||
void removeRequest(BuildRequest request){
|
||||
selectRequests.removeValue(request, true);
|
||||
selectRequests.remove(request, true);
|
||||
if(!request.breaking){
|
||||
removals.add(request);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.mozilla.javascript.*;
|
||||
public class Scripts implements Disposable{
|
||||
private final Array<String> blacklist = Array.with("net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
|
||||
"runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system",
|
||||
".awt", "socket", "classloader", "oracle");
|
||||
".awt", "socket", "classloader", "oracle", "invoke");
|
||||
private final Array<String> whitelist = Array.with("mindustry.net");
|
||||
private final Context context;
|
||||
private final String wrapper;
|
||||
|
||||
@@ -41,7 +41,6 @@ public class Administration{
|
||||
if(player.getInfo().messageInfractions >= Config.messageSpamKick.num() && Config.messageSpamKick.num() != 0){
|
||||
player.con.kick("You have been kicked for spamming.", 1000 * 60 * 2);
|
||||
}
|
||||
player.getInfo().lastSentMessage = message;
|
||||
return null;
|
||||
}else{
|
||||
player.getInfo().messageInfractions = 0;
|
||||
@@ -191,7 +190,7 @@ public class Administration{
|
||||
}
|
||||
}
|
||||
|
||||
bannedIPs.removeValue(ip, false);
|
||||
bannedIPs.remove(ip, false);
|
||||
|
||||
if(found){
|
||||
save();
|
||||
|
||||
@@ -10,7 +10,7 @@ import mindustry.ctype.ContentType;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.Effects.*;
|
||||
import mindustry.entities.type.*;
|
||||
import mindustry.entities.units.Statuses.*;
|
||||
import mindustry.entities.units.*;
|
||||
|
||||
public class StatusEffect extends MappableContent{
|
||||
/** Damage dealt by the unit with the effect. */
|
||||
|
||||
@@ -62,6 +62,10 @@ public class GameOverDialog extends FloatingDialog{
|
||||
t.row();
|
||||
t.add(Core.bundle.format("stat.deconstructed", state.stats.buildingsDeconstructed));
|
||||
t.row();
|
||||
if(control.saves.getCurrent() != null){
|
||||
t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime()));
|
||||
t.row();
|
||||
}
|
||||
if(world.isZone() && !state.stats.itemsDelivered.isEmpty()){
|
||||
t.add("$stat.delivered");
|
||||
t.row();
|
||||
|
||||
@@ -157,7 +157,7 @@ public class JoinDialog extends FloatingDialog{
|
||||
|
||||
inner.addImageButton(Icon.trash, Styles.emptyi, () -> {
|
||||
ui.showConfirm("$confirm", "$server.delete", () -> {
|
||||
servers.removeValue(server, true);
|
||||
servers.remove(server, true);
|
||||
saveServers();
|
||||
setupRemote();
|
||||
refreshRemote();
|
||||
|
||||
@@ -87,7 +87,7 @@ public class ModsDialog extends FloatingDialog{
|
||||
void modError(Throwable error){
|
||||
ui.loadfrag.hide();
|
||||
|
||||
if(Strings.getCauses(error).contains(t -> t.getMessage() != null && (t.getMessage().contains("SSL") || t.getMessage().contains("protocol")))){
|
||||
if(Strings.getCauses(error).contains(t -> t.getMessage() != null && (t.getMessage().contains("trust anchor") || t.getMessage().contains("SSL") || t.getMessage().contains("protocol")))){
|
||||
ui.showErrorMessage("$feature.unsupported");
|
||||
}else{
|
||||
ui.showException(error);
|
||||
|
||||
@@ -144,7 +144,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
}
|
||||
})));
|
||||
|
||||
if(!ios){
|
||||
if(!mobile){
|
||||
t.row();
|
||||
t.addImageTextButton("$data.openfolder", Icon.folder, style, () -> Core.app.openFolder(Core.settings.getDataDirectory().absolutePath()));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ public class ItemModule extends BlockModule{
|
||||
private int[] items = new int[content.items().size];
|
||||
private int total;
|
||||
|
||||
// Make the take() loop persistent so it does not return the same item twice in a row unless there is nothing else to return.
|
||||
protected int takeRotation;
|
||||
|
||||
public void forEach(ItemConsumer cons){
|
||||
for(int i = 0; i < items.length; i++){
|
||||
if(items[i] > 0){
|
||||
@@ -66,21 +69,27 @@ public class ItemModule extends BlockModule{
|
||||
return total;
|
||||
}
|
||||
|
||||
public Item first(){
|
||||
public Item first(){ // fixme: entangle with take()
|
||||
for(int i = 0; i < items.length; i++){
|
||||
if(items[i] > 0) return content.item(i);
|
||||
if(items[i] > 0){
|
||||
return content.item(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Item take(){
|
||||
if(first() == null) return null;
|
||||
|
||||
int id = first().id;
|
||||
items[id]--;
|
||||
total--;
|
||||
|
||||
return content.item(id);
|
||||
for(int i = 0; i < items.length; i++){
|
||||
int index = (i + takeRotation);
|
||||
if(index >= items.length) index -= items.length; //conditional instead of mod
|
||||
if(items[index] > 0){
|
||||
items[index] --;
|
||||
total --;
|
||||
takeRotation = index + 1;
|
||||
return content.item(index % items.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int get(Item item){
|
||||
|
||||
Reference in New Issue
Block a user