Skip to content

Commit dea4c05

Browse files
Merge pull request #733 from miredirex/tweak/reveal-players-overhaul
Made the 'Reveal Players' feature more user-friendly
2 parents f0418fc + e7226de commit dea4c05

File tree

20 files changed

+164
-18
lines changed

20 files changed

+164
-18
lines changed

Code/client/Services/Generic/MagicService.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -463,23 +463,47 @@ void MagicService::ApplyQueuedEffects() noexcept
463463
m_queuedRemoteEffects.erase(serverId);
464464
}
465465

466-
void MagicService::UpdateRevealOtherPlayersEffect() noexcept
466+
void MagicService::StartRevealingOtherPlayers() noexcept
467467
{
468-
if (GetAsyncKeyState(VK_F4) & 0x01)
469-
m_revealOtherPlayers = !m_revealOtherPlayers;
468+
UpdateRevealOtherPlayersEffect(/*forceTrigger=*/true);
469+
}
470470

471-
if (!m_revealOtherPlayers)
472-
return;
471+
void MagicService::UpdateRevealOtherPlayersEffect(bool aForceTrigger) noexcept
472+
{
473+
constexpr auto cRevealDuration = 10s;
474+
constexpr auto cDelayBetweenUpdates = 2s;
475+
476+
// Effect's activation and lifecycle
473477

478+
static std::chrono::steady_clock::time_point revealStartTimePoint;
474479
static std::chrono::steady_clock::time_point lastSendTimePoint;
475-
constexpr auto cDelayBetweenUpdates = 2s;
480+
481+
const bool shouldActivate = aForceTrigger || GetAsyncKeyState(VK_F4) & 0x01;
482+
483+
if (shouldActivate && !m_revealingOtherPlayers)
484+
{
485+
m_revealingOtherPlayers = true;
486+
revealStartTimePoint = std::chrono::steady_clock::now();
487+
}
488+
489+
if (!m_revealingOtherPlayers)
490+
return;
476491

477492
const auto now = std::chrono::steady_clock::now();
493+
494+
if (now - revealStartTimePoint > cRevealDuration)
495+
{
496+
m_revealingOtherPlayers = false;
497+
return;
498+
}
499+
478500
if (now - lastSendTimePoint < cDelayBetweenUpdates)
479501
return;
480502

481503
lastSendTimePoint = now;
482504

505+
// When active
506+
483507
Mod* pSkyrimTogether = ModManager::Get()->GetByName("SkyrimTogether.esp");
484508
if (!pSkyrimTogether)
485509
return;

Code/client/Services/Generic/OverlayClient.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <TiltedOnlinePCH.h>
22

33
#include <OverlayRenderHandler.hpp>
4+
#include <DInputHook.hpp>
45

56
#include <Services/OverlayClient.h>
67
#include <Services/TransportService.h>
@@ -44,6 +45,8 @@ bool OverlayClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefR
4445
ProcessConnectMessage(eventArgs);
4546
else if (eventName == "disconnect")
4647
ProcessDisconnectMessage();
48+
else if (eventName == "revealPlayers")
49+
ProcessRevealPlayersMessage();
4750
else if (eventName == "sendMessage")
4851
ProcessChatMessage(eventArgs);
4952
else if (eventName == "setTime")
@@ -105,6 +108,12 @@ void OverlayClient::ProcessDisconnectMessage()
105108
World::Get().GetRunner().Queue([]() { World::Get().GetTransport().Close(); });
106109
}
107110

