Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ plugins {
group = "net.swofty"
version = "1.0"

repositories {
mavenCentral()
}

subprojects {
apply(plugin = "java")
apply(plugin = "java-library")
Expand Down
2 changes: 1 addition & 1 deletion service.darkauction/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
java
application
id("io.github.goooler.shadow") version "8.1.7"
id("com.gradleup.shadow") version "9.3.1"
}

group = "net.swofty"
Expand Down
2 changes: 1 addition & 1 deletion service.orchestrator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
java
application
id("io.github.goooler.shadow") version "8.1.7"
id("com.gradleup.shadow") version "9.3.1"
}

group = "net.swofty"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public abstract class HypixelNPC {
public HypixelNPC(NPCConfiguration configuration) {
this.parameters = configuration;
String className = getClass().getSimpleName().replace("NPC", "").replace("Villager", "");
this.name = parameters.chatName() != null ? parameters.chatName() : className.replaceAll("(?<=.)(?=\\p{Lu})", " ");
String defaultName = className.replaceAll("(?<=.)(?=\\p{Lu})", " ");
this.name = parameters.chatName() != null ? parameters.chatName() : defaultName;
this.dialogueController = new DialogueController(this);
}

Expand Down Expand Up @@ -85,9 +86,22 @@ public static void updateForPlayer(HypixelPlayer player) {
HypixelNPC.getRegisteredNPCs().forEach((npc) -> {
// If the main username can't be used (over 16 chars), use a blank space instead and use holograms for all lines
boolean playerHasNPC = cache.getEntityImpls().containsKey(npc);
NPCConfiguration config = npc.getParameters();

// Check visibility - if not visible, skip creation or remove existing
if (!config.visible(player)) {
if (playerHasNPC) {
// Remove NPC that is no longer visible
Entity entity = cache.get(npc).getValue();
PlayerHolograms.ExternalPlayerHologram holo = cache.get(npc).getKey();
entity.remove();
PlayerHolograms.removeExternalPlayerHologram(holo);
cache.remove(npc);
}
return;
}

if (!playerHasNPC) {
NPCConfiguration config = npc.getParameters();
String[] holograms = config.holograms(player);
Pos position = config.position(player);

Expand Down Expand Up @@ -141,7 +155,6 @@ public static void updateForPlayer(HypixelPlayer player) {
Entity entity = cache.get(npc).getValue();
PlayerHolograms.ExternalPlayerHologram holo = cache.get(npc).getKey();

NPCConfiguration config = npc.getParameters();
Pos npcPosition = config.position(player);
String[] npcHolograms = config.holograms(player);

Expand Down Expand Up @@ -245,10 +258,20 @@ public void sendNPCMessage(HypixelPlayer player, String message) {
sendNPCMessage(player, message, Sound.sound().type(Key.key("entity.villager.celebrate")).volume(1.0f).pitch(0.8f + new Random().nextFloat() * 0.4f).build());
}

public void sendNPCMessage(HypixelPlayer player, String message, Sound sound) {
player.sendMessage("§e[NPC] " + getName() + "§f: " + message);
player.playSound(sound);
}
public void sendNPCMessage(HypixelPlayer player, String message, Sound sound) {
String displayName = getDisplayName(player);
player.sendMessage("§e[NPC] " + displayName + "§f: " + message);
player.playSound(sound);
}

/**
* Gets the display name for this NPC for a specific player.
* Uses per-player chatName if available, otherwise falls back to default name.
*/
public String getDisplayName(HypixelPlayer player) {
Comment thread
vicente-pixel marked this conversation as resolved.
String perPlayerName = parameters.chatName(player);
return perPlayerName != null ? perPlayerName : getName();
}

protected DialogueController dialogue() {
return dialogueController;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ default String chatName() {
return null;
}

/**
* Gets the chat name for this NPC specific to a player.
* Override this for NPCs that need per-player colored names.
* @param player The player viewing this NPC
* @return The formatted chat name, or null to use default
*/
@Nullable
default String chatName(HypixelPlayer player) {
Comment thread
vicente-pixel marked this conversation as resolved.
return chatName();
}

default Instance instance() {
return HypixelConst.getInstanceContainer();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.swofty.type.generic.event.HypixelEvent;
import net.swofty.type.generic.event.HypixelEventClass;
import net.swofty.type.generic.gui.v2.ViewNavigator;
import net.swofty.type.generic.gui.v2.ViewSession;
import net.swofty.type.generic.user.HypixelPlayer;

public class ActionInventoryOpen implements HypixelEventClass {
Expand All @@ -14,7 +15,9 @@ public class ActionInventoryOpen implements HypixelEventClass {
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
HypixelPlayer player = (HypixelPlayer) event.getPlayer();
ViewNavigator.find(player).ifPresent(navigator -> navigator.getCurrentSession().onOpenEvent(event));
ViewNavigator.find(player)
.map(ViewNavigator::getCurrentSession)
.ifPresent(session -> session.onOpenEvent(event));
});

}
Expand Down
7 changes: 7 additions & 0 deletions type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import net.swofty.type.generic.tab.TablistManager;
import net.swofty.type.generic.tab.TablistModule;
import net.swofty.type.hub.darkauction.DarkAuctionDisplay;
import net.swofty.type.hub.hoppity.HoppityHuntEntityManager;
import net.swofty.type.skyblockgeneric.chocolatefactory.HoppityHuntManager;
import net.swofty.type.hub.runes.RuneEntityImpl;
import net.swofty.type.hub.tab.HubServerModule;
import net.swofty.type.hub.util.HubMap;
Expand Down Expand Up @@ -125,6 +127,11 @@ public void afterInitialize(MinecraftServer server) {
// Place forest trees
ForestTreePlacement.placeTrees(HypixelConst.getInstanceContainer());

// Register Hoppity Hunt entity manager
HoppityHuntEntityManager hoppityEntityManager = new HoppityHuntEntityManager();
HoppityHuntManager.setOnHuntStartCallback(hoppityEntityManager::spawnAllEggs);
HoppityHuntManager.setOnHuntStopCallback(hoppityEntityManager::despawnAllEggs);

HubMap hubMap = new HubMap();
hubMap.placeItemFrames(HypixelConst.getInstanceContainer());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package net.swofty.type.hub.hoppity;

import net.minestom.server.component.DataComponents;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.instance.Instance;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.player.ResolvableProfile;
import net.swofty.type.skyblockgeneric.chocolatefactory.HoppityEggLocations;
import net.swofty.type.skyblockgeneric.chocolatefactory.HoppityEggType;
import org.json.JSONObject;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.ThreadLocalRandom;

public class HoppityEggEntity extends EntityCreature {
private static final float MAX_YAW = 360f;
private static final double Y_SPAWN_OFFSET = 1.46875;
private static final String TEXTURE_URL_PREFIX = "http://textures.minecraft.net/texture/";


private final HoppityEggLocations location;
private final HoppityEggType eggType;

public HoppityEggEntity(HoppityEggLocations location, HoppityEggType eggType) {
super(EntityType.ARMOR_STAND);
this.location = location;
this.eggType = eggType;

setInvisible(true);
ArmorStandMeta meta = (ArmorStandMeta) getEntityMeta();
meta.setCustomNameVisible(false);
meta.setHasNoGravity(true);
meta.setSmall(true);
meta.setHasNoBasePlate(true);
meta.setNotifyAboutChanges(false);

String texturesEncoded = encodeTexture(eggType.getTextureHash());
setHelmet(ItemStack.builder(Material.PLAYER_HEAD)
.set(DataComponents.PROFILE, new ResolvableProfile(new PlayerSkin(texturesEncoded, null)))
.build());
}

public void spawn(Instance instance) {
float randomYaw = ThreadLocalRandom.current().nextFloat() * MAX_YAW;
setInstance(instance, location.getPosition().sub(0, Y_SPAWN_OFFSET, 0).withYaw(randomYaw));
}

private static String encodeTexture(String textureHash) {
JSONObject json = new JSONObject();
json.put("textures", new JSONObject().put("SKIN",
new JSONObject().put("url", TEXTURE_URL_PREFIX + textureHash)));
return Base64.getEncoder().encodeToString(json.toString().getBytes(StandardCharsets.UTF_8));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package net.swofty.type.hub.hoppity;

import net.swofty.type.generic.HypixelConst;
import net.swofty.type.generic.entity.InteractionEntity;
import net.swofty.type.skyblockgeneric.chocolatefactory.HoppityEggLocations;
import net.swofty.type.skyblockgeneric.chocolatefactory.HoppityEggType;
import net.swofty.type.skyblockgeneric.chocolatefactory.HoppityHuntManager;
import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HoppityHuntEntityManager {
private static final float EGG_INTERACTION_WIDTH = 1.0f;
private static final float EGG_INTERACTION_HEIGHT = 1.0f;

private final List<HoppityEggEntity> spawnedEggs = new ArrayList<>();
private final List<InteractionEntity> spawnedInteractions = new ArrayList<>();

public void spawnAllEggs() {
HoppityHuntManager huntManager = HoppityHuntManager.getInstance();
Map<HoppityEggLocations, HoppityEggType> locationEggTypes = huntManager.getLocationEggTypes();

for (Map.Entry<HoppityEggLocations, HoppityEggType> entry : locationEggTypes.entrySet()) {
HoppityEggLocations location = entry.getKey();
HoppityEggType eggType = entry.getValue();

HoppityEggEntity eggEntity = new HoppityEggEntity(location, eggType);
eggEntity.spawn(HypixelConst.getInstanceContainer());
spawnedEggs.add(eggEntity);

InteractionEntity interaction = new InteractionEntity(EGG_INTERACTION_WIDTH, EGG_INTERACTION_HEIGHT, (player, event) -> {
if (player instanceof SkyBlockPlayer skyBlockPlayer) {
huntManager.claimEgg(skyBlockPlayer, location);
}
});
interaction.setInstance(HypixelConst.getInstanceContainer(), location.getPosition());
spawnedInteractions.add(interaction);
}
}

public void despawnAllEggs() {
for (HoppityEggEntity egg : spawnedEggs) {
egg.remove();
}
spawnedEggs.clear();

for (InteractionEntity interaction : spawnedInteractions) {
interaction.remove();
}
spawnedInteractions.clear();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package net.swofty.type.hub.npcs;

import lombok.AllArgsConstructor;
import lombok.Getter;
import net.swofty.commons.ChatColor;

@Getter
@AllArgsConstructor
public enum ChocolateFactoryRank {
UNEMPLOYED(0, "Unemployed", ChatColor.RED),
INTERN(1, "Intern", ChatColor.GRAY),
EMPLOYEE(20, "Employee", ChatColor.GREEN),
ASSISTANT(120, "Assistant", ChatColor.BLUE),
MANAGER(140, "Manager", ChatColor.DARK_PURPLE),
DIRECTOR(180, "Director", ChatColor.GOLD),
EXECUTIVE(200, "Executive", ChatColor.LIGHT_PURPLE),
BOARD_MEMBER(220, "Board Member", ChatColor.AQUA);

private final int level;
private final String name;
private final ChatColor color;
private static final ChocolateFactoryRank[] RANKS = values();

/**
* Gets the formatted hologram line for this rank using the rank's base level.
* Format: §7[Lvl X] §{color}RankName
* For UNEMPLOYED: §cUnemployed (no level)
*/
public String getHologramLine() {
return getHologramLine(level);
}

/**
* Gets the formatted hologram line for this rank with a specific level.
* Format: §7[Lvl X] §{color}RankName
* For UNEMPLOYED: §cUnemployed (no level)
*/
public String getHologramLine(int actualLevel) {
if (this == UNEMPLOYED) {
return color + name;
}
return ChatColor.GRAY + "[" + actualLevel + "] " + color + name;
}

/**
* Gets the formatted chat name for this rank.
* Format: §{color}NpcName
*/
public String getChatName(String npcName) {
return color + npcName;
}

/**
* Gets the rank for a given level.
* Returns the highest rank the level qualifies for.
*/
public static ChocolateFactoryRank fromLevel(int level) {
ChocolateFactoryRank result = UNEMPLOYED;
for (ChocolateFactoryRank rank : RANKS) {
if (level >= rank.level) {
result = rank;
}
}
return result;
}
}
Loading