# CNPC+ Health Bars Addon — Script API

**API version:** 0.4.8  
**Minecraft:** 1.7.10  
**Scripting:** CustomNPC+ JavaScript / Nashorn

The v0.4 API is no longer boss-only. The recommended entry point is the general `HealthBars` class, which can control world-space NPC health bars, colors, animations, frames, shields, phases, Custom Boss Bars, and Minecraft-style Boss Bar colors.

## Import

```javascript
var HealthBars = Java.type("com.dad.npchealthbars.api.HealthBars");
```

The old API is still available for existing scripts:

```javascript
var BossBars = Java.type("com.dad.npchealthbars.api.BossBarAPI");
```

> `BossBarAPI` is kept for backwards compatibility. New scripts should use `HealthBars`.

---

## Quick Example

```javascript
var HealthBars = Java.type("com.dad.npchealthbars.api.HealthBars");

function init(event) {
    var npc = event.npc;

    HealthBars.setVisibility(npc, "ON_TARGET");
    HealthBars.setCategory(npc, "ELITE");
    HealthBars.setStyle(npc, "MODERN");
    HealthBars.setFrame(npc, "ASTRAL");
    HealthBars.setHpText(npc, "CURRENT_MAX");
    HealthBars.setColorPreset(npc, "GOLDEN");
}
```

Per-NPC world settings are **property based**. If a property is not overridden by the API, that property continues to inherit the faction configuration.

---

# World-Space Health Bar

## Visibility

```javascript
HealthBars.show(npc);
HealthBars.hide(npc);
HealthBars.onHit(npc);
HealthBars.onTarget(npc);
HealthBars.inherit(npc);
```

Or use one method:

```javascript
HealthBars.setVisibility(npc, "SHOW");
HealthBars.setVisibility(npc, "HIDE");
HealthBars.setVisibility(npc, "ON_HIT");
HealthBars.setVisibility(npc, "ON_TARGET");
HealthBars.setVisibility(npc, "FACTION");
```

`FACTION`, `INHERIT`, and `DEFAULT` return visibility control to the faction.

## Category

```javascript
HealthBars.setCategory(npc, "NORMAL");
HealthBars.setCategory(npc, "ELITE");
HealthBars.setCategory(npc, "MINI_BOSS");
HealthBars.setCategory(npc, "BOSS");
```

Numeric form:

```javascript
HealthBars.setCategory(npc, 0); // Normal
HealthBars.setCategory(npc, 1); // Elite
HealthBars.setCategory(npc, 2); // Mini-Boss
HealthBars.setCategory(npc, 3); // Boss / Custom Boss Bar compatibility shortcut
```

Clear the category override:

```javascript
HealthBars.clearCategory(npc);
```

Convert a category name to its numeric code:

```javascript
var id = HealthBars.categoryCode("MINI_BOSS");
```

## Scale

```javascript
HealthBars.setScale(npc, 1.25);
HealthBars.clearScale(npc);
```

The accepted scale range is clamped by the addon.

## Style

```javascript
HealthBars.setStyle(npc, "DEFAULT");
HealthBars.setStyle(npc, "MODERN");
HealthBars.clearStyle(npc);
```

Numeric form:

```javascript
HealthBars.setStyle(npc, 0); // Default
HealthBars.setStyle(npc, 1); // Modern
```

## Texture Frame

Frames are independent from Style.

```javascript
HealthBars.setFrame(npc, "NONE");
HealthBars.setFrame(npc, "VANILLA+");
HealthBars.setFrame(npc, "ASTRAL");
HealthBars.clearFrame(npc);
```

Numeric form:

```javascript
HealthBars.setFrame(npc, 0); // None
HealthBars.setFrame(npc, 1); // Vanilla+
HealthBars.setFrame(npc, 2); // Astral
```

The frame accent is tinted at runtime using the active health-bar palette.

## HP Text

```javascript
HealthBars.setHpText(npc, "OFF");
HealthBars.setHpText(npc, "PERCENT");
HealthBars.setHpText(npc, "CURRENT");
HealthBars.setHpText(npc, "CURRENT_MAX");
HealthBars.clearHpText(npc);
```

Numeric values are `0..3` in the same order.

## Render Distance & Fade

```javascript
HealthBars.setMaxDistance(npc, 32);
HealthBars.setFadeLength(npc, 4);
```

Return either property to faction control:

```javascript
HealthBars.clearMaxDistance(npc);
HealthBars.clearFadeLength(npc);
```

## Vertical Offset

Adds an extra Y offset, in blocks, on top of the inherited faction position:

