Rework class pet parsing and handling.
This commit changes the pet parsing and handling such that it is a lot more dynamic. Rather than limiting pets to wolves and ocelots, any living entity is now a potential pet. This means that we can do away with the logic that specifically targets the Wolf and Ocelot interfaces and instead work with the more general Tameable interface. As a result, the discrepancies between Minecraft 1.13 and 1.14 in this regard are largely irrelevant, because server owners can just specify which entity they want to spawn given which item in their config-files. MonsterManager's two Wolf- and Ocelot-specific addPet() methods are replaced with a generic addPet() method that takes an owner (Player) and a pet (Entity). This is technically a breaking API change, but MonsterManager is an internal component that is very unlikely to be used outside of MobArena. The `global-settings` node in the config-file can no longer be forced into strict compliance via ConfigUtils, because the `pet-items` node is now dynamic rather than static. The default `pet-items` node in the config-file no longer has `ocelot` in there to avoid confusion on 1.14. It now only contains `wolf` and people will have to add their own ocelot/cat in if they haven't added it already. Fixes #563
This commit is contained in:
@@ -13,6 +13,7 @@ These changes will (most likely) be included in the next version.
|
||||
## [Unreleased]
|
||||
- Extended and upgraded potions are now supported in the item syntax by prepending `long_` or `strong_` to the data portion of a potion item (e.g. `potion:strong_instant_heal:1` will yield a Potion of Healing II). Check the wiki for details.
|
||||
- MobArena now has basic tab completion support for most of the commands that take arguments.
|
||||
- The `pet-items` node in `global-settings` now supports any living entity as a pet (but only tameable entities will _behave_ as pets). This should allow 1.14 servers to replace `ocelot` with `cat` in their `pet-items` node to get cat pets working again.
|
||||
- Tridents and crossbows are now considered weapons with regards to the `unbreakable-weapons` flag. All class items that have durability now have their unbreakable flag set to true unless the `unbreakable-weapons` and/or `unbreakable-armor` flags are set to `false`.
|
||||
- Leaderboards now work again on servers running Minecraft 1.14+.
|
||||
- Class chests (non-linked) now work again on servers running Minecraft 1.14+.
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Slime;
|
||||
@@ -40,7 +39,6 @@ import org.bukkit.entity.Snowman;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
@@ -561,12 +559,11 @@ public class ArenaListener
|
||||
if (shooter instanceof Entity) {
|
||||
damager = (Entity) shooter;
|
||||
}
|
||||
}
|
||||
else if (damager instanceof Wolf && arena.hasPet(damager)) {
|
||||
damager = (Player) ((Wolf) damager).getOwner();
|
||||
}
|
||||
else if (damager instanceof Ocelot && arena.hasPet(damager)) {
|
||||
damager = (Player) ((Ocelot) damager).getOwner();
|
||||
} else {
|
||||
Player owner = arena.getMonsterManager().getOwner(damager);
|
||||
if (owner != null) {
|
||||
damager = owner;
|
||||
}
|
||||
}
|
||||
|
||||
// If the damager was a player, add to kills.
|
||||
@@ -656,12 +653,9 @@ public class ArenaListener
|
||||
? monsters.getBoss((LivingEntity) damagee)
|
||||
: null;
|
||||
|
||||
// Pet wolf
|
||||
if (damagee instanceof Wolf && arena.hasPet(damagee)) {
|
||||
onPetDamage(event, (Wolf) damagee, damager);
|
||||
}
|
||||
else if (damagee instanceof Ocelot && arena.hasPet(damagee)) {
|
||||
onPetDamage(event, (Ocelot) damagee, damager);
|
||||
// Pets
|
||||
if (arena.hasPet(damagee)) {
|
||||
onPetDamage(event, damagee, damager);
|
||||
}
|
||||
else if (damagee instanceof ArmorStand) {
|
||||
onArmorStandDamage(event);
|
||||
@@ -712,11 +706,7 @@ public class ArenaListener
|
||||
}
|
||||
}
|
||||
|
||||
private void onPetDamage(EntityDamageEvent event, Wolf pet, Entity damager) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
private void onPetDamage(EntityDamageEvent event, Ocelot pet, Entity damager) {
|
||||
private void onPetDamage(EntityDamageEvent event, Entity pet, Entity damager) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@@ -752,16 +742,12 @@ public class ArenaListener
|
||||
aps.add("dmgDone", event.getDamage());
|
||||
aps.inc("hits");
|
||||
}
|
||||
else if (damager instanceof Wolf && arena.hasPet(damager)) {
|
||||
//event.setDamage(1);
|
||||
Player p = (Player) ((Wolf) damager).getOwner();
|
||||
ArenaPlayerStatistics aps = arena.getArenaPlayer(p).getStats();
|
||||
aps.add("dmgDone", event.getDamage());
|
||||
}
|
||||
else if (damager instanceof Ocelot && arena.hasPet(damager)) {
|
||||
Player p = (Player) ((Ocelot) damager).getOwner();
|
||||
ArenaPlayerStatistics aps = arena.getArenaPlayer(p).getStats();
|
||||
aps.add("dmgDone", event.getDamage());
|
||||
else if (arena.hasPet(damager)) {
|
||||
Player owner = arena.getMonsterManager().getOwner(damager);
|
||||
if (owner != null) {
|
||||
ArenaPlayerStatistics aps = arena.getArenaPlayer(owner).getStats();
|
||||
aps.add("dmgDone", event.getDamage());
|
||||
}
|
||||
}
|
||||
else if (monsters.getMonsters().contains(damager)) {
|
||||
if (!monsterInfight)
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -57,7 +58,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
||||
this.classes = new HashMap<>();
|
||||
|
||||
this.allowedCommands = new HashSet<>();
|
||||
this.spawnsPets = new SpawnsPets(Material.BONE, Material.SALMON);
|
||||
this.spawnsPets = new SpawnsPets();
|
||||
|
||||
this.joinInterruptTimer = new JoinInterruptTimer();
|
||||
}
|
||||
@@ -254,7 +255,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
||||
*/
|
||||
public void loadSettings() {
|
||||
ConfigurationSection section = plugin.getConfig().getConfigurationSection("global-settings");
|
||||
ConfigUtils.addMissingRemoveObsolete(plugin, "global-settings.yml", section);
|
||||
ConfigUtils.addIfEmpty(plugin, "global-settings.yml", section);
|
||||
|
||||
enabled = section.getBoolean("enabled", true);
|
||||
|
||||
@@ -276,20 +277,35 @@ public class ArenaMasterImpl implements ArenaMaster
|
||||
}
|
||||
|
||||
private void loadPetItems(ConfigurationSection settings) {
|
||||
String wolf = settings.getString("pet-items.wolf", "");
|
||||
String ocelot = settings.getString("pet-items.ocelot", "");
|
||||
spawnsPets.clear();
|
||||
|
||||
Material wolfMaterial = Material.getMaterial(wolf.toUpperCase());
|
||||
Material ocelotMaterial = Material.getMaterial(ocelot.toUpperCase());
|
||||
ConfigurationSection items = settings.getConfigurationSection("pet-items");
|
||||
|
||||
if (wolfMaterial == null && !wolf.isEmpty()) {
|
||||
throw new ConfigError("Failed to parse item type for wolf pet item: " + wolf);
|
||||
for (String key : items.getKeys(false)) {
|
||||
EntityType entity;
|
||||
try {
|
||||
entity = EntityType.valueOf(key.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ConfigError("Failed to parse entity type for pet item: " + key);
|
||||
}
|
||||
|
||||
if (!entity.isAlive()) {
|
||||
throw new ConfigError("Invalid entity type for pet item: " + key);
|
||||
}
|
||||
|
||||
Material material;
|
||||
try {
|
||||
material = Material.getMaterial(items.getString(key, "").toUpperCase());
|
||||
} catch (Exception e) {
|
||||
throw new ConfigError("Failed to parse material type for pet item: " + key);
|
||||
}
|
||||
|
||||
if (material == null) {
|
||||
throw new ConfigError("Failed to parse material type for pet item: " + key);
|
||||
}
|
||||
|
||||
spawnsPets.register(material, entity);
|
||||
}
|
||||
if (ocelotMaterial == null && !ocelot.isEmpty()) {
|
||||
throw new ConfigError("Failed to parse item type for ocelot pet item: " + ocelot);
|
||||
}
|
||||
|
||||
spawnsPets = new SpawnsPets(wolfMaterial, ocelotMaterial);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,12 +4,11 @@ import com.garbagemule.MobArena.healthbar.HealthBar;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -20,32 +19,32 @@ import java.util.Set;
|
||||
public class MonsterManager
|
||||
{
|
||||
private Set<LivingEntity> monsters, sheep, golems;
|
||||
private Set<Wolf> petWolves;
|
||||
private Set<Ocelot> petOcelots;
|
||||
private Map<LivingEntity,MABoss> bosses;
|
||||
private Map<LivingEntity,List<ItemStack>> suppliers;
|
||||
private Set<LivingEntity> mounts;
|
||||
private Map<Entity, Player> petToPlayer;
|
||||
private Map<Player, Set<Entity>> playerToPets;
|
||||
|
||||
public MonsterManager() {
|
||||
this.monsters = new HashSet<>();
|
||||
this.sheep = new HashSet<>();
|
||||
this.golems = new HashSet<>();
|
||||
this.petWolves = new HashSet<>();
|
||||
this.petOcelots = new HashSet<>();
|
||||
this.bosses = new HashMap<>();
|
||||
this.suppliers = new HashMap<>();
|
||||
this.mounts = new HashSet<>();
|
||||
this.petToPlayer = new HashMap<>();
|
||||
this.playerToPets = new HashMap<>();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
monsters.clear();
|
||||
sheep.clear();
|
||||
golems.clear();
|
||||
petWolves.clear();
|
||||
petOcelots.clear();
|
||||
bosses.clear();
|
||||
suppliers.clear();
|
||||
mounts.clear();
|
||||
petToPlayer.clear();
|
||||
playerToPets.clear();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
@@ -57,17 +56,16 @@ public class MonsterManager
|
||||
removeAll(monsters);
|
||||
removeAll(sheep);
|
||||
removeAll(golems);
|
||||
removeAll(petWolves);
|
||||
removeAll(petOcelots);
|
||||
removeAll(bosses.keySet());
|
||||
removeAll(suppliers.keySet());
|
||||
removeAll(mounts);
|
||||
removeAll(petToPlayer.keySet());
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
private void removeAll(Collection<? extends LivingEntity> collection) {
|
||||
for (LivingEntity e : collection) {
|
||||
private void removeAll(Collection<? extends Entity> collection) {
|
||||
for (Entity e : collection) {
|
||||
if (e != null) {
|
||||
e.remove();
|
||||
}
|
||||
@@ -78,8 +76,6 @@ public class MonsterManager
|
||||
if (monsters.remove(e)) {
|
||||
sheep.remove(e);
|
||||
golems.remove(e);
|
||||
petWolves.remove(e);
|
||||
petOcelots.remove(e);
|
||||
suppliers.remove(e);
|
||||
MABoss boss = bosses.remove(e);
|
||||
if (boss != null) {
|
||||
@@ -124,32 +120,34 @@ public class MonsterManager
|
||||
return golems.remove(e);
|
||||
}
|
||||
|
||||
public void addPet(Wolf w) {
|
||||
petWolves.add(w);
|
||||
}
|
||||
|
||||
public void addPet(Ocelot o) {
|
||||
petOcelots.add(o);
|
||||
public void addPet(Player player, Entity pet) {
|
||||
petToPlayer.put(pet, player);
|
||||
playerToPets
|
||||
.computeIfAbsent(player, (key) -> new HashSet<>())
|
||||
.add(pet);
|
||||
}
|
||||
|
||||
public boolean hasPet(Entity e) {
|
||||
return petWolves.contains(e) || petOcelots.contains(e);
|
||||
return petToPlayer.containsKey(e);
|
||||
}
|
||||
|
||||
public Player getOwner(Entity pet) {
|
||||
return petToPlayer.get(pet);
|
||||
}
|
||||
|
||||
public Collection<Entity> getPets(Player owner) {
|
||||
Set<Entity> pets = playerToPets.get(owner);
|
||||
if (pets != null) {
|
||||
return pets;
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
public void removePets(Player p) {
|
||||
for (Wolf w : petWolves) {
|
||||
if (w == null || !(w.getOwner() instanceof Player) || !w.getOwner().getName().equals(p.getName()))
|
||||
continue;
|
||||
|
||||
w.setOwner(null);
|
||||
w.remove();
|
||||
}
|
||||
for (Ocelot o : petOcelots) {
|
||||
if (o == null || !(o.getOwner() instanceof Player) || !o.getOwner().getName().equals(p.getName()))
|
||||
continue;
|
||||
|
||||
o.setOwner(null);
|
||||
o.remove();
|
||||
Set<Entity> pets = playerToPets.remove(p);
|
||||
if (pets != null) {
|
||||
pets.forEach(Entity::remove);
|
||||
pets.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,20 +2,29 @@ package com.garbagemule.MobArena;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SpawnsPets {
|
||||
|
||||
private final Material wolfMaterial;
|
||||
private final Material ocelotMaterial;
|
||||
private final Map<Material, EntityType> materialToEntity;
|
||||
|
||||
SpawnsPets(Material wolfMaterial, Material ocelotMaterial) {
|
||||
this.wolfMaterial = wolfMaterial;
|
||||
this.ocelotMaterial = ocelotMaterial;
|
||||
SpawnsPets() {
|
||||
this.materialToEntity = new HashMap<>();
|
||||
}
|
||||
|
||||
void register(Material material, EntityType entity) {
|
||||
materialToEntity.put(material, entity);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
materialToEntity.clear();
|
||||
}
|
||||
|
||||
void spawn(Arena arena) {
|
||||
@@ -31,47 +40,29 @@ public class SpawnsPets {
|
||||
if (ac == null || ac.getConfigName().equals("My Items")) {
|
||||
return;
|
||||
}
|
||||
spawnWolfPets(player, arena);
|
||||
spawnOcelotPets(player, arena);
|
||||
|
||||
for (Map.Entry<Material, EntityType> entry : materialToEntity.entrySet()) {
|
||||
spawnPetsFor(player, arena, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnWolfPets(Player player, Arena arena) {
|
||||
if (wolfMaterial == null) {
|
||||
return;
|
||||
}
|
||||
private void spawnPetsFor(Player player, Arena arena, Material material, EntityType entity) {
|
||||
PlayerInventory inv = player.getInventory();
|
||||
int index = inv.first(wolfMaterial);
|
||||
if (index == -1) {
|
||||
|
||||
int index = inv.first(material);
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int amount = inv.getItem(index).getAmount();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Wolf wolf = (Wolf) arena.getWorld().spawnEntity(player.getLocation(), EntityType.WOLF);
|
||||
wolf.setTamed(true);
|
||||
wolf.setOwner(player);
|
||||
arena.getMonsterManager().addPet(wolf);
|
||||
}
|
||||
|
||||
inv.setItem(index, null);
|
||||
}
|
||||
|
||||
private void spawnOcelotPets(Player player, Arena arena) {
|
||||
if (ocelotMaterial == null) {
|
||||
return;
|
||||
}
|
||||
PlayerInventory inv = player.getInventory();
|
||||
int index = inv.first(ocelotMaterial);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int amount = inv.getItem(index).getAmount();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Ocelot ocelot = (Ocelot) arena.getWorld().spawnEntity(player.getLocation(), EntityType.OCELOT);
|
||||
ocelot.setTamed(true);
|
||||
ocelot.setOwner(player);
|
||||
arena.getMonsterManager().addPet(ocelot);
|
||||
Entity pet = arena.getWorld().spawn(player.getLocation(), entity.getEntityClass());
|
||||
if (pet instanceof Tameable) {
|
||||
Tameable tameable = (Tameable) pet;
|
||||
tameable.setTamed(true);
|
||||
tameable.setOwner(player);
|
||||
}
|
||||
arena.getMonsterManager().addPet(player, pet);
|
||||
}
|
||||
|
||||
inv.setItem(index, null);
|
||||
|
||||
@@ -4,4 +4,3 @@ update-notification: true
|
||||
prefix: '&a[MobArena] '
|
||||
pet-items:
|
||||
wolf: bone
|
||||
ocelot: salmon
|
||||
|
||||
Reference in New Issue
Block a user