diff options
author | megamage <none@none> | 2009-03-15 17:54:24 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-03-15 17:54:24 -0600 |
commit | 61f519ca26f6d75e2096b5469691a0f37d53bbed (patch) | |
tree | dd7acc3a654a5c33d37f1e37c362515fa42048a5 | |
parent | 3c9c17b253e64da78fa395c1a972b6ce09cc926f (diff) |
[7464] Move check of spell using for lock open to single function. Remove more hacks. Author: VladimirMangos
--HG--
branch : trunk
-rw-r--r-- | src/game/Spell.cpp | 177 | ||||
-rw-r--r-- | src/game/Spell.h | 1 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 95 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 10 |
4 files changed, 105 insertions, 178 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7ecf1ff4b8d..bfc58631079 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4076,115 +4076,31 @@ uint8 Spell::CanCast(bool strict) return SPELL_FAILED_TRY_AGAIN; // get the lock entry - LockEntry const *lockInfo = NULL; + uint32 lockId = 0; if (GameObject* go=m_targets.getGOTarget()) - lockInfo = sLockStore.LookupEntry(go->GetLockId()); + lockId = go->GetLockId(); else if(Item* itm=m_targets.getItemTarget()) - lockInfo = sLockStore.LookupEntry(itm->GetProto()->LockID); + lockId = itm->GetProto()->LockID; - // check lock compatibility - if (lockInfo) - { - // check for lock - key pair (checked by client also, just prevent cheating - bool ok_key = false; - bool req_key = false; - for(int it = 0; it < 8; ++it) - { - switch(lockInfo->Type[it]) - { - case LOCK_KEY_NONE: - break; - case LOCK_KEY_ITEM: - { - req_key = true; - if(lockInfo->Index[it]) - { - if(m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it]) - ok_key =true; - break; - } - } - case LOCK_KEY_SKILL: - { - req_key = true; - if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->Index[it]) - break; - - SkillType skill = SkillByLockType(LockType(lockInfo->Index[it])); - if(skill==SKILL_NONE) - ok_key =true; - else if(((Player*)m_caster)->HasSkill(skill)) - ok_key =true; - } - } - if(ok_key) - break; - } + SkillType skillId =SKILL_NONE; + int32 reqSkillValue = 0; + int32 skillValue = 0; - if(!ok_key && req_key) - return SPELL_FAILED_BAD_TARGETS; - } + // check lock compatibility + SpellCastResult res = CanOpenLock(i,lockId,skillId,reqSkillValue,skillValue); + if(res != SPELL_CAST_OK) + return res; // chance for fail at orange mining/herb/LockPicking gathering attempt - if (!m_selfContainer || ((*m_selfContainer) != this)) - break; - - // get the skill value of the player - int32 SkillValue = 0; - bool canFailAtMax = true; - if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_HERBALISM) - { - SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_HERBALISM); - canFailAtMax = false; - } - else if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_MINING) - { - SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_MINING); - canFailAtMax = false; - } - else if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK) - SkillValue = ((Player*)m_caster)->GetSkillValue(SKILL_LOCKPICKING); - - // castitem check: rogue using skeleton keys. the skill values should not be added in this case. - if(m_CastItem) - SkillValue = 0; - - // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value) - // TODO: is this a hack? - SkillValue += m_currentBasePoints[i]+1; - - // get the required lock value - int32 ReqValue=0; - if (lockInfo) + // second check prevent fail at rechecks + if(skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this))) { - // check for lock - key pair - bool ok = false; - for(int it = 0; it < 8; ++it) - { - if(lockInfo->Type[it]==LOCK_KEY_ITEM && lockInfo->Index[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it]) - { - // if so, we're good to go - ok = true; - break; - } - } - if(ok) - break; + bool canFailAtMax = skillId != SKILL_HERBALISM && skillId != SKILL_MINING; - if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK) - ReqValue = lockInfo->Skill[1]; - else - ReqValue = lockInfo->Skill[0]; + // chance for failure in orange gather / lockpick (gathering skill can't fail at maxskill) + if((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue-25, skillValue+37)) + return SPELL_FAILED_TRY_AGAIN; } - - // skill doesn't meet the required value - if (ReqValue > SkillValue) - return SPELL_FAILED_LOW_CASTLEVEL; - - // chance for failure in orange gather / lockpick (gathering skill can't fail at maxskill) - if((canFailAtMax || SkillValue < sWorld.GetConfigMaxSkillValue()) && ReqValue > irand(SkillValue-25, SkillValue+37)) - return SPELL_FAILED_TRY_AGAIN; - break; } case SPELL_EFFECT_SUMMON_DEAD_PET: @@ -5729,3 +5645,64 @@ int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *mul return damageDone; } +SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue) +{ + if(!lockId) // possible case for GO and maybe for items. + return SPELL_CAST_OK; + + // Get LockInfo + LockEntry const *lockInfo = sLockStore.LookupEntry(lockId); + + if (!lockInfo) + return SPELL_FAILED_BAD_TARGETS; + + bool reqKey = false; // some locks not have reqs + + for(int j = 0; j < 8; ++j) + { + switch(lockInfo->Type[j]) + { + // check key item (many fit cases can be) + case LOCK_KEY_ITEM: + if(lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[j]) + return SPELL_CAST_OK; + reqKey = true; + break; + // check key skill (only single first fit case can be) + case LOCK_KEY_SKILL: + { + reqKey = true; + + // wrong locktype, skip + if(uint32(m_spellInfo->EffectMiscValue[effIndex]) != lockInfo->Index[j]) + continue; + + skillId = SkillByLockType(LockType(lockInfo->Index[j])); + + if ( skillId != SKILL_NONE ) + { + // skill bonus provided by casting spell (mostly item spells) + // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value) + uint32 spellSkillBonus = uint32(m_currentBasePoints[effIndex]+1); + reqSkillValue = lockInfo->Skill[j]; + + // castitem check: rogue using skeleton keys. the skill values should not be added in this case. + skillValue = m_CastItem || m_caster->GetTypeId()!= TYPEID_PLAYER ? + 0 : ((Player*)m_caster)->GetSkillValue(skillId); + + skillValue += spellSkillBonus; + + if (skillValue < reqSkillValue) + return SPELL_FAILED_LOW_CASTLEVEL; + } + + return SPELL_CAST_OK; + } + } + } + + if(reqKey) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; +} diff --git a/src/game/Spell.h b/src/game/Spell.h index f28d55b23a1..1fb074a396c 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -595,6 +595,7 @@ class Spell void SpellDamageSchoolDmg(uint32 i); void SpellDamageWeaponDmg(uint32 i); void SpellDamageHeal(uint32 i); + SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue); // ------------------------------------------- //List For Triggered Spells diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 4f5e630c56b..e494274b751 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3143,92 +3143,39 @@ void Spell::EffectOpenLock(uint32 effIndex) return; } - if(!lockId) // possible case for GO and maybe for items. - { - SendLoot(guid, LOOT_CORPSE); - return; - } + SkillType skillId = SKILL_NONE; + int32 reqSkillValue = 0; + int32 skillValue; - // Get LockInfo - LockEntry const *lockInfo = sLockStore.LookupEntry(lockId); - - if (!lockInfo) + SpellCastResult res = CanOpenLock(effIndex,lockId,skillId,reqSkillValue,skillValue); + if(res != SPELL_CAST_OK) { - sLog.outError( "Spell::EffectOpenLock: %s [guid = %u] has an unknown lockId: %u!", - (gameObjTarget ? "gameobject" : "item"), GUID_LOPART(guid), lockId); - SendCastResult(SPELL_FAILED_BAD_TARGETS); + SendCastResult(res); return; } - bool reqKey = false; // some locks not have reqs + SendLoot(guid, LOOT_SKINNING); - for(int j = 0; j < 8; ++j) + // not allow use skill grou at item base open + if(!m_CastItem && skillId != SKILL_NONE) { - switch(lockInfo->Type[j]) + // update skill if really known + if(uint32 pureSkillValue = player->GetPureSkillValue(skillId)) { - // check key item (many fit cases can be) - case LOCK_KEY_ITEM: - if(lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[j]) - { - SendLoot(guid, LOOT_CORPSE); - return; - } - reqKey = true; - break; - // check key skill (only single first fit case can be) - case LOCK_KEY_SKILL: + if(gameObjTarget) { - reqKey = true; - - // wrong locktype, skip - if(uint32(m_spellInfo->EffectMiscValue[effIndex]) != lockInfo->Index[j]) - continue; - - SkillType skillId = SkillByLockType(LockType(lockInfo->Index[j])); - - if ( skillId != SKILL_NONE ) - { - // skill bonus provided by casting spell (mostly item spells) - uint32 spellSkillBonus = uint32(damage); - uint32 reqSkillValue = lockInfo->Skill[j]; - - if ( player->GetSkillValue(skillId) + spellSkillBonus < reqSkillValue ) - { - SendCastResult(SPELL_FAILED_LOW_CASTLEVEL); - return; - } - - // update skill if really known - if(uint32 SkillValue = player->GetPureSkillValue(skillId)) - { - if(gameObjTarget) - { - // Allow one skill-up until respawned - if ( !gameObjTarget->IsInSkillupList( player->GetGUIDLow() ) && - player->UpdateGatherSkill(skillId, SkillValue, reqSkillValue) ) - gameObjTarget->AddToSkillupList( player->GetGUIDLow() ); - } - else if(itemTarget) - { - // Do one skill-up - player->UpdateGatherSkill(skillId, SkillValue, reqSkillValue); - } - } - } - - SendLoot(guid, LOOT_SKINNING); - return; + // Allow one skill-up until respawned + if ( !gameObjTarget->IsInSkillupList( player->GetGUIDLow() ) && + player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue) ) + gameObjTarget->AddToSkillupList( player->GetGUIDLow() ); + } + else if(itemTarget) + { + // Do one skill-up + player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue); } } } - - if(reqKey) - { - SendCastResult(SPELL_FAILED_BAD_TARGETS); - return; - } - - SendLoot(guid, LOOT_SKINNING); } void Spell::EffectSummonChangeItem(uint32 i) diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 8f2fa87e17f..12fa9f7d323 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -981,13 +981,15 @@ struct ItemSetEntry uint32 required_skill_value; // 52 m_requiredSkillRank }; +#define MAX_LOCK_CASE 8 + struct LockEntry { uint32 ID; // 0 m_ID - uint32 Type[8]; // 1-8 m_Type - uint32 Index[8]; // 9-16 m_Index - uint32 Skill[8]; // 17-24 m_Skill - //uint32 Action[8]; // 25-32 m_Action + uint32 Type[MAX_LOCK_CASE]; // 1-8 m_Type + uint32 Index[MAX_LOCK_CASE]; // 9-16 m_Index + uint32 Skill[MAX_LOCK_CASE]; // 17-24 m_Skill + //uint32 Action[MAX_LOCK_CASE]; // 25-32 m_Action }; struct MailTemplateEntry |