|
Патчи Если кто-то хочет выложить не свой готовый патч - не забудьте указать автора и источник.
Если кто-то хочет задать вопрос по патчу - велкам. |
|
Опции темы | Поиск в этой теме | Опции просмотра |
11.07.2011, 18:28 | #1 |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
[patch] Creature Off Hand Attack
Сейчас ситуация такая: NPC имея в левой руке какое либо оружие, не бьют ей. Данный патч поправляет данную ситуацию.
Автор: Я патч на гите: https://github.com/bwsrv/mangos/comm...5e400e19930cfc Дополнение к патчу: https://github.com/bwsrv/mangos/comm...c2c67855b52a42 патч файлом: в аттаче! diff: Код:
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 928c956..68fe6b0 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -355,8 +355,10 @@ bool Creature::UpdateEntry(uint32 Entry, Team team, const CreatureData *data /*= SetUInt32Value(UNIT_NPC_FLAGS,GetCreatureInfo()->npcflag); - SetAttackTime(BASE_ATTACK, GetCreatureInfo()->baseattacktime); - SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); + uint32 attackTimer = GetCreatureInfo()->baseattacktime; + + SetAttackTime(BASE_ATTACK, attackTimer); + SetAttackTime(OFF_ATTACK, attackTimer - attackTimer/4); SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); uint32 unitFlags = GetCreatureInfo()->unit_flags; @@ -1180,8 +1194,11 @@ void Creature::SelectLevel(const CreatureInfo *cinfo, float percentHealth, float SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cinfo->mindmg * damagemod); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cinfo->maxdmg * damagemod); - SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,cinfo->minrangedmg * damagemod); - SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,cinfo->maxrangedmg * damagemod); + SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, cinfo->mindmg * damagemod); + SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, cinfo->maxdmg * damagemod); + + SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, cinfo->minrangedmg * damagemod); + SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, cinfo->maxrangedmg * damagemod); SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod); } diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 30b03d9..695697b 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -122,22 +122,30 @@ CanCastResult CreatureAI::DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 return CAST_FAIL_IS_CASTING; } +bool CreatureAI::AttackByType(WeaponAttackType attType) +{ + // Make sure our attack is ready before checking distance + if (m_creature->isAttackReady(attType) && m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) + { + m_creature->AttackerStateUpdate(m_creature->getVictim(), attType); + m_creature->resetAttackTimer(attType); + WeaponAttackType attTypeTwo = (attType == BASE_ATTACK ? OFF_ATTACK : BASE_ATTACK); + if (m_creature->getAttackTimer(attTypeTwo) < 500) + m_creature->setAttackTimer(attTypeTwo, 500); + return true; + } + + return false; +} + bool CreatureAI::DoMeleeAttackIfReady() { // Check target if (!m_creature->getVictim()) return false; - // Make sure our attack is ready before checking distance - if (!m_creature->isAttackReady()) - return false; - - // If we are within range melee the target - if (!m_creature->CanReachWithMeleeAttack(m_creature->getVictim())) - return false; + if (AttackByType(BASE_ATTACK)) + return true; - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); + if (m_creature->haveOffhandWeapon()) + return AttackByType(OFF_ATTACK); - return true; + return false; } diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 78ec0b0..5f46f34 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -25,6 +25,7 @@ #include "Dynamic/ObjectRegistry.h" #include "Dynamic/FactoryHolder.h" #include "ObjectGuid.h" +#include "Unit.h" class WorldObject; class GameObject; @@ -163,6 +164,7 @@ class MANGOS_DLL_SPEC CreatureAI virtual bool canReachByRangeAttack(Unit*) { return false; } ///== Helper functions ============================= + bool AttackByType(WeaponAttackType attType = BASE_ATTACK); bool DoMeleeAttackIfReady(); CanCastResult DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags = 0, ObjectGuid uiOriginalCasterGUID = ObjectGuid()); diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 99f0975..20e55a8 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -901,18 +901,20 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field - if(ranged) + if (ranged) return; + //automatically update weapon damage after attack power modification UpdateDamagePhysical(BASE_ATTACK); + UpdateDamagePhysical(OFF_ATTACK); } void Creature::UpdateDamagePhysical(WeaponAttackType attType) { - if(attType > BASE_ATTACK) + if (attType > OFF_ATTACK) return; - UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; + UnitMods unitMod = (attType == BASE_ATTACK ? UNIT_MOD_DAMAGE_MAINHAND : UNIT_MOD_DAMAGE_OFFHAND); /* difference in AP between current attack power and base value from DB */ float att_pwr_change = GetTotalAttackPowerValue(attType) - GetCreatureInfo()->attackpower; @@ -922,14 +924,14 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType) float total_pct = GetModifierValue(unitMod, TOTAL_PCT); float dmg_multiplier = GetCreatureInfo()->dmg_multiplier; - float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); - float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); + float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); + float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); float mindamage = ((base_value + weapon_mindamage) * dmg_multiplier * base_pct + total_value) * total_pct; float maxdamage = ((base_value + weapon_maxdamage) * dmg_multiplier * base_pct + total_value) * total_pct; - SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); + SetStatFloatValue(attType == BASE_ATTACK ? UNIT_FIELD_MINDAMAGE : UNIT_FIELD_MINOFFHANDDAMAGE, mindamage); + SetStatFloatValue(attType == BASE_ATTACK ? UNIT_FIELD_MAXDAMAGE : UNIT_FIELD_MAXOFFHANDDAMAGE, maxdamage); } /*####################################### diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 15372cd..c27f3e8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -239,7 +239,8 @@ Unit::Unit() : m_auraModifiersGroup[i][NONSTACKING_VALUE] = 0.0f; m_auraModifiersGroup[i][NONSTACKING_PCT] = 0.0f; } - // implement 50% base damage from offhand + + // implement 50% base damage from offhand m_auraModifiersGroup[UNIT_MOD_DAMAGE_OFFHAND][TOTAL_PCT] = 0.5f; for (int i = 0; i < MAX_ATTACK; ++i) @@ -372,6 +373,11 @@ void Unit::Update( uint32 update_diff, uint32 p_time ) setAttackTimer(BASE_ATTACK, (update_diff >= base_att ? 0 : base_att - update_diff) ); } + if (uint32 base_att = getAttackTimer(OFF_ATTACK)) + { + setAttackTimer(OFF_ATTACK, (update_diff >= base_att ? 0 : base_att - update_diff) ); + } + // update abilities available only for fraction of time UpdateReactives( update_diff ); @@ -390,7 +396,15 @@ bool Unit::haveOffhandWeapon() const if(GetTypeId() == TYPEID_PLAYER) return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true,true); else + { + uint32 ItemId = GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1); + ItemEntry const* itemInfo = sItemStore.LookupEntry(ItemId); + + if (itemInfo && itemInfo->Class == ITEM_CLASS_WEAPON) + return true; + return false; + } } @@ -3079,7 +3093,6 @@ uint32 Unit::CalculateDamage (WeaponAttackType attType, bool normalized) min_damage = GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); max_damage = GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); break; - // Just for good manner default: min_damage = 0.0f; max_damage = 0.0f; Последний раз редактировалось MaxXx2021; 10.08.2011 в 15:57. |
4 пользователя(ей) сказали cпасибо: |
11.07.2011, 18:47 | #2 |
Ученый
Регистрация: 13.03.2010
Сообщений: 110
Сказал(а) спасибо: 55
Поблагодарили 23 раз(а) в 14 сообщениях
|
вполне вероятно, что на мобов вешается аура, позволяющая бить им с 2х рук.
|
11.07.2011, 18:53 | #3 |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
|
12.07.2011, 01:12 | #4 |
Ученый
|
А если это аура которая определяет ap, скорость, уровень и ранг моба и по формуле высчитывает скорость и урон с оф хенда моба?
|
12.07.2011, 03:33 | #5 |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
Вы предсталяеете давать такую ауру огромному кол-ву мобов, так же с уверенностью можно сказать, что базовая атака тоже идет от спелла и берет значения из базы
Последний раз редактировалось MaxXx2021; 12.07.2011 в 03:40. |
12.07.2011, 09:03 | #6 |
Умный
Старожил
Регистрация: 06.03.2010
Сообщений: 886
Сказал(а) спасибо: 698
Поблагодарили 433 раз(а) в 181 сообщениях
Записей в дневнике: 4
|
Копипаст чтоли???
Первая часть патча - к чему вообще эти изменения? Что было не так до этого? Код:
m_attackTimer[type] = uint32((GetAttackTime(type) == 0 ? 1500 : GetAttackTime(type)) * m_modAttackSpeedPct[type]); |
12.07.2011, 10:25 | #7 |
Ученый
Регистрация: 07.03.2010
Сообщений: 138
Сказал(а) спасибо: 200
Поблагодарили 143 раз(а) в 49 сообщениях
|
Все умножается, на скобки посмотри.
|
12.07.2011, 10:45 | #8 | |
YTDB Dev
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
|
Цитата:
UNIT_FIELD_MINOFFHANDDAMAGE UNIT_FIELD_MAXOFFHANDDAMAGE UNIT_FIELD_BASEATTACKTIME_2 p.s: Нарыл обсуждение у себя этого в хистори аськи аж от 21.01.11.)) Последний раз редактировалось YuruY; 12.07.2011 в 10:52. |
|
Пользователь сказал cпасибо: | MaxXx2021 (12.07.2011) |
12.07.2011, 10:58 | #9 | ||
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
Цитата:
Цитата:
UNIT_FIELD_MINOFFHANDDAMAGE UNIT_FIELD_MAXOFFHANDDAMAGE UNIT_FIELD_BASEATTACKTIME_2 где вы тут копипаст нашли? Последний раз редактировалось MaxXx2021; 21.05.2012 в 20:02. |
||
12.07.2011, 11:22 | #10 | |
YTDB Dev
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
|
Цитата:
|
|
12.07.2011, 11:33 | #11 |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
|
12.07.2011, 13:08 | #13 | ||
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
Цитата:
Добавлено через 1 час 23 минуты Цитата:
П.С. и скорости тоже. |
||
12.07.2011, 13:25 | #14 |
YTDB Dev
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
|
Те про которые писал, там снифф чисто без боя (мобов которые дерутся с обоих рук тоже не так много), все поля по нулям кроме "UNIT_FIELD_BASEATTACKTIME_Х" (оно всегда заполнено почемуто, не важно бой был с мобом или нет), позже эти поля в сниффах не изучал больше. Если нужно могу для изучения кинуть снифф какогонибудь данжа к примеру, там сами смотрите (версию уточните только 4.0.6, 4.1.0, 4.2.0).
Последний раз редактировалось YuruY; 12.07.2011 в 13:28. |
12.07.2011, 13:30 | #15 |
Администратор
|
Смотрел снифф выполнения квеста "Перемирие?", там есть данные боя, но везде, где смотрел, UNIT_FIELD_BASEATTACKTIME_2=UNIT_FIELD_BASEATTACKT IME=2000.
Возможно, по кодам нпц будет проще искать по сниффам, т.к. хз, у кого есть offhand, а у кого - нет. |
12.07.2011, 13:32 | #16 | |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
Цитата:
Можно снифф черного хранителя в долине эха. В испытании крестоносца у рога два вепона. Испытание чемпиона у Иллюзии Ванклифа. Битва за подгород (Орда Сильвана с двумя мечами). Битва За Подгород (Альянс, король Рин с двумя мечами). Дарион Могрейн в Акерусе с двумя мечами. Если кто сможет сделать данные сниффы буду рад Последний раз редактировалось MaxXx2021; 12.07.2011 в 13:37. |
|
12.07.2011, 19:23 | #17 | |||
YTDB Dev
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
|
Цитата:
Цитата:
Цитата:
|
|||
Пользователь сказал cпасибо: | MaxXx2021 (13.07.2011) |
13.07.2011, 11:35 | #19 |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
Обновил патч, патч работает без базы! Данные берутся относительно базовой атаки. Так как некоторая инфа в ядре уже есть по этому поводу.
Патч, готов! Теперь ждем ответа от DEVs Последний раз редактировалось MaxXx2021; 13.07.2011 в 15:57. |
14.07.2011, 18:26 | #20 |
Ученый
|
Почему-то не обращают внимания, на данный патч, в виду того что не до него?, думаю вполне нужный патч.
|
10.08.2011, 11:59 | #21 |
Ученый
Регистрация: 09.03.2010
Адрес: Кыргызстан
Сообщений: 266
Сказал(а) спасибо: 41
Поблагодарили 115 раз(а) в 34 сообщениях
|
Внес кое какие изменения: По просьбе Владимира убрал новый UnitField и сделал по аналогии плееров удары двумя руками. Патч в аттаче поменяю позже.
https://github.com/bwsrv/mangos/comm...c2c67855b52a42 Последний раз редактировалось MaxXx2021; 10.08.2011 в 12:01. |
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
[11323] Avoid explicit use HIGHGUID_UNIT as creature high guid in guids or creature creating. | newsbot | CMaNGOS Commits | 0 | 07.04.2011 20:14 |
[11311] Add SCRIPT_COMMAND_ATTACK_START to initiate attack by creature. | newsbot | CMaNGOS Commits | 0 | 03.04.2011 21:00 |
[10929] Move game event creature morphing code to Creature::UpdateEntry | newsbot | CMaNGOS Commits | 0 | 28.12.2010 22:00 |
[10561] Avoid ask AI for direct controlled creature at attack. | newsbot | CMaNGOS Commits | 0 | 30.09.2010 17:20 |