149 lines
6.4 KiB
Java
149 lines
6.4 KiB
Java
package tc.oc.pgm.spawns;
|
|
|
|
import java.time.Duration;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.logging.Logger;
|
|
import javax.inject.Inject;
|
|
import javax.inject.Provider;
|
|
|
|
import com.google.common.collect.Lists;
|
|
import net.md_5.bungee.api.chat.BaseComponent;
|
|
import org.jdom2.Document;
|
|
import org.jdom2.Element;
|
|
import tc.oc.commons.core.util.Comparables;
|
|
import tc.oc.pgm.filters.Filter;
|
|
import tc.oc.pgm.filters.matcher.StaticFilter;
|
|
import tc.oc.pgm.filters.parser.FilterParser;
|
|
import tc.oc.pgm.kits.Kit;
|
|
import tc.oc.pgm.kits.KitParser;
|
|
import tc.oc.pgm.map.MapModule;
|
|
import tc.oc.pgm.map.MapModuleContext;
|
|
import tc.oc.pgm.map.MapModuleFactory;
|
|
import tc.oc.pgm.match.Match;
|
|
import tc.oc.pgm.match.MatchModuleFactory;
|
|
import tc.oc.pgm.module.ModuleDescription;
|
|
import tc.oc.pgm.teams.TeamModule;
|
|
import tc.oc.pgm.utils.XMLUtils;
|
|
import tc.oc.pgm.xml.InvalidXMLException;
|
|
import tc.oc.pgm.xml.Node;
|
|
|
|
@ModuleDescription(name = "spawns", follows = { TeamModule.class })
|
|
public class SpawnModule implements MapModule, MatchModuleFactory<SpawnMatchModule> {
|
|
|
|
public static final Duration MINIMUM_RESPAWN_DELAY = Duration.ofSeconds(1);
|
|
public static final Duration IGNORE_CLICKS_DELAY = Duration.ofMillis(500);
|
|
public static final Duration DEFAULT_RESPAWN_DELAY = Duration.ofSeconds(2);
|
|
public static final Duration DEFAULT_FREEZE_TIME = Duration.ofSeconds(3);
|
|
|
|
protected final Spawn defaultSpawn;
|
|
protected final List<Spawn> spawns;
|
|
protected final List<Kit> playerKits;
|
|
protected final List<RespawnOptions> respawnOptions;
|
|
|
|
public SpawnModule(Spawn defaultSpawn, List<Spawn> spawns, List<Kit> playerKits, List<RespawnOptions> respawnOptions) {
|
|
this.playerKits = playerKits;
|
|
assert defaultSpawn != null;
|
|
this.defaultSpawn = defaultSpawn;
|
|
this.spawns = spawns;
|
|
this.respawnOptions = respawnOptions;
|
|
}
|
|
|
|
@Override
|
|
public SpawnMatchModule createMatchModule(Match match) {
|
|
return new SpawnMatchModule(match, this);
|
|
}
|
|
|
|
// ---------------------
|
|
// ---- XML Parsing ----
|
|
// ---------------------
|
|
|
|
public static class Factory extends MapModuleFactory<SpawnModule> {
|
|
|
|
@Inject private Provider<SpawnParser> spawnParser;
|
|
@Inject private Provider<FilterParser> filterParser;
|
|
|
|
@Override
|
|
public SpawnModule parse(MapModuleContext context, Logger logger, Document doc) throws InvalidXMLException {
|
|
final SpawnParser parser = spawnParser.get();
|
|
List<Spawn> spawns = Lists.newArrayList();
|
|
List<Kit> playerKits = new ArrayList<>();
|
|
|
|
for(Element spawnsEl : doc.getRootElement().getChildren("spawns")) {
|
|
spawns.addAll(parser.parseChildren(spawnsEl, new SpawnAttributes()));
|
|
final Kit playerKit = context.needModule(KitParser.class).property(spawnsEl, "player-kit").optional(null);
|
|
if(playerKit != null) {
|
|
playerKits.add(playerKit);
|
|
}
|
|
}
|
|
|
|
if(parser.getDefaultSpawn() == null) {
|
|
throw new InvalidXMLException("map must have a single default spawn", doc);
|
|
}
|
|
|
|
return new SpawnModule(parser.getDefaultSpawn(), spawns, playerKits, parseRespawnOptions(context, logger, doc));
|
|
}
|
|
|
|
private List<RespawnOptions> parseRespawnOptions(MapModuleContext context, Logger logger, Document doc) throws InvalidXMLException {
|
|
List<RespawnOptions> respawnOptions = Lists.newArrayList();
|
|
|
|
for (Element elRespawn : XMLUtils.flattenElements(doc.getRootElement(), "respawns", "respawn")) {
|
|
respawnOptions.add(getRespawnOptions(elRespawn));
|
|
}
|
|
// Parse root children respawn elements, Keeps old syntax and gives a default spawn if all others fail
|
|
respawnOptions.add(getRespawnOptions(doc.getRootElement().getChildren("respawn"),
|
|
doc.getRootElement().getChild("autorespawn") != null, true));
|
|
|
|
return respawnOptions;
|
|
}
|
|
|
|
private RespawnOptions getRespawnOptions(Element element) throws InvalidXMLException {
|
|
return getRespawnOptions(Collections.singleton(element), false, false);
|
|
}
|
|
|
|
private RespawnOptions getRespawnOptions(Collection<Element> elements, boolean autorespawn, boolean topLevel) throws InvalidXMLException {
|
|
Duration delay = DEFAULT_RESPAWN_DELAY;
|
|
Duration freeze = DEFAULT_FREEZE_TIME;
|
|
boolean auto = autorespawn; //Legacy support
|
|
boolean blackout = false;
|
|
boolean spectate = false;
|
|
boolean bedSpawn = false;
|
|
Filter filter = StaticFilter.ALLOW;
|
|
BaseComponent message = null;
|
|
|
|
for (Element element : elements) {
|
|
delay = XMLUtils.parseDuration(element.getAttribute("delay"), delay);
|
|
freeze = XMLUtils.parseDuration(element.getAttribute("freeze"), freeze);
|
|
auto = XMLUtils.parseBoolean(element.getAttribute("auto"), auto); //Legacy support
|
|
blackout = XMLUtils.parseBoolean(element.getAttribute("blackout"), blackout);
|
|
spectate = XMLUtils.parseBoolean(element.getAttribute("spectate"), spectate);
|
|
bedSpawn = XMLUtils.parseBoolean(element.getAttribute("bed"), bedSpawn);
|
|
filter = filterParser.get().property(element).validate((Filter filt, Node node) -> {
|
|
if (topLevel)
|
|
throw new InvalidXMLException("Parent respawn elements can't use filters", node);
|
|
}).optional(filter);
|
|
message = XMLUtils.parseFormattedText(element, "message", message);
|
|
}
|
|
|
|
if(Comparables.lessThan(delay, MINIMUM_RESPAWN_DELAY)) {
|
|
delay = MINIMUM_RESPAWN_DELAY;
|
|
}
|
|
|
|
return new RespawnOptions(delay, freeze, auto, blackout, spectate, bedSpawn, filter, message);
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void postParse(MapModuleContext context, Logger logger, Document doc) throws InvalidXMLException {
|
|
// TODO: Make this feasible and remove null checks in the spawn module
|
|
//for(Spawn spawn : spawns) {
|
|
// if(spawn.pointProvider.canFail()) {
|
|
// throw new InvalidXMLException("Spawn is not guaranteed to provide a spawning location", context.features().getNode(spawn));
|
|
// }
|
|
//}
|
|
}
|
|
}
|