1.0.0-SNAPSHOT-U38

+ Finished working on the Targeting system and fully implemented it into the boss spawning system
+ Added the targeting option to the bosses.json
This commit is contained in:
AMinecraftDev 2018-11-03 21:51:08 +08:00
parent 65d8827dc5
commit a8662dc2f3
16 changed files with 344 additions and 7 deletions

View File

@ -2,6 +2,7 @@
"SkeletonKing": {
"editing": true,
"spawnItem": "SKSpawnItem",
"targeting": "RandomNearby",
"entityStats": [
{
"mainStats": {

View File

@ -1,5 +1,6 @@
Settings:
debug: false
bossTargetRange: 50.0
BlockedWorlds:
enabled: false

View File

@ -1,5 +1,6 @@
package com.songoda.epicbosses;
import com.songoda.epicbosses.targetting.TargetHandler;
import lombok.Getter;
import com.songoda.epicbosses.api.BossAPI;
import com.songoda.epicbosses.commands.BossCmd;
@ -41,6 +42,7 @@ public class CustomBosses extends JavaPlugin implements IReloadable {
@Getter private BossListenerManager bossListenerManager;
@Getter private BossCommandManager bossCommandManager;
@Getter private BossEntityManager bossEntityManager;
@Getter private BossTargetManager bossTargetManager;
@Getter private BossPanelManager bossPanelManager;
@Getter private BossHookManager bossHookManager;
@Getter private VersionHandler versionHandler;
@ -62,6 +64,7 @@ public class CustomBosses extends JavaPlugin implements IReloadable {
this.debugManager = new DebugManager();
this.versionHandler = new VersionHandler();
this.bossTargetManager = new BossTargetManager(this);
this.bossEntityContainer = new BossEntityContainer();
this.bossMechanicManager = new BossMechanicManager(this);
this.bossHookManager = new BossHookManager(this);

View File

@ -21,8 +21,8 @@ public class BossEntity {
@Expose @Getter private final SkillsElement skills;
@Expose @Getter private final DropsElement drops;
@Expose @Getter @Setter private String spawnItem;
@Expose @Getter @Setter private boolean editing;
@Expose @Getter @Setter private String spawnItem, targeting;
public BossEntity(boolean editing, String spawnItem, List<EntityStatsElement> entityStats, SkillsElement skills, DropsElement drops, MessagesElement messages, CommandsElement commands) {
this.editing = editing;

View File

@ -1,6 +1,8 @@
package com.songoda.epicbosses.holder;
import lombok.Getter;
import lombok.Setter;
import com.songoda.epicbosses.targetting.TargetHandler;
import com.songoda.epicbosses.entity.BossEntity;
import com.songoda.epicbosses.exception.AlreadySetException;
import org.bukkit.Location;
@ -24,6 +26,9 @@ public class ActiveBossHolder {
@Getter private Map<Integer, LivingEntity> livingEntityMap = new HashMap<>();
@Getter private Map<UUID, Double> mapOfDamagingUsers = new HashMap<>();
@Getter @Setter private TargetHandler targetHandler = null;
@Getter @Setter private boolean isDead = false;
public ActiveBossHolder(BossEntity bossEntity, Location spawnLocation, String name) {
this.location = spawnLocation;
this.bossEntity = bossEntity;
@ -37,4 +42,8 @@ public class ActiveBossHolder {
this.livingEntityMap.put(position, livingEntity);
}
}
public boolean hasAttacked(UUID uuid) {
return this.mapOfDamagingUsers.containsKey(uuid);
}
}

View File

@ -55,6 +55,7 @@ public class BossDeathListener implements Listener {
if(this.bossEntityManager.isAllEntitiesDead(activeBossHolder)) {
PreBossDeathEvent preBossDeathEvent = new PreBossDeathEvent(activeBossHolder, location);
activeBossHolder.setDead(true);
ServerUtils.get().callEvent(preBossDeathEvent);
}
}
@ -129,7 +130,7 @@ public class BossDeathListener implements Listener {
Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
if(onlinePlayer.getWorld().getName().equals(location.getWorld().getName())) {
if(onlinePlayer.getLocation().distanceSquared(location) <= messageRadius) {
finalMessage.forEach(s -> onlinePlayer.sendMessage(s));
finalMessage.forEach(onlinePlayer::sendMessage);
}
}
});

View File

@ -9,6 +9,7 @@ import com.songoda.epicbosses.events.PreBossSpawnEvent;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossEntityManager;
import com.songoda.epicbosses.managers.BossLocationManager;
import com.songoda.epicbosses.managers.BossTargetManager;
import com.songoda.epicbosses.utils.Debug;
import com.songoda.epicbosses.utils.Message;
import com.songoda.epicbosses.utils.ServerUtils;
@ -38,12 +39,14 @@ import java.util.Map;
public class BossSpawnListener implements Listener {
private BossLocationManager bossLocationManager;
private BossTargetManager bossTargetManager;
private BossEntityManager bossEntityManager;
private VersionHandler versionHandler;
public BossSpawnListener(CustomBosses customBosses) {
this.versionHandler = customBosses.getVersionHandler();
this.bossEntityManager = customBosses.getBossEntityManager();
this.bossTargetManager = customBosses.getBossTargetManager();
this.bossLocationManager = customBosses.getBossLocationManager();
}
@ -99,10 +102,9 @@ public class BossSpawnListener implements Listener {
return;
}
//TODO: Set TargetHandler to the boss
PreBossSpawnEvent preBossSpawnEvent = new PreBossSpawnEvent(activeBossHolder, player, itemStack);
this.bossTargetManager.initializeTargetHandler(activeBossHolder);
ServerUtils.get().callEvent(preBossSpawnEvent);
}
@ -136,14 +138,14 @@ public class BossSpawnListener implements Listener {
Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
if(onlinePlayer.getWorld().getName().equals(location.getWorld().getName())) {
if(onlinePlayer.getLocation().distanceSquared(location) <= messagesRadius) {
messages.forEach(s -> onlinePlayer.sendMessage(s));
messages.forEach(onlinePlayer::sendMessage);
}
}
});
}
}
//TODO: Create AutoTarget for TargetHandler
activeBossHolder.getTargetHandler().runTargetCycle();
//TODO: Handle Taunts
BossSpawnEvent bossSpawnEvent = new BossSpawnEvent(activeBossHolder);

View File

@ -0,0 +1,64 @@
package com.songoda.epicbosses.managers;
import com.songoda.epicbosses.CustomBosses;
import com.songoda.epicbosses.entity.BossEntity;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.targetting.TargetHandler;
import com.songoda.epicbosses.targetting.types.ClosestTargetHandler;
import com.songoda.epicbosses.targetting.types.NotDamagedNearbyTargetHandler;
import com.songoda.epicbosses.targetting.types.RandomNearbyTargetHandler;
import com.songoda.epicbosses.targetting.types.TopDamagerTargetHandler;
import lombok.Getter;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 03-Nov-18
*/
public class BossTargetManager {
@Getter private final CustomBosses plugin;
public BossTargetManager(CustomBosses plugin) {
this.plugin = plugin;
}
public double getTargetRadius() {
return this.plugin.getConfig().getDouble("Settings.bossTargetRange", 50.0);
}
public void initializeTargetHandler(ActiveBossHolder activeBossHolder) {
BossEntity bossEntity = activeBossHolder.getBossEntity();
String targeting = bossEntity.getTargeting();
TargetHandler targetHandler;
if(targeting.equalsIgnoreCase("RandomNearby")) {
targetHandler = getRandomNearbyTargetHandler(activeBossHolder);
} else if(targeting.equalsIgnoreCase("TopDamager")) {
targetHandler = getTopDamagerTargetHandler(activeBossHolder);
} else if(targeting.equalsIgnoreCase("NotDamagedNearby")) {
targetHandler = getNotDamagedNearbyTargetHandler(activeBossHolder);
} else {
targetHandler = getClosestTargetHandler(activeBossHolder);
}
activeBossHolder.setTargetHandler(targetHandler);
}
private TargetHandler getClosestTargetHandler(ActiveBossHolder activeBossHolder) {
return new ClosestTargetHandler(activeBossHolder, this);
}
private TargetHandler getNotDamagedNearbyTargetHandler(ActiveBossHolder activeBossHolder) {
return new NotDamagedNearbyTargetHandler(activeBossHolder, this);
}
private TargetHandler getRandomNearbyTargetHandler(ActiveBossHolder activeBossHolder) {
return new RandomNearbyTargetHandler(activeBossHolder, this);
}
private TargetHandler getTopDamagerTargetHandler(ActiveBossHolder activeBossHolder) {
return new TopDamagerTargetHandler(activeBossHolder, this);
}
}

View File

@ -0,0 +1,16 @@
package com.songoda.epicbosses.targetting;
import org.bukkit.entity.LivingEntity;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 30-Oct-18
*/
public interface ITarget {
LivingEntity selectTarget(List<LivingEntity> nearbyEntities);
}

View File

@ -0,0 +1,74 @@
package com.songoda.epicbosses.targetting;
import com.songoda.epicbosses.CustomBosses;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossTargetManager;
import com.songoda.epicbosses.utils.ServerUtils;
import lombok.Getter;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 30-Oct-18
*/
public abstract class TargetHandler implements ITarget {
@Getter protected final BossTargetManager bossTargetManager;
@Getter protected final ActiveBossHolder activeBossHolder;
public TargetHandler(ActiveBossHolder activeBossHolder, BossTargetManager bossTargetManager) {
this.activeBossHolder = activeBossHolder;
this.bossTargetManager = bossTargetManager;
}
public void runTargetCycle() {
ServerUtils.get().runLaterAsync(100L, () -> {
updateTarget();
if(!getActiveBossHolder().isDead()) runTargetCycle();
});
}
protected LivingEntity getBossEntity() {
for(LivingEntity livingEntity : this.activeBossHolder.getLivingEntityMap().values()) {
if(livingEntity != null && !livingEntity.isDead()) return livingEntity;
}
return null;
}
private void updateTarget() {
LivingEntity boss = getBossEntity();
double radius = this.bossTargetManager.getTargetRadius();
if(boss == null) return;
List<LivingEntity> nearbyEntities = new ArrayList<>();
for(Entity entity : boss.getNearbyEntities(radius, radius, radius)) {
if(!(entity instanceof Player)) continue;
LivingEntity livingEntity = (LivingEntity) entity;
nearbyEntities.add(livingEntity);
}
updateBoss(selectTarget(nearbyEntities));
}
private void updateBoss(LivingEntity newTarget) {
this.activeBossHolder.getLivingEntityMap().values().forEach(livingEntity -> {
if(livingEntity != null && !livingEntity.isDead()) {
((Creature) livingEntity).setTarget(newTarget);
}
});
}
}

View File

@ -0,0 +1,37 @@
package com.songoda.epicbosses.targetting.types;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossTargetManager;
import com.songoda.epicbosses.targetting.TargetHandler;
import org.bukkit.entity.LivingEntity;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 30-Oct-18
*/
public class ClosestTargetHandler extends TargetHandler {
public ClosestTargetHandler(ActiveBossHolder activeBossHolder, BossTargetManager bossTargetManager) {
super(activeBossHolder, bossTargetManager);
}
@Override
public LivingEntity selectTarget(List<LivingEntity> nearbyEntities) {
LivingEntity boss = getBossEntity();
double radius = this.bossTargetManager.getTargetRadius();
double closestDistance = (radius * radius);
LivingEntity nearestTarget = null;
for(LivingEntity livingEntity : nearbyEntities) {
if(livingEntity.getLocation().distanceSquared(boss.getLocation()) > closestDistance) continue;
closestDistance = livingEntity.getLocation().distanceSquared(boss.getLocation());
nearestTarget = livingEntity;
}
return nearestTarget;
}
}

View File

@ -0,0 +1,31 @@
package com.songoda.epicbosses.targetting.types;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossTargetManager;
import com.songoda.epicbosses.targetting.TargetHandler;
import org.bukkit.entity.LivingEntity;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 02-Nov-18
*/
public class NotDamagedNearbyTargetHandler extends TargetHandler {
public NotDamagedNearbyTargetHandler(ActiveBossHolder activeBossHolder, BossTargetManager bossTargetManager) {
super(activeBossHolder, bossTargetManager);
}
@Override
public LivingEntity selectTarget(List<LivingEntity> nearbyEntities) {
for(LivingEntity livingEntity : nearbyEntities) {
if(getActiveBossHolder().hasAttacked(livingEntity.getUniqueId())) continue;
return livingEntity;
}
return null;
}
}

View File

@ -0,0 +1,28 @@
package com.songoda.epicbosses.targetting.types;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossTargetManager;
import com.songoda.epicbosses.targetting.TargetHandler;
import org.bukkit.entity.LivingEntity;
import java.util.Collections;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 30-Oct-18
*/
public class RandomNearbyTargetHandler extends TargetHandler {
public RandomNearbyTargetHandler(ActiveBossHolder activeBossHolder, BossTargetManager bossTargetManager) {
super(activeBossHolder, bossTargetManager);
}
@Override
public LivingEntity selectTarget(List<LivingEntity> nearbyEntities) {
Collections.shuffle(nearbyEntities);
return nearbyEntities.stream().findFirst().orElse(null);
}
}

View File

@ -0,0 +1,39 @@
package com.songoda.epicbosses.targetting.types;
import com.songoda.epicbosses.holder.ActiveBossHolder;
import com.songoda.epicbosses.managers.BossTargetManager;
import com.songoda.epicbosses.targetting.TargetHandler;
import com.songoda.epicbosses.utils.MapUtils;
import org.bukkit.entity.LivingEntity;
import java.util.*;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 30-Oct-18
*/
public class TopDamagerTargetHandler extends TargetHandler {
public TopDamagerTargetHandler(ActiveBossHolder activeBossHolder, BossTargetManager bossTargetManager) {
super(activeBossHolder, bossTargetManager);
}
@Override
public LivingEntity selectTarget(List<LivingEntity> nearbyEntities) {
Map<LivingEntity, Double> nearbyDamages = new HashMap<>();
Map<UUID, Double> mapOfDamages = getActiveBossHolder().getMapOfDamagingUsers();
nearbyEntities.forEach(livingEntity -> {
UUID uuid = livingEntity.getUniqueId();
if(mapOfDamages.containsKey(uuid)) {
nearbyDamages.put(livingEntity, mapOfDamages.get(uuid));
}
});
Map<LivingEntity, Double> sortedMap = MapUtils.get().sortByValue(nearbyDamages);
return sortedMap.keySet().stream().filter(livingEntity1 -> livingEntity1 != null && livingEntity1.isDead()).findFirst().orElse(null);
}
}

View File

@ -0,0 +1,31 @@
package com.songoda.epicbosses.utils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 03-Nov-18
*/
public class MapUtils {
private static MapUtils INSTANCE = new MapUtils();
public <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
Map<K, V> resultMap = new LinkedHashMap<>();
list.sort(Map.Entry.comparingByValue());
list.forEach(entry -> resultMap.put(entry.getKey(), entry.getValue()));
return resultMap;
}
public static MapUtils get() {
return INSTANCE;
}
}

View File

@ -19,7 +19,7 @@
</modules>
<properties>
<plugin.version>1.0.0-SNAPSHOT-U36</plugin.version>
<plugin.version>1.0.0-SNAPSHOT-U38</plugin.version>
<plugin.name>EpicBosses</plugin.name>
<plugin.main>com.songoda.epicbosses.CustomBosses</plugin.main>
<plugin.author>AMinecraftDev</plugin.author>