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; }
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; }
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(); } }
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); }
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; }
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); } }
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; }
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); }