Skip to content
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

Add splash potions entity to Spawner module #1002

Merged
merged 23 commits into from
May 22, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6d8ed1f
Add dropped potions support to spawners
CoWinkKeyDinkInc May 2, 2022
05bbe97
Make Splash potions have multiple effects, simplify code
CoWinkKeyDinkInc May 2, 2022
2487058
Simplify code
CoWinkKeyDinkInc May 2, 2022
dc2fbaa
Use <effect> inside <potion> for parsing
CoWinkKeyDinkInc May 2, 2022
f779edd
Add evaluation
CoWinkKeyDinkInc May 2, 2022
c627279
Fix evaluation of <potion> and <element>
CoWinkKeyDinkInc May 3, 2022
5a3e16b
Simplify Code
CoWinkKeyDinkInc May 3, 2022
a6a533c
Use finals for SpawnableItem and SpawnablePotion
CoWinkKeyDinkInc May 3, 2022
3e405a9
Refactor, convert spawner ID to string
CoWinkKeyDinkInc May 4, 2022
48eae5c
Use AtomicInteger for numericID, rearrange SpawnerDefinition
CoWinkKeyDinkInc May 5, 2022
3212cb2
Clone potionItem
CoWinkKeyDinkInc May 5, 2022
e956706
Parse potion effects properly
CoWinkKeyDinkInc May 5, 2022
fb03925
Rename spawner Element to spawnerEl
CoWinkKeyDinkInc May 5, 2022
ff95283
Reformat code
CoWinkKeyDinkInc May 5, 2022
cd081d4
Add damage value to determine potion color
CoWinkKeyDinkInc May 5, 2022
f0630e5
Make spawnerID string
CoWinkKeyDinkInc May 6, 2022
d610cbc
Rename variable
CoWinkKeyDinkInc May 9, 2022
cdf5fa9
Use NMSHacks to create EntityPotion
CoWinkKeyDinkInc May 9, 2022
f13edf6
Use NMSHacks properly
CoWinkKeyDinkInc May 11, 2022
04de451
Rework spawner IDs
CoWinkKeyDinkInc May 11, 2022
3e5624e
Simplify EntityPotion spawning
CoWinkKeyDinkInc May 12, 2022
682b7f3
Do pablo's suggestions
CoWinkKeyDinkInc May 13, 2022
1de5d6f
Set metadata to EntityPotion
CoWinkKeyDinkInc May 13, 2022
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
6 changes: 3 additions & 3 deletions core/src/main/java/tc/oc/pgm/spawner/SpawnerDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ public class SpawnerDefinition implements FeatureDefinition {
public final int numericID;

public SpawnerDefinition(
int numericID,
CoWinkKeyDinkInc marked this conversation as resolved.
Show resolved Hide resolved
List<Spawnable> objects,
Region spawnRegion,
Region playerRegion,
Filter playerFilter,
Duration delay,
Duration minDelay,
Duration maxDelay,
int maxEntities,
int numericID) {
int maxEntities) {
this.numericID = numericID;
this.spawnRegion = spawnRegion;
this.playerRegion = playerRegion;
this.maxEntities = maxEntities;
Expand All @@ -36,6 +37,5 @@ public SpawnerDefinition(
this.delay = delay;
this.objects = objects;
this.playerFilter = playerFilter;
this.numericID = numericID;
}
}
69 changes: 49 additions & 20 deletions core/src/main/java/tc/oc/pgm/spawner/SpawnerModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionType;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
Expand All @@ -24,6 +27,8 @@
import tc.oc.pgm.regions.RegionModule;
import tc.oc.pgm.regions.RegionParser;
import tc.oc.pgm.spawner.objects.SpawnableItem;
import tc.oc.pgm.spawner.objects.SpawnablePotion;
import tc.oc.pgm.util.xml.InheritingElement;
import tc.oc.pgm.util.xml.InvalidXMLException;
import tc.oc.pgm.util.xml.XMLUtils;

Expand All @@ -49,58 +54,82 @@ public SpawnerModule parse(MapFactory factory, Logger logger, Document doc)
RegionParser regionParser = factory.getRegions();
KitParser kitParser = factory.getKits();
FilterParser filterParser = factory.getFilters();
AtomicInteger numericId = new AtomicInteger(0);

int numericID = 0;
for (Element element :
for (Element spawnerEl :
XMLUtils.flattenElements(doc.getRootElement(), "spawners", "spawner")) {
Region spawnRegion = regionParser.parseRequiredRegionProperty(element, "spawn-region");
Region playerRegion = regionParser.parseRequiredRegionProperty(element, "player-region");
Attribute delayAttr = element.getAttribute("delay");
Attribute minDelayAttr = element.getAttribute("min-delay");
Attribute maxDelayAttr = element.getAttribute("max-delay");
Region spawnRegion = regionParser.parseRequiredRegionProperty(spawnerEl, "spawn-region");
Region playerRegion = regionParser.parseRequiredRegionProperty(spawnerEl, "player-region");
Attribute delayAttr = spawnerEl.getAttribute("delay");
Attribute minDelayAttr = spawnerEl.getAttribute("min-delay");
Attribute maxDelayAttr = spawnerEl.getAttribute("max-delay");

if ((minDelayAttr != null || maxDelayAttr != null) && delayAttr != null) {
throw new InvalidXMLException(
"Attribute 'minDelay' and 'maxDelay' cannot be combined with 'delay'", element);
"Attribute 'minDelay' and 'maxDelay' cannot be combined with 'delay'", spawnerEl);
}

Duration delay = XMLUtils.parseDuration(delayAttr, Duration.ofSeconds(10));
Duration minDelay = XMLUtils.parseDuration(minDelayAttr, delay);
Duration maxDelay = XMLUtils.parseDuration(maxDelayAttr, delay);

if (maxDelay.compareTo(minDelay) <= 0 && minDelayAttr != null && maxDelayAttr != null) {
throw new InvalidXMLException("Max-delay must be longer than min-delay", element);
throw new InvalidXMLException("Max-delay must be longer than min-delay", spawnerEl);
}

int maxEntities =
XMLUtils.parseNumber(
element.getAttribute("max-entities"), Integer.class, Integer.MAX_VALUE);
spawnerEl.getAttribute("max-entities"), Integer.class, Integer.MAX_VALUE);
Filter playerFilter =
filterParser.parseFilterProperty(element, "filter", StaticFilter.ALLOW);
filterParser.parseFilterProperty(spawnerEl, "filter", StaticFilter.ALLOW);

List<Spawnable> objects = new ArrayList<>();
for (Element spawnable :
XMLUtils.getChildren(
element, "item")) { // TODO Add more types of spawnables once entity parser is built
ItemStack stack = kitParser.parseItem(spawnable, false);
SpawnableItem item = new SpawnableItem(stack, numericID);
for (Element itemEl : XMLUtils.getChildren(spawnerEl, "item")) {
ItemStack stack = kitParser.parseItem(itemEl, false);
SpawnableItem item = new SpawnableItem(stack, "spawner-" + numericId.get());
CoWinkKeyDinkInc marked this conversation as resolved.
Show resolved Hide resolved
objects.add(item);
}

ImmutableList.Builder<PotionEffect> chBuilder = ImmutableList.builder();
CoWinkKeyDinkInc marked this conversation as resolved.
Show resolved Hide resolved
for (Element potionEl : XMLUtils.getChildren(spawnerEl, "potion")) {
for (Element potionChild : potionEl.getChildren("effect")) {
chBuilder.add(XMLUtils.parsePotionEffect(new InheritingElement(potionChild)));
}
ImmutableList<PotionEffect> potionChildren = chBuilder.build();
CoWinkKeyDinkInc marked this conversation as resolved.
Show resolved Hide resolved
if (potionChildren.isEmpty()) {
throw new InvalidXMLException("Expected child effects, but found none", spawnerEl);
}
int potionName = 0;
if (potionEl.getAttribute("damage") != null) {
potionName = XMLUtils.parseNumber(potionEl.getAttribute("damage"), Integer.class, 0);
} else {
for (PotionEffect potionEffect : potionChildren) {
// PotionType lists "true" potions, PotionEffectType lists all possible status effects
// (ie wither)
// Use the first listed PotionType for potion color
if (PotionType.getByEffect(potionEffect.getType()) != null) {
potionName = PotionType.getByEffect(potionEffect.getType()).getDamageValue();
break;
}
}
}
objects.add(
new SpawnablePotion(potionChildren, potionName, "spawner-" + numericId.get()));
}

SpawnerDefinition spawnerDefinition =
new SpawnerDefinition(
numericId.getAndIncrement(),
objects,
spawnRegion,
playerRegion,
playerFilter,
delay,
minDelay,
maxDelay,
maxEntities,
numericID);
factory.getFeatures().addFeature(element, spawnerDefinition);
maxEntities);
factory.getFeatures().addFeature(spawnerEl, spawnerDefinition);
Pablete1234 marked this conversation as resolved.
Show resolved Hide resolved
spawnerModule.spawnerDefinitions.add(spawnerDefinition);
numericID++;
}

