fix(teleport): enforce visitor warm-up
This commit is contained in:
@@ -21,7 +21,7 @@ As a **player with Base III**, I want to open my base to visitors so that other
|
|||||||
- [x] `/gotobase <owner>` autocompletes bases that the requesting player is currently eligible to visit.
|
- [x] `/gotobase <owner>` autocompletes bases that the requesting player is currently eligible to visit.
|
||||||
- [x] `/visit <owner>` aliases `/gotobase <owner>` with identical autocomplete, including eligible bases whose owners are offline.
|
- [x] `/visit <owner>` aliases `/gotobase <owner>` with identical autocomplete, including eligible bases whose owners are offline.
|
||||||
- [x] Enabled bases remain visitable while their owners are offline.
|
- [x] Enabled bases remain visitable while their owners are offline.
|
||||||
- [x] A visitor teleport uses the destination owner's current warm-up tier.
|
- [x] A visitor teleport uses the destination owner's current warm-up tier, but always requires at least a one-second stationary warm-up; `/visit` and `/gotobase` never teleport instantly.
|
||||||
- [x] Looking around is permitted, while movement between block coordinates, damage, teleportation, world change, death, logout, or a conflicting teleport cancels the visitor warm-up.
|
- [x] Looking around is permitted, while movement between block coordinates, damage, teleportation, world change, death, logout, or a conflicting teleport cancels the visitor warm-up.
|
||||||
- [x] Cancellation or destination failure does not consume a visitor cooldown.
|
- [x] Cancellation or destination failure does not consume a visitor cooldown.
|
||||||
- [x] A safe destination is resolved at or near the owner's recorded base center.
|
- [x] A safe destination is resolved at or near the owner's recorded base center.
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ final class BaseTeleportManager implements Listener {
|
|||||||
begin(
|
begin(
|
||||||
visitor,
|
visitor,
|
||||||
owner.base().orElseThrow(),
|
owner.base().orElseThrow(),
|
||||||
policy.warmup(owner),
|
policy.visitorWarmup(owner),
|
||||||
owner.playerId(),
|
owner.playerId(),
|
||||||
policy.cooldown(owner),
|
policy.cooldown(owner),
|
||||||
"visit " + owner.latestName() + "'s base"
|
"visit " + owner.latestName() + "'s base"
|
||||||
|
|||||||
@@ -25,6 +25,13 @@ public final class TeleportPolicy {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Duration visitorWarmup(PlayerState owner) {
|
||||||
|
Duration warmup = warmup(owner);
|
||||||
|
return warmup.compareTo(Duration.ofSeconds(1)) < 0
|
||||||
|
? Duration.ofSeconds(1)
|
||||||
|
: warmup;
|
||||||
|
}
|
||||||
|
|
||||||
public Duration cooldown(PlayerState player) {
|
public Duration cooldown(PlayerState player) {
|
||||||
return switch (player.cooldownLevel()) {
|
return switch (player.cooldownLevel()) {
|
||||||
case 0 -> Duration.ofSeconds(settings.current().initialTeleportCooldownSeconds());
|
case 0 -> Duration.ofSeconds(settings.current().initialTeleportCooldownSeconds());
|
||||||
|
|||||||
@@ -22,6 +22,17 @@ final class TeleportPolicyTest {
|
|||||||
assertEquals(Duration.ZERO, policy.warmup(player.withTeleportLevels(3, 0)));
|
assertEquals(Duration.ZERO, policy.warmup(player.withTeleportLevels(3, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void visitorWarmupHasOneSecondMinimum() {
|
||||||
|
PlayerState player = baseThreePlayer();
|
||||||
|
|
||||||
|
assertEquals(Duration.ofSeconds(30), policy.visitorWarmup(player));
|
||||||
|
assertEquals(
|
||||||
|
Duration.ofSeconds(1),
|
||||||
|
policy.visitorWarmup(player.withTeleportLevels(3, 0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void cooldownLevelsUseApprovedDurations() {
|
void cooldownLevelsUseApprovedDurations() {
|
||||||
PlayerState player = baseThreePlayer();
|
PlayerState player = baseThreePlayer();
|
||||||
|
|||||||
Reference in New Issue
Block a user