- void __cdecl Spell_C_GetMinMaxRange(CGUnit_C *sourceUnit, SpellRec *spellInfo, float *minRange, float *maxRange, int friendly, CGObject_C *targetObject, int difficultyID)
- {
- CGUnit_C *targetUnit; // edi@1
- SpellMiscRec *v8; // eax@6
- int v9; // eax@7
- SpellRangeRec_C *spellRange; // eax@9 MAPDST
- int v13; // eax@12
- CGUnitData *targetUnitFields; // eax@15 MAPDST
- float v17; // xmm0_4@23
- float v19; // xmm0_4@29
- float v21; // xmm0_4@32
- CGItem_C *v23; // eax@46
- CGObjectData *v24; // esi@47
- CGObjectData *v25; // eax@47
- int v26; // eax@47
- SmartGuid v27; // [sp+8h] [bp-14h]@14
- float rangeModifier; // [sp+18h] [bp-4h]@6 MAPDST
- targetUnit = (CGUnit_C *)targetObject;
- if ( !targetObject || !(((unsigned int)LOWORD(targetObject->Fields->OBJECT_FIELD_TYPE) >> 3) & 1) )
- targetUnit = 0;
- if ( CheckSpellAttribute(spellInfo, 0, 0x404) )// SPELL_ATTR0_ON_NEXT_SWING | SPELL_ATTR0_ON_NEXT_SWING_2
- {
- *(_DWORD *)maxRange = 1120403456; // 100.000000 - this means you can activate the spell from any range, not that it will go off from there (Heroic Strike)
- return;
- }
- rangeModifier = 0.0;
- v8 = (SpellMiscRec *)GetSpellMisc(difficultyID);
- if ( v8 )
- v9 = v8->RangeIndex;
- else
- v9 = 1;
- spellRange = (SpellRangeRec_C *)sub_674744((int)&g_spellRangeDB, v9, g_guidNull, 0, 0, 0);// LookupEntry
- if ( spellRange )
- {
- if ( !sourceUnit )
- {
- *minRange = spellRange->MinRange[friendly];
- *maxRange = spellRange->MaxRange[friendly];
- return;
- }
- v13 = spellRange->Flags;
- if ( v13 & 1 )
- {
- *(_DWORD *)minRange = 0;
- if ( targetUnit
- || (v27.Data[0] = sourceUnit->dwordED8.Data[0],
- v27.Data[1] = sourceUnit->dwordED8.Data[1],
- v27.Data[2] = sourceUnit->dwordED8.Data[2],
- v27.Data[3] = sourceUnit->dwordED8.Data[3],
- (targetUnit = (CGUnit_C *)ClntObjMgrObjectPtr(&v27, 8)) != 0) )
- {
- targetUnitFields = targetUnit->Fields;
- }
- else
- {
- targetUnitFields = sourceUnit->Fields;
- }
- rangeModifier = (float)(*(float *)&sourceUnit->Fields->UNIT_FIELD_COMBATREACH + 1.3333334) + *(float *)&targetUnitFields->UNIT_FIELD_COMBATREACH;
- if ( rangeModifier <= 5.0 )
- rangeModifier = 5.0;
- }
- else
- {
- if ( v13 & 2 )
- {
- if ( targetUnit )
- targetUnitFields = targetUnit->Fields;
- else
- targetUnitFields = sourceUnit->Fields;
- v17 = (float)(*(float *)&sourceUnit->Fields->UNIT_FIELD_COMBATREACH + 1.3333334) + *(float *)&targetUnitFields->UNIT_FIELD_COMBATREACH;
- *minRange = v17;
- if ( v17 <= 5.0 )
- v17 = 5.0;
- *minRange = v17;
- *minRange = spellRange->MinRange[friendly] + v17;
- }
- else
- {
- *minRange = spellRange->MinRange[friendly];
- }
- *maxRange = spellRange->MaxRange[friendly];
- if ( targetObject && targetObject->Fields->OBJECT_FIELD_TYPE & 0x88 )// player or creature or corpse
- {
- v19 = *(float *)&sourceUnit->Fields->UNIT_FIELD_COMBATREACH;
- rangeModifier = targetUnit ? *(float *)&targetUnit->Fields->UNIT_FIELD_COMBATREACH + v19 : v19 + v19;
- v21 = *minRange;
- __asm { lahf }
- if ( __SETP__(_AH & 0x44, 0) ) // !isnan(v21) && !isZero(v21)
- {
- if ( !(spellRange->Flags & 2) )
- *minRange = v21 + rangeModifier;
- }
- }
- }
- if ( targetUnit
- && *(_DWORD *)(sourceUnit->dword12C + 64) & 0x80D// MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | MOVEMENTFLAG_FALLING; in other words, IsMoving()
- && *(_DWORD *)(targetUnit->dword12C + 64) & 0x80D// MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | MOVEMENTFLAG_FALLING; in other words, IsMoving()
- && !CGUnit_C::IsWalking(sourceUnit)
- && !CGUnit_C::IsWalking(targetUnit)
- && (spellRange->Flags & 1 || ((unsigned int)LOWORD(targetUnit->Object.Fields->OBJECT_FIELD_TYPE) >> 4) & 1) )
- {
- rangeModifier = rangeModifier + 2.6666667;
- }
- }
- if ( CheckSpellAttribute(spellInfo, 0, 2) ) // SPELL_ATTR0_REQ_AMMO - bow range (not relevant for 6.x)
- {
- if ( sourceUnit )
- {
- if ( ((unsigned int)LOWORD(sourceUnit->Object.Fields->OBJECT_FIELD_TYPE) >> 4) & 1 )
- {
- v23 = (CGItem_C *)CGBag_C::GetRangedItemPointer((int)&sourceUnit[2].dwordE48);
- if ( v23 )
- {
- v24 = sourceUnit->Object.Fields;
- v25 = v23->Object.Fields;
- v27.Data[0] = v24->OBJECT_FIELD_GUID.Data[0];
- v24 = (CGObjectData *)((char *)v24 + 4);
- v27.Data[1] = v24->OBJECT_FIELD_GUID.Data[0];
- v24 = (CGObjectData *)((char *)v24 + 4);
- v27.Data[2] = v24->OBJECT_FIELD_GUID.Data[0];
- v27.Data[3] = v24->OBJECT_FIELD_GUID.Data[1];
- v26 = WowClientDB2<ItemRecSparse_C>::GetRecord((int)&g_itemSparseDB, v25->OBJECT_FIELD_ENTRY, &v27, 0, 0, 0);
- if ( v26 )
- *maxRange = (float)(*(float *)(v26 + 272) * 0.0099999998) * *maxRange;// 0.0099999998 is just the closest representable value to 0.01, use that when writing code instead (or / 100)
- }
- }
- }
- }
- ApplyModifiers(spellInfo, maxRange, 5); // SPELLMOD_RANGE
- *maxRange = *maxRange + rangeModifier;
- }