/// /// import Feature from "../../featureClass/class"; import { f, m } from "../../../mappings/mappings"; import { numberWithCommas, timeNumber } from "../../utils/numberUtils"; import { drawBoxAtBlock, drawBoxAtEntity, drawCoolWaypoint, drawFilledBox, drawLine } from "../../utils/renderUtils"; import HudTextElement from "../hud/HudTextElement"; import LocationSetting from "../settings/settingThings/location"; import ToggleSetting from "../settings/settingThings/toggle"; import DropdownSetting from "../settings/settingThings/dropdownSetting"; import socketConnection from "../../socketConnection"; import TextSetting from "../settings/settingThings/textSetting"; import { firstLetterCapital } from "../../utils/stringUtils"; import { delay } from "../../utils/delayUtils"; class Slayers extends Feature { constructor() { super(); } inSkyblock() { return this.FeatureManager.features["dataLoader"] && this.FeatureManager.features["dataLoader"].class.isInSkyblock } onEnable() { this.initVariables(); this.expOnKill = new ToggleSetting("Show slayer exp on boss kill", "Says your slayer exp in chat when you kill a boss, also says time taken to spawn+kill", true, "slayer_xp", this); this.slainAlert = new ToggleSetting("Show boss slain alert", "This helps you to not kill mobs for ages with an inactive quest", true, "boss_slain_alert", this); this.spawnAlert = new ToggleSetting("Show boss spawned alert", "This helps you to not miss your boss when you spawn it", true, "boss_spawn_alert", this); this.bossSpawnKillTime = new ToggleSetting("Show boss spawn and kill time", "tells you your slayer boss speed", true, "Slayer_spawn_kill_time", this).contributor("EmeraldMerchant"); this.bossKillTime = new ToggleSetting("Shows you bosses kill time", "tells you your slayer boss kill time", true, "slayer_kill_time", this).requires(this.bossSpawnKillTime).contributor("EmeraldMerchant"); this.slayerXpGuiElement = new ToggleSetting("Render the xp of your current slayer on your screen", "This will help you to know how much xp u have now w/o looking in chat", true, "slayer_xp_hud", this).contributor("EmeraldMerchant"); this.slayerXpElement = new HudTextElement() .setText("&6Slayer&7> &fLoading...") .setToggleSetting(this.slayerXpGuiElement) .setLocationSetting(new LocationSetting("Slayer Xp Location", "Allows you to edit the location of you current slayer xp", "slayer_xp_location", this, [10, 50, 1, 1]).requires(this.slayerXpGuiElement).editTempText("&6Enderman&7> &d&l2,147,483,647 XP").contributor("EmeraldMerchant")); this.hudElements.push(this.slayerXpElement); this.MinibossAlert = new ToggleSetting("Alert when miniboss spawned nearby", "Pops up notification when a miniboss spawned", false, "miniboss_title_ping", this).contributor("EmeraldMerchant"); this.MinibossPing = new ToggleSetting("Also make a sound when miniboss spawned", "Sound ping when a miniboss spawned", false, "miniboss_sound_ping", this).contributor("EmeraldMerchant"); this.BoxAroundMiniboss = new ToggleSetting("Draws boxes around minibosses.", "If they are too far away it doesnt draw.", false, "box_around_miniboss", this).contributor("EmeraldMerchant"); this.betterHideDeadEntity = new ToggleSetting("Also hides mob nametag when it's dead.", "An improvement for Skytils's hide dead entity", false, "hide_dead_mob_nametag", this); this.beaconSoundType = { "note.pling": "pling", "random.orb": "orb" } this.boxAroundEmanBoss = new ToggleSetting("Box around enderman slayer boss", "This helps to know which boss is yours", true, "eman_box", this); this.boxToEmanBeacon = new ToggleSetting("Box and line to the enderman beacon", "This will help to find the beacon when the boss throws it", true, "eman_beacon", this); this.emanBeaconDinkDonk = new ToggleSetting("DinkDonk when beacon is spawned", "This will help to notice when the beacon is spawned", true, "eman_beacon_dinkdink", this); this.beaconOnlyDingOnce = new ToggleSetting("Beacon DinkDonk but only Dink once", "Might make some people feel better", false, "beacon_dinkdink_once", this).requires(this.emanBeaconDinkDonk).contributor("EmeraldMerchant"); this.beaconDingSoundType = new DropdownSetting("Sound it plays for beacon ping", "1st one is louder 2nd one is higher", "note.pling", "beacon_sound", this, this.beaconSoundType).requires(this.emanBeaconDinkDonk).contributor("EmeraldMerchant"); this.emanEyeThings = new ToggleSetting("Put box around the enderman eye things", "This will help to find them", true, "eman_eye_thing", this); this.emanHpGuiElement = new ToggleSetting("Render the enderman hp on your screen", "This will help you to know what stage u are in etc.", true, "eman_hp", this).contributor("EmeraldMerchant"); this.emanHpElement = new HudTextElement().setToggleSetting(this.emanHpGuiElement).setLocationSetting(new LocationSetting("Eman Hp Location", "Allows you to edit the location of the enderman hp", "eman_location", this, [10, 50, 1, 1]).requires(this.emanHpGuiElement).editTempText("&6Enderman&7> &f&l30 Hits")); this.hudElements.push(this.emanHpElement); this.hideSummonsForLoot = new ToggleSetting("Hides summons for 3s to see t4 drops", "This will make loots more visible.", false, "show_loot", this).contributor("EmeraldMerchant"); this.allEmanBosses = new ToggleSetting("Hides summons for all eman bosses", "Hides summon for not just your boss, might fix ^ sometimes not working", false, "show_loot_all_bosses", this).requires(this.hideSummonsForLoot).contributor("EmeraldMerchant"); this.rcmDaeAxeSupport = new ToggleSetting("Eman Hyp hits before Dae axe swapping", "This will tell u how many clicks with hyp is needed before swapping to dae axe", true, "eman_rcm_support", this).requires(this.emanHpGuiElement).contributor("EmeraldMerchant"); this.rcmDamagePerHit = new TextSetting("Hyperion damage", "Your hyp's single hit damage w/o thunderlord/thunderbolt", "", "hyp_dmg", this, "Your hyp dmg (Unit: M)", false).requires(this.rcmDaeAxeSupport).contributor("EmeraldMerchant"); this.whenToShowHitsLeft = new TextSetting("Show hits left timing", "At how much hp should the hits left thing be visible", "", "eman_hp_left", this, "How much hp (Unit: M, enter a valid value 0-300)", false).requires(this.rcmDaeAxeSupport).contributor("EmeraldMerchant"); this.thunderLevel = new TextSetting("Thunderlord Level", "What thunderlord level you have on your hyperion", "", "thunderlord_level", this, "Thunderlord level (only supports 5/6/7)", false).requires(this.rcmDaeAxeSupport).contributor("EmeraldMerchant"); this.summonsHideNametag = new ToggleSetting("Hide your summons' nametags", "so u can see your boss more clearly", false, "hide_summons_nametags", this).contributor("EmeraldMerchant"); this.summonsShowNametag = new ToggleSetting("Renders your summons' HP on screen", "this shows your summons' hp on screen", false, "show_summons_hp", this).contributor("EmeraldMerchant"); this.summonsLowWarning = new ToggleSetting("Warns you when a summon is low", "this warns you after a delay after each bosses, until you respawn them", false, "warn_when_summon_low", this).contributor("EmeraldMerchant"); this.summonHPGuiElement = new ToggleSetting("Render the HP of your summons on your screen", "This will help you to know how much HP your summons have left while hide summons nametags is on", false, "summon_hp_hud", this).contributor("EmeraldMerchant"); this.summonHPElement = new HudTextElement() .setText("") .setToggleSetting(this.summonHPGuiElement) .setLocationSetting(new LocationSetting("Summon HP Location", "Allows you to edit the location of your summons' HP info", "summon_hp_location", this, [10, 50, 1, 1]).requires(this.summonHPGuiElement).editTempText("&a160k&c❤ &a160k&c❤ &a160k&c❤ &a160k&c❤").contributor("EmeraldMerchant")); this.hudElements.push(this.summonHPElement); this.warnDelay = new TextSetting("Delay for warning", "How long should it wait after the boss to warn you a summon is low", "3", "summon_warn_delay", this, "(seconds)", false).requires(this.summonsLowWarning).contributor("EmeraldMerchant"); this.summonPercentage = new TextSetting("When will it start warning you", "Below how many % hp (your summons) should it start warning you", "30", "summon_warn_percentage", this, "(%)", false).requires(this.summonsLowWarning).contributor("EmeraldMerchant"); this.maxSummons = new TextSetting("Maximum amount of your summons", "How many summons you are using", "", "max_summons", this, "Max Summons (1-8)", false).contributor("EmeraldMerchant"); this.emanLazerTimer = new ToggleSetting("Adds a timer for the boss lazer phase", "The timer will be inside the boss's body during the phase", true, "eman_lazer_timer", this); this.slayerSpeedRates = new ToggleSetting("Show slayer speed and exp rates", "(Slayer speed includes downtime inbetween slayers, only shows while doing slayers)", true, "slayer_speed_rates", this); this.slayerSpeedRatesElement = new HudTextElement() .setText("&6Slayer speed&7> &fLoading...\n&6Exp/hour&7> &fLoading...\n&6Kills/hour&7> &fLoading...") .setToggleSetting(this.slayerSpeedRates) .setLocationSetting(new LocationSetting("Slayer speed and exp rates location", "Allows you to edit the location of the information", "slayer_speed_rates_location", this, [10, 100, 1, 1]).requires(this.slayerSpeedRates).editTempText("&6Slayer speed&7> &f4:30\n&6Exp/hour&7> &f1,234,567\n&6Kills/hour&7> &f17")); this.hudElements.push(this.slayerSpeedRatesElement); this.blazeTowerDink = new ToggleSetting("DinkDonk & Box for blaze tower", "(the tower might not nessesarily belong to your boss though)", true, "blaze_tower_dinkdink", this); this.slayerProgressAlert = new ToggleSetting("Shows slayer progress in middle of screen when close", "(blame dulkir)", false, "slayer_progress_alert", this); this.dulkirThingElement = new HudTextElement() .setText("") .setToggleSetting(this.slayerProgressAlert) .setLocationSetting(new LocationSetting("Slayer progress location", "Allows you to edit the location of the dulkir thing", "dulkir_thing_location", this, [10, 150, 1, 1]).requires(this.slayerProgressAlert).editTempText("&e98&7/&c100&7 Kills")); this.hudElements.push(this.dulkirThingElement); this.otherSlayerWaypoints = new ToggleSetting("Show other users slayer boss locations", "May be usefull for loot share", true, "slayer_location_other", this) this.disableEmanTp = new ToggleSetting("Disable enderman Teleportation", "Exact same as feature in SBA", false, "emantp_disable", this) this.lastSlayerFinishes = []; this.lastSlayerExps = []; this.slayerExp = {}; this.slayerExpLoaded = false; this.lastSlayerType = ""; this.lastSlayerExp = 0; this.lastBossSlain = 0; this.registerChat("&r &r&a&lSLAYER QUEST COMPLETE!&r", (e) => { socketConnection.sendSlayerSpawnData({ loc: null }); this.lastSlayerExps.push(this.lastSlayerExp); if (this.lastSlayerExps.length > 5) { this.lastSlayerExps.shift(); } this.lastSlayerFinishes.push(Date.now()); if (this.lastSlayerFinishes.length > 5) { this.lastSlayerFinishes.shift(); } let multiplier = 1 if (this.FeatureManager.features["dataLoader"].class.mayorData.mayor?.name === "Aatrox") { if (this.FeatureManager.features["dataLoader"].class.currentMayorPerks.has("Slayer XP Buff")) { multiplier += 0.25 } } this.slayerExp[this.lastSlayerType] = Math.round(this.lastSlayerExp * multiplier) + (this.slayerExp[this.lastSlayerType] || 0); if (this.expOnKill.getValue()) { cancel(e); ChatLib.chat("&r &r&a&lSLAYER QUEST COMPLETE!&a&r"); ChatLib.chat("&r &r&aYou have &d" + numberWithCommas(this.slayerExp[this.lastSlayerType]) + " " + this.lastSlayerType + " XP&r&7!&r"); ChatLib.chat("&r &r&aYou have &d" + numberWithCommas(Object.values(this.slayerExp).reduce((a, t) => t + a, 0)) + " total XP&r&7!&r"); if (this.bossSpawnKillTime.getValue() && Date.now() - this.lastBossSlain < 60000 * 10) { ChatLib.chat(`&r &r&aBoss took &d${timeNumber(Date.now() - this.lastBossSlain)} &ato spawn and kill&r&7!`); } if (this.bossKillTime.getValue() && Date.now() - this.lastBossSpawned < 60000 * 4.6) { ChatLib.chat(`&r &r&aBoss took &d${timeNumber(Date.now() - this.lastBossSpawned)} &ato kill&r&7!`); } } this.lastBossSlain = Date.now(); if (this.summonsLowWarning.getValue() && this.warnAfterBoss) { this.warnAfterBoss = false let delayForWarn = parseInt(this.warnDelay.getValue()) * 1000 if (delayForWarn < 0 || delayForWarn > 10000) { ChatLib.chat("&6[MVP&0++&6] Soopyboo32&7: &dMan idk why you use such short/long delay, so I set it to 3 seconds for you.\n&6[MVP&0++&6] Soopyboo32&7: &cPlease use a number between 0 and 10!\n&6[MVP&0++&6] Soopyboo32&7: &c&lDon't dm me i didn't make this warning LMAO!") delayForWarn = 3000 } delay(delayForWarn, () => { Client.showTitle("&c!ONE OF THE SUMMON IS LOW!", "", 0, 40, 10); World.playSound("random.orb", 1, 1); }) } }); this.registerChat("&r &r&c&lSLAYER QUEST FAILED!&r", () => { socketConnection.sendSlayerSpawnData({ loc: null }); }) this.bossSlainMessage = false; this.bossSpawnedMessage = false; this.lastBossNotSpawnedTime = 0; this.lastBossSpawned = 0; this.registerEvent("renderOverlay", this.renderOverlay).registeredWhen(() => this.spawnAlert.getValue() || this.slainAlert.getValue()); this.registerSoopy("apiLoad", this.apiLoad); if (this.FeatureManager.features["dataLoader"] && this.FeatureManager.features["dataLoader"].class.lastApiData.skyblock) { this.apiLoad(this.FeatureManager.features["dataLoader"].class.lastApiData.skyblock, "skyblock", true, true); } this.registerChat("&r&aYou have spawned your ${soul} &r&asoul! &r&d(${mana} Mana)&r", (soul, mana) => { if (!soul.removeFormatting().includes("Tank Zombie")) { ChatLib.chat("&6[MVP&0++&6] Soopyboo32&7: &dMy mod only support Tank Zombie summons!\n&6[MVP&0++&6] Soopyboo32&7: &cPlease either use them or DISABLE the feature!\n&6[MVP&0++&6] Soopyboo32&7: &c&lDon't dm me i didn't make this warning LMAO!") return } if (this.summonAtHPShouldWarn != 0 && !this.canCaptureSummonHPInfo) { this.canCaptureSummonHPInfo = true } }) this.registerChat("&r&cYou have despawned your monsters!&r", () => { this.summonAtHPShouldWarn = 0 this.canCaptureSummonHPInfo = false }) this.todoE = []; this.beaconPoints = {}; this.beaconE = []; this.deadE = []; this.beaconLocations = {}; this.eyeE = []; this.minibossEntity = []; this.todoE2 = []; this.emanBoss = undefined; this.actualEmanBoss = undefined this.hideSummons = false; this.nextIsBoss = 0; this.counter = 0; this.emanStartedSittingTime = -1 this.pillerE = undefined this.lastPillerDink = 0 this.slayerLocationDataH = {} this.hasQuest = false this.summonEntity = [] this.summonAtHPShouldWarn = 0 this.warnAfterBoss = false this.canCaptureSummonHPInfo = false this.Miniboss = { zombie: new Set(["Revenant Sycophant", "Revenant Champion", "Deformed Revenant", "Atoned Champion", "Atoned Revenant"]), spider: new Set(["Tarantula Vermin", "Tarantula Beast", "Mutant Tarantula"]), wolf: new Set(["Pack Enforcer", "Sven Follower", "Sven Alpha"]), enderman: new Set(["Voidling Devotee", "Voidling Radical", "Voidcrazed Maniac"]), blaze: new Set(["Flare Demon", "Kindleheart Demon", "Burningsoul Demon"]) } this.SlayerWidth = { zombie: 1, spider: 2, wolf: 1, enderman: 1, blaze: 1 } this.SlayerHeight = { zombie: -2, spider: -1, wolf: -1, enderman: -3, blaze: -2 } //the volume of miniboss spawning is 0.6000000238418579 this.registerSoundPlay("random.explode", (pos, name, vol, pitch, categoryName, event) => { if (Math.round(10 * vol) !== 6 || Math.abs(pos.getY() - Player.getY()) > 5 || pos.getX() - Player.getX() > 20 || pos.getZ() - Player.getZ() > 20) return if (!this.bossSpawnedMessage) { if (this.MinibossAlert.getValue()) Client.showTitle("&c&lMiniBoss", "", 0, 20, 10); if (this.MinibossPing.getValue()) World.playSound('random.orb', 1, 1); } }) this.summonHPPossibilities = new Set(["60000❤", "105k❤", "160k❤", "180k❤", "300k❤", "525k❤", "1M❤"]) this.entityAttackEventLoaded = false; this.entityAttackEventE = undefined; this.renderEntityEvent = this.registerEvent("renderEntity", this.renderEntity); this.renderEntityEvent.unregister(); this.registerForge(net.minecraftforge.event.entity.EntityJoinWorldEvent, this.entityJoinWorldEvent).registeredWhen(() => this.hasQuest); this.registerEvent("tick", this.tick); this.registerEvent("renderWorld", this.renderWorld); this.registerEvent("worldLoad", this.worldLoad); this.registerStep(true, 2, this.step); this.registerStep(true, 4, this.step_4fps); this.registerForge(Java.type("net.minecraftforge.event.entity.living.EnderTeleportEvent"), this.emanTp).registeredWhen(() => this.inSkyblock() && this.disableEmanTp.getValue()) this.formatNumber = (HPString) => { HPString = HPString.removeFormatting().replace("❤", ""); if (HPString.endsWith("k")) { return parseInt(HPString.replace("k", "")) * 1000; } else if (HPString.endsWith("M")) { return parseInt(HPString.replace("M", "")) * 1000000; } else if (!HPString.endsWith("B")) { return parseInt(HPString); } } } emanTp(event) { cancel(event) } slayerLocationData(loc, user) { if (!loc) { delete this.slayerLocationDataH[user] return } this.slayerLocationDataH[user] = [loc, Date.now()] } worldLoad() { this.todoE = []; this.beaconPoints = {}; this.beaconE = []; this.deadE = []; this.todoE2 = []; this.beaconLocations = {}; this.eyeE = []; this.minibossEntity = []; this.emanBoss = undefined; this.actualEmanBoss = undefined; this.hideSummons = false this.slayerLocationDataH = {} this.summonEntity = [] this.warnAfterBoss = false this.canCaptureSummonHPInfo = false } renderEntity(entity, pos, partialTicks, event) { if (entity.getClassName() === "EntityZombie") { cancel(event) } } entityAttackEvent(event) { if (event.source.func_76346_g() === Player.getPlayer()) { if (event.entity instanceof net.minecraft.entity.monster.EntityEnderman) { World.getAllEntitiesOfType(net.minecraft.entity.item.EntityArmorStand).forEach((e) => { if (e.getName().includes("Voidgloom Seraph")) { //if distance from e to event.entity < 5 if ((e.getX() - event.entity[f.posX.Entity]) ** 2 + (e.getY() - event.entity[f.posY.Entity]) ** 2 + (e.getZ() - event.entity[f.posZ.Entity]) ** 2 < 25) { this.emanBoss = e; this.actualEmanBoss = event.entity; } } }); } } } renderWorld(ticks) { this.minibossEntity.forEach((x) => { drawBoxAtEntity(x[0], 0, 255, 0, this.SlayerWidth[x[1]], this.SlayerHeight[x[1]], ticks, 4, false); }) if (this.emanBoss && this.boxAroundEmanBoss.getValue()) drawBoxAtEntity(this.emanBoss, 0, 255, 0, 1, -3, ticks, 4, false); if (this.emanBoss && this.emanStartedSittingTime > 0 && this.emanLazerTimer.getValue()) { Tessellator.drawString(ChatLib.addColor("&a&lLazer: &c&l" + Math.max(0, 8.2 - (Date.now() - this.emanStartedSittingTime) / 1000).toFixed(1)), this.emanBoss.getX(), this.emanBoss.getY() - 1.2, this.emanBoss.getZ(), 0, true, 0.04, false); } if (this.pillerE && this.bossSpawnedMessage) { drawBoxAtBlock(~~this.pillerE.getX() - 1, ~~this.pillerE.getY() + 2, ~~this.pillerE.getZ() - 1, 255, 0, 0, 1, -4); } if (this.boxToEmanBeacon.getValue()) { Object.values(this.beaconPoints).forEach((line) => { let lastPoint = undefined; line.forEach((p) => { if (lastPoint) { drawLine(lastPoint[0], lastPoint[1], lastPoint[2], p[0], p[1], p[2], 0, 0, 255, 3); } lastPoint = p; }); }); Object.values(this.beaconLocations).forEach((loc) => { drawFilledBox(loc[0] + 0.5, loc[1], loc[2] + 0.5, 1.01, 1.01, 0, 0, 1, 1, true); }); } this.eyeE.forEach((e) => { let x = e.getX() + (e.getX() - e.getLastX()) * ticks; let y = e.getY() + (e.getY() - e.getLastY()) * ticks; let z = e.getZ() + (e.getZ() - e.getLastZ()) * ticks; drawBoxAtBlock(x - 0.5, y + 0.7, z - 0.5, 255, 0, 0); }); if (this.otherSlayerWaypoints.getValue()) { Object.keys(this.slayerLocationDataH).forEach(key => { drawCoolWaypoint(this.slayerLocationDataH[key][0][0], this.slayerLocationDataH[key][0][1], this.slayerLocationDataH[key][0][2], 255, 0, 0, { name: key + "'s boss" }) }) } } entityJoinWorldEvent(event) { this.todoE2.push(event.entity); } step_4fps() { if (this.hideSummonsForLoot.getValue() && this.hideSummons) { this.renderEntityEvent.register(); } else if (this.hideSummonsForLoot.getValue()) { this.renderEntityEvent.unregister(); } if (this.BoxAroundMiniboss.getValue() || this.betterHideDeadEntity.getValue() || this.summonsHideNametag.getValue() || this.summonsShowNametag.getValue() || this.summonsLowWarning.getValue()) { let entities = World.getAllEntitiesOfType(net.minecraft.entity.item.EntityArmorStand) for (let name of entities) { let nameSplit = name.getName().removeFormatting().split(" ") let MobName = nameSplit[0] + " " + nameSplit[1] if (this.BoxAroundMiniboss.getValue() && !this.bossSpawnedMessage && this.Miniboss[this.lastSlayerType]?.has(MobName) && !this.minibossEntity.map(a => a[0].getUUID().toString()).includes(name.getUUID().toString())) { this.minibossEntity.push([name, this.lastSlayerType]); } if (this.betterHideDeadEntity.getValue()) { if (nameSplit[nameSplit.length - 1][0] === "0" && nameSplit[nameSplit.length - 1].endsWith("❤")) { name.getEntity()[m.setAlwaysRenderNameTag](false) } } if (this.summonEntity.length === parseInt(this.maxSummons.getValue())) return; if (this.summonsHideNametag.getValue() || this.summonsShowNametag.getValue() || this.summonsLowWarning.getValue()) { // 2nd statement makes it to support both tank zombie and super tank zombie if (nameSplit[0] === `${Player.getName()}'s` && `${nameSplit[nameSplit.length - 3]} ${nameSplit[nameSplit.length - 2]}` === "Tank Zombie" && !this.summonEntity?.map(a => a.getUUID().toString()).includes(name.getUUID().toString())) { this.summonEntity.push(name) } } }; } } tick() { if (this.FeatureManager.features["dataLoader"].class.isInSkyblock) { if (!this.entityAttackEventLoaded) { this.entityAttackEventLoaded = true; this.entityAttackEventE = this.registerForge(net.minecraftforge.event.entity.living.LivingAttackEvent, this.entityAttackEvent); } } else { if (this.entityAttackEventLoaded) { this.entityAttackEventLoaded = false; this.entityAttackEventE.unregister() } } this.todoE.forEach((e) => { try { if (e instanceof net.minecraft.entity.item.EntityArmorStand && e[m.getEquipmentInSlot](4)) { if (e[m.getEquipmentInSlot](4)[m.getDisplayName.ItemStack]() === "Beacon") { let closestEIsGaming = false; let closestDist = Infinity; World.getAllEntitiesOfType(net.minecraft.entity.item.EntityArmorStand).forEach((e2) => { if (e2.getName().includes("Voidgloom Seraph")) { if ((e2.getX() - e[f.posX.Entity]) ** 2 + (e2.getY() - e[f.posY.Entity]) ** 2 + (e2.getZ() - e[f.posZ.Entity]) ** 2 < closestDist) { closestDist = (e2.getX() - e[f.posX.Entity]) ** 2 + (e2.getY() - e[f.posY.Entity]) ** 2 + (e2.getZ() - e[f.posZ.Entity]) ** 2; closestEIsGaming = this.emanBoss ? e2.getUUID().toString() === this.emanBoss.getUUID().toString() : false; } } }); if (closestEIsGaming && closestDist < 100) { this.beaconE.push(e); } } if (e[m.getEquipmentInSlot](4)[m.getDisplayName.ItemStack]().startsWith("§a")) { let closestEIsGaming = false; let closestDist = Infinity; World.getAllEntitiesOfType(net.minecraft.entity.item.EntityArmorStand).forEach((e2) => { if (e2.getName().includes("Voidgloom Seraph")) { if ((e2.getX() - e[f.posX.Entity]) ** 2 + (e2.getY() - e[f.posY.Entity]) ** 2 + (e2.getZ() - e[f.posZ.Entity]) ** 2 < closestDist) { closestDist = (e2.getX() - e[f.posX.Entity]) ** 2 + (e2.getY() - e[f.posY.Entity]) ** 2 + (e2.getZ() - e[f.posZ.Entity]) ** 2; closestEIsGaming = this.emanBoss ? e2.getUUID().toString() === this.emanBoss.getUUID().toString() : false; } } }); if (closestEIsGaming && closestDist < 100 && new Item(e[m.getEquipmentInSlot](4)).getNBT().getCompoundTag("tag").getCompoundTag("SkullOwner").getCompoundTag("Properties").getRawNBT()[m.getTagList]("textures", 10)[m.getCompoundTagAt](0)[m.getString.NBTTagCompound]("Value") === "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWIwNzU5NGUyZGYyNzM5MjFhNzdjMTAxZDBiZmRmYTExMTVhYmVkNWI5YjIwMjllYjQ5NmNlYmE5YmRiYjRiMyJ9fX0=") { this.eyeE.push(new Entity(e)); } // console.log(":" + new Item(e[m.getEquipmentInSlot](4)).getNBT().getCompoundTag("tag").getCompoundTag("SkullOwner").getCompoundTag("Properties").getRawNBT().func_150295_c("textures", 10).func_150305_b(0).func_74779_i("Value")) } } if (e[m.getCustomNameTag]() && e[m.getCustomNameTag]().includes("Voidgloom Seraph")) { if (Date.now() - this.nextIsBoss < 3000) { this.emanBoss = new Entity(e); this.nextIsBoss = false; } // just makes it to work on all eman slayers if (this.allEmanBosses.getValue()) { if ((e[f.posX.Entity] - Player.getX()) ** 2 + (e[f.posY.Entity] - Player.getY()) ** 2 + (e[f.posZ.Entity] - Player.getZ()) ** 2 > 20) return let emanHealth = ChatLib.removeFormatting(e[m.getCustomNameTag]().split("Voidgloom Seraph")[1]) //only runs when t4's hp is <= 3m if (emanHealth.includes("k") || (emanHealth.includes("M") && emanHealth.replace(/[^\d.]/g, "") <= 3)) { this.hideSummons = true } else if (emanHealth.replace(/[^\d.]/g, "") == 0) { delay(2000, () => { this.hideSummons = false }) } else this.hideSummons = false } } if (!this.bossSpawnedMessage && e instanceof net.minecraft.entity.item.EntityArmorStand) { let mobName = `${e[m.getCustomNameTag]().removeFormatting().split(" ")[0]} ${e[m.getCustomNameTag]().removeFormatting().split(" ")[1]}` if (this.Miniboss[this.lastSlayerType].has(mobName)) { if (this.BoxAroundMiniboss.getValue() && !this.minibossEntity.map(a => a[0].getUUID().toString()).includes(e[m.getEntityId.Entity]().toString())) { this.minibossEntity.push([new Entity(e), this.lastSlayerType]); } } } if (e instanceof net.minecraft.entity.item.EntityArmorStand && e[m.getCustomNameTag]() && this.blazeTowerDink.getValue()) { let name = ChatLib.removeFormatting(e[m.getCustomNameTag]()) let isPiller = true if (isPiller && name.trim().split(" ").length !== 3) isPiller = false if (isPiller && name.trim().split(" ")[0].split("").pop() !== "s") isPiller = false if (isPiller && name.trim().split(" ")[2] !== "hits") isPiller = false if (isPiller) { this.pillerE = new Entity(e) } } } catch (_) { console.log(JSON.stringify(_, undefined, 2)); } }); this.todoE = this.todoE2; this.todoE2 = []; if (this.slayerXpGuiElement.getValue() && this.lastSlayerType) { this.slayerXpElement.setText(`&6${firstLetterCapital(this.lastSlayerType)}&7> &d&l${numberWithCommas(this.slayerExp[this.lastSlayerType])} XP`); } else { this.slayerXpElement.setText(``); } if (this.emanBoss && this.emanBoss.getEntity()[f.isDead]) { if (this.hideSummonsForLoot.getValue()) { this.hideSummons = true delay(2000, () => { this.hideSummons = false }) } this.emanBoss = undefined this.actualEmanBoss = undefined } summonHpFloatText = "" this.summonEntity?.forEach((eArray) => { let splitted = eArray.getName().split(" ") let summonHP = splitted[splitted.length - 1] if (this.summonsHideNametag.getValue()) { eArray.getEntity()[m.setAlwaysRenderNameTag](false) } if (this.summonsShowNametag.getValue()) { if (this.formatNumber(summonHP) <= this.summonAtHPShouldWarn) { summonHpFloatText += `&c&l${summonHP.removeFormatting().replace("❤", "")}&r&c❤ ` } else { summonHpFloatText += `${summonHP} ` } } if (this.summonsLowWarning.getValue()) { if (this.formatNumber(summonHP) <= this.summonAtHPShouldWarn && !this.warnAfterBoss) { this.warnAfterBoss = true } if (this.canCaptureSummonHPInfo) { if (!this.summonHPPossibilities.has(summonHP.removeFormatting())) return this.canCaptureSummonHPInfo = false this.summonAtHPShouldWarn = this.formatNumber(summonHP) * (parseInt(this.summonPercentage.getValue()) / 100) } } }) this.summonEntity = this.summonEntity?.filter((e) => !e.getEntity()[f.isDead]); if (this.summonHPGuiElement.getValue()) { this.summonHPElement.setText(summonHpFloatText) } this.minibossEntity.forEach((eArray) => { if (eArray[0].getEntity()[f.isDead]) { this.minibossEntity.splice(this.minibossEntity.indexOf(eArray)) } }) this.eyeE = this.eyeE.filter((e) => !e.getEntity()[f.isDead]); this.beaconE = this.beaconE.filter((e) => { if (e[f.isDead]) { this.deadE.push([Date.now(), e[m.getUniqueID.Entity]().toString()]); let pos = [e[f.posX.Entity] + 0.5, e[f.posY.Entity] + 0.7, e[f.posZ.Entity] + 0.5]; //check for a beacon block within 5 blocks of pos if (World.getBlockAt(0, 0, 0).getID) { for (let x = pos[0] - 5; x <= pos[0] + 5; x++) { for (let y = pos[1] - 5; y <= pos[1] + 5; y++) { for (let z = pos[2] - 5; z <= pos[2] + 5; z++) { if (World.getBlockAt(Math.floor(x), Math.floor(y), Math.floor(z)).getID() === 138) { this.beaconLocations[e[m.getUniqueID.Entity]().toString()] = [Math.floor(x), Math.floor(y), Math.floor(z)]; } } } } } else { //CT 2.0 support for (let x = pos[0] - 5; x <= pos[0] + 5; x++) { for (let y = pos[1] - 5; y <= pos[1] + 5; y++) { for (let z = pos[2] - 5; z <= pos[2] + 5; z++) { if (World.getBlockAt(Math.floor(x), Math.floor(y), Math.floor(z)).getType().getID() === 138) { this.beaconLocations[e[m.getUniqueID.Entity]().toString()] = [Math.floor(x), Math.floor(y), Math.floor(z)]; } } } } } // if(!this.beaconLocations[e[m.getUniqueID.Entity]().toString()]){ // console.log("Diddnt find beacon wtf?????") // } return false; } return true; }); this.beaconE.forEach((e) => { if (!this.beaconPoints[e[m.getUniqueID.Entity]().toString()]) this.beaconPoints[e[m.getUniqueID.Entity]().toString()] = []; this.beaconPoints[e[m.getUniqueID.Entity]().toString()].push([e[f.posX.Entity] + 0.5, e[f.posY.Entity] + 0.7, e[f.posZ.Entity] + 0.5]); //x, y, z }); this.deadE = this.deadE.filter((e) => { if (Date.now() - e[0] > 5000) { delete this.beaconPoints[e[1]]; delete this.beaconLocations[e[1]]; return false; } let location = this.beaconLocations[e[1]]; if (!location) { delete this.beaconPoints[e[1]]; delete this.beaconLocations[e[1]]; return false; } if (World.getBlockAt(0, 0, 0).getID) { if (World.getBlockAt(location[0], location[1], location[2]).getID() === 138) { if (this.emanBeaconDinkDonk.getValue()) { Client.showTitle("&cGO TO BEACON!", "&c" + (Math.max(0, 5000 - (Date.now() - e[0])) / 1000).toFixed(1) + "s", 0, 20, 10); if (this.beaconOnlyDingOnce.getValue() && (Math.max(0, 5000 - (Date.now() - e[0])) / 1000).toFixed(1) > 4.9) { World.playSound(this.beaconDingSoundType?.getValue(), 1, 1); } else if ((this.beaconOnlyDingOnce.getValue() && (Math.max(0, 5000 - (Date.now() - e[0])) / 1000).toFixed(1) >= 4.9) || !this.beaconOnlyDingOnce.getValue()) { World.playSound(this.beaconDingSoundType?.getValue(), 1, 1); } } } else { delete this.beaconPoints[e[1]]; delete this.beaconLocations[e[1]]; return false; } } else { //CT 2.0 support if (World.getBlockAt(location[0], location[1], location[2]).getType().getID() === 138) { if (this.emanBeaconDinkDonk.getValue()) { Client.showTitle("&cGO TO BEACON!", "&c" + (Math.max(0, 5000 - (Date.now() - e[0])) / 1000).toFixed(1) + "s", 0, 20, 10); if (this.beaconOnlyDingOnce.getValue() && (Math.max(0, 5000 - (Date.now() - e[0])) / 1000).toFixed(1) > 4.9) { World.playSound(this.beaconDingSoundType?.getValue(), 1, 1); } else if ((this.beaconOnlyDingOnce.getValue() && (Math.max(0, 5000 - (Date.now() - e[0])) / 1000).toFixed(1) >= 4.9) || !this.beaconOnlyDingOnce.getValue()) { World.playSound(this.beaconDingSoundType?.getValue(), 1, 1); } } } else { delete this.beaconPoints[e[1]]; delete this.beaconLocations[e[1]]; return false; } } return true; }); if (this.emanBoss) { let emanText = "&6Enderman&7> " + (this.emanBoss.getName().split("Voidgloom Seraph")[1] || "").trim() let emanHealth = ChatLib.removeFormatting(this.emanBoss.getName().split("Voidgloom Seraph")[1]) //only runs when t4's hp is <= 3m if (emanHealth.includes("k") || (emanHealth.includes("M") && emanHealth.replace(/[^\d.]/g, "") <= 3)) { this.hideSummons = true } else if (emanHealth.replace(/[^\d.]/g, "") == 0) { delay(2000, () => { this.hideSummons = false }) } else this.hideSummons = false if (this.rcmDaeAxeSupport.getValue()) { if (emanHealth.includes("k")) { emanText += " &c0 Hits" } else if (emanHealth.includes("M") && parseInt(emanHealth) <= parseFloat(this.whenToShowHitsLeft.getValue())) { let thunderLevel = MathLib.clamp(parseInt(this.thunderLevel.getValue()), 5, 7) let thunderMultiplier = 1 + ((thunderLevel - 1) / 10); let hits = parseInt(emanHealth) / (parseFloat(this.rcmDamagePerHit.getValue()) * thunderMultiplier); emanText += ` &c${Math.max(0, Math.floor(hits - 0.75))} Hits` } } this.emanHpElement.setText(emanText); } else { this.emanHpElement.setText(""); } if (this.pillerE) { if (this.pillerE.getEntity()[f.isDead]) this.pillerE = undefined } if (this.pillerE && ChatLib.removeFormatting(this.pillerE.getName())[1] === "s" && this.bossSpawnedMessage) { let time = parseInt(ChatLib.removeFormatting(this.pillerE.getName())[0]); if (Date.now() - this.lastPillerDink > time * 40) { World.playSound("note.pling", 1, 1); this.lastPillerDink = Date.now() } Client.showTitle(this.pillerE.getName(), "", 0, 20, 10); } if (this.emanLazerTimer.getValue() && this.actualEmanBoss && this.actualEmanBoss[m.isRiding]()) { if (this.emanStartedSittingTime === -1) { this.emanStartedSittingTime = Date.now() } } else { this.emanStartedSittingTime = -1 } } apiLoad(data, dataType, isSoopyServer, isLatest) { if (!isSoopyServer || !isLatest) return; if (dataType !== "skyblock") return; this.slayerExp.zombie = data.data.profiles[data.data.stats.currentProfileId].members[Player.getUUID().replace(/-/g, "")].slayer.zombie?.xp; this.slayerExp.spider = data.data.profiles[data.data.stats.currentProfileId].members[Player.getUUID().replace(/-/g, "")].slayer.spider?.xp; this.slayerExp.wolf = data.data.profiles[data.data.stats.currentProfileId].members[Player.getUUID().replace(/-/g, "")].slayer.wolf?.xp; this.slayerExp.enderman = data.data.profiles[data.data.stats.currentProfileId].members[Player.getUUID().replace(/-/g, "")].slayer.enderman?.xp; this.slayerExp.blaze = data.data.profiles[data.data.stats.currentProfileId].members[Player.getUUID().replace(/-/g, "")].slayer.blaze?.xp; } renderOverlay() { if (this.slainAlert.getValue() && this.bossSlainMessage) { let scale = Renderer.getStringWidth(ChatLib.removeFormatting("BOSS SLAIN")) / (Renderer.screen.getWidth() * 0.75); Renderer.scale(1 / scale, 1 / scale); Renderer.drawString("&4BOSS SLAIN", Renderer.screen.getWidth() * 0.125 * scale, (Renderer.screen.getHeight() / 2 - 9 / scale) * scale); Renderer.scale(1, 1); } if (this.spawnAlert.getValue() && this.bossSpawnedMessage && Date.now() - this.lastBossNotSpawnedTime < 3000) { let scale = Renderer.getStringWidth(ChatLib.removeFormatting("BOSS SPAWNED")) / (Renderer.screen.getWidth() * 0.75); Renderer.scale(1 / scale, 1 / scale); Renderer.drawString("&4BOSS SPAWNED", Renderer.screen.getWidth() * 0.125 * scale, (Renderer.screen.getHeight() / 2 - 9 / scale) * scale); Renderer.scale(1, 1); } } step() { let averageExp = this.lastSlayerExps.reduce((a, b) => a + b, 0) / this.lastSlayerExps.length; let averageLength = (this.lastSlayerFinishes[this.lastSlayerFinishes.length - 1] - this.lastSlayerFinishes[0]) / (this.lastSlayerFinishes.length - 1); let runsperHour = (60000 * 60) / averageLength; let expPerHour = averageExp * runsperHour; if (Date.now() - this.lastSlayerFinishes[this.lastSlayerFinishes.length - 1] < 60000 * 5 || (this.FeatureManager.features["dataLoader"].class.slayerXpToSpawn && this.FeatureManager.features["dataLoader"].class.slayerXpToSpawn[0] !== 0)) { if (this.lastSlayerFinishes.length > 1) { this.slayerSpeedRatesElement.setText("&6Slayer speed&7> &f" + Math.floor(averageLength / 60000) + ":" + ((Math.floor(averageLength / 1000) % 60 < 10 ? "0" : "") + (Math.floor(averageLength / 1000) % 60)) + "\n&6Exp/hour&7> &f" + numberWithCommas(Math.round(expPerHour)) + "\n&6Kills/hour&7> &f" + Math.floor(runsperHour)); } else { this.slayerSpeedRatesElement.setText("&6Slayer speed&7> &fLoading...\n&6Exp/hour&7> &fLoading...\n&6Kills/hour&7> &fLoading..."); } } else { this.slayerSpeedRatesElement.setText(""); } Object.keys(this.slayerLocationDataH).forEach(n => { if (this.slayerLocationDataH[n][1] + 60000 * 3 < Date.now()) { delete this.slayerLocationDataH[n] } }) let lastBossSlainMessage = this.bossSlainMessage this.bossSlainMessage = false; this.hasQuest = false let dis1 = false; this.dulkirThingElement.setText("") Scoreboard.getLines().forEach((line, i) => { if (ChatLib.removeFormatting(line.getName()).includes("Slayer Quest")) { this.hasQuest = true let slayerInfo = ChatLib.removeFormatting(Scoreboard.getLines()[i - 1].getName().replace(/§/g, "&")); let levelString = slayerInfo.split(" ").pop().trim(); let slayerLevelToExp = { I: 5, II: 25, III: 100, IV: 500, V: 1500, }; this.lastSlayerExp = slayerLevelToExp[levelString]; let slayerStrToType = { revenant: "zombie", tarantula: "spider", sven: "wolf", voidgloom: "enderman", inferno: "blaze" } this.lastSlayerType = slayerStrToType[slayerInfo.split(" ")[0].toLowerCase()]; //slayerExp[lastSlayerType] += lastSlayerExp } if (line.getName().includes("Boss slain!")) { if (!lastBossSlainMessage) { socketConnection.sendSlayerSpawnData({ loc: null }); } this.bossSlainMessage = true; } if (line.getName().includes("Slay the boss!")) { if (!this.bossSpawnedMessage) { socketConnection.sendSlayerSpawnData({ loc: [Math.round(Player.getX()), Math.round(Player.getY()), Math.round(Player.getZ())] }); this.lastBossSpawned = Date.now(); } if (!this.bossSpawnedMessage && !this.emanBoss) { this.nextIsBoss = Date.now(); } dis1 = true; this.bossSpawnedMessage = true; } let lineSplitThing = ChatLib.removeFormatting(line.getName()).replace(/[^a-z/0-9 ]/gi, "").trim().split(" ") // ChatLib.chat(ChatLib.removeFormatting(line.getName()).replace(/[^a-z/0-9 ]+/gi, "").trim()) if (this.slayerProgressAlert.getValue() && lineSplitThing[0] && lineSplitThing[0].split("/").length === 2 && lineSplitThing[1] === "Kills") { let kills = lineSplitThing[0].split("/").map(a => parseInt(a)) if (kills[0] / kills[1] >= 0.9) { this.dulkirThingElement.setText(line.getName()) } } }); if (!dis1) { this.lastBossNotSpawnedTime = Date.now(); this.bossSpawnedMessage = false; } } initVariables() { this.expOnKill = undefined; this.slainAlert = undefined; this.spawnAlert = undefined; this.slayerExp = undefined; this.slayerExpLoaded = undefined; this.lastSlayerType = undefined; this.lastSlayerExp = undefined; this.bossSpawnedMessage = undefined; this.lastBossNotSpawnedTime = undefined; this.bossSlainMessage = undefined; this.todoE = undefined; this.beaconPoints = undefined; this.beaconE = undefined; this.deadE = undefined; this.beaconLocations = undefined; this.emanBoss = undefined; this.actualEmanBoss = undefined this.emanStartedSittingTime = undefined this.eyeE = undefined; this.minibossEntity = undefined; this.nextIsBoss = undefined; this.hudElements = []; this.entityAttackEventLoaded = undefined; this.todoE2 = undefined; this.entityAttackEventE = undefined; this.hideSummons = false; this.summonAtHPShouldWarn = undefined; this.warnAfterBoss = false this.canCaptureSummonHPInfo = false } onDisable() { this.hudElements.forEach(h => h.delete()) this.initVariables(); } } module.exports = { class: new Slayers(), };