Skip to content

Feature - Cosmetics Module#275

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

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

Conversation

@ItsNature

@ItsNature ItsNature commented Apr 30, 2026

Copy link
Copy Markdown
Collaborator

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
ItsNature added a commit that referenced this pull request May 13, 2026
* Deploy as `1.2.6-SNAPSHOT`

* Documentation Updates & Improvements (#277)

* Restructure some docs

* Restructure some docs

* add integration callout redirects to all modules

* add overview to private & public modules

* update developers FAQs

* update server owner FAQs

* minor tweaks to FAQ pages

* Mod Settings -> Mod Options, fix redirects

* update module callouts

* fix redirects

---------

Co-authored-by: TrentinTheKid <25537885+TrentinTheKid@users.noreply.github.com>

* Add `Profile` to `ItemStackIcon` (#274)

* Add `Profile` to `ItemStackIcon`

* Publish

* Fix typo

* make profile uuid nullable

* dont publish on this branch

* Stopwatch Module v2 (#272)

* Stopwatch module overhaul

* Add `hideWhenStopped` to stopwatches & timers

* Update Module Overview

* Overview touchups

* fix typos

* format fix

* update fields to match protos

---------

Co-authored-by: Trentin <25537885+TrentinTheKid@users.noreply.github.com>

* Feature - Cosmetics Module (#275)

* NPC Cosmetic module!

* Bump CI to java 21

* Cosmetics module!

* example: dont run nametag example on join

* fix tests setting options for everyone

* example: fix spray example npe

* `Spray` & `Cosmetic` builder docs

* add cosmetic module overview

* fix overview typo

* gardle fixes

* move cosmetic module docs to private modules

* final docs changes

---------

Co-authored-by: TrentinTheKid <25537885+TrentinTheKid@users.noreply.github.com>

* Sync LunarClient Mods & Options (#278)

* Sync LunarClient Mods & Options

* Update version tags to 1.2.6

---------

Co-authored-by: LunarClient Bot <lc-bot@moonsworth.com>

* Bump to 1.2.6 (#279)

---------

Co-authored-by: TrentinTheKid <25537885+TrentinTheKid@users.noreply.github.com>
Co-authored-by: LunarClient Bot <lc-bot@moonsworth.com>
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