// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.objects; import engine.Enum; import engine.InterestManagement.WorldGrid; import engine.gameManager.*; import engine.net.ByteBufferWriter; import engine.net.client.msg.ErrorPopupMsg; import engine.server.MBServerStatics; import org.joda.time.DateTime; import org.pmw.tinylog.Logger; import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; import static engine.gameManager.DbManager.MineQueries; import static engine.gameManager.DbManager.getObject; import static engine.math.FastMath.sqr; public class Mine extends AbstractGameObject { public static ConcurrentHashMap mineMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); public static ConcurrentHashMap towerMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); private final String zoneName; private final Zone parentZone; public boolean isActive = false; public PlayerCharacter lastClaimer; public boolean wasClaimed = false; // Not persisted to DB public String guildName; public GuildTag guildTag; public String nationName; public GuildTag nationTag; private Resource production; private Guild owningGuild; private int flags; private int buildingID; private MineProduction mineType; public int capSize; public final HashSet _playerMemory = new HashSet<>(); public final HashMap _recentMemory = new HashMap<>(); HashMap> dividedPlayers; public boolean hasProduced = false; public int liveTime; public Boolean firstThirty = true; public static ArrayList ChinaMines = new ArrayList<>(); public static ArrayList EuroMines = new ArrayList<>(); public static ArrayList AmericaMines = new ArrayList<>(); /** * ResultSet Constructor */ public Mine(ResultSet rs) throws SQLException, UnknownHostException { super(rs); this.mineType = MineProduction.getByName(rs.getString("mine_type")); int ownerUID = rs.getInt("mine_ownerUID"); this.buildingID = rs.getInt("mine_buildingUID"); this.flags = rs.getInt("flags"); int parent = rs.getInt("parent"); this.parentZone = ZoneManager.getZoneByUUID(parent); this.zoneName = this.parentZone.getParent().getName(); this.owningGuild = Guild.getGuild(ownerUID); Guild nation = null; if (this.owningGuild.isEmptyGuild()) { this.guildName = ""; this.guildTag = GuildTag.ERRANT; nation = Guild.getErrantGuild(); this.owningGuild = Guild.getErrantGuild(); } else { this.guildName = this.owningGuild.getName(); this.guildTag = this.owningGuild.getGuildTag(); nation = this.owningGuild.getNation(); } if (!nation.isEmptyGuild()) { this.nationName = nation.getName(); this.nationTag = nation.getGuildTag(); } else { this.nationName = ""; this.nationTag = GuildTag.ERRANT; } this.production = Resource.valueOf(rs.getString("mine_resource")); this.lastClaimer = null; //int capRoll = ThreadLocalRandom.current().nextInt(0,101); //if(capRoll >= 0 && capRoll <= 33){ this.capSize = 5; //} //if(capRoll >= 34 && capRoll <= 66){ // this.capSize = 10; //} //if(capRoll >= 67 && capRoll <= 100){ // this.capSize = 20; //} Building mineTower = BuildingManager.getBuilding(this.buildingID); mineTower.setMaxHitPoints(5000 * this.capSize); mineTower.setCurrentHitPoints((float)5000 * this.capSize); //add a comment } public static void SetTimes(){ EuroMines.get(0).liveTime = 12; EuroMines.get(1).liveTime = 12; EuroMines.get(2).liveTime = 12; EuroMines.get(3).liveTime = 12; EuroMines.get(4).liveTime = 13; EuroMines.get(5).liveTime = 13; EuroMines.get(6).liveTime = 13; ChinaMines.get(0).liveTime = 7; ChinaMines.get(1).liveTime = 7; ChinaMines.get(2).liveTime = 7; ChinaMines.get(3).liveTime = 8; ChinaMines.get(4).liveTime = 8; ChinaMines.get(5).liveTime = 8; ChinaMines.get(6).liveTime = 8; ChinaMines.get(7).liveTime = 8; ChinaMines.get(8).liveTime = 8; ChinaMines.get(9).liveTime = 8; ChinaMines.get(10).liveTime = 9; ChinaMines.get(11).liveTime = 9; ChinaMines.get(12).liveTime = 9; ChinaMines.get(13).liveTime = 9; AmericaMines.get(0).liveTime = 20; AmericaMines.get(1).liveTime = 20; AmericaMines.get(2).liveTime = 20; AmericaMines.get(3).liveTime = 21; AmericaMines.get(4).liveTime = 21; AmericaMines.get(5).liveTime = 21; AmericaMines.get(6).liveTime = 21; AmericaMines.get(7).liveTime = 21; AmericaMines.get(8).liveTime = 21; AmericaMines.get(9).liveTime = 21; AmericaMines.get(10).liveTime = 22; AmericaMines.get(11).liveTime = 22; AmericaMines.get(12).liveTime = 22; AmericaMines.get(13).liveTime = 22; } public static void releaseMineClaims(PlayerCharacter playerCharacter) { if (playerCharacter == null) return; for (Mine mine : Mine.getMines()) { if (mine.lastClaimer != null) if (mine.lastClaimer.equals(playerCharacter)) { mine.lastClaimer = null; mine.updateGuildOwner(null); } } } public static void SendMineAttackMessage(Building mine) { if (mine.getBlueprint() == null) return; if (mine.getBlueprint().getBuildingGroup() != Enum.BuildingGroup.MINE) return; if (mine.getGuild().isEmptyGuild()) return; if (mine.getGuild().getNation().isEmptyGuild()) return; if (mine.getTimeStamp("MineAttack") > System.currentTimeMillis()) return; mine.getTimestamps().put("MineAttack", System.currentTimeMillis() + MBServerStatics.ONE_MINUTE); ChatManager.chatNationInfo(mine.getGuild().getNation(), mine.getName() + " in " + mine.getParentZone().getParent().getName() + " is Under attack!"); } public static void loadAllMines() { try { //Load mine resources MineProduction.addResources(); //pre-load all building sets ArrayList serverMines = MineQueries.GET_ALL_MINES_FOR_SERVER(); for (Mine mine : serverMines) { Mine.mineMap.put(mine, mine.buildingID); Mine.towerMap.put(mine.buildingID, mine); } ChinaMines.add(serverMines.get(0)); AmericaMines.add(serverMines.get(1)); EuroMines.add(serverMines.get(2)); ChinaMines.add(serverMines.get(3)); AmericaMines.add(serverMines.get(4)); EuroMines.add(serverMines.get(5)); ChinaMines.add(serverMines.get(6)); AmericaMines.add(serverMines.get(7)); EuroMines.add(serverMines.get(8)); ChinaMines.add(serverMines.get(9)); AmericaMines.add(serverMines.get(10)); EuroMines.add(serverMines.get(11)); ChinaMines.add(serverMines.get(12)); AmericaMines.add(serverMines.get(13)); EuroMines.add(serverMines.get(14)); ChinaMines.add(serverMines.get(15)); AmericaMines.add(serverMines.get(16)); EuroMines.add(serverMines.get(17)); ChinaMines.add(serverMines.get(18)); AmericaMines.add(serverMines.get(19)); EuroMines.add(serverMines.get(20)); ChinaMines.add(serverMines.get(21)); AmericaMines.add(serverMines.get(22)); ChinaMines.add(serverMines.get(23)); AmericaMines.add(serverMines.get(24)); ChinaMines.add(serverMines.get(25)); AmericaMines.add(serverMines.get(26)); ChinaMines.add(serverMines.get(27)); AmericaMines.add(serverMines.get(28)); ChinaMines.add(serverMines.get(29)); AmericaMines.add(serverMines.get(30)); ChinaMines.add(serverMines.get(31)); AmericaMines.add(serverMines.get(32)); ChinaMines.add(serverMines.get(33)); AmericaMines.add(serverMines.get(34)); SetTimes(); for(Mine mine : EuroMines){ if(EuroMines.indexOf(mine) %2 == 0 ){ mine.firstThirty = true; } else{ mine.firstThirty = false; } } for(Mine mine : AmericaMines){ if(AmericaMines.indexOf(mine) %2 == 0 ){ mine.firstThirty = true; } else{ mine.firstThirty = false; } } for(Mine mine : ChinaMines){ if(ChinaMines.indexOf(mine) %2 == 0 ){ mine.firstThirty = true; } else{ mine.firstThirty = false; } } } catch (Exception e) { e.printStackTrace(); } } /* * Getters */ public static Mine getMineFromTower(int towerID) { return Mine.towerMap.get(towerID); } public static void serializeForClientMsg(Mine mine, ByteBufferWriter writer) { writer.putInt(mine.getObjectType().ordinal()); writer.putInt(mine.getObjectUUID()); writer.putInt(mine.getObjectUUID()); //actually a hash of mine writer.putString(mine.mineType.name); if(ChinaMines.contains((mine))) { writer.putString("Chinese" + " {" + mine.capSize + " Man}"); } else if(AmericaMines.contains(mine)){ writer.putString("American" + " {" + mine.capSize + " Man}"); } else if(EuroMines.contains(mine)){ writer.putString("European" + " {" + mine.capSize + " Man}"); }else{ writer.putString("Unknown" + " {" + mine.capSize + " Man}"); } writer.putInt(mine.production.hash); writer.putInt(mine.getModifiedProductionAmount()); writer.putInt(mine.getModifiedProductionAmount()); //TODO calculate range penalty here writer.putInt(1800); //window in seconds // Errant mines are currently open. Set time to now. LocalDateTime mineOpenTime;// = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); if(mine.firstThirty == true){ if (mine.wasClaimed == true) mineOpenTime = mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(0).withSecond(0).withNano(0).plusDays(1); else mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(0).withSecond(0).withNano(0); } else{ if (mine.wasClaimed == true) mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(30).withSecond(0).withNano(0).plusDays(1); else mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(30).withSecond(0).withNano(0); } // Mine times are those of the nation not individual guild. Guild mineNatonGuild = mine.getOwningGuild().getNation(); // Adjust the serialized mine time based upon whether // the Guild's mine window has passed or not and if it was claimed. // If a mine is active serialize current datetime irrespective // of any claim. writer.putLocalDateTime(mineOpenTime); writer.putLocalDateTime(mineOpenTime.plusHours(1)); writer.put(mine.isActive ? (byte) 0x01 : (byte) 0x00); Building mineTower = BuildingManager.getBuilding(mine.buildingID); writer.putFloat(mineTower.getLoc().x); writer.putFloat(mineTower.getParentZone().getLoc().y); writer.putFloat(mineTower.getLoc().z); writer.putInt(mine.isExpansion() ? mine.mineType.xpacHash : mine.mineType.hash); writer.putString(mine.guildName); GuildTag._serializeForDisplay(mine.guildTag, writer); writer.putString(mine.nationName); GuildTag._serializeForDisplay(mine.nationTag, writer); } public static ArrayList getMinesForGuild(int guildID) { ArrayList mineList = new ArrayList<>(); // Only inactive mines are returned. for (Mine mine : Mine.mineMap.keySet()) { if (mine.owningGuild.getObjectUUID() == guildID && mine.isActive == false) mineList.add(mine); } return mineList; } /* * Database */ public static Mine getMine(int UID) { return MineQueries.GET_MINE(UID); } public static ArrayList getMines() { return new ArrayList<>(mineMap.keySet()); } public static boolean validateClaimer(PlayerCharacter playerCharacter) { // Method validates that the claimer meets // all the requirements to claim; landed // guild with a warehouse, etc. Guild playerGuild; //verify the player exists if (playerCharacter == null) return false; //verify the player is in valid guild playerGuild = playerCharacter.getGuild(); // Can't claim something if you don't have a guild! if (playerGuild.isEmptyGuild()) return false; if (playerGuild.getNation().isEmptyGuild()) return false; // Guild must own a city to hold a mine. City guildCity = playerGuild.getOwnedCity(); if (guildCity == null) return false; if (guildCity.getWarehouse() == null) { ErrorPopupMsg.sendErrorMsg(playerCharacter, "No Warehouse exists for this claim."); return false; } // Number of mines is based on the rank of the nation's tree. City nationCapitol = playerGuild.getNation().getOwnedCity(); Building nationCapitolTOL = nationCapitol.getTOL(); if (nationCapitolTOL == null) return false; //int treeRank = nationCapitolTOL.getRank(); //if (treeRank < 1) // return false; //if (guildUnderMineLimit(playerGuild.getNation(), treeRank) == false) { // ErrorPopupMsg.sendErrorMsg(playerCharacter, "Your nation cannot support another mine."); // return false; //} return true; } private static boolean guildUnderMineLimit(Guild playerGuild, int tolRank) { int mineCnt = 0; mineCnt += Mine.getMinesForGuild(playerGuild.getObjectUUID()).size(); for (Guild guild : playerGuild.getSubGuildList()) mineCnt += Mine.getMinesForGuild(guild.getObjectUUID()).size(); return mineCnt <= tolRank; } public boolean changeProductionType(Resource resource) { //if (!this.validForMine(resource)) // return false; //update resource in database; if (!MineQueries.CHANGE_RESOURCE(this, resource)) return false; if(this.isActive || this.hasProduced) return false; this.production = resource; this.hasProduced = true; ItemBase resourceIB = ItemBase.getItemBase(this.production.UUID); return this.owningGuild.getOwnedCity().getWarehouse().depositFromMine(this, resourceIB, this.getModifiedProductionAmount()); } public MineProduction getMineType() { return this.mineType; } public void setMineType(String type) { this.mineType = MineProduction.getByName(type); } public String getZoneName() { return this.zoneName; } public Resource getProduction() { return this.production; } public boolean getIsActive() { return this.isActive; } public Guild getOwningGuild() { if (this.owningGuild == null) return Guild.getErrantGuild(); else return this.owningGuild; } public void setOwningGuild(Guild owningGuild) { this.owningGuild = owningGuild; } /* * Serialization */ public int getFlags() { return flags; } public void setFlags(int flags) { this.flags = flags; } public Zone getParentZone() { return parentZone; } public GuildTag getGuildTag() { return guildTag; } public void setActive(boolean isAc) { this.isActive = isAc; Building building = BuildingManager.getBuildingFromCache(this.buildingID); if (building != null && !this.isActive) building.isDeranking.compareAndSet(true, false); } public boolean validForMine(Resource r) { if (this.mineType == null) return false; return this.mineType.validForMine(r, this.isExpansion()); } public void serializeForMineProduction(ByteBufferWriter writer) { writer.putInt(this.getObjectType().ordinal()); writer.putInt(this.getObjectUUID()); writer.putInt(this.getObjectUUID()); //actually a hash of mine // writer.putInt(0x215C92BB); //this.unknown1); writer.putString(this.mineType.name); writer.putString(this.zoneName); writer.putInt(this.production.hash); writer.putInt(this.production.baseProduction); writer.putInt(this.getModifiedProductionAmount()); //TODO calculate range penalty here writer.putInt(3600); //window in seconds writer.putInt(this.isExpansion() ? this.mineType.xpacHash : this.mineType.hash); } @Override public void updateDatabase() { // TODO Create update logic. } public int getBuildingID() { return buildingID; } public void setBuildingID(int buildingID) { this.buildingID = buildingID; } public void handleDestroyMine() { if (!this.isActive) return; //remove tags from mine this.guildName = ""; this.nationName = ""; this.owningGuild = Guild.getErrantGuild(); this.lastClaimer = null; this.wasClaimed = false; this.hasProduced = false; // Update database DbManager.MineQueries.CHANGE_OWNER(this, 0); // Update mesh Building mineBuilding = BuildingManager.getBuildingFromCache(this.buildingID); if (mineBuilding == null) { Logger.debug("Null mine building " + this.getObjectUUID() + ". Unable to Load Building with UID " + this.buildingID); return; } mineBuilding.setOwner(null); mineBuilding.refresh(false); // remove hirelings Building building = (Building) getObject(Enum.GameObjectType.Building, this.buildingID); BuildingManager.cleanupHirelings(building); } public boolean claimMine(PlayerCharacter claimer) { if (claimer == null) return false; if (!validateClaimer(claimer)) return false; if (!this.isActive) { ErrorPopupMsg.sendErrorMsg(claimer, "Can not for to claim inactive mine."); return false; } if (!updateGuildOwner(claimer)) return false; // Successful claim this.lastClaimer = claimer; return true; } public boolean depositMineResources() { if (this.owningGuild.isEmptyGuild()) return false; if (this.owningGuild.getOwnedCity() == null) return false; if (this.owningGuild.getOwnedCity().getWarehouse() == null) return false; ItemBase resourceIB = ItemBase.getItemBase(this.production.UUID); return this.owningGuild.getOwnedCity().getWarehouse().depositFromMine(this, resourceIB, this.getModifiedProductionAmount()); } public boolean updateGuildOwner(PlayerCharacter playerCharacter) { Building mineBuilding = BuildingManager.getBuildingFromCache(this.buildingID); //should never return null, but let's check just in case. if (mineBuilding == null) { ChatManager.chatSystemError(playerCharacter, "Unable to find mine tower."); Logger.debug("Failed to Update Mine with UID " + this.getObjectUUID() + ". Unable to Load Building with UID " + this.buildingID); return false; } if (playerCharacter == null) { this.owningGuild = Guild.getErrantGuild(); this.guildName = "None"; this.guildTag = GuildTag.ERRANT; this.nationName = "None"; this.nationTag = GuildTag.ERRANT; //Update Building. mineBuilding.setOwner(null); WorldGrid.updateObject(mineBuilding); return true; } Guild guild = playerCharacter.getGuild(); if (guild.getOwnedCity() == null) return false; if (!MineQueries.CHANGE_OWNER(this, guild.getObjectUUID())) { Logger.debug("Database failed to Change Ownership of Mine with UID " + this.getObjectUUID()); ChatManager.chatSystemError(playerCharacter, "Failed to claim Mine."); return false; } //update mine. this.owningGuild = guild; //Update Building. PlayerCharacter guildLeader = (PlayerCharacter) Guild.GetGL(this.owningGuild); if (guildLeader != null) mineBuilding.setOwner(guildLeader); WorldGrid.updateObject(mineBuilding); return true; } public boolean isExpansion() { return true; } public int getModifiedProductionAmount() { int value = Warehouse.getCostForResource(this.production.UUID); int amount = 0; switch(this.capSize){ case 5: amount = 3000000; break; case 10: amount = 6000000; break; case 20: amount = 12000000; break; } if(this.production.UUID == 7) amount *= 0.5f; else amount = amount / value; return (int) amount; } public void onEnterZerg() { HashSet currentPlayers; PlayerCharacter player; // Gather current list of players within the zone bounds Building tower = BuildingManager.getBuildingFromCache(this.buildingID); currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, Enum.CityBoundsType.GRID.extents * 0.5f, MBServerStatics.MASK_PLAYER); for (AbstractWorldObject playerObject : currentPlayers) { if (playerObject == null) continue; player = (PlayerCharacter) playerObject; // Player is already in our memory if (this._recentMemory.containsKey(player.getObjectUUID())) this._recentMemory.remove(player.getObjectUUID()); if (this._playerMemory.contains(player.getObjectUUID())) continue; // Add player to our city's memory this._playerMemory.add(player.getObjectUUID()); // ***For debugging // Logger.info("PlayerMemory for ", this.getCityName() + ": " + _playerMemory.size()); } boolean updated = false; try { //updated = onExitZerg(currentPlayers); updated = onExit(currentPlayers); } catch (Exception e) { Logger.error(e.getMessage()); } this.dividedPlayers = new HashMap<>(); for(Integer playerID : this._playerMemory){ player = PlayerCharacter.getFromCache(playerID); Guild nation = player.getGuild().getNation(); Guild entry; if(this.dividedPlayers.containsKey(nation)){ this.dividedPlayers.get(nation).add(playerID); }else{ ArrayList newEntry = new ArrayList<>(); newEntry.add(playerID); this.dividedPlayers.put(nation,newEntry); } } //if(updated == true && this.dividedPlayers.size() > 1){ for(Integer playerID : this._playerMemory){ player = PlayerCharacter.getFromCache(playerID); if(this.dividedPlayers.containsKey(player.getGuild().getNation())){ int count = this.dividedPlayers.get(player.getGuild().getNation()).size(); switch(this.capSize){ case 5: player.ZergMultiplier = ZergManager.getMultiplier5Man(count,player); break; case 10: player.ZergMultiplier = ZergManager.getMultiplier10Man(count,player); break; case 20: player.ZergMultiplier = ZergManager.getMultiplier20Man(count,player); break; } player.mineAppliedID = this.getObjectUUID(); //ChatManager.chatSystemInfo(player,"ZergBuff: " + player.ZergMultiplier); } else{ player.ZergMultiplier = 1.0f; //something went wrong reset to default until next cycle //ChatManager.chatSystemInfo(player,"There Was a Problem"); } } //} } private Boolean onExit(HashSet currentPlayers){ ArrayList purge = new ArrayList<>(); for(int id : this._playerMemory){ PlayerCharacter player = PlayerCharacter.getPlayerCharacter(id); if(currentPlayers.contains(player) == false){ purge.add(id); player.ZergMultiplier = 1.0f; //ChatManager.chatSystemInfo(player,"Left Mine, Multiplier: " + player.ZergMultiplier); } } if(purge.size() > 0) { //this._playerMemory.removeAll(purge); for(int id : purge){ if(this._recentMemory.containsKey(id) == false) { this._recentMemory.put(id, System.currentTimeMillis() + 60000); } else if(this._recentMemory.get(id) > System.currentTimeMillis()){ this._playerMemory.remove(id); //ChatManager.chatSystemInfo(PlayerCharacter.getPlayerCharacter(id),"Left Have Been Removed from The Mine List"); } } } return true; } private Boolean onExitZerg(HashSet currentPlayers) { PlayerCharacter player; int playerUUID = 0; HashSet toRemove = new HashSet<>(); Iterator iter = _playerMemory.iterator(); while (iter.hasNext()) { playerUUID = iter.next(); player = PlayerCharacter.getFromCache(playerUUID); if (currentPlayers.contains(player)) continue; toRemove.add(playerUUID); if(this._recentMemory.containsKey(playerUUID) == false) { this._recentMemory.put(playerUUID, System.currentTimeMillis()); PlayerCharacter.getPlayerCharacter(playerUUID).mineAppliedID = 0; PlayerCharacter.getPlayerCharacter(playerUUID).ZergMultiplier = 1.0f; } //player.ZergMultiplier = 1.0f; // reset damage modifier to 1.0 } // Remove players from mine memory //_playerMemory.removeAll(toRemove); HashSet purge = new HashSet<>(); for(Integer id : _recentMemory.keySet()){ if(System.currentTimeMillis() > _recentMemory.get(playerUUID) + 60000){ purge.add(id); } } for(Integer id : purge){ this._recentMemory.remove(id); this._playerMemory.remove(id); PlayerCharacter.getPlayerCharacter(playerUUID).mineAppliedID = 0; PlayerCharacter.getPlayerCharacter(playerUUID).ZergMultiplier = 1.0f; } if(toRemove.isEmpty()){ return false; }else{ return true; } } }