Merge branch 'master' of https://github.com/Anuken/Mindustry into v103.3

This commit is contained in:
Petr Gašparík
2020-02-03 10:05:06 +01:00
36 changed files with 1029 additions and 247 deletions
+1 -1
View File
@@ -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(){
+9 -10
View File
@@ -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;
@@ -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;
}
}
}
@@ -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{}
}
@@ -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();
+1 -1
View File
@@ -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;
@@ -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
@@ -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;
}
}
}
@@ -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);
+1 -1
View File
@@ -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);
}
}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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. */
@@ -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()));
}