Jump to content

thenecromancer

Members
  • Posts

    110
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Posts posted by thenecromancer

  1. I usualy do not ask about ETAs, but this thing has been REALLY useful in past, and there is still no update for 3.2 client ( which is needed ), I am wondering if it is going to be up in future ? ( I cannot find sources of that thing either )

    As far as I understand it does not need any major overhaul to support new version.

  2. Only change that client will notice is setting skin tone byte in player_bytes_2, and this is safe as long as dbc do not have any illegal skin Id ( and player would have also to select it, so it would have to crash while already using that chair ), however dbc editing is not recommended and shouldn't be done... ever..

  3. What does it change:

    Seal of Command shouldn't recieve any spell damage bonus after 3.2.# client switch

    Judgement of Command however should have been increased by both Attack Power and Spell Power since early 3.#.# releases

    diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
    index 1a0b9d4..5e390b3 100644
    --- a/src/game/SpellEffects.cpp
    +++ b/src/game/SpellEffects.cpp
    @@ -4472,12 +4472,12 @@ void Spell::EffectWeaponDmg(uint32 i)
            }
            case SPELLFAMILY_PALADIN:
            {
    -            // Seal of Command - receive benefit from Spell Damage and Healing
    -            if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000002000000))
    +            // Judgement of Command - receive benefit from Spell Damage and Attack Power
    +            if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x00020000000000))
                {
                    spellBonusNeedWeaponDamagePercentMod = true;// apply weaponDamagePercentMod to spell_bonus (and then to all bonus, fixes and weapon already have applied)
    -                spell_bonus += int32(0.23f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
    -                spell_bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget));
    +                spell_bonus += int32(0.08f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
    +                spell_bonus += int32(0.13f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
                }
                break;
            }

    EDIT: I'll not spam forums with very similar threads, I've just noticed few more ( mostly Paladin ) functions outdated in same function:

    * Old removed Seals ( no longer exist in game )

    * Whirlwind recieving offhand damage ( Off-hand damage should be handled by triggering another spell )

    diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
    index 5e390b3..da4bd02 100644
    --- a/src/game/SpellEffects.cpp
    +++ b/src/game/SpellEffects.cpp
    @@ -4401,14 +4401,8 @@ void Spell::EffectWeaponDmg(uint32 i)
        {
            case SPELLFAMILY_WARRIOR:
            {
    -            // Whirlwind, single only spell with 2 weapon white damage apply if have
    -            if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000400000000)))
    -            {
    -                if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK,true))
    -                    spell_bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized);
    -            }
                // Devastate bonus and sunder armor refresh
    -            else if(m_spellInfo->SpellVisual[0] == 12295 && m_spellInfo->SpellIconID == 1508)
    +            if(m_spellInfo->SpellVisual[0] == 12295 && m_spellInfo->SpellIconID == 1508)
                {
                    uint32 stack = 0;
                    // Need refresh all Sunder Armor auras from this caster
    @@ -4627,27 +4621,6 @@ void Spell::EffectWeaponDmg(uint32 i)
            if(m_caster->GetTypeId()==TYPEID_PLAYER)
                ((Player*)m_caster)->AddComboPoints(unitTarget, 1);
        }
    -    else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_PALADIN)
    -    {
    -        // Judgement of Blood/of the Martyr backlash damage (33%)
    -        if(m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153)
    -        {
    -            int32 damagePoint  = m_damage * 33 / 100;
    -            if(m_spellInfo->Id == 31898)
    -                m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
    -            else
    -                m_caster->CastCustomSpell(m_caster, 53725, &damagePoint, NULL, NULL, true);
    -        }
    -        // Seal of Blood/of the Martyr backlash damage (10%)
    -        else if(m_spellInfo->SpellIconID==2293)
    -        {
    -            int32 damagePoint  = m_damage * 10 / 100;
    -            if(m_spellInfo->Id == 31893)
    -                m_caster->CastCustomSpell(m_caster, 32221, &damagePoint, NULL, NULL, true);
    -            else
    -                m_caster->CastCustomSpell(m_caster, 53718, &damagePoint, NULL, NULL, true);
    -        }
    -    }
    
        // take ammo
        if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)

  4. What does this do:

    It switches display ID depending on player's racial features.

    I cannot guarantee correctness of these IDs ( some are very similar ), but it is easy to correct them

    diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
    index bd852d8..8fa949f 100644
    --- a/src/game/SpellAuras.cpp
    +++ b/src/game/SpellAuras.cpp
    @@ -2783,85 +2783,36 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
        switch(form)
        {
            case FORM_CAT:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 892;
    -            else
    -                modelid = 8571;
                PowerType = POWER_ENERGY;
                break;
    -        case FORM_TRAVEL:
    -            modelid = 632;
    -            break;
    -        case FORM_AQUA:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 2428;
    -            else
    -                modelid = 2428;
    -            break;
            case FORM_BEAR:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 2281;
    -            else
    -                modelid = 2289;
    -            PowerType = POWER_RAGE;
    -            break;
    -        case FORM_GHOUL:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 10045;
    -            break;
            case FORM_DIREBEAR:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 2281;
    -            else
    -                modelid = 2289;
    +        case FORM_BATTLESTANCE:
    +        case FORM_BERSERKERSTANCE:
    +        case FORM_DEFENSIVESTANCE:
                PowerType = POWER_RAGE;
                break;
    +        case FORM_TRAVEL:
    +        case FORM_AQUA:
    +        case FORM_GHOUL:
            case FORM_CREATUREBEAR:
    -            modelid = 902;
    -            break;
            case FORM_GHOSTWOLF:
    -            modelid = 4613;
    -            break;
            case FORM_FLIGHT:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 20857;
    -            else
    -                modelid = 20872;
    -            break;
            case FORM_MOONKIN:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 15374;
    -            else
    -                modelid = 15375;
    -            break;
            case FORM_FLIGHT_EPIC:
    -            if(Player::TeamForRace(m_target->getRace()) == ALLIANCE)
    -                modelid = 21243;
    -            else
    -                modelid = 21244;
    -            break;
            case FORM_METAMORPHOSIS:
    -            modelid = 25277;
    -            break;
            case FORM_AMBIENT:
            case FORM_SHADOW:
            case FORM_STEALTH:
    -            break;
            case FORM_TREE:
    -            modelid = 864;
    -            break;
    -        case FORM_BATTLESTANCE:
    -        case FORM_BERSERKERSTANCE:
    -        case FORM_DEFENSIVESTANCE:
    -            PowerType = POWER_RAGE;
    -            break;
            case FORM_SPIRITOFREDEMPTION:
    -            modelid = 16031;
                break;
            default:
                sLog.outError("Auras: Unknown Shapeshift Type: %u, SpellId %u.", m_modifier.m_miscvalue, GetId());
        }
    
    +    modelid = m_target->GetModelForForm(form);
    +
        // remove polymorph before changing display id to keep new display id
        switch ( form )
        {
    diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
    index ea2837a..ea4b31e 100644
    --- a/src/game/Unit.cpp
    +++ b/src/game/Unit.cpp
    @@ -12424,3 +12424,203 @@ void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpee
            NearTeleportTo(fx, fy, fz, GetOrientation(), this == target);
        }
    }
    +
    +uint32 Unit::GetModelForForm(ShapeshiftForm form)
    +{
    +    switch(form)
    +    {
    +        case FORM_CAT:
    +            // Based on Hair color
    +            if (getRace() == RACE_NIGHTELF)
    +            {
    +                uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
    +                switch (hairColor)
    +                {
    +                    case 7: // Violet
    +                    case 8: 
    +                        return 29405;
    +                    case 3: // Light Blue
    +                        return 29406;
    +                    case 0: // Green
    +                    case 1: // Light Green
    +                    case 2: // Dark Green
    +                        return 29407;
    +                    case 4: // White
    +                        return 29408;
    +                    default: // original - Dark Blue
    +                        return 892;
    +                }
    +            }
    +            // Based on Skin color
    +            else if (getRace() == RACE_TAUREN)
    +            {
    +                uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
    +                // Male
    +                if (getGender() == GENDER_MALE)
    +                {
    +                    switch(skinColor)
    +                    {
    +                        case 12: // White
    +                        case 13:
    +                        case 14:
    +                        case 18: // Completly White
    +                            return 29409;
    +                        case 9: // Light Brown
    +                        case 10:
    +                        case 11:
    +                            return 29410;
    +                        case 6: // Brown 
    +                        case 7:
    +                        case 8:
    +                            return 29411;
    +                        case 0: // Dark
    +                        case 1:
    +                        case 2:
    +                        case 3: // Dark Grey
    +                        case 4:
    +                        case 5:
    +                            return 29412;
    +                        default: // original - Grey
    +                            return 8571;
    +                    }
    +                }
    +                // Female
    +                else switch (skinColor)
    +                {
    +                    case 10: // White
    +                        return 29409;
    +                    case 6: // Light Brown
    +                    case 7:
    +                        return 29410;
    +                    case 4: // Brown
    +                    case 5:
    +                        return 29411;
    +                    case 0: // Dark
    +                    case 1:
    +                    case 2:
    +                    case 3:
    +                        return 29412;
    +                    default: // original - Grey
    +                        return 8571;
    +                }
    +            }
    +            else if(Player::TeamForRace(getRace())==ALLIANCE)
    +                return 892;
    +            else
    +                return 8571;
    +        case FORM_DIREBEAR:
    +        case FORM_BEAR:
    +            // Based on Hair color
    +            if (getRace() == RACE_NIGHTELF)
    +            {
    +                uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
    +                switch (hairColor)
    +                {
    +                    case 0: // Green
    +                    case 1: // Light Green
    +                    case 2: // Dark Green
    +                        return 29413; // 29415?
    +                    case 6: // Dark Blue
    +                        return 29414;
    +                    case 4: // White
    +                        return 29416;
    +                    case 3: // Light Blue
    +                        return 29417;
    +                    default: // original - Violet
    +                        return 2281;
    +                }
    +            }
    +            // Based on Skin color
    +            else if (getRace() == RACE_TAUREN)
    +            {
    +                uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
    +                // Male
    +                if (getGender() == GENDER_MALE)
    +                {
    +                    switch (skinColor)
    +                    {
    +                        case 0: // Dark (Black)
    +                        case 1:
    +                        case 2:
    +                            return 29418;
    +                        case 3: // White
    +                        case 4:
    +                        case 5:
    +                        case 12:
    +                        case 13:
    +                        case 14:
    +                            return 29419;
    +                        case 9: // Light Brown/Grey
    +                        case 10:
    +                        case 11:
    +                        case 15:
    +                        case 16:
    +                        case 17:
    +                            return 29420;
    +                        case 18: // Completly White
    +                            return 29421;
    +                        default: // original - Brown
    +                            return 2289;
    +                    }
    +                }
    +                // Female
    +                else switch (skinColor)
    +                {
    +                    case 0: // Dark (Black)
    +                    case 1:
    +                        return 29418;
    +                    case 2: // White
    +                    case 3:
    +                        return 29419;
    +                    case 6: // Light Brown/Grey
    +                    case 7:
    +                    case 8:
    +                    case 9:
    +                        return 29420;
    +                    case 10: // Completly White
    +                        return 29421;
    +                    default: // original - Brown
    +                        return 2289;
    +                }
    +            }
    +            else if(Player::TeamForRace(getRace())==ALLIANCE)
    +                return 2281;
    +            else
    +                return 2289;
    +        case FORM_TRAVEL:
    +            return 632;
    +        case FORM_AQUA:
    +            if(Player::TeamForRace(getRace())==ALLIANCE)
    +                return 2428;
    +            else
    +                return 2428;
    +        case FORM_GHOUL:
    +            return 24994;
    +        case FORM_CREATUREBEAR:
    +            return 902;
    +        case FORM_GHOSTWOLF:
    +            return 4613;
    +        case FORM_FLIGHT:
    +            if(Player::TeamForRace(getRace())==ALLIANCE)
    +                return 20857;
    +            else
    +                return 20872;
    +        case FORM_MOONKIN:
    +            if(Player::TeamForRace(getRace())==ALLIANCE)
    +                return 15374;
    +            else
    +                return 15375;
    +        case FORM_FLIGHT_EPIC:
    +            if(Player::TeamForRace(getRace())==ALLIANCE)
    +                return 21243;
    +            else
    +                return 21244;
    +        case FORM_METAMORPHOSIS:
    +            return 25277;
    +        case FORM_TREE:
    +            return 864;
    +        case FORM_SPIRITOFREDEMPTION:
    +            return 16031;
    +    }
    +    return 0;
    +}
    \\ No newline at end of file
    diff --git a/src/game/Unit.h b/src/game/Unit.h
    index 43b305d..8e89227 100644
    --- a/src/game/Unit.h
    +++ b/src/game/Unit.h
    @@ -1519,6 +1519,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
            void AddPetAura(PetAura const* petSpell);
            void RemovePetAura(PetAura const* petSpell);
    
    +        uint32 GetModelForForm(ShapeshiftForm form);
        protected:
            explicit Unit ();
    

  5. What does it change:

    Do not skip part of barbershop packet changing skin tone

    Misc info:

    Sorry for weird patch format, if it's possible I've missed something that will prevent this to apply smoothly

    75% of the cost seems to be in sync with game display.

    Note that currently this is useful for only a single race in game, other's are sending null value ( though I did not check for it, I'm sure they're not creating any conflicts with this )

    diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
    index 20ac51d..2e97f07 100644
    --- a/src/game/CharacterHandler.cpp
    +++ b/src/game/CharacterHandler.cpp
    @@ -1064,8 +1064,8 @@ void WorldSession::HandleAlterAppearance( WorldPacket & recv_data )
    {
        sLog.outDebug("CMSG_ALTER_APPEARANCE");
    
    -    uint32 Hair, Color, FacialHair;
    -    recv_data >> Hair >> Color >> FacialHair;
    +    uint32 Hair, Color, FacialHair, SkinColor;
    +    recv_data >> Hair >> Color >> FacialHair >> SkinColor;
    
        BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
    
    @@ -1077,7 +1077,12 @@ void WorldSession::HandleAlterAppearance( WorldPacket & recv_data )
        if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
            return;
    
    -    uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id);
    +    BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
    +
    +    if( bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender()))
    +        return;
    +
    +    uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor);
    
        // 0 - ok
        // 1,3 - not enough money
    @@ -1102,6 +1107,8 @@ void WorldSession::HandleAlterAppearance( WorldPacket & recv_data )
        _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
        _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color));
        _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
    +    if (bs_skinColor)
    +        _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
    
        _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
    
    diff --git a/src/game/Player.cpp b/src/game/Player.cpp
    index 05130dd..4d499ea 100644
    --- a/src/game/Player.cpp
    +++ b/src/game/Player.cpp
    @@ -19532,7 +19532,7 @@ bool Player::CanCaptureTowerPoint()
               );
    }
    
    -uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair)
    +uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin )
    {
        uint32 level = getLevel();
    
    @@ -19542,8 +19542,9 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n
        uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2);
        uint8 haircolor = GetByteValue(PLAYER_BYTES, 3);
        uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0);
    +    uint8 skincolor = GetByteValue(PLAYER_BYTES, 0);
    
    -    if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair))
    +    if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair) && (!newSkin || (newSkin->hair_id == skincolor)))
            return 0;
    
        GtBarberShopCostBaseEntry const *bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1);
    @@ -19562,6 +19563,9 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n
        if(facialhair != newfacialhair)
            cost += bsc->cost * 0.75f;                          // +3/4 of price
    
    +    if(newSkin && skincolor != newSkin->hair_id)
    +        cost += bsc->cost * 0.75f;                          // ??
    +
        return uint32(cost);
    }
    
    diff --git a/src/game/Player.h b/src/game/Player.h
    index 39a25e8..8fd4149 100644
    --- a/src/game/Player.h
    +++ b/src/game/Player.h
    @@ -1059,7 +1059,7 @@ class MANGOS_DLL_SPEC Player : public Unit
            std::string afkMsg;
            std::string dndMsg;
    
    -        uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair);
    +        uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin=NULL);
    
            PlayerSocial *GetSocial() { return m_social; }
    

  6. Well, sorry did just a quick look at the code :) ( scared of the wall of text )

    Well, here are some tips:

    *Add auras to pet even with zero values, and put them all in list of pointers.

    This list ( or lists ) can be quickly accessed from statsystem, so you shouldn't worry much about CPU usage ( but instead of deleting/readding them it'd be nice to just unapply modifier, change it's value and reapply it again )

    *You don't really have to add

    *Using template functions for resilience is ok, but it'd be probably much more editable if you used just 2 functions (crit chance reduction and crit/player damage reduction ) with 3/2 args ( original damage, rating name, crit boolean value ) for unit class ( in it check if unit is player or has player as owner, if found grab rating ( get rating name from function arg ), if not player typeid then just multiply value by 0.4 ), that will make it whole much better readable, as currently it is mostly duplicate stuff

    * Scaling existing auras with newly applied modifiers is needed for Aspect of the Beast if I remmember correctly ( so very probably not part of this patch )

    I like how is damage read from DB though, that makes fine-tuning much easier :)

  7. It would be much more useful if somebody removed this hack code used for years, and implemented usage for scaling auras ( they do pretty much everything except resilience ).

    Problem is that it will also need quite intensive updating of aura modifier amount ( and mainly modify already existing aura amount when modifier is applied/removed, this is not really that easy ), and those auras could maybe have a pointers in pet class, because of often access to them.

    EDIT: this is useful for you http://www.wowhead.com/?search=scaling

  8. If you set a byte value server should update those object for nearby players, and you probably can remove those functions out of the patch.

    If this does not work ( eg. GO art is not updated for clients nearby ) then it probably needs other kind of fix.

    In other words, those lines are kind of hack that shouldn't be needed.

  9. If you avoid doing those routines on every relocation it might be somewhat quirky.

    While not exactly realistic situation but this might be an extreme:

    Stealth user enters visibility range and stops moving. Reciever is not moving either. In this case if this was done in some sweet spot of those 500ms, they'd theoreticly never detect each other, until anyone move ( but in reality there is also some static check for stealth detection AFAIK ).

    On normal gameplay, this will come in cost of visibility update accuracy. I can see the worst problem with stealth though, because it works quite dynamicly it'll affect gameplay.

    If something affects gameplay, server admins usualy would want a way to configure it. Some might consider 200ms update as better trade-off, some might just ignore it, because they already has no more than one server update in that interval.

  10. You're doing it wrong, rune-using spells are sending rune state mask ( states of runes before and after cast ) so client will show correctly cooldown on them. This is quite logical and it keeps rune slot in sync.

    IDK what is that RP bug about, because on TC there was never such problem.

    Also bear in mind that few spells cost runic power, but also have Rune cost ( which is unused, but Mangos might still check for it, and Mind Freeze is nice example of such spell ), try to check out if spell has rune powertype before manipulating with runes.

    EDIT: I see that you've figured that out in another topic...

  11. It is a guid stored and sent as unit value at time of channeling start ( unit field, do not know what enum it has assigned but you should figure it without much efforts ), but I'm afraid it might be unsafe, you should test it.

    ( for AE spells you can also use original casting coordinates ), this is just a timesafer, because your original idea is interesting but they did not make it easy ...

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use