diff --git a/Code/client/Services/Generic/OverlayService.cpp b/Code/client/Services/Generic/OverlayService.cpp index 50f2b3a734..8c9a9fce18 100644 --- a/Code/client/Services/Generic/OverlayService.cpp +++ b/Code/client/Services/Generic/OverlayService.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -491,7 +493,10 @@ void OverlayService::RunPlayerHealthUpdates() noexcept static float s_previousPercentage = -1.f; - const float newPercentage = CalculateHealthPercentage(PlayerCharacter::Get()); + // The party UI shows a bar, so whole percents are enough. Round up so that 0 still means dead. + // Without rounding, regeneration in combat changes the value on every tick and each update + // makes the overlay redraw. + const float newPercentage = std::ceil(CalculateHealthPercentage(PlayerCharacter::Get())); if (newPercentage == s_previousPercentage) return; diff --git a/Code/skyrim_ui/src/app/components/group/group.component.html b/Code/skyrim_ui/src/app/components/group/group.component.html index 522ea6325f..4f64c96989 100644 --- a/Code/skyrim_ui/src/app/components/group/group.component.html +++ b/Code/skyrim_ui/src/app/components/group/group.component.html @@ -5,7 +5,7 @@ [ngStyle]="positionStyle | async" >
{ this.flashGroup(); @@ -210,6 +210,10 @@ export class GroupComponent implements OnInit, OnDestroy { } } + public trackByMemberId(_index: number, member: Player) { + return member.id; + } + public invite(playerId: number) { this.groupService.invite(playerId); } diff --git a/Code/skyrim_ui/src/app/services/client.service.ts b/Code/skyrim_ui/src/app/services/client.service.ts index cb69624922..c9b9e620ed 100644 --- a/Code/skyrim_ui/src/app/services/client.service.ts +++ b/Code/skyrim_ui/src/app/services/client.service.ts @@ -484,7 +484,9 @@ export class ClientService implements OnDestroy { private onSetHealth(playerId: number, health: number) { this.zone.run(() => { - this.healthChange.next(new Player({ id: playerId, health: health })); + this.healthChange.next( + new Player({ id: playerId, health: Math.ceil(health) }), + ); }); } diff --git a/Code/skyrim_ui/src/app/services/group.service.ts b/Code/skyrim_ui/src/app/services/group.service.ts index 706a19f93b..539b628d40 100644 --- a/Code/skyrim_ui/src/app/services/group.service.ts +++ b/Code/skyrim_ui/src/app/services/group.service.ts @@ -6,6 +6,7 @@ import { Observable, of, pluck, + Subject, Subscription, } from 'rxjs'; import { filter, map } from 'rxjs/operators'; @@ -25,6 +26,9 @@ import { Sound, SoundService } from './sound.service'; export class GroupService implements OnDestroy { public group = new BehaviorSubject(undefined); + /** Emits the id of a party member whose health value actually changed. */ + public memberHealthChange = new Subject(); + private debugSubscription: Subscription; private connectionSubscription: Subscription; private userHealthSubscription: Subscription; @@ -102,9 +106,10 @@ export class GroupService implements OnDestroy { if (group) { const foundPlayer = this.playerListService.getPlayerById(player.id); - if (foundPlayer) { + if (foundPlayer && foundPlayer.health !== player.health) { foundPlayer.health = player.health; this.updateGroup(); + this.memberHealthChange.next(foundPlayer.id); } } },