void Init(Object* obj) { if(obj == NULL) { mDeleted = true; return; } mItemGUID = TO_ITEM(obj)->GetGUID(); if(mProcPerMinute) mProcChance = TO_ITEM(obj)->GetProto()->Delay * mProcPerMinute / 600; }
Item* Container::SafeRemoveAndRetreiveItemFromSlot(int16 slot, bool destroy) { if (slot < 0 || (uint32)slot >= GetProto()->ContainerSlots) return NULLITEM; Item* pItem = m_Slot[slot]; if (pItem == NULL || pItem == TO_ITEM(this)) return NULLITEM; m_Slot[slot] = NULLITEM; if( pItem->GetOwner() == m_owner ) { SetUInt64Value(CONTAINER_FIELD_SLOT_1 + slot*2, 0 ); pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); if(destroy) { if(pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); } } else pItem = NULLITEM; return pItem; }
void Init(Object* obj) { if(obj == NULL) { mDeleted = true; //initializing anyway all fields. mItemGUID = 0; damage = 0; return; } mItemGUID = obj->GetGUID(); damage = 0; uint32 wp_speed; Item* item = TO_ITEM(obj); EnchantmentInstance* enchant = item->GetEnchantment(TEMP_ENCHANTMENT_SLOT); if(enchant != NULL) { SpellEntry* sp = dbcSpell.LookupEntryForced(enchant->Enchantment->spell[0]); if(sp != NULL && sp->NameHash == SPELL_HASH_FLAMETONGUE_WEAPON__PASSIVE_) { wp_speed = item->GetProto()->Delay; damage = (sp->EffectBasePoints[0] + 1) * wp_speed / 100000; } } }
int LuaAura_GetCaster(lua_State * L, Aura * aura) { TEST_AURA_RET_NULL(); Object* caster = aura->GetCaster(); if(caster == NULL) RET_NIL(true); if (caster->IsUnit()) //unit caster { Lunar<Unit>::push(L, TO_UNIT(caster)); return 1; } else if (caster->IsGameObject()) //gameobject { Lunar<GameObject>::push(L, TO_GAMEOBJECT(caster)); return 1; } else if (caster->IsItem()) //item { Lunar<Item>::push(L, TO_ITEM(caster)); return 1; } RET_NIL(true); }
void LuaGossip::OnHello(Object* pObject, Player* Plr) { GET_LOCK; if(pObject->GetTypeId() == TYPEID_UNIT) { if(m_unit_gossip_binding == NULL) { RELEASE_LOCK; return; } lua_engine::BeginLuaFunctionCall(m_unit_gossip_binding->refs[GOSSIP_EVENT_ON_TALK]); push_creature(TO_CREATURE(pObject)); push_int(GOSSIP_EVENT_ON_TALK); push_player(Plr); lua_engine::ExecuteLuaFunction(3); } else if(pObject->GetTypeId() == TYPEID_ITEM) { if(m_item_gossip_binding == NULL) { RELEASE_LOCK; return; } lua_engine::BeginLuaFunctionCall(m_item_gossip_binding->refs[GOSSIP_EVENT_ON_TALK]); push_item(TO_ITEM(pObject)); push_int(GOSSIP_EVENT_ON_TALK); push_player(Plr); lua_engine::ExecuteLuaFunction(3); } else if(pObject->GetTypeId() == TYPEID_GAMEOBJECT) { if(m_go_gossip_binding == NULL) { RELEASE_LOCK; return; } lua_engine::BeginLuaFunctionCall(m_go_gossip_binding->refs[GOSSIP_EVENT_ON_TALK]); push_go(TO_GAMEOBJECT(pObject)); push_int(GOSSIP_EVENT_ON_TALK); push_player(Plr); lua_engine::ExecuteLuaFunction(3); } RELEASE_LOCK }
void Init(Object* obj) { if(obj == NULL) { mDeleted = true; return; } mProcChance = TO_ITEM(obj)->GetProto()->Delay * 9 / 600; }
void LuaEngine::PushItem(Object * item, lua_State *LuaS) { Item * pItem = NULL; if(item != NULL && (item->GetTypeId() == TYPEID_ITEM || item->GetTypeId() == TYPEID_CONTAINER)) pItem = TO_ITEM(item); if(LuaS == NULL) Lunar<Item>::push(L, pItem); else Lunar<Item>::push(LuaS, pItem); }
void GossipHello( ObjectPointer pObject, PlayerPointer pPlayer, bool AutoSend ) { if ( pObject == NULL || pObject->GetTypeId() != TYPEID_ITEM || pPlayer == NULL ) return; QuestLogEntry* QuestEntry = pPlayer->GetQuestLogForEntry( 9452 ); if ( QuestEntry == NULL ) return; #ifndef BLIZZLIKE //if ( QuestEntry->GetMobCount( 0 ) >= QuestEntry->GetQuest()->required_mobcount[ 0 ] ) // return; #endif if ( pPlayer->GetMapMgr() == NULLMAPMGR ) return; // Meh, double object looking - we should find a way to remove this GameObjectPointer School = pPlayer->GetMapMgr()->GetInterface()->GetGameObjectNearestCoords( pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 181616 ); if ( School == NULLGOB || pPlayer->CalcDistance( School ) > 5.0f ) return; #ifdef BLIZZLIKE sEventMgr.AddEvent( School, &GameObject::Despawn, static_cast< uint32 >( 20000 ), EVENT_GAMEOBJECT_ITEM_SPAWN, 1000, 1, 0 ); #else School->Despawn( 20000 ); #endif pPlayer->CastSpell( pPlayer, dbcSpell.LookupEntry( TO_ITEM( pObject )->GetProto()->Spells[ 0 ].Id ), false ); uint32 Chance = RandomUInt( 10 ); if ( Chance <= 3 ) { CreaturePointer NewCreature = sEAS.SpawnCreature( pPlayer, 17102, pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), pPlayer->GetOrientation(), 180000 ); if ( NewCreature != NULLCREATURE ) { NewCreature->GetAIInterface()->StopMovement( 500 ); NewCreature->setAttackTimer( 1000, false ); NewCreature->m_noRespawn = true; }; return; }; sEAS.AddItem( 23614, pPlayer ); QuestEntry->SendUpdateAddKill( 1 ); QuestEntry->UpdatePlayerFields(); pPlayer->Gossip_Complete(); };
////////////////////////////////////////////////////////////// /// This function handles CMSG_GOSSIP_SELECT_OPTION: ////////////////////////////////////////////////////////////// void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data) { CHECK_INWORLD_RETURN uint32 option; uint32 unk24; uint64 guid; recv_data >> guid >> unk24 >> option; LOG_DETAIL("WORLD: CMSG_GOSSIP_SELECT_OPTION Option %i Guid %.8X", option, guid); Arcemu::Gossip::Script* script = NULL; uint32 guidtype = GET_TYPE_FROM_GUID(guid); Object* qst_giver; if(guidtype == HIGHGUID_TYPE_ITEM) //Item objects are retrieved differently. { qst_giver = GetPlayer()->GetItemInterface()->GetItemByGUID(guid); if(qst_giver != NULL) script = Arcemu::Gossip::Script::GetInterface(TO_ITEM(qst_giver)); } else qst_giver = GetPlayer()->GetMapMgr()->_GetObject(guid); if(qst_giver != NULL) { if(guidtype == HIGHGUID_TYPE_UNIT) script = Arcemu::Gossip::Script::GetInterface(TO_CREATURE(qst_giver)); else if(guidtype == HIGHGUID_TYPE_GAMEOBJECT) script = Arcemu::Gossip::Script::GetInterface(TO_GAMEOBJECT(qst_giver)); } if(script != NULL) { string str; if(recv_data.rpos() != recv_data.wpos()) recv_data >> str; if(str.length() > 0) script->OnSelectOption(qst_giver, GetPlayer() , option, str.c_str()); else script->OnSelectOption(qst_giver, GetPlayer() , option, NULL); }
bool Container::SafeFullRemoveItemFromSlot(int16 slot) { if (slot < 0 || (uint32)slot >= GetProto()->ContainerSlots) return false; Item* pItem = m_Slot[slot]; if (pItem == NULL ||pItem == TO_ITEM(this)) return false; m_Slot[slot] = NULLITEM; SetUInt64Value(CONTAINER_FIELD_SLOT_1 + slot*2, 0 ); pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); if(pItem->IsInWorld()) { pItem->RemoveFromWorld(); } pItem->DeleteFromDB(); pItem->Destructor(); return true; }
void LuaGossip::OnSelectOption(Object* pObject, Player* Plr, uint32 Id, const char* EnteredCode) { GET_LOCK; if(pObject->GetTypeId() == TYPEID_UNIT) { if(m_unit_gossip_binding == NULL) { RELEASE_LOCK; return; } lua_engine::BeginLuaFunctionCall(m_unit_gossip_binding->refs[GOSSIP_EVENT_ON_SELECT_OPTION]); push_creature(TO_CREATURE(pObject)); push_int(GOSSIP_EVENT_ON_SELECT_OPTION); push_player(Plr); push_int(Id); push_str(EnteredCode); lua_engine::ExecuteLuaFunction(5); } else if(pObject->GetTypeId() == TYPEID_ITEM) { if(m_item_gossip_binding == NULL) { RELEASE_LOCK; return; } lua_engine::BeginLuaFunctionCall(m_item_gossip_binding->refs[GOSSIP_EVENT_ON_SELECT_OPTION]); push_item(TO_ITEM(pObject)); push_int(GOSSIP_EVENT_ON_SELECT_OPTION); push_player(Plr); push_int(Id); push_str(EnteredCode); lua_engine::ExecuteLuaFunction(5); } else if(pObject->GetTypeId() == TYPEID_GAMEOBJECT) { if(m_go_gossip_binding == NULL) { RELEASE_LOCK; return; } lua_engine::BeginLuaFunctionCall(m_go_gossip_binding->refs[GOSSIP_EVENT_ON_SELECT_OPTION]); push_go(TO_GAMEOBJECT(pObject)); push_int(GOSSIP_EVENT_ON_SELECT_OPTION); push_player(Plr); push_int(Id); push_str(EnteredCode); lua_engine::ExecuteLuaFunction(5); } RELEASE_LOCK }
void Item::ApplyEnchantmentBonus( uint32 Slot, bool Apply ) { if( m_owner == NULL ) return; EnchantmentMap::iterator itr = Enchantments.find( Slot ); if( itr == Enchantments.end() ) return; EnchantEntry* Entry = itr->second.Enchantment; uint32 RandomSuffixAmount = itr->second.RandomSuffix; if( itr->second.Dummy ) return; if( itr->second.BonusApplied == Apply ) return; itr->second.BonusApplied = Apply; // Apply the visual on the player. uint32 ItemSlot = m_owner->GetItemInterface()->GetInventorySlotByGuid( GetGUID() ); if(ItemSlot < EQUIPMENT_SLOT_END && Slot < 1) { uint32 VisibleBase = PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + ItemSlot * PLAYER_VISIBLE_ITEM_LENGTH; m_owner->SetUInt16Value( VisibleBase, Slot, Apply ? Entry->Id : 0 ); } if( Apply ) { // Send the enchantment time update packet. SendEnchantTimeUpdate( itr->second.Slot, itr->second.Duration ); } // Another one of those for loop that where not indented properly god knows what will break // but i made it actually affect the code below it for( uint32 c = 0; c < 3; c++ ) { if( Entry->type[c] ) { // Depending on the enchantment type, take the appropriate course of action. switch( Entry->type[c] ) { case 1: // Trigger spell on melee attack. { if( Apply && Entry->spell[c] != 0 ) { // Create a proc trigger spell ProcTriggerSpell TS; memset(&TS, 0, sizeof(ProcTriggerSpell)); TS.caster = m_owner->GetGUID(); TS.procFlags = PROC_ON_MELEE_ATTACK; TS.origId = 0; TS.procflags2 = 0; TS.SpellClassMask[0] = 0; TS.SpellClassMask[1] = 0; TS.SpellClassMask[2] = 0; TS.ProcType = 0; TS.LastTrigger = 0; TS.procValue = 0; TS.procCharges = 0; TS.procChance = 10; if(ItemSlot == EQUIPMENT_SLOT_MAINHAND) TS.weapon_damage_type = 1; // Proc only on main hand attacks else if(ItemSlot == EQUIPMENT_SLOT_OFFHAND) TS.weapon_damage_type = 2; // Proc only on off hand attacks else TS.weapon_damage_type = 0; // Doesn't depend on weapon /* This needs to be modified based on the attack speed of the weapon. * Secondly, need to assign some static chance for instant attacks (ss, * gouge, etc.) */ if( GetProto()->Class == ITEM_CLASS_WEAPON ) { if( !Entry->min[c] ) { float speed = (float)GetProto()->Delay; /////// procChance calc /////// float ppm = 0; SpellEntry* sp = dbcSpell.LookupEntry( Entry->spell[c] ); if( sp ) { switch( sp->NameHash ) { case SPELL_HASH_FROSTBRAND_ATTACK: ppm = 9; break; } } if( ppm != 0 ) { float pcount = 60/ppm; float chance = (speed/10) / pcount; TS.procChance = (uint32)chance; } else TS.procChance = (uint32)( speed / 600.0f ); /////////////////////////////// } else TS.procChance = Entry->min[c]; } sLog.Debug( "Enchant", "Setting procChance to %u%%.", TS.procChance ); TS.deleted = false; TS.spellId = Entry->spell[c]; m_owner->m_procSpells.push_back( TS ); } else { // Remove the proctriggerspell uint32 SpellId; list< struct ProcTriggerSpell >::iterator itr/*, itr2*/; for( itr = m_owner->m_procSpells.begin(); itr != m_owner->m_procSpells.end(); ) { SpellId = itr->spellId; /*itr2 = itr;*/ /*++itr;*/ if( SpellId == Entry->spell[c] ) { //m_owner->m_procSpells.erase(itr2); itr->deleted = true; } ++itr; } } }break; case 2: // Mod damage done. { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); if( Apply ) m_owner->DamageDonePosMod[0] += val; else m_owner->DamageDonePosMod[0] -= val; m_owner->UpdateStats(); }break; case 3: // Cast spell (usually means apply aura) { if( Apply ) { SpellCastTargets targets( m_owner->GetGUID() ); SpellEntry* sp; if( Entry->spell[c] != 0 ) { sp = dbcSpell.LookupEntry( Entry->spell[c] ); if( sp == NULL ) continue; Spell* spell = NULLSPELL; //Never found out why, //but this Blade of Life's Inevitability spell must be casted by the item, not owner. if( m_itemProto->ItemId != 34349 ) spell = (new Spell( m_owner, sp, true, NULLAURA )); else spell = (new Spell( TO_ITEM(this), sp, true, NULLAURA )); spell->i_caster = TO_ITEM(this); spell->prepare( &targets ); } } else { if( Entry->spell[c] != 0 ) m_owner->RemoveAura( Entry->spell[c] ); } }break; case 4: // Modify physical resistance { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); if( Apply ) m_owner->FlatResistanceModifierPos[Entry->spell[c]] += val; else m_owner->FlatResistanceModifierPos[Entry->spell[c]] -= val; m_owner->CalcResistance( Entry->spell[c] ); }break; case 5: //Modify rating ...order is PLAYER_FIELD_COMBAT_RATING_1 and above { //spellid is enum ITEM_STAT_TYPE //min=max is amount int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); m_owner->ModifyBonuses( Entry->spell[c], Apply ? val : -val ); }break; case 6: // Rockbiter weapon (increase damage per second... how the hell do you calc that) { if( Apply ) { //if i'm not wrong then we should apply DMPS formula for this. This will have somewhat a larger value 28->34 int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); //int32 value = GetProto()->Delay * val / 1000; m_owner->DamageDonePosMod[0] += val; } else { int32 val = Entry->min[c]; if( RandomSuffixAmount ) val = RANDOM_SUFFIX_MAGIC_CALCULATION( RandomSuffixAmount, GetItemRandomSuffixFactor() ); //int32 value =- (int32)(GetProto()->Delay * val / 1000 ); m_owner->DamageDonePosMod[0] += val; } m_owner->UpdateStats(); }break; case 7: { if( Apply ) { for( uint32 i = 0; i < 3; ++i ) OnUseSpells[ i ] = Entry->spell[ i ]; } else { for( uint32 i = 0; i < 3; ++i ) OnUseSpells[ i ] = 0; } }break; case 8:{}break; default: { sLog.Debug( "Enchant","Unknown enchantment type: %u (%u)", Entry->type[c], Entry->Id ); }break; } } } }
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_1_1; SetUInt32Value( EnchantBase, Enchantment->Id ); SetUInt32Value( EnchantBase + 1, (uint32)Instance.ApplyTime ); SetUInt32Value( EnchantBase + 2, 0 ); // charges // Add it to our map. Enchantments[Slot] = Instance; if( m_owner == NULL ) return Slot; Player* owner = m_owner; // Add the removal event. if( Duration ) { sEventMgr.AddEvent( TO_ITEM(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( !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); owner->GetSession()->SendPacket( &EnchantLog ); if( owner->GetTradeTarget() ) { 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 ); } owner->SaveToDB(false); return Slot; }