111+
void OverlayClient::ProcessRevealPlayersMessage()
112+
{
113+
SetUIVisible(false);
114+
World::Get().GetMagicService().StartRevealingOtherPlayers();
115+
}
116+
108117
void OverlayClient::ProcessChatMessage(CefRefPtr<CefListValue> aEventArgs)
109118
{
110119
std::string contents = aEventArgs->GetString(1).ToString();
@@ -140,3 +149,14 @@ void OverlayClient::ProcessToggleDebugUI()
140149
{
141150
World::Get().GetDebugService().m_showDebugStuff = !World::Get().GetDebugService().m_showDebugStuff;
142151
}
152+
153+
void OverlayClient::SetUIVisible(bool aVisible) noexcept
154+
{
155+
auto pRenderer = GetOverlayRenderHandler();
156+
if (!pRenderer)
157+
return;
158+
159+
TiltedPhoques::DInputHook::Get().SetEnabled(aVisible);
160+
World::Get().GetOverlayService().SetActive(aVisible);
161+
pRenderer->SetCursorVisible(aVisible);
162+
}

Code/client/Services/MagicService.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ struct MagicService
3333

3434
TP_NOCOPYMOVE(MagicService);
3535

36+
/**
37+
* @brief Starts revealing remote players for a few seconds
38+
* @see UpdateRevealOtherPlayersEffect
39+
*/
40+
void StartRevealingOtherPlayers() noexcept;
41+
3642
protected:
3743
/**
3844
* @brief Checks to apply queued effects on each frame.
@@ -75,7 +81,7 @@ struct MagicService
7581
/**
7682
* Apply the "reveal players" effect on remote players.
7783
*/
78-
void UpdateRevealOtherPlayersEffect() noexcept;
84+
void UpdateRevealOtherPlayersEffect(bool aForceTrigger = false) noexcept;
7985

8086
World& m_world;
8187
entt::dispatcher& m_dispatcher;
@@ -88,7 +94,7 @@ struct MagicService
8894
Map<uint32_t, AddTargetRequest> m_queuedEffects;
8995
Map<uint32_t, NotifyAddTarget> m_queuedRemoteEffects;
9096

91-
bool m_revealOtherPlayers = false;
97+
bool m_revealingOtherPlayers = false;
9298

9399
entt::scoped_connection m_updateConnection;
94100
entt::scoped_connection m_spellCastEventConnection;

Code/client/Services/OverlayClient.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ struct OverlayClient : TiltedPhoques::OverlayClient
2424
private:
2525
void ProcessConnectMessage(CefRefPtr<CefListValue> aEventArgs);
2626
void ProcessDisconnectMessage();
27+
void ProcessRevealPlayersMessage();
2728
void ProcessChatMessage(CefRefPtr<CefListValue> aEventArgs);
2829
void ProcessSetTimeCommand(CefRefPtr<CefListValue> aEventArgs);
2930
void ProcessTeleportMessage(CefRefPtr<CefListValue> aEventArgs);
3031
void ProcessToggleDebugUI();
32+
void SetUIVisible(bool aVisible) noexcept;
3133

3234
TransportService& m_transport;
3335
};

Code/client/World.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <Services/CharacterService.h>
77
#include <Services/OverlayService.h>
88
#include <Services/CharacterService.h>
9+
#include <Services/MagicService.h>
910
#include <Services/DebugService.h>
1011

1112
#include <Systems/ModSystem.h>
@@ -31,6 +32,8 @@ struct World : entt::registry
3132
const OverlayService& GetOverlayService() const noexcept { return ctx().at<const OverlayService>(); }
3233
DebugService& GetDebugService() noexcept { return ctx().at<DebugService>(); }
3334
const DebugService& GetDebugService() const noexcept { return ctx().at<const DebugService>(); }
35+
MagicService& GetMagicService() noexcept { return ctx().at<MagicService>(); }
36+
const MagicService& GetMagicService() const noexcept { return ctx().at<const MagicService>(); }
3437

3538
auto& GetDispatcher() noexcept { return m_dispatcher; }
3639

Code/skyrim_ui/src/app/components/root/root.component.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,25 @@
4848
>
4949
{{ 'COMPONENT.ROOT.PLAYER_MANAGER' | transloco }}
5050
</button>
51+
<button data-style-ornament="inverted" (click)="revealPlayers()">
52+
<!-- See note in 'root.component.scss' for explanation -->
53+
<div style="position: relative;">
54+
<span
55+
class="cooldown-supporting-text-normal"
56+
[class.cooldown-supporting-text-animating]="revealingInProgress$"
57+
>
58+
{{ 'COMPONENT.ROOT.REVEAL_PLAYERS' | transloco }}
59+
</span>
60+
<span
61+
style="position: absolute; left: 0; top: 0;"
62+
class="text-cooldown-effect"
63+
[class.cooldown-active]="revealingInProgress$"
64+
[style.--cooldown-duration]="revealingInProgress$ ? '10s' : '0.3s'"
65+
>
66+
{{ 'COMPONENT.ROOT.REVEAL_PLAYERS' | transloco }}
67+
</span>
68+
</div>
69+
</button>
5170
</ng-container>
5271
<button
5372
data-style-ornament="inverted"

Code/skyrim_ui/src/app/components/root/root.component.scss

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
}
6363

