Feedback from testing

This commit is contained in:
Sam 2017-05-31 13:05:06 +01:00
parent c3a80ed0cb
commit 0edd2c8947
35 changed files with 898 additions and 219 deletions

View File

@ -1,7 +1,11 @@
package nautilus.game.arcade.game.games.moba;
import mineplex.core.common.Rank;
import mineplex.core.common.util.*;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.combat.DeathMessageType;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.GameType;
@ -12,7 +16,8 @@ import nautilus.game.arcade.game.TeamGame;
import nautilus.game.arcade.game.games.moba.boss.BossManager;
import nautilus.game.arcade.game.games.moba.boss.wither.WitherBoss;
import nautilus.game.arcade.game.games.moba.fountain.MobaFountain;
import nautilus.game.arcade.game.games.moba.general.TeamDamageManager;
import nautilus.game.arcade.game.games.moba.general.ArrowKBManager;
import nautilus.game.arcade.game.games.moba.general.MobaDamageManager;
import nautilus.game.arcade.game.games.moba.gold.GoldManager;
import nautilus.game.arcade.game.games.moba.kit.HeroKit;
import nautilus.game.arcade.game.games.moba.kit.KitPlayer;
@ -33,6 +38,7 @@ import nautilus.game.arcade.game.modules.CustomScoreboardModule;
import nautilus.game.arcade.game.modules.compass.CompassModule;
import nautilus.game.arcade.kit.Kit;
import nautilus.game.arcade.scoreboard.GameScoreboard;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Arrow;
@ -44,7 +50,13 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class Moba extends TeamGame
@ -66,6 +78,7 @@ public class Moba extends TeamGame
private final BossManager _boss;
private final TowerManager _tower;
private final CapturePointManager _capturePoint;
private final ArrowKBManager _arrowKb;
public Moba(ArcadeManager manager)
{
@ -88,13 +101,15 @@ public class Moba extends TeamGame
HungerSet = 20;
DamageFall = false;
manager.GetCreature().SetDisableCustomDrops(true);
// Instantiate managers
// Global managers
_shop = registerManager(new MobaShop(this));
_goldManager = registerManager(new GoldManager(this));
registerManager(new HPManager(this));
registerManager(new TeamDamageManager(this));
registerManager(new MobaDamageManager(this));
registerManager(new MobaFountain(this));
registerManager(new Recall(this));
@ -112,6 +127,9 @@ public class Moba extends TeamGame
// Minions
registerManager(new MinionManager(this));
// Arrow Knockback
_arrowKb = registerManager(new ArrowKBManager(this));
new CompassModule()
.setGiveCompass(true)
.setGiveCompassToSpecs(true)
@ -176,6 +194,9 @@ public class Moba extends TeamGame
return C.cYellow + " " + suffix + C.Reset;
})
.setUnderNameObjective(C.cRed + "")
.setUnderName((perspective, subject) ->
(int) (Math.ceil(subject.getHealth() / 2D)))
.register(this);
registerDebugCommand(new DebugCommand("kit", Rank.ADMIN)
@ -183,14 +204,14 @@ public class Moba extends TeamGame
@Override
public void Execute(Player caller, String[] args)
{
String kit = "";
StringBuilder builder = new StringBuilder();
for (String arg : args)
{
kit += arg + " ";
builder.append(arg).append(" ");
}
kit = kit.trim();
String kit = builder.toString().trim();
for (Kit kits : _kits)
{
@ -223,6 +244,8 @@ public class Moba extends TeamGame
{
locations.forEach(location -> location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, GetSpectatorLocation()))));
}
SpectatorSpawn = WorldData.GetCustomLocs("CENTER").get(0);
}
private void writePrepare(Player player, GameScoreboard scoreboard)
@ -259,21 +282,44 @@ public class Moba extends TeamGame
private void writeLive(Player player, GameScoreboard scoreboard)
{
GameTeam team = GetTeam(player);
boolean alive = IsAlive(player);
scoreboard.writeNewLine();
// GameTeam team = GetTeam(player);
// boolean blueBottom = team == null || team.GetColor() == ChatColor.BLUE;
//
// // Tower Data
// List<String> lines = new ArrayList<>();
// GameTeam red = GetTeam(ChatColor.RED);
// GameTeam blue = GetTeam(ChatColor.AQUA);
//
// lines.add("");
// Towers
GameTeam red = GetTeam(ChatColor.RED);
GameTeam blue = GetTeam(ChatColor.AQUA);
String redTitle;
String blueTitle;
if (alive)
{
boolean playerRed = team.equals(red);
redTitle = playerRed ? "Your Team" : "Enemy Team";
blueTitle = playerRed ? "Enemy Team" : "Your Team";
}
else
{
redTitle = "Red Team";
blueTitle = "Blue Team";
}
scoreboard.write(red.GetColor() + C.Bold + redTitle);
scoreboard.write("Base: " + _tower.getDisplayString(red) + _boss.getWitherDisplayString(red));
scoreboard.write("Beacons: " + _capturePoint.getDisplayString(red));
scoreboard.writeNewLine();
scoreboard.write(blue.GetColor() + C.Bold + blueTitle);
scoreboard.write("Base: " + _tower.getDisplayString(blue) + _boss.getWitherDisplayString(blue));
scoreboard.write("Beacons: " + _capturePoint.getDisplayString(blue));
scoreboard.writeNewLine();
// Gold
scoreboard.write(C.cGoldB + "Gold");
if (IsAlive(player))
scoreboard.write(C.cGoldB + "Your Gold");
if (alive)
{
int gold = _goldManager.getGold(player);
@ -553,6 +599,31 @@ public class Moba extends TeamGame
return players;
}
public boolean isRoleFree(Player player, MobaRole role)
{
GameTeam team = GetTeam(player);
if (team == null)
{
return false;
}
for (MobaPlayer mobaPlayer : getTeamData(team))
{
if (mobaPlayer.getRole() == role)
{
return false;
}
}
return true;
}
public CustomScoreboardModule getScoreboardModule()
{
return getModule(CustomScoreboardModule.class);
}
public MobaShop getShop()
{
return _shop;
@ -577,4 +648,9 @@ public class Moba extends TeamGame
{
return _boss;
}
public ArrowKBManager getArrowKbManager()
{
return _arrowKb;
}
}

View File

@ -46,7 +46,7 @@ public class MobaAI
return;
}
if (_target == null)
if (_target == null || _target.isDead() || !_target.isValid())
{
_target = MobaUtil.getBestEntityTarget(_host, _owner, _entity, _home, _host.WorldData.GetDataLocs(getBoundaryKey()));

View File

@ -9,13 +9,10 @@ import org.bukkit.util.Vector;
public class MobaDirectAIMethod implements MobaAIMethod
{
private static final float YAW_SNAP_LIMIT = 30F;
@Override
public boolean updateMovement(LivingEntity entity, Location goal, float speed)
{
Location entityLocation = entity.getLocation();
float entityYaw = entityLocation.getYaw();
// Speed is blocks per second
float magnitude = speed / 20F;
@ -25,32 +22,10 @@ public class MobaDirectAIMethod implements MobaAIMethod
// From the direction, get the yaw of this direction
float directionYaw = UtilAlg.GetYaw(direction);
entityLocation.setYaw(directionYaw);
// Get the absolute yaw offset from the direction
// This can then be used to see how far the entity is
// looking away from the goal
float yawOffset = Math.abs(directionYaw - entityYaw);
// If the entity is facing too far away from the goal to consider the
// "Head Snapping" of turning the entity too severe
if (yawOffset > YAW_SNAP_LIMIT)
{
// Facing too far right
if (entityYaw > directionYaw)
{
entityYaw -= YAW_SNAP_LIMIT;
}
// Facing too far left
else
{
entityYaw += YAW_SNAP_LIMIT;
}
// Only alter the entity's yaw
entityLocation.setYaw(entityYaw);
}
// If reached the goal
else if (UtilMath.offsetSquared(entityLocation, goal) < 4)
if (UtilMath.offsetSquared(entityLocation, goal) < 4)
{
return false;
}

View File

@ -6,6 +6,7 @@ import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.boss.pumpkin.PumpkinBoss;
import nautilus.game.arcade.game.games.moba.boss.wither.WitherBoss;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import nautilus.game.arcade.world.WorldData;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@ -74,6 +75,13 @@ public class BossManager implements Listener
_pumpkinBoss.cleanup();
}
public String getWitherDisplayString(GameTeam team)
{
WitherBoss boss = getWitherBoss(team);
return MobaUtil.getColour(boss.getHealthPercentage()) + "";
}
public WitherBoss getWitherBoss(GameTeam team)
{
return _teamBosses.get(team);

View File

@ -1,6 +1,7 @@
package nautilus.game.arcade.game.games.moba.boss.pumpkin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
@ -24,9 +25,11 @@ import nautilus.game.arcade.game.games.moba.ai.MobaAI;
import nautilus.game.arcade.game.games.moba.ai.goal.MobaAIMethod;
import nautilus.game.arcade.game.games.moba.ai.goal.MobaDirectAIMethod;
import nautilus.game.arcade.game.games.moba.boss.MobaBoss;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -38,11 +41,14 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -50,18 +56,20 @@ import java.util.concurrent.TimeUnit;
public class PumpkinBoss extends MobaBoss
{
private static final int SPAWN_TIME = (int) TimeUnit.MINUTES.toMillis(1);
private static final int RESPAWN_TIME = (int) TimeUnit.MINUTES.toMillis(1);
private static final int SPAWN_TIME = (int) TimeUnit.MINUTES.toMillis(5);
private static final int RESPAWN_TIME = (int) TimeUnit.MINUTES.toMillis(5);
private static final MobaAIMethod AI_METHOD = new MobaDirectAIMethod();
private static final ItemStack HELMET = new ItemStack(Material.PUMPKIN);
private static final ItemStack IN_HAND = new ItemStack(Material.STONE_SWORD);
private static final String DAMAGE_REASON = "Pumpkin King";
private static final String CONDITION_REASON = DAMAGE_REASON + " Buff";
private static final int CONDITION_LENGTH = (int) TimeUnit.MINUTES.toSeconds(3);
private static final int DAMAGE_RADIUS = 3;
private static final int DAMAGE_RANGE = 4;
private static final int DAMAGE_DIRECT = 10;
private static final int CONDITION_LENGTH = 60;
private static final double CONDITION_DAMAGE_FACTOR = 1.5;
private static final int DAMAGE_RADIUS = 2;
private static final int DAMAGE_RANGE = 3;
private static final int DAMAGE_DIRECT = 8;
private static final int DAMAGE_DIRECT_RADIUS_SQUARED = 9;
private static final int HEALTH = 400;
private static final Material[] BLOCKS = {
Material.OBSIDIAN,
Material.NETHERRACK,
@ -71,12 +79,14 @@ public class PumpkinBoss extends MobaBoss
private MobaAI _ai;
private boolean _initialSpawn;
private final Set<Block> _changed;
private final Set<Player> _buffs;
public PumpkinBoss(Moba host, Location location)
{
super(host, location, RESPAWN_TIME);
_changed = new HashSet<>();
_buffs = new HashSet<>();
}
@Override
@ -97,6 +107,8 @@ public class PumpkinBoss extends MobaBoss
skeleton.setCustomNameVisible(true);
skeleton.getEquipment().setHelmet(HELMET);
skeleton.getEquipment().setItemInHand(IN_HAND);
skeleton.setMaxHealth(HEALTH);
skeleton.setHealth(HEALTH);
UtilEnt.vegetate(skeleton);
UtilEnt.setFakeHead(skeleton, true);
@ -104,7 +116,7 @@ public class PumpkinBoss extends MobaBoss
skeleton.getWorld().strikeLightningEffect(skeleton.getLocation());
UtilTextMiddle.display(C.cDRedB + "The Pumpkin King", "Has Awoken!", 10, 40, 10);
_host.Announce(C.cRedB + "The Pumpkin King Has Awoken!", false);
_host.Announce(F.main("Game", C.cRedB + "The Pumpkin King Has Awoken!"), false);
for (Player player : Bukkit.getOnlinePlayers())
{
@ -191,27 +203,32 @@ public class PumpkinBoss extends MobaBoss
giveBuffs(team);
String base = C.mBody + "killed the " + C.cDRedB + "Pumpkin King";
_host.Announce(team.GetFormattedName() + " " + base + C.mBody + "! They have been given buffs!", false);
UtilTextMiddle.display(team.GetFormattedName(), base, 10, 40, 10);
_host.Announce(F.main("Game", team.GetFormattedName() + C.mBody + " killed the " + C.cDRedB + DAMAGE_REASON), false);
UtilTextMiddle.display("", team.GetFormattedName() + C.cWhite + " killed the " + C.cDRedB + DAMAGE_REASON, 10, 40, 10);
for (Block block : _changed)
{
_host.getArcadeManager().GetBlockRestore().restore(block);
}
event.getEntity().getWorld().playSound(event.getEntity().getLocation(), Sound.EXPLODE, 1, 0.2F);
UtilParticle.PlayParticle(ParticleType.HUGE_EXPLOSION, event.getEntity().getEyeLocation(), 1, 1, 1, 0.1F, 3, ViewDist.LONG);
}
@EventHandler
@EventHandler(priority = EventPriority.HIGHEST)
public void entityDamage(CustomDamageEvent event)
{
if (!event.GetDamageeEntity().equals(_entity) || event.GetCause() != DamageCause.SUFFOCATION)
if (!event.GetDamageeEntity().equals(_entity))
{
return;
}
event.SetCancelled("Pumpkin King Suffocation");
updateDisplay();
if (event.GetCause() == DamageCause.SUFFOCATION)
{
event.SetCancelled("Pumpkin King Suffocation");
}
}
@EventHandler
@ -224,7 +241,7 @@ public class PumpkinBoss extends MobaBoss
if (_ai.getTarget() != null && !UtilPlayer.isSpectator(_ai.getTarget()) && UtilMath.offsetSquared(_entity, _ai.getTarget()) < DAMAGE_DIRECT_RADIUS_SQUARED)
{
_host.getArcadeManager().GetDamage().NewDamageEvent(_ai.getTarget(), _entity, null, DamageCause.CUSTOM, DAMAGE_DIRECT, true, true, false, UtilEnt.getName(_entity), DAMAGE_REASON);
_host.getArcadeManager().GetDamage().NewDamageEvent(_ai.getTarget(), _entity, null, DamageCause.CUSTOM, DAMAGE_DIRECT, true, true, false, DAMAGE_REASON, DAMAGE_REASON);
// Send a fake hit packet
// Magic number 0 means swing item/attack
@ -243,36 +260,90 @@ public class PumpkinBoss extends MobaBoss
continue;
}
_host.getArcadeManager().GetDamage().NewDamageEvent(entity, _entity, null, DamageCause.CUSTOM, DAMAGE_RANGE, false, true, false, UtilEnt.getName(entity), DAMAGE_REASON);
_host.getArcadeManager().GetDamage().NewDamageEvent(entity, _entity, null, DamageCause.CUSTOM, DAMAGE_RANGE, false, true, false, DAMAGE_REASON, DAMAGE_REASON);
UtilAction.velocity(entity, UtilAlg.getTrajectory(_entity, entity).setY(1));
UtilParticle.PlayParticleToAll(ParticleType.FLAME, entity.getLocation().add(0, 1, 0), 0.5F, 0.5F, 0.5F, 0.1F, 5, ViewDist.LONG);
}
}
private void updateDisplay()
{
_entity.setCustomName(MobaUtil.getHealthBar(_entity, 20));
}
private void giveBuffs(GameTeam team)
{
ConditionFactory factory = _host.getArcadeManager().GetCondition().Factory();
for (Player player : team.GetPlayers(true))
{
factory.Regen(CONDITION_REASON, player, null, CONDITION_LENGTH, 2, false, true, false);
factory.Strength(CONDITION_REASON, player, null, CONDITION_LENGTH, 1, false, true, false);
factory.Regen(CONDITION_REASON, player, null, CONDITION_LENGTH, 1, false, true, false);
UtilParticle.PlayParticleToAll(ParticleType.LAVA, player.getLocation().add(0, 1, 0), 0.5F, 0.5F, 0.5F, 0.1F, 10, ViewDist.LONG);
player.playSound(player.getLocation(), Sound.PORTAL_TRAVEL, 1, 0.5F);
player.sendMessage(F.main("Game", "You feel the power of the Pumpkin King flow through you. Your damage and regeneration are increased!"));
_buffs.add(player);
// Magic number 4 means helmet
PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment(player.getEntityId(), 4, CraftItemStack.asNMSCopy(HELMET));
sendFakeHelmet(player);
}
}
for (Player other : Bukkit.getOnlinePlayers())
@EventHandler
public void updateFakeHelmet(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOW)
{
return;
}
Iterator<Player> iterator = _buffs.iterator();
while (iterator.hasNext())
{
Player player = iterator.next();
if (!player.isOnline() || !player.hasPotionEffect(PotionEffectType.REGENERATION))
{
// Don't send wearer their own data
if (other.equals(player))
{
continue;
}
UtilPlayer.sendPacket(other, packet);
iterator.remove();
}
sendFakeHelmet(player);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void damageIncrease(CustomDamageEvent event)
{
if (event.isCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
Player damager = event.GetDamagerPlayer(true);
if (damager == null || !_buffs.contains(damager))
{
return;
}
UtilParticle.PlayParticleToAll(ParticleType.LARGE_SMOKE, damagee.getLocation().add(0, 0.5, 0), 0.25F, 0.25F, 0.25F, 10, 1, ViewDist.NORMAL);
event.AddMod(CONDITION_REASON, CONDITION_DAMAGE_FACTOR);
}
private void sendFakeHelmet(Player player)
{
// Magic number 4 means helmet
PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment(player.getEntityId(), 4, CraftItemStack.asNMSCopy(HELMET));
for (Player other : Bukkit.getOnlinePlayers())
{
// Don't send wearer their own data
if (other.equals(player))
{
continue;
}
UtilPlayer.sendPacket(other, packet);
}
}
}

View File

@ -1,11 +1,11 @@
package nautilus.game.arcade.game.games.moba.boss.wither;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilTextTop;
import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.disguise.disguises.DisguiseWither;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ -34,14 +34,12 @@ public class WitherBoss extends MobaBoss
private static final float SPEED_TARGET = 7F;
private static final float SPEED_HOME = 9F;
private static final int INITIAL_HEALTH = 1750;
private static final int FIRST_TOWER_HEALTH_REDUCTION = 100;
private static final int SECOND_TOWER_HEALTH_REDUCTION = 250;
private static final MobaAIMethod AI_METHOD = new MobaDirectAIMethod();
private GameTeam _team;
private MobaAI _ai;
private DisguiseWither _disguise;
private boolean _damageable;
public WitherBoss(Moba host, Location location, GameTeam team)
{
@ -56,10 +54,13 @@ public class WitherBoss extends MobaBoss
{
ArmorStand stand = _location.getWorld().spawn(_location, ArmorStand.class);
// Reducing the wither's health to 10% gives a shield like effect.
stand.setMaxHealth(INITIAL_HEALTH);
stand.setHealth(INITIAL_HEALTH);
stand.setHealth(INITIAL_HEALTH * 0.1);
stand.setGravity(false);
UtilEnt.setBoundingBox(stand, 3, 5);
_disguise = new DisguiseWither(stand);
_disguise.setName(_team.GetColor() + _team.GetName() + "\'s Wither");
_disguise.setCustomNameVisible(true);
@ -102,11 +103,18 @@ public class WitherBoss extends MobaBoss
event.SetCancelled("Wither Boss");
// Fire doesn't damage the wither
if (event.GetCause() == DamageCause.FIRE || event.GetCause() == DamageCause.FIRE_TICK)
{
return;
}
// If not damageable
if (!_damageable)
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
Player damager = event.GetDamagerPlayer(true);
@ -147,16 +155,13 @@ public class WitherBoss extends MobaBoss
return;
}
if (tower.isFirstTower())
// Here we can remove the shield effect, as the wither is no longer invincible
if (!tower.isFirstTower())
{
_entity.setHealth(_entity.getHealth() - FIRST_TOWER_HEALTH_REDUCTION);
_damageable = true;
_entity.setHealth(INITIAL_HEALTH);
updateDisplay();
}
else
{
_entity.setHealth(_entity.getHealth() - SECOND_TOWER_HEALTH_REDUCTION);
}
updateDisplay();
}
@EventHandler
@ -167,14 +172,19 @@ public class WitherBoss extends MobaBoss
return;
}
double percent = _entity.getHealth() / _entity.getMaxHealth();
double percent = getHealthPercentage();
for (Player player : _team.GetPlayers(true))
{
UtilTextTop.displayTextBar(player, percent, _team.GetColor() + "Your Wither");
UtilTextTop.displayTextBar(player, percent, _team.GetColor() + "Your Wither");
}
}
public double getHealthPercentage()
{
return _damageable ? (_entity.getHealth() / _entity.getMaxHealth()) : 1;
}
private void updateDisplay()
{
_disguise.setName(MobaUtil.getHealthBar(_entity, 40));

View File

@ -33,8 +33,9 @@ public class WitherSkullProjectile implements IThrown
_manager = host.getArcadeManager();
_owner = owner;
WitherSkull skull = shooter.launchProjectile(WitherSkull.class);
WitherSkull skull = shooter.getWorld().spawn(shooter.getLocation().add(0, 2, 0), WitherSkull.class);
skull.setShooter(shooter);
skull.setYield(0);
skull.setVelocity(skull.getVelocity().add(UtilAlg.getTrajectory(shooter, target)));
@ -58,7 +59,7 @@ public class WitherSkullProjectile implements IThrown
// Not team damage
if (!_owner.equals(targetTeam))
{
_manager.GetDamage().NewDamageEvent(target, data.getThrower(), null, DamageCause.CUSTOM, DAMAGE, true, true, false, UtilEnt.getName(data.getThrower()), "Wither Skull");
_manager.GetDamage().NewDamageEvent(target, data.getThrower(), null, DamageCause.CUSTOM, DAMAGE, true, true, false, "Wither Boss", "Wither Skull");
}
Expire(data);

View File

@ -83,7 +83,7 @@ public class MobaFountain implements Listener
}
else
{
_host.getArcadeManager().GetDamage().NewDamageEvent(player, null, null, DamageCause.CUSTOM, 6, false, true, true, "Fountain", "Fountain");
_host.getArcadeManager().GetDamage().NewDamageEvent(player, null, null, DamageCause.CUSTOM, 10, false, true, true, "Fountain", "Fountain");
}
}
}

