diff options
author | Shauren <shauren.trinity@gmail.com> | 2013-06-04 16:28:30 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2013-06-04 16:28:30 +0200 |
commit | eed1286a8c5cba31a75fd8f17fc78bef865d3a83 (patch) | |
tree | 283e0f4e5ce60448a14489546b8de8964adae368 /src | |
parent | f03f443150b5bc9db38bda708600185179f9bda8 (diff) |
Core/Vehicles: Handle vehicle seat switches through aura effects.
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 49 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rwxr-xr-x | src/server/game/Entities/Vehicle/Vehicle.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Vehicle/Vehicle.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 7 |
5 files changed, 37 insertions, 31 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4ad2a06a61e..b62b5124987 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16816,29 +16816,23 @@ void Unit::EnterVehicle(Unit* base, int8 seatId) void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp) { // Must be called only from aura handler + ASSERT(aurApp); + if (!isAlive() || GetVehicleKit() == vehicle || vehicle->GetBase()->IsOnVehicle(this)) return; if (m_vehicle) { - if (m_vehicle == vehicle) - { - if (seatId >= 0 && seatId != GetTransSeat()) - { - TC_LOG_DEBUG(LOG_FILTER_VEHICLES, "EnterVehicle: %u leave vehicle %u seat %d and enter %d.", GetEntry(), m_vehicle->GetBase()->GetEntry(), GetTransSeat(), seatId); - ChangeSeat(seatId); - } - - return; - } - else + if (m_vehicle != vehicle) { TC_LOG_DEBUG(LOG_FILTER_VEHICLES, "EnterVehicle: %u exit %u and enter %u.", GetEntry(), m_vehicle->GetBase()->GetEntry(), vehicle->GetBase()->GetEntry()); ExitVehicle(); } + else if (seatId >= 0 && seatId == GetTransSeat()) + return; } - if (!aurApp || aurApp->GetRemoveMode()) + if (aurApp->GetRemoveMode()) return; if (Player* player = ToPlayer()) @@ -16868,16 +16862,22 @@ void Unit::ChangeSeat(int8 seatId, bool next) if (seat == m_vehicle->Seats.end() || seat->second.Passenger) return; - // Todo: the functions below could be consolidated and refactored to take - // SeatMap::const_iterator as parameter, to save redundant map lookups. - m_vehicle->RemovePassenger(this); + AuraEffect* rideVehicleEffect = NULL; + AuraEffectList const& vehicleAuras = m_vehicle->GetBase()->GetAuraEffectsByType(SPELL_AURA_CONTROL_VEHICLE); + for (AuraEffectList::const_iterator itr = vehicleAuras.begin(); itr != vehicleAuras.end(); ++itr) + { + if ((*itr)->GetCasterGUID() != GetGUID()) + continue; + + // Make sure there is only one ride vehicle aura on target cast by the unit changing seat + ASSERT(!rideVehicleEffect); + rideVehicleEffect = *itr; + } - // Set m_vehicle to NULL before adding passenger as adding new passengers is handled asynchronously - // and someone may call ExitVehicle again before passenger is added to new seat - Vehicle* veh = m_vehicle; - m_vehicle = NULL; - if (!veh->AddPassenger(this, seatId)) - ASSERT(false); + // Unit riding a vehicle must always have control vehicle aura on target + ASSERT(rideVehicleEffect); + + rideVehicleEffect->ChangeAmount(seat->first + 1); } void Unit::ExitVehicle(Position const* /*exitPosition*/) @@ -16907,7 +16907,8 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (!m_vehicle) return; - m_vehicle->RemovePassenger(this); + // This should be done before dismiss, because there may be some aura removal + Vehicle* vehicle = m_vehicle->RemovePassenger(this); Player* player = ToPlayer(); @@ -16915,10 +16916,6 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (player && player->duel && player->duel->isMounted) player->DuelComplete(DUEL_FLED); - // This should be done before dismiss, because there may be some aura removal - Vehicle* vehicle = m_vehicle; - m_vehicle = NULL; - SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT Position pos; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 67a6fa2a994..c65f08ffa6f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2082,6 +2082,7 @@ class Unit : public WorldObject void RemoveVehicleKit(); Vehicle* GetVehicleKit()const { return m_vehicleKit; } Vehicle* GetVehicle() const { return m_vehicle; } + void SetVehicle(Vehicle* vehicle) { m_vehicle = vehicle; } bool IsOnVehicle(const Unit* vehicle) const; Unit* GetVehicleBase() const; Creature* GetVehicleCreatureBase() const; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 86ea67c2d0f..5cfb9cc2fae 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -496,10 +496,10 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) * @param [in, out] unit The passenger to remove. */ -void Vehicle::RemovePassenger(Unit* unit) +Vehicle* Vehicle::RemovePassenger(Unit* unit) { if (unit->GetVehicle() != this) - return; + return NULL; SeatMap::iterator seat = GetSeatIteratorForPassenger(unit); ASSERT(seat != Seats.end()); @@ -531,6 +531,9 @@ void Vehicle::RemovePassenger(Unit* unit) if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnRemovePassenger(this, unit); + + unit->SetVehicle(NULL); + return this; } /** @@ -801,7 +804,7 @@ bool VehicleJoinEvent::Execute(uint64, uint32) Target->RemovePendingEventsForSeat(Seat->first); - Passenger->m_vehicle = Target; + Passenger->SetVehicle(Target); Seat->second.Passenger = Passenger->GetGUID(); if (Seat->second.SeatInfo->CanEnterOrExit()) { diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index c83a9fa5f33..9fb1b6614b5 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -59,7 +59,7 @@ class Vehicle : public TransportBase bool AddPassenger(Unit* passenger, int8 seatId = -1); void EjectPassenger(Unit* passenger, Unit* controller); - void RemovePassenger(Unit* passenger); + Vehicle* RemovePassenger(Unit* passenger); void RelocatePassengers(); void RemoveAllPassengers(); bool IsVehicleInUse() const; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b65213e134d..0f1950bc860 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2926,7 +2926,12 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m if (caster->GetTypeId() == TYPEID_UNIT) caster->ToCreature()->RemoveCorpse(); } - caster->_ExitVehicle(); + + if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT)) + caster->_ExitVehicle(); + else + target->GetVehicleKit()->RemovePassenger(caster); // Only remove passenger from vehicle without launching exit movement or despawning the vehicle + // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them caster->RemoveAurasDueToSpell(GetId()); } |