ProjectAres/PGM/src/main/java/tc/oc/pgm/core/Core.java

193 lines
6.5 KiB
Java

package tc.oc.pgm.core;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.material.MaterialData;
import org.bukkit.util.Vector;
import tc.oc.commons.core.chat.Components;
import tc.oc.commons.bukkit.chat.NameStyle;
import tc.oc.pgm.match.Competitor;
import tc.oc.pgm.match.Match;
import tc.oc.pgm.match.MatchPlayerState;
import tc.oc.pgm.match.ParticipantState;
import tc.oc.pgm.goals.ModeChangeGoal;
import tc.oc.pgm.goals.TouchableGoal;
import tc.oc.pgm.regions.CuboidRegion;
import tc.oc.pgm.regions.FiniteBlockRegion;
import tc.oc.pgm.regions.Region;
import tc.oc.pgm.teams.Team;
import tc.oc.pgm.utils.MaterialPattern;
public class Core extends TouchableGoal<CoreFactory> implements ModeChangeGoal<CoreFactory> {
protected final FiniteBlockRegion casingRegion;
protected final FiniteBlockRegion lavaRegion;
protected final Region leakRegion;
protected MaterialData material;
protected boolean leaked = false;
protected Iterable<Location> proximityLocations;
protected Map<MatchPlayerState, Material> breakers;
public Core(CoreFactory definition, Match match) {
super(definition, match);
this.material = definition.getMaterial();
Region region = definition.getRegion();
final FiniteBlockRegion.Factory regionFactory = new FiniteBlockRegion.Factory(match.getMapInfo().proto);
this.casingRegion = regionFactory.fromWorld(region, match.getWorld(), new MaterialPattern(this.material));
if(this.casingRegion.blockVolume() == 0) {
match.getServer().getLogger().warning("No casing material (" + this.material + ") found in core " + this.getName());
}
this.lavaRegion = regionFactory.fromWorld(region,
match.getWorld(),
new MaterialPattern(Material.LAVA, (byte) 0),
new MaterialPattern(Material.STATIONARY_LAVA, (byte) 0));
if(this.lavaRegion.blockVolume() == 0) {
match.getServer().getLogger().warning("No lava found in core " + this.getName());
}
Vector min = new Vector(region.getBounds().minimum()).subtract(new Vector(15, 0, 15));
min.setY(0);
Vector max = new Vector(region.getBounds().maximum()).add(new Vector(15, 0, 15));
max.setY(region.getBounds().minimum().getY() - definition.getLeakLevel());
this.leakRegion = new CuboidRegion(min, max);
this.breakers = new HashMap<>();
}
// Remove @Nullable
@Override
public @Nonnull Team getOwner() {
return super.getOwner();
}
@Override
public boolean getDeferTouches() {
return true;
}
@Override
public BaseComponent getTouchMessage(@Nullable ParticipantState toucher, boolean self) {
if(toucher == null) {
return new TranslatableComponent("match.touch.core.owner",
Components.blank(),
getComponentName(),
getOwner().getComponentName());
} else if(self) {
return new TranslatableComponent("match.touch.core.owner.you",
Components.blank(),
getComponentName(),
getOwner().getComponentName());
} else {
return new TranslatableComponent("match.touch.core.owner.toucher",
toucher.getStyledName(NameStyle.COLOR),
getComponentName(),
getOwner().getComponentName());
}
}
@Override
public Iterable<Location> getProximityLocations(ParticipantState player) {
if(proximityLocations == null) {
proximityLocations = Collections.singleton(casingRegion.getBounds().center().toLocation(this.getMatch().getWorld()));
}
return proximityLocations;
}
public MaterialData getMaterial() {
return this.material;
}
public FiniteBlockRegion getCasingRegion() {
return this.casingRegion;
}
public FiniteBlockRegion getLavaRegion() {
return this.lavaRegion;
}
public Region getLeakRegion() {
return this.leakRegion;
}
public void markLeaked() {
this.leaked = true;
}
public boolean hasLeaked() {
return this.leaked;
}
@Override
public boolean canComplete(Competitor team) {
return team != this.getOwner();
}
@Override
public boolean isCompleted() {
return this.leaked;
}
@Override
public boolean isCompleted(Competitor team) {
return this.leaked && this.canComplete(team);
}
@Override
public boolean isAffectedByModeChanges() {
return this.definition.hasModeChanges();
}
@Override
@SuppressWarnings("deprecation")
public void replaceBlocks(MaterialData newMaterial) {
for(Block block : this.getCasingRegion().getBlocks(match.getWorld())) {
if(this.isObjectiveMaterial(block)) {
block.setTypeIdAndData(newMaterial.getItemTypeId(), newMaterial.getData(), true);
}
}
this.material = newMaterial;
}
@Override
@SuppressWarnings("deprecation")
public boolean isObjectiveMaterial(Block block) {
return block.getType() == this.material.getItemType() && block.getData() == this.material.getData();
}
@Override
public String getModeChangeMessage() {
return "match.objectiveMode.name.core";
}
@Override
public void touch(@Nullable ParticipantState toucher) {
super.touch(toucher);
breakers.putIfAbsent(toucher, material.getItemType());
}
public ImmutableList<CoreContribution> getContributions() {
Set<ParticipantState> touchers = getTouchingPlayers();
ImmutableList.Builder<CoreContribution> builder = ImmutableList.builder();
for(MatchPlayerState player : touchers) {
builder.add(new CoreContribution(player, 1d / touchers.size(), breakers.get(player)));
}
return builder.build();
}
}