Permalink
Browse files

Correctly transmit spectator health

  • Loading branch information...
DolceTriade committed Dec 7, 2015
1 parent b467d3a commit 6a9b17bd171eac622d8d79e26d89f8c04cc13eac
Showing with 7 additions and 1 deletion.
  1. +7 −1 src/sgame/components/HealthComponent.cpp
@@ -18,7 +18,13 @@ void HealthComponent::HandlePrepareNetCode() {
gclient_t *client = entity.oldEnt->client;

if (client) {
if (client->ps.stats[STAT_HEALTH] != transmittedHealth) {
// if we are doing a chase cam or a remote view, grab the latest info
if (client->sess.spectatorState == SPECTATOR_FOLLOW) {
gentity_t *otherEnt = &g_entities[ entity.oldEnt->client->sess.spectatorClient ];
const HealthComponent *otherComp = otherEnt->entity->Get<HealthComponent>();
maxHealth = otherComp->maxHealth;
transmittedHealth = Math::Clamp((int)std::ceil(otherComp->health), -999, 999);
} else if (client->ps.stats[STAT_HEALTH] != transmittedHealth) {
client->pers.infoChangeTime = level.time;
}
client->ps.stats[STAT_HEALTH] = transmittedHealth;

5 comments on commit 6a9b17b

@Viech

This comment has been minimized.

Copy link
Member

Viech replied Dec 7, 2015

This looks like special-casing the spectator case within, potentially, every component used by a client. That is not acceptable. Spectator handling must be outside the regular component logic, if at all possible. I will need to disucss the best way to do this with @Kangz.

Please revert – not only should we avoid workarounds within CBSE whenever possible (we'll end up re-refactoring our own code instead of progressing with the conversion), but also you can't just change the component's maxHealth field within HandlePrepareNetcode, which is only ever supposed to export the component state to the network, not modify the component. I prefer to keep spectating broken and improve on the general client/spectator handling for next relase.

@DolceTriade

This comment has been minimized.

Copy link
Member

DolceTriade replied Dec 7, 2015

Definitely will revert when we have an appropriate alternative. Currently, spectator is handled by copying over the player who is being spectated's playerState_t. perhaps something analogous can be done with the entity?

@Viech

This comment has been minimized.

Copy link
Member

Viech replied Dec 8, 2015

If that's all that is necessary, we could add a SpectatorEntity with a SpectatorComponent that does this inside HandlePrepareNetCode.

Is there a lazy way to turn this thread into an issue? 😛

@DolceTriade

This comment has been minimized.

Copy link
Member

DolceTriade replied Dec 9, 2015

However, the issue with that is that HandleNetCode could be executed N times, where N is the number of times the player is being spectated. It would be annoying having to iterate, store specs somewhere else, and then iterate over the specs, which is further complicated by the fact that with stickySpec enabled, spectators can spectate spectators...

@Viech

This comment has been minimized.

Copy link
Member

Viech replied Dec 9, 2015

I think you misread my post. We certainly should not have multiple clients attached to any one entity or component. I was suggesting to add a SpectatorEntity used by spectating clients that would have a SpectatorComponent (and not much more) that would copy the networked state from the client/spectator being spectated to its own entity's (= the SpectatorEntity's) networked state.

Please sign in to comment.