View File

@ -0,0 +1,41 @@
package nautilus.game.arcade.game.games.moba.general;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.moba.Moba;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.metadata.FixedMetadataValue;
public class ArrowKBManager implements Listener
{
private static final String ENTITY_METADATA = "KB";
private final Moba _host;
public ArrowKBManager(Moba host)
{
_host = host;
}
@EventHandler
public void arrowDamage(CustomDamageEvent event)
{
Projectile projectile = event.GetProjectile();
if (projectile == null || projectile.getType() != EntityType.ARROW || projectile.hasMetadata(ENTITY_METADATA))
{
return;
}
event.SetKnockback(false);
}
public void allowKnockback(Entity projectile)
{
projectile.setMetadata(ENTITY_METADATA, new FixedMetadataValue(_host.getArcadeManager().getPlugin(), true));
}
}

View File

@ -1,5 +1,7 @@
package nautilus.game.arcade.game.games.moba.general;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent;
@ -10,12 +12,12 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class TeamDamageManager implements Listener
public class MobaDamageManager implements Listener
{
private final Moba _host;
public TeamDamageManager(Moba host)
public MobaDamageManager(Moba host)
{
_host = host;
}
@ -43,6 +45,10 @@ public class TeamDamageManager implements Listener
{
event.SetCancelled("Team Damage");
}
else
{
_host.getScoreboardModule().refreshAsSubject(damagee);
}
}
@EventHandler
@ -73,4 +79,14 @@ public class TeamDamageManager implements Listener
event.setCancelled(true);
}
@EventHandler
public void updateDamageScoreboard(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
_host.getScoreboardModule().refresh();
}
}

