Merge branch 'develop' of https://github.com/Mineplex-LLC/Minecraft-PC into feature/party-v2

This commit is contained in:
TadahTech 2016-06-22 00:36:23 -05:00
commit d9c5e6323a
3 changed files with 274 additions and 296 deletions

View File

@ -256,33 +256,36 @@ public class MapUtil
@SuppressWarnings({ "rawtypes" }) @SuppressWarnings({ "rawtypes" })
public static boolean ClearWorldReferences(String worldName) public static boolean ClearWorldReferences(String worldName)
{ {
HashMap regionfiles = (HashMap) RegionFileCache.a; synchronized (RegionFileCache.class)
try
{ {
for (Iterator<Object> iterator = regionfiles.entrySet().iterator(); iterator.hasNext();) HashMap regionfiles = (HashMap) RegionFileCache.a;
{
Map.Entry e = (Map.Entry) iterator.next();
RegionFile file = (RegionFile) e.getValue();
try try
{
for (Iterator<Object> iterator = regionfiles.entrySet().iterator(); iterator.hasNext(); )
{ {
file.c(); Map.Entry e = (Map.Entry) iterator.next();
iterator.remove(); RegionFile file = (RegionFile) e.getValue();
}
catch (Exception ex) try
{ {
ex.printStackTrace(); file.c();
iterator.remove();
}
catch (Exception ex)
{
ex.printStackTrace();
}
} }
} }
} catch (Exception ex)
catch (Exception ex) {
{ System.out.println("Exception while removing world reference for '" + worldName + "'!");
System.out.println("Exception while removing world reference for '" + worldName + "'!"); ex.printStackTrace();
ex.printStackTrace(); }
}
return true; return true;
}
} }
public static BlockPosition getBlockPos(int x, int y, int z) public static BlockPosition getBlockPos(int x, int y, int z)

View File

