Placement config code cleanup
This commit is contained in:
@@ -49,11 +49,7 @@ public class BuilderAI extends AIController{
|
||||
blocks.removeFirst();
|
||||
}else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid.
|
||||
//add build request.
|
||||
BuildPlan req = new BuildPlan(block.x, block.y, block.rotation, content.block(block.block));
|
||||
if(block.config != null){
|
||||
req.configure(block.config);
|
||||
}
|
||||
builder.addBuild(req);
|
||||
builder.addBuild(new BuildPlan(block.x, block.y, block.rotation, content.block(block.block), block.config));
|
||||
}else{
|
||||
//shift head of queue to tail, try something else next time
|
||||
blocks.removeFirst();
|
||||
|
||||
@@ -325,7 +325,7 @@ public class UnitTypes implements ContentList{
|
||||
mineSpeed = 7f;
|
||||
drawShields = false;
|
||||
|
||||
abilities.add(new ForceFieldAbility(60f, 0.2f, 300f, 60f * 7));
|
||||
abilities.add(new ForceFieldAbility(60f, 0.3f, 400f, 60f * 6));
|
||||
|
||||
weapons.add(new Weapon("beam-weapon"){{
|
||||
shake = 2f;
|
||||
|
||||
@@ -110,11 +110,7 @@ abstract class BuilderComp implements Unitc{
|
||||
if(current.breaking){
|
||||
entity.deconstruct(base(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier);
|
||||
}else{
|
||||
if(entity.construct(base(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier, current.hasConfig)){
|
||||
if(current.hasConfig){
|
||||
Call.tileConfig(null, tile.build, current.config);
|
||||
}
|
||||
}
|
||||
entity.construct(base(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier, current.config);
|
||||
}
|
||||
|
||||
current.stuck = Mathf.equal(current.progress, entity.progress);
|
||||
|
||||
@@ -813,9 +813,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
/** Called after the block is placed by this client. */
|
||||
@CallSuper
|
||||
public void playerPlaced(){
|
||||
if(block.saveConfig && block.lastConfig != null){
|
||||
configure(block.lastConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Called after the block is placed by anyone. */
|
||||
@@ -856,7 +854,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
|
||||
/** Called when arbitrary configuration is applied to a tile. */
|
||||
public void configured(@Nullable Player player, @Nullable Object value){
|
||||
public void configured(@Nullable Unit builder, @Nullable Object value){
|
||||
//null is of type void.class; anonymous classes use their superclass.
|
||||
Class<?> type = value == null ? void.class : value.getClass().isAnonymousClass() ? value.getClass().getSuperclass() : value.getClass();
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ public class BuildPlan{
|
||||
public @Nullable Block block;
|
||||
/** Whether this is a break request.*/
|
||||
public boolean breaking;
|
||||
/** Whether this request comes with a config int. If yes, any blocks placed with this request will not call playerPlaced.*/
|
||||
public boolean hasConfig;
|
||||
/** Config int. Not used unless hasConfig is true.*/
|
||||
public Object config;
|
||||
/** Original position, only used in schematics.*/
|
||||
@@ -40,6 +38,16 @@ public class BuildPlan{
|
||||
this.breaking = false;
|
||||
}
|
||||
|
||||
/** This creates a build request with a config. */
|
||||
public BuildPlan(int x, int y, int rotation, Block block, Object config){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.block = block;
|
||||
this.breaking = false;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/** This creates a remove request. */
|
||||
public BuildPlan(int x, int y){
|
||||
this.x = x;
|
||||
@@ -84,7 +92,6 @@ public class BuildPlan{
|
||||
copy.rotation = rotation;
|
||||
copy.block = block;
|
||||
copy.breaking = breaking;
|
||||
copy.hasConfig = hasConfig;
|
||||
copy.config = config;
|
||||
copy.originalX = originalX;
|
||||
copy.originalY = originalY;
|
||||
@@ -127,12 +134,6 @@ public class BuildPlan{
|
||||
return y*tilesize + block.offset;
|
||||
}
|
||||
|
||||
public BuildPlan configure(Object config){
|
||||
this.config = config;
|
||||
this.hasConfig = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @Nullable Tile tile(){
|
||||
return world.tile(x, y);
|
||||
}
|
||||
|
||||
@@ -224,12 +224,14 @@ public class EventType{
|
||||
public final Team team;
|
||||
public final @Nullable Unit unit;
|
||||
public final boolean breaking;
|
||||
public final @Nullable Object config;
|
||||
|
||||
public BlockBuildEndEvent(Tile tile, @Nullable Unit unit, Team team, boolean breaking){
|
||||
public BlockBuildEndEvent(Tile tile, @Nullable Unit unit, Team team, boolean breaking, @Nullable Object config){
|
||||
this.tile = tile;
|
||||
this.team = team;
|
||||
this.unit = unit;
|
||||
this.breaking = breaking;
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ public class Schematics implements Loadable{
|
||||
Draw.rect(Tmp.tr1, buffer.getWidth()/2f, buffer.getHeight()/2f, buffer.getWidth(), -buffer.getHeight());
|
||||
Draw.color();
|
||||
|
||||
Seq<BuildPlan> requests = schematic.tiles.map(t -> new BuildPlan(t.x, t.y, t.rotation, t.block).configure(t.config));
|
||||
Seq<BuildPlan> requests = schematic.tiles.map(t -> new BuildPlan(t.x, t.y, t.rotation, t.block, t.config));
|
||||
|
||||
Draw.flush();
|
||||
//scale each request to fit schematic
|
||||
@@ -278,7 +278,7 @@ public class Schematics implements Loadable{
|
||||
|
||||
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
||||
public Seq<BuildPlan> toRequests(Schematic schem, int x, int y){
|
||||
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config))
|
||||
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block, t.config).original(t.x, t.y, schem.width, schem.height))
|
||||
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedNow());
|
||||
}
|
||||
|
||||
|
||||
@@ -215,11 +215,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
|
||||
@Remote(targets = Loc.both, called = Loc.both, forward = true)
|
||||
public static void tileConfig(Player player, Building tile, @Nullable Object value){
|
||||
public static void tileConfig(@Nullable Player player, Building tile, @Nullable Object value){
|
||||
if(tile == null) return;
|
||||
if(net.server() && (!Units.canInteract(player, tile) ||
|
||||
!netServer.admins.allowAction(player, ActionType.configure, tile.tile(), action -> action.config = value))) throw new ValidateException(player, "Player cannot configure a tile.");
|
||||
tile.configured(player, value);
|
||||
tile.configured(player == null || player.dead() ? null : player.unit(), value);
|
||||
Core.app.post(() -> Events.fire(new ConfigEvent(tile, player, value)));
|
||||
}
|
||||
|
||||
@@ -645,13 +645,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
protected void drawRequest(BuildPlan request){
|
||||
request.block.drawRequest(request, allRequests(), validPlace(request.x, request.y, request.block, request.rotation));
|
||||
|
||||
if(request.block.saveConfig && request.block.lastConfig != null && !request.hasConfig){
|
||||
Object conf = request.config;
|
||||
request.config = request.block.lastConfig;
|
||||
request.block.drawRequestConfig(request, allRequests());
|
||||
request.config = conf;
|
||||
}
|
||||
}
|
||||
|
||||
/** Draws a placement icon for a specific block. */
|
||||
@@ -720,7 +713,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
lineRequests.clear();
|
||||
iterateLine(x1, y1, x2, y2, l -> {
|
||||
rotation = l.rotation;
|
||||
BuildPlan req = new BuildPlan(l.x, l.y, l.rotation, block);
|
||||
BuildPlan req = new BuildPlan(l.x, l.y, l.rotation, block, block.nextConfig());
|
||||
req.animScale = 1f;
|
||||
lineRequests.add(req);
|
||||
});
|
||||
@@ -993,13 +986,12 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(req != null){
|
||||
player.builder().plans().remove(req);
|
||||
}
|
||||
player.builder().addBuild(new BuildPlan(x, y, rotation, block));
|
||||
player.builder().addBuild(new BuildPlan(x, y, rotation, block, block.nextConfig()));
|
||||
}
|
||||
|
||||
public void breakBlock(int x, int y){
|
||||
Tile tile = world.tile(x, y);
|
||||
//TODO hacky
|
||||
if(tile != null && tile.build != null) tile = tile.build.tile();
|
||||
if(tile != null && tile.build != null) tile = tile.build.tile;
|
||||
player.builder().addBuild(new BuildPlan(tile.x, tile.y));
|
||||
}
|
||||
|
||||
|
||||
@@ -569,7 +569,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
removeRequest(getRequest(cursor));
|
||||
}else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, block, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, block)){
|
||||
//add to selection queue if it's a valid place position
|
||||
selectRequests.add(lastPlaced = new BuildPlan(cursor.x, cursor.y, rotation, block));
|
||||
selectRequests.add(lastPlaced = new BuildPlan(cursor.x, cursor.y, rotation, block, block.nextConfig()));
|
||||
}else if(mode == breaking && validBreak(linked.x,linked.y) && !hasRequest(linked)){
|
||||
//add to selection queue if it's a valid BREAK position
|
||||
selectRequests.add(new BuildPlan(linked.x, linked.y));
|
||||
|
||||
@@ -231,7 +231,7 @@ public class TypeIO{
|
||||
if(!request.breaking){
|
||||
write.s(request.block.id);
|
||||
write.b((byte)request.rotation);
|
||||
write.b(request.hasConfig ? (byte)1 : 0);
|
||||
write.b(1); //always has config
|
||||
writeObject(write, request.config);
|
||||
}
|
||||
}
|
||||
@@ -254,8 +254,9 @@ public class TypeIO{
|
||||
boolean hasConfig = read.b() == 1;
|
||||
Object config = readObject(read);
|
||||
currentRequest = new BuildPlan(Point2.x(position), Point2.y(position), rotation, content.block(block));
|
||||
//should always happen, but is kept for legacy reasons just in case
|
||||
if(hasConfig){
|
||||
currentRequest.configure(config);
|
||||
currentRequest.config = config;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,21 +27,10 @@ public class Administration{
|
||||
|
||||
/** All player info. Maps UUIDs to info. This persists throughout restarts. Do not access directly. */
|
||||
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
|
||||
private IntIntMap lastPlaced = new IntIntMap();
|
||||
|
||||
public Administration(){
|
||||
load();
|
||||
|
||||
Events.on(ResetEvent.class, e -> lastPlaced = new IntIntMap());
|
||||
|
||||
//keep track of who placed what on the server
|
||||
Events.on(BlockBuildEndEvent.class, e -> {
|
||||
//players should be able to configure their own tiles
|
||||
if(net.server() && e.unit != null && e.unit.isPlayer()){
|
||||
lastPlaced.put(e.tile.pos(), e.unit.getPlayer().id());
|
||||
}
|
||||
});
|
||||
|
||||
//anti-spam
|
||||
addChatFilter((player, message) -> {
|
||||
long resetTime = Config.messageRateLimit.num() * 1000;
|
||||
@@ -80,12 +69,6 @@ public class Administration{
|
||||
action.type != ActionType.placeBlock &&
|
||||
Config.antiSpam.bool()){
|
||||
|
||||
//make sure players can configure their own stuff, e.g. in schematics - but only once.
|
||||
if(lastPlaced.get(action.tile.pos(), -1) == action.player.id()){
|
||||
lastPlaced.remove(action.tile.pos());
|
||||
return true;
|
||||
}
|
||||
|
||||
Ratekeeper rate = action.player.getInfo().rate;
|
||||
if(rate.allow(Config.interactRateWindow.num() * 1000, Config.interactRateLimit.num())){
|
||||
return true;
|
||||
@@ -93,13 +76,6 @@ public class Administration{
|
||||
if(rate.occurences > Config.interactRateKick.num()){
|
||||
action.player.kick("You are interacting with too many blocks.", 1000 * 30);
|
||||
}else if(action.player.getInfo().messageTimer.get(60f * 2f)){
|
||||
|
||||
//I don't know what causes this so I'll make it log an error instead
|
||||
new Exception("!!REPORT TO ANUKE: " + action.player.name + " was (likely) incorrectly ratelimited. " +
|
||||
"action=" + action.type +
|
||||
" player=" + action.player.name + "#" + action.player.id +
|
||||
" tile=" + action.tile).printStackTrace();
|
||||
|
||||
action.player.sendMessage("[scarlet]You are interacting with blocks too quickly.");
|
||||
}
|
||||
|
||||
|
||||
@@ -374,6 +374,13 @@ public class Block extends UnlockableContent{
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object nextConfig(){
|
||||
if(saveConfig && lastConfig != null){
|
||||
return lastConfig;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void drawRequest(BuildPlan req, Eachable<BuildPlan> list, boolean valid){
|
||||
Draw.reset();
|
||||
Draw.mixcol(!valid ? Pal.breakInvalid : Color.white, (!valid ? 0.4f : 0.24f) + Mathf.absin(Time.globalTime(), 6f, 0.28f));
|
||||
@@ -389,7 +396,7 @@ public class Block extends UnlockableContent{
|
||||
TextureRegion reg = getRequestRegion(req, list);
|
||||
Draw.rect(reg, req.drawx(), req.drawy(), !rotate ? 0 : req.rotation * 90);
|
||||
|
||||
if(req.hasConfig){
|
||||
if(req.config != null){
|
||||
drawRequestConfig(req, list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,26 +48,35 @@ public class BuildBlock extends Block{
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void deconstructFinish(Tile tile, Block block, int builderID){
|
||||
public static void deconstructFinish(Tile tile, Block block, Unit builder){
|
||||
Team team = tile.team();
|
||||
Fx.breakBlock.at(tile.drawx(), tile.drawy(), block.size);
|
||||
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, true));
|
||||
Events.fire(new BlockBuildEndEvent(tile, builder, team, true, null));
|
||||
tile.remove();
|
||||
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
public static void constructFinish(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
||||
public static void constructFinish(Tile tile, Block block, Unit builder, byte rotation, Team team, Object config){
|
||||
if(tile == null) return;
|
||||
|
||||
float healthf = tile.build == null ? 1f : tile.build.healthf();
|
||||
|
||||
tile.setBlock(block, team, rotation);
|
||||
if(tile.build != null) tile.build.health = block.health * healthf;
|
||||
//last builder was this local client player, call placed()
|
||||
if(tile.build != null && !headless && builderID == player.unit().id()){
|
||||
if(!skipConfig){
|
||||
tile.build.playerPlaced();
|
||||
|
||||
if(tile.build != null){
|
||||
tile.build.health = block.health * healthf;
|
||||
|
||||
if(config != null){
|
||||
tile.build.configured(builder, config);
|
||||
}
|
||||
}
|
||||
|
||||
//last builder was this local client player, call placed()
|
||||
if(tile.build != null && !headless && builder == player.unit()){
|
||||
tile.build.playerPlaced();
|
||||
}
|
||||
|
||||
Fx.placeBlock.at(tile.drawx(), tile.drawy(), block.size);
|
||||
}
|
||||
|
||||
@@ -95,11 +104,11 @@ public class BuildBlock extends Block{
|
||||
}
|
||||
}
|
||||
|
||||
public static void constructed(Tile tile, Block block, int builderID, byte rotation, Team team, boolean skipConfig){
|
||||
Call.constructFinish(tile, block, builderID, rotation, team, skipConfig);
|
||||
public static void constructed(Tile tile, Block block, Unit builder, byte rotation, Team team, Object config){
|
||||
Call.constructFinish(tile, block, builder, rotation, team, config);
|
||||
tile.build.placed();
|
||||
|
||||
Events.fire(new BlockBuildEndEvent(tile, Groups.unit.getByID(builderID), team, false));
|
||||
Events.fire(new BlockBuildEndEvent(tile, builder, team, false, config));
|
||||
if(shouldPlay()) Sounds.place.at(tile, calcPitch(true));
|
||||
}
|
||||
|
||||
@@ -122,7 +131,7 @@ public class BuildBlock extends Block{
|
||||
* If a non-recipe block is being deconstructed, this is the block that is being deconstructed.
|
||||
*/
|
||||
public Block previous;
|
||||
public int builderID = -1;
|
||||
public Object lastConfig;
|
||||
|
||||
private float[] accumulator;
|
||||
private float[] totalAccumulator;
|
||||
@@ -154,7 +163,7 @@ public class BuildBlock extends Block{
|
||||
if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){
|
||||
control.input.isBuilding = true;
|
||||
}
|
||||
player.builder().addBuild(new BuildPlan(tile.x, tile.y, rotation, cblock), false);
|
||||
player.builder().addBuild(new BuildPlan(tile.x, tile.y, rotation, cblock, lastConfig), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,12 +199,14 @@ public class BuildBlock extends Block{
|
||||
});
|
||||
}
|
||||
|
||||
public boolean construct(Unit builder, @Nullable Building core, float amount, boolean configured){
|
||||
public void construct(Unit builder, @Nullable Building core, float amount, Object config){
|
||||
if(cblock == null){
|
||||
kill();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
lastConfig = config;
|
||||
|
||||
if(cblock.requirements.length != accumulator.length || totalAccumulator.length != cblock.requirements.length){
|
||||
setConstruct(previous, cblock);
|
||||
}
|
||||
@@ -211,16 +222,13 @@ public class BuildBlock extends Block{
|
||||
maxProgress = core == null || team.rules().infiniteResources ? maxProgress : checkRequired(core.items, maxProgress, true);
|
||||
|
||||
progress = Mathf.clamp(progress + maxProgress);
|
||||
builderID = builder.id;
|
||||
|
||||
if(progress >= 1f || state.rules.infiniteResources){
|
||||
constructed(tile, cblock, builderID, (byte)rotation, builder.team, configured);
|
||||
return true;
|
||||
constructed(tile, cblock, builder, (byte)rotation, builder.team, config);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void deconstruct(Unitc builder, @Nullable Building core, float amount){
|
||||
public void deconstruct(Unit builder, @Nullable Building core, float amount){
|
||||
float deconstructMultiplier = state.rules.deconstructRefundMultiplier;
|
||||
|
||||
if(cblock != null){
|
||||
@@ -253,10 +261,8 @@ public class BuildBlock extends Block{
|
||||
|
||||
progress = Mathf.clamp(progress - amount);
|
||||
|
||||
builderID = builder.id();
|
||||
|
||||
if(progress <= 0 || state.rules.infiniteResources){
|
||||
Call.deconstructFinish(tile, this.cblock == null ? previous : this.cblock, builderID);
|
||||
Call.deconstructFinish(tile, this.cblock == null ? previous : this.cblock, builder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class Sorter extends Block{
|
||||
public @Nullable Item sortItem;
|
||||
|
||||
@Override
|
||||
public void configured(Player player, Object value){
|
||||
public void configured(Unit player, Object value){
|
||||
super.configured(player, value);
|
||||
|
||||
if(!headless){
|
||||
|
||||
Reference in New Issue
Block a user