Skip to content

Commit

Permalink
blood stones
Browse files Browse the repository at this point in the history
  • Loading branch information
sk7725 committed Jan 13, 2021
1 parent 4768d6c commit 2643840
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 21 deletions.
77 changes: 61 additions & 16 deletions src/betamindy/util/XeloUtil.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package betamindy.util;

import arc.func.Boolf;
import arc.func.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.Seq;
import arc.struct.*;
import arc.util.*;
import betamindy.world.blocks.distribution.PistonArm;
import betamindy.world.blocks.distribution.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.gen.*;
Expand Down Expand Up @@ -43,7 +43,13 @@ public void init(){

/** returns whether a building is allowed to be pushed. */
public boolean pushable(Building build){
if(build.dead || (build.block instanceof CoreBlock) || (build.block instanceof PistonArm)) return false;
if(build.dead || (build.block instanceof CoreBlock) || (build.block instanceof PistonArm) || ((build.block instanceof Piston) && ((Piston.PistonBuild)build).extended)) return false;
return true;
}

/** returns whether a building is allowed to be sticked. */
public boolean stickable(Building build){
if(!pushable(build)) return false;
return true;
}

Expand Down Expand Up @@ -123,46 +129,85 @@ private int project(Building build, int direction){
* @param root the building to be scanned from
* @param direction number from 0-4 same direction as the block rotation to push the building in.
* @param max max number of blocks to scan
* @param bool boolf consumer as a custom selection criteria.
* @param bool boolf consumer as a custom selection criteria for pushing.
* @param bool2 boolf consumer as a custom selection criteria for sticking.
*/

public @Nullable Seq<Building> _getAllContacted(Building root, int direction, int max, Boolf<Building> bool){
public @Nullable Seq<Building> _getAllContacted(Building root, int direction, int max, Boolf<Building> bool, Boolf<Building> bool2){
PriorityQueue<Building> queue = new PriorityQueue<Building>(10, (a, b)->{//require ordering to be projection of the block's leading edge along push direction.
return Math.round(project(a, direction) - project(b, direction));
});
queue.add(root);
Seq<Building> contacts = new Seq<Building>();
boolean dirty = false;
while(!queue.isEmpty() && contacts.size <= max){
Building next = queue.poll();
contacts.add(next);
Point2 tangent = d4((direction + 1) % 4);
Point2 o = origins[next.block.size-1][direction];
for(int i=0; i < next.block.size; i++){ // iterate over forward edge.
Tile t = next.tile.nearby(o.x + tangent.x * i + d4(direction).x,o.y + tangent.y * i+ d4(direction).y);
Building b = t.build;
if(b == null || queue.contains(b)|| contacts.contains(b)){continue;}
if(!pushable(b) || !bool.get(b)){
return null; // if a single block cannot be pushed then the entire group cannot be pushed from the root.
if(next.block instanceof SlimeBlock){
// if sticky, iterate over all 4 edges, but for 3 sides, ignore non-sticky blocks
// iterate over forward edge.
for(int i=0; i < next.block.size; i++){
Tile t = next.tile.nearby(o.x + tangent.x * i + d4(direction).x,o.y + tangent.y * i+ d4(direction).y);
Building b = t.build;
if(b == null || queue.contains(b)|| contacts.contains(b)){continue;}
if(!pushable(b) || !bool.get(b)){
return null; // if a single block cannot be pushed then the entire group cannot be pushed from the root.
}
queue.add(b);
}
for(int k=0; k < 3; k++){
// iterate over a side edge
int td = (direction + k + 1) % 4;
tangent = d4((td + 1) % 4);
o = origins[next.block.size-1][td];
for(int i=0; i < next.block.size; i++){
Tile t = next.tile.nearby(o.x + tangent.x * i + d4(td).x,o.y + tangent.y * i+ d4(td).y);
Building b = t.build;
if(b == null || queue.contains(b)|| contacts.contains(b)){continue;}
if(!stickable(b) || !bool2.get(b) || !bool.get(b)){
continue; // ignore blocks that refuse to stick.
}
// contacts is not ordered; sort at the end
if(k == 1) dirty = true;
queue.add(b);

}
}
}
else{
// iterate over forward edge.
for(int i=0; i < next.block.size; i++){
Tile t = next.tile.nearby(o.x + tangent.x * i + d4(direction).x,o.y + tangent.y * i+ d4(direction).y);
Building b = t.build;
if(b == null || queue.contains(b)|| contacts.contains(b)){continue;}
if(!pushable(b) || !bool.get(b)){
return null; // if a single block cannot be pushed then the entire group cannot be pushed from the root.
}
queue.add(b);
}
queue.add(b);
}
}
if(contacts.size<=max){
if(dirty){
contacts.sort((a, b) -> Math.round(project(a, direction) - project(b, direction)));
}
return contacts;
}else{
return null;
}
}

/** pushes a single building and pushes all blocks behind the pushed block., unlike the previous. */
public boolean pushBlock(Building build, int direction, int maxBlocks){
@Nullable Seq<Building> pushing = _getAllContacted(build, direction, maxBlocks, b -> true);
public boolean pushBlock(Building build, int direction, int maxBlocks, Boolf<Building> boolPush, Boolf<Building> boolStick){
@Nullable Seq<Building> pushing = _getAllContacted(build, direction, maxBlocks, boolPush, boolStick);
if(pushing == null){
return false;
}
//scan in reverse
for(int i = pushing.size - 1; i >= 0; i--){
if(!canPush(pushing.get(i),direction)){
if(!canPush(pushing.get(i), direction)){
return false;
}
}
Expand Down
16 changes: 12 additions & 4 deletions src/betamindy/world/blocks/distribution/Piston.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package betamindy.world.blocks.distribution;

import arc.audio.Sound;
import arc.func.*;
import arc.graphics.g2d.*;
import arc.math.geom.Geometry;
import arc.util.*;
import betamindy.BetaMindy;
import betamindy.content.MindySounds;
import mindustry.content.Blocks;
import mindustry.gen.Building;
import mindustry.type.Category;
import mindustry.world.*;
Expand All @@ -26,6 +28,8 @@ public class Piston extends Block {
public Sound pushSound = MindySounds.pistonPush, pullSound = MindySounds.pistonPull;

public static final float extendTicks = 8f;
public final Boolf<Building> pushBool = b -> !(b.block == Blocks.thoriumWall || b.block == Blocks.thoriumWallLarge);
public final Boolf<Building> stickBool = b -> !(b.block == Blocks.phaseWall || b.block == Blocks.phaseWallLarge);

public Piston(String name){
super(name);
Expand Down Expand Up @@ -95,15 +99,19 @@ public void pullBuild(Building tile, int r){

/** Tries to push blocks and returns its success*/
public boolean push(){
if(tile.nearbyBuild(rotation) == null) return true;
return BetaMindy.pushUtil.pushBlock(tile.nearbyBuild(rotation), rotation, maxBlocks);
if(tile.nearby(rotation) == null) return false;
if(tile.nearbyBuild(rotation) == null) return tile.nearby(rotation).block() == Blocks.air;
if(!pushBool.get(tile.nearbyBuild(rotation))) return false;
return BetaMindy.pushUtil.pushBlock(tile.nearbyBuild(rotation), rotation, maxBlocks, b -> (b != this && pushBool.get(b)), stickBool);
}
/** Tries to pull blocks and returns its success*/
public boolean pull(){
//TODO: temp
if(tile.nearby(rotation) == null || tile.nearby(rotation).nearbyBuild(rotation) == null) return true;
if(tile.nearby(rotation).block() == armBlock) tile.nearby(rotation).remove();
//pullBuild(tile.nearby(rotation).nearbyBuild(rotation), rotation);
Building pullb = tile.nearby(rotation).nearbyBuild(rotation);
if(!stickBool.get(pullb) || !pushBool.get(pullb)) return true;
//does not care if it actually succeeds to push
BetaMindy.pushUtil.pushBlock(pullb, (rotation + 2) % 4, maxBlocks, b -> (b != this && pushBool.get(b)), stickBool);
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/betamindy/world/blocks/power/AccelBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public float getPowerProduction(){
else{
lastpower = wasMoved(rotation % 2);
ballTimer.reset(powercheckid, 0);
return lastpower ? powerProduction : 0f;
return !ballTimer.check(ballid, 9f) ? powerProduction : 0f;
}
}

Expand Down

0 comments on commit 2643840

Please sign in to comment.