6695: Improve snapping of draggers r=def- a=trml

These are some things i noticed could be improved while attempting to add prediction for draggers:

Sets dragger owner to be the dragged player (this also means alpha will be applied).

It also ensures that the dragger that is sent for the players own team always has the same netobject id, and additionally that an idle dragger is always sent if no one in the players owns team is dragged (before it used to be that an idle dragger wasn't sent if _any_ player was dragged, including other teams visible to the player). The first one helps with keeping track of the dragger between snapshots (and simplifies prediction), while the second one ensures that a player still sees a dragger after show_other_alpha is applied to other teams.

Also fixes snapped order of to/from pos.

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: trml <trml@users.noreply.github.com>
This commit is contained in:
bors[bot] 2023-06-01 22:22:14 +00:00 committed by GitHub
commit 2d3221492d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 9 deletions

View file

@ -160,6 +160,31 @@ void CDragger::RemoveDraggerBeam(int ClientID)
m_apDraggerBeam[ClientID] = nullptr;
}
bool CDragger::WillDraggerBeamUseDraggerID(int TargetClientID, int SnappingClientID)
{
// For each snapping client, this must return true for at most one target (i.e. only one of the dragger beams),
// in which case the dragger itself must not be snapped
CCharacter *pTargetChar = GameServer()->GetPlayerChar(TargetClientID);
CCharacter *pSnapChar = GameServer()->GetPlayerChar(SnappingClientID);
if(pTargetChar && pSnapChar && m_apDraggerBeam[TargetClientID] != nullptr)
{
if(pSnapChar->Teams()->m_Core.GetSolo(SnappingClientID))
{
return TargetClientID == SnappingClientID;
}
else if(!pTargetChar->Teams()->m_Core.GetSolo(TargetClientID))
{
const int SnapTeam = pSnapChar->Team();
const int TargetTeam = pTargetChar->Team();
if(SnapTeam == TargetTeam && SnapTeam < MAX_CLIENTS && m_aTargetIdInTeam[SnapTeam] == TargetClientID)
{
return true;
}
}
}
return false;
}
void CDragger::Reset()
{
m_MarkedForDestroy = true;
@ -171,16 +196,12 @@ void CDragger::Snap(int SnappingClient)
if(NetworkClipped(SnappingClient))
return;
// Send the dragger in its resting position if the player would not otherwise see a dragger beam
// Send the dragger in its resting position if the player would not otherwise see a dragger beam within its own team
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(m_apDraggerBeam[i] != nullptr)
if(WillDraggerBeamUseDraggerID(i, SnappingClient))
{
CCharacter *pChar = GameServer()->GetPlayerChar(i);
if(pChar && pChar->CanSnapCharacter(SnappingClient))
{
return;
}
return;
}
}

View file

@ -36,6 +36,7 @@ public:
CDragger(CGameWorld *pGameWorld, vec2 Pos, float Strength, bool IgnoreWalls, int Layer = 0, int Number = 0);
void RemoveDraggerBeam(int ClientID);
bool WillDraggerBeamUseDraggerID(int TargetClientID, int SnappingClientID);
void Reset() override;
void Tick() override;

View file

@ -121,9 +121,15 @@ void CDraggerBeam::Snap(int SnappingClient)
StartTick = Server()->Tick();
}
int SnapObjID = GetID();
if(m_pDragger->WillDraggerBeamUseDraggerID(m_ForClientID, SnappingClient))
{
SnapObjID = m_pDragger->GetID();
}
int SnappingClientVersion = GameServer()->GetClientVersion(SnappingClient);
GameServer()->SnapLaserObject(CSnapContext(SnappingClientVersion), GetID(),
m_Pos, TargetPos, StartTick, -1, LASERTYPE_DRAGGER, Subtype, m_Number);
GameServer()->SnapLaserObject(CSnapContext(SnappingClientVersion), SnapObjID,
TargetPos, m_Pos, StartTick, m_ForClientID, LASERTYPE_DRAGGER, Subtype, m_Number);
}
void CDraggerBeam::SwapClients(int Client1, int Client2)