void Totem::InitStats(uint32 duration) { // client requires SMSG_TOTEM_CREATED to be sent before adding to world and before removing old totem if (GetOwner()->GetTypeId() == TYPEID_PLAYER && m_Properties->Slot >= SUMMON_SLOT_TOTEM && m_Properties->Slot < MAX_TOTEM_SLOT) { WorldPacket data(SMSG_TOTEM_CREATED, 1 + 8 + 4 + 4); data << uint8(m_Properties->Slot - 1); data << uint64(GetGUID()); data << uint32(duration); data << uint32(GetUInt32Value(UNIT_CREATED_BY_SPELL)); GetOwner()->ToPlayer()->SendDirectMessage(&data); // set display id depending on caster's race SetDisplayId(GetOwner()->GetModelForTotem(PlayerTotemType(m_Properties->Id))); } Minion::InitStats(duration); // Get spell cast by totem if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(GetSpell())) if (totemSpell->CalcCastTime()) // If spell has cast time -> its an active totem m_type = TOTEM_ACTIVE; if (GetEntry() == SENTRY_TOTEM_ENTRY) { Position pos; GetOwner()->GetPosition(&pos); Relocate(&pos); } m_duration = duration; SetLevel(GetOwner()->getLevel()); }
bool Item::CanBeTraded(bool mail, bool trade) const { if (m_lootGenerated) return false; if ((!mail || !IsBoundAccountWide()) && (IsSoulBound() && (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_BOP_TRADEABLE) || !trade))) return false; if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty())) return false; if (Player* owner = GetOwner()) { if (owner->CanUnequipItem(GetPos(), false) != EQUIP_ERR_OK) return false; if (owner->GetLootGUID() == GetGUID()) return false; } if (IsBoundByEnchant()) return false; return true; }
Creature* Transport::AddNPCPassenger (uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim) { Map* map = GetMap(); Creature* pCreature = new Creature; if (!pCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0)) { delete pCreature; return 0; } pCreature->SetTransport(this); pCreature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); pCreature->m_movementInfo.guid = GetGUID(); pCreature->m_movementInfo.t_pos.Relocate(x, y, z, o); o += GetOrientation(); MapManager::NormalizeOrientation(o); pCreature->Relocate(GetPositionX() + (x * cos(GetOrientation()) + y * sin(GetOrientation() + float(M_PI))), GetPositionY() + (y * cos(GetOrientation()) + x * sin(GetOrientation())), z + GetPositionZ(), o); pCreature->SetHomePosition(pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ(), pCreature->GetOrientation()); if (!pCreature->IsPositionValid()) { sLog->outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)", pCreature->GetGUIDLow(), pCreature->GetEntry(), pCreature->GetPositionX(), pCreature->GetPositionY()); delete pCreature; return 0; } map->Add(pCreature); m_NPCPassengerSet.insert(pCreature); pCreature->setActive(true); sScriptMgr->OnAddCreaturePassenger(this, pCreature); return pCreature; }
bool Item::CanBeTraded(bool mail) const { if(!mail && IsBoundAccountWide()) // Dirty hack, because trade window is closing return false; if ((!mail || !IsBoundAccountWide()) && IsSoulBound()) return false; if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()) ) return false; if (Player* owner = GetOwner()) { if (owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK ) return false; if (owner->GetLootGUID()==GetGUID()) return false; } if (IsBoundByEnchant()) return false; return true; }
void Item::SendEnchantTimeUpdate( uint32 Slot, uint32 Duration ) { /* {SERVER} Packet: (0x01EB) SMSG_ITEM_ENCHANT_TIME_UPDATE Size = 24 |------------------------------------------------|----------------| |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| |------------------------------------------------|----------------| |69 32 F0 35 00 00 00 40 01 00 00 00 08 07 00 00 |i2.5...@........| |51 46 35 00 00 00 00 00 |QF5..... | ------------------------------------------------------------------- uint64 item_guid uint32 count? uint32 time_in_seconds uint64 player_guid */ WorldPacket* data = new WorldPacket(SMSG_ITEM_ENCHANT_TIME_UPDATE, 24 ); *data << GetGUID(); *data << Slot; *data << Duration; *data << m_owner->GetGUID(); m_owner->delayedPackets.add( data ); }
bool Item::CanBeTraded() const { if (m_lootGenerated) return false; if (IsSoulBound()) return false; if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty())) return false; if (Player* owner = GetOwner()) { if (owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK) return false; if (owner->GetLootGUID() == GetGUID()) return false; } if (IsBoundByEnchant()) return false; return true; }
GameObject::~GameObject() { sEventMgr.RemoveEvents(this); if(m_ritualmembers) { delete[] m_ritualmembers; m_ritualmembers = NULL; } uint32 guid = GetUInt32Value(OBJECT_FIELD_CREATED_BY); if(guid) { Player *plr = objmgr.GetPlayer(guid); if(plr && plr->GetSummonedObject() == this) plr->SetSummonedObject(NULL); if(plr == m_summoner) m_summoner = 0; } if(m_respawnCell!=NULL) hashmap64_remove(m_respawnCell->_respawnObjects, GetGUID()); if (m_summonedGo && m_summoner) for(int i = 0; i < 4; i++) if (m_summoner->m_ObjectSlots[i] == GetLowGUID()) m_summoner->m_ObjectSlots[i] = 0; if( m_battleground != NULL && m_battleground->GetType() == BATTLEGROUND_ARATHI_BASIN ) { if( bannerslot >= 0 && static_cast<ArathiBasin*>(m_battleground)->m_controlPoints[bannerslot] == this ) static_cast<ArathiBasin*>(m_battleground)->m_controlPoints[bannerslot] = NULL; if( bannerauraslot >= 0 && static_cast<ArathiBasin*>(m_battleground)->m_controlPointAuras[bannerauraslot] == this ) static_cast<ArathiBasin*>(m_battleground)->m_controlPointAuras[bannerauraslot] = NULL; } }
void Vehicle::AddPassenger(Unit *unit, int8 seatId, bool force) { SeatMap::iterator seat; seat = m_Seats.find(seatId); // this should never happen if(seat == m_Seats.end()) return; unit->SetVehicleGUID(GetGUID()); seat->second.passenger = unit; if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->isVehicle()) { if(((Vehicle*)unit)->GetEmptySeatsCount(true) == 0) seat->second.flags = SEAT_VEHICLE_FULL; else seat->second.flags = SEAT_VEHICLE_FREE; } else { seat->second.flags = SEAT_FULL; } if(unit->GetTypeId() == TYPEID_PLAYER) { WorldPacket data0(SMSG_FORCE_MOVE_ROOT, 10); data0 << unit->GetPackGUID(); data0 << (uint32)((seat->second.vs_flags & SF_CAN_CAST) ? 2 : 0); unit->SendMessageToSet(&data0,true); } if(seat->second.vs_flags & SF_MAIN_RIDER) { if(!(GetVehicleFlags() & VF_MOVEMENT)) { GetMotionMaster()->Clear(false); GetMotionMaster()->MoveIdle(); SetCharmerGUID(unit->GetGUID()); unit->SetUInt64Value(UNIT_FIELD_CHARM, GetGUID()); if(unit->GetTypeId() == TYPEID_PLAYER) { ((Player*)unit)->SetMover(this); ((Player*)unit)->SetMoverInQueve(this); ((Player*)unit)->SetClientControl(this, 1); } if(canFly() || HasAuraType(SPELL_AURA_FLY) || HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED)) { WorldPacket data3(SMSG_MOVE_SET_CAN_FLY, 12); data3<< GetPackGUID(); data3 << (uint32)(0); SendMessageToSet(&data3,false); } } SpellClickInfoMapBounds clickPair = sObjectMgr.GetSpellClickInfoMapBounds(GetEntry()); for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) { if (unit->GetTypeId() == TYPEID_UNIT || itr->second.IsFitToRequirements((Player*)unit)) { Unit *caster = (itr->second.castFlags & 0x1) ? unit : this; Unit *target = (itr->second.castFlags & 0x2) ? unit : this; caster->CastSpell(target, itr->second.spellId, true); } } if(unit->GetTypeId() == TYPEID_PLAYER) { // it should be added only on rider enter? if(((Player*)unit)->GetGroup()) ((Player*)unit)->SetGroupUpdateFlag(GROUP_UPDATE_VEHICLE); ((Player*)unit)->GetCamera().SetView(this); BuildVehicleActionBar((Player*)unit); } if(!(GetVehicleFlags() & VF_FACTION)) setFaction(unit->getFaction()); if(GetVehicleFlags() & VF_CANT_MOVE) { WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10); data2<< GetPackGUID(); data2 << (uint32)(2); SendMessageToSet(&data2,false); } if(GetVehicleFlags() & VF_NON_SELECTABLE) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } if(seat->second.vs_flags & SF_UNATTACKABLE) unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); EmptySeatsCountChanged(); }
void Item::SaveToDB(SQLTransaction& trans) { bool isInTransaction = bool(trans); if (!isInTransaction) trans = CharacterDatabase.BeginTransaction(); ObjectGuid::LowType guid = GetGUID().GetCounter(); switch (uState) { case ITEM_NEW: case ITEM_CHANGED: { uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(uState == ITEM_NEW ? CHAR_REP_ITEM_INSTANCE : CHAR_UPD_ITEM_INSTANCE); stmt->setUInt32( index, GetEntry()); stmt->setUInt32(++index, GetOwnerGUID().GetCounter()); stmt->setUInt32(++index, GetGuidValue(ITEM_FIELD_CREATOR).GetCounter()); stmt->setUInt32(++index, GetGuidValue(ITEM_FIELD_GIFTCREATOR).GetCounter()); stmt->setUInt32(++index, GetCount()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURATION)); std::ostringstream ssSpells; for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) ssSpells << GetSpellCharges(i) << ' '; stmt->setString(++index, ssSpells.str()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_FLAGS)); std::ostringstream ssEnchants; for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i) { ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' '; ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' '; ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' '; } stmt->setString(++index, ssEnchants.str()); stmt->setInt16 (++index, GetItemRandomPropertyId()); stmt->setUInt16(++index, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)); stmt->setString(++index, m_text); stmt->setUInt32(++index, guid); trans->Append(stmt); if ((uState == ITEM_CHANGED) && HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GIFT_OWNER); stmt->setUInt32(0, GetOwnerGUID().GetCounter()); stmt->setUInt32(1, guid); trans->Append(stmt); } break; } case ITEM_REMOVED: { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); stmt->setUInt32(0, guid); trans->Append(stmt); if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); stmt->setUInt32(0, guid); trans->Append(stmt); } if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); // Delete the items if this is a container if (!loot.isLooted()) sLootItemStorage->RemoveStoredLootForContainer(GetGUID().GetCounter()); delete this; return; } case ITEM_UNCHANGED: break; } SetState(ITEM_UNCHANGED); if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); }
int32 Item::AddEnchantment( EnchantEntry* Enchantment, uint32 Duration, bool Perm /* = false */, bool apply /* = true */, bool RemoveAtLogout /* = false */, uint32 Slot_, uint32 RandomSuffix ) { int32 Slot = Slot_; m_isDirty = true; /* if(Perm) { if(Slot_) { Slot=Slot_; } else { Slot = FindFreeEnchantSlot(Enchantment); } } else { if(Enchantment->EnchantGroups > 1) // replaceable temp enchants { Slot = 1; RemoveEnchantment(1); } else { Slot = FindFreeEnchantSlot(Enchantment);*/ /* Slot = Enchantment->type ? 3 : 0; //that's 's code for(uint32 Index = ITEM_FIELD_ENCHANTMENT_09; Index < ITEM_FIELD_ENCHANTMENT_32; Index += 3) { if(m_uint32Values[Index] == 0) break;; ++Slot; } //Slot = FindFreeEnchantSlot(Enchantment); // reach max of temp enchants if(Slot >= 11) return -1; */ /*} } */ // Create the enchantment struct. EnchantmentInstance Instance; Instance.ApplyTime = UNIXTIME; Instance.BonusApplied = false; Instance.Slot = Slot; Instance.Enchantment = Enchantment; Instance.Duration = Duration; Instance.RemoveAtLogout = RemoveAtLogout; Instance.RandomSuffix = RandomSuffix; // Set the enchantment in the item fields. uint32 EnchantBase = Slot * 3 + ITEM_FIELD_ENCHANTMENT; SetUInt32Value( EnchantBase, Enchantment->Id ); SetUInt32Value( EnchantBase + 1, (uint32)Instance.ApplyTime ); SetUInt32Value( EnchantBase + 2, 0 ); // charges // Add it to our map. Enchantments.insert(make_pair((uint32)Slot, Instance)); if( m_owner == NULL ) return Slot; // Add the removal event. if( Duration ) { sEventMgr.AddEvent( this, &Item::RemoveEnchantment, uint32(Slot), EVENT_REMOVE_ENCHANTMENT1 + Slot, Duration * 1000, 1, 0 ); } // No need to send the log packet, if the owner isn't in world (we're still loading) if( !m_owner->IsInWorld() ) return Slot; if( apply ) { WorldPacket EnchantLog( SMSG_ENCHANTMENTLOG, 25 ); EnchantLog << m_owner->GetGUID(); EnchantLog << m_owner->GetGUID(); EnchantLog << m_uint32Values[OBJECT_FIELD_ENTRY]; EnchantLog << Enchantment->Id; EnchantLog << uint8(0); m_owner->GetSession()->SendPacket( &EnchantLog ); if( m_owner->GetTradeTarget() ) { m_owner->SendTradeUpdate(); } /* Only apply the enchantment bonus if we're equipped */ uint8 slot = m_owner->GetItemInterface()->GetInventorySlotByGuid( GetGUID() ); if( slot >= EQUIPMENT_SLOT_START && slot < EQUIPMENT_SLOT_END ) ApplyEnchantmentBonus( Slot, APPLY ); } return Slot; }
bool Item::ItemContainerLoadLootFromDB() { // Loads the money and item loot associated with an openable item from the DB // Default. If there are no records for this item then it will be rolled for in Player::SendLoot() m_lootGenerated = false; ObjectGuid::LowType container_id = GetGUID().GetCounter(); // Save this for later use loot.containerID = container_id; // First, see if there was any money loot. This gets added directly to the container. PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEMCONTAINER_MONEY); stmt->setUInt32(0, container_id); PreparedQueryResult money_result = CharacterDatabase.Query(stmt); if (money_result) { Field* fields = money_result->Fetch(); loot.gold = fields[0].GetUInt32(); } // Next, load any items that were saved stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEMCONTAINER_ITEMS); stmt->setUInt32(0, container_id); PreparedQueryResult item_result = CharacterDatabase.Query(stmt); if (item_result) { // Get a LootTemplate for the container item. This is where // the saved loot was originally rolled from, we will copy conditions from it LootTemplate const* lt = LootTemplates_Item.GetLootFor(GetEntry()); if (lt) { do { // Create an empty LootItem LootItem loot_item = LootItem(); // Fill in the rest of the LootItem from the DB Field* fields = item_result->Fetch(); // item_id, itm_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix loot_item.itemid = fields[0].GetUInt32(); loot_item.count = fields[1].GetUInt32(); loot_item.follow_loot_rules = fields[2].GetBool(); loot_item.freeforall = fields[3].GetBool(); loot_item.is_blocked = fields[4].GetBool(); loot_item.is_counted = fields[5].GetBool(); loot_item.canSave = true; loot_item.is_underthreshold = fields[6].GetBool(); loot_item.needs_quest = fields[7].GetBool(); loot_item.randomPropertyId = fields[8].GetInt32(); loot_item.randomSuffix = fields[9].GetUInt32(); // Copy the extra loot conditions from the item in the loot template lt->CopyConditions(&loot_item); // If container item is in a bag, add that player as an allowed looter if (GetBagSlot()) loot_item.allowedGUIDs.insert(GetOwner()->GetGUID().GetCounter()); // Finally add the LootItem to the container loot.items.push_back(loot_item); // Increment unlooted count loot.unlootedCount++; } while (item_result->NextRow()); } } // Mark the item if it has loot so it won't be generated again on open m_lootGenerated = !loot.isLooted(); return m_lootGenerated; }
void GameObject::Use(Unit* user) { // by default spell caster is user Unit* spellCaster = user; uint32 spellId = 0; switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: //0 case GAMEOBJECT_TYPE_BUTTON: //1 //doors/buttons never really despawn, only reset to default state/flags UseDoorOrButton(); // activate script sWorld.ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this); return; case GAMEOBJECT_TYPE_QUESTGIVER: //2 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; player->PrepareQuestMenu( GetGUID() ); player->SendPreparedQuest( GetGUID() ); return; } //Sitting: Wooden bench, chairs enzz case GAMEOBJECT_TYPE_CHAIR: //7 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; // a chair may have n slots. we have to calculate their positions and teleport the player to the nearest one // check if the db is sane if(info->chair.slots > 0) { float lowestDist = DEFAULT_VISIBILITY_DISTANCE; float x_lowest = GetPositionX(); float y_lowest = GetPositionY(); // the object orientation + 1/2 pi // every slot will be on that straight line float orthogonalOrientation = GetOrientation()+M_PI*0.5f; // find nearest slot for(uint32 i=0; i<info->chair.slots; i++) { // the distance between this slot and the center of the go - imagine a 1D space float relativeDistance = (info->size*i)-(info->size*(info->chair.slots-1)/2.0f); float x_i = GetPositionX() + relativeDistance * cos(orthogonalOrientation); float y_i = GetPositionY() + relativeDistance * sin(orthogonalOrientation); // calculate the distance between the player and this slot float thisDistance = player->GetDistance2d(x_i, y_i); /* debug code. It will spawn a npc on each slot to visualize them. Creature* helper = player->SummonCreature(14496, x_i, y_i, GetPositionZ(), GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10000); std::ostringstream output; output << i << ": thisDist: " << thisDistance; helper->MonsterSay(output.str().c_str(), LANG_UNIVERSAL, 0); */ if(thisDistance <= lowestDist) { lowestDist = thisDistance; x_lowest = x_i; y_lowest = y_i; } } player->TeleportTo(GetMapId(), x_lowest, y_lowest, GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); } else { // fallback, will always work player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); } player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->chair.height); return; } //big gun, its a spell/aura case GAMEOBJECT_TYPE_GOOBER: //10 { GameObjectInfo const* info = GetGOInfo(); if(user->GetTypeId()==TYPEID_PLAYER) { Player* player = (Player*)user; // show page if(info->goober.pageId) { WorldPacket data(SMSG_GAMEOBJECT_PAGETEXT, 8); data << GetGUID(); player->GetSession()->SendPacket(&data); } // possible quest objective for active quests player->CastedCreatureOrGO(info->id, GetGUID(), 0); } // cast this spell later if provided spellId = info->goober.spellId; break; } case GAMEOBJECT_TYPE_CAMERA: //13 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if(info->camera.cinematicId) { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << info->camera.cinematicId; player->GetSession()->SendPacket(&data); } return; } //fishing bobber case GAMEOBJECT_TYPE_FISHINGNODE: //17 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if(player->GetGUID() != GetOwnerGUID()) return; switch(getLootState()) { case GO_READY: // ready for loot { // 1) skill must be >= base_zone_skill // 2) if skill == base_zone_skill => 5% chance // 3) chance is linear dependence from (base_zone_skill-skill) uint32 subzone = GetAreaId(); int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone ); if(!zone_skill) zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() ); //provide error, no fishable zone or area should be 0 if(!zone_skill) sLog.outErrorDb("Fishable areaId %u are not properly defined in `skill_fishing_base_level`.",subzone); int32 skill = player->GetSkillValue(SKILL_FISHING); int32 chance = skill - zone_skill + 5; int32 roll = irand(1,100); DEBUG_LOG("Fishing check (skill: %i zone min skill: %i chance %i roll: %i",skill,zone_skill,chance,roll); if(skill >= zone_skill && chance >= roll) { // prevent removing GO at spell cancel player->RemoveGameObject(this,false); SetOwnerGUID(player->GetGUID()); //fish catched player->UpdateFishingSkill(); GameObject* ok = LookupFishingHoleAround(DEFAULT_VISIBILITY_DISTANCE); if (ok) { player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE); SetLootState(GO_JUST_DEACTIVATED); } else player->SendLoot(GetGUID(),LOOT_FISHING); } else { // fish escaped, can be deleted now SetLootState(GO_JUST_DEACTIVATED); WorldPacket data(SMSG_FISH_ESCAPED, 0); player->GetSession()->SendPacket(&data); } break; } case GO_JUST_DEACTIVATED: // nothing to do, will be deleted at next update break; default: { SetLootState(GO_JUST_DEACTIVATED); WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); player->GetSession()->SendPacket(&data); break; } } if(player->m_currentSpells[CURRENT_CHANNELED_SPELL]) { player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); } return; } case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; Unit* caster = GetOwner(); GameObjectInfo const* info = GetGOInfo(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; // accept only use by player from same group for caster except caster itself if(((Player*)caster)==player || !((Player*)caster)->IsInSameRaidWith(player)) return; AddUniqueUse(player); // full amount unique participants including original summoner if(GetUniqueUseCount() < info->summoningRitual.reqParticipants) return; // in case summoning ritual caster is GO creator spellCaster = caster; if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) return; spellId = info->summoningRitual.spellId; // finish spell caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); // can be deleted now SetLootState(GO_JUST_DEACTIVATED); // go to end function to spell casting break; } case GAMEOBJECT_TYPE_SPELLCASTER: //22 { SetUInt32Value(GAMEOBJECT_FLAGS,2); GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(info->spellcaster.partyOnly) { Unit* caster = GetOwner(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; if(user->GetTypeId()!=TYPEID_PLAYER || !((Player*)user)->IsInSameRaidWith((Player*)caster)) return; } spellId = info->spellcaster.spellId; AddUse(); break; } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 { GameObjectInfo const* info = GetGOInfo(); if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection()); // accept only use by player from same group for caster except caster itself if(!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameGroupWith(player)) return; //required lvl checks! uint8 level = player->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; level = targetPlayer->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; spellId = 23598; break; } case GAMEOBJECT_TYPE_FLAGSTAND: // 24 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); if(!bg) return; // BG flag click // AB: // 15001 // 15002 // 15003 // 15004 // 15005 bg->EventPlayerClickedOnFlag(player, this); return; //we don;t need to delete flag ... it is despawned! } break; } case GAMEOBJECT_TYPE_FLAGDROP: // 26 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); if(!bg) return; // BG flag dropped // WS: // 179785 - Silverwing Flag // 179786 - Warsong Flag // EotS: // 184142 - Netherstorm Flag GameObjectInfo const* info = GetGOInfo(); if(info) { switch(info->id) { case 179785: // Silverwing Flag // check if it's correct bg if(bg->GetTypeID() == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 179786: // Warsong Flag if(bg->GetTypeID() == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 184142: // Netherstorm Flag if(bg->GetTypeID() == BATTLEGROUND_EY) bg->EventPlayerClickedOnFlag(player, this); break; } } //this cause to call return, all flags must be deleted here!! spellId = 0; Delete(); } break; } case GAMEOBJECT_TYPE_BARBER_CHAIR: //32 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; // fallback, will always work player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0); player->GetSession()->SendPacket(&data); player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight); return; } default: sLog.outDebug("Unknown Object Type %u", GetGoType()); break; } if(!spellId) return; SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) { sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType()); return; } Spell *spell = new Spell(spellCaster, spellInfo, false); // spell target is user of GO SpellCastTargets targets; targets.setUnitTarget( user ); spell->prepare(&targets); }
int main(const int argc, const char *argv[]) { if (argc != 4) { std::cout << "ERROR!!! Specify all arguments\n"; std::cout << "Usage:\n"; std::cout << "\tVITDatasetCreator DIR_WITH_ETALONS ALPHABET_FILE OUTPUT_DIR\n"; return 1; } const char *kInputDirectory = argv[1]; const char *kAlphabetFile = argv[2]; const char *kOutputDir = argv[3]; auto alphabet = ReadAlphabetFromFile(kAlphabetFile); for (auto elem : alphabet.GetMap()) { fs::path directory_path = fs::path(kOutputDir) / fs::path(elem.second.name); if (!fs::is_directory(fs::status(directory_path)) && !fs::create_directory(directory_path)) { std::cout << "Can't create directory: " << directory_path << std::endl; return 1; } } std::string process_dir = kInputDirectory; auto img_paths = DirFiles(process_dir, ".jpg"); std::cout << "There are " << img_paths.size() << " images\n"; int processed = 0; for (auto impath : img_paths) { if (processed % 100 == 0) { std::cout << "Processed " << processed << " files of " << img_paths.size() << std::endl; } auto etalon_path = fs::path(impath).replace_extension("txt"); DataInfo dinfo; try { dinfo = ReadEtalonsFromFile(etalon_path.string()); if (0 == dinfo.pinfo.size()) continue; } catch(std::exception &e) { std::cout << "Skip " << impath << ", reason: " << e.what() << std::endl; continue; } //Export file to filesystem cv::Mat original_image = cv::imread(impath.string(), CV_LOAD_IMAGE_GRAYSCALE); for (auto p : dinfo.pinfo) { //std::cout << p.to_string() << std::endl; for (int i = 0; i < p.symbols.size(); i++) { std::string dir_name = alphabet.GetElemName(p.symbols[i].text); if (!dir_name.length()) { std::cout << "Unknown symbol: " << p.symbols[i].text << std::endl; continue; } fs::path output_dir = fs::path(kOutputDir) / fs::path(dir_name); auto save_image = [&output_dir](const cv::Mat& image) { std::string image_name = GetGUID() + ".bmp"; cv::Mat output_image; cv::resize(image, output_image, cv::Size(10, 12), 0, 0, CV_INTER_LANCZOS4); cv::imwrite((output_dir / fs::path(image_name)).c_str(), output_image); }; auto equalize = [](const cv::Mat& image) { cv::Mat result; cv::equalizeHist(image, result); return result; }; auto get_symbol_by_roi = [&original_image](cv::Rect r, int left_pad, int right_pad, int top_pad, int bottom_pad) { cv::Rect new_roi = r; int width = r.width; int height = r.height; new_roi.x = std::max(0, new_roi.x - width * left_pad / 100); new_roi.y = std::max(0, new_roi.y - height * top_pad / 100); int new_x2 = std::min(original_image.cols, r.x + width * (1 + right_pad / 100)); int new_y2 = std::min(original_image.rows, r.y + height * (1 + bottom_pad / 100)); new_roi.width = new_x2 - new_roi.x; new_roi.height = new_y2 - new_roi.y; return original_image(new_roi); }; cv::Rect symbol_roi = p.symbols[i].rect; //todo: rewrite using cycles save_image(equalize(get_symbol_by_roi(symbol_roi, 0, 0, 0, 0))); save_image(equalize(get_symbol_by_roi(symbol_roi, 20, 0, 0, 0))); save_image(equalize(get_symbol_by_roi(symbol_roi, 0, 20, 0, 0))); save_image(equalize(get_symbol_by_roi(symbol_roi, 0, 0, 20, 0))); save_image(equalize(get_symbol_by_roi(symbol_roi, 0, 0, 0, 20))); save_image(equalize(get_symbol_by_roi(symbol_roi, 20, 20, 20, 20))); save_image(get_symbol_by_roi(symbol_roi, 0, 0, 0, 0)); save_image(get_symbol_by_roi(symbol_roi, 20, 0, 0, 0)); save_image(get_symbol_by_roi(symbol_roi, 0, 20, 0, 0)); save_image(get_symbol_by_roi(symbol_roi, 0, 0, 20, 0)); save_image(get_symbol_by_roi(symbol_roi, 0, 0, 0, 20)); save_image(get_symbol_by_roi(symbol_roi, 20, 20, 20, 20)); } } } exit(1); }
//! Get the GUID of the camera [return string] std::string PS3::GetGUIDStr() const { return GUID2String( GetGUID() ); }
void TempSummon::InitStats(uint32 duration) { ASSERT(!isPet()); m_timer = duration; m_lifetime = duration; if (m_type == TEMPSUMMON_MANUAL_DESPAWN) m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; Unit* owner = GetSummoner(); if (owner && isTrigger() && m_spells[0]) { setFaction(owner->getFaction()); SetLevel(owner->getLevel()); if (owner->GetTypeId() == TYPEID_PLAYER) m_ControlledByPlayer = true; } if (!m_Properties) return; // Fix Force of Nature treants stats if (owner && owner->getClass() == CLASS_DRUID && owner->HasSpell(106737)) { float damage = 0.0f; switch (GetEntry()) { case ENTRY_TREANT_RESTO: case ENTRY_TREANT_BALANCE: SetMaxHealth(owner->CountPctFromMaxHealth(40)); break; case ENTRY_TREANT_GUARDIAN: SetMaxHealth(owner->CountPctFromMaxHealth(40)); // (Attack power / 14 * 2 * 0.75) * 0.2f damage = ((owner->GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f) * 2.0f * 0.75f) * 0.2f; SetStatFloatValue(UNIT_FIELD_MINDAMAGE, damage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, damage); case ENTRY_TREANT_FERAL: SetMaxHealth(owner->CountPctFromMaxHealth(40)); // Attack power / 14 * 2 * 0.75 damage = (owner->GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f) * 2.0f * 0.75f; SetStatFloatValue(UNIT_FIELD_MINDAMAGE, damage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, damage); default: break; } } if (owner) { if (uint32 slot = m_Properties->Slot) { if (owner->m_SummonSlot[slot] && owner->m_SummonSlot[slot] != GetGUID()) { Creature* oldSummon = GetMap()->GetCreature(owner->m_SummonSlot[slot]); if (oldSummon && oldSummon->IsSummon()) oldSummon->ToTempSummon()->UnSummon(); } owner->m_SummonSlot[slot] = GetGUID(); } } if (m_Properties->Faction) setFaction(m_Properties->Faction); else if (IsVehicle() && owner) // properties should be vehicle setFaction(owner->getFaction()); }
/** * Parse header extension object. Takes a pointer to a newly allocated * header extension structure, a pointer to the data buffer and the * length of the data buffer as its parameters. Subobject contents are * not parsed, but they are added as a linked list to the header object. */ static int asf_parse_headerext(asf_object_headerext_t *header, uint8_t *buf, uint64_t buflen) { int64_t datalen; uint8_t *data; if (header->size < 46) { /* invalide size for headerext */ return ASF_ERROR_INVALID_OBJECT_SIZE; } /* Read reserved and datalen fields from the buffer */ GetGUID(buf + 24, &header->reserved1); header->reserved2 = GetWLE(buf + 40); header->datalen = GetDWLE(buf + 42); if (header->datalen != header->size - 46) { /* invalid header extension data length value */ return ASF_ERROR_INVALID_LENGTH; } header->data = buf + 46; debug_printf("parsing header extension subobjects"); datalen = header->datalen; data = header->data; while (datalen > 0) { asfint_object_t *current; if (datalen < 24) { /* not enough data for reading a new object */ break; } /* Allocate a new subobject */ current = malloc(sizeof(asfint_object_t)); if (!current) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object(current, data); if (current->size > datalen || current->size < 24) { /* invalid object size */ break; } current->datalen = current->size - 24; current->data = data + 24; /* add to the list of subobjects */ if (!header->first) { header->first = current; header->last = current; } else { header->last->next = current; header->last = current; } data += current->size; datalen -= current->size; } if (datalen != 0) { /* not enough data for reading the whole object */ return ASF_ERROR_INVALID_LENGTH; } debug_printf("header extension subobjects parsed successfully"); return header->size; }
void Pet::Update(uint32 diff) { if (m_removed) // pet already removed, just wait in remove queue, no updates return; if (m_loading) return; switch (m_deathState) { case CORPSE: { if (getPetType() != HUNTER_PET || m_corpseRemoveTime <= time(NULL)) { Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER! return; } break; } case ALIVE: { // unsummon pet that lost owner Player* owner = GetOwner(); if (!owner || (!IsWithinDistInMap(owner, GetMap()->GetVisibilityRange()) && !isPossessed()) || (isControlled() && !owner->GetPetGUID())) //if (!owner || (!IsWithinDistInMap(owner, GetMap()->GetVisibilityDistance()) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID())) { Remove(PET_SAVE_NOT_IN_SLOT, true); return; } if (isControlled()) { if (owner->GetPetGUID() != GetGUID()) { sLog->outError("Pet %u is not pet of owner %s, removed", GetEntry(), m_owner->GetName()); Remove(getPetType() == HUNTER_PET?PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT); return; } } if (m_duration > 0) { if (uint32(m_duration) > diff) m_duration -= diff; else { Remove(getPetType() != SUMMON_PET ? PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT); return; } } //regenerate focus for hunter pets or energy for deathknight's ghoul if (m_regenTimer) { if (m_regenTimer > diff) m_regenTimer -= diff; else { switch (getPowerType()) { case POWER_FOCUS: Regenerate(POWER_FOCUS); m_regenTimer += PET_FOCUS_REGEN_INTERVAL - diff; if (!m_regenTimer) ++m_regenTimer; break; // in creature::update //case POWER_ENERGY: // Regenerate(POWER_ENERGY); // m_regenTimer += CREATURE_REGEN_INTERVAL - diff; // if (!m_regenTimer) ++m_regenTimer; // break; default: m_regenTimer = 0; break; } } } if (getPetType() != HUNTER_PET) break; if (m_happinessTimer <= diff) { LoseHappiness(); m_happinessTimer = 7500; } else m_happinessTimer -= diff; break; } default: break; } Creature::Update(diff); }
void HandleDummy(SpellEffIndex /*effIndex*/) { auto target = GetHitUnit(); if (!target || target->GetTypeId() != TYPEID_PLAYER) return; auto player = GetCaster()->ToPlayer(); if (player->GetQuestStatus(29951) == QUEST_STATUS_INCOMPLETE) { if (!player->HasAura(106284)) { player->MonsterTextEmote("Mudmug's vial will slowly spill water while you are moving. Plan your path carefully!", player->GetGUID() , true); player->CastSpell(player, 106284, true); } else player->CastSpell(player, 106294, true); if (player->GetPower(POWER_ALTERNATE_POWER) == 100) { player->AddItem(76356, 1); player->RemoveAurasDueToSpell(106284); } } }
void GameObject::Update(uint32 /*p_time*/) { if (IS_MO_TRANSPORT(GetGUID())) { //((Transport*)this)->Update(p_time); return; } switch (m_lootState) { case GO_NOT_READY: { switch(GetGoType()) { case GAMEOBJECT_TYPE_TRAP: { // Arming Time for GAMEOBJECT_TYPE_TRAP (6) Unit* owner = GetOwner(); if (owner && ((Player*)owner)->isInCombat()) m_cooldownTime = time(NULL) + GetGOInfo()->trap.startDelay; m_lootState = GO_READY; break; } case GAMEOBJECT_TYPE_FISHINGNODE: { // fishing code (bobber ready) if( time(NULL) > m_respawnTime - FISHING_BOBBER_READY_TIME ) { // splash bobber (bobber ready now) Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { SetGoState(0); SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); UpdateData udata; WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster)); udata.BuildPacket(&packet); ((Player*)caster)->GetSession()->SendPacket(&packet); WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4); data << GetGUID(); data << (uint32)(0); ((Player*)caster)->SendMessageToSet(&data,true); } m_lootState = GO_READY; // can be successfully open with some chance } return; } default: m_lootState = GO_READY; // for other GOis same switched without delay to GO_READY break; } // NO BREAK for switch (m_lootState) } case GO_READY: { if (m_respawnTime > 0) // timer on { if (m_respawnTime <= time(NULL)) // timer expired { m_respawnTime = 0; m_SkillupList.clear(); m_usetimes = 0; switch (GetGoType()) { case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now { Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) { caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(false); } WorldPacket data(SMSG_FISH_NOT_HOOKED,0); ((Player*)caster)->GetSession()->SendPacket(&data); } // can be delete m_lootState = GO_JUST_DEACTIVATED; return; } case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) if( !GetGoState() ) SwitchDoorOrButton(false); //flags in AB are type_button and we need to add them here so no break! default: if(!m_spawnedByDefault) // despawn timer { // can be despawned or destroyed SetLootState(GO_JUST_DEACTIVATED); return; } // respawn timer GetMap()->Add(this); break; } } } // traps can have time and can not have GameObjectInfo const* goInfo = GetGOInfo(); if(goInfo->type == GAMEOBJECT_TYPE_TRAP) { // traps Unit* owner = GetOwner(); Unit* ok = NULL; // pointer to appropriate target if found any if(m_cooldownTime >= time(NULL)) return; bool IsBattleGroundTrap = false; //FIXME: this is activation radius (in different casting radius that must be selected from spell data) //TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state float radius = goInfo->trap.radius; if(!radius) { if(goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call) return; else { if(m_respawnTime > 0) break; radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3 IsBattleGroundTrap = true; } } bool NeedDespawn = (goInfo->trap.charges != 0); CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; // Note: this hack with search required until GO casting not implemented // search unfriendly creature if(owner && NeedDespawn) // hunter trap { MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius); MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(ok, u_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *GetMap()); // or unfriendly player/pet if(!ok) { TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *GetMap()); } } else // environmental trap { // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support // affect only players Player* p_ok = NULL; MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius); MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> checker(p_ok, p_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *GetMap()); ok = p_ok; } if (ok) { Unit *caster = owner ? owner : ok; caster->CastSpell(ok, goInfo->trap.spellId, true); m_cooldownTime = time(NULL) + 4; // 4 seconds if(NeedDespawn) SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER) { //BattleGround gameobjects case if(((Player*)ok)->InBattleGround()) if(BattleGround *bg = ((Player*)ok)->GetBattleGround()) bg->HandleTriggerBuff(GetGUID()); } } } if (m_charges && m_usetimes >= m_charges) SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed break; } case GO_ACTIVATED: { switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: if(GetAutoCloseTime() && (m_cooldownTime < time(NULL))) { SwitchDoorOrButton(false); SetLootState(GO_JUST_DEACTIVATED); } break; } break; } case GO_JUST_DEACTIVATED: { //if Gameobject should cast spell, then this, but some GOs (type = 10) should be destroyed if (GetGoType() == GAMEOBJECT_TYPE_GOOBER) { uint32 spellId = GetGOInfo()->goober.spellId; if(spellId) { std::set<uint32>::iterator it = m_unique_users.begin(); std::set<uint32>::iterator end = m_unique_users.end(); for (; it != end; it++) { Unit* owner = Unit::GetUnit(*this, uint64(*it)); if (owner) owner->CastSpell(owner, spellId, false); } m_unique_users.clear(); m_usetimes = 0; } //any return here in case battleground traps } if(GetOwnerGUID()) { m_respawnTime = 0; Delete(); return; } //burning flags in some battlegrounds, if you find better condition, just add it if (GetGoAnimProgress() > 0) { SendObjectDeSpawnAnim(GetGUID()); //reset flags SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); } loot.clear(); SetLootState(GO_READY); if(!m_respawnDelayTime) return; if(!m_spawnedByDefault) { m_respawnTime = 0; return; } m_respawnTime = time(NULL) + m_respawnDelayTime; // if option not set then object will be saved at grid unload if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) SaveRespawnTime(); ObjectAccessor::UpdateObjectVisibility(this); break; } } }
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; } } uint32 phase = PHASEMASK_NORMAL; uint32 team = 0; if (summoner) { phase = summoner->GetPhaseMask(); if (summoner->GetTypeId() == TYPEID_PLAYER) team = summoner->ToPlayer()->GetTeam(); } TempSummon* summon = NULL; 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, phase, entry, vehId, team, x, y, z, o)) { delete summon; return NULL; } 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; }
void Item::ItemContainerSaveLootToDB() { // Saves the money and item loot associated with an openable item to the DB if (loot.isLooted()) // no money and no loot return; ObjectGuid::LowType container_id = GetGUID().GetCounter(); SQLTransaction trans = CharacterDatabase.BeginTransaction(); loot.containerID = container_id; // Save this for when a LootItem is removed // Save money if (loot.gold > 0) { PreparedStatement* stmt_money = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_MONEY); stmt_money->setUInt32(0, container_id); trans->Append(stmt_money); stmt_money = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEMCONTAINER_MONEY); stmt_money->setUInt32(0, container_id); stmt_money->setUInt32(1, loot.gold); trans->Append(stmt_money); } // Save items if (!loot.isLooted()) { PreparedStatement* stmt_items = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEMS); stmt_items->setUInt32(0, container_id); trans->Append(stmt_items); // Now insert the items for (LootItemList::const_iterator _li = loot.items.begin(); _li != loot.items.end(); ++_li) { // When an item is looted, it doesn't get removed from the items collection // but we don't want to resave it. if (!_li->canSave) continue; // Conditions are not checked when loot is generated, it is checked when loot is sent to a player. // For items that are lootable, loot is saved to the DB immediately, that means that loot can be // saved to the DB that the player never should have gotten. This check prevents that, so that only // items that the player should get in loot are in the DB. // IE: Horde items are not saved to the DB for Ally players. Player* const guid = GetOwner(); if (!_li->AllowedForPlayer(guid)) continue; stmt_items = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEMCONTAINER_ITEMS); // container_id, item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix stmt_items->setUInt32(0, container_id); stmt_items->setUInt32(1, _li->itemid); stmt_items->setUInt32(2, _li->count); stmt_items->setBool(3, _li->follow_loot_rules); stmt_items->setBool(4, _li->freeforall); stmt_items->setBool(5, _li->is_blocked); stmt_items->setBool(6, _li->is_counted); stmt_items->setBool(7, _li->is_underthreshold); stmt_items->setBool(8, _li->needs_quest); stmt_items->setInt32(9, _li->randomPropertyId); stmt_items->setUInt32(10, _li->randomSuffix); trans->Append(stmt_items); } } CharacterDatabase.CommitTransaction(trans); }
Creature::Creature(uint64 guid) { proto=0; m_valuesCount = UNIT_END; m_objectTypeId = TYPEID_UNIT; m_uint32Values = _fields; memset(m_uint32Values, 0,(UNIT_END)*sizeof(uint32)); m_updateMask.SetCount(UNIT_END); SetUInt32Value( OBJECT_FIELD_TYPE,TYPE_UNIT|TYPE_OBJECT); SetUInt64Value( OBJECT_FIELD_GUID,guid); m_wowGuid.Init(GetGUID()); m_quests = NULL; proto = NULL; spawnid=0; creature_info=NULL; m_H_regenTimer=0; m_P_regenTimer=0; m_useAI = true; mTaxiNode = 0; Tagged = false; TaggerGuid = 0; Skinned = false; m_enslaveCount = 0; m_enslaveSpell = 0; for(uint32 x=0;x<7;x++) { FlatResistanceMod[x]=0; BaseResistanceModPct[x]=0; ResistanceModPct[x]=0; ModDamageDone[x]=0; ModDamageDonePct[x]=1.0; } for(uint32 x=0;x<5;x++) { TotalStatModPct[x]=0; StatModPct[x]=0; FlatStatMod[x]=0; } totemOwner = NULL; totemSlot = -1; m_PickPocketed = false; m_SellItems = NULL; _myScriptClass = NULL; m_TaxiNode = 0; myFamily = 0; loot.gold = 0; haslinkupevent = false; original_emotestate = 0; mTrainer = 0; m_spawn = 0; spawnid = 0; auctionHouse = 0; has_waypoint_text = has_combat_text = false; SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER,1); SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER,1); m_custom_waypoint_map = 0; m_escorter = 0; m_limbostate = false; m_corpseEvent=false; m_respawnCell=NULL; m_walkSpeed = 2.5f; m_runSpeed = MONSTER_NORMAL_RUN_SPEED; m_base_runSpeed = m_runSpeed; m_base_walkSpeed = m_walkSpeed; m_noRespawn=false; m_canRegenerateHP = true; m_transportGuid = 0; m_transportPosition = NULL; BaseAttackType = SCHOOL_NORMAL; m_lootMethod = -1; }
//called instead of parametrized constructor void Item::Init( uint32 high, uint32 low ) { SetUInt32Value( OBJECT_FIELD_GUID, low ); SetUInt32Value( OBJECT_FIELD_GUID + 1, high ); m_wowGuid.Init( GetGUID() ); }
void Item::ApplyEnchantmentBonus( uint32 Slot, bool Apply ) { if( m_owner == NULL ) return; EnchantmentMap::iterator itr = Enchantments.find( Slot ); if( itr == Enchantments.end() ) return; EnchantEntry* Entry = itr->second.Enchantment; uint32 RandomSuffixAmount = itr->second.RandomSuffix; if( itr->second.Dummy ) return; if( itr->second.BonusApplied == Apply ) return; itr->second.BonusApplied = Apply; // Apply the visual on the player. uint32 ItemSlot = m_owner->GetItemInterface()->GetInventorySlotByGuid( GetGUID() ); if(ItemSlot < EQUIPMENT_SLOT_END && Slot < 1) { uint32 VisibleBase = PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + ItemSlot * PLAYER_VISIBLE_ITEM_LENGTH; m_owner->SetUInt16Value( VisibleBase, Slot, Apply ? Entry->Id : 0 ); } if( Apply ) { // Send the enchantment time update packet. SendEnchantTimeUpdate( itr->second.Slot, itr->second.Duration ); } // Another one of those for loop that where not indented properly god knows what will break // but i made it actually affect the code below it for( uint32 c = 0; c < 3; c++ ) { if( Entry->type[c] ) { // Depending on the enchantment type, take the appropriate course of action. switch( Entry->type[c] ) { case 1: // Trigger spell on melee attack. { if( Apply && Entry->spell[c] != 0 ) { // Create a proc trigger spell ProcTriggerSpell TS; memset(&TS, 0, sizeof(ProcTriggerSpell)); TS.caster = m_owner->GetGUID(); TS.procFlags = PROC_ON_MELEE_ATTACK; TS.origId = 0; TS.procflags2 = 0; TS.SpellClassMask[0] = 0; TS.SpellClassMask[1] = 0; TS.SpellClassMask[2] = 0; TS.ProcType = 0; TS.LastTrigger = 0; TS.procValue = 0; TS.procCharges = 0; TS.procChance = 10; if(ItemSlot == EQUIPMENT_SLOT_MAINHAND) TS.weapon_damage_type = 1; // Proc only on main hand attacks else if(ItemSlot == EQUIPMENT_SLOT_OFFHAND) TS.weapon_damage_type = 2; // Proc only on off hand attacks else TS.weapon_damage_type = 0; // Doesn't depend on weapon /* This needs to be modified based on the attack speed of the weapon. * Secondly, need to assign some static chance for instant attacks (ss, * gouge, etc.) */ if( GetProto()->Class == ITEM_CLASS_WEAPON ) { if( !Entry->min[c] ) { float speed = (float)GetProto()->Delay; /////// procChance calc /////// float ppm = 0; SpellEntry* sp = dbcSpell.LookupEntry( Entry->spell[c] ); if( sp ) { switch( sp->NameHash ) { case SPELL_HASH_FROSTBRAND_ATTACK: ppm = 9; break; } } if( ppm != 0 ) { float pcount = 60/ppm; float chance = (speed/10) / pcount; TS.procChance = (uint32)chance; } else TS.procChance = (uint32)( speed / 600.0f ); /////////////////////////////// } else TS.procChance = Entry->min[c]; } sLog.Debug( "Enchant", "Setting procChance to %u%%.", TS.procChance ); TS.deleted = false; TS.spellId = Entry->spell[c]; m_owner->m_procSpells.push_back( TS ); } else { // Remove the proctriggerspell uint32 SpellId; list< struct ProcTriggerSpell >::iterator itr/*, itr2*/; for( itr = m_owner->m_procSpells.begin(); itr != m_owner->m_procSpells.end(); ) { SpellId = itr->spellId; /*itr2 = itr;*/ /*++itr;*/ if( SpellId == Entry->spell[c] ) { //m_owner->m_procSpells.erase(itr2); itr->deleted = true; } ++itr; } } }break; case 2: // Mod damage done. { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); if( Apply ) m_owner->DamageDonePosMod[0] += val; else m_owner->DamageDonePosMod[0] -= val; m_owner->UpdateStats(); }break; case 3: // Cast spell (usually means apply aura) { if( Apply ) { SpellCastTargets targets( m_owner->GetGUID() ); SpellEntry* sp; if( Entry->spell[c] != 0 ) { sp = dbcSpell.LookupEntry( Entry->spell[c] ); if( sp == NULL ) continue; Spell* spell = NULLSPELL; //Never found out why, //but this Blade of Life's Inevitability spell must be casted by the item, not owner. if( m_itemProto->ItemId != 34349 ) spell = (new Spell( m_owner, sp, true, NULLAURA )); else spell = (new Spell( TO_ITEM(this), sp, true, NULLAURA )); spell->i_caster = TO_ITEM(this); spell->prepare( &targets ); } } else { if( Entry->spell[c] != 0 ) m_owner->RemoveAura( Entry->spell[c] ); } }break; case 4: // Modify physical resistance { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); if( Apply ) m_owner->FlatResistanceModifierPos[Entry->spell[c]] += val; else m_owner->FlatResistanceModifierPos[Entry->spell[c]] -= val; m_owner->CalcResistance( Entry->spell[c] ); }break; case 5: //Modify rating ...order is PLAYER_FIELD_COMBAT_RATING_1 and above { //spellid is enum ITEM_STAT_TYPE //min=max is amount int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); m_owner->ModifyBonuses( Entry->spell[c], Apply ? val : -val ); }break; case 6: // Rockbiter weapon (increase damage per second... how the hell do you calc that) { if( Apply ) { //if i'm not wrong then we should apply DMPS formula for this. This will have somewhat a larger value 28->34 int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); //int32 value = GetProto()->Delay * val / 1000; m_owner->DamageDonePosMod[0] += val; } else { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); //int32 value =- (int32)(GetProto()->Delay * val / 1000 ); m_owner->DamageDonePosMod[0] += val; } m_owner->UpdateStats(); }break; case 7: { if( Apply ) { for( uint32 i = 0; i < 3; ++i ) OnUseSpells[ i ] = Entry->spell[ i ]; } else { for( uint32 i = 0; i < 3; ++i ) OnUseSpells[ i ] = 0; } }break; case 8:{}break; default: { sLog.Debug( "Enchant","Unknown enchantment type: %u (%u)", Entry->type[c], Entry->Id ); }break; } } } }
void Item::ApplyEnchantmentBonus( uint32 Slot, bool Apply ) { if( m_owner == NULL ) return; EnchantmentMap::iterator itr = Enchantments.find( Slot ); if( itr == Enchantments.end() ) return; EnchantEntry* Entry = itr->second.Enchantment; uint32 RandomSuffixAmount = itr->second.RandomSuffix; if( itr->second.BonusApplied == Apply ) return; itr->second.BonusApplied = Apply; if( Apply ) { // Send the enchantment time update packet. SendEnchantTimeUpdate( itr->second.Slot, itr->second.Duration ); } // Apply the visual on the player. uint32 ItemSlot = m_owner->GetItemInterface()->GetInventorySlotByGuid( GetGUID() ) * 16; uint32 VisibleBase = PLAYER_VISIBLE_ITEM_1_0 + ItemSlot; m_owner->SetUInt32Value( VisibleBase + 1 + Slot, Apply ? Entry->Id : 0 ); // Another one of those for loop that where not indented properly god knows what will break // but i made it actually affect the code below it for( uint32 c = 0; c < 3; c++ ) { if( Entry->type[c] ) { // Depending on the enchantment type, take the appropriate course of action. switch( Entry->type[c] ) { case 1: // Trigger spell on melee attack. { if( Apply && Entry->spell[c] != 0 ) { // Create a proc trigger spell ProcTriggerSpell TS; TS.caster = m_owner->GetGUID(); TS.origId = 0; TS.procFlags = PROC_ON_MELEE_ATTACK; TS.procCharges = 0; /* This needs to be modified based on the attack speed of the weapon. * Secondly, need to assign some static chance for instant attacks (ss, * gouge, etc.) */ if( !Entry->min[c] && GetProto()->Class == 2 ) { float speed = (float)GetProto()->Delay; /////// procChance calc /////// float ppm = 0; SpellEntry* sp = dbcSpell.LookupEntry( Entry->spell[c] ); if( sp ) { switch( sp->NameHash ) { case SPELL_HASH_FROSTBRAND_ATTACK: ppm = 9; break; } } if( ppm != 0 ) { float pcount = 60/ppm; float chance = (speed/10) / pcount; TS.procChance = (uint32)chance; } else TS.procChance = (uint32)( speed / 600.0f ); /////////////////////////////// } else TS.procChance = Entry->min[c]; Log.Debug( "Enchant", "Setting procChance to %u%%.", TS.procChance ); TS.deleted = false; TS.spellId = Entry->spell[c]; TS.groupRelation = 0; TS.ProcType = 0; TS.LastTrigger = 0; m_owner->m_procSpells.push_back( TS ); } else { // Remove the proctriggerspell uint32 SpellId; list< struct ProcTriggerSpell >::iterator itr/*, itr2*/; for( itr = m_owner->m_procSpells.begin(); itr != m_owner->m_procSpells.end(); ) { SpellId = itr->spellId; /*itr2 = itr++;*/ if( SpellId == Entry->spell[c] ) { //m_owner->m_procSpells.erase(itr2); itr->deleted = true; } itr++; } } }break; case 2: // Mod damage done. { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); if( Apply ) m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, val ); else m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, -val ); m_owner->CalcDamage(); }break; case 3: // Cast spell (usually means apply aura) { if( Apply ) { SpellCastTargets targets( m_owner->GetGUID() ); SpellEntry* sp; Spell* spell; if( Entry->spell[c] != 0 ) { sp = dbcSpell.LookupEntry( Entry->spell[c] ); if( sp == NULL ) continue; spell = SpellPool.PooledNew(); spell->Init( m_owner, sp, true, 0 ); spell->i_caster = this; spell->prepare( &targets ); } } else { if( Entry->spell[c] != 0 ) m_owner->RemoveAura( Entry->spell[c] ); } }break; case 4: // Modify physical resistance { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); if( Apply ) { m_owner->FlatResistanceModifierPos[Entry->spell[c]] += val; } else { m_owner->FlatResistanceModifierPos[Entry->spell[c]] -= val; } m_owner->CalcResistance( Entry->spell[c] ); }break; case 5: //Modify rating ...order is PLAYER_FIELD_COMBAT_RATING_1 and above { //spellid is enum ITEM_STAT_TYPE //min=max is amount int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); m_owner->ModifyBonuses( Entry->spell[c], val, Apply ); m_owner->UpdateStats(); }break; case 6: // Rockbiter weapon (increase damage per second... how the hell do you calc that) { if( Apply ) { //m_owner->ModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, Entry->min[c]); //if i'm not wrong then we should apply DMPS formula for this. This will have somewhat a larger value 28->34 int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); int32 value = GetProto()->Delay * val / 1000; m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, value ); } else { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); int32 value =- (int32)(GetProto()->Delay * val / 1000 ); m_owner->ModUnsigned32Value( PLAYER_FIELD_MOD_DAMAGE_DONE_POS, value ); } m_owner->CalcDamage(); }break; default: { sLog.outError( "Unknown enchantment type: %u (%u)", Entry->type[c], Entry->Id ); }break; } } } }
void Creature::_LoadGoods() { itemcount = 0; std::stringstream query; query << "SELECT * FROM vendors WHERE vendorGuid=" << GetGUIDLow(); QueryResult *result = sDatabase.Query( query.str().c_str() ); if(!result) { std::stringstream query7; query7 << "SELECT * FROM vendors WHERE vendorGuid=" << GetNameID(); result = sDatabase.Query( query7.str().c_str() ); if (result) Log::getSingleton( ).outError( "Vendor %u has items.", GetNameID() ); } if(!result) { std::stringstream query2; query2 << "SELECT * FROM vendors WHERE vendorGuid=" << uint64(GetGUIDLow()+1); result = sDatabase.Query( query2.str().c_str() ); } if(!result) { std::stringstream query5; query5 << "SELECT * FROM vendors WHERE vendorGuid=" << uint64(GetGUIDLow()-10); result = sDatabase.Query( query5.str().c_str() ); } if(!result) { std::stringstream query3; query3 << "SELECT * FROM vendors WHERE vendorGuid=" << uint64(GetGUID()); result = sDatabase.Query( query3.str().c_str() ); } if(!result) { std::stringstream query4; query4 << "SELECT * FROM vendors WHERE vendorGuid=" << uint64(GetGUID()+1); result = sDatabase.Query( query4.str().c_str() ); } if(!result) { std::stringstream query6; query6 << "SELECT * FROM vendors WHERE vendorGuid=" << uint64(GetGUID()-10); result = sDatabase.Query( query6.str().c_str() ); } if(result) { do { Field *fields = result->Fetch(); if (getItemCount() >= MAX_CREATURE_ITEMS) { Log::getSingleton( ).outError( "Vendor %u has too many items (%u >= %i). Check the DB!", GetNameID(), getItemCount(), MAX_CREATURE_ITEMS ); break; } setItemId(getItemCount() , fields[1].GetUInt32()); setItemAmount(getItemCount() , fields[2].GetUInt32()); increaseItemCount(); } while( result->NextRow() ); delete result; } }
void Item::DeleteFromInventoryDB(SQLTransaction& trans) { DeleteFromInventoryDB(trans, GetGUID().GetCounter()); }
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->Control) { 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->Title) { 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; } } 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(map->GenerateLowGuid<HighGuid::Creature>(), map, entry, x, y, z, o, nullptr, vehId)) { delete summon; return nullptr; } PhasingHandler::InheritPhaseShift(summon, summoner ? static_cast<WorldObject*>(summoner) : static_cast<WorldObject*>(this)); 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 nullptr; } _staticPassengers.insert(summon); summon->InitSummon(); summon->SetTempSummonType(summonType); return summon; }
void DynamicObject::Delete() { SendObjectDeSpawnAnim(GetGUID()); AddObjectToRemoveList(); }
/** * Takes an initialized asf_file_t structure file as a parameter. Allocates * a new asf_object_index_t in file->index and uses the file->iostream to * read all its compulsory fields into it. Notice that the actual data is * not read in any way, because we need to be able to work with non-seekable * streams as well. */ int asf_parse_index(asf_file_t *file) { asf_object_index_t *index; asf_iostream_t *iostream; uint8_t idata[56]; uint64_t entry_data_size; uint8_t *entry_data = NULL; int tmp, i; file->index = NULL; iostream = &file->iostream; /* read the raw data of an index header */ tmp = asf_byteio_read(iostream, idata, 56); if (tmp < 0) { printf("Could not read index header\n"); return tmp; } /* allocate the index object */ index = malloc(sizeof(asf_object_index_t)); if (!index) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object((asfint_object_t *) index, idata); if (index->type != GUID_INDEX) { tmp = index->size; free(index); /* The guid type was wrong, just return the bytes to skip */ return tmp; } if (index->size < 56) { /* invalid size for index object */ free(index); return ASF_ERROR_INVALID_OBJECT_SIZE; } GetGUID(idata + 24, &index->file_id); index->entry_time_interval = GetQWLE(idata + 40); index->max_packet_count = GetDWLE(idata + 48); index->entry_count = GetDWLE(idata + 52); printf("INDEX\n"); printf("Total Index Entries %d\n",index->entry_count); printf("Index Size in bytes %Ld\n",index->size); printf("Index Max Packet Count %d\n",index->max_packet_count); printf("Index Entry Time Interval %Ld\n",index->entry_time_interval); if (index->entry_count == 0) { printf("Index has no entries\n"); file->index = index; return index->size; } if (index->entry_count * 6 + 56 > index->size) { free(index); return ASF_ERROR_INVALID_LENGTH; } entry_data_size = index->entry_count * 6; entry_data = malloc(entry_data_size * sizeof(uint8_t)); if (!entry_data) { free(index); return ASF_ERROR_OUTOFMEM; } tmp = asf_byteio_read(iostream, entry_data, entry_data_size); if (tmp < 0) { printf("Could not read entry data\n"); free(index); free(entry_data); return tmp; } index->entries = malloc(index->entry_count * sizeof(asf_index_entry_t)); if (!index->entries) { free(index); free(entry_data); return ASF_ERROR_OUTOFMEM; } for (i=0; i<index->entry_count; i++) { index->entries[i].packet_index = GetDWLE(entry_data + i*6); index->entries[i].packet_count = GetWLE(entry_data + i*6 + 4); } free(entry_data); file->index = index; return index->size; }