Global drone repair / Fixed item bridge
This commit is contained in:
@@ -2,7 +2,7 @@ package io.anuke.mindustry.ai;
|
|||||||
|
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.*;
|
import com.badlogic.gdx.utils.*;
|
||||||
import io.anuke.mindustry.content.Items;
|
import com.badlogic.gdx.utils.Bits;
|
||||||
import io.anuke.mindustry.content.blocks.Blocks;
|
import io.anuke.mindustry.content.blocks.Blocks;
|
||||||
import io.anuke.mindustry.entities.TileEntity;
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
||||||
@@ -14,10 +14,7 @@ import io.anuke.mindustry.world.Tile;
|
|||||||
import io.anuke.mindustry.world.meta.BlockFlag;
|
import io.anuke.mindustry.world.meta.BlockFlag;
|
||||||
import io.anuke.ucore.core.Events;
|
import io.anuke.ucore.core.Events;
|
||||||
import io.anuke.ucore.function.Predicate;
|
import io.anuke.ucore.function.Predicate;
|
||||||
import io.anuke.ucore.util.EnumSet;
|
import io.anuke.ucore.util.*;
|
||||||
import io.anuke.ucore.util.Geometry;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
|
||||||
import io.anuke.ucore.util.ThreadArray;
|
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -33,12 +30,14 @@ public class BlockIndexer{
|
|||||||
private final static int structQuadrantSize = 12;
|
private final static int structQuadrantSize = 12;
|
||||||
|
|
||||||
/**Set of all ores that are being scanned.*/
|
/**Set of all ores that are being scanned.*/
|
||||||
private final ObjectSet<Item> scanOres = ObjectSet.with(Items.copper, Items.coal, Items.lead, Items.thorium, Items.titanium);
|
private final ObjectSet<Item> scanOres = new ObjectSet<Item>(){{addAll(Item.getAllOres());}};
|
||||||
private final ObjectSet<Item> itemSet = new ObjectSet<>();
|
private final ObjectSet<Item> itemSet = new ObjectSet<>();
|
||||||
/**Stores all ore quadtrants on the map.*/
|
/**Stores all ore quadtrants on the map.*/
|
||||||
private ObjectMap<Item, ObjectSet<Tile>> ores;
|
private ObjectMap<Item, ObjectSet<Tile>> ores;
|
||||||
/**Tags all quadrants.*/
|
/**Tags all quadrants.*/
|
||||||
private Bits[] structQuadrants;
|
private Bits[] structQuadrants;
|
||||||
|
/**Stores all damaged tile entities by team.*/
|
||||||
|
private ObjectSet<Tile>[] damagedTiles = new ObjectSet[Team.all.length];
|
||||||
|
|
||||||
/**Maps teams to a map of flagged tiles by type.*/
|
/**Maps teams to a map of flagged tiles by type.*/
|
||||||
private ObjectSet<Tile>[][] flagMap = new ObjectSet[Team.all.length][BlockFlag.all.length];
|
private ObjectSet<Tile>[][] flagMap = new ObjectSet[Team.all.length][BlockFlag.all.length];
|
||||||
@@ -62,7 +61,9 @@ public class BlockIndexer{
|
|||||||
});
|
});
|
||||||
|
|
||||||
Events.on(WorldLoadEvent.class, event -> {
|
Events.on(WorldLoadEvent.class, event -> {
|
||||||
|
damagedTiles = new ObjectSet[Team.all.length];
|
||||||
flagMap = new ObjectSet[Team.all.length][BlockFlag.all.length];
|
flagMap = new ObjectSet[Team.all.length][BlockFlag.all.length];
|
||||||
|
|
||||||
for(int i = 0; i < flagMap.length; i++){
|
for(int i = 0; i < flagMap.length; i++){
|
||||||
for(int j = 0; j < BlockFlag.all.length; j++){
|
for(int j = 0; j < BlockFlag.all.length; j++){
|
||||||
flagMap[i][j] = new ObjectSet<>();
|
flagMap[i][j] = new ObjectSet<>();
|
||||||
@@ -79,7 +80,13 @@ public class BlockIndexer{
|
|||||||
|
|
||||||
for(int x = 0; x < world.width(); x++){
|
for(int x = 0; x < world.width(); x++){
|
||||||
for(int y = 0; y < world.height(); y++){
|
for(int y = 0; y < world.height(); y++){
|
||||||
process(world.tile(x, y));
|
Tile tile = world.tileWorld(x, y);
|
||||||
|
|
||||||
|
process(tile);
|
||||||
|
|
||||||
|
if(tile.entity != null && tile.entity.healthf() < 0.9999f){
|
||||||
|
notifyTileDamaged(tile.entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +104,28 @@ public class BlockIndexer{
|
|||||||
return flagMap[team.ordinal()];
|
return flagMap[team.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Returns all damaged tiles by team.*/
|
||||||
|
public ObjectSet<Tile> getDamaged(Team team){
|
||||||
|
returnArray.clear();
|
||||||
|
|
||||||
|
if(damagedTiles[team.ordinal()] == null){
|
||||||
|
damagedTiles[team.ordinal()] = new ObjectSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectSet<Tile> set = damagedTiles[team.ordinal()];
|
||||||
|
for(Tile tile : set){
|
||||||
|
if(tile.entity == null || tile.entity.getTeam() != team || tile.entity.healthf() >= 0.9999f){
|
||||||
|
returnArray.add(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Tile tile : returnArray){
|
||||||
|
set.remove(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
/**Get all allied blocks with a flag.*/
|
/**Get all allied blocks with a flag.*/
|
||||||
public ObjectSet<Tile> getAllied(Team team, BlockFlag type){
|
public ObjectSet<Tile> getAllied(Team team, BlockFlag type){
|
||||||
return flagMap[team.ordinal()][type.ordinal()];
|
return flagMap[team.ordinal()][type.ordinal()];
|
||||||
@@ -115,6 +144,15 @@ public class BlockIndexer{
|
|||||||
return returnArray;
|
return returnArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyTileDamaged(TileEntity entity){
|
||||||
|
if(damagedTiles[entity.getTeam().ordinal()] == null){
|
||||||
|
damagedTiles[entity.getTeam().ordinal()] = new ObjectSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectSet<Tile> set = damagedTiles[entity.getTeam().ordinal()];
|
||||||
|
set.add(entity.tile);
|
||||||
|
}
|
||||||
|
|
||||||
public TileEntity findTile(Team team, float x, float y, float range, Predicate<Tile> pred){
|
public TileEntity findTile(Team team, float x, float y, float range, Predicate<Tile> pred){
|
||||||
TileEntity closest = null;
|
TileEntity closest = null;
|
||||||
float dst = 0;
|
float dst = 0;
|
||||||
|
|||||||
@@ -143,10 +143,14 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
|||||||
public void damage(float damage){
|
public void damage(float damage){
|
||||||
if(dead) return;
|
if(dead) return;
|
||||||
|
|
||||||
|
float preHealth = health;
|
||||||
|
|
||||||
Call.onTileDamage(tile, health - tile.block().handleDamage(tile, damage));
|
Call.onTileDamage(tile, health - tile.block().handleDamage(tile, damage));
|
||||||
|
|
||||||
if(health <= 0){
|
if(health <= 0){
|
||||||
Call.onTileDestroyed(tile);
|
Call.onTileDestroyed(tile);
|
||||||
|
}else if(preHealth >= maxHealth() - 0.00001f && health < maxHealth()){ //when just damaged
|
||||||
|
world.indexer.notifyTileDamaged(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import io.anuke.ucore.entities.EntityGroup;
|
|||||||
import io.anuke.ucore.entities.EntityQuery;
|
import io.anuke.ucore.entities.EntityQuery;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
import io.anuke.ucore.function.Predicate;
|
import io.anuke.ucore.function.Predicate;
|
||||||
import io.anuke.ucore.util.Threads;
|
|
||||||
import io.anuke.ucore.util.EnumSet;
|
import io.anuke.ucore.util.EnumSet;
|
||||||
|
import io.anuke.ucore.util.Geometry;
|
||||||
|
import io.anuke.ucore.util.Threads;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -125,6 +126,12 @@ public class Units{
|
|||||||
return value[0];
|
return value[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Returns the neareset damaged tile.*/
|
||||||
|
public static TileEntity findDamagedTile(Team team, float x, float y){
|
||||||
|
Tile tile = Geometry.findClosest(x, y, world.indexer.getDamaged(team));
|
||||||
|
return tile == null ? null : tile.entity;
|
||||||
|
}
|
||||||
|
|
||||||
/**Returns the neareset ally tile in a range.*/
|
/**Returns the neareset ally tile in a range.*/
|
||||||
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
|
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
|
||||||
return world.indexer.findTile(team, x, y, range, pred);
|
return world.indexer.findTile(team, x, y, range, pred);
|
||||||
|
|||||||
@@ -104,22 +104,17 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update(){
|
public void update(){
|
||||||
if(target != null && (((TileEntity) target).health >= ((TileEntity) target).tile.block().health
|
|
||||||
|| target.distanceTo(Drone.this) > discoverRange)){
|
|
||||||
target = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(target == null){
|
|
||||||
retarget(() -> {
|
retarget(() -> {
|
||||||
target = Units.findAllyTile(team, x, y, discoverRange,
|
target = Units.findDamagedTile(team, x, y);
|
||||||
tile -> tile.entity != null && tile.entity.health + 0.0001f < tile.block().health);
|
|
||||||
|
|
||||||
if(target == null){
|
if(target == null){
|
||||||
setState(mine);
|
setState(mine);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else if(target.distanceTo(Drone.this) > type.range){
|
|
||||||
circle(type.range);
|
if(target.distanceTo(Drone.this) > type.range){
|
||||||
|
circle(type.range*0.9f);
|
||||||
}else{
|
}else{
|
||||||
TileEntity entity = (TileEntity) target;
|
TileEntity entity = (TileEntity) target;
|
||||||
entity.healBy(type.healSpeed * entity.tile.block().health / 100f * Timers.delta());
|
entity.healBy(type.healSpeed * entity.tile.block().health / 100f * Timers.delta());
|
||||||
@@ -318,7 +313,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
target = null;
|
target = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Net.client() && state.is(repair) && target instanceof TileEntity){
|
if(Net.client() && state.is(repair) && target instanceof TileEntity && target.distanceTo(this) < type.range){
|
||||||
TileEntity entity = (TileEntity) target;
|
TileEntity entity = (TileEntity) target;
|
||||||
entity.health += type.healSpeed * Timers.delta();
|
entity.health += type.healSpeed * Timers.delta();
|
||||||
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
|
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
|
||||||
@@ -329,7 +324,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateRotation(){
|
protected void updateRotation(){
|
||||||
if(target != null && (state.is(repair) || state.is(mine))){
|
if(target != null && ((state.is(repair) && target.distanceTo(this) < type.range) || state.is(mine))){
|
||||||
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
|
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
|
||||||
}else{
|
}else{
|
||||||
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
|
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
|
||||||
@@ -355,7 +350,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
|
|
||||||
TargetTrait entity = target;
|
TargetTrait entity = target;
|
||||||
|
|
||||||
if(entity instanceof TileEntity && state.is(repair)){
|
if(entity instanceof TileEntity && state.is(repair) && target.distanceTo(this) < type.range){
|
||||||
float len = 5f;
|
float len = 5f;
|
||||||
Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f));
|
Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f));
|
||||||
Shapes.laser("beam", "beam-end",
|
Shapes.laser("beam", "beam-end",
|
||||||
|
|||||||
@@ -221,9 +221,7 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**Tries to select the player to drop off items, returns true if successful.*/
|
||||||
* Tries to select the player to drop off items, returns true if successful.
|
|
||||||
*/
|
|
||||||
boolean tryTapPlayer(float x, float y){
|
boolean tryTapPlayer(float x, float y){
|
||||||
if(canTapPlayer(x, y)){
|
if(canTapPlayer(x, y)){
|
||||||
droppingItem = true;
|
droppingItem = true;
|
||||||
@@ -236,9 +234,7 @@ public abstract class InputHandler extends InputAdapter{
|
|||||||
return Vector2.dst(x, y, player.x, player.y) <= playerSelectRange && player.inventory.hasItem();
|
return Vector2.dst(x, y, player.x, player.y) <= playerSelectRange && player.inventory.hasItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**Tries to begin mining a tile, returns true if successful.*/
|
||||||
* Tries to begin mining a tile, returns true if successful.
|
|
||||||
*/
|
|
||||||
boolean tryBeginMine(Tile tile){
|
boolean tryBeginMine(Tile tile){
|
||||||
if(canMine(tile)){
|
if(canMine(tile)){
|
||||||
//if a block is clicked twice, reset it
|
//if a block is clicked twice, reset it
|
||||||
|
|||||||
@@ -101,14 +101,6 @@ public class Tile implements PosTrait, TargetTrait{
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte sizedRelativeTo(int cx, int cy){
|
|
||||||
if(x == cx && y == cy - 1 - block().size / 2) return 1;
|
|
||||||
if(x == cx && y == cy + 1 + block().size / 2) return 3;
|
|
||||||
if(x == cx - 1 - block().size / 2 && y == cy) return 0;
|
|
||||||
if(x == cx + 1 + block().size / 2 && y == cy) return 2;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends TileEntity> T entity(){
|
public <T extends TileEntity> T entity(){
|
||||||
return (T) entity;
|
return (T) entity;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import io.anuke.mindustry.graphics.Layer;
|
|||||||
import io.anuke.mindustry.graphics.Palette;
|
import io.anuke.mindustry.graphics.Palette;
|
||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.Item;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.mindustry.world.Edges;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.meta.BlockGroup;
|
import io.anuke.mindustry.world.meta.BlockGroup;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
@@ -265,7 +266,8 @@ public class ItemBridge extends Block{
|
|||||||
|
|
||||||
Tile other = world.tile(entity.link);
|
Tile other = world.tile(entity.link);
|
||||||
if(!linkValid(tile, other)){
|
if(!linkValid(tile, other)){
|
||||||
int i = tile.absoluteRelativeTo(to.x, to.y);
|
Tile edge = Edges.getFacingEdge(to, tile);
|
||||||
|
int i = tile.absoluteRelativeTo(edge.x, edge.y);
|
||||||
|
|
||||||
IntSetIterator it = entity.incoming.iterator();
|
IntSetIterator it = entity.incoming.iterator();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user