Skip to content

Feature - Cosmetics Module#275

Merged
ItsNature merged 13 commits intoversion/1.2.6from
feature/cosmetics-module
May 4, 2026
Merged

Feature - Cosmetics Module#275
ItsNature merged 13 commits intoversion/1.2.6from
feature/cosmetics-module

Conversation

@ItsNature
Copy link
Copy Markdown
Collaborator

@ItsNature ItsNature commented Apr 30, 2026

Overview

Description:
Adds a new Cosmetic module, servers can equip and unequip cosmetics on Player NPCs (with per-type display options for hats, cloaks, pets and body cosmetics), and can place, remove, and reset sprays in the world.

Changes:

  • New CosmeticModule API
    • equipNpcCosmetics(Recipients, UUID npcUuid, List<Cosmetic>)
    • unequipNpcCosmetics(Recipients, UUID npcUuid, List<Integer> cosmeticIds)
    • resetNpcCosmetics(Recipients, UUID npcUuid)
    • displaySpray(Recipients, Spray)
    • removeSpray(Recipients, int sprayId) and removeSpray(Recipients, int sprayId, ApolloBlockLocation)
    • resetSprays(Recipients)
  • New builders:
    • Cosmetic: pair a Lunar Client cosmetic id with optional CosmeticOptions.
    • Spray: block location, facing direction, rotation , duration.
    • HatOptions, CloakOptions, PetOptions, BodyOptions for per-type tuning (e.g. showOverHelmet, useClothPhysics, flipShoulder, height offsets).

Code Example:

public void equipNpcCosmeticsExample(Player viewer, UUID npcUuid) {
    List<Cosmetic> cosmetics = Lists.newArrayList(
        Cosmetic.builder()
            .id(434)
            .build(),
        Cosmetic.builder()
            .id(5095)
            .options(PetOptions.builder()
                .flipShoulder(true)
                .build())
            .build(),
        Cosmetic.builder()
            .id(3)
            .options(CloakOptions.builder()
                .useClothPhysics(true)
                .build())
            .build()
    );

    Optional<ApolloPlayer> apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
    apolloPlayerOpt.ifPresent(apolloPlayer ->
        this.cosmeticModule.equipNpcCosmetics(apolloPlayer, npcUuid, cosmetics));
}

public void displaySprayExample(Player viewer, int sprayId, Block block, BlockFace face) {
    Spray spray = Spray.builder()
        .sprayId(sprayId)
        .location(ApolloBlockLocation.builder()
            .world(block.getWorld().getName())
            .x(block.getX()).y(block.getY()).z(block.getZ())
            .build())
        .facing(Direction.values()[face.ordinal()])
        .rotation(0f)
        .duration(Duration.ofSeconds(30))
        .build();

    Optional<ApolloPlayer> apolloPlayerOpt = Apollo.getPlayerManager().getPlayer(viewer.getUniqueId());
    apolloPlayerOpt.ifPresent(apolloPlayer -> this.cosmeticModule.displaySpray(apolloPlayer, spray));
}

Review Request Checklist

  • Your code follows the style guidelines of this project.
  • I have performed a self-review of my code.
  • I have tested this change myself. (If applicable)
  • I have made corresponding changes to the documentation. (If applicable)
  • The branch name follows the projects naming conventions. (e.g. feature/add-module & bugfix/fix-issue)

@ItsNature ItsNature added type: Documentation Documentation improvement or issue type: Enhancement Feature improvement or addition labels Apr 30, 2026
@ItsNature ItsNature mentioned this pull request Apr 30, 2026
@ItsNature ItsNature merged commit 6cb827d into version/1.2.6 May 4, 2026
1 check passed
@ItsNature ItsNature deleted the feature/cosmetics-module branch May 4, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: Documentation Documentation improvement or issue type: Enhancement Feature improvement or addition

Development

Successfully merging this pull request may close these issues.

3 participants