View File

@ -1,6 +1,7 @@
package nautilus.game.arcade.game.games.moba.gold;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ -10,6 +11,9 @@ import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.structure.point.CapturePoint;
import nautilus.game.arcade.game.games.moba.structure.point.CapturePointCaptureEvent;
import nautilus.game.arcade.game.games.moba.structure.tower.TowerDestroyEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@ -24,6 +28,10 @@ public class GoldManager implements Listener
private static final int GOLD_PER_5 = 20;
private static final int GOLD_PER_CAPTURE_5 = 5;
private static final int GOLD_PER_CAPTURE_INITIAL = 25;
private static final int GOLD_PER_FIRST_TOWER = 100;
private static final int GOLD_PER_SECOND_TOWER = 250;
private final Moba _host;
@ -112,14 +120,50 @@ public class GoldManager implements Listener
}
}
@EventHandler
public void towerDestroy(TowerDestroyEvent event)
{
for (Player player : _host.GetPlayers(true))
{
// Don't give the gold to the owners
if (_host.GetTeam(player).equals(event.getTower().getOwner()))
{
continue;
}
addGold(player, event.getTower().isFirstTower() ? GOLD_PER_FIRST_TOWER : GOLD_PER_SECOND_TOWER, "Destroying a tower");
}
}
@EventHandler
public void pointCapture(CapturePointCaptureEvent event)
{
GameTeam team = event.getPoint().getOwner();
for (Player player : team.GetPlayers(true))
{
addGold(player, GOLD_PER_CAPTURE_INITIAL, "Capturing a beacon");
}
}
public int getGold(Player player)
{
return _playerGold.get(player);
}
public void addGold(Player player, int amount)
{
addGold(player, amount, null);
}
public void addGold(Player player, int amount, String reason)
{
_playerGold.put(player, _playerGold.get(player) + amount);
if (amount > 20 && reason != null)
{
player.sendMessage(F.main("Game", C.cGold + "+" + amount + " gold (" + reason + ")" + C.cGray + "."));
}
}
public void removeGold(Player player, int amount)

