コード例 #1
0
ファイル: Transport.cpp プロジェクト: Exodius/ArkCORE-NG
TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
{
    Map* map = FindMap();
    if (!map)
        return NULL;

    uint32 mask = UNIT_MASK_SUMMON;
    if (properties)
    {
        switch (properties->Category)
        {
        case SUMMON_CATEGORY_PET:
            mask = UNIT_MASK_GUARDIAN;
            break;
        case SUMMON_CATEGORY_PUPPET:
            mask = UNIT_MASK_PUPPET;
            break;
        case SUMMON_CATEGORY_VEHICLE:
            mask = UNIT_MASK_MINION;
            break;
        case SUMMON_CATEGORY_WILD:
        case SUMMON_CATEGORY_ALLY:
        case SUMMON_CATEGORY_UNK:
        {
            switch (properties->Type)
            {
            case SUMMON_TYPE_MINION:
            case SUMMON_TYPE_GUARDIAN:
            case SUMMON_TYPE_GUARDIAN2:
                mask = UNIT_MASK_GUARDIAN;
                break;
            case SUMMON_TYPE_TOTEM:
            case SUMMON_TYPE_LIGHTWELL:
                mask = UNIT_MASK_TOTEM;
                break;
            case SUMMON_TYPE_VEHICLE:
            case SUMMON_TYPE_VEHICLE2:
                mask = UNIT_MASK_SUMMON;
                break;
            case SUMMON_TYPE_MINIPET:
                mask = UNIT_MASK_MINION;
                break;
            default:
                if (properties->Flags & 512) // Mirror Image, Summon Gargoyle
                    mask = UNIT_MASK_GUARDIAN;
                break;
            }
            break;
        }
        default:
            return NULL;
        }
    }

    uint64 phaseMask = PHASEMASK_NORMAL;
    std::set<uint16> phaseIds;
    if (summoner)
        phaseIds = summoner->GetPhaseIds();
    else
        phaseIds = GetPhaseIds(); // If there was no summoner, try to use the transport phases

    uint32 team = 0;
    if (summoner)
    {
        phaseMask = summoner->GetPhaseMask();
        if (summoner->GetTypeId() == TYPEID_PLAYER)
            team = summoner->ToPlayer()->GetTeam();
    }

    TempSummon* summon = nullptr;
    switch (mask)
    {
    case UNIT_MASK_SUMMON:
        summon = new TempSummon(properties, summoner, false);
        break;
    case UNIT_MASK_GUARDIAN:
        summon = new Guardian(properties, summoner, false);
        break;
    case UNIT_MASK_PUPPET:
        summon = new Puppet(properties, summoner);
        break;
    case UNIT_MASK_TOTEM:
        summon = new Totem(properties, summoner);
        break;
    case UNIT_MASK_MINION:
        summon = new Minion(properties, summoner, false);
        break;
    }

    float x, y, z, o;
    pos.GetPosition(x, y, z, o);
    CalculatePassengerPosition(x, y, z, &o);

    if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phaseMask, entry, vehId, team, x, y, z, o))
    {
        delete summon;
        return NULL;
    }

    for (uint16 phase : phaseIds)
        summon->SetInPhase(phase, false, true);

    summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);

    summon->SetTransport(this);
    summon->m_movementInfo.transport.guid = GetGUID();
    summon->m_movementInfo.transport.pos.Relocate(pos);
    summon->Relocate(x, y, z, o);
    summon->SetHomePosition(x, y, z, o);
    summon->SetTransportHomePosition(pos);

    /// @HACK - transport models are not added to map's dynamic LoS calculations
    ///         because the current GameObjectModel cannot be moved without recreating
    summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);

    summon->InitStats(duration);

    if (!map->AddToMap<Creature>(summon))
    {
        delete summon;
        return NULL;
    }

    _staticPassengers.insert(summon);

    summon->InitSummon();
    summon->SetTempSummonType(summonType);

    return summon;
}