コード例 #1
0
ファイル: Item.cpp プロジェクト: Bootz/mangos
void Item::AddToUpdateQueueOf(Player* player)
{
    if (IsInUpdateQueue())
        return;

    if (!player)
    {
        player = GetOwner();
        if (!player)
        {
            sLog.outError("Item::AddToUpdateQueueOf - %s current owner (%s) not in world!",
                GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str());
            return;
        }
    }

    if (player->GetObjectGuid() != GetOwnerGuid())
    {
        sLog.outError("Item::AddToUpdateQueueOf - %s current owner (%s) and inventory owner (%s) don't match!",
            GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str(), player->GetGuidStr().c_str());
        return;
    }

    if (player->m_itemUpdateQueueBlocked)
        return;

    player->m_itemUpdateQueue.push_back(this);
    uQueuePos = player->m_itemUpdateQueue.size() -1;
}
コード例 #2
0
void Item::RemoveFromUpdateQueueOf(Player* player)
{
    if (!IsInUpdateQueue())
        return;

    if (!player)
    {
        player = GetOwner();
        if (!player)
        {
            sLog.outError("Item::RemoveFromUpdateQueueOf - %s current owner (%s) not in world!",
                          GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str());
            return;
        }
    }

    if (player->GetObjectGuid() != GetOwnerGuid())
    {
        sLog.outError("Item::RemoveFromUpdateQueueOf - %s current owner (%s) and inventory owner (%s) don't match!",
                      GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str(), player->GetGuidStr().c_str());
        return;
    }

    if (player->m_itemUpdateQueueBlocked)
        return;

    player->m_itemUpdateQueue[uQueuePos] = NULL;
    uQueuePos = -1;
}
コード例 #3
0
ファイル: DynamicObject.cpp プロジェクト: Jojo2323/mangos3
void DynamicObject::Update(uint32 /*update_diff*/, uint32 p_time)
{
    Unit* caster = NULL;
    if (GetType() == DYNAMIC_OBJECT_RAID_MARKER)
    {
        Group* group = sObjectMgr.GetGroup(GetCasterGuid());
        if (!group || !group->HasRaidMarker(GetObjectGuid()))
        {
            Delete();
            return;
        }
    }
    else
    {
        caster = GetCaster();
        // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor
        if (!caster)
        {
            Delete();
            return;
        }
    }

    bool deleteThis = false;

    if (m_aliveDuration > int32(p_time))
        m_aliveDuration -= p_time;
    else
        deleteThis = true;

    // have radius and work as persistent effect
    if (m_radius && caster)
    {
        // TODO: make a timer and update this in larger intervals
        MaNGOS::DynamicObjectUpdater notifier(*this, caster, m_positive);
        Cell::VisitAllObjects(this, notifier, m_radius);
    }

    if (deleteThis)
    {
        DEBUG_LOG("DynObject %s type %u removed from caster %s", GetGuidStr().c_str(), GetType(), caster->GetGuidStr().c_str());

        if (GetType() == DYNAMIC_OBJECT_RAID_MARKER)
        {
            if (Group* group = sObjectMgr.GetGroup(GetCasterGuid()))
                group->ClearRaidMarker(GetObjectGuid());
        }
        else
            caster->RemoveDynObjectWithGuid(GetObjectGuid());

        Delete();
    }
}
コード例 #4
0
ファイル: Item.cpp プロジェクト: Splash/mangos
void Item::LoadLootFromDB(Field* fields)
{
    uint32 itemId     = fields[1].GetUInt32();
    uint32 itemAmount = fields[2].GetUInt32();

    // money value special case
    if (!itemId)
    {
        loot.gold = itemAmount;
        SetLootState(ITEM_LOOT_UNCHANGED);
        return;
    }

    // normal item case
    ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemId);
    if (!proto)
    {
        DeleteLootFromDB(GetGUIDLow(), itemId);
        sLog.outError("Item::LoadLootFromDB: %s has an unknown item (id: %u) in item_loot, deleted.", GetGuidStr().c_str(), itemId);
        return;
    }

    uint32 itemSuffix = fields[3].GetUInt32();
    int32  itemPropId = fields[4].GetInt32();

    loot.items.push_back(LootItem(itemId, itemAmount, itemSuffix, itemPropId));
    ++loot.unlootedCount;

    SetLootState(ITEM_LOOT_UNCHANGED);
}
コード例 #5
0
ファイル: Item.cpp プロジェクト: Splash/mangos
bool Item::LoadFromDB(uint32 guidLow, Field* fields, ObjectGuid ownerGuid)
{
    // create item before any checks for store correct guid
    // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB
    Object::_Create(ObjectGuid(HIGHGUID_ITEM, guidLow));

    if (!LoadValues(fields[0].GetString()))
    {
        sLog.outError("Item::LoadFromDB: %s have broken data in `data` field. Can't be loaded.", GetGuidStr().c_str());
        return false;
    }

    SetText(fields[1].GetCppString());

    bool needSave = false;                                  // need explicit save data at load fixes

    // overwrite possible wrong/corrupted guid
    ObjectGuid new_item_guid = ObjectGuid(HIGHGUID_ITEM, guidLow);
    if (GetGuidValue(OBJECT_FIELD_GUID) != new_item_guid)
    {
        SetGuidValue(OBJECT_FIELD_GUID, new_item_guid);
        needSave = true;
    }

    ItemPrototype const* proto = GetProto();
    if (!proto)
        return false;

    // update max durability (and durability) if need
    if (proto->MaxDurability != GetUInt32Value(ITEM_FIELD_MAXDURABILITY))
    {
        SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability);
        if (GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability)
            SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability);

        needSave = true;
    }

    // recalculate suffix factor
    if (GetItemRandomPropertyId() < 0)
    {
        if (UpdateItemSuffixFactor())
            needSave = true;
    }

    // Remove bind flag for items vs NO_BIND set
    if (IsSoulBound() && proto->Bonding == NO_BIND)
    {
        ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_BINDED, false);
        needSave = true;
    }

    // update duration if need, and remove if not need
    if ((proto->Duration == 0) != (GetUInt32Value(ITEM_FIELD_DURATION) == 0))
    {
        SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration);
        needSave = true;
    }

    // set correct owner
    if (ownerGuid && GetOwnerGuid() != ownerGuid)
    {
        SetOwnerGuid(ownerGuid);
        needSave = true;
    }

    // set correct wrapped state
    if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
    {
        // wrapped item must be wrapper (used version that not stackable)
        if (!(proto->Flags & ITEM_FLAG_WRAPPER) || GetMaxStackCount() > 1)
        {
            RemoveFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED);
            needSave = true;

            // also cleanup for sure gift table
            DeleteGiftsFromDB();
        }
    }

    if (needSave)                                          // normal item changed state set not work at loading
    {
        std::ostringstream ss;
        for (uint16 i = 0; i < m_valuesCount; ++i)
            ss << GetUInt32Value(i) << " ";

        static SqlStatementID updItem;
        SqlStatement stmt = CharacterDatabase.CreateStatement(updItem, "UPDATE item_instance SET owner_guid = ?, data = ? WHERE guid = ?");
        stmt.PExecute(GetOwnerGuid().GetCounter(), ss.str().c_str(), guidLow);
    }

    return true;
}
コード例 #6
0
ファイル: Transports.cpp プロジェクト: Splash/mangos
void Transport::DoEventIfAny(WayPointMap::value_type const& node, bool departure)
{
    if (uint32 eventid = departure ? node.second.departureEventID : node.second.arrivalEventID)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES, "Taxi %s event %u of node %u of %s \"%s\") path", departure ? "departure" : "arrival", eventid, node.first, GetGuidStr().c_str(), GetName());

        if (!sScriptMgr.OnProcessEvent(eventid, this, this, departure))
            GetMap()->ScriptsStart(sEventScripts, eventid, this, this);
    }
}
コード例 #7
0
ファイル: Corpse.cpp プロジェクト: krullgor/mangos-wotlk
bool Corpse::LoadFromDB(uint32 lowguid, Field* fields)
{
    ////                                                    0            1       2                  3                  4                  5                   6
    // QueryResult *result = CharacterDatabase.Query("SELECT corpse.guid, player, corpse.position_x, corpse.position_y, corpse.position_z, corpse.orientation, corpse.map,"
    ////   7     8            9         10         11      12    13     14           15            16              17       18
    //    "time, corpse_type, instance, phaseMask, gender, race, class, playerBytes, playerBytes2, equipmentCache, guildId, playerFlags FROM corpse"
    uint32 playerLowGuid = fields[1].GetUInt32();
    float positionX     = fields[2].GetFloat();
    float positionY     = fields[3].GetFloat();
    float positionZ     = fields[4].GetFloat();
    float orientation   = fields[5].GetFloat();
    uint32 mapid        = fields[6].GetUInt32();

    Object::_Create(lowguid, 0, HIGHGUID_CORPSE);

    m_time = time_t(fields[7].GetUInt64());
    m_type = CorpseType(fields[8].GetUInt32());

    if (m_type >= MAX_CORPSE_TYPE)
    {
        sLog.outError("%s Owner %s have wrong corpse type (%i), not load.", GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str(), m_type);
        return false;
    }

    uint32 instanceid   = fields[9].GetUInt32();
    uint32 phaseMask    = fields[10].GetUInt32();
    uint8 gender        = fields[11].GetUInt8();
    uint8 race          = fields[12].GetUInt8();
    uint8 _class        = fields[13].GetUInt8();
    uint32 playerBytes  = fields[14].GetUInt32();
    uint32 playerBytes2 = fields[15].GetUInt32();
    uint32 guildId      = fields[17].GetUInt32();
    uint32 playerFlags  = fields[18].GetUInt32();

    ObjectGuid guid = ObjectGuid(HIGHGUID_CORPSE, lowguid);
    ObjectGuid playerGuid = ObjectGuid(HIGHGUID_PLAYER, playerLowGuid);

    // overwrite possible wrong/corrupted guid
    SetGuidValue(OBJECT_FIELD_GUID, guid);
    SetOwnerGuid(playerGuid);

    SetObjectScale(DEFAULT_OBJECT_SCALE);

    PlayerInfo const* info = sObjectMgr.GetPlayerInfo(race, _class);
    if (!info)
    {
        sLog.outError("Player %u has incorrect race/class pair.", GetGUIDLow());
        return false;
    }
    SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, gender == GENDER_FEMALE ? info->displayId_f : info->displayId_m);

    // Load equipment
    Tokens data = StrSplit(fields[16].GetCppString(), " ");
    for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
    {
        uint32 visualbase = slot * 2;
        uint32 item_id = GetUInt32ValueFromArray(data, visualbase);
        const ItemPrototype* proto = ObjectMgr::GetItemPrototype(item_id);
        if (!proto)
        {
            SetUInt32Value(CORPSE_FIELD_ITEM + slot, 0);
            continue;
        }

        SetUInt32Value(CORPSE_FIELD_ITEM + slot, proto->DisplayInfoID | (proto->InventoryType << 24));
    }

    uint8 skin       = (uint8)(playerBytes);
    uint8 face       = (uint8)(playerBytes >> 8);
    uint8 hairstyle  = (uint8)(playerBytes >> 16);
    uint8 haircolor  = (uint8)(playerBytes >> 24);
    uint8 facialhair = (uint8)(playerBytes2);
    SetUInt32Value(CORPSE_FIELD_BYTES_1, ((0x00) | (race << 8) | (gender << 16) | (skin << 24)));
    SetUInt32Value(CORPSE_FIELD_BYTES_2, ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24)));

    SetUInt32Value(CORPSE_FIELD_GUILD, guildId);

    uint32 flags = CORPSE_FLAG_UNK2;
    if (playerFlags & PLAYER_FLAGS_HIDE_HELM)
        flags |= CORPSE_FLAG_HIDE_HELM;
    if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK)
        flags |= CORPSE_FLAG_HIDE_CLOAK;
    SetUInt32Value(CORPSE_FIELD_FLAGS, flags);

    // no need to mark corpse as lootable, because corpses are not saved in battle grounds

    // place
    SetLocationInstanceId(instanceid);
    SetLocationMapId(mapid);
    SetPhaseMask(phaseMask, false);
    Relocate(positionX, positionY, positionZ, orientation);

    if (!IsPositionValid())
    {
        sLog.outError("%s Owner %s not created. Suggested coordinates isn't valid (X: %f Y: %f)",
                      GetGuidStr().c_str(), GetOwnerGuid().GetString().c_str(), GetPositionX(), GetPositionY());
        return false;
    }

    m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY());

    return true;
}
コード例 #8
0
void TemporarySummon::Update(uint32 update_diff, uint32 diff)
{
    TSUpdateActions ua = TSUA_NONE;

    switch (m_type)
    {
        case TEMPSUMMON_MANUAL_DESPAWN:
            break;
        case TEMPSUMMON_DEAD_DESPAWN:
        {
            if (IsDespawned())
                ua = TSUA_UNSUMMON;
            break;
        }
        case TEMPSUMMON_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            if (isDead())
                ua = TSUA_UNSUMMON;
            break;
        }
        case TEMPSUMMON_CORPSE_TIMED_DESPAWN:
        {
            if (IsDespawned())
                ua = TSUA_UNSUMMON;
            else if (IsCorpse())
                ua = TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_DESPAWN:
        {
            ua = TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_OOC_DESPAWN:
        {
            ua = isInCombat() ? TSUA_RESET_TIMER : TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_OR_DEAD_DESPAWN:
        {
            ua = IsDespawned() ? TSUA_UNSUMMON : TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN:
        {
            // if m_deathState is DEAD, CORPSE was skipped
            ua = isDead() ? TSUA_UNSUMMON : TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN:
        {
            if (IsDespawned())
                ua = TSUA_UNSUMMON;
            else
                ua = (!isInCombat() && isAlive()) ? TSUA_CHECK_TIMER : TSUA_RESET_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN:
        {
            if (isDead())
                ua = TSUA_UNSUMMON;
            else
                ua = isInCombat() ? TSUA_RESET_TIMER : TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_LOST_OWNER_DESPAWN:
        case TEMPSUMMON_DEAD_OR_LOST_OWNER_DESPAWN:
        {
            if (m_type == TEMPSUMMON_DEAD_OR_LOST_OWNER_DESPAWN && IsDespawned())
                ua = TSUA_UNSUMMON;
            else if (!GetSummoner())
            {
                m_type = TEMPSUMMON_TIMED_DESPAWN;
                m_lifetime = DEFAULT_DESPAWN_DELAY;
                ua = TSUA_RESET_TIMER;
            }
            break;
        }
        case TEMPSUMMON_TIMED_OR_DEAD_OR_LOST_OWNER_DESPAWN:
        {
            ua = (IsDespawned() || !GetSummoner()) ? TSUA_UNSUMMON : TSUA_CHECK_TIMER;
            break;
        }
        case TEMPSUMMON_TIMED_OR_DEAD_OR_LOST_UNIQUENESS_DESPAWN:
        {
            ua = IsDespawned() ? TSUA_UNSUMMON : TSUpdateActions(TSUA_CHECK_UNIQUENESS | TSUA_CHECK_TIMER);
            break;
        }
        case TEMPSUMMON_DEAD_OR_LOST_UNIQUENESS_DESPAWN:
        {
            ua = IsDespawned() ? TSUA_UNSUMMON : TSUA_CHECK_UNIQUENESS;
            break;
        }
        default:
            ua = TSUA_UNSUMMON;
            sLog.outError("Temporary summoned %s have unknown type %u of", GetGuidStr().c_str(), m_type);
            break;
    }

    if (ua & TSUA_RESET_TIMER)
    {
        if (m_timer != m_lifetime)
            m_timer = m_lifetime;
    }
    else if (ua & TSUA_CHECK_TIMER)
    {
        if (m_timer <= update_diff)
            ua = TSUA_UNSUMMON;
        else
            m_timer -= update_diff;
    }

    if (ua & TSUA_CHECK_UNIQUENESS)
    {
        std::list<Creature*> tlist;
        MaNGOS::AllIdenticalObjectsInRangeCheck check(this, GetMap()->GetVisibilityDistance());
        MaNGOS::CreatureListSearcher<MaNGOS::AllIdenticalObjectsInRangeCheck> searcher(tlist, check);
        Cell::VisitGridObjects(this, searcher, GetMap()->GetVisibilityDistance(), true);

        for (std::list<Creature*>::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
        {
            Creature* pCre = *itr;
            if (!pCre || !pCre->isAlive() || !pCre->IsTemporarySummon())
                continue;

            if (((TemporarySummon*)pCre)->GetTempSummonType() == GetTempSummonType() &&
                ((TemporarySummon*)pCre)->GetSummonerGuid() == GetSummonerGuid())
            {
                ua = TSUA_UNSUMMON;
                break;
            }
        }
    }

    if (ua & TSUA_UNSUMMON)
    {
        UnSummon();
        return;
    }

    if (!m_isActive)
        return;

    Creature::Update(update_diff, diff);
}