View File

@ -1,7 +1,12 @@
package nautilus.game.arcade.game.games.moba.kit;
import mineplex.core.common.util.*;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
@ -16,13 +21,18 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class HeroSkill extends Perk
{
@ -31,7 +41,8 @@ public class HeroSkill extends Perk
private ItemStack _cooldownItem;
private final int _slot;
private final ActionType _actionType;
private final boolean _sneakActivate;
private boolean _sneakActivate;
private boolean _dropItemActivate;
protected HeroKit _kit;
private long _cooldown;
@ -44,11 +55,6 @@ public class HeroSkill extends Perk
}
public HeroSkill(String name, String[] perkDesc, ItemStack itemStack, int slot, ActionType actionType)
{
this(name, perkDesc, itemStack, slot, actionType, false);
}
public HeroSkill(String name, String[] perkDesc, ItemStack itemStack, int slot, ActionType actionType, boolean sneakActivate)
{
super(name, perkDesc);
@ -56,11 +62,20 @@ public class HeroSkill extends Perk
_items.add(itemStack);
_slot = slot;
_actionType = actionType;
_sneakActivate = sneakActivate;
prettifyItems();
}
public void setSneakActivate(boolean activate)
{
_sneakActivate = activate;
}
public void setDropItemActivate(boolean activate)
{
_dropItemActivate = activate;
}
protected void setCooldown(long cooldown)
{
_cooldown = cooldown;
@ -149,6 +164,11 @@ public class HeroSkill extends Perk
_lastSkill.remove(key);
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
}
protected boolean isSkillItem(PlayerInteractEvent event)
{
if (event.isCancelled())
@ -209,6 +229,25 @@ public class HeroSkill extends Perk
return false;
}
@EventHandler
public void dropTrigger(PlayerDropItemEvent event)
{
Player player = event.getPlayer();
if (!_dropItemActivate || !hasPerk(player))
{
return;
}
// Call interact with a fake PlayerInteractEvent
PlayerInteractEvent interactEvent = new PlayerInteractEvent(event.getPlayer(), Action.RIGHT_CLICK_AIR, player.getInventory().getItem(_slot), null, null);
// You actually need to setCancelled false here otherwise it remains cancelled by default when the clicked block is null, thanks Bukkit
interactEvent.setCancelled(false);
interact(interactEvent);
}
public void useSkill(Player player)
{
_lastSkill.put(player.getUniqueId(), System.currentTimeMillis());

View File

@ -1,6 +1,7 @@
package nautilus.game.arcade.game.games.moba.kit.anath;
import mineplex.core.common.util.UtilEvent.ActionType;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
import nautilus.game.arcade.game.games.moba.util.MobaConstants;
import org.bukkit.Material;
@ -18,6 +19,7 @@ public class SkillFireProjectile extends HeroSkill
"Fires an Ember at high speed in front of you.",
"Any enemies it collides with take damage and are set on fire."
};
private static final int DAMAGE = 5;
private static final ItemStack SKILL_ITEM = new ItemStack(Material.BLAZE_ROD);
@ -45,6 +47,7 @@ public class SkillFireProjectile extends HeroSkill
Item item = player.getWorld().dropItem(player.getEyeLocation().add(direction), _kit.getAmmo());
item.setVelocity(direction);
Manager.GetFire().Add(item, player, 3, 0, 1, 5, MobaConstants.BASIC_ATTACK, false);
((Moba) Manager.GetGame()).getTowerManager().addProjectile(player, item, DAMAGE);
Manager.GetFire().Add(item, player, 3, 0, 1, DAMAGE, MobaConstants.BASIC_ATTACK, false);
}
}

View File

@ -42,8 +42,10 @@ public class SkillMeteor extends HeroSkill implements IThrown
super("Meteor Shower", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(60000);
setDropItemActivate(true);
}
@Override
@EventHandler
public void interact(PlayerInteractEvent event)
{

View File

@ -71,8 +71,10 @@ public class SkillBuildPainting extends HeroSkill implements IThrown
super("The Joy Of Painting", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(60000);
setDropItemActivate(true);
}
@Override
@EventHandler
public void interact(PlayerInteractEvent event)
{

View File

@ -6,6 +6,7 @@ import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilMath;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileUser;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -28,6 +29,7 @@ public class SkillPaint extends HeroSkill implements IThrown
"Bob Ross"
};
private static final byte[] COLOURS = { 14, 1, 4, 5, 3, 11, 0};
private static final int DAMAGE = 2;
private static final ItemStack SKILL_ITEM = new ItemStack(Material.DIAMOND_BARDING);
@ -55,6 +57,7 @@ public class SkillPaint extends HeroSkill implements IThrown
Snowball snowball = player.launchProjectile(Snowball.class);
((Moba) Manager.GetGame()).getTowerManager().addProjectile(player, snowball, DAMAGE);
Manager.GetProjectile().AddThrow(snowball, player, this, -1, true, true, true, false, 0.5F);
}
@ -67,7 +70,7 @@ public class SkillPaint extends HeroSkill implements IThrown
if (target != null)
{
thrower.playSound(thrower.getLocation(), Sound.LAVA_POP, 1, 1.3F);
Manager.GetDamage().NewDamageEvent(target, thrower, (Projectile) data.getThrown(), DamageCause.PROJECTILE, 2, true, true, false, UtilEnt.getName(thrower), GetName());
Manager.GetDamage().NewDamageEvent(target, thrower, (Projectile) data.getThrown(), DamageCause.PROJECTILE, DAMAGE, true, true, false, UtilEnt.getName(thrower), GetName());
}
for (Block nearby : UtilBlock.getBlocksInRadius(data.getThrown().getLocation(), 2))

View File

@ -49,9 +49,10 @@ public class DashSkill extends HeroSkill
public DashSkill(String name, String[] perkDesc, ItemStack itemStack, int slot)
{
super(name, perkDesc, itemStack, slot, ActionType.ANY, true);
super(name, perkDesc, itemStack, slot, ActionType.ANY);
_startTime = new HashMap<>();
setSneakActivate(true);
}
@EventHandler

View File

