Changeset 136

Show
Ignore:
Timestamp:
11/19/08 13:39:20 (17 years ago)
Author:
yumileroy
Message:

[svn] Provide creature dual wield support.
Update glancing damage formula.
Do not daze creatures when other creatures attack from the back (need to find a better way).
Fix the damage calculation of +damage aura.

Original author: megamage
Date: 2008-10-29 20:00:21-05:00

Location:
trunk/src/game
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/Creature.cpp

    r123 r136  
    12351235    SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cinfo->mindmg * damagemod); 
    12361236    SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cinfo->maxdmg * damagemod); 
    1237  
    1238     SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,cinfo->minrangedmg * damagemod); 
    1239     SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,cinfo->maxrangedmg * damagemod); 
     1237    SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, cinfo->mindmg * damagemod); 
     1238    SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, cinfo->maxdmg * damagemod); 
     1239    SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, cinfo->minrangedmg * damagemod); 
     1240    SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, cinfo->maxrangedmg * damagemod); 
    12401241 
    12411242    SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod); 
     1243    SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, cinfo->rangedattackpower * damagemod); 
    12421244} 
    12431245 
  • trunk/src/game/Player.cpp

    r128 r136  
    993993 
    994994    Unit::Update( p_time ); 
    995  
    996     // update player only attacks 
    997     if(uint32 ranged_att = getAttackTimer(RANGED_ATTACK)) 
    998     { 
    999         setAttackTimer(RANGED_ATTACK, (p_time >= ranged_att ? 0 : ranged_att - p_time) ); 
    1000     } 
    1001  
    1002     if(uint32 off_att = getAttackTimer(OFF_ATTACK)) 
    1003     { 
    1004         setAttackTimer(OFF_ATTACK, (p_time >= off_att ? 0 : off_att - p_time) ); 
    1005     } 
    1006995 
    1007996    time_t now = time (NULL); 
  • trunk/src/game/Player.h

    r126 r136  
    17511751        bool CanBlock() const { return m_canBlock; } 
    17521752        void SetCanBlock(bool value); 
    1753         bool CanDualWield() const { return m_canDualWield; } 
    1754         void SetCanDualWield(bool value) { m_canDualWield = value; } 
    17551753 
    17561754        void SetRegularAttackTime(); 
     
    22412239        bool m_canParry; 
    22422240        bool m_canBlock; 
    2243         bool m_canDualWield; 
    22442241        uint8 m_swingErrorMsg; 
    22452242        float m_ammoDPS; 
  • trunk/src/game/SpellEffects.cpp

    r130 r136  
    34413441void Spell::EffectDualWield(uint32 /*i*/) 
    34423442{ 
    3443     if (unitTarget->GetTypeId() == TYPEID_PLAYER) 
    3444         ((Player*)unitTarget)->SetCanDualWield(true); 
     3443    unitTarget->SetCanDualWield(true); 
     3444    if(unitTarget->GetTypeId() == TYPEID_UNIT) 
     3445        ((Creature*)unitTarget)->UpdateDamagePhysical(OFF_ATTACK); 
    34453446} 
    34463447 
  • trunk/src/game/StatSystem.cpp

    r102 r136  
    667667    UpdateMaxHealth(); 
    668668    UpdateAttackPowerAndDamage(); 
     669    UpdateAttackPowerAndDamage(true); 
    669670 
    670671    for(int i = POWER_MANA; i < MAX_POWERS; ++i) 
     
    710711void Creature::UpdateAttackPowerAndDamage(bool ranged) 
    711712{ 
     713    //automatically update weapon damage after attack power modification 
    712714    if(ranged) 
    713         return; 
    714  
    715     //automatically update weapon damage after attack power modification 
    716     UpdateDamagePhysical(BASE_ATTACK); 
     715        UpdateDamagePhysical(RANGED_ATTACK); 
     716    else 
     717    { 
     718        UpdateDamagePhysical(BASE_ATTACK); 
     719        UpdateDamagePhysical(OFF_ATTACK); 
     720    } 
    717721} 
    718722 
    719723void Creature::UpdateDamagePhysical(WeaponAttackType attType) 
    720724{ 
    721     if(attType > BASE_ATTACK) 
    722         return; 
    723  
    724     UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; 
    725  
    726     float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; 
     725    UnitMods unitMod; 
     726    switch(attType) 
     727    { 
     728        case BASE_ATTACK: 
     729        default: 
     730            unitMod = UNIT_MOD_DAMAGE_MAINHAND; 
     731            break; 
     732        case OFF_ATTACK: 
     733            unitMod = UNIT_MOD_DAMAGE_OFFHAND; 
     734            break; 
     735        case RANGED_ATTACK: 
     736            unitMod = UNIT_MOD_DAMAGE_RANGED; 
     737            break; 
     738    } 
     739 
     740    float att_speed = float(GetAttackTime(attType))/1000.0f; 
    727741 
    728742    float base_value  = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; 
     
    731745    float total_pct   = GetModifierValue(unitMod, TOTAL_PCT); 
    732746 
    733     float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); 
    734     float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); 
     747    float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); 
     748    float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); 
    735749 
    736750    float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct ; 
    737751    float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct ; 
    738752 
    739     SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); 
    740     SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); 
     753    switch(attType) 
     754    { 
     755        case BASE_ATTACK: 
     756        default: 
     757            SetStatFloatValue(UNIT_FIELD_MINDAMAGE,mindamage); 
     758            SetStatFloatValue(UNIT_FIELD_MAXDAMAGE,maxdamage); 
     759            break; 
     760        case OFF_ATTACK: 
     761            SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE,mindamage); 
     762            SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE,maxdamage); 
     763            break; 
     764        case RANGED_ATTACK: 
     765            SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,mindamage); 
     766            SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,maxdamage); 
     767            break; 
     768    } 
    741769} 
    742770 
  • trunk/src/game/Unit.cpp

    r131 r136  
    159159 
    160160    m_extraAttacks = 0; 
     161    m_canDualWield = false; 
    161162 
    162163    m_state = 0; 
     
    280281 
    281282    if(uint32 base_att = getAttackTimer(BASE_ATTACK)) 
    282     { 
    283283        setAttackTimer(BASE_ATTACK, (p_time >= base_att ? 0 : base_att - p_time) ); 
    284     } 
     284    if(uint32 ranged_att = getAttackTimer(RANGED_ATTACK)) 
     285        setAttackTimer(RANGED_ATTACK, (p_time >= ranged_att ? 0 : ranged_att - p_time) ); 
     286    if(uint32 off_att = getAttackTimer(OFF_ATTACK)) 
     287        setAttackTimer(OFF_ATTACK, (p_time >= off_att ? 0 : off_att - p_time) ); 
    285288 
    286289    // update abilities available only for fraction of time 
     
    298301        return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true); 
    299302    else 
    300         return false; 
     303        return m_canDualWield; 
    301304} 
    302305 
     
    17701773    /// If this is a creature and it attacks from behind it has a probability to daze it's victim 
    17711774    if( (outcome==MELEE_HIT_CRIT || outcome==MELEE_HIT_CRUSHING || outcome==MELEE_HIT_NORMAL || outcome==MELEE_HIT_GLANCING) && 
    1772         GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this) ) 
     1775        GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this) 
     1776        && pVictim->GetTypeId() == TYPEID_PLAYER) 
    17731777    { 
    17741778        // -probability is between 0% and 40% 
     
    20572061        case MELEE_HIT_GLANCING: 
    20582062        { 
    2059             float reducePercent = 1.0f;                     //damage factor 
    2060  
    2061             // calculate base values and mods 
    2062             float baseLowEnd = 1.3; 
    2063             float baseHighEnd = 1.2; 
    2064             switch(getClass())                              // lowering base values for casters 
    2065             { 
    2066                 case CLASS_SHAMAN: 
    2067                 case CLASS_PRIEST: 
    2068                 case CLASS_MAGE: 
    2069                 case CLASS_WARLOCK: 
    2070                 case CLASS_DRUID: 
    2071                     baseLowEnd  -= 0.7; 
    2072                     baseHighEnd -= 0.3; 
    2073                     break; 
    2074             } 
    2075  
    2076             float maxLowEnd = 0.6; 
    2077             switch(getClass())                              // upper for melee classes 
    2078             { 
    2079                 case CLASS_WARRIOR: 
    2080                 case CLASS_ROGUE: 
    2081                     maxLowEnd = 0.91;                       //If the attacker is a melee class then instead the lower value of 0.91 
    2082             } 
    2083  
    2084             // calculate values 
    2085             int32 diff = int32(pVictim->GetDefenseSkillValue(this)) - int32(GetWeaponSkillValue(attType,pVictim)); 
    2086             float lowEnd  = baseLowEnd - ( 0.05f * diff ); 
    2087             float highEnd = baseHighEnd - ( 0.03f * diff ); 
    2088  
    2089             // apply max/min bounds 
    2090             if ( lowEnd < 0.01f )                           //the low end must not go bellow 0.01f 
    2091                 lowEnd = 0.01f; 
    2092             else if ( lowEnd > maxLowEnd )                  //the smaller value of this and 0.6 is kept as the low end 
    2093                 lowEnd = maxLowEnd; 
    2094  
    2095             if ( highEnd < 0.2f )                           //high end limits 
    2096                 highEnd = 0.2f; 
    2097             if ( highEnd > 0.99f ) 
    2098                 highEnd = 0.99f; 
    2099  
    2100             if(lowEnd > highEnd)                            // prevent negative range size 
    2101                 lowEnd = highEnd; 
    2102  
    2103             reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd ); 
    2104  
    2105             *damage = uint32(reducePercent * *damage); 
    2106             cleanDamage->damage += *damage; 
     2063            int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel()); 
     2064            if (leveldif > 3) leveldif = 3; 
     2065            *damage *= (1 - leveldif * 0.1f); 
     2066            cleanDamage->damage = *damage; 
    21072067            *hitInfo |= HITINFO_GLANCING; 
    21082068            break; 
     
    75767536 
    75777537    float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; 
    7578     float TakenActualBenefit = TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty; 
     7538    float TakenActualBenefit = TakenAdvertisedBenefit; 
     7539    if(spellProto->SpellFamilyName) 
     7540        TakenActualBenefit *= (CastingTime / 3500.0f) * DotFactor * LvlPenalty; 
    75797541 
    75807542    float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod; 
  • trunk/src/game/Unit.h

    r110 r136  
    718718        bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; } 
    719719        bool haveOffhandWeapon() const; 
     720        bool CanDualWield() const { return m_canDualWield; } 
     721        void SetCanDualWield(bool value) { m_canDualWield = value; } 
    720722        bool canReachWithAttack(Unit *pVictim) const; 
    721723        bool IsWithinCombatDist(Unit *obj, float dist2compare) const; 
    722724        uint32 m_extraAttacks; 
     725        bool m_canDualWield; 
    723726 
    724727        void _addAttacker(Unit *pAttacker)                  // must be called only from Unit::Attack(Unit*)