return spawnerModule.spawnerDefinitions.isEmpty() ? null : spawnerModule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@

public class SpawnableItem implements Spawnable {

private ItemStack stack;
private String METADATA_VALUE;
private final ItemStack stack;
private final String spawnerId;

public SpawnableItem(ItemStack stack, int spawnerID) {
public SpawnableItem(ItemStack stack, String spawnerId) {
this.stack = stack;
this.METADATA_VALUE = Integer.toString(spawnerID);
this.spawnerId = spawnerId;
}

@Override
public void spawn(Location location, Match match) {
Item item = location.getWorld().dropItem(location, stack);
item.setMetadata(Spawner.METADATA_KEY, new FixedMetadataValue(PGM.get(), METADATA_VALUE));
item.setMetadata(Spawner.METADATA_KEY, new FixedMetadataValue(PGM.get(), spawnerId));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package tc.oc.pgm.spawner.objects;

import java.util.List;
import org.bukkit.Location;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import tc.oc.pgm.api.PGM;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.spawner.Spawnable;
import tc.oc.pgm.spawner.Spawner;

public class SpawnablePotion implements Spawnable {
private final ItemStack potionItem;
private final String spawnerId;

public SpawnablePotion(List<PotionEffect> potion, int potionName, String spawnerId) {
this.spawnerId = spawnerId;
// Potion "name" determines potion color
ItemStack potionItem = new ItemStack(new Potion(potionName).splash().toItemStack(1));
PotionMeta potionMeta = (PotionMeta) potionItem.getItemMeta();
for (PotionEffect effect : potion) {
potionMeta.addCustomEffect(effect, false);
}
potionItem.setItemMeta(potionMeta);
this.potionItem = potionItem;
}

@Override
public void spawn(Location location, Match match) {
ThrownPotion thrownPotion = location.getWorld().spawn(location, ThrownPotion.class);
thrownPotion.setItem(potionItem.clone());
thrownPotion.setMetadata(Spawner.METADATA_KEY, new FixedMetadataValue(PGM.get(), spawnerId));
}

@Override
public int getSpawnCount() {
return potionItem.getAmount();
}
}