@ -19,6 +19,7 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
@ -44,8 +45,10 @@ public class SkillRally extends HeroSkill
super("Rally", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(40000);
setDropItemActivate(true);
}
@Override
@EventHandler
public void interact(PlayerInteractEvent event)
{
@ -197,6 +200,12 @@ public class SkillRally extends HeroSkill
}
}
@EventHandler
public void playerDeath(PlayerDeathEvent event)
{
_data.removeIf(rallyData -> rallyData.Owner.equals(event.getEntity()));
}
private Pattern getPattern(GameTeam team)
{
return team.GetColor() == ChatColor.RED ? new Pattern(DyeColor.WHITE, PatternType.CROSS) : new Pattern(DyeColor.WHITE, PatternType.CIRCLE_MIDDLE);

View File

@ -8,6 +8,7 @@ import nautilus.game.arcade.game.games.moba.kit.HeroKit;
import nautilus.game.arcade.game.games.moba.kit.common.SkillBow;
import nautilus.game.arcade.kit.Perk;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.inventory.ItemStack;
public class HeroDevon extends HeroKit
@ -36,6 +37,6 @@ public class HeroDevon extends HeroKit
super(manager, "Devon", DESCRIPTION, PERKS, IN_HAND, MobaRole.HUNTER);
setAmmo(AMMO, 3000);
setMaxAmmo(1);
setMaxAmmo(3);
}
}

View File

@ -20,9 +20,10 @@ public class SkillBoost extends HeroSkill
public SkillBoost(int slot)
{
super("Hunters Boost", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY, true);
super("Hunters Boost", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(10000);
setSneakActivate(true);
}
@EventHandler

View File

@ -8,11 +8,13 @@ import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
@ -42,8 +44,10 @@ public class SkillInfinity extends HeroSkill
super("Infinity", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(60000);
setDropItemActivate(true);
}
@Override
@EventHandler
public void interact(PlayerInteractEvent event)
{
@ -85,6 +89,9 @@ public class SkillInfinity extends HeroSkill
return;
}
Moba moba = (Moba) Manager.GetGame();
moba.getArrowKbManager().allowKnockback(event.getProjectile());
_arrows.put(event.getProjectile(), player);
}

View File

@ -7,6 +7,7 @@ import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
import org.bukkit.Location;
import org.bukkit.Material;
@ -95,6 +96,9 @@ public class SkillTNTArrows extends HeroSkill
itemStack.setAmount(arrows);
}
Moba moba = (Moba) Manager.GetGame();
moba.getArrowKbManager().allowKnockback(event.getProjectile());
_arrows.add((Arrow) event.getProjectile());
}

View File

@ -32,6 +32,7 @@ public class SkillNinjaBlade extends HeroSkill
private static final ItemStack SKILL_ITEM = new ItemStack(Material.NETHER_STAR);
private static final ItemStack ACTIVE_ITEM = new ItemBuilder(Material.DIAMOND_SWORD)
.setTitle(C.cGreenB + "NINJA BLADE")
.setUnbreakable(true)
.build();
private Set<UUID> _active = new HashSet<>();
@ -41,8 +42,10 @@ public class SkillNinjaBlade extends HeroSkill
super("Ninja Blade", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(60000);
setDropItemActivate(true);
}
@Override
@EventHandler
public void interact(PlayerInteractEvent event)
{
@ -54,6 +57,7 @@ public class SkillNinjaBlade extends HeroSkill
Player player = event.getPlayer();
player.getInventory().setItem(getSlot(), ACTIVE_ITEM);
player.getInventory().setHeldItemSlot(getSlot());
_active.add(player.getUniqueId());
useActiveSkill(() -> _active.remove(player.getUniqueId()), player, 7000);
@ -71,7 +75,9 @@ public class SkillNinjaBlade extends HeroSkill
return;
}
if (!_active.contains(player.getUniqueId()) || player.getItemInHand() == null || player.getItemInHand().getType() != Material.DIAMOND_SWORD)
ItemStack itemStack = player.getItemInHand();
if (!_active.contains(player.getUniqueId()) || itemStack == null || itemStack.getType() != Material.DIAMOND_SWORD || itemStack.getItemMeta() == null || !itemStack.getItemMeta().getDisplayName().equals(ACTIVE_ITEM.getItemMeta().getDisplayName()))
{
return;
}

View File

@ -4,6 +4,7 @@ import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileUser;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -25,6 +26,7 @@ public class SkillSnowball extends HeroSkill implements IThrown
"Fires 3 snowballs, one after another.",
"Each snowball deals 3 damage to any enemy it hits."
};
private static final int DAMAGE = 3;
private static final ItemStack SKILL_ITEM = new ItemStack(Material.SNOW_BALL);
public SkillSnowball(int slot)
@ -57,6 +59,7 @@ public class SkillSnowball extends HeroSkill implements IThrown
{
Snowball snowball = player.launchProjectile(Snowball.class);
((Moba) Manager.GetGame()).getTowerManager().addProjectile(player, snowball, DAMAGE);
Manager.GetProjectile().AddThrow(snowball, player, SkillSnowball.this, -1, true, true, true, false, 0.5F);
if (++balls == 3)
@ -75,7 +78,7 @@ public class SkillSnowball extends HeroSkill implements IThrown
if (target != null && !isTeamDamage(target, thrower))
{
thrower.playSound(thrower.getLocation(), Sound.LAVA_POP, 1, 1.3F);
Manager.GetDamage().NewDamageEvent(target, thrower, (Projectile) data.getThrown(), DamageCause.CUSTOM, 3, true, true, false, UtilEnt.getName(thrower), GetName());
Manager.GetDamage().NewDamageEvent(target, thrower, (Projectile) data.getThrown(), DamageCause.CUSTOM, DAMAGE, true, true, false, UtilEnt.getName(thrower), GetName());
}
}

View File

@ -36,12 +36,12 @@ public class Minion
UtilEnt.setBoundingBox(entity, HIT_BOX, HIT_BOX);
entity.setCustomNameVisible(true);
updateDisplay();
updateDisplay(entity.getMaxHealth());
}
public void updateDisplay()
public void updateDisplay(double health)
{
_entity.setCustomName(MobaUtil.getHealthBar(_entity, 10));
_entity.setCustomName(MobaUtil.getHealthBar(_entity, health, 10));
}
public LivingEntity getEntity()

View File

@ -3,7 +3,7 @@ package nautilus.game.arcade.game.games.moba.minion;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.recharge.Recharge;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
@ -16,6 +16,7 @@ import nautilus.game.arcade.game.games.moba.boss.wither.WitherBoss;
import nautilus.game.arcade.game.games.moba.structure.tower.Tower;
import nautilus.game.arcade.game.games.moba.util.MobaConstants;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -29,14 +30,15 @@ import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MinionWave implements Listener
{
private static final int MAX_MINIONS_PER_WAVE = 6;
private static final int TOO_CLOSE_SQUARED = 9;
private static final int MINION_TOO_CLOSE_SQUARED = 16;
private static final int DAMAGE_RANGE_SQUARED = 16;
private static final double DAMAGE_AMOUNT = 0.2;
private static final MobaAIMethod AI_METHOD = new MobaDirectAIMethod();
@ -49,6 +51,8 @@ public class MinionWave implements Listener
private final List<Location> _path;
private final List<Minion> _minions;
//private final Map<Entity, Long> _lastDamage;
public MinionWave(Moba host, MinionManager minionManager, GameTeam owner, List<Location> path, Class<? extends LivingEntity> clazz)
{
_host = host;
@ -57,6 +61,7 @@ public class MinionWave implements Listener
_clazz = clazz;
_path = path;
_minions = new ArrayList<>(MAX_MINIONS_PER_WAVE);
//_lastDamage = new HashMap<>(MAX_MINIONS_PER_WAVE);
UtilServer.RegisterEvents(this);
@ -371,11 +376,24 @@ public class MinionWave implements Listener
if (minion != null)
{
minion.updateDisplay();
minion.updateDisplay(minion.getEntity().getHealth() - event.GetDamage());
}
}
}
// @EventHandler(priority = EventPriority.MONITOR)
// public void damageSound(CustomDamageEvent event)
// {
// LivingEntity damagee = event.GetDamageeEntity();
//
// if (event.isCancelled() || !isMinion(damagee) || !UtilTime.elapsed(_lastDamage.get(damagee), 2000))
// {
// return;
// }
//
// damagee.getWorld().playSound(damagee.getLocation(), Sound.ZOMBIE_HURT, 1, 1.4F);
// }
@EventHandler
public void entityCombust(EntityCombustEvent event)
{
@ -403,6 +421,7 @@ public class MinionWave implements Listener
}
event.getDrops().clear();
event.setDroppedExp(0);
}
public void cleanup()