```javascript
HealthBars.setVerticalOffset(npc, 0.35);
HealthBars.clearVerticalOffset(npc);
```

---

# World-Bar Animation

## Damage Trail

```javascript
HealthBars.setDamageTrail(npc, true);
HealthBars.setDamageTrail(npc, false);
```

Set enabled state, delay in milliseconds, and speed together:

```javascript
HealthBars.setDamageTrail(npc, true, 180, 7.0);
```

Individual controls:

```javascript
HealthBars.setTrailDelay(npc, 180);
HealthBars.setTrailSpeed(npc, 7.0);
```

Return individual properties to faction control:

```javascript
HealthBars.clearDamageTrail(npc);
HealthBars.clearTrailDelay(npc);
HealthBars.clearTrailSpeed(npc);
```

## Hit Flash

```javascript
HealthBars.setHitFlash(npc, true);
HealthBars.setHitFlash(npc, false);
HealthBars.clearHitFlash(npc);
```

## Healing Animation

```javascript
HealthBars.setHealingAnimation(npc, true);
HealthBars.setHealingAnimation(npc, false);
HealthBars.clearHealingAnimation(npc);
```

## Large-Hit Pulse

```javascript
HealthBars.setLargeHitPulse(npc, true);
HealthBars.setLargeHitPulse(npc, false);
HealthBars.clearLargeHitPulse(npc);
```

## On Target Hold Time

The value is in Minecraft ticks (`20 ticks = 1 second`):

```javascript
HealthBars.setTargetHoldTicks(npc, 40);
HealthBars.clearTargetHoldTicks(npc);
```

Clear every world-bar animation override at once:

```javascript
HealthBars.clearAnimationOverrides(npc);
```

---

# World-Bar Colors

## Faction or Custom Palette

```javascript
HealthBars.setColorMode(npc, "FACTION");
HealthBars.setColorMode(npc, "CUSTOM");
```

Numeric form:

```javascript
HealthBars.setColorMode(npc, 0); // Faction
HealthBars.setColorMode(npc, 1); // Custom
```

## Color Presets

```javascript
HealthBars.setColorPreset(npc, "CLASSIC_GREEN");
HealthBars.setColorPreset(npc, "CRIMSON");
HealthBars.setColorPreset(npc, "BLOOD");
HealthBars.setColorPreset(npc, "AZURE");
HealthBars.setColorPreset(npc, "ARCANE_PURPLE");
HealthBars.setColorPreset(npc, "POISON");
HealthBars.setColorPreset(npc, "GOLDEN");
HealthBars.setColorPreset(npc, "ICE");
HealthBars.setColorPreset(npc, "DARK");
HealthBars.setColorPreset(npc, "UNDEAD");
```

## Individual RGB Colors

```javascript
HealthBars.setPrimaryColor(npc, 0xC9363E);
HealthBars.setDamageColor(npc, 0xF0A45D);
HealthBars.setHealColor(npc, 0x70E28A);
HealthBars.setBackgroundColor(npc, 0x171313);
HealthBars.setBorderColor(npc, 0x080808);
HealthBars.setShieldColor(npc, 0x60B9FF);
```

Return all per-NPC colors to the faction palette:

```javascript
HealthBars.clearColors(npc);
```

---

# Shield

The Shield value is presentation state. Your NPC script decides how it absorbs damage.

```javascript
HealthBars.setShield(npc, 500, 500); // current, maximum
HealthBars.clearShield(npc);
```

Example damage absorption:

```javascript
var HealthBars = Java.type("com.dad.npchealthbars.api.HealthBars");
var SHIELD_MAX = 500;

function init(event) {
    event.npc.setTempData("shield", SHIELD_MAX);
    HealthBars.setShield(event.npc, SHIELD_MAX, SHIELD_MAX);
}

function damaged(event) {
    var npc = event.npc;
    var shield = Number(npc.getTempData("shield"));
    if (isNaN(shield) || shield <= 0) return;

    var damage = event.getDamage();
    var absorbed = Math.min(shield, damage);
    shield -= absorbed;

    npc.setTempData("shield", shield);
    event.setDamage(damage - absorbed);

    if (shield > 0) {
        HealthBars.setShield(npc, shield, SHIELD_MAX);
    } else {
        HealthBars.clearShield(npc);
        HealthBars.flash(npc);
    }
}
```

---

# Phases

```javascript
HealthBars.setPhase(npc, 1, 3);
HealthBars.setPhase(npc, 2, 3, "Corrupted Form");
HealthBars.setPhase(npc, 3, 3, "Final Form", 0xE03E2D);
HealthBars.setPhaseName(npc, "Awakened");
```

