Many things
This commit is contained in:
@@ -352,6 +352,7 @@ zone.desolateRift.name = Desolate Rift
|
|||||||
zone.nuclearComplex.name = Nuclear Production Complex
|
zone.nuclearComplex.name = Nuclear Production Complex
|
||||||
zone.overgrowth.name = Overgrowth
|
zone.overgrowth.name = Overgrowth
|
||||||
zone.tarFields.name = Tar Fields
|
zone.tarFields.name = Tar Fields
|
||||||
|
zone.saltFlats.name = Salt Flats
|
||||||
|
|
||||||
settings.language = Language
|
settings.language = Language
|
||||||
settings.reset = Reset to Defaults
|
settings.reset = Reset to Defaults
|
||||||
|
|||||||
Binary file not shown.
@@ -246,8 +246,28 @@ public class TechTree implements ContentList{
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
node(spiritFactory, () -> {
|
node(draugFactory, () -> {
|
||||||
node(phantomFactory);
|
node(spiritFactory, () -> {
|
||||||
|
node(phantomFactory);
|
||||||
|
});
|
||||||
|
|
||||||
|
node(daggerFactory, () -> {
|
||||||
|
node(crawlerFactory, () -> {
|
||||||
|
node(titanFactory, () -> {
|
||||||
|
node(fortressFactory, () -> {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
node(wraithFactory, () -> {
|
||||||
|
node(spiritFactory, () -> {
|
||||||
|
node(revenantFactory, () -> {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
node(dartPad, () -> {
|
node(dartPad, () -> {
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public class Zones implements ContentList{
|
|||||||
launchPeriod = 5;
|
launchPeriod = 5;
|
||||||
loadout = Loadouts.basicFoundation;
|
loadout = Loadouts.basicFoundation;
|
||||||
zoneRequirements = ZoneRequirement.with(desertWastes, 60);
|
zoneRequirements = ZoneRequirement.with(desertWastes, 60);
|
||||||
|
blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.draugFactory};
|
||||||
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
|
resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,21 @@ import io.anuke.arc.ApplicationListener;
|
|||||||
import io.anuke.arc.Events;
|
import io.anuke.arc.Events;
|
||||||
import io.anuke.arc.collection.ObjectSet.ObjectSetIterator;
|
import io.anuke.arc.collection.ObjectSet.ObjectSetIterator;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
import io.anuke.mindustry.content.Fx;
|
import io.anuke.mindustry.content.*;
|
||||||
import io.anuke.mindustry.content.Items;
|
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.*;
|
import io.anuke.mindustry.entities.*;
|
||||||
import io.anuke.mindustry.entities.type.Player;
|
import io.anuke.mindustry.entities.type.Player;
|
||||||
import io.anuke.mindustry.entities.type.TileEntity;
|
import io.anuke.mindustry.entities.type.TileEntity;
|
||||||
import io.anuke.mindustry.game.EventType.*;
|
import io.anuke.mindustry.game.EventType.*;
|
||||||
import io.anuke.mindustry.game.*;
|
import io.anuke.mindustry.game.*;
|
||||||
|
import io.anuke.mindustry.game.Teams.TeamData;
|
||||||
|
import io.anuke.mindustry.gen.BrokenBlock;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.Item;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||||
|
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -39,13 +43,25 @@ public class Logic implements ApplicationListener{
|
|||||||
p.respawns = state.rules.respawns;
|
p.respawns = state.rules.respawns;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
Events.on(BlockDestroyEvent.class, event -> {
|
||||||
public void init(){
|
//blocks that get broken are appended to the team's broken block queue
|
||||||
collisions.setCollider(tilesize, (x, y) -> {
|
Tile tile = event.tile;
|
||||||
Tile tile = world.tile(x, y);
|
Block block = tile.block();
|
||||||
return tile != null && tile.solid();
|
if(block instanceof BuildBlock){
|
||||||
|
BuildEntity entity = tile.entity();
|
||||||
|
|
||||||
|
//update block to reflect the fact that something was being constructed
|
||||||
|
if(entity.cblock != null && entity.cblock.synthetic()){
|
||||||
|
block = entity.cblock;
|
||||||
|
}else{
|
||||||
|
//otherwise this was a deconstruction that was interrupted, don't want to rebuild that
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamData data = state.teams.get(tile.getTeam());
|
||||||
|
data.brokenBlocks.addFirst(BrokenBlock.get(tile.x, tile.y, block.id, tile.rotation()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +213,6 @@ public class Logic implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
collisions.collideGroups(bulletGroup, playerGroup);
|
collisions.collideGroups(bulletGroup, playerGroup);
|
||||||
collisions.collideGroups(playerGroup, playerGroup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
world.pathfinder.update();
|
world.pathfinder.update();
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package io.anuke.mindustry.entities;
|
package io.anuke.mindustry.entities;
|
||||||
|
|
||||||
import io.anuke.arc.collection.Array;
|
import io.anuke.arc.collection.Array;
|
||||||
import io.anuke.arc.collection.IntSet;
|
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.arc.math.geom.*;
|
import io.anuke.arc.math.geom.*;
|
||||||
import io.anuke.mindustry.entities.traits.Entity;
|
import io.anuke.mindustry.entities.traits.Entity;
|
||||||
import io.anuke.mindustry.entities.traits.SolidTrait;
|
import io.anuke.mindustry.entities.traits.SolidTrait;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class EntityCollisions{
|
public class EntityCollisions{
|
||||||
//range for tile collision scanning
|
//range for tile collision scanning
|
||||||
@@ -14,29 +17,15 @@ public class EntityCollisions{
|
|||||||
private static final float seg = 1f;
|
private static final float seg = 1f;
|
||||||
|
|
||||||
//tile collisions
|
//tile collisions
|
||||||
private float tilesize;
|
|
||||||
private Rectangle tmp = new Rectangle();
|
private Rectangle tmp = new Rectangle();
|
||||||
private TileCollider collider;
|
|
||||||
private TileHitboxProvider hitboxProvider;
|
|
||||||
private Vector2 vector = new Vector2();
|
private Vector2 vector = new Vector2();
|
||||||
private Vector2 l1 = new Vector2();
|
private Vector2 l1 = new Vector2();
|
||||||
private Rectangle r1 = new Rectangle();
|
private Rectangle r1 = new Rectangle();
|
||||||
private Rectangle r2 = new Rectangle();
|
private Rectangle r2 = new Rectangle();
|
||||||
|
|
||||||
//entity collisions
|
//entity collisions
|
||||||
private IntSet collided = new IntSet();
|
|
||||||
private Array<SolidTrait> arrOut = new Array<>();
|
private Array<SolidTrait> arrOut = new Array<>();
|
||||||
|
|
||||||
public void setCollider(float tilesize, TileCollider collider, TileHitboxProvider hitbox){
|
|
||||||
this.tilesize = tilesize;
|
|
||||||
this.collider = collider;
|
|
||||||
this.hitboxProvider = hitbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCollider(float tilesize, TileCollider collider){
|
|
||||||
setCollider(tilesize, collider, (x, y, out) -> out.setSize(tilesize).setCenter(x * tilesize, y * tilesize));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(SolidTrait entity, float deltax, float deltay){
|
public void move(SolidTrait entity, float deltax, float deltay){
|
||||||
|
|
||||||
boolean movedx = false;
|
boolean movedx = false;
|
||||||
@@ -67,8 +56,6 @@ public class EntityCollisions{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void moveDelta(SolidTrait entity, float deltax, float deltay, boolean x){
|
public void moveDelta(SolidTrait entity, float deltax, float deltay, boolean x){
|
||||||
if(collider == null)
|
|
||||||
throw new IllegalArgumentException("No tile collider specified! Call setCollider() first.");
|
|
||||||
|
|
||||||
Rectangle rect = r1;
|
Rectangle rect = r1;
|
||||||
entity.hitboxTile(rect);
|
entity.hitboxTile(rect);
|
||||||
@@ -81,9 +68,8 @@ public class EntityCollisions{
|
|||||||
for(int dx = -r; dx <= r; dx++){
|
for(int dx = -r; dx <= r; dx++){
|
||||||
for(int dy = -r; dy <= r; dy++){
|
for(int dy = -r; dy <= r; dy++){
|
||||||
int wx = dx + tilex, wy = dy + tiley;
|
int wx = dx + tilex, wy = dy + tiley;
|
||||||
if(collider.solid(wx, wy) && entity.collidesGrid(wx, wy)){
|
if(solid(wx, wy) && entity.collidesGrid(wx, wy)){
|
||||||
|
tmp.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
|
||||||
hitboxProvider.getHitbox(wx, wy, tmp);
|
|
||||||
|
|
||||||
if(tmp.overlaps(rect)){
|
if(tmp.overlaps(rect)){
|
||||||
Vector2 v = Geometry.overlap(rect, tmp, x);
|
Vector2 v = Geometry.overlap(rect, tmp, x);
|
||||||
@@ -99,9 +85,6 @@ public class EntityCollisions{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean overlapsTile(Rectangle rect){
|
public boolean overlapsTile(Rectangle rect){
|
||||||
if(collider == null)
|
|
||||||
throw new IllegalArgumentException("No tile collider specified! Call setCollider() first.");
|
|
||||||
|
|
||||||
rect.getCenter(vector);
|
rect.getCenter(vector);
|
||||||
int r = 1;
|
int r = 1;
|
||||||
|
|
||||||
@@ -112,8 +95,8 @@ public class EntityCollisions{
|
|||||||
for(int dx = -r; dx <= r; dx++){
|
for(int dx = -r; dx <= r; dx++){
|
||||||
for(int dy = -r; dy <= r; dy++){
|
for(int dy = -r; dy <= r; dy++){
|
||||||
int wx = dx + tilex, wy = dy + tiley;
|
int wx = dx + tilex, wy = dy + tiley;
|
||||||
if(collider.solid(wx, wy)){
|
if(solid(wx, wy)){
|
||||||
hitboxProvider.getHitbox(wx, wy, r2);
|
r2.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
|
||||||
|
|
||||||
if(r2.overlaps(rect)){
|
if(r2.overlaps(rect)){
|
||||||
return true;
|
return true;
|
||||||
@@ -126,7 +109,6 @@ public class EntityCollisions{
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Entity> void updatePhysics(EntityGroup<T> group){
|
public <T extends Entity> void updatePhysics(EntityGroup<T> group){
|
||||||
collided.clear();
|
|
||||||
|
|
||||||
QuadTree tree = group.tree();
|
QuadTree tree = group.tree();
|
||||||
tree.clear();
|
tree.clear();
|
||||||
@@ -140,6 +122,11 @@ public class EntityCollisions{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean solid(int x, int y){
|
||||||
|
Tile tile = world.tile(x, y);
|
||||||
|
return tile != null && tile.solid();
|
||||||
|
}
|
||||||
|
|
||||||
private void checkCollide(Entity entity, Entity other){
|
private void checkCollide(Entity entity, Entity other){
|
||||||
|
|
||||||
SolidTrait a = (SolidTrait)entity;
|
SolidTrait a = (SolidTrait)entity;
|
||||||
@@ -221,10 +208,9 @@ public class EntityCollisions{
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){
|
public void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){
|
||||||
collided.clear();
|
|
||||||
|
|
||||||
for(Entity entity : groupa.all()){
|
for(Entity entity : groupa.all()){
|
||||||
if(!(entity instanceof SolidTrait) || collided.contains(entity.getID()))
|
if(!(entity instanceof SolidTrait))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SolidTrait solid = (SolidTrait)entity;
|
SolidTrait solid = (SolidTrait)entity;
|
||||||
@@ -241,20 +227,10 @@ public class EntityCollisions{
|
|||||||
|
|
||||||
for(SolidTrait sc : arrOut){
|
for(SolidTrait sc : arrOut){
|
||||||
sc.hitbox(r1);
|
sc.hitbox(r1);
|
||||||
if(r2.overlaps(r1) && !collided.contains(sc.getID())){
|
if(r2.overlaps(r1)){
|
||||||
checkCollide(entity, sc);
|
checkCollide(entity, sc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collided.add(entity.getID());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TileCollider{
|
|
||||||
boolean solid(int x, int y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface TileHitboxProvider{
|
|
||||||
void getHitbox(int x, int y, Rectangle out);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ public class EventType{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called right before a block is destroyed.
|
||||||
|
* The tile entity of the tile in this event cannot be null when this happens.*/
|
||||||
public static class BlockDestroyEvent{
|
public static class BlockDestroyEvent{
|
||||||
public final Tile tile;
|
public final Tile tile;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.game;
|
package io.anuke.mindustry.game;
|
||||||
|
|
||||||
|
import io.anuke.annotations.Annotations.Struct;
|
||||||
import io.anuke.arc.collection.*;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
@@ -43,6 +44,7 @@ public class Teams{
|
|||||||
|
|
||||||
public class TeamData{
|
public class TeamData{
|
||||||
public final ObjectSet<Tile> cores = new ObjectSet<>();
|
public final ObjectSet<Tile> cores = new ObjectSet<>();
|
||||||
|
public final LongQueue brokenBlocks = new LongQueue();
|
||||||
public final EnumSet<Team> enemies;
|
public final EnumSet<Team> enemies;
|
||||||
public final Team team;
|
public final Team team;
|
||||||
|
|
||||||
@@ -51,4 +53,11 @@ public class Teams{
|
|||||||
this.enemies = enemies;
|
this.enemies = enemies;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Represents a block made by this team that was destroyed somewhere on the map.
|
||||||
|
* This does not include deconstructed blocks.*/
|
||||||
|
@Struct
|
||||||
|
public class BrokenBlockStruct{
|
||||||
|
public short x, y, rotation, block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,44 +246,51 @@ public class TechTreeDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
infoTable.background("content-background");
|
|
||||||
infoTable.update(() -> infoTable.setPosition(button.getX() + button.getWidth(), button.getY() + button.getHeight(), Align.topLeft));
|
infoTable.update(() -> infoTable.setPosition(button.getX() + button.getWidth(), button.getY() + button.getHeight(), Align.topLeft));
|
||||||
|
|
||||||
infoTable.margin(0).left().defaults().left();
|
infoTable.left();
|
||||||
|
|
||||||
infoTable.addImageButton("icon-info", "node", 14 * 2, () -> ui.content.show(node.block)).growY().width(50f);
|
infoTable.table("content-background", b -> {
|
||||||
|
b.margin(0).left().defaults().left();
|
||||||
|
|
||||||
infoTable.add().grow();
|
b.addImageButton("icon-info", "node", 14 * 2, () -> ui.content.show(node.block)).growY().width(50f);
|
||||||
|
b.add().grow();
|
||||||
|
b.table(desc -> {
|
||||||
|
desc.left().defaults().left();
|
||||||
|
desc.add(node.block.localizedName);
|
||||||
|
desc.row();
|
||||||
|
if(locked(node)){
|
||||||
|
desc.table(t -> {
|
||||||
|
t.left();
|
||||||
|
for(ItemStack req : node.requirements){
|
||||||
|
t.table(list -> {
|
||||||
|
list.left();
|
||||||
|
list.addImage(req.item.getContentIcon()).size(8 * 3).padRight(3);
|
||||||
|
list.add(req.item.localizedName()).color(Color.LIGHT_GRAY);
|
||||||
|
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
|
||||||
|
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET));
|
||||||
|
}).fillX().left();
|
||||||
|
t.row();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
desc.add("$completed");
|
||||||
|
}
|
||||||
|
}).pad(9);
|
||||||
|
|
||||||
infoTable.table(desc -> {
|
if(mobile && locked(node)){
|
||||||
desc.left().defaults().left();
|
b.row();
|
||||||
desc.add(node.block.localizedName);
|
b.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node))
|
||||||
desc.row();
|
.disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
|
||||||
if(locked(node)){
|
|
||||||
desc.table(t -> {
|
|
||||||
t.left();
|
|
||||||
for(ItemStack req : node.requirements){
|
|
||||||
t.table(list -> {
|
|
||||||
list.left();
|
|
||||||
list.addImage(req.item.getContentIcon()).size(8 * 3).padRight(3);
|
|
||||||
list.add(req.item.localizedName()).color(Color.LIGHT_GRAY);
|
|
||||||
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
|
|
||||||
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET));
|
|
||||||
}).fillX().left();
|
|
||||||
t.row();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
desc.add("$completed");
|
|
||||||
}
|
}
|
||||||
}).pad(9);
|
});
|
||||||
|
|
||||||
if(mobile && locked(node)){
|
infoTable.row();
|
||||||
infoTable.row();
|
if(node.block.description != null){
|
||||||
infoTable.addImageTextButton("$research", "icon-check", "node", 16 * 2, () -> unlock(node))
|
infoTable.table("dialogDim", t -> t.margin(3f).left().labelWrap(node.block.description).color(Color.LIGHT_GRAY).growX()).fillX();
|
||||||
.disabled(b -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addChild(infoTable);
|
addChild(infoTable);
|
||||||
infoTable.pack();
|
infoTable.pack();
|
||||||
infoTable.act(Core.graphics.getDeltaTime());
|
infoTable.act(Core.graphics.getDeltaTime());
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class BuildBlock extends Block{
|
|||||||
* The recipe of the block that is being constructed.
|
* The recipe of the block that is being constructed.
|
||||||
* If there is no recipe for this block, as is the case with rocks, 'previous' is used.
|
* If there is no recipe for this block, as is the case with rocks, 'previous' is used.
|
||||||
*/
|
*/
|
||||||
public Block cblock;
|
public @Nullable Block cblock;
|
||||||
|
|
||||||
public float progress = 0;
|
public float progress = 0;
|
||||||
public float buildCost;
|
public float buildCost;
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class Generators{
|
|||||||
|
|
||||||
ImagePacker.generate("block-icons", () -> {
|
ImagePacker.generate("block-icons", () -> {
|
||||||
Image colors = new Image(content.blocks().size, 1);
|
Image colors = new Image(content.blocks().size, 1);
|
||||||
Color outlineColor = Color.valueOf("4d4e58");
|
Color outlineColor = Color.valueOf("404049");
|
||||||
|
|
||||||
for(Block block : content.blocks()){
|
for(Block block : content.blocks()){
|
||||||
TextureRegion[] regions = block.getGeneratedIcons();
|
TextureRegion[] regions = block.getGeneratedIcons();
|
||||||
|
|||||||
Reference in New Issue
Block a user