6464
> app-notifications {
65-
width: 30vw;
65+
width: 32vw;
6666
left: $-size-gap;
6767
bottom: $-size-gap;
6868
position: absolute;
@@ -76,7 +76,7 @@
7676
::ng-deep {
7777
.app-root-popups {
7878
> app-popup > app-window {
79-
max-width: 30vw;
79+
max-width: 32vw;
8080
min-width: 20vw;
8181
}
8282

@@ -98,9 +98,8 @@
9898
position: absolute;
9999
left: $-size-gap;
100100
display: flex;
101-
align-items: center;
102101
flex-direction: column;
103-
width: 30vw;
102+
width: 32vw;
104103
bottom: $-size-gap;
105104
}
106105

@@ -112,6 +111,7 @@
112111
.app-root-menu {
113112
display: flex;
114113
height: 4rem;
114+
margin: 0 auto;
115115

116116
> button {
117117
flex: 1 1 auto;
@@ -131,3 +131,34 @@
131131
flex: 1 1 auto;
132132
}
133133
}
134+
135+
// Note: due to how `-webkit-background-clip` renders clipped text (that's needed for
136+
// the cooldown effect), we need to apply a few workarounds to make it look just right. I'm sorry!
137+
138+
.cooldown-supporting-text-normal {
139+
color: mod($-color-background, 0.8);
140+
transition: color 0.3s linear;
141+
}
142+
143+
.cooldown-supporting-text-animating {
144+
color: mod($-color-background, 0.3);
145+
}
146+
147+
.text-cooldown-effect {
148+
--cooldown-duration: 10s;
149+
background: linear-gradient(
150+
to left,
151+
mod($-color-background, 0.3) 50%,
152+
mod($-color-background, 1) 50%
153+
);
154+
background-clip: text;
155+
-webkit-background-clip: text;
156+
transition: background-position var(--cooldown-duration) linear;
157+
color: transparent;
158+
background-size: 200%;
159+
background-position: 0%;
160+
161+
&.cooldown-active {
162+
background-position: 100%;
163+
}
164+
}

Code/skyrim_ui/src/app/components/root/root.component.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { controlsAnimation } from './controls.animation';
1919
import { notificationsAnimation } from './notifications.animation';
2020
import { map } from 'rxjs/operators';
2121

22+
const REVEAL_EFFECT_DURATION_MS = 10000 // todo: pass value from C++?
23+
2224
@Component({
2325
selector: 'app-root',
2426
templateUrl: './root.component.html',
@@ -41,8 +43,8 @@ export class RootComponent implements OnInit {
4143
menuOpen$ = this.client.openingMenuChange.asObservable();
4244
inGame$ = this.client.inGameStateChange.asObservable();
4345
active$ = this.client.activationStateChange.asObservable();
44-
connectionInProgress$ =
45-
this.client.isConnectionInProgressChange.asObservable();
46+
connectionInProgress$ = this.client.isConnectionInProgressChange.asObservable();
47+
revealingInProgress$ = false;
4648

4749
@ViewChild('chat') private chatComp!: ChatComponent;
4850
@ViewChild(GroupComponent) private groupComponent: GroupComponent;
@@ -122,4 +124,15 @@ export class RootComponent implements OnInit {
122124
public reconnect(): void {
123125
this.client.reconnect();
124126
}
127+
128+
public revealPlayers(): void {
129+
if (this.revealingInProgress$)
130+
return;
131+
132+
this.revealingInProgress$ = true;
133+
setTimeout(() => { this.revealingInProgress$ = false }, REVEAL_EFFECT_DURATION_MS);
134+
135+
this.sound.play(Sound.Focus);
136+
this.client.revealPlayers();
137+
}
125138
}

Code/skyrim_ui/src/app/mock/skyrimtogether.mock.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ export class SkyrimtogetherMock extends EventEmitter implements SkyrimTogether {
105105
throw new Error('NOT YET IMPLEMENTED');
106106
}
107107

108+
revealPlayers(): void {
109+
this.sendMessage(MessageTypes.SYSTEM_MESSAGE, "Revealing players...");
110+
}
111+
112+
setTime(hours: number, minutes: number): void {
113+
this.sendMessage(MessageTypes.SYSTEM_MESSAGE, `Setting time to "${hours}:${minutes}"!`);
114+
}
115+
108116
sendMessage(type: MessageTypes, message: string): void {
109117
if (this.connected) {
110118
this.emit('message', type, message, this.playerName);

Code/skyrim_ui/src/app/services/client.service.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ export class ClientService implements OnDestroy {
209209
this._remainingReconnectionAttempt = 0;
210210
}
211211

212+
/**
213+
* Reveal players in the immediate area (lighting them up with a visual effect).
214+
*/
215+
public revealPlayers(): void {
216+
skyrimtogether.revealPlayers();
217+
}
218+
212219
/**
213220
* Launch a party.
214221
*/

0 commit comments

Comments
 (0)