The color argument in the final overload also updates the legacy primary-color override for compatibility.

Trigger a manual visual flash/pulse:

```javascript
HealthBars.flash(npc);
```

---

# Custom Boss Bar

## Mode

```javascript
HealthBars.setBossMode(npc, "HIDE");
HealthBars.setBossMode(npc, "SHOW");
HealthBars.setBossMode(npc, "ATTACKING");
HealthBars.setBossMode(npc, "CUSTOM");
```

Numeric mode:

```javascript
HealthBars.setBossMode(npc, 0); // Hide
HealthBars.setBossMode(npc, 1); // Show
HealthBars.setBossMode(npc, 2); // Show while attacking
HealthBars.setBossMode(npc, 3); // Custom
```

## Boss Style

```javascript
HealthBars.setBossStyle(npc, "DEFAULT");
HealthBars.setBossStyle(npc, "MODERN");
```

## Boss Texture Frame

```javascript
HealthBars.setBossFrame(npc, "NONE");
HealthBars.setBossFrame(npc, "VANILLA");
HealthBars.setBossFrame(npc, "VANILLA+");
HealthBars.setBossFrame(npc, "ASTRAL");
```

Boss frame identity:

- `NONE` — no extra frame.
- `VANILLA` — restrained Minecraft-like frame.
- `VANILLA+` — clean neutral frame with compact closed endcaps.
- `ASTRAL` — clean angular/cosmic frame with faceted endcaps.

Numeric values: `0` = None, `2` = Vanilla, `1` = Vanilla+, `4` = Astral. The old boss `ORNATE` name is accepted as a compatibility alias for `VANILLA`.

## Size & Position

```javascript
HealthBars.setBossWidth(npc, 72);  // screen percentage
HealthBars.setBossHeight(npc, 10); // pixels
HealthBars.setBossY(npc, 12);      // screen Y
```

## Boss HP Text

```javascript
HealthBars.setBossHpText(npc, "OFF");
HealthBars.setBossHpText(npc, "PERCENT");
HealthBars.setBossHpText(npc, "CURRENT");
HealthBars.setBossHpText(npc, "CURRENT_MAX");
```

## Phase & Shield Display

```javascript
HealthBars.setBossShowPhase(npc, true);
HealthBars.setBossShowShield(npc, true);
```

## Boss Damage / Healing Feedback

```javascript
HealthBars.setBossDamageTrail(npc, true);
HealthBars.setBossDamageTrail(npc, true, 180, 7.0);
HealthBars.setBossTrailDelay(npc, 180);
HealthBars.setBossTrailSpeed(npc, 7.0);
HealthBars.setBossHitFlash(npc, true);
HealthBars.setBossHealingAnimation(npc, true);
HealthBars.setBossLargeHitPulse(npc, true);
```

## Boss Color Preset

```javascript
HealthBars.setBossPreset(npc, "CRIMSON");
```

Boss presets use the same palette names as world bars.

## Boss RGB Colors

```javascript
HealthBars.setBossPrimaryColor(npc, 0xC9363E);
HealthBars.setBossDamageColor(npc, 0xF0A45D);
HealthBars.setBossHealColor(npc, 0x70E28A);
HealthBars.setBossBackgroundColor(npc, 0x171313);
HealthBars.setBossBorderColor(npc, 0x080808);
HealthBars.setBossShieldColor(npc, 0x60B9FF);
```

Reset Custom Boss Bar appearance to addon defaults:

```javascript
HealthBars.resetBossAppearance(npc);
```

---

# Minecraft-Style Boss Bar Color

Used with `SHOW` or `ATTACKING` modes.

```javascript
HealthBars.setVanillaBossColorPreset(npc, "PURPLE");
HealthBars.setVanillaBossColorPreset(npc, "CRIMSON");
HealthBars.setVanillaBossColorPreset(npc, "GREEN");
HealthBars.setVanillaBossColorPreset(npc, "BLUE");
HealthBars.setVanillaBossColorPreset(npc, "GOLD");
HealthBars.setVanillaBossColorPreset(npc, "WHITE");
```

Custom RGB:

```javascript
HealthBars.setVanillaBossColor(npc, 0x33AAFF);
```

Restore the exact original purple behavior:

```javascript
HealthBars.resetVanillaBossColor(npc);
```

---

## 0.4.6 Client Rendering Notes

These are client renderer features rather than per-NPC script properties:

