aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2009-02-03 19:12:17 -0600
committermegamage <none@none>2009-02-03 19:12:17 -0600
commit50c82c666093b5dac3cd60cddf9f46223a48d8d9 (patch)
treeac07b3816a327853dee3610e88da379931670e5e /src
parent1c51b382dc6e961edeb4c081748f3ddba96be61b (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.cpp2
-rw-r--r--src/game/Item.h2
-rw-r--r--src/game/ItemHandler.cpp81
-rw-r--r--src/game/Player.cpp3
-rw-r--r--src/game/SharedDefines.h2
-rw-r--r--src/game/Spell.cpp2
-rw-r--r--src/game/Spell.h1
-rw-r--r--src/game/SpellEffects.cpp65
-rw-r--r--src/shared/Database/DBCStructure.h16
-rw-r--r--src/shared/revision_nr.h2
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__