Esempio n. 1
0
bool TransportKit::AddPassenger(WorldObject* passenger, Position const& transportPos)
{
    // possible requires check for board possibility here and return false

    // Calculate passengers local position, if not provided
    BoardPassenger(passenger, transportPos.IsEmpty() ? CalculateBoardingPositionOf(passenger->GetPosition()) : transportPos, -1);

    DETAIL_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES,"TransportKit::AddPassenger %s boarded on %s offset %f %f %f",
        passenger->GetObjectGuid().GetString().c_str(), GetBase()->GetObjectGuid().GetString().c_str(), transportPos.getX(), transportPos.getY(), transportPos.getZ());

    return true;
}
Esempio n. 2
0
/**
 * This function will board a passenger onto a vehicle
 *
 * @param passenger MUST be provided. This Unit will be boarded onto the vehicles (if it checks out)
 * @param seat      Seat to which the passenger will be boarded (if can, elsewise an alternative will be selected if possible)
 */
void VehicleInfo::Board(Unit* passenger, uint8 seat)
{
    MANGOS_ASSERT(passenger);

    DEBUG_LOG("VehicleInfo::Board: Try to board passenger %s to seat %u", passenger->GetGuidStr().c_str(), seat);

    // This check is also called in Spell::CheckCast()
    if (!CanBoard(passenger))
        return;

    // Use the planned seat only if the seat is valid, possible to choose and empty
    if (!IsSeatAvailableFor(passenger, seat))
        if (!GetUsableSeatFor(passenger, seat))
            return;

    VehicleSeatEntry const* seatEntry = GetSeatEntry(seat);
    MANGOS_ASSERT(seatEntry);

    // ToDo: Unboard passenger from a MOTransport when they are properly implemented
    /*if (TransportInfo* transportInfo = passenger->GetTransportInfo())
    {
        WorldObject* transporter = transportInfo->GetTransport();

        // Must be a MO transporter
        MANGOS_ASSERT(transporter->GetObjectGuid().IsMOTransport());

        ((Transport*)transporter)->UnBoardPassenger(passenger);
    }*/

    DEBUG_LOG("VehicleInfo::Board: Board passenger: %s to seat %u", passenger->GetGuidStr().c_str(), seat);

    // Calculate passengers local position
    float lx, ly, lz, lo;
    CalculateBoardingPositionOf(passenger->GetPositionX(), passenger->GetPositionY(), passenger->GetPositionZ(), passenger->GetOrientation(), lx, ly, lz, lo);

    BoardPassenger(passenger, lx, ly, lz, lo, seat);        // Use TransportBase to store the passenger

    // Set data for createobject packets
    passenger->m_movementInfo.SetTransportData(m_owner->GetObjectGuid(), lx, ly, lz, lo, 0, seat);

    if (passenger->GetTypeId() == TYPEID_PLAYER)
    {
        Player* pPlayer = (Player*)passenger;
        pPlayer->RemovePet(PET_SAVE_AS_CURRENT);

        WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA);
        pPlayer->GetSession()->SendPacket(&data);

        // SMSG_BREAK_TARGET (?)
    }

    if (!passenger->IsRooted())
        passenger->SetRoot(true);

    Movement::MoveSplineInit init(*passenger);
    init.MoveTo(0.0f, 0.0f, 0.0f);                          // ToDo: Set correct local coords
    init.SetFacing(0.0f);                                   // local orientation ? ToDo: Set proper orientation!
    init.SetBoardVehicle();
    init.Launch();

    // Apply passenger modifications
    ApplySeatMods(passenger, seatEntry->m_flags);
}
Esempio n. 3
0
bool VehicleKit::AddPassenger(Unit* passenger, int8 seatId)
{
    SeatMap::iterator seat;

    if (seatId < 0) // no specific seat requirement
    {
        for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
        {
            if (!seat->second.passenger && (seat->second.seatInfo->IsUsable() || (seat->second.seatInfo->m_flags & SEAT_FLAG_UNCONTROLLED)))
                break;
        }

        if (seat == m_Seats.end()) // no available seat
            return false;
    }
    else
    {
        seat = m_Seats.find(seatId);

        if (seat == m_Seats.end())
            return false;

        if (seat->second.passenger)
            return false;
    }

    VehicleSeatEntry const* seatInfo = seat->second.seatInfo;
    seat->second.passenger = passenger->GetObjectGuid();
    seat->second.b_dismount = true;

    if (!(seatInfo->m_flags & SEAT_FLAG_FREE_ACTION))
        passenger->addUnitState(UNIT_STAT_ON_VEHICLE);

    GetBase()->SetPhaseMask(passenger->GetPhaseMask(), true);

    // Calculate passengers local position
    float lx, ly, lz, lo;
    CalculateBoardingPositionOf(passenger->GetPositionX(), passenger->GetPositionY(), passenger->GetPositionZ(), passenger->GetOrientation(), lx, ly, lz, lo);

    BoardPassenger(passenger, lx, ly, lz, lo, seat->first);        // Use TransportBase to store the passenger

    passenger->m_movementInfo.ClearTransportData();
    passenger->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT);
    passenger->m_movementInfo.SetTransportData(GetBase()->GetObjectGuid(), lx, ly, lz, lo, WorldTimer::getMSTime(), seat->first, seatInfo);

    if (passenger->GetTypeId() == TYPEID_PLAYER)
    {
        ((Player*)passenger)->SetViewPoint(GetBase());
        passenger->SetRoot(true);
    }

    if (seat->second.IsProtectPassenger())
    {
        switch (GetBase()->GetEntry())
        {
            case 33651:                                     // VX 001
            case 33432:                                     // Leviathan MX
            case 33118:                                     // Ignis (Ulduar)
            case 30234:                                     // Nexus Lord's Hover Disk (Eye of Eternity, Malygos Encounter)
            case 30248:                                     // Scion's of Eternity Hover Disk (Eye of Eternity, Malygos Encounter)
                break;
            case 28817:
            default:
                passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                break;
        }
        passenger->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
    }

    if (seatInfo->m_flags & SEAT_FLAG_CAN_CONTROL)
    {
        if (!(GetEntry()->m_flags & (VEHICLE_FLAG_ACCESSORY)))
        {
            GetBase()->StopMoving();
            GetBase()->GetMotionMaster()->Clear();
            GetBase()->CombatStop(true);
        }
        GetBase()->DeleteThreatList();
        GetBase()->getHostileRefManager().deleteReferences();
        GetBase()->SetCharmerGuid(passenger->GetObjectGuid());
        GetBase()->addUnitState(UNIT_STAT_CONTROLLED);

        passenger->SetCharm(GetBase());

        if (GetBase()->HasAuraType(SPELL_AURA_FLY) || GetBase()->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED))
        {
            WorldPacket data;
            data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
            data << GetBase()->GetPackGUID();
            data << (uint32)(0);
            GetBase()->SendMessageToSet(&data,false);
        }

        if (passenger->GetTypeId() == TYPEID_PLAYER)
        {
            GetBase()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);

            if (CharmInfo* charmInfo = GetBase()->InitCharmInfo(GetBase()))
            {
                charmInfo->SetState(CHARM_STATE_ACTION,ACTIONS_DISABLE);
                charmInfo->InitVehicleCreateSpells(seat->first);
            }

            Player* player = (Player*)passenger;
            player->SetMover(GetBase());
            player->SetClientControl(GetBase(), 1);
            player->VehicleSpellInitialize();
        }

        if(!(((Creature*)GetBase())->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_KEEP_AI))
            ((Creature*)GetBase())->AIM_Initialize();

        if (GetBase()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
        {
            GetBase()->SetRoot(true);
        }
        else if (passenger->IsWalking() && !GetBase()->IsWalking())
            ((Creature*)GetBase())->SetWalk(true, true);
        else if (!passenger->IsWalking() && GetBase()->IsWalking())
            ((Creature*)GetBase())->SetWalk(false, true);
    }
    else if ((seatInfo->m_flags & SEAT_FLAG_FREE_ACTION) || (seatInfo->m_flags & SEAT_FLAG_CAN_ATTACK))
    {
        if (passenger->GetTypeId() == TYPEID_PLAYER)
        {
            Player* player = (Player*)passenger;
            player->SetClientControl(GetBase(), 0);
        }
    }

    // need correct, position not normalized currently
    passenger->GetMotionMaster()->MoveBoardVehicle(seatInfo->m_attachmentOffsetX,
        seatInfo->m_attachmentOffsetY,
        seatInfo->m_attachmentOffsetZ,
        seatInfo->m_passengerYaw,
        seatInfo->m_enterSpeed < M_NULL_F ? BASE_CHARGE_SPEED : seatInfo->m_enterSpeed,
        0.0f);

    UpdateFreeSeatCount();

    if (GetBase()->GetTypeId() == TYPEID_UNIT)
    {
        if (((Creature*)GetBase())->AI())
            ((Creature*)GetBase())->AI()->PassengerBoarded(passenger, seat->first, true);
    }
    if (passenger->GetTypeId() == TYPEID_UNIT)
    {
        if (((Creature*)passenger)->AI())
            ((Creature*)passenger)->AI()->EnteredVehicle(GetBase(), seat->first, true);
    }

    if (b_dstSet && (seatInfo->m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE_FORCED))
    {
        uint32 delay = seatInfo->m_exitMaxDuration * IN_MILLISECONDS;
        GetBase()->AddEvent(new PassengerEjectEvent(seatId,*GetBase()), delay);
        DEBUG_LOG("Vehicle::AddPassenger eject event for %s added, delay %u",passenger->GetObjectGuid().GetString().c_str(), delay);
    }

    DEBUG_LOG("VehicleKit::AddPassenger passenger %s boarded on %s, transport offset %f %f %f %f (parent - %s)",
            passenger->GetObjectGuid().GetString().c_str(),
            passenger->m_movementInfo.GetTransportGuid().GetString().c_str(),
            passenger->m_movementInfo.GetTransportPos()->x,
            passenger->m_movementInfo.GetTransportPos()->y,
            passenger->m_movementInfo.GetTransportPos()->z,
            passenger->m_movementInfo.GetTransportPos()->o,
            GetBase()->m_movementInfo.GetTransportGuid().IsEmpty() ? "<none>" : GetBase()->m_movementInfo.GetTransportGuid().GetString().c_str());

    return true;
}
Esempio n. 4
0
bool VehicleKit::AddPassenger(Unit* passenger, SeatId seatId)
{
    SeatMap::iterator seat;

    if (seatId < 0) // no specific seat requirement
    {
        for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
        {
            if (!seat->second.passengerGuid && (seat->second.seatInfo->IsUsable() || (seat->second.seatInfo->m_flags & SEAT_FLAG_UNCONTROLLED)))
                break;
        }

        if (seat == m_Seats.end()) // no available seat
            return false;
    }
    else
    {
        seat = m_Seats.find(seatId);

        if (seat == m_Seats.end())
            return false;

        if (seat->second.passengerGuid)
            return false;
    }

    VehicleSeatEntry const* seatInfo = seat->second.seatInfo;
    seat->second.passengerGuid = passenger->GetObjectGuid();
    seat->second.b_dismount = true;

    if (!(seatInfo->m_flags & SEAT_FLAG_FREE_ACTION))
        passenger->addUnitState(UNIT_STAT_ON_VEHICLE);

    GetBase()->SetPhaseMask(passenger->GetPhaseMask(), true);

    // Calculate passengers local position
    Position localPos = CalculateBoardingPositionOf(passenger->GetPosition());

    BoardPassenger(passenger, localPos, seat->first);        // Use TransportBase to store the passenger

    if (passenger->GetTypeId() == TYPEID_PLAYER)
    {
        ((Player*)passenger)->SetViewPoint(GetBase());
        ((Player*)passenger)->SetGravity(false);

        passenger->SetRoot(true, (seatInfo->m_flags & (SEAT_FLAG_CAN_CAST | SEAT_FLAG_CAN_ATTACK) ? 2 : 0));
    }

    if (seat->second.IsProtectPassenger())
    {
        // make passenger attackable in some vehicles and allow him to cast when sitting on vehicle
        switch (GetBase()->GetEntry())
        {
            case 29625:        // Hyldsmeet Proto-Drake
            case 30234:        // Nexus Lord's Hover Disk (Eye of Eternity, Malygos Encounter)
            case 30248:        // Scion's of Eternity Hover Disk (Eye of Eternity, Malygos Encounter)
            case 33118:        // Ignis (Ulduar)
            case 33432:        // Leviathan MX
            case 33651:        // VX 001
                break;
//            case 28817:        // Mine Car (quest Massacre At Light's Point)
//            case 28864:        // Scourge Gryphon (quest Massacre At Light's Point)
            default:
                passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                break;
        }
        passenger->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
    }

    if (passenger->GetTypeId() == TYPEID_UNIT)
    {
        if (seatInfo->m_flags & SEAT_FLAG_NOT_SELECTABLE)
            passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
    }

    if ((seatInfo->m_flags & SEAT_FLAG_CAN_CONTROL) && GetBase()->GetTypeId() == TYPEID_UNIT)
    {
        if (!(GetEntry()->m_flags & VEHICLE_FLAG_ACCESSORY))
        {
            GetBase()->StopMoving();
            GetBase()->GetMotionMaster()->Clear();
            GetBase()->CombatStop(true);
        }

        GetBase()->DeleteThreatList();
        GetBase()->getHostileRefManager().deleteReferences();
        GetBase()->SetCharmerGuid(passenger->GetObjectGuid());
        GetBase()->addUnitState(UNIT_STAT_CONTROLLED);

        passenger->SetCharm(GetBase());

        if (GetBase()->HasAuraType(SPELL_AURA_FLY) || GetBase()->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED) ||
            (GetBase()->GetTypeId() == TYPEID_UNIT && ((Creature*)GetBase())->CanFly()))
        {
            WorldPacket data;
            GetBase()->BuildMoveSetCanFlyPacket(&data, true, 0);
            GetBase()->SendMessageToSet(&data, false);
        }

        if (passenger->GetTypeId() == TYPEID_PLAYER)
        {
            GetBase()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);

            if (CharmInfo* charmInfo = GetBase()->InitCharmInfo(GetBase()))
            {
                charmInfo->SetState(CHARM_STATE_ACTION, ACTIONS_DISABLE);
                charmInfo->InitVehicleCreateSpells(seat->first);
            }

            Player* player = (Player*)passenger;
            player->SetMover(GetBase());
            player->SetClientControl(GetBase(), 1);
            player->VehicleSpellInitialize();
        }

        // Allow to keep AI of controlled vehicle with CREATURE_FLAG_EXTRA_KEEP_AI extra-flag
        if (!(((Creature*)GetBase())->GetCreatureInfo()->ExtraFlags & CREATURE_FLAG_EXTRA_KEEP_AI))
            ((Creature*)GetBase())->AIM_Initialize();

        if (GetBase()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
        {
            GetBase()->SetRoot(true);
            // save player's walk mode for further use in dismount
            ((Creature*)GetBase())->SetWalk(passenger->IsWalking(), true);
        }
        // Set owner's speedrate to vehicle at board.
        else if (passenger->IsWalking() && !GetBase()->IsWalking())
            ((Creature*)GetBase())->SetWalk(true, true);
        else if (!passenger->IsWalking() && GetBase()->IsWalking())
            ((Creature*)GetBase())->SetWalk(false, true);
    }
    else if ((seatInfo->m_flags & SEAT_FLAG_FREE_ACTION) || (seatInfo->m_flags & SEAT_FLAG_CAN_ATTACK))
    {
        if (passenger->GetTypeId() == TYPEID_PLAYER)
            ((Player*)passenger)->SetClientControl(GetBase(), 0);
    }

    // Calculate passenger seat position (FIXME - requires correct calculation!)
    Position seatpos = CalculateSeatPositionOf(seatInfo);
    passenger->GetMotionMaster()->MoveBoardVehicle(seatpos.x, seatpos.y, seatpos.z, seatpos.o,
        seatInfo->m_enterSpeed < M_NULL_F ? BASE_CHARGE_SPEED : seatInfo->m_enterSpeed,
        0.0f);

    UpdateFreeSeatCount();

    if (passenger->GetTypeId() == TYPEID_PLAYER)
    {
        // group update
        if (((Player*)passenger)->GetGroup())
            ((Player*)passenger)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT);
    }

    if (GetBase()->GetTypeId() == TYPEID_UNIT)
    {
        if (((Creature*)GetBase())->AI())
            ((Creature*)GetBase())->AI()->PassengerBoarded(passenger, seat->first, true);
    }

    if (passenger->GetTypeId() == TYPEID_UNIT)
    {
        if (((Creature*)passenger)->AI())
        {
            ((Creature*)passenger)->AI()->SetCombatMovement(false);
            ((Creature*)passenger)->AI()->EnteredVehicle(GetBase(), seat->first, true);
        }

        // Not entirely sure how this must be handled in relation to CONTROL
        // But in any way this at least would require some changes in the movement system most likely
        passenger->GetMotionMaster()->Clear(false, true);
    }

    if (m_dstSet && (seatInfo->m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE_FORCED))
    {
        uint32 delay = seatInfo->m_exitMaxDuration * IN_MILLISECONDS;
        GetBase()->AddEvent(new PassengerEjectEvent(seatId, *GetBase()), delay);
        DEBUG_LOG("Vehicle::AddPassenger eject event for %s added, delay %u", passenger->GetGuidStr().c_str(), delay);
    }

    DEBUG_LOG("VehicleKit::AddPassenger passenger %s boarded on %s, transport offset %f %f %f %f (parent - %s)",
            passenger->GetGuidStr().c_str(),
            passenger->m_movementInfo.GetTransportGuid().GetString().c_str(),
            passenger->m_movementInfo.GetTransportPos()->x,
            passenger->m_movementInfo.GetTransportPos()->y,
            passenger->m_movementInfo.GetTransportPos()->z,
            passenger->m_movementInfo.GetTransportPos()->o,
            GetBase()->m_movementInfo.GetTransportGuid().IsEmpty() ? "<none>" : GetBase()->m_movementInfo.GetTransportGuid().GetString().c_str());

    return true;
}