Global drone repair / Fixed item bridge

This commit is contained in:
Anuken 2018-11-01 19:45:13 -04:00
parent ddc59dfb97
commit cf44efa02e
7 changed files with 74 additions and 40 deletions

View file

@ -2,7 +2,7 @@ package io.anuke.mindustry.ai;
import com.badlogic.gdx.math.Vector2;
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.entities.TileEntity;
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.ucore.core.Events;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.EnumSet;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.ThreadArray;
import io.anuke.ucore.util.*;
import static io.anuke.mindustry.Vars.*;
@ -33,12 +30,14 @@ public class BlockIndexer{
private final static int structQuadrantSize = 12;
/**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<>();
/**Stores all ore quadtrants on the map.*/
private ObjectMap<Item, ObjectSet<Tile>> ores;
/**Tags all quadrants.*/
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.*/
private ObjectSet<Tile>[][] flagMap = new ObjectSet[Team.all.length][BlockFlag.all.length];
@ -62,7 +61,9 @@ public class BlockIndexer{
});
Events.on(WorldLoadEvent.class, event -> {
damagedTiles = new ObjectSet[Team.all.length];
flagMap = new ObjectSet[Team.all.length][BlockFlag.all.length];
for(int i = 0; i < flagMap.length; i++){
for(int j = 0; j < BlockFlag.all.length; j++){
flagMap[i][j] = new ObjectSet<>();
@ -79,7 +80,13 @@ public class BlockIndexer{
for(int x = 0; x < world.width(); x++){
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()];
}
/**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.*/
public ObjectSet<Tile> getAllied(Team team, BlockFlag type){
return flagMap[team.ordinal()][type.ordinal()];
@ -115,6 +144,15 @@ public class BlockIndexer{
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){
TileEntity closest = null;
float dst = 0;

View file

@ -143,10 +143,14 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
public void damage(float damage){
if(dead) return;
float preHealth = health;
Call.onTileDamage(tile, health - tile.block().handleDamage(tile, damage));
if(health <= 0){
Call.onTileDestroyed(tile);
}else if(preHealth >= maxHealth() - 0.00001f && health < maxHealth()){ //when just damaged
world.indexer.notifyTileDamaged(this);
}
}

View file

@ -11,8 +11,9 @@ import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityQuery;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Threads;
import io.anuke.ucore.util.EnumSet;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Threads;
import static io.anuke.mindustry.Vars.*;
@ -125,6 +126,12 @@ public class Units{
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.*/
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return world.indexer.findTile(team, x, y, range, pred);

View file

@ -104,22 +104,17 @@ public class Drone extends FlyingUnit implements BuilderTrait{
}
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(() -> {
target = Units.findAllyTile(team, x, y, discoverRange,
tile -> tile.entity != null && tile.entity.health + 0.0001f < tile.block().health);
retarget(() -> {
target = Units.findDamagedTile(team, x, y);
if(target == null){
setState(mine);
}
});
}else if(target.distanceTo(Drone.this) > type.range){
circle(type.range);
if(target == null){
setState(mine);
}
});
if(target.distanceTo(Drone.this) > type.range){
circle(type.range*0.9f);
}else{
TileEntity entity = (TileEntity) target;
entity.healBy(type.healSpeed * entity.tile.block().health / 100f * Timers.delta());
@ -318,7 +313,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
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;
entity.health += type.healSpeed * Timers.delta();
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
@ -329,7 +324,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
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);
}else{
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
@ -355,7 +350,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
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;
Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f));
Shapes.laser("beam", "beam-end",

View file

@ -221,9 +221,7 @@ public abstract class InputHandler extends InputAdapter{
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){
if(canTapPlayer(x, y)){
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();
}
/**
* Tries to begin mining a tile, returns true if successful.
*/
/**Tries to begin mining a tile, returns true if successful.*/
boolean tryBeginMine(Tile tile){
if(canMine(tile)){
//if a block is clicked twice, reset it

View file

@ -101,14 +101,6 @@ public class Tile implements PosTrait, TargetTrait{
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(){
return (T) entity;
}

View file

@ -14,6 +14,7 @@ import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockGroup;
import io.anuke.ucore.core.Timers;
@ -265,7 +266,8 @@ public class ItemBridge extends Block{
Tile other = world.tile(entity.link);
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();