Boss waves, health bars / Better lasers / Bugfixes

This commit is contained in:
Anuken
2019-02-21 13:11:28 -05:00
parent f591403b7d
commit 5b7b50f555
38 changed files with 1483 additions and 1379 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -263,6 +263,7 @@ zone.complete = Wave {0} reached:\nNew zone requirements met.
zone.config.complete = Wave {0} reached:\nLoadout config unlocked. zone.config.complete = Wave {0} reached:\nLoadout config unlocked.
zone.resources = Resources Detected: zone.resources = Resources Detected:
add = Add... add = Add...
boss.health = Boss Health
connectfail = [crimson]Failed to connect to server:\n\n[accent]{0} connectfail = [crimson]Failed to connect to server:\n\n[accent]{0}
error.unreachable = Server unreachable.\nIs the address spelled correctly? error.unreachable = Server unreachable.\nIs the address spelled correctly?
@@ -564,7 +565,7 @@ block.stained-rocks-red.name = Stained Rocks Red
block.stained-stone-red.name = Stained Stone Red block.stained-stone-red.name = Stained Stone Red
block.stained-rocks-yellow.name = Stained Rocks Yellow block.stained-rocks-yellow.name = Stained Rocks Yellow
block.stained-stone-yellow.name = Stained Stone Yellow block.stained-stone-yellow.name = Stained Stone Yellow
block.stained-boulder.name = Stained Boulde block.stained-boulder.name = Stained Boulder
block.metal-floor.name = Metal Floor block.metal-floor.name = Metal Floor
block.metal-floor-2.name = Metal Floor 2 block.metal-floor-2.name = Metal Floor 2
block.metal-floor-3.name = Metal Floor 3 block.metal-floor-3.name = Metal Floor 3

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.content; package io.anuke.mindustry.content;
import io.anuke.arc.Core; import io.anuke.arc.Core;
import io.anuke.mindustry.entities.Effects.Effect;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.graphics.g2d.Fill;
@@ -9,6 +8,7 @@ import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles; import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Tmp; import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.entities.Effects.Effect;
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect; import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.ContentList;
@@ -34,7 +34,7 @@ public class Fx implements ContentList{
bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke, bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke,
shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium, shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium,
shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot, shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot,
unitSpawn, spawnShockwave, magmasmoke, impactShockwave, impactcloud, impactsmoke; unitSpawn, spawnShockwave, magmasmoke, impactShockwave, impactcloud, impactsmoke, dynamicExplosion;
@Override @Override
public void load(){ public void load(){
@@ -604,6 +604,31 @@ public class Fx implements ContentList{
Draw.reset(); Draw.reset();
}); });
dynamicExplosion = new Effect(30, e -> {
float intensity = e.rotation;
e.scaled(5 + intensity*2, i -> {
Lines.stroke(3.1f * i.fout());
Lines.poly(e.x, e.y, (int)(20 * intensity), (3f + i.fin() * 14f) * intensity);
});
Draw.color(Color.GRAY);
Angles.randLenVectors(e.id, e.finpow(), (int)(6 * intensity), 21f*intensity, (x, y, in, out) -> {
Fill.circle(e.x + x, e.y + y, out * (2f+intensity) * 3 + 0.5f);
Fill.circle(e.x + x / 2f, e.y + y / 2f, out * (intensity) * 3);
});
Draw.color(Pal.lighterOrange, Pal.lightOrange, Color.GRAY, e.fin());
Lines.stroke((1.7f * e.fout()) * (1f + (intensity - 1f) / 2f));
Angles.randLenVectors(e.id + 1, e.finpow(), (int)(9*intensity), 40f*intensity, (x, y, in, out) -> {
Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + out * 4 * (3f+intensity));
});
Draw.reset();
});
blockExplosion = new Effect(30, e -> { blockExplosion = new Effect(30, e -> {
e.scaled(7, i -> { e.scaled(7, i -> {
Lines.stroke(3.1f * i.fout()); Lines.stroke(3.1f * i.fout());

View File

@@ -6,7 +6,7 @@ import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.type.StatusEffect;
public class StatusEffects implements ContentList{ public class StatusEffects implements ContentList{
public static StatusEffect none, burning, freezing, wet, melting, tarred, overdrive, shielded, shocked, corroded; public static StatusEffect none, burning, freezing, wet, melting, tarred, overdrive, shielded, shocked, corroded, boss;
@Override @Override
public void load(){ public void load(){
@@ -71,6 +71,14 @@ public class StatusEffects implements ContentList{
armorMultiplier = 3f; armorMultiplier = 3f;
}}; }};
boss = new StatusEffect(){{
armorMultiplier = 3f;
damageMultiplier = 3f;
speedMultiplier = 1.1f;
//TODO custom effect
//effect = Fx.overdriven;
}};
shocked = new StatusEffect(); shocked = new StatusEffect();
//no effects, just small amounts of damage. //no effects, just small amounts of damage.

View File

@@ -57,7 +57,10 @@ public class Zones implements ContentList{
new SpawnGroup(UnitTypes.dagger){{ new SpawnGroup(UnitTypes.dagger){{
begin = 30; begin = 30;
unitScaling = 2; unitScaling = 2;
}} }},
bossGroup(UnitTypes.fortress)
); );
}}; }};
}}; }};
@@ -105,7 +108,9 @@ public class Zones implements ContentList{
begin = 25; begin = 25;
unitScaling = 1; unitScaling = 1;
unitAmount = 2; unitAmount = 2;
}} }},
bossGroup(UnitTypes.revenant)
); );
}}; }};
}}; }};
@@ -167,7 +172,16 @@ public class Zones implements ContentList{
begin = 35; begin = 35;
spacing = 10; spacing = 10;
unitAmount = 6; unitAmount = 6;
}} }},
//boss
new SpawnGroup(UnitTypes.revenant){{
begin = configureWave;
effect = StatusEffects.boss;
unitScaling = never;
}},
bossGroup(UnitTypes.eruptor)
); );
}}; }};
}}; }};
@@ -241,7 +255,10 @@ public class Zones implements ContentList{
spacing = 3; spacing = 3;
unitScaling = 3; unitScaling = 3;
unitAmount = 2; unitAmount = 2;
}} }},
bossGroup(UnitTypes.revenant),
bossGroup(UnitTypes.revenant)
); );
}}; }};
}}; }};
@@ -329,7 +346,9 @@ public class Zones implements ContentList{
spacing = 10; spacing = 10;
unitScaling = 0.5f; unitScaling = 0.5f;
unitAmount = 10; unitAmount = 10;
}} }},
bossGroup(UnitTypes.chaosArray)
); );
}}; }};
}}; }};
@@ -411,7 +430,9 @@ public class Zones implements ContentList{
spacing = 10; spacing = 10;
unitScaling = 0.5f; unitScaling = 0.5f;
unitAmount = 10; unitAmount = 10;
}} }},
bossGroup(UnitTypes.lich)
); );
}}; }};
}}; }};
@@ -482,7 +503,9 @@ public class Zones implements ContentList{
spacing = 2; spacing = 2;
unitAmount = 4; unitAmount = 4;
begin = 13; begin = 13;
}} }},
bossGroup(UnitTypes.chaosArray)
); );
}}; }};
}}; }};
@@ -598,7 +621,9 @@ public class Zones implements ContentList{
spacing = 10; spacing = 10;
unitScaling = 0.5f; unitScaling = 0.5f;
unitAmount = 10; unitAmount = 10;
}} }},
bossGroup(UnitTypes.reaper)
); );
}}; }};
}}; }};

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.core; package io.anuke.mindustry.core;
import io.anuke.arc.Events; import io.anuke.arc.Events;
import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.game.EventType.StateChangeEvent;
import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.Rules;
import io.anuke.mindustry.game.Stats; import io.anuke.mindustry.game.Stats;
@@ -32,6 +33,10 @@ public class GameState{
return Net.client() ? enemies : unitGroups[waveTeam.ordinal()].size(); return Net.client() ? enemies : unitGroups[waveTeam.ordinal()].size();
} }
public BaseUnit boss(){
return unitGroups[waveTeam.ordinal()].find(BaseUnit::isBoss);
}
public void set(State astate){ public void set(State astate){
Events.fire(new StateChangeEvent(state, astate)); Events.fire(new StateChangeEvent(state, astate));
state = astate; state = astate;

View File

@@ -7,10 +7,6 @@ import io.anuke.arc.Events;
import io.anuke.arc.collection.Array; import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntMap; import io.anuke.arc.collection.IntMap;
import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.collection.ObjectSet;
import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.EntityQuery;
import io.anuke.mindustry.entities.traits.Entity;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Colors; import io.anuke.arc.graphics.Colors;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
@@ -19,14 +15,19 @@ import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Log; import io.anuke.arc.util.Log;
import io.anuke.arc.util.Structs; import io.anuke.arc.util.Structs;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.arc.util.io.ByteBufferOutput; import io.anuke.arc.util.io.ByteBufferOutput;
import io.anuke.arc.util.io.CountableByteArrayOutputStream; import io.anuke.arc.util.io.CountableByteArrayOutputStream;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.EntityQuery;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
import io.anuke.mindustry.entities.traits.Entity;
import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.type.Player;
import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.Version; import io.anuke.mindustry.game.Version;
@@ -51,13 +52,7 @@ import static io.anuke.mindustry.Vars.*;
public class NetServer implements ApplicationListener{ public class NetServer implements ApplicationListener{
public final static int maxSnapshotSize = 430; public final static int maxSnapshotSize = 430;
private final static float serverSyncTime = 40, kickDuration = 30 * 1000;
public final static boolean debugSnapshots = false;
public final static float maxSnapshotDelay = 200;
public final static float snapshotDropchance = 0.01f;
private final static byte[] reusableSnapArray = new byte[maxSnapshotSize];
private final static float serverSyncTime = 4, kickDuration = 30 * 1000;
private final static Vector2 vector = new Vector2(); private final static Vector2 vector = new Vector2();
private final static Rectangle viewport = new Rectangle(); private final static Rectangle viewport = new Rectangle();
private final static Array<Entity> returnArray = new Array<>(); private final static Array<Entity> returnArray = new Array<>();
@@ -475,7 +470,7 @@ public class NetServer implements ApplicationListener{
returnArray.clear(); returnArray.clear();
if(represent.isClipped()){ if(represent.isClipped()){
EntityQuery.getNearby(group, viewport, entity -> { EntityQuery.getNearby(group, viewport, entity -> {
if(((SyncTrait) entity).isSyncing() && viewport.contains(entity.getX(), entity.getY())){ if(((SyncTrait) entity).isSyncing() && viewport.overlaps(Tmp.r3.setSize(((SyncTrait)entity).clipSize(), ((SyncTrait)entity).clipSize()).setCenter(entity.getX(), entity.getY()))){
returnArray.add(entity); returnArray.add(entity);
} }
}); });

View File

@@ -304,7 +304,7 @@ public class Renderer implements ApplicationListener{
public void clampScale(){ public void clampScale(){
float s = io.anuke.arc.scene.ui.layout.Unit.dp.scl(1f); float s = io.anuke.arc.scene.ui.layout.Unit.dp.scl(1f);
targetscale = Mathf.clamp(targetscale, s * 2.5f, Math.round(s * 7)); targetscale = Mathf.clamp(targetscale, s * 2.5f, Math.round(s * 5));
} }
public void takeMapScreenshot(){ public void takeMapScreenshot(){

View File

@@ -60,7 +60,7 @@ public class Damage{
float shake = Math.min(explosiveness / 4f + 3f, 9f); float shake = Math.min(explosiveness / 4f + 3f, 9f);
Effects.shake(shake, shake, x, y); Effects.shake(shake, shake, x, y);
Effects.effect(Fx.blockExplosion, x, y); Effects.effect(Fx.dynamicExplosion, x, y, radius/8f);
} }
public static void createIncend(float x, float y, float range, int amount){ public static void createIncend(float x, float y, float range, int amount){

View File

@@ -347,7 +347,7 @@ public interface BuilderTrait extends Entity, TeamTrait{
Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl)); Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl));
Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey); Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey, 0.75f);
if(unit instanceof Player && ((Player) unit).isLocal){ if(unit instanceof Player && ((Player) unit).isLocal){
Lines.stroke(1f, Pal.accent); Lines.stroke(1f, Pal.accent);

View File

@@ -62,6 +62,10 @@ public interface SyncTrait extends Entity, TypeTrait{
return true; return true;
} }
default float clipSize(){
return (this instanceof DrawTrait ? ((DrawTrait)this).drawSize() : 8f);
}
//Read and write sync data, usually position //Read and write sync data, usually position
void write(DataOutput data) throws IOException; void write(DataOutput data) throws IOException;

View File

@@ -12,6 +12,7 @@ import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.util.Interval; import io.anuke.arc.util.Interval;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.ShooterTrait; import io.anuke.mindustry.entities.traits.ShooterTrait;
@@ -163,6 +164,10 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
} }
} }
public boolean isBoss(){
return hasEffect(StatusEffects.boss);
}
@Override @Override
public boolean isImmune(StatusEffect effect){ public boolean isImmune(StatusEffect effect){
return type.immunities.contains(effect); return type.immunities.contains(effect);
@@ -212,11 +217,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
return type.health; return type.health;
} }
@Override
public float getSize(){
return 8;
}
@Override @Override
public float mass(){ public float mass(){
return type.mass; return type.mass;
@@ -284,6 +284,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
return type.hitsize * 10; return type.hitsize * 10;
} }
@Override
public float clipSize(){
return isBoss() ? 10000000000f : super.clipSize();
}
@Override @Override
public void onDeath(){ public void onDeath(){
Call.onUnitDeath(this); Call.onUnitDeath(this);

View File

@@ -213,11 +213,6 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
return mech.flying || boostHeat > liftoffBoost; return mech.flying || boostHeat > liftoffBoost;
} }
@Override
public float getSize(){
return 8;
}
@Override @Override
public void damage(float amount){ public void damage(float amount){
hitTime = hitDuration; hitTime = hitDuration;

View File

@@ -10,6 +10,7 @@ import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Damage; import io.anuke.mindustry.entities.Damage;
@@ -382,6 +383,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
Draw.rect(getIconRegion(), x + offsetX, y + offsetY, rotation - 90); Draw.rect(getIconRegion(), x + offsetX, y + offsetY, rotation - 90);
} }
public float getSize(){
hitbox(Tmp.r1);
return Math.max(Tmp.r1.width, Tmp.r1.height) * 2f;
}
public abstract TextureRegion getIconRegion(); public abstract TextureRegion getIconRegion();
public abstract Weapon getWeapon(); public abstract Weapon getWeapon();
@@ -391,6 +397,4 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
public abstract float mass(); public abstract float mass();
public abstract boolean isFlying(); public abstract boolean isFlying();
public abstract float getSize();
} }

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.entities.units; package io.anuke.mindustry.entities.units;
import io.anuke.arc.collection.Array; import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.Bits;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Color;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp; import io.anuke.arc.util.Tmp;
@@ -22,6 +23,7 @@ public class Statuses implements Saveable{
private static final Array<StatusEntry> removals = new Array<>(); private static final Array<StatusEntry> removals = new Array<>();
private Array<StatusEntry> statuses = new Array<>(); private Array<StatusEntry> statuses = new Array<>();
private Bits applied = new Bits(content.getBy(ContentType.status).size);
private float speedMultiplier; private float speedMultiplier;
private float damageMultiplier; private float damageMultiplier;
@@ -76,6 +78,7 @@ public class Statuses implements Saveable{
} }
public void update(Unit unit){ public void update(Unit unit){
applied.clear();
speedMultiplier = damageMultiplier = armorMultiplier = 1f; speedMultiplier = damageMultiplier = armorMultiplier = 1f;
if(statuses.size == 0) return; if(statuses.size == 0) return;
@@ -84,6 +87,7 @@ public class Statuses implements Saveable{
for(StatusEntry entry : statuses){ for(StatusEntry entry : statuses){
entry.time = Math.max(entry.time - Time.delta(), 0); entry.time = Math.max(entry.time - Time.delta(), 0);
applied.set(entry.effect.id);
if(entry.time <= 0){ if(entry.time <= 0){
Pools.free(entry); Pools.free(entry);
@@ -114,10 +118,7 @@ public class Statuses implements Saveable{
} }
public boolean hasEffect(StatusEffect effect){ public boolean hasEffect(StatusEffect effect){
for(StatusEntry entry : statuses){ return applied.get(effect.id);
if(entry.effect == effect) return true;
}
return false;
} }
@Override @Override
@@ -125,7 +126,7 @@ public class Statuses implements Saveable{
stream.writeByte(statuses.size); stream.writeByte(statuses.size);
for(StatusEntry entry : statuses){ for(StatusEntry entry : statuses){
stream.writeByte(entry.effect.id); stream.writeByte(entry.effect.id);
stream.writeShort((short) (entry.time * 2)); stream.writeFloat(entry.time);
} }
} }
@@ -140,7 +141,7 @@ public class Statuses implements Saveable{
byte amount = stream.readByte(); byte amount = stream.readByte();
for(int i = 0; i < amount; i++){ for(int i = 0; i < amount; i++){
byte id = stream.readByte(); byte id = stream.readByte();
float time = stream.readShort() / 2f; float time = stream.readFloat();
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new); StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(content.getByID(ContentType.status, id), time); entry.set(content.getByID(ContentType.status, id), time);
statuses.add(entry); statuses.add(entry);

View File

@@ -1,7 +1,22 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.game;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
public abstract class Loadout{ public enum Loadout{
test(Blocks.coreShard){
@Override
public void setup(Tile tile){
}
};
public final Block core;
Loadout(Block core){
this.core = core;
}
public abstract void setup(Tile tile); public abstract void setup(Tile tile);
} }

View File

@@ -11,10 +11,12 @@ import io.anuke.mindustry.type.UnitType;
* Each spawn group can have multiple sub-groups spawned in different areas of the map. * Each spawn group can have multiple sub-groups spawned in different areas of the map.
*/ */
public class SpawnGroup{ public class SpawnGroup{
protected static final int never = Integer.MAX_VALUE;
/**The unit type spawned*/ /**The unit type spawned*/
public final UnitType type; public final UnitType type;
/**When this spawn should end*/ /**When this spawn should end*/
protected int end = Integer.MAX_VALUE; protected int end = never;
/**When this spawn should start*/ /**When this spawn should start*/
protected int begin; protected int begin;
/**The spacing, in waves, of spawns. For example, 2 = spawns every other wave*/ /**The spacing, in waves, of spawns. For example, 2 = spawns every other wave*/
@@ -34,9 +36,7 @@ public class SpawnGroup{
this.type = type; this.type = type;
} }
/** /**Returns the amount of units spawned on a specific wave.*/
* Returns the amount of units spawned on a specific wave.
*/
public int getUnitsSpawned(int wave){ public int getUnitsSpawned(int wave){
if(wave < begin || wave > end || (wave - begin) % spacing != 0){ if(wave < begin || wave > end || (wave - begin) % spacing != 0){
return 0; return 0;

View File

@@ -6,6 +6,9 @@ import io.anuke.arc.collection.ObjectSet;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.waveTeam;
import static io.anuke.mindustry.Vars.world;
/**Class for various team-based utilities.*/ /**Class for various team-based utilities.*/
public class Teams{ public class Teams{
private TeamData[] map = new TeamData[Team.all.length]; private TeamData[] map = new TeamData[Team.all.length];
@@ -23,7 +26,8 @@ public class Teams{
/**Returns team data by type.*/ /**Returns team data by type.*/
public TeamData get(Team team){ public TeamData get(Team team){
if(map[team.ordinal()] == null){ if(map[team.ordinal()] == null){
add(team, Array.with(Team.all).select(t -> t != team && t != Team.none && team != Team.none).toArray(Team.class)); Array<Team> enemies = Array.with(Team.all).select(t -> t != team && ((t != Team.none && team != Team.none) || (world.isZone() && team == waveTeam)));
add(team, enemies.toArray(Team.class));
} }
return map[team.ordinal()]; return map[team.ordinal()];
} }

View File

@@ -37,6 +37,7 @@ public class BlockRenderer{
private int iterateidx = 0; private int iterateidx = 0;
private FrameBuffer shadows = new FrameBuffer(2, 2); private FrameBuffer shadows = new FrameBuffer(2, 2);
private FrameBuffer fog = new FrameBuffer(2, 2); private FrameBuffer fog = new FrameBuffer(2, 2);
private Array<Tile> outArray = new Array<>();
public BlockRenderer(){ public BlockRenderer(){
@@ -181,6 +182,14 @@ public class BlockRenderer{
if(block.layer2 != null && block.isLayer2(tile)){ if(block.layer2 != null && block.isLayer2(tile)){
addRequest(tile, block.layer2); addRequest(tile, block.layer2);
} }
if(tile.entity != null && tile.entity.power != null && tile.entity.power.links.size > 0){
for(Tile other : block.getPowerConnections(tile, outArray)){
if(other.block().layer == Layer.power){
addRequest(other, Layer.power);
}
}
}
} }
} }
} }

View File

@@ -6,6 +6,7 @@ import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Tmp;
//TODO remove //TODO remove
public class Shapes{ public class Shapes{
@@ -19,16 +20,16 @@ public class Shapes{
} }
public static void laser(String line, String edge, float x, float y, float x2, float y2, float rotation, float scale){ public static void laser(String line, String edge, float x, float y, float x2, float y2, float rotation, float scale){
Lines.stroke(12f * scale);
Lines.line(Core.atlas.find(line), x, y, x2, y2, CapStyle.none, 0f);
Lines.stroke(1f);
TextureRegion region = Core.atlas.find(edge); TextureRegion region = Core.atlas.find(edge);
Draw.rect(Core.atlas.find(edge), x, y, region.getWidth() * Draw.scl, region.getHeight() * scale * Draw.scl, rotation + 180); Tmp.v1.trns(rotation, 8f * scale * Draw.scl);
Draw.rect(Core.atlas.find(edge), x2, y2, region.getWidth() * Draw.scl, region.getHeight() * scale * Draw.scl, rotation); Draw.rect(Core.atlas.find(edge), x, y, region.getWidth() * scale * Draw.scl, region.getHeight() * scale * Draw.scl, rotation + 180);
Draw.rect(Core.atlas.find(edge), x2, y2, region.getWidth() * scale * Draw.scl, region.getHeight() * scale * Draw.scl, rotation);
Lines.stroke(12f * scale);
Lines.line(Core.atlas.find(line), x + Tmp.v1.x, y + Tmp.v1.y, x2 - Tmp.v1.x, y2 - Tmp.v1.y, CapStyle.none, 0f);
Lines.stroke(1f);
} }
public static void tri(float x, float y, float width, float length, float rotation){ public static void tri(float x, float y, float width, float length, float rotation){

View File

@@ -37,13 +37,6 @@ public class Interpolator{
public void update(){ public void update(){
/*
if(pos.dst(target) > 128){
pos.set(target);
lastUpdated = 0;
updateSpacing = 16;
}*/
if(lastUpdated != 0 && updateSpacing != 0){ if(lastUpdated != 0 && updateSpacing != 0){
float timeSinceUpdate = Time.timeSinceMillis(lastUpdated); float timeSinceUpdate = Time.timeSinceMillis(lastUpdated);
float alpha = Math.min(timeSinceUpdate / updateSpacing, 2f); float alpha = Math.min(timeSinceUpdate / updateSpacing, 2f);

View File

@@ -6,10 +6,12 @@ import io.anuke.arc.collection.Array;
import io.anuke.arc.function.Supplier; import io.anuke.arc.function.Supplier;
import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.game.EventType.ZoneCompleteEvent; import io.anuke.mindustry.game.EventType.ZoneCompleteEvent;
import io.anuke.mindustry.game.EventType.ZoneConfigureCompleteEvent; import io.anuke.mindustry.game.EventType.ZoneConfigureCompleteEvent;
import io.anuke.mindustry.game.Loadout; import io.anuke.mindustry.game.Loadout;
import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.Rules;
import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.maps.generators.MapGenerator; import io.anuke.mindustry.maps.generators.MapGenerator;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@@ -39,6 +41,19 @@ public class Zone extends UnlockableContent{
this.generator = generator; this.generator = generator;
} }
protected SpawnGroup bossGroup(UnitType type){
return new SpawnGroup(type){{
begin = configureWave-1;
effect = StatusEffects.boss;
unitScaling = 1;
spacing = configureWave;
}};
}
public boolean isBossWave(int wave){
return wave % configureWave == 0 && wave > 0;
}
public ItemStack[] getLaunchCost(){ public ItemStack[] getLaunchCost(){
if(launchCost == null){ if(launchCost == null){
updateLaunchCost(); updateLaunchCost();

View File

@@ -30,6 +30,7 @@ import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.input.Binding;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.net.Packets.AdminAction;
import io.anuke.mindustry.ui.Bar;
import io.anuke.mindustry.ui.IntFormat; import io.anuke.mindustry.ui.IntFormat;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -93,7 +94,7 @@ public class HudFragment extends Fragment{
if(Net.active() && mobile){ if(Net.active() && mobile){
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-chat"); i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-chat");
}else{ }else{
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-database"); i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-database-small");
} }
}).get(); }).get();
@@ -126,6 +127,12 @@ public class HudFragment extends Fragment{
cont.row(); cont.row();
Table healthTable = cont.table("button", t ->
t.margin(10f).add(new Bar("boss.health", Pal.health, () -> state.boss() == null ? 0f : state.boss().healthf()).blink(Color.WHITE)).grow()
).fillX().visible(() -> world.isZone() && state.boss() != null).height(60f).update(t -> t.getTranslation().set(wavetable.getTranslation())).get();
cont.row();
//fps display //fps display
infolabel = cont.table(t -> { infolabel = cont.table(t -> {
IntFormat fps = new IntFormat("fps"); IntFormat fps = new IntFormat("fps");
@@ -135,7 +142,8 @@ public class HudFragment extends Fragment{
if(Net.hasClient()){ if(Net.hasClient()){
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2); t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
} }
}).size(-1).visible(() -> Core.settings.getBool("fps")).update(t -> t.setTranslation(0, (!waves.isVisible() ? wavetable.getHeight() : Math.min(wavetable.getTranslation().y, wavetable.getHeight())))).get(); }).size(-1).visible(() -> Core.settings.getBool("fps")).update(t -> t.setTranslation(0,
(!waves.isVisible() ? wavetable.getHeight() + healthTable.getHeight() : Math.min(wavetable.getTranslation().y + healthTable.getHeight(), wavetable.getHeight() + healthTable.getHeight())))).get();
//make wave box appear below rest of menu //make wave box appear below rest of menu
if(mobile){ if(mobile){

View File

@@ -3,11 +3,12 @@ package io.anuke.mindustry.world.blocks.power;
import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote; import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.Core; import io.anuke.arc.Core;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.Lines;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.math.Angles;
import io.anuke.arc.util.Strings; import io.anuke.arc.util.Strings;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.type.Player;
@@ -15,6 +16,7 @@ import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.graphics.Shapes;
import io.anuke.mindustry.ui.Bar; import io.anuke.mindustry.ui.Bar;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock; import io.anuke.mindustry.world.blocks.PowerBlock;
@@ -240,6 +242,7 @@ public class PowerNode extends PowerBlock{
} }
protected void drawLaser(Tile tile, Tile target){ protected void drawLaser(Tile tile, Tile target){
float x1 = tile.drawx(), y1 = tile.drawy(), float x1 = tile.drawx(), y1 = tile.drawy(),
x2 = target.drawx(), y2 = target.drawy(); x2 = target.drawx(), y2 = target.drawy();
@@ -254,9 +257,11 @@ public class PowerNode extends PowerBlock{
x2 += t2.x; x2 += t2.x;
y2 += t2.y; y2 += t2.y;
Draw.color(Pal.powerLight, Pal.power, Mathf.absin(Time.time(), 8f, 1f)); Draw.color(Pal.powerLight, Color.WHITE, Mathf.absin(Time.time(), 8f, 0.3f) + 0.2f);
Lines.stroke(2f); //Lines.stroke(2f);
Lines.line(x1, y1, x2, y2); //Lines.line(x1, y1, x2, y2);
Shapes.laser("laser", "laser-end", x1, y1, x2, y2, 0.5f);
} }
} }

View File

@@ -55,7 +55,7 @@ def antialias = {File file ->
[p1, p2, p3, p4, p5, p6, p7, p8, p9].each{ val -> [p1, p2, p3, p4, p5, p6, p7, p8, p9].each{ val ->
Color.argb8888ToColor(color, val) Color.argb8888ToColor(color, val)
if(color.a > 0.1){ if(color.a > 0.05){
sum.r += color.r sum.r += color.r
sum.g += color.g sum.g += color.g
sum.b += color.b sum.b += color.b