View File

@ -64,7 +64,7 @@ public class PrepareInformation implements Listener
String[] description = mobaPlayer.getRole().getDescription();
// Description is too short
if (description.length > _messageIndex + 2)
if (description.length <= _messageIndex + 1)
{
continue;
}

View File

@ -30,7 +30,6 @@ public class PrepareManager implements Listener
{
private static final long PREPARE_TIME = TimeUnit.MINUTES.toMillis(1);
private static final String OWNED_METADATA = "owned";
private final Moba _host;
@ -108,21 +107,21 @@ public class PrepareManager implements Listener
MobaRole role = event.getRole();
ClientArmorStand stand = event.getStand();
if (stand.hasMetadata(OWNED_METADATA))
if (!_host.isRoleFree(player, role))
{
player.sendMessage(F.main("Game", "Another player has already chosen this role."));
event.setCancelled(true);
return;
}
// Store inside the stand that it is claimed by a player
stand.setMetadata(OWNED_METADATA, new FixedMetadataValue(_host.getArcadeManager().getPlugin(), true));
// Show that the kit is claimed.
stand.setCustomName(C.cGreenB + role.getName() + C.cGray + " - " + player.getName());
// Store the role of the player
_host.getMobaData(player).setRole(role);
// Update the scoreboard
_host.getScoreboardModule().refreshAsSubject(player);
}
@EventHandler

View File

@ -1,25 +1,48 @@
package nautilus.game.arcade.game.games.moba.structure.point;
import mineplex.core.common.util.*;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
public class CapturePoint
{
private static final int MAX_RADIUS = 5;
private static final int MAX_PROGRESS = 10;
private static final int MAX_PROGRESS = 5;
private static final int MAX_PROGRESS_NETURAL = 10;
private static final int MIN_INFORM_TIME = (int) TimeUnit.SECONDS.toMillis(30);
private final Moba _host;
private final String _name;
private final ChatColor _colour;
private final Location _center;
private final List<Block> _wool;
private final List<Block> _changed;
@ -29,10 +52,13 @@ public class CapturePoint
private GameTeam _owner;
private GameTeam _side;
private int _progress;
private long _lastInform;
public CapturePoint(Moba host, Location center)
public CapturePoint(Moba host, String name, ChatColor colour, Location center)
{
_host = host;
_name = name;
_colour = colour;
_center = center;
_wool = new ArrayList<>(36);
_changed = new ArrayList<>(_wool.size());
@ -117,9 +143,23 @@ public class CapturePoint
{
return;
}
// Players on the point
// Only inform if it has been a while
else if (!_owner.equals(highest) && UtilTime.elapsed(_lastInform, MIN_INFORM_TIME))
{
_lastInform = System.currentTimeMillis();
for (Player player : Bukkit.getOnlinePlayers())
{
player.playSound(player.getLocation(), Sound.GHAST_SCREAM2, 1, 1.2F);
}
_host.Announce(F.main("Game", "Team " + highest.GetFormattedName() + C.mBody + " is capturing beacon " + _colour + _name + C.mBody + "!"), false);
UtilTextMiddle.display("", "Team " + highest.GetFormattedName() + C.cWhite + " is capturing beacon " + _colour + _name, 0, 30, 10);
}
// If it has just reached the maximum progress, set the owner.
if (_owner != null && _owner.equals(highest) && _progress >= MAX_PROGRESS)
if (_owner != null && _owner.equals(highest) && _progress >= (_owner == null ? MAX_PROGRESS_NETURAL : MAX_PROGRESS))
{
return;
}
@ -143,7 +183,7 @@ public class CapturePoint
display(team, true);
// Captured
if (_progress >= MAX_PROGRESS)
if (_progress >= (_owner == null ? MAX_PROGRESS_NETURAL : MAX_PROGRESS))
{
setOwner(team);
}
@ -168,23 +208,36 @@ public class CapturePoint
private void setOwner(GameTeam team)
{
// Same team
if (_owner != null && _owner.equals(team))
setBeaconColour(team);
if (_owner != null)
{
return;
// Same team no need to inform
if (_owner.equals(team))
{
return;
}
}
else
{
// As the point is easier to capture after the initial capture
// We need to adjust the current progress, otherwise it has to go
// from 10 to 0 then to 5 which is unintended
_progress = MAX_PROGRESS;
}
_owner = team;
setBeaconColour(team);
UtilFirework.playFirework(_center, Type.BURST, team.GetColorBase(), false, false);
_host.Announce(F.main("Game", "Team " + team.GetFormattedName() + C.mBody + " captured beacon " + _colour + _name + C.mBody + "!"));
UtilTextMiddle.display("", "Team " + team.GetFormattedName() + C.cWhite + " captured beacon " + _colour + _name, 0, 30, 10);
UtilFirework.playFirework(_center, Type.BURST, team.GetColorBase(), false, false);
UtilServer.CallEvent(new CapturePointCaptureEvent(this));
}
private void display(GameTeam team, boolean forward)
{
double toChange = Math.ceil(_wool.size() / MAX_PROGRESS) + 1;
double toChange = Math.ceil(_wool.size() / (_owner == null ? MAX_PROGRESS_NETURAL : MAX_PROGRESS)) + 1;
int changed = 0;
for (Block block : _wool)
{
@ -231,6 +284,11 @@ public class CapturePoint
_center.getBlock().getRelative(BlockFace.DOWN).setData(colour);
}
public ChatColor getColour()
{
return _colour;
}
public GameTeam getOwner()
{
return _owner;

View File

@ -1,17 +1,20 @@
package nautilus.game.arcade.game.games.moba.structure.point;
import mineplex.core.common.util.C;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import nautilus.game.arcade.events.GameStateChangeEvent;
import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
public class CapturePointManager implements Listener
{
@ -35,11 +38,28 @@ public class CapturePointManager implements Listener
return;
}
Collection<Location> capturePoints = _host.getLocationStartsWith("POINT").values();
for (Location location : capturePoints)
for (Entry<String, Location> entry : _host.getLocationStartsWith("POINT").entrySet())
{
_capturePoints.add(new CapturePoint(_host, location));
String[] split = entry.getKey().split(" ");
if (split.length < 3)
{
continue;
}
String name = split[1];
ChatColor colour;
try
{
colour = ChatColor.valueOf(split[2]);
}
catch (IllegalArgumentException e)
{
continue;
}
_capturePoints.add(new CapturePoint(_host, name, colour, entry.getValue()));
}
}
@ -57,6 +77,30 @@ public class CapturePointManager implements Listener
}
}
public String getDisplayString(GameTeam team)
{
StringBuilder out = new StringBuilder();
int owned = 0;
for (CapturePoint point : _capturePoints)
{
if (point.getOwner() == null || !point.getOwner().equals(team))
{
continue;
}
out.append(point.getColour()).append("");
owned++;
}
while (owned++ < 3)
{
out.append(C.cGray).append("");
}
return out.toString().trim();
}
public List<CapturePoint> getCapturePoints()
{
return _capturePoints;

View File

@ -7,6 +7,7 @@ import mineplex.core.disguise.disguises.DisguiseGuardian;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -15,32 +16,34 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import java.util.concurrent.TimeUnit;
public class Tower
{
private static final int DAMAGE = 3;
private static final int TARGET_RANGE = 10;
public static final int TARGET_RANGE_SQUARED = TARGET_RANGE * TARGET_RANGE;
private static final int MIN_INFORM_TIME = (int) TimeUnit.SECONDS.toMillis(30);
private final Moba _host;
private final Location _location;
private final GameTeam _team;
private float _fallbackYaw;
private double _health;
private int _maxHealth;
private boolean _firstTower;
private boolean _dead;
private long _lastInform;
private ArmorStand _stand;
private DisguiseGuardian _guardian;
private EnderCrystal _crystal;
private boolean _dead;
private float _fallbackYaw;
private LivingEntity _target;
public Tower(Moba host, Location location, GameTeam team, int health, boolean firstTower)
@ -51,6 +54,7 @@ public class Tower
_health = health;
_maxHealth = health;
_firstTower = firstTower;
_lastInform = System.currentTimeMillis();
}
public void setup()
@ -82,7 +86,15 @@ public class Tower
{
if (_target == null)
{
// Target just entities
LivingEntity target = MobaUtil.getBestEntityTarget(_host, _team, _stand, _crystal.getLocation(), TARGET_RANGE, false);
if (target == null)
{
// Try targeting players
target = MobaUtil.getBestEntityTarget(_host, _team, _stand, _crystal.getLocation(), TARGET_RANGE, true);
}
_target = target;
setLaserTarget(target);
}
@ -117,9 +129,7 @@ public class Tower
_guardian.setTarget(0);
Location standLocation = _stand.getLocation();
standLocation.setYaw(_fallbackYaw);
_guardian.getEntity().setLocation(standLocation.getX(), standLocation.getY(), standLocation.getZ(), standLocation.getYaw(), 0);
_guardian.getEntity().setLocation(standLocation.getX(), standLocation.getY(), standLocation.getZ(), _fallbackYaw, 0);
}
else
{
@ -160,6 +170,18 @@ public class Tower
_guardian.setName(out);
_crystal.setCustomName(out);
if (UtilTime.elapsed(_lastInform, MIN_INFORM_TIME))
{
_lastInform = System.currentTimeMillis();
for (Player player : _team.GetPlayers(true))
{
player.playSound(player.getLocation(), Sound.ANVIL_LAND, 1, 0.5F);
player.sendMessage(F.main("Game", "Your Tower is under attack!"));
UtilTextMiddle.display("", _team.GetColor() + "Your Tower is under attack!", 0, 30, 10, player);
}
}
}
private void explode()
@ -221,4 +243,14 @@ public class Tower
return _dead;
}
public double getHealth()
{
return _health;
}
public double getMaxHealth()
{
return _maxHealth;
}
}

