feat(heights): mount larger players without consent
This commit is contained in:
@@ -59,27 +59,43 @@ Heights corrects Purpur 2618's no-op conversion of custom potions without a vani
|
||||
|
||||
**Verification:** `nativeBrewingTest` executes real Purpur 2618 brewing cycles with native inventories, recipes, metadata and Paper event dispatch. It covers all four splash/lingering conversions, ingredient safety and cancellation, mixed/ordinary potions, and output compatibility with the stature adapters. World and entity boundaries are test doubles; these checks do not claim native projectile/cloud spawning, client appearance, or live logout/restart gameplay. Those remain supplementary live checks.
|
||||
|
||||
## Consensual carrying (US-010; live acceptance pending)
|
||||
## Ride larger players (US-010)
|
||||
|
||||
Sneak-right-click another player with your main hand to request a ride or pickup. The larger player is always the carrier, regardless of who asks. The other player has **30 seconds** to explicitly accept:
|
||||
Right-click a larger player with your **main hand** to mount immediately. Sneaking and consent are
|
||||
not required. Only the smaller rider may initiate: larger players cannot force pickup of smaller
|
||||
players. Either participant can end the ride, without administrator permission or rider approval:
|
||||
|
||||
```text
|
||||
/heights carry accept
|
||||
/heights carry decline
|
||||
/heights carry stop
|
||||
```
|
||||
|
||||
These commands require **no administrator permission**; settings and player-height commands still require `spigotheights.admin`. Console cannot carry players. One outstanding request per participant prevents replacement/ambiguous consent. Either participant can withdraw a pending request with `stop`; `decline` rejects an incoming request. Requests and carry tracking are not persisted.
|
||||
There are no consent requests, expiry timers, or accept/decline commands. Settings and player-height
|
||||
commands still require `spigotheights.admin`; console cannot carry players. Ride tracking is not
|
||||
persisted. There is no remount cooldown or opt-out: a smaller player can mount again after ejection.
|
||||
|
||||
Both players must be available and within **4 blocks**, in the same world, when requesting and accepting. Their **effective** scale difference must be at least **three current adjustment steps** (normally `0.3`), including other plugins' attribute modifiers. Neither may already have a vehicle or passengers. Heights permits only one rider per carrier, and blocks additional/nested mounts involving an active pair.
|
||||
Both players must be available and within **4 blocks**, in the same world. Their **effective** scale
|
||||
difference, including attribute modifiers, must meet `carry.minimum-scale-gap` (default **0.1**,
|
||||
independent of potion adjustment sizes). Zero still requires a strictly larger carrier. Neither
|
||||
may already have a vehicle or passengers. Heights permits only one rider per carrier and blocks
|
||||
additional/nested mounts involving an active pair. Ineligible player clicks remain uncancelled for
|
||||
other plugins; only eligible carry attempts and their same-tick duplicates are consumed.
|
||||
|
||||
Either player can stop with **normal Minecraft dismounting**. Heights calls the rider's native `leaveVehicle()` and allows ordinary sneak-dismounts, leaving placement, falling, damage, and environmental hazards to Minecraft. There is no safe-ground requirement or search, rescue teleport, saved-position/spawn fallback, motion/fall-distance reset, invulnerability, or recovery system. Getting off above a drop is a gameplay risk.
|
||||
The rider can **sneak-dismount normally**; either participant can use the stop command. Heights calls only the rider's native `leaveVehicle()` when commanded, leaving placement, falling, damage, and environmental hazards to Minecraft. There is no safe-ground requirement or search, rescue teleport, saved-position/spawn fallback, motion/fall-distance reset, invulnerability, or recovery system. Getting off above a drop is a gameplay risk.
|
||||
|
||||
Eligibility is rechecked every five ticks, including temporary potion application/expiry, administrator edits and external scale modifiers. Death, disconnect, plugin disable and loss of eligibility attempt native cleanup. For observed teleport events, Heights detaches the pair and lets the original teleport continue, without replaying or redirecting it. Native carrier teleports that refuse passengers before emitting an event may still require `/heights carry stop` first.
|
||||
|
||||
Server/plugin cancellation remains authoritative: a refused dismount leaves accurate tracking and is reported, not bypassed or called successful. A cancelled voluntary stop can be retried by either player; automatic eligibility cleanup continues checking and reports refusal once per ride rather than spamming. Lifecycle/disable refusals are logged. Native dismount events are reconciled after dispatch so a later cancellation is honored. An unrelated vehicle is never ejected during stale-pair cleanup.
|
||||
|
||||
**Verification:** automated domain and constructed Bukkit-event tests are not live-server evidence. Purpur 26.2 build 2618 still needs checks for scaled rider positioning and movement, ordinary dismount placement/falling, cancellation interoperability, both-role death/disconnect, portal/cross-world teleports, plugin disable and eligibility changes. No throwing or added launch force, player items, storage, or changes to throwable-potion opt-in behavior are included.
|
||||
**Verification:** API/domain tests preserve native cleanup and reject rescue/motion-reset calls.
|
||||
`NativeCarryRoutingTest` registers the production listener through Purpur 2618's actual Paper
|
||||
plugin manager and dispatches both `PlayerInteractEntityEvent` and `PlayerInteractAtEntityEvent`.
|
||||
Same-tick duplicate rider/target interactions are coalesced, including refused mounts; a fresh
|
||||
interaction next tick can retry without a gameplay cooldown. Registered mount/dismount cancellation
|
||||
and nonadmin stop routing are also covered. Server/player boundaries are doubled; this is not
|
||||
client-packet generation or live-server evidence. Supplementary Purpur checks remain for empty/occupied
|
||||
hands, scaled rider positioning and movement, native placement/falling, cancellation interoperability,
|
||||
both-role death/disconnect, portal/cross-world teleports, disable and potion/admin/expiry eligibility
|
||||
changes. No throwing, added launch force, player items, storage, opt-out or rescue behavior is included.
|
||||
|
||||
## Tiny-player launchers
|
||||
|
||||
@@ -94,12 +110,19 @@ height:
|
||||
minimum: 0.4
|
||||
maximum: 2.0
|
||||
adjustment-step: 0.1
|
||||
carry:
|
||||
minimum-scale-gap: 0.1
|
||||
launcher:
|
||||
maximum-player-scale-exclusive: 0.5
|
||||
speed: 1.5
|
||||
cooldown-ticks: 20
|
||||
```
|
||||
|
||||
`carry.minimum-scale-gap` is independent of potion `height.adjustment-step` and defaults to `0.1`,
|
||||
including existing files without the key. It must be a finite, nonnegative number; invalid values
|
||||
prevent plugin enable. Zero permits any strictly positive scale difference, **not equal-size riding**.
|
||||
Edit this setting in the file and restart; min/max commands preserve it.
|
||||
|
||||
Player scales are stored by UUID in `plugins/SpigotHeights/state.yml`.
|
||||
|
||||
## Commands
|
||||
@@ -136,7 +159,7 @@ Player names must match an online player exactly (case-insensitive); partial nam
|
||||
|
||||
The plugin JAR is written to `build/libs/`.
|
||||
|
||||
`check` includes `nativeBrewingTest`. It downloads the exact Purpur 26.2 build 2618 launcher (SHA-256 verified) and prepares its runtime dependencies with Paperclip's **patch-only** mode under `build/brewing-runtime/`. It does not start a server, open ports, create a world or accept the EULA. Initial/clean builds need network access; the native test JVM permits up to 1 GiB heap. No runtime implementation classes or test dependencies are packaged in the plugin. Run `./gradlew test` for the fast API/domain suite alone, or `./gradlew nativeBrewingTest` for the native brewing suite. Full verification remains `./gradlew clean check jar`.
|
||||
`check` includes `nativeBrewingTest`. It downloads the exact Purpur 26.2 build 2618 launcher (SHA-256 verified) and prepares its runtime dependencies with Paperclip's **patch-only** mode under `build/brewing-runtime/`. It does not start a server, open ports, create a world or accept the EULA. Initial/clean builds need network access; the native test JVM permits up to 1 GiB heap. No runtime implementation classes or test dependencies are packaged in the plugin. Run `./gradlew test` for the fast API/domain suite alone, or `./gradlew nativeBrewingTest` for native brewing and registered carry-event routing tests. Full verification remains `./gradlew clean check jar`.
|
||||
|
||||
## Releases
|
||||
|
||||
|
||||
Reference in New Issue
Block a user