Files
Runelite-EssentialsPlus/tree-cooldown.md
T
2026-09-18 17:18:57 +02:00

74 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.