diff options
author | megamage <none@none> | 2009-02-03 19:12:17 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-02-03 19:12:17 -0600 |
commit | 50c82c666093b5dac3cd60cddf9f46223a48d8d9 (patch) | |
tree | ac07b3816a327853dee3610e88da379931670e5e /src | |
parent | 1c51b382dc6e961edeb4c081748f3ddba96be61b (diff) |
[7227] Implement prismatic sockets. Related code cleanups.
Big thanks to TOM_RUS for help in reseach!
Author: VladimirMangos
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Item.cpp | 2 | ||||
-rw-r--r-- | src/game/Item.h | 2 | ||||
-rw-r--r-- | src/game/ItemHandler.cpp | 81 | ||||
-rw-r--r-- | src/game/Player.cpp | 3 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 2 | ||||
-rw-r--r-- | src/game/Spell.h | 1 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 65 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 16 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
10 files changed, 134 insertions, 42 deletions
diff --git a/src/game/Item.cpp b/src/game/Item.cpp index c39b573e24a..1f9d00b64e3 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -288,7 +288,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff) } SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION) - diff); - SetState(ITEM_CHANGED); // save new time in database + SetState(ITEM_CHANGED, owner); // save new time in database } void Item::SaveToDB() diff --git a/src/game/Item.h b/src/game/Item.h index a51f06d8d51..a6fe03dac4c 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -167,6 +167,8 @@ enum EnchantmentSlot #define MAX_VISIBLE_ITEM_OFFSET 18 // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1)) +#define MAX_GEM_SOCKETS 3 // (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) + enum EnchantmentOffset { ENCHANTMENT_ID_OFFSET = 0, diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index 2c2cf2f82f1..7787995c324 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -1111,55 +1111,80 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) { sLog.outDebug("WORLD: CMSG_SOCKET_GEMS"); - CHECK_PACKET_SIZE(recv_data,8*4); + CHECK_PACKET_SIZE(recv_data,8+8*MAX_GEM_SOCKETS); - uint64 guids[4]; - for(int i = 0; i < 4; i++) - recv_data >> guids[i]; + uint64 item_guid; + uint64 gem_guids[MAX_GEM_SOCKETS]; - if(!guids[0]) + recv_data >> item_guid; + if(!item_guid) return; + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) + recv_data >> gem_guids[i]; + //cheat -> tried to socket same gem multiple times - if((guids[1] && (guids[1] == guids[2] || guids[1] == guids[3])) || (guids[2] && (guids[2] == guids[3]))) + if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) || + (gem_guids[1] && (gem_guids[1] == gem_guids[2]))) return; - Item *itemTarget = _player->GetItemByGuid(guids[0]); + Item *itemTarget = _player->GetItemByGuid(item_guid); if(!itemTarget) //missing item to socket return; + ItemPrototype const* itemProto = itemTarget->GetProto(); + if(!itemProto) + return; + //this slot is excepted when applying / removing meta gem bonus uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : NULL_SLOT; - Item *Gems[3]; - for(int i = 0; i < 3; i++) - Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL; + Item *Gems[MAX_GEM_SOCKETS]; + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) + Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : NULL; - GemPropertiesEntry const *GemProps[3]; - for(int i = 0; i < 3; ++i) //get geminfo from dbc storage - { + GemPropertiesEntry const *GemProps[MAX_GEM_SOCKETS]; + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL; - } - for(int i = 0; i < 3; ++i) //check for hack maybe + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe { - // tried to put gem in socket where no socket exists / tried to put normal gem in meta socket + if (!GemProps[i]) + continue; + + // tried to put gem in socket where no socket exists (take care about prismatic sockets) + if (!itemProto->Socket[i].Color) + { + // no prismatic socket + if(!itemTarget->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT)) + return; + + // not first not-colored (not normaly used) socket + if(i!=0 && !itemProto->Socket[i-1].Color && (i+1 >= MAX_GEM_SOCKETS || itemProto->Socket[i+1].Color)) + return; + + // ok, this is first not colored socket for item with prismatic socket + } + + // tried to put normal gem in meta socket + if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META) + return; + // tried to put meta gem in normal socket - if( GemProps[i] && ( !itemTarget->GetProto()->Socket[i].Color || - itemTarget->GetProto()->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META || - itemTarget->GetProto()->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META ) ) + if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META) return; } - uint32 GemEnchants[3], OldEnchants[3]; - for(int i = 0; i < 3; ++i) //get new and old enchantments + uint32 GemEnchants[MAX_GEM_SOCKETS]; + uint32 OldEnchants[MAX_GEM_SOCKETS]; + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments { GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0; OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i)); } // check unique-equipped conditions - for(int i = 0; i < 3; ++i) + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) { if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)) { @@ -1174,7 +1199,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) } // continue check for case when attempt add 2 similar unique equipped gems in one item. - for (int j = 0; j < 3; ++j) + for (int j = 0; j < MAX_GEM_SOCKETS; ++j) { if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId)) { @@ -1182,7 +1207,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) return; } } - for (int j = 0; j < 3; ++j) + for (int j = 0; j < MAX_GEM_SOCKETS; ++j) { if (OldEnchants[j]) { @@ -1206,20 +1231,20 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met //remove ALL enchants - for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),false); - for(int i = 0; i < 3; ++i) + for(int i = 0; i < MAX_GEM_SOCKETS; ++i) { if(GemEnchants[i]) { itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0); - if(Item* guidItem = _player->GetItemByGuid(guids[i + 1])) + if(Item* guidItem = _player->GetItemByGuid(gem_guids[i])) _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true ); } } - for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true); bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 985865cb812..9931fba20c8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12403,6 +12403,9 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a case ITEM_ENCHANTMENT_TYPE_USE_SPELL: // processed in Player::CastItemUseSpell break; + case ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET: + // nothing do.. + break; default: sLog.outError("Unknown item enchantment (id = %d) display type: %d", enchant_id, enchant_display_type); break; diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index b08bb45e322..c315f288c00 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -685,7 +685,7 @@ enum SpellEffects SPELL_EFFECT_153 = 153, SPELL_EFFECT_154 = 154, SPELL_EFFECT_TITAN_GRIP = 155, - SPELL_EFFECT_ADD_SOCKET = 156, + SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC = 156, SPELL_EFFECT_CREATE_ITEM_2 = 157, SPELL_EFFECT_MILLING = 158, SPELL_EFFECT_ALLOW_RENAME_PET = 159, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 36766c67011..eada07c4c10 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -574,6 +574,7 @@ void Spell::FillTargetMap() break; /*case SPELL_EFFECT_ENCHANT_ITEM: case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: + case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: case SPELL_EFFECT_DISENCHANT: case SPELL_EFFECT_PROSPECTING: case SPELL_EFFECT_MILLING: @@ -5008,6 +5009,7 @@ uint8 Spell::CheckItems() break; } case SPELL_EFFECT_ENCHANT_ITEM: + case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: { Item* targetItem = m_targets.getItemTarget(); if(!targetItem) diff --git a/src/game/Spell.h b/src/game/Spell.h index 38345525b65..9a3e079dcdf 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -350,6 +350,7 @@ class Spell void EffectRedirectThreat(uint32 i); void EffectActivateRune(uint32 i); void EffectTitanGrip(uint32 i); + void EffectEnchantItemPrismatic(uint32 i); Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL, bool skipCheck = false ); ~Spell(); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 0fec6925203..262f3f679e0 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -220,7 +220,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry &Spell::EffectNULL, //154 unused &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal. - &Spell::EffectNULL, //156 Add Socket + &Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC &Spell::EffectCreateItem, //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession &Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling &Spell::EffectRenamePet //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again @@ -3888,7 +3888,7 @@ void Spell::EffectTradeSkill(uint32 /*i*/) // ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75); } -void Spell::EffectEnchantItemPerm(uint32 i) +void Spell::EffectEnchantItemPerm(uint32 effect_idx) { if(m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -3897,9 +3897,10 @@ void Spell::EffectEnchantItemPerm(uint32 i) Player* p_caster = (Player*)m_caster; + // not grow at item use at item case p_caster->UpdateCraftSkill(m_spellInfo->Id); - uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx]; if (!enchant_id) return; @@ -3929,6 +3930,64 @@ void Spell::EffectEnchantItemPerm(uint32 i) item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true); } +void Spell::EffectEnchantItemPrismatic(uint32 effect_idx) +{ + if(m_caster->GetTypeId() != TYPEID_PLAYER) + return; + if (!itemTarget) + return; + + Player* p_caster = (Player*)m_caster; + + uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx]; + if (!enchant_id) + return; + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return; + + // support only enchantings with add socket in this slot + { + bool add_socket = false; + for(int i = 0; i < 3; ++i) + { + if(pEnchant->type[i]==ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET) + { + add_socket = true; + break; + } + } + if(!add_socket) + { + sLog.outError("Spell::EffectEnchantItemPrismatic: attempt apply enchant spell %u with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC (%u) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET (u), not suppoted yet.", + m_spellInfo->Id,SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC,ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET); + return; + } + } + + // item can be in trade slot and have owner diff. from caster + Player* item_owner = itemTarget->GetOwner(); + if(!item_owner) + return; + + if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) + { + sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", + p_caster->GetName(),p_caster->GetSession()->GetAccountId(), + itemTarget->GetProto()->Name1,itemTarget->GetEntry(), + item_owner->GetName(),item_owner->GetSession()->GetAccountId()); + } + + // remove old enchanting before applying new if equipped + item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,false); + + itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0); + + // add new enchanting if equipped + item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,true); +} + void Spell::EffectEnchantItemTmp(uint32 i) { if(m_caster->GetTypeId() != TYPEID_PLAYER) diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 8ffe97f46a7..d8055813967 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -1278,14 +1278,14 @@ struct SpellItemEnchantmentEntry uint32 amount[3]; // 5-7 m_effectPointsMin[3] //uint32 amount2[3] // 8-10 m_effectPointsMax[3] uint32 spellid[3]; // 11-13 m_effectArg[3] - char* description[16]; // 14-30 m_name_lang[16] - //uint32 descriptionFlags; // 31 name flags - uint32 aura_id; // 32 m_itemVisual - uint32 slot; // 33 m_flags - uint32 GemID; // 34 m_src_itemID - uint32 EnchantmentCondition; // 35 m_condition_id - //uint32 requiredSkill; // 36 m_requiredSkillID - //uint32 requiredSkillValue; // 37 m_requiredSkillRank + char* description[16]; // 14-29 m_name_lang[16] + //uint32 descriptionFlags; // 30 name flags + uint32 aura_id; // 31 m_itemVisual + uint32 slot; // 32 m_flags + uint32 GemID; // 33 m_src_itemID + uint32 EnchantmentCondition; // 34 m_condition_id + //uint32 requiredSkill; // 35 m_requiredSkillID + //uint32 requiredSkillValue; // 36 m_requiredSkillRank }; struct SpellItemEnchantmentConditionEntry diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cd1d48dc8b3..a257b588318 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7226" + #define REVISION_NR "7227" #endif // __REVISION_NR_H__ |