void Item::LoadFromDB(Field* fields, Player* plr, bool light) { uint32 itemid = fields[2].GetUInt32(); uint32 random_prop, random_suffix; uint32 count; m_itemProto = ItemPrototypeStorage.LookupEntry(itemid); ARCEMU_ASSERT(m_itemProto != NULL); locked = m_itemProto->LockId ? true : false; SetEntry(itemid); m_owner = plr; wrapped_item_id = fields[3].GetUInt32(); SetGiftCreatorGUID(fields[4].GetUInt32()); SetCreatorGUID(fields[5].GetUInt32()); count = fields[6].GetUInt32(); if (count > m_itemProto->MaxCount && (m_owner && !m_owner->ItemStackCheat)) count = m_itemProto->MaxCount; SetStackCount(count); SetChargesLeft(fields[7].GetUInt32()); SetUInt32Value(ITEM_FIELD_FLAGS, fields[8].GetUInt32()); random_prop = fields[9].GetUInt32(); random_suffix = fields[10].GetUInt32(); SetItemRandomPropertyId(random_prop); int32 rprop = int32(random_prop); // If random properties point is negative that means the item uses random suffix as random enchantment if (rprop < 0) SetItemRandomSuffixFactor(random_suffix); else SetItemRandomSuffixFactor(0); //SetTextId( fields[11].GetUInt32() ); SetDurabilityMax(m_itemProto->MaxDurability); SetDurability(fields[12].GetUInt32()); if (light) return; string enchant_field = fields[15].GetString(); vector< string > enchants = StrSplit(enchant_field, ";"); uint32 enchant_id; EnchantEntry* entry; uint32 time_left; uint32 enchslot; for (vector<string>::iterator itr = enchants.begin(); itr != enchants.end(); ++itr) { if (sscanf((*itr).c_str(), "%u,%u,%u", (unsigned int*)&enchant_id, (unsigned int*)&time_left, (unsigned int*)&enchslot) == 3) { entry = dbcEnchant.LookupEntryForced(enchant_id); if (entry && entry->Id == enchant_id && m_itemProto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN) { AddEnchantment(entry, time_left, (time_left == 0), false, false, enchslot); //(enchslot != 2) ? false : true, false); } else { /* EnchantEntry *pEnchant = new EnchantEntry; memset(pEnchant,0,sizeof(EnchantEntry)); pEnchant->Id = enchant_id; if(enchslot != 2) AddEnchantment(pEnchant,0,true, false); else AddEnchantment(pEnchant,0,false,false); */ } } } ItemExpiresOn = fields[16].GetUInt32(); ///////////////////////////////////////////////////// Refund stuff //////////////////////// std::pair< time_t, uint32 > refundentry; refundentry.first = fields[17].GetUInt32(); refundentry.second = fields[18].GetUInt32(); if (refundentry.first != 0 && refundentry.second != 0 && GetOwner() != NULL) { uint32* played = GetOwner()->GetPlayedtime(); if (played[1] < uint32(refundentry.first + 60 * 60 * 2)) m_owner->GetItemInterface()->AddRefundable(this, refundentry.second, refundentry.first); } /////////////////////////////////////////////////////////////////////////////////////////// text = fields[19].GetString(); ApplyRandomProperties(false); // Charter stuff if (GetEntry() == ITEM_ENTRY_GUILD_CHARTER) { SoulBind(); SetStackCount(1); SetItemRandomSuffixFactor(57813883); if (plr != NULL && plr->m_charters[CHARTER_TYPE_GUILD]) SetEnchantmentId(0, plr->m_charters[CHARTER_TYPE_GUILD]->GetID()); } if (GetEntry() == ARENA_TEAM_CHARTER_2v2) { SoulBind(); SetStackCount(1); SetItemRandomSuffixFactor(57813883); if (plr != NULL && plr->m_charters[CHARTER_TYPE_ARENA_2V2]) SetEnchantmentId(0, plr->m_charters[CHARTER_TYPE_ARENA_2V2]->GetID()); } if (GetEntry() == ARENA_TEAM_CHARTER_3v3) { SoulBind(); SetStackCount(1); SetItemRandomSuffixFactor(57813883); if (plr != NULL && plr->m_charters[CHARTER_TYPE_ARENA_3V3]) SetEnchantmentId(0, plr->m_charters[CHARTER_TYPE_ARENA_3V3]->GetID()); } if (GetEntry() == ARENA_TEAM_CHARTER_5v5) { SoulBind(); SetStackCount(1); SetItemRandomSuffixFactor(57813883); if (plr != NULL && plr->m_charters[CHARTER_TYPE_ARENA_5V5]) SetEnchantmentId(0, plr->m_charters[CHARTER_TYPE_ARENA_5V5]->GetID()); } }
void Item::LoadFromDB(Field* fields, Player* plr, bool light ) { uint32 itemid = fields[2].GetUInt32(); uint32 random_prop, random_suffix; uint32 count; m_itemProto = ItemPrototypeStorage.LookupEntry( itemid ); ASSERT( m_itemProto ); if(m_itemProto->LockId > 1) locked = true; else locked = false; SetUInt32Value( OBJECT_FIELD_ENTRY, itemid ); m_owner = plr; wrapped_item_id=fields[3].GetUInt32(); m_uint32Values[ITEM_FIELD_GIFTCREATOR] = fields[4].GetUInt32(); m_uint32Values[ITEM_FIELD_CREATOR] = fields[5].GetUInt32(); count = fields[6].GetUInt32(); if (count > m_itemProto->MaxCount) count = m_itemProto->MaxCount; SetUInt32Value( ITEM_FIELD_STACK_COUNT, count); // Again another for that did not indent to make it do anything for more than // one iteration x == 0 was the only one executed for( uint32 x = 0; x < 5; x++ ) { if( m_itemProto->Spells[x].Id ) { SetUInt32Value( ITEM_FIELD_SPELL_CHARGES + x , fields[7].GetUInt32() ); break; } } SetUInt32Value( ITEM_FIELD_FLAGS, fields[8].GetUInt32() ); random_prop = fields[9].GetUInt32(); random_suffix = fields[10].GetUInt32(); if( random_prop ) SetRandomProperty( random_prop ); else if( random_suffix ) SetRandomSuffix( random_suffix ); SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID, fields[11].GetUInt32() ); SetUInt32Value( ITEM_FIELD_MAXDURABILITY, m_itemProto->MaxDurability ); SetUInt32Value( ITEM_FIELD_DURABILITY, fields[12].GetUInt32() ); if( light ) return; string enchant_field = fields[15].GetString(); vector< string > enchants = StrSplit( enchant_field, ";" ); uint32 enchant_id; EnchantEntry* entry; uint32 time_left; uint32 enchslot; for( vector<string>::iterator itr = enchants.begin(); itr != enchants.end(); ++itr ) { if( sscanf( (*itr).c_str(), "%u,%u,%u", (unsigned int*)&enchant_id, (unsigned int*)&time_left, (unsigned int*)&enchslot) == 3 ) { entry = dbcEnchant.LookupEntry( enchant_id ); if( entry && entry->Id == enchant_id && m_itemProto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN) { AddEnchantment( entry, time_left, ( time_left == 0 ), false, false, enchslot ); //(enchslot != 2) ? false : true, false); } else { /* EnchantEntry *pEnchant = new EnchantEntry; memset(pEnchant,0,sizeof(EnchantEntry)); pEnchant->Id = enchant_id; if(enchslot != 2) AddEnchantment(pEnchant,0,true, false); else AddEnchantment(pEnchant,0,false,false); */ } } } ApplyRandomProperties( false ); // Charter stuff if(m_uint32Values[OBJECT_FIELD_ENTRY] == ITEM_ENTRY_GUILD_CHARTER) { SetUInt32Value( ITEM_FIELD_FLAGS, 1 ); SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_charters[CHARTER_TYPE_GUILD] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT, plr->m_charters[CHARTER_TYPE_GUILD]->GetID() ); } if( m_uint32Values[OBJECT_FIELD_ENTRY] == ARENA_TEAM_CHARTER_2v2 ) { SetUInt32Value( ITEM_FIELD_FLAGS, 1 ); SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_charters[CHARTER_TYPE_ARENA_2V2] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT, plr->m_charters[CHARTER_TYPE_ARENA_2V2]->GetID() ); } if( m_uint32Values[OBJECT_FIELD_ENTRY] == ARENA_TEAM_CHARTER_3v3 ) { SetUInt32Value( ITEM_FIELD_FLAGS, 1 ); SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_charters[CHARTER_TYPE_ARENA_3V3] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT, plr->m_charters[CHARTER_TYPE_ARENA_3V3]->GetID() ); } if( m_uint32Values[OBJECT_FIELD_ENTRY] == ARENA_TEAM_CHARTER_5v5 ) { SetUInt32Value( ITEM_FIELD_FLAGS, 1 ); SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_charters[CHARTER_TYPE_ARENA_5V5] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT, plr->m_charters[CHARTER_TYPE_ARENA_5V5]->GetID() ); } }
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 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(ObjectGuid(HIGHGUID_CORPSE, lowguid)); 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); SetGuidValue(CORPSE_FIELD_OWNER, 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 Player::UpdateArmorPenetration(int32 amount) { // Store Rating Value SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_ARMOR_PENETRATION, amount); }
void Pet::CreateAsSummon(uint32 entry, CreatureInfo *ci, Creature* created_from_creature, Unit* owner, SpellEntry* created_by_spell, uint32 type, uint32 expiretime) { if(ci == NULL) return; SetIsPet(true); m_OwnerGuid = owner->GetGUID(); m_Owner = TO_PLAYER(owner); m_OwnerGuid = m_Owner->GetGUID(); creature_info = ci; myFamily = dbcCreatureFamily.LookupEntry(creature_info->Family); //m_name = objmgr.GetCreatureFamilyName(myFamily->ID); if( myFamily->name == NULL ) m_name = "Pet"; else m_name.assign( myFamily->name ); // Create ourself Create(m_name.c_str(), owner->GetMapId(), owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation()); SetUInt32Value(OBJECT_FIELD_ENTRY, entry); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // better set this one // Fields common to both lock summons and pets uint32 level = (m_Owner->GetUInt32Value( UNIT_FIELD_LEVEL ) - 5); if( type & 0x2 && created_from_creature != NULL && created_from_creature->getLevel() > level) { level = created_from_creature->getLevel(); } SetUInt32Value(UNIT_FIELD_LEVEL, level); SetUInt32Value(UNIT_FIELD_DISPLAYID, ci->Male_DisplayID); SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, ci->Male_DisplayID); SetSummonedByGUID(owner->GetGUID()); SetCreatedByGUID(owner->GetGUID()); if(type & 0x1 && created_by_spell != NULL) SetUInt64Value(UNIT_CREATED_BY_SPELL, created_by_spell->Id); if(type & 0x1 || created_from_creature == NULL) { Summon = true; SetUInt32Value(UNIT_FIELD_BYTES_0, 2048 | (0 << 24)); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, 2000); SetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME, 2000); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.5f); SetFloatValue(UNIT_FIELD_COMBATREACH, 0.75f); SetUInt32Value(UNIT_FIELD_BYTES_2, (0x01 | (0x2 << 24))); SetUInt32Value(UNIT_FIELD_PETNUMBER, GetUIdFromGUID()); SetPowerType(POWER_TYPE_MANA); if(entry == WATER_ELEMENTAL) m_name = "Water Elemental"; else if( entry == 19668) m_name = "Shadowfiend"; else m_name = sWorld.GenerateName(); } else { SetUInt32Value(UNIT_FIELD_BYTES_0, 2048 | (0 << 24)); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, 2000); SetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME, 2000); // Supalosa: 2.00 normalized attack speed // hacks D: allow correct creation of hunter pets via gm command if(created_from_creature == this) { SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.5f); SetFloatValue(UNIT_FIELD_COMBATREACH, 0.75f); } else { SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, created_from_creature->GetFloatValue(UNIT_FIELD_BOUNDINGRADIUS)); SetFloatValue(UNIT_FIELD_COMBATREACH, created_from_creature->GetFloatValue(UNIT_FIELD_COMBATREACH)); } // These need to be checked. SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED | UNIT_FLAG_COMBAT); // why combat ?? SetHappiness(PET_HAPPINESS_UPDATE_VALUE >> 1); // happiness SetUInt32Value(UNIT_FIELD_MAXPOWER5, 1000000); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, GetNextLevelXP(getLevel())); SetUInt32Value(UNIT_FIELD_BYTES_1, 0); // Focus SetUInt32Value(UNIT_FIELD_POWER3, 100); SetUInt32Value(UNIT_FIELD_MAXPOWER3, 100); // 0x3 -> Enable pet rename. SetUInt32Value(UNIT_FIELD_BYTES_2, 1 | (0x3 << 16)); // Change the power type to FOCUS SetPowerType(POWER_TYPE_FOCUS); // create our spells SetDefaultSpells(); InitTalentsForLevel(true); } // Apply stats. ApplyStatsForLevel(); BaseDamage[0]=GetFloatValue(UNIT_FIELD_MINDAMAGE); BaseDamage[1]=GetFloatValue(UNIT_FIELD_MAXDAMAGE); BaseOffhandDamage[0]=GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); BaseOffhandDamage[1]=GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); BaseRangedDamage[0]=GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); BaseRangedDamage[1]=GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE)); m_PartySpellsUpdateTimer = 0; m_PetNumber = TO_PLAYER(owner)->GeneratePetNumber(); SetUInt32Value(UNIT_FIELD_PETNUMBER, GetUIdFromGUID()); m_ExpireTime = expiretime; bExpires = m_ExpireTime > 0 ? true : false; if(!bExpires) { // Create PlayerPet struct (Rest done by UpdatePetInfo) PlayerPet *pp = new PlayerPet; pp->number = m_PetNumber; pp->stablestate = STABLE_STATE_ACTIVE; TO_PLAYER(owner)->AddPlayerPet(pp, pp->number); } //maybe we should use speed from the template we created the creature ? m_base_runSpeed = m_runSpeed = owner->m_base_runSpeed; //should we be able to keep up with master ? m_base_walkSpeed = m_walkSpeed = owner->m_base_walkSpeed; //should we be able to keep up with master ? InitializeMe(true); }
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); }
void GameObject::EventCloseDoor() { SetUInt32Value(GAMEOBJECT_STATE, 0); }
void GameObject::Deactivate() { SetUInt32Value(GAMEOBJECT_DYN_FLAGS, 0); }
void Player::UpdateAttackPowerAndDamage(bool ranged ) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch(getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR:val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch(m_form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch(getClass()) { case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_DRUID: { //Check if Predatory Strikes is skilled float mLevelMult = 0.0; switch(m_form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: case FORM_MOONKIN: { Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { // Predatory Strikes if ((*itr)->GetSpellProto()->SpellIconID == 1563) { mLevelMult = (*itr)->GetModifier()->m_amount / 100.0f; break; } } break; } } switch(m_form) { case FORM_CAT: val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f; break; case FORM_BEAR: case FORM_DIREBEAR: val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case FORM_MOONKIN: val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; default: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if (ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0) { AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); for (AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifierValue() / 100.0f); } float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetUInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetUInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); Pet *pet = GetPet(); //update pet's AP if (pet) pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN) // mental quickness UpdateSpellDamageAndHealingBonus(); } }
void Pet::CreateAsSummon(uint32 entry, CreatureInfo *ci, Creature* created_from_creature, Unit *owner, SpellEntry* created_by_spell, uint32 type, uint32 expiretime) { SetIsPet(true); std::string myname = sWorld.GenerateName(); if(!ci) return; m_Owner = static_cast<Player*>(owner); m_OwnerGuid = m_Owner->GetGUID(); // Create ourself Create(myname.c_str(), owner->GetMapId(), owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation()); creature_info = ci; SetUInt32Value(OBJECT_FIELD_ENTRY, entry); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // better set this one // Fields common to both lock summons and pets if(type & 0x2 && created_from_creature != NULL) SetUInt32Value(UNIT_FIELD_LEVEL, created_from_creature->getLevel()); else SetUInt32Value(UNIT_FIELD_LEVEL,owner->GetUInt32Value(UNIT_FIELD_LEVEL)); SetUInt32Value(UNIT_FIELD_DISPLAYID, ci->DisplayID); SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, ci->DisplayID); SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()); SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID()); if(type & 0x1 && created_by_spell != NULL) SetUInt64Value(UNIT_CREATED_BY_SPELL, created_by_spell->Id); BaseStats[0] = uint32(20+getLevel()*1.55); BaseStats[1] = uint32(20+getLevel()*0.64); BaseStats[2] = uint32(20+getLevel()*1.27); BaseStats[3] = uint32(20+getLevel()*0.18); BaseStats[4] = uint32(20+getLevel()*0.36); if(type & 0x1 || created_from_creature == NULL) { Summon = true; float scale = 1.0f; switch(GetEntry()) { case 416: //Imp { scale = 0.4f; }break; case 417: //Felhunter { scale = 0.7f; }break; case 1860: //VoidWalker { scale = 0.75f; }break; case 1863: //Succubus { scale = 1.0f; }break; } SetFloatValue(OBJECT_FIELD_SCALE_X, scale); uint32 hp=uint32(28 + 10 * getLevel()); SetUInt32Value(UNIT_FIELD_MAXHEALTH, hp); SetUInt32Value(UNIT_FIELD_BASE_HEALTH,hp); uint32 mp=uint32(28 + 10 * getLevel()); SetUInt32Value(UNIT_FIELD_MAXPOWER1,mp ); SetUInt32Value(UNIT_FIELD_BASE_MANA,mp); SetFloatValue(OBJECT_FIELD_SCALE_X, scale); SetUInt32Value(UNIT_FIELD_BYTES_0, 2048 | (0 << 24)); SetUInt32Value(UNIT_FIELD_FLAGS, 8); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, 2000); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME_01, 2000); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.5f); SetFloatValue(UNIT_FIELD_COMBATREACH, 0.75f); SetFloatValue(UNIT_FIELD_MINDAMAGE,float(getLevel() * 1.88)); SetFloatValue(UNIT_FIELD_MAXDAMAGE,float(getLevel() * 3)); SetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, float(GetFloatValue(UNIT_FIELD_MINDAMAGE)*0.5)); SetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, float(GetFloatValue(UNIT_FIELD_MAXDAMAGE)*0.5)); SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,float((getLevel() * 1.88)/2)); SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,float((getLevel() * 3)/2)); SetUInt32Value(UNIT_FIELD_ATTACK_POWER, uint32(getLevel() * 1.7)); SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, uint32(getLevel() * 2.4)); for(int x=0;x<5;x++) SetUInt32Value(UNIT_FIELD_STAT0 + x, BaseStats[x]); SetUInt32Value(UNIT_FIELD_RESISTANCES, 180); SetUInt32Value(UNIT_FIELD_BYTES_2, 0x01); SetUInt32Value(UNIT_FIELD_MAXPOWER1, uint32(28 + 10 * getLevel())); SetUInt32Value(UNIT_FIELD_PETNUMBER, GetGUIDLow()); } else { uint32 hp=created_from_creature->GetUInt32Value(UNIT_FIELD_MAXHEALTH); SetUInt32Value(UNIT_FIELD_MAXHEALTH, hp); SetUInt32Value(UNIT_FIELD_BASE_HEALTH,hp); SetFloatValue(OBJECT_FIELD_SCALE_X, created_from_creature->GetFloatValue(OBJECT_FIELD_SCALE_X)); SetUInt32Value(UNIT_FIELD_BYTES_0, created_from_creature->GetUInt32Value(UNIT_FIELD_BYTES_0)); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, created_from_creature->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME)); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME_01, created_from_creature->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME_01)); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, created_from_creature->GetFloatValue(UNIT_FIELD_BOUNDINGRADIUS)); SetFloatValue(UNIT_FIELD_COMBATREACH, created_from_creature->GetFloatValue(UNIT_FIELD_COMBATREACH)); SetFloatValue(UNIT_FIELD_MINDAMAGE, created_from_creature->GetFloatValue(UNIT_FIELD_MINDAMAGE)); SetFloatValue(UNIT_FIELD_MAXDAMAGE, created_from_creature->GetFloatValue(UNIT_FIELD_MAXDAMAGE)); SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, created_from_creature->GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE)); SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, created_from_creature->GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE)); SetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, created_from_creature->GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE)); SetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, created_from_creature->GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)); SetUInt32Value(UNIT_FIELD_ATTACK_POWER, created_from_creature->GetUInt32Value(UNIT_FIELD_ATTACK_POWER)); SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, created_from_creature->GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER));; SetUInt32Value(UNIT_FIELD_MAXPOWER1, 0); SetUInt32Value(UNIT_FIELD_BASE_MANA, 0); SetUInt32Value(UNIT_FIELD_MAXPOWER2, 0); SetUInt32Value(UNIT_FIELD_MAXPOWER3, 200); SetUInt32Value(UNIT_FIELD_MAXPOWER4, 0); SetUInt32Value(UNIT_FIELD_RESISTANCES, created_from_creature->GetUInt32Value(UNIT_FIELD_RESISTANCES)); // These need to be checked. SetUInt32Value(UNIT_FIELD_FLAGS, 0x00000828); SetUInt32Value(UNIT_FIELD_POWER5, 600000); SetUInt32Value(UNIT_FIELD_MAXPOWER5, 1000000); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, GetNextLevelXP(getLevel())); // Change the power type to FOCUS SetPowerType(POWER_TYPE_FOCUS); for(int x=0;x<5;x++) SetUInt32Value(UNIT_FIELD_STAT0 + x, BaseStats[x]); // create our spellz SetDefaultSpells(); } BaseDamage[0]=GetFloatValue(UNIT_FIELD_MINDAMAGE); BaseDamage[1]=GetFloatValue(UNIT_FIELD_MAXDAMAGE); BaseOffhandDamage[0]=GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); BaseOffhandDamage[1]=GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); BaseRangedDamage[0]=GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); BaseRangedDamage[1]=GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE)); // Set all values to full. SetUInt32Value(UNIT_FIELD_HEALTH, GetUInt32Value(UNIT_FIELD_MAXHEALTH)); SetUInt32Value(UNIT_FIELD_POWER1, GetUInt32Value(UNIT_FIELD_MAXPOWER1)); SetUInt32Value(UNIT_FIELD_POWER2, GetUInt32Value(UNIT_FIELD_MAXPOWER2)); SetUInt32Value(UNIT_FIELD_POWER3, GetUInt32Value(UNIT_FIELD_MAXPOWER3)); SetUInt32Value(UNIT_FIELD_POWER4, GetUInt32Value(UNIT_FIELD_MAXPOWER4)); // Set base values SetUInt32Value(UNIT_FIELD_BASE_HEALTH, GetUInt32Value(UNIT_FIELD_HEALTH)); SetUInt32Value(UNIT_FIELD_BASE_MANA, GetUInt32Value(UNIT_FIELD_POWER1)); memcpy(m_baseUint32Values, m_uint32Values,m_valuesCount*sizeof(uint32)); m_PartySpellsUpdateTimer = 0; m_PetNumber = static_cast<Player*>(owner)->GeneratePetNumber(); SetUInt32Value(UNIT_FIELD_PETNUMBER, m_GuidLow); m_ExpireTime = expiretime; bExpires = m_ExpireTime > 0 ? true : false; if(!bExpires) { // Create PlayerPet struct (Rest done by UpdatePetInfo) PlayerPet *pp = new PlayerPet; pp->number = m_PetNumber; static_cast<Player*>(owner)->AddPlayerPet(pp, pp->number); } InitializeMe(true); }
//----------------------------------------------------------------------------- void Unit::ApplyModifier(const Modifier *mod, bool apply, Affect* parent) { //Player * player; Creature * creature; Unit * unit; WorldPacket data; Unit * caster = WorldGetUnit (parent->GetCasterGUID()); if (caster != NULL && Call_Aura_ApplyModifier (mod->GetType(), caster, this, apply, mod->GetAmount(), mod->GetMiscValue(), mod->GetMiscValue2())) { sLog.outDebug ("ApplyModifier->SCRIPT: Type=%d Amount=%d V1=%d V2=%d", mod->GetType(), mod->GetAmount(), mod->GetMiscValue(), mod->GetMiscValue2()); return; } sLog.outDebug ("ApplyModifier: Type=%d Amount=%d V1=%d V2=%d", mod->GetType(), mod->GetAmount(), mod->GetMiscValue(), mod->GetMiscValue2()); switch(mod->GetType()) { case SPELL_AURA_NONE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_NONE"); break; } case SPELL_AURA_BIND_SIGHT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_BIND_SIGHT"); break; } case SPELL_AURA_MOD_THREAT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_THREAT"); break; } case SPELL_AURA_AURAS_VISIBLE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_AURAS_VISIBLE"); break; } case SPELL_AURA_MOD_RESISTANCE_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RESISTANCE_PCT"); break; } case SPELL_AURA_MOD_CREATURE_ATTACK_POWER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CREATURE_ATTACK_POWER"); break; } case SPELL_AURA_MOD_TOTAL_THREAT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_TOTAL_THREAT"); break; } case SPELL_AURA_WATER_WALK: { apply ? data.Initialize(SMSG_MOVE_WATER_WALK) : data.Initialize(SMSG_MOVE_LAND_WALK); data << GetGUID(); SendMessageToSet(&data,true); break; } case SPELL_AURA_FEATHER_FALL: { apply ? data.Initialize(SMSG_MOVE_FEATHER_FALL) : data.Initialize(SMSG_MOVE_NORMAL_FALL); data << GetGUID(); SendMessageToSet(&data,true); break; } case SPELL_AURA_HOVER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_HOVER"); break; } case SPELL_AURA_ADD_FLAT_MODIFIER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_FLAT_MODIFIER"); break; } case SPELL_AURA_ADD_PCT_MODIFIER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_PCT_MODIFIER"); break; } case SPELL_AURA_ADD_TARGET_TRIGGER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_TARGET_TRIGGER"); break; } case SPELL_AURA_MOD_TAUNT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_TAUNT"); break; } case SPELL_AURA_MOD_POWER_REGEN_PERCENT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_REGEN_PERCENT"); break; } case SPELL_AURA_ADD_CASTER_HIT_TRIGGER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_CASTER_HIT_TRIGGER"); break; } case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_OVERRIDE_CLASS_SCRIPTS"); break; } case SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN"); break; } case SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT"); break; } case SPELL_AURA_MOD_HEALING: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING"); break; } case SPELL_AURA_IGNORE_REGEN_INTERRUPT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_IGNORE_REGEN_INTERRUPT"); break; } case SPELL_AURA_MOD_MECHANIC_RESISTANCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MECHANIC_RESISTANCE"); break; } case SPELL_AURA_MOD_HEALING_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING_PCT"); break; } case SPELL_AURA_SHARE_PET_TRACKING: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SHARE_PET_TRACKING"); break; } case SPELL_AURA_MOD_CONFUSE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CONFUSE"); break; } case SPELL_AURA_MOD_STUN: { //sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_STUN"); if (apply) SetTarget (0); break; } case SPELL_AURA_UNTRACKABLE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_UNTRACKABLE"); break; } case SPELL_AURA_EMPATHY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_EMPATHY"); break; } case SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT"); break; } case SPELL_AURA_MOD_POWER_COST_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_COST_PCT"); break; } case SPELL_AURA_MOD_RANGED_ATTACK_POWER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_ATTACK_POWER"); break; } case SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN"); break; } case SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT"); break; } case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS"); break; } case SPELL_AURA_MOD_POSSESS_PET: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POSSESS_PET"); break; } case SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS: { unit = WorldGetUnit (GetGUID()); if (unit != NULL) { if (apply) unit->ModifySpeedMod (mod->GetAmount() / 100.0f); else { if (mod->GetAmount() != 0) unit->ModifySpeedMod (100.0f / mod->GetAmount()); else unit->SetSpeedMod (1.0f); } } else { sLog.outDebug ("ApplyModifier SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS: Unit %X not found", GetGUIDLow()); } break; } case SPELL_AURA_MOD_DAMAGE_DONE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_DONE"); break; } case SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS"); break; } case SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER"); break; } case SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT: { uint32 percent = mod->GetAmount(); uint32 current = GetUInt32Value(UNIT_FIELD_POWER4); apply ? SetUInt32Value(UNIT_FIELD_POWER4,current+current/100*percent) : SetUInt32Value(UNIT_FIELD_POWER4,current-current/(100+percent)*100); break; } case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT: { uint32 percent = mod->GetAmount(); uint32 current = GetUInt32Value(UNIT_FIELD_MAXHEALTH); apply ? SetUInt32Value(UNIT_FIELD_MAXHEALTH,current+current/100*percent) : SetUInt32Value(UNIT_FIELD_MAXHEALTH,current-current/(100+percent)*100); break; } case SPELL_AURA_MOD_MANA_REGEN_INTERRUPT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MANA_REGEN_INTERRUPT"); break; } case SPELL_AURA_MOD_HEALING_DONE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING_DONE"); break; } case SPELL_AURA_MOD_HEALING_DONE_PERCENT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING_DONE_PERCENT"); break; } case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE"); break; } case SPELL_AURA_MOD_HASTE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HASTE"); break; } case SPELL_AURA_FORCE_REACTION: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_FORCE_REACTION"); break; } case SPELL_AURA_MOD_DAMAGE_TAKEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_TAKEN"); break; } case SPELL_AURA_MOD_RANGED_HASTE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_HASTE"); break; } case SPELL_AURA_MOD_RANGED_AMMO_HASTE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_AMMO_HASTE"); break; } case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_BASE_RESISTANCE_PCT"); break; } case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE"); break; } case SPELL_AURA_SAFE_FALL: { apply ? data.Initialize(SMSG_MOVE_FEATHER_FALL) : data.Initialize(SMSG_MOVE_NORMAL_FALL); data << GetGUID(); SendMessageToSet(&data,true); break; } case SPELL_AURA_CHARISMA: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_CHARISMA"); break; } case SPELL_AURA_PERSUADED: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERSUADED"); break; } case SPELL_AURA_ADD_CREATURE_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_CREATURE_IMMUNITY"); break; } case SPELL_AURA_RETAIN_COMBO_POINTS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_RETAIN_COMBO_POINTS"); break; } case SPELL_AURA_DAMAGE_SHIELD: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_DAMAGE_SHIELD"); break; } case SPELL_AURA_MOD_STEALTH: { //sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_STEALTH"); // Convert float stored into integer field to normal view float amountf; *((int *)&amountf) = mod->GetAmount(); // Clip effective stealth level by spell level int amount = min (GetLevel() * 5, (int)amountf + 95); if (apply) m_stealthLevel += amount; else m_stealthLevel -= amount; sLog.outDebug ("ApplyModifier: STEALTH value set to %d", m_stealthLevel); break; } case SPELL_AURA_MOD_DETECT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DETECT"); break; } case SPELL_AURA_MOD_INVISIBILITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INVISIBILITY"); break; } case SPELL_AURA_MOD_INVISIBILITY_DETECTION: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INVISIBILITY_DETECTION"); break; } case SPELL_AURA_MOD_POSSESS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POSSESS"); break; } case SPELL_AURA_MOD_RESISTANCE: { uint16 index = 0; uint16 index2 = 0; switch(mod->GetMiscValue()) { case DMG_PHYSICAL: { index = UNIT_FIELD_RESISTANCES; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE; break; } case DMG_HOLY: { index = UNIT_FIELD_RESISTANCES + DMG_HOLY; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_HOLY : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_HOLY; break; } case DMG_FIRE: { index = UNIT_FIELD_RESISTANCES + DMG_FIRE; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_FIRE : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_FIRE; break; } case DMG_NATURE: { index = UNIT_FIELD_RESISTANCES + DMG_NATURE; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_NATURE : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_NATURE; break; } case DMG_FROST: { index = UNIT_FIELD_RESISTANCES + DMG_FROST; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_FROST : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_FROST; break; } case DMG_SHADOW:{ index = UNIT_FIELD_RESISTANCES + DMG_SHADOW; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_SHADOW : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_SHADOW; break; } case DMG_ARCANE:{ index = UNIT_FIELD_RESISTANCES + DMG_ARCANE; mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_ARCANE : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_ARCANE; break; } default:{ sLog.outDetail ("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid\n"); return; break; } } if(apply){ SetUInt32Value(index,GetUInt32Value(index)+mod->GetAmount()); if (isPlayer()) SetUInt32Value(index2,GetUInt32Value(index2)+mod->GetAmount()); }else{ SetUInt32Value(index,GetUInt32Value(index)-mod->GetAmount()); if (isPlayer()) SetUInt32Value(index2,GetUInt32Value(index2)-mod->GetAmount()); } break; } case SPELL_AURA_PERIODIC_TRIGGER_SPELL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_TRIGGER_SPELL"); break; } case SPELL_AURA_PERIODIC_ENERGIZE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_ENERGIZE"); break; } case SPELL_AURA_MOD_PACIFY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PACIFY"); break; } case SPELL_AURA_MOD_ROOT: { apply ? data.Initialize(MSG_MOVE_ROOT) : data.Initialize(MSG_MOVE_UNROOT); data << GetGUID(); SendMessageToSet(&data,true); break; } case SPELL_AURA_MOD_SILENCE: { apply ? m_silenced = true : m_silenced = false; break; } case SPELL_AURA_REFLECT_SPELLS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_REFLECT_SPELLS"); break; } case SPELL_AURA_MOD_STAT: { uint16 index = 0; uint16 index2 = 0; int32 v = mod->GetAmount(); switch(mod->GetMiscValue()) { case 0:{ //index = UNIT_FIELD_STAT0; ModifyStrength (apply ? v : -v); mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT0 : index2 = PLAYER_FIELD_NEGSTAT0; break; } case 1:{ //index = UNIT_FIELD_STAT1; ModifyAgility (apply ? v : -v); mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT1 : index2 = PLAYER_FIELD_NEGSTAT1; break; } case 2:{ //index = UNIT_FIELD_STAT2; ModifyStamina (apply ? v : -v); mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT2 : index2 = PLAYER_FIELD_NEGSTAT2; break; } case 3:{ //index = UNIT_FIELD_STAT3; ModifyIntellect (apply ? v : -v); mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT3 : index2 = PLAYER_FIELD_NEGSTAT3; break; } case 4:{ //index = UNIT_FIELD_STAT4; ModifySpirit (apply ? v : -v); mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT4 : index2 = PLAYER_FIELD_NEGSTAT4; break; } default:{ printf("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid\n"); return; break; } } if(apply){ if (isPlayer()) SetUInt32Value(index2,GetUInt32Value(index2) + v); }else{ if (isPlayer()) SetUInt32Value(index2,GetUInt32Value(index2) - v); } break; } case SPELL_AURA_PERIODIC_DAMAGE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_DAMAGE"); break; } case SPELL_AURA_MOD_SKILL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SKILL"); break; } case SPELL_AURA_MOD_INCREASE_SPEED: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INCREASE_SPEED"); break; } case SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED: { if (GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_MOUNTED ) { float newspeed = (float)mod->GetAmount() / 100.0f; newspeed = newspeed + 1.0f; sLog.outDebug("New Speed (With mount): %.1f", newspeed); unit = WorldGetUnit (GetGUID()); if (unit != NULL) unit->SetSpeedMod(newspeed); } else { unit = WorldGetUnit (GetGUID()); if (unit != NULL) unit->SetSpeedMod(1.0f); } sLog.outDebug ("ApplyModifier: SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED"); break; } case SPELL_AURA_MOD_DECREASE_SPEED: { unit = WorldGetUnit (GetGUID()); if (unit != NULL) { if (apply) unit->ModifySpeedMod (mod->GetAmount() / 100.0f); else { if (mod->GetAmount() != 0) unit->ModifySpeedMod (100.0f / mod->GetAmount()); else unit->SetSpeedMod (1.0f); } } break; } case SPELL_AURA_MOD_INCREASE_HEALTH: { uint32 newValue; newValue = GetUInt32Value(UNIT_FIELD_MAXHEALTH); apply ? newValue += mod->GetAmount() : newValue -= mod->GetAmount(); SetUInt32Value(UNIT_FIELD_MAXHEALTH,newValue); break; } case SPELL_AURA_MOD_INCREASE_ENERGY: { uint32 powerField = 23; uint8 powerType = (uint8)(GetUInt32Value(UNIT_FIELD_BYTES_0) >> 24); if(powerType == 0) // Mana powerField = UNIT_FIELD_POWER1; else if(powerType == 1) // Rage powerField = UNIT_FIELD_POWER2; else if(powerType == 3) // Energy powerField = UNIT_FIELD_POWER4; uint32 newValue = GetUInt32Value(powerType); apply ? newValue += mod->GetAmount() : newValue -= mod->GetAmount(); SetUInt32Value(powerType,newValue); break; } case SPELL_AURA_MOD_SHAPESHIFT: { Affect* tmpAff; uint32 spellId; switch(mod->GetMiscValue()) { case FORM_CAT: { spellId = 3025; break; } case FORM_TREE:{ spellId = 3122; break; } case FORM_TRAVEL:{ spellId = 5419; break; } case FORM_AQUA:{ spellId = 5421; break; } case FORM_BEAR:{ spellId = 1178; break; } case FORM_AMBIENT:{ spellId = 0; break; } case FORM_GHOUL:{ spellId = 0; break; } case FORM_DIREBEAR:{ spellId = 9635; break; } case FORM_CREATUREBEAR:{ spellId = 2882; break; } case FORM_GHOSTWOLF:{ spellId = 0; break; } case FORM_BATTLESTANCE:{ spellId = 2457; break; } case FORM_DEFENSIVESTANCE:{ spellId = 7376; break; } case FORM_BERSERKERSTANCE:{ spellId = 7381; break; } case FORM_SHADOW:{ spellId = 0; break; } case FORM_STEALTH:{ //spellId = 0; // Turn on Sneaky Stance, Switch stealth button to unstealth and switch spellbar SetUInt32Value (UNIT_FIELD_BYTES_1, apply? 0x021E0000: 0); if (apply == false && isPlayer()) { data.Initialize (SMSG_COOLDOWN_EVENT); data << (uint32)1784 << GetGUID(); ((Player*)this)->GetSession()->SendPacket (&data); } return; } default:{ printf("Unknown Shapeshift Type\n"); break; } } // check for spell id SpellEntry *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) { sLog.outError("WORLD: unknown spell id %i\n", spellId); break; } tmpAff = new Affect(spellInfo,parent->GetDuration(),parent->GetCasterGUID()); for(uint8 i=0; i<3; ++i){ if(spellInfo->Effect[i] == 6){ uint32 value = 0; uint32 type = 0; uint32 damage = 0; if(spellInfo->EffectBasePoints[i] < 0){ tmpAff->SetNegative(); type = 1; } uint32 sBasePoints = (uint32)sqrt((float)(spellInfo->EffectBasePoints[i]*spellInfo->EffectBasePoints[i])); if(spellInfo->EffectApplyAuraName[i] == 3){ // Periodic Trigger Damage damage = spellInfo->EffectBasePoints[i]+rand()%spellInfo->EffectDieSides[i]+1; //TODO: why the hell it takes uint16? tmpAff->SetDamagePerTick((uint16)damage, spellInfo->EffectAmplitude[i]); tmpAff->SetNegative(); }else if(spellInfo->EffectApplyAuraName[i] == 23)// Periodic Trigger Spell tmpAff->SetPeriodicTriggerSpell(spellInfo->EffectTriggerSpell[i],spellInfo->EffectAmplitude[i]); else{ if(spellInfo->EffectDieSides[i] != 0) value = sBasePoints+rand()%spellInfo->EffectDieSides[i]; else value = sBasePoints; if(spellInfo->EffectDieSides[i] <= 1) value += 1; //TODO: why the hell it takes uint8? tmpAff->AddMod((uint8)spellInfo->EffectApplyAuraName[i],value,spellInfo->EffectMiscValue[i],type); } } } if(tmpAff){ parent->SetCoAffect(tmpAff); AddAffect(tmpAff); } break; } case SPELL_AURA_EFFECT_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_EFFECT_IMMUNITY"); break; } case SPELL_AURA_STATE_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_STATE_IMMUNITY"); break; } case SPELL_AURA_SCHOOL_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SCHOOL_IMMUNITY"); break; } case SPELL_AURA_DAMAGE_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_DAMAGE_IMMUNITY"); break; } case SPELL_AURA_DISPEL_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_DISPEL_IMMUNITY"); break; } case SPELL_AURA_PROC_TRIGGER_SPELL: { apply ? m_triggerSpell = mod->GetAmount() : m_triggerSpell = 0; break; } case SPELL_AURA_PROC_TRIGGER_DAMAGE: { apply ? m_triggerDamage = mod->GetAmount() : m_triggerDamage = 0; break; } case SPELL_AURA_TRACK_CREATURES: { apply ? SetUInt32Value(PLAYER_TRACK_CREATURES,mod->GetMiscValue()) : SetUInt32Value(PLAYER_TRACK_CREATURES,0); break; } case SPELL_AURA_TRACK_RESOURCES: { apply ? SetUInt32Value(PLAYER_TRACK_RESOURCES,mod->GetMiscValue()) : SetUInt32Value(PLAYER_TRACK_RESOURCES,0); break; } case SPELL_AURA_MOD_PARRY_SKILL: { break; } case SPELL_AURA_MOD_PARRY_PERCENT: { //uint32 current = GetUInt32Value(PLAYER_PARRY_PERCENTAGE); //apply ? SetUInt32Value(PLAYER_PARRY_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_PARRY_PERCENTAGE,current-mod->GetAmount()); ModifyParryChance (apply ? mod->GetAmount() : -mod->GetAmount()); break; } case SPELL_AURA_MOD_DODGE_SKILL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DODGE_SKILL"); break; } case SPELL_AURA_MOD_DODGE_PERCENT: { //uint32 current = GetUInt32Value(PLAYER_DODGE_PERCENTAGE); //apply ? SetUInt32Value(PLAYER_DODGE_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_DODGE_PERCENTAGE,current-mod->GetAmount()); ModifyDodgeChance (apply ? mod->GetAmount() : -mod->GetAmount()); break; } case SPELL_AURA_MOD_BLOCK_SKILL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_BLOCK_SKILL"); break; } case SPELL_AURA_MOD_BLOCK_PERCENT: { //uint32 current = GetUInt32Value(PLAYER_BLOCK_PERCENTAGE); //apply ? SetUInt32Value(PLAYER_BLOCK_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_BLOCK_PERCENTAGE,current-mod->GetAmount()); ModifyBlockChance (apply ? mod->GetAmount() : -mod->GetAmount()); break; } case SPELL_AURA_MOD_CRIT_PERCENT: { //uint32 current = GetUInt32Value(PLAYER_CRIT_PERCENTAGE); //apply ? SetUInt32Value(PLAYER_CRIT_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_CRIT_PERCENTAGE,current-mod->GetAmount()); ModifyCritChance (apply ? mod->GetAmount() : -mod->GetAmount()); break; } case SPELL_AURA_PERIODIC_LEECH: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_LEECH"); break; } case SPELL_AURA_MOD_HIT_CHANCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HIT_CHANCE"); break; } case SPELL_AURA_MOD_SPELL_HIT_CHANCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SPELL_HIT_CHANCE"); break; } case SPELL_AURA_TRANSFORM: { if (parent->GetId() == 118) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 228) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 304); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 851) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 4060) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 131); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 5254) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 12824) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 12825) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 12826) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 13323) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 15534) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 856); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } if (parent->GetId() == 17738) { if (apply) { //((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID)); SetUInt32Value (UNIT_FIELD_DISPLAYID, 1141); } else { SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); if (caster != NULL) AddHate (caster, 1.0f); } } break; } case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SPELL_CRIT_CHANCE"); break; } case SPELL_AURA_MOD_INCREASE_SWIM_SPEED: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INCREASE_SWIM_SPEED"); break; } case SPELL_AURA_MOD_DAMAGE_DONE_CREATURE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_DONE_CREATURE"); break; } case SPELL_AURA_MOD_CHARM: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CHARM"); break; } case SPELL_AURA_MOD_PACIFY_SILENCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PACIFY_SILENCE"); break; } case SPELL_AURA_MOD_SCALE: { float current = GetFloatValue(OBJECT_FIELD_SCALE_X); apply ? SetFloatValue(OBJECT_FIELD_SCALE_X,current+current/100*10) : SetFloatValue(OBJECT_FIELD_SCALE_X,current-current/110*100); break; } case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_HEALTH_FUNNEL"); break; } case SPELL_AURA_PERIODIC_MANA_FUNNEL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_MANA_FUNNEL"); break; } case SPELL_AURA_PERIODIC_MANA_LEECH: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_MANA_LEECH"); break; } case SPELL_AURA_MOD_CASTING_SPEED: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CASTING_SPEED"); break; } case SPELL_AURA_FEIGN_DEATH: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_FEIGN_DEATH"); break; } case SPELL_AURA_MOD_DISARM: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DISARM"); break; } case SPELL_AURA_MOD_STALKED: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_STALKED"); break; } case SPELL_AURA_SCHOOL_ABSORB: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SCHOOL_ABSORB"); break; } case SPELL_AURA_MOD_FEAR: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_FEAR"); break; } case SPELL_AURA_EXTRA_ATTACKS: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_EXTRA_ATTACKS"); break; } case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL"); break; } case SPELL_AURA_MOD_POWER_COST: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_COST"); break; } case SPELL_AURA_MOD_POWER_COST_SCHOOL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_COST_SCHOOL"); break; } case SPELL_AURA_REFLECT_SPELLS_SCHOOL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_REFLECT_SPELLS_SCHOOL"); break; } case SPELL_AURA_MOD_LANGUAGE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_LANGUAGE"); break; } case SPELL_AURA_FAR_SIGHT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_FAR_SIGHT"); break; } case SPELL_AURA_MECHANIC_IMMUNITY: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MECHANIC_IMMUNITY"); break; } case SPELL_AURA_MOUNTED: { sLog.outDebug ("ApplyModifier: SPELL_AURA_MOUNTED"); if (GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_MOUNTED ) { SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID , 0); RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED ); // Remove the "player locked" flag, to allow movement if (GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_LOCKED ) RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_LOCKED ); // Make sure we're standing ;) SetUInt32Value(UNIT_FIELD_BYTES_1, STANDSTATE_STAND); } else { // Set mount ID from creatures_templ CreatureTemplate *ptempl = objmgr.GetCreatureTemplate(mod->GetMiscValue(), true); SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID , ptempl->Model); //SetUInt32Value( UNIT_FIELD_FLAGS , UNIT_FLAG_MOUNTED ); SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED ); } break; } case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_PERCENT_DONE"); break; } case SPELL_AURA_PERIODIC_HEAL: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_HEAL"); break; } case SPELL_AURA_MOD_PERCENT_STAT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PERCENT_STAT"); break; } case SPELL_AURA_SPLIT_DAMAGE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SPLIT_DAMAGE"); break; } case SPELL_AURA_WATER_BREATHING: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_WATER_BREATHING"); break; } case SPELL_AURA_MOD_BASE_RESISTANCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_BASE_RESISTANCE"); break; } case SPELL_AURA_MOD_REGEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_REGEN"); break; } case SPELL_AURA_MOD_POWER_REGEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_REGEN"); break; } case SPELL_AURA_CHANNEL_DEATH_ITEM: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_CHANNEL_DEATH_ITEM"); break; } case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN"); break; } case SPELL_AURA_MOD_PERCENT_REGEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PERCENT_REGEN"); break; } case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_DAMAGE_PERCENT"); break; } case SPELL_AURA_MOD_ATTACKSPEED: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_ATTACKSPEED"); break; } case SPELL_AURA_MOD_RESIST_CHANCE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RESIST_CHANCE"); break; } case SPELL_AURA_MOD_DETECT_RANGE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DETECT_RANGE"); break; } case SPELL_AURA_PREVENTS_FLEEING: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PREVENTS_FLEEING"); break; } case SPELL_AURA_MOD_UNATTACKABLE: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_UNATTACKABLE"); break; } case SPELL_AURA_INTERRUPT_REGEN: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_INTERRUPT_REGEN"); break; } case SPELL_AURA_GHOST: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_GHOST"); break; } case SPELL_AURA_SPELL_MAGNET: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SPELL_MAGNET"); break; } case SPELL_AURA_MANA_SHIELD: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MANA_SHIELD"); break; } case SPELL_AURA_MOD_SKILL_TALENT: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SKILL_TALENT"); break; } case SPELL_AURA_MOD_ATTACK_POWER: { sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_ATTACK_POWER"); break; } default: { sLog.outError("Unknown affect id %u", (uint32)mod->GetType()); } } }
void Vehicle::_AddToSlot(Unit* pPassenger, uint8 slot) { assert( slot < m_seatSlotMax ); if(pPassenger->IsPlayer() && TO_PLAYER(pPassenger)->m_CurrentCharm) return; if(pPassenger->IsPlayer() && TO_PLAYER(pPassenger)->m_isGmInvisible) { sChatHandler.GreenSystemMessage(TO_PLAYER(pPassenger)->GetSession(), "Please turn off invis before entering vehicle."); return; } CreatureProtoVehicle* vehicleproto = CreatureProtoVehicleStorage.LookupEntry(GetEntry()); m_passengers[slot] = pPassenger; LocationVector v; v.x = m_vehicleSeats[slot]->m_attachmentOffsetX; /* pPassenger->m_TransporterX = */ v.y = m_vehicleSeats[slot]->m_attachmentOffsetY; /* pPassenger->m_TransporterY = */ v.z = m_vehicleSeats[slot]->m_attachmentOffsetZ; /* pPassenger->m_TransporterZ = */ v.o = 0; /* pPassenger->m_TransporterO = */ //pPassenger->m_transportPosition =& v; // This is handled elsewhere, do not initialize here. pPassenger->movement_info.flags |= MOVEFLAG_TAXI; pPassenger->movement_info.transX = v.x; pPassenger->movement_info.transY = v.y; pPassenger->movement_info.transZ = v.z; pPassenger->movement_info.transO = GetOrientation(); pPassenger->movement_info.transSeat = slot; pPassenger->movement_info.transGuid = WoWGuid(GetGUID()); pPassenger->SetSeatID(slot); pPassenger->m_TransporterGUID = GetGUID(); if( m_CastSpellOnMount ) pPassenger->CastSpell( pPassenger, m_CastSpellOnMount, true ); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SELF_RES); // This is where the real magic happens if( pPassenger->IsPlayer() ) { Player* pPlayer = TO_PLAYER(pPassenger); //pPlayer->Root(); //Dismount if(pPlayer->m_MountSpellId && pPlayer->m_MountSpellId != m_mountSpell) pPlayer->RemoveAura(pPlayer->m_MountSpellId); //Remove morph spells if(pPlayer->GetUInt32Value(UNIT_FIELD_DISPLAYID) != pPlayer->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)) { pPlayer->RemoveAllAurasOfType(SPELL_AURA_TRANSFORM); pPlayer->RemoveAllAurasOfType(SPELL_AURA_MOD_SHAPESHIFT); } //Dismiss any pets if(pPlayer->GetSummon()) { if(pPlayer->GetSummon()->GetUInt32Value(UNIT_CREATED_BY_SPELL) > 0) pPlayer->GetSummon()->Dismiss(false); // warlock summon -> dismiss else pPlayer->GetSummon()->Remove(false, true, true); // hunter pet -> just remove for later re-call } pPlayer->SetVehicle(this); pPlayer->SetUInt64Value(PLAYER_FARSIGHT, GetGUID()); pPlayer->SetPlayerStatus(TRANSFER_PENDING); sEventMgr.AddEvent(pPlayer, &Player::CheckPlayerStatus, (uint8)TRANSFER_PENDING, EVENT_PLAYER_CHECK_STATUS_Transfer, 5000, 0, 0); pPlayer->m_sentTeleportPosition.ChangeCoords(GetPositionX(), GetPositionY(), GetPositionZ()); WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, 100); data << pPlayer->GetNewGUID(); // Passengerguid data << GetNewGUID(); // Transporterguid (vehicleguid) data << uint8(slot); // Vehicle Seat ID data << uint8(0); // Unknown data << GetPositionX() - pPlayer->GetPositionX(); // OffsetTransporterX data << GetPositionY() - pPlayer->GetPositionY(); // OffsetTransporterY data << GetPositionZ() - pPlayer->GetPositionZ(); // OffsetTransporterZ data << getMSTime(); // Timestamp data << uint8(0x04); // Flags data << float(0); // Orientation Offset data << uint32(MOVEFLAG_TB_MOVED); // MovementFlags data << uint32(0); // MoveTime data << uint32(1); // Points data << v.x; // GetTransOffsetX(); data << v.y; // GetTransOffsetY(); data << v.z; // GetTransOffsetZ(); SendMessageToSet(&data, true); if(vehicleproto) { // We have proto, no accessory in slot, and slot sets unselectable, unlike some seats if(!vehicleproto->seats[slot].accessoryentry && vehicleproto->seats[slot].unselectableaccessory) pPlayer->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); } else pPlayer->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); if(slot == 0) { if(m_vehicleSeats[slot]->IsControllable()) { m_redirectSpellPackets = pPlayer; SetSpeed(RUN, m_runSpeed); SetSpeed(FLY, m_flySpeed); // send "switch mover" packet data.Initialize(SMSG_CLIENT_CONTROL_UPDATE); data << GetNewGUID() << uint8(1); pPlayer->GetSession()->SendPacket(&data); pPlayer->m_CurrentCharm = TO_UNIT(this); pPlayer->SetUInt64Value(UNIT_FIELD_CHARM, GetGUID()); SetUInt64Value(UNIT_FIELD_CHARMEDBY, pPlayer->GetGUID()); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED_CREATURE); if(!m_faction || m_faction->ID == 35 || m_faction->ID == 2105) { SetCharmTempVal(pPlayer->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE)); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, pPlayer->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE)); } if(vehicleproto && vehicleproto->healthfromdriver) { uint32 health = GetUInt32Value(UNIT_FIELD_HEALTH); uint32 maxhealth = GetUInt32Value(UNIT_FIELD_MAXHEALTH); uint32 healthdiff = maxhealth - health; SetUInt32Value(UNIT_FIELD_MAXHEALTH, (maxhealth+((pPlayer->GetTotalItemLevel())*(vehicleproto->healthunitfromitemlev)))); SetUInt32Value(UNIT_FIELD_HEALTH, (health+((pPlayer->GetTotalItemLevel())*(vehicleproto->healthunitfromitemlev))) - healthdiff); } SendSpells(GetEntry(), pPlayer); if(pPlayer->HasAura(62064)) { uint32 stack = pPlayer->FindActiveAura(62064)->stackSize; AddAura(new Aura(dbcSpell.LookupEntry(62064),-1,this,this)); FindActiveAura(62064)->ModStackSize(stack); } } } else { data.Initialize(SMSG_CLIENT_CONTROL_UPDATE); data << GetNewGUID() << uint8(0); pPlayer->GetSession()->SendPacket(&data); } data.Initialize(SMSG_PET_DISMISS_SOUND); data << uint32(m_vehicleSeats[slot]->m_enterUISoundID); data << pPlayer->GetPosition(); pPlayer->GetSession()->SendPacket(&data); ++m_ppassengerCount; } else { pPassenger->SetVehicle(this); if(vehicleproto != NULL) if(vehicleproto->seats[slot].accessoryentry == pPassenger->GetEntry()) if(vehicleproto->seats[slot].unselectableaccessory == true) pPassenger->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); else pPassenger->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION)); else pPassenger->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); pPassenger->SetPosition(GetPositionX()+v.x, GetPositionY()+v.y, GetPositionZ()+v.z, GetOrientation()); } SendHeartBeatMsg(false); if(IsFull()) RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); if(canFly()) EnableFlight(); _setFaction(); }
void Vehicle::RemovePassenger(Unit* pPassenger) { if(pPassenger == NULL) // We have enough problems that we need to do this :( return; uint8 slot = pPassenger->GetSeatID(); pPassenger->SetVehicle(NULL); pPassenger->SetSeatID(NULL); pPassenger->RemoveFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); if( pPassenger->IsPlayer() && TO_PLAYER(pPassenger)->m_MountSpellId != m_mountSpell ) pPassenger->RemoveAura(TO_PLAYER(pPassenger)->m_MountSpellId); if( m_mountSpell ) pPassenger->RemoveAura( m_mountSpell ); if( m_CastSpellOnMount ) pPassenger->RemoveAura( m_CastSpellOnMount ); WorldPacket data(SMSG_MONSTER_MOVE, 85); data << pPassenger->GetNewGUID(); // PlayerGUID data << uint8(0x40); // Unk - blizz uses 0x40 data << pPassenger->GetPosition(); // Player Position xyz data << getMSTime(); // Timestamp data << uint8(0x4); // Flags data << pPassenger->GetOrientation(); // Orientation data << uint32(MOVEFLAG_AIR_SUSPENSION); // MovementFlags data << uint32(0); // MovementTime data << uint32(1); // Pointcount data << GetPosition(); // Vehicle Position xyz SendMessageToSet(&data, false); pPassenger->movement_info.flags &= ~MOVEFLAG_TAXI; pPassenger->movement_info.transX = 0; pPassenger->movement_info.transY = 0; pPassenger->movement_info.transZ = 0; pPassenger->movement_info.transO = 0; pPassenger->movement_info.transTime = 0; pPassenger->movement_info.transSeat = 0; pPassenger->movement_info.transGuid = WoWGuid(uint64(NULL)); if(pPassenger->IsPlayer()) { Player* plr = TO_PLAYER(pPassenger); if(plr == GetControllingUnit()) { plr->m_CurrentCharm = NULL; data.Initialize(SMSG_CLIENT_CONTROL_UPDATE); data << GetNewGUID() << (uint8)0; plr->GetSession()->SendPacket(&data); } RemoveFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_PLAYER_CONTROLLED_CREATURE | UNIT_FLAG_PLAYER_CONTROLLED)); plr->SetPlayerStatus(TRANSFER_PENDING); // We get an ack later, if we don't set this now, we get disconnected. sEventMgr.AddEvent(plr, &Player::CheckPlayerStatus, (uint8)TRANSFER_PENDING, EVENT_PLAYER_CHECK_STATUS_Transfer, 5000, 0, 0); plr->m_sentTeleportPosition.ChangeCoords(GetPositionX(), GetPositionY(), GetPositionZ()); plr->SetPosition(GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); data.Initialize(MSG_MOVE_TELEPORT_ACK); data << plr->GetNewGUID(); data << plr->m_teleportAckCounter; plr->m_teleportAckCounter++; data << uint32(MOVEFLAG_FLYING); data << uint16(0x40); data << getMSTime(); data << GetPositionX(); data << GetPositionY(); data << GetPositionZ(); data << GetOrientation(); data << uint32(0); plr->GetSession()->SendPacket(&data); plr->SetUInt64Value( PLAYER_FARSIGHT, 0 ); data.Initialize(SMSG_PET_DISMISS_SOUND); data << uint32(m_vehicleSeats[slot]->m_exitUISoundID); data << plr->GetPosition(); plr->GetSession()->SendPacket(&data); data.Initialize(SMSG_PET_SPELLS); data << uint64(0); data << uint32(0); plr->GetSession()->SendPacket(&data); CreatureProtoVehicle* vehicleproto = CreatureProtoVehicleStorage.LookupEntry(GetEntry()); if(vehicleproto && vehicleproto->healthfromdriver) { if(slot == 0) { uint32 health = GetUInt32Value(UNIT_FIELD_HEALTH); uint32 maxhealth = GetUInt32Value(UNIT_FIELD_MAXHEALTH); uint32 protomaxhealth = GetProto()->MaxHealth; uint32 healthdiff = maxhealth - health; uint32 plritemlevel = plr->GetTotalItemLevel(); uint32 convrate = vehicleproto->healthunitfromitemlev; if(plritemlevel != 0 && convrate != 0) { uint32 healthloss = healthdiff+plritemlevel*convrate; SetUInt32Value(UNIT_FIELD_HEALTH, GetProto()->MaxHealth - healthloss); } else if(protomaxhealth > healthdiff) SetUInt32Value(UNIT_FIELD_HEALTH, protomaxhealth-healthdiff); else SetUInt32Value(UNIT_FIELD_HEALTH, 1); SetUInt32Value(UNIT_FIELD_MAXHEALTH, protomaxhealth); } } } if(slot == 0) { m_redirectSpellPackets = NULLPLR; CombatStatus.Vanished(); pPassenger->SetUInt64Value( UNIT_FIELD_CHARM, 0 ); SetUInt64Value(UNIT_FIELD_CHARMEDBY, 0); if(!m_faction || m_faction->ID == 35 || m_faction->ID == 2105) SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, GetCharmTempVal()); RemoveAura(62064); } SendHeartBeatMsg(false); m_passengers[slot] = NULL; pPassenger->m_TransporterGUID = NULL; // We need to null this out if(pPassenger->IsPlayer()) --m_ppassengerCount; //note: this is not blizz like we should despawn //and respawn at spawn point. //Well actually this is how blizz wanted it //but they couldnt get it to work xD bool haspassengers = false; for(uint8 i = 0; i < m_seatSlotMax; i++) { if(m_passengers[i] != NULL && m_passengers[i]->IsPlayer()) { haspassengers = true; break; } } if(!haspassengers && !GetVehicle()) // Passenger and accessory checks. { if( m_spawn == NULL ) SafeDelete(); } if(!IsFull()) SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); if(canFly()) DisableFlight(); _setFaction(); }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) { // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); bool delete_result = false; if(!result) { result = CharacterDatabase.PQuery("SELECT data FROM item_instance WHERE guid = '%u'", guid); delete_result = true; } if (!result) { sLog.outError("Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid)); return false; } Field *fields = result->Fetch(); if(!LoadValues(fields[0].GetString())) { sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.",guid); if (delete_result) delete result; return false; } bool need_save = false; // need explicit save data at load fixes // overwrite possible wrong/corrupted guid uint64 new_item_guid = MAKE_NEW_GUID(guid,0, HIGHGUID_ITEM); if(GetUInt64Value(OBJECT_FIELD_GUID) != new_item_guid) { SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid,0, HIGHGUID_ITEM)); need_save = true; } if (delete_result) delete result; 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); need_save = true; } // recalculate suffix factor if(GetItemRandomPropertyId() < 0) { if(UpdateItemSuffixFactor()) need_save = true; } // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED, false); need_save = 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); need_save = true; } // set correct owner if (owner_guid != 0 && GetOwnerGUID() != owner_guid) { SetOwnerGUID(owner_guid); need_save = true; } if (need_save) // normal item changed state set not work at loading { std::ostringstream ss; ss << "UPDATE item_instance SET data = '"; for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'"; CharacterDatabase.Execute( ss.str().c_str() ); } //Set extended cost for refundable item if(HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) { QueryResult *result_ext = CharacterDatabase.PQuery("SELECT ExtendedCost, price FROM item_instance WHERE guid = '%u'", guid); if(result_ext) { m_ExtendedCostId = result_ext->Fetch()[0].GetUInt32(); m_price = result_ext->Fetch()[1].GetUInt32(); delete result_ext; } } return true; }
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state) { Relocate(x,y,z,ang); SetMapId(map->GetId()); SetInstanceId(map->GetInstanceId()); if(!IsPositionValid()) { sLog.outError("ERROR: Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y); return false; } GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(name_id); if (!goinfo) { sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f) ang: %f rotation0: %f rotation1: %f rotation2: %f rotation3: %f",guidlow, name_id, map->GetId(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3); return false; } Object::_Create(guidlow, goinfo->id, HIGHGUID_GAMEOBJECT); m_DBTableGuid = guidlow; if (goinfo->type >= MAX_GAMEOBJECT_TYPE) { sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist GO type '%u' in `gameobject_template`. It's will crash client if created.",guidlow,name_id,goinfo->type); return false; } // SetUInt32Value(GAMEOBJECT_TIMESTAMP, (uint32)time(NULL)); SetFloatValue(GAMEOBJECT_POS_X, x); SetFloatValue(GAMEOBJECT_POS_Y, y); SetFloatValue(GAMEOBJECT_POS_Z, z); SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle SetFloatValue (GAMEOBJECT_ROTATION, rotation0); SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1); SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2); SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3); SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); m_flags = goinfo->flags; SetUInt32Value (OBJECT_FIELD_ENTRY, goinfo->id); SetUInt32Value (GAMEOBJECT_DISPLAYID, goinfo->displayId); SetUInt32Value (GAMEOBJECT_STATE, go_state); SetUInt32Value (GAMEOBJECT_TYPE_ID, goinfo->type); SetUInt32Value (GAMEOBJECT_ANIMPROGRESS, animprogress); // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER) m_charges = goinfo->spellcaster.charges; //Notify the map's instance data. //Only works if you create the object in it, not if it is moves to that map. //Normally non-players do not teleport to other maps. if(map && map->GetInstanceData()) { map->GetInstanceData()->OnObjectCreate(this); } return true; }
void Pet::Init() { SetUInt32Value(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + POWER_TYPE_FOCUS, 20); Creature::Init(); }
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; }
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; } } }
bool Creature::Load(CreatureSpawn *spawn, uint32 mode, MapInfo *info) { m_spawn = spawn; proto = CreatureProtoStorage.LookupEntry(spawn->entry); if(!proto) return false; creature_info = CreatureNameStorage.LookupEntry(spawn->entry); if(!creature_info) return false; spawnid = spawn->id; m_walkSpeed = m_base_walkSpeed = proto->walk_speed; //set speeds m_runSpeed = m_base_runSpeed = proto->run_speed; //set speeds m_flySpeed = proto->fly_speed; //Set fields SetUInt32Value(OBJECT_FIELD_ENTRY,proto->Id); SetFloatValue(OBJECT_FIELD_SCALE_X,proto->Scale); //SetUInt32Value(UNIT_FIELD_HEALTH, (mode ? long2int32(proto->Health * 1.5) : proto->Health)); //SetUInt32Value(UNIT_FIELD_BASE_HEALTH, (mode ? long2int32(proto->Health * 1.5) : proto->Health)); //SetUInt32Value(UNIT_FIELD_MAXHEALTH, (mode ? long2int32(proto->Health * 1.5) : proto->Health)); uint32 health = proto->MinHealth + RandomUInt(proto->MaxHealth - proto->MinHealth); if(mode) health = long2int32(double(health) * 1.5); SetUInt32Value(UNIT_FIELD_HEALTH, health); SetUInt32Value(UNIT_FIELD_MAXHEALTH, health); SetUInt32Value(UNIT_FIELD_BASE_HEALTH, health); SetUInt32Value(UNIT_FIELD_POWER1,proto->Mana); SetUInt32Value(UNIT_FIELD_MAXPOWER1,proto->Mana); SetUInt32Value(UNIT_FIELD_BASE_MANA,proto->Mana); // Whee, thank you blizz, I love patch 2.2! Later on, we can randomize male/female mobs! xD // Determine gender (for voices) //if(spawn->displayid != creature_info->Male_DisplayID) // setGender(1); // Female uint32 model; uint32 gender = creature_info->GenerateModelId(&model); setGender(gender); SetUInt32Value(UNIT_FIELD_DISPLAYID,model); SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID,model); SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,proto->MountedDisplayID); //SetUInt32Value(UNIT_FIELD_LEVEL, (mode ? proto->Level + (info ? info->lvl_mod_a : 0) : proto->Level)); SetUInt32Value(UNIT_FIELD_LEVEL, proto->MinLevel + (RandomUInt(proto->MaxLevel - proto->MinLevel))); if(mode && info) ModUnsigned32Value(UNIT_FIELD_LEVEL, info->lvl_mod_a); for(uint32 i = 0; i < 7; ++i) SetUInt32Value(UNIT_FIELD_RESISTANCES+i,proto->Resistances[i]); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME,proto->AttackTime); SetFloatValue(UNIT_FIELD_MINDAMAGE, (mode ? proto->MinDamage * 1.5f : proto->MinDamage)); SetFloatValue(UNIT_FIELD_MAXDAMAGE, (mode ? proto->MaxDamage * 1.5f : proto->MaxDamage)); SetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME,proto->RangedAttackTime); SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,proto->RangedMinDamage); SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,proto->RangedMaxDamage); SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, proto->Item1SlotDisplay); SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, proto->Item2SlotDisplay); SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, proto->Item3SlotDisplay); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, proto->Item1Info1); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_01, proto->Item1Info2); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_02, proto->Item2Info1); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_03, proto->Item2Info2); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_04, proto->Item3Info1); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_05, proto->Item3Info2); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, spawn->factionid); SetUInt32Value(UNIT_FIELD_FLAGS, spawn->flags); SetUInt32Value(UNIT_NPC_EMOTESTATE, spawn->emote_state); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, proto->BoundingRadius); SetFloatValue(UNIT_FIELD_COMBATREACH, proto->CombatReach); original_emotestate = spawn->emote_state; // set position m_position.ChangeCoords( spawn->x, spawn->y, spawn->z, spawn->o ); m_spawnLocation.ChangeCoords(spawn->x, spawn->y, spawn->z, spawn->o); m_aiInterface->setMoveType(spawn->movetype); m_aiInterface->m_waypoints = objmgr.GetWayPointMap(spawn->id); m_faction = dbcFactionTemplate.LookupEntry(spawn->factionid); if(m_faction) { m_factionDBC = dbcFaction.LookupEntry(m_faction->Faction); // not a neutral creature if(!(m_factionDBC->RepListId == -1 && m_faction->HostileMask == 0 && m_faction->FriendlyMask == 0)) { GetAIInterface()->m_canCallForHelp = true; } } //SETUP NPC FLAGS SetUInt32Value(UNIT_NPC_FLAGS,proto->NPCFLags); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ) ) m_SellItems = objmgr.GetVendorList(GetEntry()); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER ) ) _LoadQuests(); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TAXIVENDOR) ) m_TaxiNode = sTaxiMgr.GetNearestTaxiNode( m_position.x, m_position.y, m_position.z, GetMapId() ); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER) || HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER_PROF)) mTrainer = objmgr.GetTrainer(GetEntry()); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER ) ) auctionHouse = sAuctionMgr.GetAuctionHouse(GetEntry()); //NPC FLAGS m_aiInterface->m_waypoints=objmgr.GetWayPointMap(spawn->id); //load resistances for(uint32 x=0;x<7;x++) BaseResistance[x]=GetUInt32Value(UNIT_FIELD_RESISTANCES+x); for(uint32 x=0;x<5;x++) BaseStats[x]=GetUInt32Value(UNIT_FIELD_STAT0+x); BaseDamage[0]=GetFloatValue(UNIT_FIELD_MINDAMAGE); BaseDamage[1]=GetFloatValue(UNIT_FIELD_MAXDAMAGE); BaseOffhandDamage[0]=GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); BaseOffhandDamage[1]=GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); BaseRangedDamage[0]=GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); BaseRangedDamage[1]=GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); BaseAttackType=proto->AttackType; SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // better set this one SetUInt32Value(UNIT_FIELD_BYTES_0, spawn->bytes); SetUInt32Value(UNIT_FIELD_BYTES_2, spawn->bytes2); ////////////AI // kek for(list<AI_Spell*>::iterator itr = proto->spells.begin(); itr != proto->spells.end(); ++itr) { m_aiInterface->addSpellToList(*itr); } //m_aiInterface->m_canCallForHelp = proto->m_canCallForHelp; //m_aiInterface->m_CallForHelpHealth = proto->m_callForHelpHealth; m_aiInterface->m_canFlee = proto->m_canFlee; m_aiInterface->m_FleeHealth = proto->m_fleeHealth; m_aiInterface->m_FleeDuration = proto->m_fleeDuration; //these fields are always 0 in db GetAIInterface()->setMoveType(0); GetAIInterface()->setMoveRunFlag(0); // load formation data if( spawn->form != NULL ) { m_aiInterface->m_formationLinkSqlId = spawn->form->fol; m_aiInterface->m_formationFollowDistance = spawn->form->dist; m_aiInterface->m_formationFollowAngle = spawn->form->ang; } else { m_aiInterface->m_formationLinkSqlId = 0; m_aiInterface->m_formationFollowDistance = 0; m_aiInterface->m_formationFollowAngle = 0; } //////////////AI myFamily = dbcCreatureFamily.LookupEntry(creature_info->Family); // PLACE FOR DIRTY FIX BASTARDS // HACK! set call for help on civ health @ 100% if(creature_info->Civilian >= 1) m_aiInterface->m_CallForHelpHealth = 100; //HACK! if(m_uint32Values[UNIT_FIELD_DISPLAYID] == 17743 || m_uint32Values[UNIT_FIELD_DISPLAYID] == 20242 || m_uint32Values[UNIT_FIELD_DISPLAYID] == 15435 || (creature_info->Family == UNIT_TYPE_MISC)) { m_useAI = false; } /* more hacks! */ if(proto->Mana != 0) SetPowerType(POWER_TYPE_MANA); else SetPowerType(0); has_combat_text = objmgr.HasMonsterSay(GetEntry(), MONSTER_SAY_EVENT_ENTER_COMBAT); has_waypoint_text = objmgr.HasMonsterSay(GetEntry(), MONSTER_SAY_EVENT_RANDOM_WAYPOINT); m_aiInterface->m_isGuard = isGuard(GetEntry()); m_aiInterface->getMoveFlags(); /* creature death state */ if(proto->death_state == 1) { uint32 newhealth = m_uint32Values[UNIT_FIELD_HEALTH] / 100; if(!newhealth) newhealth = 1; SetUInt32Value(UNIT_FIELD_HEALTH, 1); m_limbostate = true; bInvincible = true; SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DEAD); } m_invisFlag = proto->invisibility_type; if( spawn->stand_state ) SetStandState( (uint8)spawn->stand_state ); return true; }
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state) { Relocate(x,y,z,ang); SetMapId(map->GetId()); SetInstanceId(map->GetInstanceId()); if(!IsPositionValid()) { sLog.outError("ERROR: Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y); return false; } GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(name_id); if (!goinfo) { sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f) ang: %f rotation0: %f rotation1: %f rotation2: %f rotation3: %f",guidlow, name_id, map->GetId(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3); return false; } Object::_Create(guidlow, goinfo->id, HIGHGUID_GAMEOBJECT); m_goInfo = goinfo; if (goinfo->type >= MAX_GAMEOBJECT_TYPE) { sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist GO type '%u' in `gameobject_template`. It's will crash client if created.",guidlow,name_id,goinfo->type); return false; } SetFloatValue(GAMEOBJECT_POS_X, x); SetFloatValue(GAMEOBJECT_POS_Y, y); SetFloatValue(GAMEOBJECT_POS_Z, z); SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle int64 rotation = 0; float f_rot1 = sin(ang / 2.0f); int64 i_rot1 = f_rot1 / atan(pow(2.0f, -20.0f)); rotation |= (i_rot1 << 43 >> 43) & 0x00000000001FFFFF; //float f_rot2 = sin(0.0f / 2.0f); //int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f)); //rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000; //float f_rot3 = sin(0.0f / 2.0f); //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f)); //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000; SetUInt64Value(GAMEOBJECT_ROTATION, rotation); SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0); SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1); SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2); SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3); SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetEntry(goinfo->id); SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); SetGoState(go_state); SetGoType(GameobjectTypes(goinfo->type)); SetGoAnimProgress(animprogress); // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER) m_charges = goinfo->spellcaster.charges; //Notify the map's instance data. //Only works if you create the object in it, not if it is moves to that map. //Normally non-players do not teleport to other maps. if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) { ((InstanceMap*)map)->GetInstanceData()->OnObjectCreate(this); } return true; }
void Item::LoadFromDB(Field* fields, Player* plr, bool light ) { int32 count; uint32 itemid = fields[2].GetUInt32(), random_prop = fields[9].GetUInt32(), random_suffix = fields[10].GetUInt32(); m_itemProto = ItemPrototypeStorage.LookupEntry( itemid ); ASSERT( m_itemProto ); if(m_itemProto->LockId > 1) locked = true; else locked = false; SetUInt32Value( OBJECT_FIELD_ENTRY, itemid ); m_owner = plr; wrapped_item_id=fields[3].GetUInt32(); m_uint32Values[ITEM_FIELD_GIFTCREATOR] = fields[4].GetUInt32(); m_uint32Values[ITEM_FIELD_CREATOR] = fields[5].GetUInt32(); count = fields[6].GetUInt32(); if(m_itemProto->MaxCount > 0 && count > m_itemProto->MaxCount) count = m_itemProto->MaxCount; SetUInt32Value( ITEM_FIELD_STACK_COUNT, count); // Again another for that did not indent to make it do anything for more than // one iteration x == 0 was the only one executed for( uint32 x = 0; x < 5; x++ ) { if( m_itemProto->Spells[x].Id ) { SetUInt32Value( ITEM_FIELD_SPELL_CHARGES + x , fields[7].GetUInt32() ); break; } } SetUInt32Value( ITEM_FIELD_FLAGS, fields[8].GetUInt32() ); Bind(ITEM_BIND_ON_PICKUP); // Check if we need to bind our shit. if( random_prop ) SetRandomProperty( random_prop ); else if( random_suffix ) SetRandomSuffix( random_suffix ); SetTextID( fields[11].GetUInt32() ); SetUInt32Value( ITEM_FIELD_MAXDURABILITY, m_itemProto->MaxDurability ); SetUInt32Value( ITEM_FIELD_DURABILITY, fields[12].GetUInt32() ); if( light ) return; string enchant_field = fields[15].GetString(); vector< string > enchants = StrSplit( enchant_field, ";" ); uint32 enchant_id; EnchantEntry* entry; uint32 time_left; uint32 enchslot; uint32 dummy = 0; for( vector<string>::iterator itr = enchants.begin(); itr != enchants.end(); itr++ ) { if( sscanf( (*itr).c_str(), "%u,%u,%u,%u", (unsigned int*)&enchant_id, (unsigned int*)&time_left, (unsigned int*)&enchslot, (unsigned int*)&dummy) > 3 ) { entry = dbcEnchant.LookupEntry( enchant_id ); if( entry && entry->Id == enchant_id ) { AddEnchantment( entry, time_left, ( time_left == 0 ), false, false, enchslot, 0, ((dummy > 0) ? true : false) ); //(enchslot != 2) ? false : true, false); } } } string gem_field = fields[16].GetString(); for( uint8 k = 0; k < 3; k++ ) sscanf( gem_field.c_str(), GemReadFormat[k], &Gems[k]); ApplyRandomProperties( false ); Charter* charter = guildmgr.GetCharterByItemGuid(GetLowGUID()); if(charter != NULL) { SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetID()); // Charter stuff if(m_uint32Values[OBJECT_FIELD_ENTRY] == ITEM_ENTRY_GUILD_CHARTER) { SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_playerInfo->charterId[CHARTER_TYPE_GUILD] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT_1_1, plr->m_playerInfo->charterId[CHARTER_TYPE_GUILD] ); } if( m_uint32Values[OBJECT_FIELD_ENTRY] == ARENA_TEAM_CHARTER_2v2 ) { SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_playerInfo->charterId[CHARTER_TYPE_ARENA_2V2] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT_1_1, plr->m_playerInfo->charterId[CHARTER_TYPE_ARENA_2V2] ); } if( m_uint32Values[OBJECT_FIELD_ENTRY] == ARENA_TEAM_CHARTER_3v3 ) { SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_playerInfo->charterId[CHARTER_TYPE_ARENA_3V3] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT_1_1, plr->m_playerInfo->charterId[CHARTER_TYPE_ARENA_3V3] ); } if( m_uint32Values[OBJECT_FIELD_ENTRY] == ARENA_TEAM_CHARTER_5v5 ) { SetUInt32Value( ITEM_FIELD_STACK_COUNT, 1 ); SetUInt32Value( ITEM_FIELD_PROPERTY_SEED, 57813883 ); if( plr->m_playerInfo->charterId[CHARTER_TYPE_ARENA_5V5] ) SetUInt32Value( ITEM_FIELD_ENCHANTMENT_1_1, plr->m_playerInfo->charterId[CHARTER_TYPE_ARENA_5V5] ); } } }
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(guidLow, 0, HIGHGUID_ITEM); if (!LoadValues(fields[0].GetString())) { sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.", guidLow); return false; } SetText(fields[1].GetCppString()); bool need_save = 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); need_save = 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); need_save = true; } // recalculate suffix factor if (GetItemRandomPropertyId() < 0) { if (UpdateItemSuffixFactor()) need_save = true; } // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_BINDED, false); need_save = 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); need_save = true; } // set correct owner if (ownerGuid && GetOwnerGuid() != ownerGuid) { SetOwnerGuid(ownerGuid); need_save = 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); need_save = true; static SqlStatementID delGifts ; // also cleanup for sure gift table SqlStatement stmt = CharacterDatabase.CreateStatement(delGifts, "DELETE FROM character_gifts WHERE item_guid = ?"); stmt.PExecute(GetGUIDLow()); } } if (need_save) // normal item changed state set not work at loading { static SqlStatementID updItem ; SqlStatement stmt = CharacterDatabase.CreateStatement(updItem, "UPDATE item_instance SET data = ?, owner_guid = ? WHERE guid = ?"); std::ostringstream ss; for (uint16 i = 0; i < m_valuesCount; ++i) ss << GetUInt32Value(i) << " "; stmt.addString(ss); stmt.addUInt32(GetOwnerGuid().GetCounter()); stmt.addUInt32(guidLow); stmt.Execute(); } return true; }
// TODO: Move stat mods code to pet passive auras bool Guardian::InitStatsForLevel(uint8 petlevel) { CreatureTemplate const* cinfo = GetCreatureInfo(); ASSERT(cinfo); SetLevel(petlevel); //Determine pet type PetType petType = MAX_PET_TYPE; if (isPet() && m_owner->GetTypeId() == TYPEID_PLAYER) { if ((m_owner->getClass() == CLASS_WARLOCK) || (m_owner->getClass() == CLASS_SHAMAN) // Fire Elemental || (m_owner->getClass() == CLASS_DEATH_KNIGHT)) // Risen Ghoul petType = SUMMON_PET; else if (m_owner->getClass() == CLASS_HUNTER) { petType = HUNTER_PET; m_unitTypeMask |= UNIT_MASK_HUNTER_PET; } else sLog->outError("Unknown type pet %u is summoned by player class %u", GetEntry(), m_owner->getClass()); } uint32 creature_ID = (petType == HUNTER_PET) ? 1 : cinfo->Entry; SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel*50)); SetAttackTime(BASE_ATTACK, BASE_ATTACK_TIME); SetAttackTime(OFF_ATTACK, BASE_ATTACK_TIME); SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); //scale CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); if (cFamily && cFamily->minScale > 0.0f && petType == HUNTER_PET) { float scale; if (getLevel() >= cFamily->maxScaleLevel) scale = cFamily->maxScale; else if (getLevel() <= cFamily->minScaleLevel) scale = cFamily->minScale; else scale = cFamily->minScale + float(getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale); SetFloatValue(OBJECT_FIELD_SCALE_X, scale); } // Resistance for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(cinfo->resistance[i])); //health, mana, armor and resistance PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(creature_ID, petlevel); if (pInfo) // exist in DB { SetCreateHealth(pInfo->health); if (petType != HUNTER_PET) //hunter pet use focus SetCreateMana(pInfo->mana); if (pInfo->armor > 0) SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor)); for (uint8 stat = 0; stat < MAX_STATS; ++stat) SetCreateStat(Stats(stat), float(pInfo->stats[stat])); } else // not exist in DB, use some default fake data { // remove elite bonuses included in DB values CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class); SetCreateHealth(stats->BaseHealth[cinfo->expansion]); SetCreateMana(stats->BaseMana); SetCreateStat(STAT_STRENGTH, 22); SetCreateStat(STAT_AGILITY, 22); SetCreateStat(STAT_STAMINA, 25); SetCreateStat(STAT_INTELLECT, 28); SetCreateStat(STAT_SPIRIT, 27); } SetBonusDamage(0); switch (petType) { case SUMMON_PET: { //the damage bonus used for pets is either fire or shadow damage, whatever is higher uint32 fire = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE); uint32 shadow = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW); uint32 val = (fire > shadow) ? fire : shadow; SetBonusDamage(int32 (val * 0.15f)); //bonusAP += val * 0.57; SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower)); break; } case HUNTER_PET: { SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32(sObjectMgr->GetXPForLevel(petlevel)*PET_XP_FACTOR)); //these formula may not be correct; however, it is designed to be close to what it should be //this makes dps 0.5 of pets level SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); //damage range is then petlevel / 2 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); //damage is increased afterwards as strength and pet scaling modify attack power break; } default: { switch (GetEntry()) { case 510: // mage Water Elemental { SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f)); break; } case 1964: //force of nature { if (!pInfo) SetCreateHealth(30 + 30*petlevel); float bonusDmg = m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_NATURE) * 0.15f; SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2) + bonusDmg)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2) + bonusDmg)); break; } case 15352: //earth elemental 36213 { if (!pInfo) SetCreateHealth(100 + 120*petlevel); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); break; } case 15438: //fire elemental { if (!pInfo) { SetCreateHealth(40*petlevel); SetCreateMana(28 + 10*petlevel); } SetBonusDamage(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel)); break; } case 19668: // Shadowfiend { if (!pInfo) { SetCreateMana(28 + 10*petlevel); SetCreateHealth(28 + 30*petlevel); } int32 bonus_dmg = (int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_SHADOW)* 0.3f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + bonus_dmg)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + bonus_dmg)); break; } case 19833: //Snake Trap - Venomous Snake { SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel / 2) - 25)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel / 2) - 18)); break; } case 19921: //Snake Trap - Viper { SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel / 2 - 10)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel / 2)); break; } case 29264: // Feral Spirit { if (!pInfo) SetCreateHealth(30*petlevel); float dmg_multiplier = 0.3f; if (m_owner->GetAuraEffect(63271, 0)) // Glyph of Feral Spirit dmg_multiplier = 0.6f; SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier)); // 14AP == 1dps, wolf's strike speed == 2s so dmg = basedmg + AP / 14 * 2 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + (m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier * 2 / 14))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + (m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier * 2 / 14))); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(m_owner->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor) SetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(m_owner->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina) if (!HasAura(58877))//prevent apply twice for the 2 wolves AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done. break; } case 31216: // Mirror Image { SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f)); SetDisplayId(m_owner->GetDisplayId()); if (!pInfo) { SetCreateMana(28 + 30*petlevel); SetCreateHealth(28 + 10*petlevel); } break; } case 27829: // Ebon Gargoyle { if (!pInfo) { SetCreateMana(28 + 10*petlevel); SetCreateHealth(28 + 30*petlevel); } SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); break; } } break; } } UpdateAllStats(); SetFullHealth(); SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); return true; }
void Player::UpdateShieldBlockValue() { SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue()); }
bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool current) { m_loading = true; uint32 ownerid = owner->GetGUIDLow(); QueryResult result; if (petnumber) // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND id = '%u'", ownerid, petnumber); else if (current) // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND slot = '%u'", ownerid, PET_SAVE_AS_CURRENT); else if (petentry) // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ", ownerid, petentry, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); else // any current or other non-stabled pet (for hunter "call pet") // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ", ownerid, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); if (!result) { m_loading = false; return false; } Field* fields = result->Fetch(); // update for case of current pet "slot = 0" petentry = fields[1].GetUInt32(); if (!petentry) return false; uint32 summon_spell_id = fields[15].GetUInt32(); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summon_spell_id); bool is_temporary_summoned = spellInfo && spellInfo->GetDuration() > 0; // check temporary summoned pets like mage water elemental if (current && is_temporary_summoned) return false; PetType pet_type = PetType(fields[16].GetUInt8()); if (pet_type == HUNTER_PET) { CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petentry); if (!creatureInfo || !creatureInfo->isTameable(owner->CanTameExoticPets())) return false; } uint32 pet_number = fields[0].GetUInt32(); if (current && owner->IsPetNeedBeTemporaryUnsummoned()) { owner->SetTemporaryUnsummonedPetNumber(pet_number); return false; } Map* map = owner->GetMap(); uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_PET); if (!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number)) return false; float px, py, pz; owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle()); Relocate(px, py, pz, owner->GetOrientation()); if (!IsPositionValid()) { sLog->outError("Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); return false; } setPetType(pet_type); setFaction(owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id); CreatureTemplate const* cinfo = GetCreatureInfo(); if (cinfo->type == CREATURE_TYPE_CRITTER) { map->AddToMap(this->ToCreature()); return true; } m_charmInfo->SetPetNumber(pet_number, IsPermanentPetFor(owner)); SetDisplayId(fields[3].GetUInt32()); SetNativeDisplayId(fields[3].GetUInt32()); uint32 petlevel = fields[4].GetUInt16(); SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); SetName(fields[8].GetString()); switch (getPetType()) { case SUMMON_PET: petlevel = owner->getLevel(); SetUInt32Value(UNIT_FIELD_BYTES_0, 0x800); // class = mage SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet dismiss, cancel) break; case HUNTER_PET: SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); // class = warrior, gender = none, power = focus SetSheath(SHEATH_STATE_MELEE); SetByteFlag(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_CAN_BE_ABANDONED : UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet abandon, cancel) SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); SetPower(POWER_HAPPINESS, fields[12].GetUInt32()); setPowerType(POWER_FOCUS); break; default: if (!IsPetGhoul()) sLog->outError("Pet have incorrect type (%u) for pet loading.", getPetType()); break; } SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped here SetCreatorGUID(owner->GetGUID()); InitStatsForLevel(petlevel); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32()); SynchronizeLevelWithOwner(); SetReactState(ReactStates(fields[6].GetUInt8())); SetCanModifyStats(true); if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); else { uint32 savedhealth = fields[10].GetUInt32(); uint32 savedmana = fields[11].GetUInt32(); if (!savedhealth && getPetType() == HUNTER_PET) setDeathState(JUST_DIED); else { SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); } } // set current pet as current // 0=current // 1..MAX_PET_STABLES in stable slot // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) if (fields[7].GetUInt8()) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber()); trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'", PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber()); CharacterDatabase.CommitTransaction(trans); } // Send fake summon spell cast - this is needed for correct cooldown application for spells // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside // TODO: pets should be summoned from real cast instead of just faking it? if (summon_spell_id) { WorldPacket data(SMSG_SPELL_GO, (8+8+4+4+2)); data.append(owner->GetPackGUID()); data.append(owner->GetPackGUID()); data << uint8(0); data << uint32(summon_spell_id); data << uint32(256); // CAST_FLAG_UNKNOWN3 data << uint32(0); owner->SendMessageToSet(&data, true); } owner->SetMinion(this, true); map->AddToMap(this->ToCreature()); InitTalentForLevel(); // set original talents points before spell loading uint32 timediff = uint32(time(NULL) - fields[14].GetUInt32()); _LoadAuras(timediff); // load action bar, if data broken will fill later by default spells. if (!is_temporary_summoned) { m_charmInfo->LoadPetActionBar(fields[13].GetString()); _LoadSpells(); InitTalentForLevel(); // re-init to check talent count _LoadSpellCooldowns(); LearnPetPassives(); InitLevelupSpellsForLevel(); CastPetAuras(current); } CleanupActionBar(); // remove unknown spells from action bar after load sLog->outDebug(LOG_FILTER_PETS, "New Pet has guid %u", GetGUIDLow()); owner->PetSpellInitialize(); if (owner->GetGroup()) owner->SetGroupUpdateFlag(GROUP_UPDATE_PET); owner->SendTalentsInfoData(true); if (getPetType() == HUNTER_PET) { result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", owner->GetGUIDLow(), GetCharmInfo()->GetPetNumber()); if (result) { delete m_declinedname; m_declinedname = new DeclinedName; Field* fields2 = result->Fetch(); for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { m_declinedname->name[i] = fields2[i].GetString(); } } } //set last used pet number (for use in BG's) if (owner->GetTypeId() == TYPEID_PLAYER && isControlled() && !isTemporarySummoned() && (getPetType() == SUMMON_PET || getPetType() == HUNTER_PET)) owner->ToPlayer()->SetLastPetNumber(pet_number); m_loading = false; return true; }
//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() ); }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); // Set entry, MUST be before proto check SetEntry(entry); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); ItemPrototype const* proto = GetProto(); if (!proto) return false; // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid != 0) SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes SetUInt64Value(ITEM_FIELD_CREATOR, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); SetUInt64Value(ITEM_FIELD_GIFTCREATOR, MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER)); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); need_save = true; } Tokens tokens(fields[4].GetString(), ' ', MAX_ITEM_PROTO_SPELLS); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i])); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, false); need_save = true; } std::string enchants = fields[6].GetString(); //_LoadIntoDataField(enchants.c_str(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); { // NOTE: // in the recent update of reforge system, definition of EnchantmentSlot has been changed, // and MAX_ENCHANTMENT_SLOT has been changed from 13 to 14, // which makes enchantments column of item_instance table incompatible with previous version. // in this case we will load only first 9 enchantment slots (0-8, for permanent, temporary, sockets, bonus, prismatic and reforge) // and ignore the remaining ones (9-13, for random properties). // which means item random properties will be lost after this update. // after player logging in and saving the inventory, enchantments column will be properly updated. uint32 count = MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET; Tokens tokens(enchants, ' ', count); if (tokens.size() < MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET) count = REFORGE_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET; for (uint32 index = 0; index < count; ++index) m_uint32Values[ITEM_FIELD_ENCHANTMENT_1_1 + index] = index < tokens.size() ? atol(tokens[index]) : 0; } SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt16(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (durability > proto->MaxDurability) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetString()); if (need_save) // normal item changed state set not work at loading { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ITEM_INSTANCE_ON_LOAD); stmt->setUInt32(0, GetUInt32Value(ITEM_FIELD_DURATION)); stmt->setUInt32(1, GetUInt32Value(ITEM_FIELD_FLAGS)); stmt->setUInt32(2, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(3, guid); CharacterDatabase.Execute(stmt); } return true; }
bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fields, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HighGuid::Item); // Set entry, MUST be before proto check SetEntry(entry); SetObjectScale(1.0f); ItemTemplate const* proto = GetTemplate(); if (!proto) return false; // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid) SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes SetGuidValue(ITEM_FIELD_CREATOR, ObjectGuid(HighGuid::Player, fields[0].GetUInt32())); SetGuidValue(ITEM_FIELD_GIFTCREATOR, ObjectGuid(HighGuid::Player, fields[1].GetUInt32())); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); need_save = true; } Tokenizer tokens(fields[4].GetString(), ' ', MAX_ITEM_PROTO_SPELLS); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i])); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND, false); need_save = true; } _LoadIntoDataField(fields[6].GetString(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt16(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); // do not overwrite durability for wrapped items if (durability > proto->MaxDurability && !HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetString()); if (need_save) // normal item changed state set not work at loading { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD); stmt->setUInt32(0, GetUInt32Value(ITEM_FIELD_DURATION)); stmt->setUInt32(1, GetUInt32Value(ITEM_FIELD_FLAGS)); stmt->setUInt32(2, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(3, guid); CharacterDatabase.Execute(stmt); } return true; }
void GameObject::Update(uint32 p_time) { if (GUID_HIPART(GetGUID()) == HIGHGUID_TRANSPORT) { //((Transport*)this)->Update(p_time); return; } switch (m_lootState) { case GO_NOT_READY: if (GetGoType()==17) { // 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) { SetUInt32Value(GAMEOBJECT_STATE, 0); SetUInt32Value(GAMEOBJECT_FLAGS, 32); UpdateData udata; WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster)); udata.BuildPacket(&packet); ((Player*)caster)->GetSession()->SendPacket(&packet); WorldPacket data; data.Initialize(SMSG_GAMEOBJECT_CUSTOM_ANIM); data << GetGUID(); data << (uint32)(0); ((Player*)caster)->SendMessageToSet(&data,true); } m_lootState = GO_CLOSED; // can be succesfully open with some chance } return; } m_lootState = GO_CLOSED; // for not bobber is same as GO_CLOSED // NO BREAK case GO_CLOSED: if (m_respawnTime > 0) // timer on { if (m_respawnTime <= time(NULL)) // timer expired { m_respawnTime = 0; m_SkillupList.clear(); switch (GetGoType()) { case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now { Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { if(caster->m_currentSpell) { caster->m_currentSpell->SendChannelUpdate(0); caster->m_currentSpell->finish(false); } WorldPacket data; data.Initialize(SMSG_FISH_NOT_HOOKED); ((Player*)caster)->GetSession()->SendPacket(&data); } m_lootState = GO_LOOTED; // can be delete return; } case GAMEOBJECT_TYPE_DOOR: SetUInt32Value (GAMEOBJECT_FLAGS, m_flags); SetUInt32Value (GAMEOBJECT_STATE, 1); break; case GAMEOBJECT_TYPE_TRAP: break; default: if(GetOwnerGUID()) // despawn timer { m_respawnTime = 0; Delete(); return; } // respawn timer MapManager::Instance().GetMap(GetMapId(), this)->Add(this); break; } } } break; case GO_OPEN: break; case GO_LOOTED: if(GetOwnerGUID()) { m_respawnTime = 0; Delete(); return; } loot.clear(); SetLootState(GO_CLOSED); SendDestroyObject(GetGUID()); m_respawnTime = time(NULL) + m_respawnDelayTime; // if option not set then object will be ssaved at grif unload if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) SaveRespawnTime(); break; } SpellEntry const *createSpell = m_spellId ? sSpellStore.LookupEntry(m_spellId) : NULL; if (!createSpell) return; int i; for (i = 0; i < 3; i++) if (createSpell->Effect[i] == SPELL_EFFECT_SUMMON_OBJECT_SLOT1) break; if (i<3) { // traps CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); Cell cell = RedZone::GetZone(p); cell.data.Part.reserved = ALL_DISTRICT; Unit* owner = GetOwner(); if (!owner) { m_respawnTime = 0; // to prevent save respawn timer Delete(); return; } Unit* ok = NULL; // pointer to appropriate target if found any float radius = GetRadius(sSpellRadiusStore.LookupEntry(createSpell->EffectRadiusIndex[i])); MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius); MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(ok, u_check); CellLock<GridReadGuard> cell_lock(cell, p); // search unfriedly creature { TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); } // or unfriendly player/pet if(!ok) { TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); } if (ok) { owner->CastSpell(ok, GetGOInfo()->sound3, true); m_respawnTime = 0; // to prevent save respawn timer Delete(); } } if (m_usetimes >= 5) { m_respawnTime = 0; // to prevent save respawn timer Delete(); } }