Prototype unit cap mechanic
This commit is contained in:
@@ -591,6 +591,7 @@ bar.poweramount = Power: {0}
|
|||||||
bar.poweroutput = Power Output: {0}
|
bar.poweroutput = Power Output: {0}
|
||||||
bar.items = Items: {0}
|
bar.items = Items: {0}
|
||||||
bar.capacity = Capacity: {0}
|
bar.capacity = Capacity: {0}
|
||||||
|
bar.units = Units: {0}/{1}
|
||||||
bar.liquid = Liquid
|
bar.liquid = Liquid
|
||||||
bar.heat = Heat
|
bar.heat = Heat
|
||||||
bar.power = Power
|
bar.power = Power
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ public class BlockIndexer{
|
|||||||
private ObjectSet<Item> allOres = new ObjectSet<>();
|
private ObjectSet<Item> allOres = new ObjectSet<>();
|
||||||
/** Stores teams that are present here as tiles. */
|
/** Stores teams that are present here as tiles. */
|
||||||
private Array<Team> activeTeams = new Array<>();
|
private Array<Team> activeTeams = new Array<>();
|
||||||
/** Maps teams to a map of flagged tiles by type. */
|
/** Maps teams to a map of flagged tiles by flag. */
|
||||||
private TileArray[][] flagMap = new TileArray[Team.all().length][BlockFlag.all.length];
|
private TileArray[][] flagMap = new TileArray[Team.all().length][BlockFlag.all.length];
|
||||||
|
/** Max units by team. */
|
||||||
|
private int[] unitCaps = new int[Team.all().length];
|
||||||
/** Maps tile positions to their last known tile index data. */
|
/** Maps tile positions to their last known tile index data. */
|
||||||
private IntMap<TileIndex> typeMap = new IntMap<>();
|
private IntMap<TileIndex> typeMap = new IntMap<>();
|
||||||
/** Empty set used for returning. */
|
/** Empty set used for returning. */
|
||||||
@@ -55,6 +57,10 @@ public class BlockIndexer{
|
|||||||
for(BlockFlag flag : index.flags){
|
for(BlockFlag flag : index.flags){
|
||||||
getFlagged(index.team)[flag.ordinal()].remove(event.tile);
|
getFlagged(index.team)[flag.ordinal()].remove(event.tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(index.flags.contains(BlockFlag.unitModifier)){
|
||||||
|
updateCap(index.team);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
process(event.tile);
|
process(event.tile);
|
||||||
updateQuadrant(event.tile);
|
updateQuadrant(event.tile);
|
||||||
@@ -65,6 +71,7 @@ public class BlockIndexer{
|
|||||||
scanOres.addAll(Item.getAllOres());
|
scanOres.addAll(Item.getAllOres());
|
||||||
damagedTiles = new TileArray[Team.all().length];
|
damagedTiles = new TileArray[Team.all().length];
|
||||||
flagMap = new TileArray[Team.all().length][BlockFlag.all.length];
|
flagMap = new TileArray[Team.all().length][BlockFlag.all.length];
|
||||||
|
unitCaps = new int[Team.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++){
|
||||||
@@ -296,6 +303,19 @@ public class BlockIndexer{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return extra unit cap of a team. This is added onto the base value. */
|
||||||
|
public int getExtraUnits(Team team){
|
||||||
|
return unitCaps[team.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCap(Team team){
|
||||||
|
TileArray capped = getFlagged(team)[BlockFlag.unitModifier.ordinal()];
|
||||||
|
unitCaps[team.id] = 0;
|
||||||
|
for(Tile capper : capped){
|
||||||
|
unitCaps[team.id] += capper.block().unitCapModifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void process(Tile tile){
|
private void process(Tile tile){
|
||||||
if(tile.block().flags.size() > 0 && tile.team() != Team.derelict){
|
if(tile.block().flags.size() > 0 && tile.team() != Team.derelict){
|
||||||
TileArray[] map = getFlagged(tile.team());
|
TileArray[] map = getFlagged(tile.team());
|
||||||
@@ -308,6 +328,11 @@ public class BlockIndexer{
|
|||||||
|
|
||||||
map[flag.ordinal()] = arr;
|
map[flag.ordinal()] = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tile.block().flags.contains(BlockFlag.unitModifier)){
|
||||||
|
updateCap(tile.team());
|
||||||
|
}
|
||||||
|
|
||||||
typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.team()));
|
typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.team()));
|
||||||
}
|
}
|
||||||
if(!activeTeams.contains(tile.team())){
|
if(!activeTeams.contains(tile.team())){
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import mindustry.gen.*;
|
|||||||
public class TeamIndexProcess implements AsyncProcess{
|
public class TeamIndexProcess implements AsyncProcess{
|
||||||
private QuadTree<Unitc>[] trees = new QuadTree[Team.all().length];
|
private QuadTree<Unitc>[] trees = new QuadTree[Team.all().length];
|
||||||
private Array<Team> active = new Array<>();
|
private Array<Team> active = new Array<>();
|
||||||
|
private int[] counts = new int[Team.all().length];
|
||||||
|
|
||||||
public QuadTree<Unitc> tree(Team team){
|
public QuadTree<Unitc> tree(Team team){
|
||||||
if(trees[team.uid] == null) trees[team.uid] = new QuadTree<>(Vars.world.getQuadBounds(new Rect()));
|
if(trees[team.uid] == null) trees[team.uid] = new QuadTree<>(Vars.world.getQuadBounds(new Rect()));
|
||||||
@@ -18,9 +19,18 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
return trees[team.uid];
|
return trees[team.uid];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int count(Team team){
|
||||||
|
return counts[team.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateCount(Team team, int amount){
|
||||||
|
counts[team.id] += amount;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset(){
|
public void reset(){
|
||||||
active.clear();
|
active.clear();
|
||||||
|
counts = new int[Team.all().length];
|
||||||
trees = new QuadTree[Team.all().length];
|
trees = new QuadTree[Team.all().length];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +48,13 @@ public class TeamIndexProcess implements AsyncProcess{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(Team team : active){
|
||||||
|
counts[team.id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(Unitc unit : Groups.unit){
|
for(Unitc unit : Groups.unit){
|
||||||
tree(unit.team()).insert(unit);
|
tree(unit.team()).insert(unit);
|
||||||
|
counts[unit.team().id] ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -293,7 +293,10 @@ public class NetServer implements ApplicationListener{
|
|||||||
});
|
});
|
||||||
|
|
||||||
clientCommands.<Playerc>register("t", "<message...>", "Send a message only to your teammates.", (args, player) -> {
|
clientCommands.<Playerc>register("t", "<message...>", "Send a message only to your teammates.", (args, player) -> {
|
||||||
Groups.player.each(p -> p.team() == player.team(), o -> o.sendMessage(args[0], player, "[#" + player.team().color.toString() + "]<T>" + NetClient.colorizeName(player.id(), player.name())));
|
String message = admins.filterMessage(player, args[0]);
|
||||||
|
if(message != null){
|
||||||
|
Groups.player.each(p -> p.team() == player.team(), o -> o.sendMessage(message, player, "[#" + player.team().color.toString() + "]<T>" + NetClient.colorizeName(player.id(), player.name())));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//duration of a a kick in seconds
|
//duration of a a kick in seconds
|
||||||
|
|||||||
@@ -15,6 +15,15 @@ public class Units{
|
|||||||
private static float cdist;
|
private static float cdist;
|
||||||
private static boolean boolResult;
|
private static boolean boolResult;
|
||||||
|
|
||||||
|
/** @return whether a new instance of a unit of this team can be created. */
|
||||||
|
public static boolean canCreate(Team team){
|
||||||
|
return teamIndex.count(team) < getCap(team);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getCap(Team team){
|
||||||
|
return state.rules.unitCap + indexer.getExtraUnits(team);
|
||||||
|
}
|
||||||
|
|
||||||
/** @return whether this player can interact with a specific tile. if either of these are null, returns true.*/
|
/** @return whether this player can interact with a specific tile. if either of these are null, returns true.*/
|
||||||
public static boolean canInteract(Playerc player, Tilec tile){
|
public static boolean canInteract(Playerc player, Tilec tile){
|
||||||
return player == null || tile == null || tile.interactable(player.team());
|
return player == null || tile == null || tile.interactable(player.team());
|
||||||
|
|||||||
@@ -115,6 +115,16 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
type(this.type);
|
type(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(){
|
||||||
|
teamIndex.updateCount(team(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(){
|
||||||
|
teamIndex.updateCount(team(), -1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
drag(type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f));
|
drag(type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f));
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ public class Rules{
|
|||||||
public float bossWaveMultiplier = 3f;
|
public float bossWaveMultiplier = 3f;
|
||||||
/** How many times longer a launch wave takes. */
|
/** How many times longer a launch wave takes. */
|
||||||
public float launchWaveMultiplier = 2f;
|
public float launchWaveMultiplier = 2f;
|
||||||
|
/** Base unit cap. Can still be increased by blocks. */
|
||||||
|
public int unitCap = 10;
|
||||||
/** Sector for saves that have them.*/
|
/** Sector for saves that have them.*/
|
||||||
public @Nullable Sector sector;
|
public @Nullable Sector sector;
|
||||||
/** Region that save is on. Indicates campaign. TODO not implemented. */
|
/** Region that save is on. Indicates campaign. TODO not implemented. */
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ public class Block extends UnlockableContent{
|
|||||||
public EnumSet<BlockFlag> flags = EnumSet.of();
|
public EnumSet<BlockFlag> flags = EnumSet.of();
|
||||||
/** Targeting priority of this block, as seen by enemies.*/
|
/** Targeting priority of this block, as seen by enemies.*/
|
||||||
public TargetPriority priority = TargetPriority.base;
|
public TargetPriority priority = TargetPriority.base;
|
||||||
|
/** How much this block affects the unit cap by.
|
||||||
|
* The block flags must contain unitModifier in order for this to work. */
|
||||||
|
public int unitCapModifier = 0;
|
||||||
/** Whether the block can be tapped and selected to configure. */
|
/** Whether the block can be tapped and selected to configure. */
|
||||||
public boolean configurable;
|
public boolean configurable;
|
||||||
/** Whether this block consumes touchDown events when tapped. */
|
/** Whether this block consumes touchDown events when tapped. */
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
@@ -28,7 +29,8 @@ public class CoreBlock extends StorageBlock{
|
|||||||
solid = true;
|
solid = true;
|
||||||
update = true;
|
update = true;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
flags = EnumSet.of(BlockFlag.core, BlockFlag.producer);
|
flags = EnumSet.of(BlockFlag.core, BlockFlag.producer, BlockFlag.unitModifier);
|
||||||
|
unitCapModifier = 30;
|
||||||
activeSound = Sounds.respawning;
|
activeSound = Sounds.respawning;
|
||||||
activeSoundVolume = 1f;
|
activeSoundVolume = 1f;
|
||||||
}
|
}
|
||||||
@@ -59,6 +61,13 @@ public class CoreBlock extends StorageBlock{
|
|||||||
() -> Pal.items,
|
() -> Pal.items,
|
||||||
() -> e.items().total() / (float)(((CoreEntity)e).storageCapacity * content.items().count(i -> i.type == ItemType.material))
|
() -> e.items().total() / (float)(((CoreEntity)e).storageCapacity * content.items().count(i -> i.type == ItemType.material))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
bars.add("units", e ->
|
||||||
|
new Bar(
|
||||||
|
() -> Core.bundle.format("bar.units", teamIndex.count(e.team()), Units.getCap(e.team())),
|
||||||
|
() -> Pal.power,
|
||||||
|
() -> (float)teamIndex.count(e.team()) / Units.getCap(e.team())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
package mindustry.world.blocks.units;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.graphics.*;
|
|
||||||
import arc.graphics.g2d.*;
|
|
||||||
import arc.scene.style.*;
|
|
||||||
import arc.scene.ui.*;
|
|
||||||
import arc.scene.ui.layout.*;
|
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
|
||||||
import arc.util.io.*;
|
|
||||||
import mindustry.ai.BlockIndexer.*;
|
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.entities.*;
|
|
||||||
import mindustry.entities.units.*;
|
|
||||||
import mindustry.game.EventType.*;
|
|
||||||
import mindustry.gen.*;
|
|
||||||
import mindustry.graphics.*;
|
|
||||||
import mindustry.ui.*;
|
|
||||||
import mindustry.world.*;
|
|
||||||
import mindustry.world.meta.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
|
||||||
|
|
||||||
public class CommandCenter extends Block{
|
|
||||||
protected TextureRegionDrawable[] commandRegions = new TextureRegionDrawable[UnitCommand.all.length];
|
|
||||||
protected Color topColor = Pal.command;
|
|
||||||
protected Color bottomColor = Color.valueOf("5e5e5e");
|
|
||||||
protected Effect effect = Fx.commandSend;
|
|
||||||
|
|
||||||
public CommandCenter(String name){
|
|
||||||
super(name);
|
|
||||||
|
|
||||||
flags = EnumSet.of(BlockFlag.comandCenter);
|
|
||||||
destructible = true;
|
|
||||||
solid = true;
|
|
||||||
configurable = true;
|
|
||||||
config(Integer.class, (tile, value) -> {
|
|
||||||
UnitCommand command = UnitCommand.all[value];
|
|
||||||
((CommandCenter)tile.block()).effect.at(tile);
|
|
||||||
|
|
||||||
for(Tile center : indexer.getAllied(tile.team(), BlockFlag.comandCenter)){
|
|
||||||
if(center.block() instanceof CommandCenter){
|
|
||||||
CommandCenterEntity entity = center.ent();
|
|
||||||
entity.command = command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Groups.unit.each(t -> t.team() == tile.team(), u -> u.controller().command(command));
|
|
||||||
Events.fire(new CommandIssueEvent(tile, command));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(){
|
|
||||||
super.load();
|
|
||||||
|
|
||||||
if(ui != null){
|
|
||||||
for(UnitCommand cmd : UnitCommand.all){
|
|
||||||
commandRegions[cmd.ordinal()] = ui.getIcon("command" + Strings.capitalize(cmd.name()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CommandCenterEntity extends TileEntity{
|
|
||||||
public UnitCommand command = UnitCommand.attack;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(){
|
|
||||||
super.draw();
|
|
||||||
|
|
||||||
float size = 6f;
|
|
||||||
|
|
||||||
Draw.color(bottomColor);
|
|
||||||
Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y - 1, size, size);
|
|
||||||
Draw.color(topColor);
|
|
||||||
Draw.rect(commandRegions[command.ordinal()].getRegion(), x, y, size, size);
|
|
||||||
Draw.color();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void buildConfiguration(Table table){
|
|
||||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
|
||||||
Table buttons = new Table();
|
|
||||||
|
|
||||||
for(UnitCommand cmd : UnitCommand.all){
|
|
||||||
buttons.button(commandRegions[cmd.ordinal()], Styles.clearToggleTransi, () -> configure(cmd.ordinal()))
|
|
||||||
.size(44).group(group).update(b -> b.setChecked(command == cmd));
|
|
||||||
}
|
|
||||||
table.add(buttons);
|
|
||||||
table.row();
|
|
||||||
table.label(() -> command.localized()).style(Styles.outlineLabel).center().growX().get().setAlignment(Align.center);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void placed(){
|
|
||||||
super.placed();
|
|
||||||
TileArray set = indexer.getAllied(team, BlockFlag.comandCenter);
|
|
||||||
|
|
||||||
if(set.size() > 0){
|
|
||||||
CommandCenterEntity oe = set.first().ent();
|
|
||||||
command = oe.command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRemoved(){
|
|
||||||
super.onRemoved();
|
|
||||||
|
|
||||||
TileArray set = indexer.getAllied(team, BlockFlag.comandCenter);
|
|
||||||
|
|
||||||
if(set.size() == 1){
|
|
||||||
Groups.unit.each(t -> t.team() == team, u -> u.controller().command(UnitCommand.all[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer config(){
|
|
||||||
return command.ordinal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(Writes write){
|
|
||||||
super.write(write);
|
|
||||||
write.b(command.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(Reads read, byte revision){
|
|
||||||
super.read(read, revision);
|
|
||||||
command = UnitCommand.all[read.b()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -220,7 +220,7 @@ public class UnitFactory extends Block{
|
|||||||
if(currentPlan != -1){
|
if(currentPlan != -1){
|
||||||
UnitPlan plan = plans[currentPlan];
|
UnitPlan plan = plans[currentPlan];
|
||||||
|
|
||||||
if(progress >= plan.time/* && !Units.anyEntities(tile, !plan.unit.flying)*/){
|
if(progress >= plan.time/* && !Units.anyEntities(tile, !plan.unit.flying)*/ && Units.canCreate(team)){
|
||||||
progress = 0f;
|
progress = 0f;
|
||||||
|
|
||||||
Call.onUnitFactorySpawn(tile);
|
Call.onUnitFactorySpawn(tile);
|
||||||
|
|||||||
@@ -4,18 +4,14 @@ package mindustry.world.meta;
|
|||||||
public enum BlockFlag{
|
public enum BlockFlag{
|
||||||
/** Enemy core; primary target for all units. */
|
/** Enemy core; primary target for all units. */
|
||||||
core,
|
core,
|
||||||
/** Rally point for units.*/
|
|
||||||
rally,
|
|
||||||
/** Producer of important goods. */
|
/** Producer of important goods. */
|
||||||
producer,
|
producer,
|
||||||
/** A turret. */
|
/** A turret. */
|
||||||
turret,
|
turret,
|
||||||
/** Only the command center block.*/
|
|
||||||
comandCenter,
|
|
||||||
/** Repair point. */
|
/** Repair point. */
|
||||||
repair,
|
repair,
|
||||||
/** Upgrade pad. */
|
/** Any block that boosts unit capacity. */
|
||||||
mechPad;
|
unitModifier;
|
||||||
|
|
||||||
public final static BlockFlag[] all = values();
|
public final static BlockFlag[] all = values();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=a9ac74c4165c71b4a2cddffe2d560717b9698d15
|
archash=64304225a74ee3e2c2bd97fd1f23dc4042ba29e2
|
||||||
|
|||||||
Reference in New Issue
Block a user