@ -1,8 +1,13 @@
package nautilus.game.arcade.game.games.uhc; package nautilus.game.arcade.game.games.uhc;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
@ -35,6 +40,19 @@ import nautilus.game.arcade.game.TeamGame;
import nautilus.game.arcade.game.Game.GameState; import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.kit.Kit;
import net.minecraft.server.v1_8_R3.BiomeCache;
import net.minecraft.server.v1_8_R3.ChunkCoordIntPair;
import net.minecraft.server.v1_8_R3.ChunkProviderServer;
import net.minecraft.server.v1_8_R3.EmptyChunk;
import net.minecraft.server.v1_8_R3.ExceptionWorldConflict;
import net.minecraft.server.v1_8_R3.FileIOThread;
import net.minecraft.server.v1_8_R3.IChunkLoader;
import net.minecraft.server.v1_8_R3.IChunkProvider;
import net.minecraft.server.v1_8_R3.LongHashMap;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.World;
import net.minecraft.server.v1_8_R3.WorldChunkManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -46,6 +64,9 @@ import org.bukkit.WorldBorder;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.generator.NormalChunkGenerator;
import org.bukkit.craftbukkit.v1_8_R3.util.LongHash;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -86,19 +107,21 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Objective;
import org.spigotmc.WatchdogThread;
public class UHC extends TeamGame public class UHC extends TeamGame
{ {
private NautHashMap<Player, Player> _teamReqs = new NautHashMap<Player, Player>(); private NautHashMap<Player, Player> _teamReqs = new NautHashMap<Player, Player>();
private NautHashMap<String, Long> _deathTime = new NautHashMap<String, Long>(); private NautHashMap<String, Long> _deathTime = new NautHashMap<String, Long>();
// private NautHashMap<String, Long> _combatTime = new NautHashMap<String, Long>(); // private NautHashMap<String, Long> _combatTime = new NautHashMap<String, Long>();
private boolean _mapLoaded = false; private volatile boolean _mapLoaded = false;
private double _mapLoadPercent = 0; private volatile double _mapLoadPercent = 0;
private int _chunksPerTick = 1; private volatile int _chunksPerTick = 1;
private volatile boolean stopGen = false;
private int _chunkTotal; private int _chunkTotal;
private Chunk _chunk = null;
private int _chunkX = 0; private int _chunkX = 0;
private int _chunkZ = 0; private int _chunkZ = 0;
private int _chunksLoaded = 0; private int _chunksLoaded = 0;
@ -111,7 +134,7 @@ public class UHC extends TeamGame
private long _createTime; private long _createTime;
private long _serverTime; private long _serverTime;
private boolean xrayDebug = false; private boolean xrayDebug = false;
@ -139,21 +162,21 @@ public class UHC extends TeamGame
{ {
super(manager, type, super(manager, type,
new Kit[] new Kit[]
{ {
new KitUHC(manager) new KitUHC(manager)
}, },
new String[] new String[]
{ {
"10 minutes of no PvP", "Only Golden Apples restore health", "Ores can only be found in caves", "10 minutes of no PvP", "Only Golden Apples restore health", "Ores can only be found in caves",
"Borders shrink over time", "Last player/team alive wins!" "Borders shrink over time", "Last player/team alive wins!"
}); });
this.HideTeamSheep = true; this.HideTeamSheep = true;
this.StrictAntiHack = true; this.StrictAntiHack = true;
AnnounceStay = false; AnnounceStay = false;
this.GameTimeout = 10800000; this.GameTimeout = 10800000;
@ -203,7 +226,7 @@ public class UHC extends TeamGame
this.GadgetsDisabled = true; this.GadgetsDisabled = true;
WorldTimeSet = -1; WorldTimeSet = -1;
CraftRecipes(); CraftRecipes();
// Disable Custom Mob Drops (and EXP Disable) // Disable Custom Mob Drops (and EXP Disable)
@ -225,8 +248,8 @@ public class UHC extends TeamGame
@Override @Override
public void ParseData() public void ParseData()
{ {
WorldData.World.setDifficulty(Difficulty.HARD); WorldData.World.setDifficulty(Difficulty.HARD);
_chunkX = (int) -(_currentBorder / 16); _chunkX = (int) -(_currentBorder / 16);
_chunkZ = (int) -(_currentBorder / 16); _chunkZ = (int) -(_currentBorder / 16);
_chunkTotal = (int) ((_currentBorder * 2 / 16) * (_currentBorder * 2 / 16)); _chunkTotal = (int) ((_currentBorder * 2 / 16) * (_currentBorder * 2 / 16));
@ -368,84 +391,6 @@ public class UHC extends TeamGame
return borders; return borders;
} }
@EventHandler
public void loadMap(UpdateEvent event)
{
if (_mapLoaded)
return;
if (WorldData.World == null)
return;
if (GetState() != GameState.Recruit)
return;
// Print Debug
if (event.getType() == UpdateType.SLOWER)
{
Announce(C.cGreen + C.Bold + "Generating Map: " + C.cWhite + getMapLoadETA() + " Remaining...", false);
TimingManager.endTotal("UHC Generation", true);
return;
}
if (event.getType() != UpdateType.TICK)
return;
// Timings
TimingManager.startTotal("UHC Generation");
for (int i = 0; i < _chunksPerTick ; i++)
{
// Unload Previous
// if (_chunk != null)
// _chunk.unload(true);
// Load Chunks
_chunk = WorldData.World.getChunkAt(_chunkX, _chunkZ);
_chunk.load(true);
// Scan Map
if (_chunkX < _currentBorder / 16)
{
_chunkX++;
}
else if (_chunkZ < _currentBorder / 16)
{
_chunkX = (int) -(_currentBorder / 16);
_chunkZ++;
}
else
{
_mapLoaded = true;
System.out.println("Map Loading Finished!");
generateSpawns();
break;
}
_chunksLoaded++;
}
_mapLoadPercent = (double)_chunksLoaded / (double)_chunkTotal;
// Timings
TimingManager.stopTotal("UHC Generation");
}
@EventHandler
public void chunkUnload(ChunkUnloadEvent event)
{
//Allow unloading after players in
if (IsLive())
return;
if (WorldData.World != null && event.getWorld().equals(WorldData.World))
{
System.out.println("Disallowing Unload of World");
event.setCancelled(true);
}
}
public void generateSpawns() public void generateSpawns()
{ {
// Wipe Spawns // Wipe Spawns
@ -467,7 +412,7 @@ public class UHC extends TeamGame
double dist = (2 * _currentBorder) / (Math.sqrt(this.GetPlayers(true).size()) + 3); double dist = (2 * _currentBorder) / (Math.sqrt(this.GetPlayers(true).size()) + 3);
// Ensure distance between Teams - 500 Attempts // Ensure distance between Teams - 500 Attempts
for (int i=0 ; i<500 ; i++) for (int i = 0; i < 500; i++)
{ {
boolean clash = false; boolean clash = false;
@ -500,7 +445,7 @@ public class UHC extends TeamGame
double dist = (2 * _currentBorder) / (Math.sqrt(GetTeamList().size()) + 3); double dist = (2 * _currentBorder) / (Math.sqrt(GetTeamList().size()) + 3);
// Ensure distance between Teams - 500 Attempts // Ensure distance between Teams - 500 Attempts
for (int i=0 ; i<500 ; i++) for (int i = 0; i < 500; i++)
{ {
boolean clash = false; boolean clash = false;
@ -622,63 +567,183 @@ public class UHC extends TeamGame
} }
} }
/*@EventHandler
public void WorldBoundaryCheck(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
return;
for (Player player : GetPlayers(true))
{
//Damage
if (Math.abs(player.getLocation().getX()) > _borderSize || Math.abs(player.getLocation().getZ()) > _borderSize)
{
player.damage(0.75);
}
}
}
@EventHandler @EventHandler
public void WorldBoundaryShrink(UpdateEvent event) public void generateWorld(GameStateChangeEvent event)
{ {
if (!IsLive()) if (event.GetState() == GameState.Dead)
{
stopGen = true;
return; return;
}
if (event.getType() == UpdateType.SLOW)
if (_borderSize > 16)
_borderSize--;
}
//@EventHandler
public void WorldBoundarySet(GameStateChangeEvent event)
{
if (event.GetState() != GameState.Recruit) if (event.GetState() != GameState.Recruit)
{
return; return;
}
long time = System.currentTimeMillis(); new Thread(() ->
{
this.WorldData.MinX = -_borderSize; try
this.WorldData.MaxX = _borderSize;
this.WorldData.MinZ = -_borderSize;
this.WorldData.MaxZ = _borderSize;
this.WorldData.MinY = -1000;
this.WorldData.MaxY = 1000;
//Find Y Max
for (int x=-16 ; x<16 ; x++)
for (int z=-16 ; z<16 ; z++)
{ {
int y = UtilBlock.getHighest(WorldData.World, x, z).getY(); Field fileIOThreadB = FileIOThread.class.getDeclaredField("b");
fileIOThreadB.setAccessible(true);
if (y > _yMax) // This list is the list of chunks to be saved on the File IO Thread
_yMax = y; List list = (List) fileIOThreadB.get(FileIOThread.a());
net.minecraft.server.v1_8_R3.WorldServer worldServer = ((CraftWorld) WorldData.World).getHandle();
WorldChunkManager manager = worldServer.getWorldChunkManager();
Field biomeCacheField = manager.getClass().getDeclaredField("d");
biomeCacheField.setAccessible(true);
// A thread safe BiomeCache
// The implementation is literally a copy/paste from the original BiomeCache, but with some synchronization
// Reason being while the server is ticking the world (for some reason, if you want to dig through the entire Arcade codebase go for it)
// it stores stuff in the BiomeCache, and chunk gen needs that BiomeCache info too
// Causing desynchronization in the cache
biomeCacheField.set(manager, new BiomeCache(manager)
{
private final Object _lock = new Object();
private long _lastCleanTime; // b -> _lastCleanTime
private Map<Long, BiomeCacheBlock> _blockByCoord = new HashMap<>(); // LongHashMap -> HashMap, c -> _blockByCoord
private List<BiomeCache.BiomeCacheBlock> _blocks = new ArrayList<>(); // d -> _blocks
@Override
public BiomeCache.BiomeCacheBlock a(int x, int z)
{
x >>= 4;
z >>= 4;
long var3 = hash(x, z);
BiomeCache.BiomeCacheBlock var5 = this._blockByCoord.get(var3);
if (var5 == null)
{
var5 = new BiomeCache.BiomeCacheBlock(x, z);
synchronized (_lock)
{
this._blockByCoord.put(var3, var5);
this._blocks.add(var5);
}
}
var5.e = MinecraftServer.az();
return var5;
}
@Override
public void a()
{
long currentTime = MinecraftServer.az();
long deltaTime = currentTime - this._lastCleanTime;
if (deltaTime > 7500L || deltaTime < 0L)
{
this._lastCleanTime = currentTime;
synchronized (_lock)
{
for (int i = 0; i < this._blocks.size(); ++i)
{
BiomeCache.BiomeCacheBlock biomeCacheBlock = (BiomeCache.BiomeCacheBlock) this._blocks.get(i);
long var7 = currentTime - biomeCacheBlock.e;
if (var7 > 30000L || var7 < 0L)
{
this._blocks.remove(i--);
this._blockByCoord.remove(hash(biomeCacheBlock.c, biomeCacheBlock.d));
}
}
}
}
}
private long hash(int x, int z)
{
return (long) x & 4294967295L | ((long) z & 4294967295L) << 32;
}
});
ChunkProviderServer cps = worldServer.chunkProviderServer;
IChunkProvider icp = cps.chunkProvider;
System.out.println("Using chunk provider " + icp.getClass());
TimingManager.start("Map Generation");
long start = System.currentTimeMillis();
long last = start;
while (!stopGen)
{
long now = System.currentTimeMillis();
if ((now - last) >= 4000)
{
Announce(C.cGreen + C.Bold + "Generating Map: " + C.cWhite + getMapLoadETA() + " Remaining...", false);
last = now;
}
long hash = LongHash.toLong(_chunkX, _chunkZ);
// This is just a shortcut to how the Minecraft server would have generated a chunk if it doesn't exist.
// This should always create a chunk because we're not loading any chunks beforehand...
// /me looks at new maintainer
net.minecraft.server.v1_8_R3.Chunk chunk = icp.getOrCreateChunk(_chunkX, _chunkZ);
// Run the copypasted code for chunk saving.
cps.saveChunk(chunk);
cps.saveChunkNOP(chunk);
cps.unloadQueue.remove(_chunkX, _chunkZ);
cps.chunks.remove(hash);
if (_chunkX < _currentBorder / 16)
{
_chunkX++;
}
else if (_chunkZ < _currentBorder / 16)
{
_chunkX = (int) -(_currentBorder / 16);
_chunkZ++;
}
else
{
_mapLoaded = true;
System.out.println("Map Loading Finished! Took " + TimeUnit.MILLISECONDS.toSeconds(now - start) + " seconds");
break;
}
_chunksLoaded++;
// Clamp it so we don't get 101%
_mapLoadPercent = UtilMath.clamp((double) _chunksLoaded / (double) _chunkTotal, 0.0, 1.0);
_chunksPerTick = (int) (_chunksLoaded / ((now - start) / 50.0));
}
TimingManager.stop("Map Generation");
if (stopGen)
{
return;
}
TimingManager.start("Map Saving");
// Wait for all the chunks to save (but do we need this?)
while (!list.isEmpty())
{
Thread.sleep(100);
}
TimingManager.stop("Map Saving");
getArcadeManager().runSync(this::generateSpawns);
} }
catch (Throwable t)
System.out.println("Y Max: " + _yMax); {
// todo proper exception handling
System.out.println("Time: " + UtilTime.MakeStr(System.currentTimeMillis() - time)); // maybe force shutdown?
}*/ t.printStackTrace();
}
}, "WorldGen Thread").start();
}
@EventHandler @EventHandler
public void WorldBoundaryYLimit(BlockPlaceEvent event) public void WorldBoundaryYLimit(BlockPlaceEvent event)
@ -865,45 +930,6 @@ public class UHC extends TeamGame
event.setLeaveMessage(null); event.setLeaveMessage(null);
} }
/*
@EventHandler(priority = EventPriority.LOWEST)
public void PlayerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
GameTeam team = GetTeam(player);
if (team == null) return;
if (!team.IsAlive(player))
return;
team.RemovePlayer(player);
if (player.isDead())
return;
if (true)
{
//Announcement
Announce(team.GetColor() + C.Bold + player.getName() + " was killed for disconnecting.");
player.damage(5000);
return;
}
if (_combatTime.containsKey(player.getName()) && !UtilTime.elapsed(_combatTime.get(player.getName()), 15000))
{
//Announcement
Announce(team.GetColor() + C.Bold + player.getName() + " was killed for disconnecting during combat.");
player.damage(5000);
return;
}
}
*/
@EventHandler @EventHandler
public void CreatureCull(UpdateEvent event) public void CreatureCull(UpdateEvent event)
{ {
@ -1074,37 +1100,6 @@ public class UHC extends TeamGame
} }
} }
/*
@EventHandler
public void HeadEat(PlayerInteractEvent event)
{
if (UtilGear.isMat(event.getPlayer().getItemInHand(), Material.SKULL_ITEM))
{
UtilPlayer.message(event.getPlayer(), "You ate " + event.getPlayer().getItemInHand().getItemMeta().getDisplayName() + ChatColor.RESET + ".");
(new PotionEffect(PotionEffectType.ABSORPTION, 2400, 0)).apply(event.getPlayer());
(new PotionEffect(PotionEffectType.REGENERATION, 200, 1)).apply(event.getPlayer());
event.getPlayer().setItemInHand(null);
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void DamageHealCancel(EntityDamageEvent event)
{
if (event.isCancelled())
return;
if (event.getEntity() instanceof Player)
{
Player player = (Player)event.getEntity();
player.removePotionEffect(PotionEffectType.REGENERATION);
UtilPlayer.message(player, "You took damage and lost " + F.elem(C.cGreen + "Regeneration") + ChatColor.RESET + ".");
}
}*/
@EventHandler @EventHandler
public void ConsumeHeadApple(PlayerItemConsumeEvent event) public void ConsumeHeadApple(PlayerItemConsumeEvent event)
{ {
@ -1139,30 +1134,6 @@ public class UHC extends TeamGame
{ {
if (event.getMessage().startsWith("/kill")) if (event.getMessage().startsWith("/kill"))
event.setCancelled(true); event.setCancelled(true);
// if (event.getMessage().startsWith("/uhc time day"))
// {
// this.WorldTimeSet = 4000;
// event.setCancelled(true);
//
// Announce(event.getPlayer().getName() + " set time to Always Day!");
// }
//
// if (event.getMessage().startsWith("/uhc time night"))
// {
// this.WorldTimeSet = 16000;
// event.setCancelled(true);
//
// Announce(event.getPlayer().getName() + " set time to Always Night!");
// }
//
// if (event.getMessage().startsWith("/uhc time cycle"))
// {
// this.WorldTimeSet = -1;
// event.setCancelled(true);
//
// Announce(event.getPlayer().getName() + " set time to Day and Night!");
// }
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
@ -1645,27 +1616,27 @@ public class UHC extends TeamGame
return _mapLoaded; return _mapLoaded;
} }
public String getMapLoadPercent() public String getMapLoadPercent()
{ {
return (int)(_mapLoadPercent * 100) + "%"; return (int) (_mapLoadPercent * 100) + "%";
} }
public String getMapLoadETA() public String getMapLoadETA()
{ {
int chunksToGo = _chunkTotal - _chunksLoaded; int chunksToGo = _chunkTotal - _chunksLoaded;
return UtilTime.MakeStr((long) ((double)chunksToGo / (double)(_chunksPerTick * 20) * 1000d), 1); return UtilTime.MakeStr((long) ((double) chunksToGo / (double) (_chunksPerTick * 20) * 1000d), 1);
} }
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
public void teamSelectInteract(PlayerInteractEntityEvent event) public void teamSelectInteract(PlayerInteractEntityEvent event)
{ {
if (GetState() != GameState.Recruit) if (GetState() != GameState.Recruit)
return; return;
if (event.getRightClicked() == null) if (event.getRightClicked() == null)
return; return;
if (!(event.getRightClicked() instanceof Player)) if (!(event.getRightClicked() instanceof Player))
return; return;
@ -1678,34 +1649,34 @@ public class UHC extends TeamGame
return; return;
} }
selectTeamMate(player, (Player)event.getRightClicked()); selectTeamMate(player, (Player) event.getRightClicked());
} }
@EventHandler @EventHandler
public void teamSelectCommand(PlayerCommandPreprocessEvent event) public void teamSelectCommand(PlayerCommandPreprocessEvent event)
{ {
if (GetState() != GameState.Recruit) if (GetState() != GameState.Recruit)
return; return;
if (!event.getMessage().toLowerCase().startsWith("/team ")) if (!event.getMessage().toLowerCase().startsWith("/team "))
return; return;
event.setCancelled(true); event.setCancelled(true);
Player target = UtilPlayer.searchOnline(event.getPlayer(), event.getMessage().split(" ")[1], true); Player target = UtilPlayer.searchOnline(event.getPlayer(), event.getMessage().split(" ")[1], true);
if (target == null) if (target == null)
return; return;
//Observer //Observer
if (Manager.IsObserver(event.getPlayer())) if (Manager.IsObserver(event.getPlayer()))
{ {
UtilPlayer.message(event.getPlayer(), F.main("Game", "Spectators cannot partake in games.")); UtilPlayer.message(event.getPlayer(), F.main("Game", "Spectators cannot partake in games."));
return; return;
} }
if (event.getPlayer().equals(target)) if (event.getPlayer().equals(target))
return; return;
selectTeamMate(event.getPlayer(), target); selectTeamMate(event.getPlayer(), target);
} }
@ -1717,28 +1688,28 @@ public class UHC extends TeamGame
//Remove Prefs //Remove Prefs
_teamReqs.remove(player); _teamReqs.remove(player);
_teamReqs.remove(ally); _teamReqs.remove(ally);
//Inform //Inform
UtilPlayer.message(player, F.main("Game", "You accepted " + ally.getName() + "'s Team Request!")); UtilPlayer.message(player, F.main("Game", "You accepted " + ally.getName() + "'s Team Request!"));
UtilPlayer.message(ally, F.main("Game", player.getName() + " accepted your Team Request!")); UtilPlayer.message(ally, F.main("Game", player.getName() + " accepted your Team Request!"));
//Leave Old Teams //Leave Old Teams
if (GetTeam(player) != null) if (GetTeam(player) != null)
GetTeam(player).DisbandTeam(); GetTeam(player).DisbandTeam();
if (GetTeam(ally) != null) if (GetTeam(ally) != null)
GetTeam(ally).DisbandTeam(); GetTeam(ally).DisbandTeam();
//Get Team //Get Team
GameTeam team = getEmptyTeam(); GameTeam team = getEmptyTeam();
if (team == null) if (team == null)
return; return;
team.setDisplayName(player.getName() + " & " + ally.getName()); team.setDisplayName(player.getName() + " & " + ally.getName());
//Join Team //Join Team
SetPlayerTeam(player, team, true); SetPlayerTeam(player, team, true);
SetPlayerTeam(ally, team, true); SetPlayerTeam(ally, team, true);
} }
//Send Invite //Send Invite
else else
@ -1747,33 +1718,33 @@ public class UHC extends TeamGame
if (GetTeam(player) != null) if (GetTeam(player) != null)
if (GetTeam(player).HasPlayer(ally)) if (GetTeam(player).HasPlayer(ally))
return; return;
//Inform Player //Inform Player
UtilPlayer.message(player, F.main("Game", "You sent a Team Request to " + ally.getName() + "!")); UtilPlayer.message(player, F.main("Game", "You sent a Team Request to " + ally.getName() + "!"));
//Inform Target //Inform Target
if (Recharge.Instance.use(player, "Team Req " + ally.getName(), 2000, false, false)) if (Recharge.Instance.use(player, "Team Req " + ally.getName(), 2000, false, false))
{ {
UtilPlayer.message(ally, F.main("Game", player.getName() + " sent you a Team Request!")); UtilPlayer.message(ally, F.main("Game", player.getName() + " sent you a Team Request!"));
UtilPlayer.message(ally, F.main("Game", "Type " + F.elem("/team " + player.getName()) + " to accept!")); UtilPlayer.message(ally, F.main("Game", "Type " + F.elem("/team " + player.getName()) + " to accept!"));
} }
//Add Pref //Add Pref
_teamReqs.put(player, ally); _teamReqs.put(player, ally);
} }
} }
@EventHandler @EventHandler
public void teamQuit(PlayerQuitEvent event) public void teamQuit(PlayerQuitEvent event)
{ {
if (GetState() != GameState.Recruit) if (GetState() != GameState.Recruit)
return; return;
Player player = event.getPlayer(); Player player = event.getPlayer();
if (GetTeam(player) != null) if (GetTeam(player) != null)
GetTeam(player).DisbandTeam(); GetTeam(player).DisbandTeam();
Iterator<Player> teamIter = _teamReqs.keySet().iterator(); Iterator<Player> teamIter = _teamReqs.keySet().iterator();
while (teamIter.hasNext()) while (teamIter.hasNext())
{ {
@ -1782,7 +1753,7 @@ public class UHC extends TeamGame
teamIter.remove(); teamIter.remove();
} }
} }
public GameTeam getEmptyTeam() public GameTeam getEmptyTeam()
{ {
for (GameTeam team : GetTeamList()) for (GameTeam team : GetTeamList())
@ -1790,7 +1761,7 @@ public class UHC extends TeamGame
if (team.GetPlayers(false).isEmpty()) if (team.GetPlayers(false).isEmpty())
return team; return team;
} }
return null; return null;
} }
} }

View File

@ -416,6 +416,10 @@ public class WorldData
public boolean LoadChunks(long maxMilliseconds) public boolean LoadChunks(long maxMilliseconds)
{ {
if (Host instanceof UHC)
{
return true;
}
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
for (; CurX <= MaxX; CurX += 16) for (; CurX <= MaxX; CurX += 16)