From ec7b78616b20a8052186d77e203d33a0406d0ea4 Mon Sep 17 00:00:00 2001 From: Eshed Date: Thu, 7 Jan 2016 12:17:20 +0200 Subject: [PATCH] Fix bug when giving units --- rts/Sim/Misc/QuadField.cpp | 35 +++++++++++++++++++----------- rts/Sim/Misc/QuadField.h | 4 ++-- rts/Sim/Units/Unit.cpp | 3 +-- rts/Sim/Weapons/PlasmaRepulser.cpp | 6 ++--- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/rts/Sim/Misc/QuadField.cpp b/rts/Sim/Misc/QuadField.cpp index 1dd7fee82b2..4173b4d529a 100644 --- a/rts/Sim/Misc/QuadField.cpp +++ b/rts/Sim/Misc/QuadField.cpp @@ -283,16 +283,13 @@ void CQuadField::MovedUnit(CUnit* unit) } for (const int qi: unit->quads) { - std::vector& quadUnits = baseQuads[qi].units; - std::vector& quadAllyUnits = baseQuads[qi].teamUnits[unit->allyteam]; - - VectorErase(quadUnits, unit); - VectorErase(quadAllyUnits, unit); + VectorErase(baseQuads[qi].units, unit); + VectorErase(baseQuads[qi].teamUnits[unit->allyteam], unit); } for (const int qi: newQuads) { - baseQuads[qi].units.push_back(unit); - baseQuads[qi].teamUnits[unit->allyteam].push_back(unit); + VectorInsertUnique(baseQuads[qi].units, unit, false); + VectorInsertUnique(baseQuads[qi].teamUnits[unit->allyteam], unit, false); } unit->quads = std::move(newQuads); @@ -309,10 +306,20 @@ void CQuadField::RemoveUnit(CUnit* unit) } unit->quads.clear(); + + #ifdef DEBUG_QUADFIELD + for (const Quad& q: baseQuads) { + for (auto& teamUnits: q.teamUnits) { + for (CUnit* u: teamUnits) { + assert(u != unit); + } + } + } + #endif } -void CQuadField::MovedRepulsor(CPlasmaRepulser* repulser) +void CQuadField::MovedRepulser(CPlasmaRepulser* repulser) { auto newQuads = std::move(GetQuads(repulser->weaponMuzzlePos, repulser->GetRadius())); @@ -328,13 +335,13 @@ void CQuadField::MovedRepulsor(CPlasmaRepulser* repulser) } for (const int qi: newQuads) { - baseQuads[qi].repulsers.push_back(repulser); + VectorInsertUnique(baseQuads[qi].repulsers, repulser, false); } repulser->quads = std::move(newQuads); } -void CQuadField::RemoveRepulsor(CPlasmaRepulser* repulser) +void CQuadField::RemoveRepulser(CPlasmaRepulser* repulser) { const auto& quads = GetQuads(repulser->weaponMuzzlePos, repulser->GetRadius()); @@ -342,6 +349,8 @@ void CQuadField::RemoveRepulsor(CPlasmaRepulser* repulser) VectorErase(baseQuads[qi].repulsers, repulser); } + repulser->quads.clear(); + #ifdef DEBUG_QUADFIELD for (const Quad& q: baseQuads) { for (CPlasmaRepulser* r: q.repulsers) { @@ -357,7 +366,7 @@ void CQuadField::AddFeature(CFeature* feature) const auto& newQuads = GetQuads(feature->pos, feature->radius); for (const int qi: newQuads) { - baseQuads[qi].features.push_back(feature); + VectorInsertUnique(baseQuads[qi].features, feature, false); } } @@ -403,13 +412,13 @@ void CQuadField::AddProjectile(CProjectile* p) auto newQuads = std::move(GetQuadsOnRay(p->pos, p->dir, p->speed.w)); for (const int qi: newQuads) { - baseQuads[qi].projectiles.push_back(p); + VectorInsertUnique(baseQuads[qi].projectiles, p, false); } p->quads = std::move(newQuads); } else { int newQuad = WorldPosToQuadFieldIdx(p->pos); - baseQuads[newQuad].projectiles.push_back(p); + VectorInsertUnique(baseQuads[newQuad].projectiles, p, false); p->quads.clear(); p->quads.push_back(newQuad); } diff --git a/rts/Sim/Misc/QuadField.h b/rts/Sim/Misc/QuadField.h index 16745c00a1a..6ff676a0d7f 100644 --- a/rts/Sim/Misc/QuadField.h +++ b/rts/Sim/Misc/QuadField.h @@ -95,8 +95,8 @@ needed to support dynamic resizing (not used yet) void AddProjectile(CProjectile* projectile); void RemoveProjectile(CProjectile* projectile); - void MovedRepulsor(CPlasmaRepulser* repulser); - void RemoveRepulsor(CPlasmaRepulser* repulser); + void MovedRepulser(CPlasmaRepulser* repulser); + void RemoveRepulser(CPlasmaRepulser* repulser); struct Quad { CR_DECLARE_STRUCT(Quad) diff --git a/rts/Sim/Units/Unit.cpp b/rts/Sim/Units/Unit.cpp index d4a4d59196b..b0ffffac05f 100644 --- a/rts/Sim/Units/Unit.cpp +++ b/rts/Sim/Units/Unit.cpp @@ -1516,8 +1516,6 @@ bool CUnit::ChangeTeam(int newteam, ChangeType type) eoh->UnitCaptured(*this, oldteam, newteam); quadField->RemoveUnit(this); - quads.clear(); - quadField->MovedUnit(this); if (type == ChangeGiven) { @@ -1540,6 +1538,7 @@ bool CUnit::ChangeTeam(int newteam, ChangeType type) team = newteam; allyteam = teamHandler->AllyTeam(newteam); neutral = false; + quadField->MovedUnit(this); unitHandler->unitsByDefs[oldteam][unitDef->id].erase(this); unitHandler->unitsByDefs[newteam][unitDef->id].insert(this); diff --git a/rts/Sim/Weapons/PlasmaRepulser.cpp b/rts/Sim/Weapons/PlasmaRepulser.cpp index 97bc5f99847..a12381e1e93 100644 --- a/rts/Sim/Weapons/PlasmaRepulser.cpp +++ b/rts/Sim/Weapons/PlasmaRepulser.cpp @@ -49,7 +49,7 @@ CPlasmaRepulser::CPlasmaRepulser(CUnit* owner, const WeaponDef* def): CWeapon(ow CPlasmaRepulser::~CPlasmaRepulser() { shieldProjectile->PreDelete(); - quadField->RemoveRepulsor(this); + quadField->RemoveRepulser(this); } @@ -67,7 +67,7 @@ void CPlasmaRepulser::Init() CWeapon::Init(); - quadField->MovedRepulsor(this); + quadField->MovedRepulser(this); // deleted by ProjectileHandler shieldProjectile = new ShieldProjectile(this); @@ -117,7 +117,7 @@ void CPlasmaRepulser::Update() UpdateWeaponVectors(); collisionVolume.SetOffsets((relWeaponMuzzlePos - owner->relMidPos) * WORLD_TO_OBJECT_SPACE); if (weaponMuzzlePos != lastPos) - quadField->MovedRepulsor(this); + quadField->MovedRepulser(this); lastPos = weaponMuzzlePos; }