View File

@ -1,5 +1,7 @@
package nautilus.game.arcade.game.games.moba.structure.tower;
import mineplex.core.common.Pair;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.recharge.Recharge;
@ -10,6 +12,8 @@ import nautilus.game.arcade.events.GameStateChangeEvent;
import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.util.MobaConstants;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.EnderCrystal;
@ -24,6 +28,8 @@ import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.projectiles.ProjectileSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -33,16 +39,19 @@ public class TowerManager implements Listener
private static final int FIRST_TOWER_HEALTH = 500;
private static final int SECOND_TOWER_HEALTH = 1000;
private static final int PROJECTILE_RANGE_SQUARED = 4;
private final Moba _host;
private final List<Tower> _towers;
private final Map<Entity, Pair<Player, Double>> _projectilesToCheck;
public TowerManager(Moba host)
{
_host = host;
_towers = new ArrayList<>(12);
_projectilesToCheck = new HashMap<>();
}
@EventHandler
@ -90,6 +99,21 @@ public class TowerManager implements Listener
_towers.add(new Tower(_host, location, gameTeam, health, firstTower));
}
_towers.sort((o1, o2) ->
{
if (o1.isFirstTower())
{
return Integer.MIN_VALUE;
}
if (!o2.isFirstTower())
{
return Integer.MAX_VALUE;
}
return 0;
});
_host.CreatureAllowOverride = true;
for (Tower tower : _towers)
{
@ -166,7 +190,6 @@ public class TowerManager implements Listener
Location playerLocation = player.getLocation();
playerLocation.setY(entityLocation.getY());
// TODO TEMP
if (UtilMath.offsetSquared(playerLocation, entityLocation) > Tower.TARGET_RANGE_SQUARED)
{
return;
@ -198,51 +221,52 @@ public class TowerManager implements Listener
if (Recharge.Instance.use(player, "Tower Sound", 500, false, false))
{
player.playSound(tower.getCrystal().getLocation(), Sound.BLAZE_HIT, 1, 0.8F);
playSound(player, tower);
}
return;
}
}
public Tower getFirstTower(GameTeam team)
public void addProjectile(Player shooter, Entity entity, double damage)
{
for (Tower tower : _towers)
{
if (tower.isFirstTower() && tower.getOwner().equals(team))
{
return tower;
}
}
return null;
_projectilesToCheck.put(entity, Pair.create(shooter, damage));
}
// /*
// Hacky work arounds!!!!
// */
// @EventHandler
// public void updateAnathBlazePowder(UpdateEvent event)
// {
// if (event.getType() != UpdateType.FASTEST)
// {
// return;
// }
//
// for (Tower tower : _towers)
// {
// for (Entity entity : UtilEnt.getAllInRadius(tower.getCrystal().getLocation(), 1.5).keySet())
// {
// if (entity instanceof Item)
// {
// Item item = (Item) entity;
// if (item.getItemStack().getType() == Material.BLAZE_POWDER)
// {
//
// }
// }
// }
// }
// }
@EventHandler
public void updateProjectiles(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<Entity> iterator = _projectilesToCheck.keySet().iterator();
while (iterator.hasNext())
{
Entity entity = iterator.next();
Pair<Player, Double> pair = _projectilesToCheck.get(entity);
GameTeam team = _host.GetTeam(pair.getLeft());
for (Tower tower : _towers)
{
if (tower.isDead() || tower.getOwner().equals(team) || UtilMath.offsetSquared(tower.getCrystal(), entity) > PROJECTILE_RANGE_SQUARED)
{
continue;
}
playSound(pair.getLeft(), tower);
tower.damage(pair.getRight());
entity.remove();
iterator.remove();
}
}
}
private void playSound(Player player, Tower tower)
{
player.playSound(tower.getCrystal().getLocation(), Sound.BLAZE_HIT, 1, 0.8F);
}
public boolean canDamage(Tower tower, GameTeam team)
{
@ -276,6 +300,26 @@ public class TowerManager implements Listener
return false;
}
public String getDisplayString(GameTeam team)
{
StringBuilder out = new StringBuilder();
for (Tower tower : _towers)
{
if (!tower.getOwner().equals(team))
{
continue;
}
double health = tower.getHealth() / tower.getMaxHealth();
String colour = tower.isDead() ? C.cGray : MobaUtil.getColour(health);
out.append(colour).append("");
}
return out.toString();
}
public List<Tower> getTowers()
{
return _towers;

View File

@ -7,6 +7,7 @@ public class MobaConstants
public static final String BASIC_ATTACK = "Basic Attack";
public static final String AMMO = "Ammo";
public static final String TEAM_METADATA = "team";
public static final String SHOOTER_METADATA = "shooter";
// Location Constants
public static final String MINION_PATH_START = "WHITE";

View File

@ -21,7 +21,12 @@ import java.util.Set;
public class MobaUtil
{
public static LivingEntity getBestEntityTarget(Moba host, GameTeam owner, LivingEntity source, Location location, int targetRange, boolean targetPlayersMore)
public static LivingEntity getBestEntityTarget(Moba host, GameTeam owner, LivingEntity source, Location location, int targetRange, boolean targetPlayers)
{
return getBestEntityTarget(host, owner, source, location, targetRange, targetPlayers, false);
}
public static LivingEntity getBestEntityTarget(Moba host, GameTeam owner, LivingEntity source, Location location, int targetRange, boolean targetPlayers, boolean targetPlayersMore)
{
LivingEntity highest = null;
double bestDist = 0;
@ -45,7 +50,7 @@ public class MobaUtil
// Make players more desirable
if (entity instanceof Player)
{
if (owner.equals(host.GetTeam((Player) entity)))
if (!targetPlayers || owner.equals(host.GetTeam((Player) entity)))
{
continue;
}
@ -155,26 +160,14 @@ public class MobaUtil
public static String getHealthBar(LivingEntity entity, int bars)
{
String out = "";
String colour;
double health = entity.getHealth() / entity.getMaxHealth();
return getHealthBar(entity, entity.getHealth(), bars);
}
if (health < 0.25)
{
colour = C.cRedB;
}
else if (health < 0.5)
{
colour = C.cGoldB;
}
else if (health < 0.75)
{
colour = C.cYellowB;
}
else
{
colour = C.cGreenB;
}
public static String getHealthBar(LivingEntity entity, double newHealth, int bars)
{
StringBuilder out = new StringBuilder();
double health = newHealth / entity.getMaxHealth();
String colour = getColour(health);
for (int i = 0; i < bars; i++)
{
@ -182,16 +175,32 @@ public class MobaUtil
if (cur < health)
{
out += colour + "|";
out.append(colour).append("|");
}
else
{
out += C.cGrayB + "|";
out.append(C.cGrayB).append("|");
}
}
return out;
return out.toString();
}
public static String getColour(double percentage)
{
if (percentage < 0.25)
{
return C.cRedB;
}
else if (percentage < 0.5)
{
return C.cGoldB;
}
else if (percentage < 0.75)
{
return C.cYellowB;
}
return C.cGreenB;
}
}

View File

@ -11,6 +11,9 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
@ -20,6 +23,22 @@ import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
/**
* CustomScoreboardModule allows for the use of per-player scoreboards in an Arcade game.
* Including sidebars, tab-list prefixes, suffixes, undernames and scores.<br>
* These scoreboard system is backed by {@link mineplex.core.scoreboard.ScoreboardManager} and is thus optimised
* extremely efficiently, so don't be afraid to call the <i>set</i> methods often as they will not be updated then and there.<br>
* Scoreboards are refreshed for all players upon the prepare, live and end state changes. While sidebars are updated every 10 ticks/0.5 seconds.<br>
* If you wish to update the scoreboard more frequently than these, the methods:
* <ul>
* <li>{@link #refresh()}</li>
* <li>{@link #refreshAsPerspective(Player)}</li>
* <li{@link #refreshAsSubject(Player)}</li>
* </ul>
*
* @see mineplex.core.scoreboard.MineplexScoreboard
* @see nautilus.game.arcade.game.games.moba.Moba
*/
public class CustomScoreboardModule extends Module
{
@ -28,18 +47,28 @@ public class CustomScoreboardModule extends Module
private BiConsumer<Player, GameScoreboard> _scoreboardConsumer;
private BiFunction<Player, Player, String> _prefixFunction;
private BiFunction<Player, Player, String> _suffixFunction;
private BiFunction<Player, Player, Integer> _tabListFunction;
private String _underNameObjective;
private BiFunction<Player, Player, Integer> _underNameFunction;
public CustomScoreboardModule()
{
_scoreboard = new HashMap<>();
}
/**
* The use of the boolean UseCustomScoreboard in {@link nautilus.game.arcade.game.Game} is required so the Arcade doesn't
* try and create the scoreboard itself or reference the standard {@link GameScoreboard}, which it does (a lot).
*/
@Override
protected void setup()
{
getGame().UseCustomScoreboard = true;
}
/**
* Calls {@link #setupScoreboard(Player)} when the players joins, if the game is not in a Lobby state.
*/
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
@ -54,6 +83,11 @@ public class CustomScoreboardModule extends Module
setupScoreboard(player);
}
/**
* Removes the player's scoreboard from the {@link #_scoreboard} map.
* <br>
* Unregisters the quitting player's entries from all other scoreboards.
*/
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
@ -67,7 +101,10 @@ public class CustomScoreboardModule extends Module
}
}
@EventHandler(priority = EventPriority.MONITOR)
/**
* Calls {@link #setupScoreboard(Player)} when the game switches to the prepare state.
*/
@EventHandler(priority = EventPriority.HIGHEST)
public void prepare(GameStateChangeEvent event)
{
if (event.GetState() != GameState.Prepare)
@ -79,14 +116,15 @@ public class CustomScoreboardModule extends Module
{
setupScoreboard(player);
}
refresh();
}
/**
* Refreshes all player scoreboards upon an in progress state change.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void live(GameStateChangeEvent event)
{
if (event.GetState() != GameState.Live)
if (event.GetState() != GameState.Prepare && event.GetState() != GameState.Live && event.GetState() != GameState.End)
{
return;
}
@ -94,6 +132,9 @@ public class CustomScoreboardModule extends Module
refresh();
}
/**
* Calls the draw method every 10 ticks/0.5 seconds.
*/
@EventHandler
public void update(UpdateEvent event)
{
@ -140,6 +181,27 @@ public class CustomScoreboardModule extends Module
return this;
}
public CustomScoreboardModule setTabList(BiFunction<Player, Player, Integer> function)
{
_tabListFunction = function;
return this;
}
public CustomScoreboardModule setUnderNameObjective(String name)
{
_underNameObjective = name;
return this;
}
public CustomScoreboardModule setUnderName(BiFunction<Player, Player, Integer> function)
{
_underNameFunction = function;
return this;
}
/**
* Refreshes all player's scoreboards.
*/
public void refresh()
{
for (CustomArcadeScoreboard scoreboard : _scoreboard.values())
@ -148,12 +210,43 @@ public class CustomScoreboardModule extends Module
}
}
/**
* Refreshes an individual player's scoreboard.
*
* @param perspective The player that has the perspective of the scoreboard to be refreshed.
*/
public void refreshAsPerspective(Player perspective)
{
CustomArcadeScoreboard scoreboard = _scoreboard.get(perspective.getUniqueId());
if (scoreboard == null)
{
return;
}
scoreboard.draw(false);
}
/**
* Refreshes all scoreboards but only where the subject of said scoreboard is the player passed in as the subject parameter.
*/
public void refreshAsSubject(Player subject)
{
for (CustomArcadeScoreboard scoreboard : _scoreboard.values())
{
scoreboard.draw(subject);
}
}
@Override
public void cleanup()
{
_scoreboard.clear();
}
/**
* An internal class that simply implements the actions set out by {@link CustomScoreboardModule}.
*/
class CustomArcadeScoreboard extends GameScoreboard
{
@ -162,12 +255,15 @@ public class CustomScoreboardModule extends Module
super(getGame(), owner);
}
private void setTag(Player subject, String prefix, String suffix)
private void updateTag(Player subject)
{
Scoreboard handle = getHandle();
String teamName = subject.getName();
Team team = handle.getTeam(teamName);
String prefix = _prefixFunction == null ? null : _prefixFunction.apply(getOwner(), subject);
String suffix = _suffixFunction == null ? null : _suffixFunction.apply(getOwner(), subject);
if (team == null)
{
team = handle.registerNewTeam(teamName);
@ -190,6 +286,56 @@ public class CustomScoreboardModule extends Module
}
}
private void updateTabList(Player subject)
{
if (_tabListFunction == null)
{
return;
}
Scoreboard handle = getHandle();
Objective objective = handle.getObjective(DisplaySlot.PLAYER_LIST);
int value = _tabListFunction.apply(getOwner(), subject);
if (objective == null)
{
objective = handle.registerNewObjective("TabList", "dummy");
objective.setDisplaySlot(DisplaySlot.PLAYER_LIST);
}
Score score = objective.getScore(subject.getName());
if (score.getScore() != value)
{
score.setScore(value);
}
}
private void updateUnderName(Player subject)
{
if (_underNameFunction == null || _underNameObjective == null)
{
return;
}
Scoreboard handle = getHandle();
Objective objective = handle.getObjective(DisplaySlot.BELOW_NAME);
int value = _underNameFunction.apply(getOwner(), subject);
if (objective == null)
{
objective = handle.registerNewObjective(_underNameObjective, "dummy");
objective.setDisplaySlot(DisplaySlot.BELOW_NAME);
}
Score score = objective.getScore(subject.getName());
if (score.getScore() != value)
{
score.setScore(value);
}
}
@Override
public void draw()
{
@ -204,16 +350,20 @@ public class CustomScoreboardModule extends Module
}
if (!sidebarOnly)
{
if (_prefixFunction != null)
for (Player player : Bukkit.getOnlinePlayers())
{
for (Player player : Bukkit.getOnlinePlayers())
{
setTag(player, _prefixFunction.apply(getOwner(), player), _suffixFunction.apply(getOwner(), player));
}
draw(player);
}
}
super.draw();
}
private void draw(Player player)
{
updateTag(player);
updateTabList(player);
updateUnderName(player);
}
}