- NPC discovery uses an event-fed cache. A full loaded-entity reconciliation happens only when the client world object changes.
- Renderer state is cleared on world unload, dimension change, disconnect, NPC death, and stale NPC removal.
- Shader Safe is enabled by default. It forces the health-bar background opaque and adds strict OpenGL state guards. Emissive rendering can be allowed explicitly.
- High-HP Custom Boss Bars are segmented automatically. The default chunk size is 1000 HP and a recent-damage position marker is shown briefly after a hit.
- Client settings are written to `config/CNPC-Health-Bars-Addon-client.properties`.

# Reset / Inheritance

Remove only per-NPC world appearance overrides such as Style, Frame, HP Text, distance, fade and animation settings:

```javascript
HealthBars.clearWorldAppearance(npc);
```

Clear general world-bar script state and return the world bar to GUI/faction defaults:

```javascript
HealthBars.resetWorld(npc);
```

Full addon reset for the NPC:

```javascript
HealthBars.reset(npc);
```

---

# Built-In Color Presets

| Preset | Primary | Damage | Healing | Background | Border | Shield |
|---|---:|---:|---:|---:|---:|---:|
| Classic Green | `#63C878` | `#E7D7A0` | `#72E18F` | `#171717` | `#080808` | `#55B8FF` |
| Crimson | `#C9363E` | `#F0A45D` | `#70E28A` | `#171313` | `#080808` | `#60B9FF` |
| Blood | `#981E2B` | `#D95C55` | `#63D982` | `#150E0F` | `#060606` | `#6CA9D9` |
| Azure | `#3C8EE8` | `#80C4FF` | `#72E39B` | `#11161B` | `#080A0D` | `#69E7FF` |
| Arcane Purple | `#9A55E8` | `#D39AF7` | `#76E39A` | `#16111B` | `#09070C` | `#5EBFFF` |
| Poison | `#76B93F` | `#C4D85C` | `#82F0A2` | `#12170F` | `#070907` | `#70CFE7` |
| Golden | `#D9A62E` | `#FFE08A` | `#74E494` | `#19150D` | `#090805` | `#77C8FF` |
| Ice | `#7BCFE8` | `#D5F5FF` | `#92FFD0` | `#10171A` | `#070A0B` | `#A5EFFF` |
| Dark | `#5F566B` | `#A59AAF` | `#69D88B` | `#0D0D10` | `#050506` | `#588CB5` |
| Undead | `#7E9B58` | `#B7C28B` | `#65D985` | `#12150F` | `#070807` | `#699EB8` |

---

# Full Multi-Phase Example

```javascript
var HealthBars = Java.type("com.dad.npchealthbars.api.HealthBars");

function init(event) {
    var npc = event.npc;

    npc.setTempData("phase", 1);

    HealthBars.setBossMode(npc, "CUSTOM");
    HealthBars.setBossStyle(npc, "MODERN");
    HealthBars.setBossFrame(npc, "ASTRAL");
    HealthBars.setBossPreset(npc, "CRIMSON");
    HealthBars.setBossHpText(npc, "CURRENT_MAX");
    HealthBars.setBossShowPhase(npc, true);
    HealthBars.setBossShowShield(npc, true);

    HealthBars.setPhase(npc, 1, 3, "Awakening");
    HealthBars.setShield(npc, 500, 500);
}

function tick(event) {
    var npc = event.npc;
    var phase = Number(npc.getTempData("phase"));
    var hp = npc.getHealth();

    if (phase == 1 && hp <= 500) {
        npc.setTempData("phase", 2);
        HealthBars.setPhase(npc, 2, 3, "Corrupted Form", 0x9A55E8);
        HealthBars.setBossPreset(npc, "ARCANE_PURPLE");
        HealthBars.setShield(npc, 300, 300);
        HealthBars.flash(npc);
    }

    if (phase == 2 && hp <= 200) {
        npc.setTempData("phase", 3);
        HealthBars.setPhase(npc, 3, 3, "Final Form", 0xE03E2D);
        HealthBars.setBossPreset(npc, "BLOOD");
        HealthBars.clearShield(npc);
        HealthBars.flash(npc);
    }
}
```

---

# Notes

- All mutation methods return `true` on success and `false` if the NPC could not be resolved or the supplied string value was invalid.
- You may pass `event.npc` directly. The API also accepts the raw CustomNPC+ NPC entity.
- Shield values are visual/presentation state; combat absorption remains controlled by your NPC script.
- World-space appearance overrides are property-based, so unmodified properties continue to inherit faction configuration.
- `BossBarAPI` remains available so older v0.2/v0.3 scripts do not need to be rewritten.
- For multiplayer, server and clients should run the same addon version.
