8000 Implement blocks filter & refactor regions by Pablete1234 · Pull Request #1076 · PGMDev/PGM · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Implement blocks filter & refactor regions #1076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 84 additions & 19 deletions core/src/main/java/tc/oc/pgm/api/region/Region.java
10000
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package tc.oc.pgm.api.region;

import com.google.common.collect.Iterators;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Random;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
Expand All @@ -13,44 +20,68 @@
import tc.oc.pgm.api.filter.query.LocationQuery;
import tc.oc.pgm.filters.matcher.TypedFilter;
import tc.oc.pgm.regions.Bounds;
import tc.oc.pgm.util.block.BlockVectors;
import tc.oc.pgm.util.event.PlayerCoarseMoveEvent;

/** Represents an arbitrary region in a Bukkit world. */
public interface Region extends TypedFilter<LocationQuery> {
/** Test if the region contains the given point */
boolean contains(Vector point);

/** Test if the region contains the given point */
boolean contains(Location point);
default boolean contains(Location point) {
return this.contains(point.toVector());
}

/** Test if the region contains the center of the given block */
boolean contains(BlockVector pos);
default boolean contains(BlockVector blockPos) {
return this.contains((Vector) BlockVectors.center(blockPos));
}

/** Test if the region contains the center of the given block */
boolean contains(Block block);
default boolean contains(Block block) {
return this.contains(BlockVectors.center(block));
}

/** Test if the region contains the center of the given block */
boolean contains(BlockState block);
default boolean contains(BlockState block) {
return this.contains(BlockVectors.center(block));
}

/** Test if the region contains the given entity */
boolean contains(Entity entity);
default boolean contains(Entity entity) {
return this.contains(entity.getLocation().toVector());
}

/** Test if the region contains the queried location */
boolean contains(LocationQuery query);
default boolean contains(LocationQuery query) {
return this.contains(query.getBlockCenter());
}

/** Test if moving from the first point to the second crosses into the region */
boolean enters(Location from, Location to);
default boolean enters(Location from, Location to) {
return !this.contains(from) && this.contains(to);
}

/** Test if moving from the first point to the second crosses into the region */
boolean enters(Vector from, Vector to);
default boolean enters(Vector from, Vector to) {
return !this.contains(from) && this.contains(to);
}

/** Test if moving from the first point to the second crosses out of the region */
boolean exits(Location from, Location to);
default boolean exits(Location from, Location to) {
return this.contains(from) && !this.contains(to);
}

/** Test if moving from the first point to the second crosses out of the region */
boolean exits(Vector from, Vector to);
default boolean exits(Vector from, Vector to) {
return this.contains(from) && !this.contains(to);
}

/** Can this region generate evenly distributed random points? */
boolean canGetRandom();
default boolean canGetRandom() {
return false;
}

/**
* Gets a random point contained within this region.
Expand All @@ -59,10 +90,15 @@ public interface Region extends TypedFilter<LocationQuery> {
* @return Random point within this region.
* @throws UnsupportedOperationException if this region cannot generate random points
*/
Vector getRandom(Random random);
default Vector getRandom(Random random) {
throw new UnsupportedOperationException(
"Cannot generate a random point in " + this.getClass().getSimpleName());
}

/** Does this region contain a finite number of blocks? */
boolean isBlockBounded();
default boolean isBlockBounded() {
return false;
}

/** @return The smallest cuboid that entirely contains this region */
Bounds getBounds();
Expand All @@ -71,16 +107,45 @@ public interface Region extends TypedFilter<LocationQuery> {
* Return true if the region is definitely empty, false if it may or may not be empty. This is
* just used for optimization, so don't do anything expensive to try and return true.
*/
boolean isEmpty();
default boolean isEmpty() {
return false;
}

@Override
default Collection<Class<? extends Event>> getRelevantEvents() {
return Collections.singleton(PlayerCoarseMoveEvent.class);
}

@Override
default Class<? extends LocationQuery> queryType() {
return LocationQuery.class;
}

@Override
default boolean matches(LocationQuery query) {
return contains(query);
}

/**
* Iterate over all the blocks inside this region.
*
* @throws UnsupportedOperationException if the region's blocks are not enumerable
*/
public Iterator<BlockVector> getBlockVectorIterator();

public Iterable<BlockVector> getBlockVectors();

public Collection<Class<? extends Event>> getRelevantEvents();
default Iterator<BlockVector> getBlockVectorIterator() {
return Iterators.filter(this.getBounds().getBlockIterator(), this::contains);
}

default Iterable<BlockVector> getBlockVectors() {
return this::getBlockVectorIterator;
}

default Stream<BlockVector> getBlockPositions() {
return StreamSupport.stream(
Spliterato 6D4E rs.spliterator(getBlockVectorIterator(), 0, Spliterator.ORDERED), false);
}

default Iterable<Block> getBlocks(World world) {
return () ->
Iterators.transform(getBlockVectorIterator(), pos -> BlockVectors.blockAt(world, pos));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.util.BlockVector;
import org.jetbrains.annotations.Nullable;
import tc.oc.pgm.api.filter.Filter;
import tc.oc.pgm.api.filter.query.Query;
Expand Down Expand Up @@ -46,7 +46,7 @@ public ImmutableList<BlockDropsRule> getRules() {
public BlockDropsRuleSet subsetAffecting(FiniteBlockRegion region) {
ImmutableList.Builder<BlockDropsRule> subset = ImmutableList.builder();
for (BlockDropsRule rule : this.rules) {
for (Block block : region.getBlocks()) {
for (BlockVector block : region.getBlockVectors()) {
if (rule.region == null || rule.region.contains(block)) {
subset.add(rule);
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package tc.oc.pgm.controlpoint;

import com.google.common.collect.Lists;
import java.util.List;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
import tc.oc.pgm.api.filter.Filter;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.party.Competitor;
import tc.oc.pgm.api.region.Region;
import tc.oc.pgm.controlpoint.events.CapturingTimeChangeEvent;
import tc.oc.pgm.controlpoint.events.ControllerChangeEvent;
import tc.oc.pgm.filters.operator.AllFilter;
import tc.oc.pgm.filters.operator.InverseFilter;
import tc.oc.pgm.filters.query.BlockQuery;
import tc.oc.pgm.regions.FiniteBlockRegion;
import tc.oc.pgm.regions.SectorRegion;
import tc.oc.pgm.renewable.BlockImage;
import tc.oc.pgm.util.block.BlockVectors;

/** Displays the status of a ControlPoint by coloring blocks in specified regions */
public class ControlPointBlockDisplay implements Listener {
Expand Down Expand Up @@ -54,21 +56,17 @@ public ControlPointBlockDisplay(Match match, ControlPoint controlPoint) {
this.controllerDisplayRegion = null;
this.controllerDisplayImage = null;
} else {
FiniteBlockRegion unfilteredControllerDisplayRegion =
Filter controllerDisplayFilter =
this.progressDisplayRegion == null
? visualMaterials
: AllFilter.of(visualMaterials, new InverseFilter(progressDisplayRegion));

this.controllerDisplayRegion =
FiniteBlockRegion.fromWorld(
controllerDisplayRegion,
match.getWorld(),
visualMaterials,
controllerDisplayFilter,
match.getMap().getProto());

// Ensure the controller and progress display regions do not overlap. The progress display has
// priority.
List<Block> filteredControllerBlocks =
Lists.newArrayList(unfilteredControllerDisplayRegion.getBlocks());
if (this.progressDisplayRegion != null) {
filteredControllerBlocks.removeAll(this.progressDisplayRegion.getBlocks());
}
this.controllerDisplayRegion = new FiniteBlockRegion(filteredControllerBlocks);
this.controllerDisplayImage =
new BlockImage(match.getWorld(), this.controllerDisplayRegion.getBounds());
this.controllerDisplayImage.save();
Expand All @@ -82,21 +80,22 @@ public ControlPointBlockDisplay(Match match, ControlPoint controlPoint) {
public void setController(Competitor controllingTeam) {
if (this.controllingTeam != controllingTeam && this.controllerDisplayRegion != null) {
if (controllingTeam == null) {
for (Block block : this.controllerDisplayRegion.getBlocks()) {
for (BlockVector block : this.controllerDisplayRegion.getBlockVectors()) {
this.controllerDisplayImage.restore(block);
}
} else {
byte blockData = controllingTeam.getDyeColor().getWoolData();
for (Block block : this.controllerDisplayRegion.getBlocks()) {
block.setData(blockData);
for (BlockVector pos : this.controllerDisplayRegion.getBlockVectors()) {
BlockVectors.blockAt(match.getWorld(), pos).setData(blockData);
}
}
this.controllingTeam = controllingTeam;
}
}

@SuppressWarnings("deprecation")
private void setBlock(Block block, Competitor team) {
private void setBlock(BlockVector pos, Competitor team) {
final Block block = BlockVectors.blockAt(match.getWorld(), pos);
if (this.controlPoint
.getDefinition()
.getVisualMaterials()
Expand All @@ -120,11 +119,11 @@ protected void setProgress(
SectorRegion sectorRegion =
new SectorRegion(center.getX(), center.getZ(), 0, (1 - capturingProgress) * 2 * Math.PI);

for (Block block : this.progressDisplayRegion.getBlocks()) {
if (sectorRegion.contains(block.getLocation().toVector())) {
this.setBlock(block, controllingTeam);
for (BlockVector pos : this.progressDisplayRegion.getBlockVectors()) {
if (sectorRegion.contains(pos)) {
this.setBlock(pos, controllingTeam);
} else {
this.setBlock(block, capturingTeam);
this.setBlock(pos, capturingTeam);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/tc/oc/pgm/core/Core.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public Core(CoreFactory definition, Match match) {
match.getWorld(),
match.getMap().getProto(),
new SingleMaterialMatcher(this.material));
if (this.casingRegion.getBlocks().isEmpty()) {
if (this.casingRegion.getBlockVolume() == 0) {
match
.getLogger()
.warning("No casing world (" + this.material + ") found in core " + this.getName());
Expand All @@ -78,7 +78,7 @@ public Core(CoreFactory definition, Match match) {
match.getMap().getProto(),
new SingleMaterialMatcher(Material.LAVA, (byte) 0),
new SingleMaterialMatcher(Material.STATIONARY_LAVA, (byte) 0));
if (this.lavaRegion.getBlocks().isEmpty()) {
if (this.lavaRegion.getBlockVolume() == 0) {
match.getLogger().warning("No lava found in core " + this.getName());
}

Expand Down Expand Up @@ -232,7 +232,7 @@ public String renderSidebarStatusText(@Nullable Competitor competitor, Party vie
@Override
@SuppressWarnings("deprecation")
public void replaceBlocks(MaterialData newMaterial) {
for (Block block : this.getCasingRegion().getBlocks()) {
for (Block block : this.getCasingRegion().getBlocks(match.getWorld())) {
if (this.isObjectiveMaterial(block)) {
block.setTypeIdAndData(newMaterial.getItemTypeId(), newMaterial.getData(), true);
}
Expand Down
12 changes: 6 additions & 6 deletions core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public Destroyable(DestroyableFactory definition, Match match) {
match.getWorld(),
this.materialPatterns,
match.getMap().getProto());
if (this.blockRegion.getBlocks().isEmpty()) {
if (this.blockRegion.getBlockVolume() == 0) {
match.getLogger().warning("No destroyable blocks found in destroyable " + this.getName());
}

Expand Down Expand Up @@ -199,9 +199,9 @@ protected void recalculateHealth() {
this.buildMaterialHealthMap();
} else {
this.blockMaterialHealth = null;
this.maxHealth = this.blockRegion.getBlocks().size();
this.maxHealth = this.blockRegion.getBlockVolume();
this.health = 0;
for (Block block : this.blockRegion.getBlocks()) {
for (Bloc B0DD k block : this.blockRegion.getBlocks(match.getWorld())) {
if (this.hasMaterial(block.getState().getData())) {
this.health++;
}
Expand All @@ -214,7 +214,7 @@ protected boolean isAffectedByBlockReplacementRules() {
return false;
}

for (Block block : this.blockRegion.getBlocks()) {
for (Block block : this.blockRegion.getBlocks(match.getWorld())) {
for (MaterialData material : this.materials) {
BlockDrops drops = this.blockDropsRuleSet.getDrops(block.getState(), material);
if (drops != null && drops.replacement != null && this.hasMaterial(drops.replacement)) {
Expand All @@ -234,7 +234,7 @@ protected void buildMaterialHealthMap() {
this.health = 0;
Set<MaterialData> visited = new HashSet<>();
try {
for (Block block : blockRegion.getBlocks()) {
for (Block block : blockRegion.getBlocks(match.getWorld())) {
Map<MaterialData, Integer> materialHealthMap = new HashMap<>();
int blockMaxHealth = 0;

Expand Down Expand Up @@ -612,7 +612,7 @@ public void replaceBlocks(MaterialData newMaterial) {
// of the destroyable: individual block health can only decrease, while the total health
// percentage can only increase.

for (Block block : this.getBlockRegion().getBlocks()) {
for (Block block : this.getBlockRegion().getBlocks(match.getWorld())) {
BlockState oldState = block.getState();
int oldHealth = this.getBlockHealth(oldState);

Expand Down
Loading
0