Files
Runelite-EssentialsPlus/tree-cooldown.md
T

74 lines
5.4 KiB
Markdown
Raw Normal View History

2026-09-18 17:18:53 +02:00
# Tree Cooldowns – Taskbeschreibung
Implementiere ein **„Tree Cooldowns"**-Helper in **Essentials Plus** (`com.example.essentialsplus.helpers`). Es gibt zwei Anzeigen:
1. **Respawn-Countdown** über Baumstümpfen: Sekunden bis der Baum wieder wächst (nur Stümpfe, deren Fällung man in der Nähe *miterlebt* hat — zugehörige Zeiten sind sonst nicht messbar).
2. **Verbleibende Chop-Zeit** auf langlebigen Bäumen (Maple+, z. B. Yew/Magic/Redwood) über dem Baum, solange man ihn hackt.
**Format:** reine Sekunden (Ganzzahl, z. B. `8`). Deutsch als Display-Sprache.
## Mechanik (OSRS-Wiki, Depletion-System)
Despawn = wie lange aktiv gehäckt werden kann (beginnt beim ersten Hieb, **regeneriert** bei Pause). Respawn = Zeit bis der Baum wieder da ist.
| Baum | Despawn | Respawn |
|---|---|---|
| Normal tree | — | ~10 s |
| Oak | 27 s | 8,4 s |
| Willow | 30 s | 8,4 s |
| Teak | 30 s | 9 s |
| Maple | 60 s | 35,4 s |
| Hollow | 36 s | 25,8 s |
| Mahogany | 60 s | 8,4 s |
| Arctic pine | 84 s | 8,4 s |
| Yew | 114 s | 59,4 s |
| Camphor | 120 s | 59,4 s |
| Magic | 234 s | 119,4 s |
| Ironwood | 240 s | 119,4 s |
| Redwood | 264 s | 119,4 s |
| Rosewood | 275 s | 123 s |
Chop-Countdown nur wenn `despawnSec > 30` (`CHOP_MIN_DESPAWN_SEC`).
## Neue Dateien
### `helpers/TreeCooldowns.java` (`@Singleton`, Logik)
- **`TreeType`-Enum** mit `despawnSec`, `respawnSec` und Objekt-ID-Sets aus `net.runelite.api.gameval.ObjectID` (z. B. `OAKTREE`, `OAKTREE_STUMP`, `WILLOWTREE`, `YEWTREE`, `YEWTREE_STUMP`, `MAPLETREE`, `MAGICTREE`, `TEAKTREE`, `MAHOGANYTREE`, `ACHEY_TREE`, `REDWOODTREE_L/_R(+_CUT)`, diverse Varianten wie `TREE/TREE2/LIGHTTREE/DEADTREE/JUNGLETREE/EVERGREEN` plus jeweilige `*_STUMP`-Ids). IDs zusätzlich über `ObjectComposition.getName()` verifizieren; unbekannte Regio-Varianten ergänzen.
- **`WOODCUT_ANIMS`**: alle `AnimationID.HUMAN_WOODCUTTING_*`.
- **State**: `Map<TileKey(sceneX, sceneY, plane), TreeState{type, choppedMs, chopStartTick, respawnDeadlineMs}>`.
- **Events** (im Plugin registriert):
- `GameTick`: Ist `client.getLocalPlayer().getAnimation()` ∈ `WOODCUT_ANIMS` → nächsten Baum in Reichweite suchen (Scan der Scene-Tiles wie `WorldObjectHighlighterOverlay.java:91`), als Ziel merken und `choppedMs += 600`. Kein Hacken (Animation weg / anderes Ziel) → `choppedMs` zurücksetzen (Depletion regeneriert).
- `GameObjectDespawned`: getracktes Ziel (Baum) verschwindet → felled: `respawnDeadlineMs = now + respawnSec(type)` am Tile setzen.
- `GameObjectSpawned`:
- Stump-Id → fremder Baum wurde in der Nähe gefällt → ebenfalls `respawnDeadlineMs = now + respawnSec(stumpType)` setzen (Fallback `TreeType.NORMAL` bei unbekannter Stump-Id). Nur wenn Tile in einem Radius von ~16 Tiles um den Spieler („in der Nähe gefällt").
- Baum-Id an einem Tile mit aktiver Respawn-Deadline → Eintrag löschen (wiedergewachsen).
- `GameStateChanged` (`!= LOGGED_IN`) und Region-Wechsel → `reset()`.
- **API für das Overlay**: Iteratoren `respawnTimers()`, `chopTimers()` (nur Records mit Rest > 0) samt Referenz auf das Tile (`LocalPoint`, `sceneX/Y`, plane).
### `helpers/TreeCooldownOverlay.java` (`Overlay`)
- `OverlayPosition.DYNAMIC`, `OverlayLayer.ABOVE_SCENE`.
- Text-Draw mit Schatten, identisch zu `AttackTimerOverlay.shadowed`; Font über `TimerTextSize`.
- **Respawn**: Sekunden-Zahl über dem Stumpf/Perspektivenpunkt der Tree-Basis (Anchor über `Perspective.getCanvasTextLocation`, s. `AttackTimerOverlay.java:130`), Höhe = `treeCooldownOffset`.
- **Chop**: Rest-Sekunden über dem Baum, Höhe = `treeCooldownOffset + 80`.
- Optional Fortschrittsbalken (`treeCooldownBar`), Muster aus `AttackTimerOverlay.drawTimer` (drainende Pips).
- Nichts rendern wenn `!config.treeCooldowns()`.
## Zu ändernde Dateien
- **`EssentialsPlusConfig.java`**: `@ConfigItem treeCooldowns` (bool, default `false`, position 34). Stil/Toggles als `configManager`-Keys via `setHelperOption` (eingesetztes Muster):
- `treeCooldownRespawn` (bool, true), `treeCooldownChop` (bool, true), `treeCooldownBar` (bool, false)
- `treeCooldownSize` (`TimerTextSize`, NORMAL), `treeCooldownOffset` (int, 50), `treeCooldownColor` (Color, weiß oder grün `0x8FBF3F`), `treeCooldownReadyColor` (Color, `0x66FF66`)
- **`EssentialsPlusPlugin.java`**: `@Inject TreeCooldowns` + `TreeCooldownOverlay`; `startUp()`: `eventBus.register(treeCooldowns)`, `overlayManager.add(treeCooldownOverlay)`; `shutDown()`: spiegeln + `treeCooldowns.reset()`. `isHelperOption()`: `case "treeCooldowns"`.
- **`HelpersCard.java`**: neues `JCheckBox "Tree cooldowns"` (Tooltip: „Respawn-Countdown auf gefällten Bäumen + Rest-Zeit auf langlebigen Bäumen. Rechtsklick für Optionen"). Rechtsklick-Menü analog `priceMenu`/`styleMenu`: Toggles `treeCooldownRespawn`/`treeCooldownChop`/`treeCooldownBar`, Größe, Höhe, Farben, Reset. `refresh()` erweitern.
## Verifikation
- `./gradlew compileJava` (bzw. `./gradlew deploy` für Bolt).
- Manuell: Baum fällen (Oak/Willow → Respawn-Zahl auf Stump), Yew/Magic/Redwood hacken (Chop-Rest über Baum, zählt runter, fällt → Respawn-Zahl), weggehen und zurück (fremder frisch gefällter Stump in der Nähe → Timer), ausloggen (alles reset).
## Hinweise / Einschränkungen
- Nur Bäume, die selbst beobachtet gefällt wurden (eigene oder fremde in der Nähe); vorab vorhandene Stümpfe unbekannten Alters → kein Timer.
- Times anderer Spieler stimmen nicht exakt (Depletion läuft global); selbst gehackte Bäume sind exakt.