EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=590)
-   -   PC main and second hand attacks (https://www.eqemulator.org/forums/showthread.php?t=26316)

Congdar 09-23-2008 12:22 PM

PC main and second hand attacks
 
This is the main hand and secondary hand client attack logic from the client_process.cpp file starting at line 253 in the 1129 source. I've indicated in blue text a couple of places I think code should be added and in red text some code I think should be deleted.

For the primary hand, I added a check for the Raging Flurry AA that says its bonus should only be calculated on a successful tripple attack. Currently it always adds the bonus. The red text i think should be deleted because it is checking for Flurry AA on secondary hand and I think the Flurry attack is primary hand only. Also deleting the call to some Necromancer AA 183? that would never get called in an offhand attack. It may have been for the Raging Flurry but got changed to 183. So if I'm wrong about offhand flurry's, then maybe the 183 should be change to aaRagingFlurry. Additionally the bonus is different for main hand Flurry than it is for offhand flurry... 15, 30, 50 instead of 10, 20, 30.

The AA check for Ambidexterity I also want to delete in the if for dual wield. There's a bonus calculation right above it, but it ignores the bonus anyway and just plain gives you automatic dual wield on the secondary hand if you have this aa and it doesn't make any sense. The dualwield check also adds in the itembonus and spellbonus, but GetSkill also adds in the item bonus so I think GetRawSkill should be used instead. There's also an extra check for dual wield skill increase that should be deleted.

Should secondary hand get triple attack? Am I correct about secondary hand not supposed to get flurry?

Code:

                if (auto_attack && target != NULL && may_use_attacks && attack_timer.Check()) {
                        if (!CombatRange(target)) {
                                //Message(0,"Target's Name: %s",target->GetName());
                                //Message(0,"Target's X: %f, Your X: %f",target->CastToMob()->GetX(),GetX());
                                //Message(0,"Target's Y: %f, Your Y: %f",target->CastToMob()->GetY(),GetY());
                                //Message(0,"Target's Z: %f, Your Z: %f",target->CastToMob()->GetZ(),GetZ());
                                Message_StringID(13,TARGET_TOO_FAR);
                                //Message(13,"Your target is too far away, get closer!");
                        }
                        else if (target == this) {
                                Message_StringID(13,TRY_ATTACKING_SOMEONE);
                                //Message(13,"Try attacking someone else then yourself!");
                        }
                        /*
                        else if (CantSee(target)) {
                                Message(13,"You can't see your target from here.");
                        }*/
                        else if (target->GetHP() > -10) { // -10 so we can watch people bleed in PvP
                                if(CheckAAEffect(aaEffectRampage)){        //Dook- AA Destructive Force- AE attacks for duration
                                        entity_list.AEAttack(this, 30);
                                } else {
                                        Attack(target, 13);        // Kaiyodo - added attacking hand to arguments
                                }
                                // Kaiyodo - support for double attack. Chance based on formula from Monkly business
                                bool tripleAttackSuccess = false;
                                if( target && CanThisClassDoubleAttack() ) {
                                       
                                        if(CheckDoubleAttack(true)) {
                                                //should we allow rampage on double attack?
                                                if(CheckAAEffect(aaEffectRampage)) {
                                                        entity_list.AEAttack(this, 30);
                                                } else {
                                                        Attack(target, 13, true);
                                                }
                                        }
                                       
                                        //triple attack: rangers, monks, warriors, berserkers over level 60
                                        if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
                                                && GetLevel() >= 60) || SpecAttacks[SPECATK_TRIPLE])
                                          && CheckDoubleAttack(false,true))
                                        {
                                                tripleAttackSuccess = true;
                                                Attack(target, 13, true);
                                        }
                                       
                                        //quad attack, does this belong here??
                                        if(SpecAttacks[SPECATK_QUAD] && CheckDoubleAttack(false,true))
                                        {
                                                Attack(target, 13, true);
                                        }
                                }
                                if (target && GetAA(aaFlurry) > 0) {
                                        int flurrychance = 0;
                                        switch (GetAA(aaFlurry)) {
                                                case 1:
                                                        flurrychance += 10;
                                                        break;
                                                case 2:
                                                        flurrychance += 20;
                                                        break;
                                                case 3:
                                                        flurrychance += 30;
                                                        break;
                                        }
                                        if(tripleAttackSuccess) {
                                                tripleAttackSuccess = false;
                                                switch (GetAA(aaRagingFlurry)) {
                                                        case 1:
                                                                flurrychance += 10;
                                                                break;
                                                        case 2:
                                                                flurrychance += 20;
                                                                break;
                                                        case 3:
                                                                flurrychance += 30;
                                                                break;
                                                }
                                        }
                                        if (rand()%1000 < flurrychance) {
                                                Message_StringID(MT_CritMelee, 128);
                                                Attack(target, 13, true);
                                               
                                                //50% chance for yet another attack?
                                                if(MakeRandomFloat(0, 1) < 0.5)
                                                        Attack(target, 13, true);
                                        }
                                }
                               
                                if (target && (GetAA(aaPunishingBlade) > 0 || GetAA(aaSpeedoftheKnight) > 0)) {
                                        ItemInst *wpn = GetInv().GetItem(SLOT_PRIMARY);
                                        if(wpn){
                                                if(wpn->GetItem()->ItemType == ItemType2HS ||
                                                        wpn->GetItem()->ItemType == ItemType2HB ||
                                                        wpn->GetItem()->ItemType == ItemType2HPierce )
                                                {
                                                        int extatk = GetAA(aaPunishingBlade)*5;
                                                        extatk += GetAA(aaSpeedoftheKnight)*5;
                                                        if(MakeRandomInt(0, 100) < extatk)
                                                        {
                                                                Attack(target, 13, true);
                                                        }
                                                }
                                        }
                                }
                        }
                }
               
                if (GetClass() == WARRIOR || GetClass() == BERSERKER) {
                        if(!dead && !berserk && this->GetHPRatio() < 30) {
        //                        char temp[100];
        //                        snprintf(temp, 100, "%s goes into a berserker frenzy!", this->GetName());
        //                        entity_list.MessageClose(this, 0, 200, 10, temp);
                                entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_START, GetName());
                                this->berserk = true;
                        }
                        if (berserk && this->GetHPRatio() > 30) {
        //                        char temp[100];
        //                        snprintf(temp, 100, "%s is no longer berserk.", this->GetName());
        //                        entity_list.MessageClose(this, 0, 200, 10, temp);
                                entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_END, GetName());
                                this->berserk = false;
                        }
                }
               
                // Kaiyodo - Check offhand attack timer
                if(auto_attack && may_use_attacks && target != NULL
                        && CanThisClassDualWield() && attack_dw_timer.Check()) {
                       
                        // Range check
                        if(!CombatRange(target)) {
                                //Message(13,"Your target is too far away, get closer! (dual)");
                                Message_StringID(13,TARGET_TOO_FAR);
                        }
                        // Don't attack yourself
                        else if(target == this) {
                                //Message(13,"Try attacking someone else then yourself! (dual)");
                                Message_StringID(13,TRY_ATTACKING_SOMEONE);
                        }
                        else if(target->GetHP() > -10) {
                                float DualWieldProbability = (GetRawSkill(DUAL_WIELD) + GetLevel()) / 400.0f; // 78.0 max
                                if(GetAA(aaAmbidexterity))
                                        DualWieldProbability += 0.1f;
                                //discipline effects:
                                DualWieldProbability += (spellbonuses.DualWeildChance + itembonuses.DualWeildChance) / 100.0f;
                               
                                float random = MakeRandomFloat(0, 1);
                                //if (random > 0.9)        //this dosent make sense...
                                        CheckIncreaseSkill(DUAL_WIELD);

                                if (random < DualWieldProbability  || GetAA(aaAmbidexterity)) { // Max 78% of DW
                                        if(CheckAAEffect(aaEffectRampage)) {
                                                entity_list.AEAttack(this, 30, 14);
                                        } else {
                                                Attack(target, 14);        // Single attack with offhand
                                        }
                                        CheckIncreaseSkill(DUAL_WIELD);
                                       
                                        if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
                                                if(CheckAAEffect(aaEffectRampage)) {
                                                        entity_list.AEAttack(this, 30, 14);
                                                } else {
                                                        if(target && target->GetHP() > -10)
                                                                Attack(target, 14);        // Single attack with offhand
                                                }
                                        }
                                }
                                if (target && GetAA(aaFlurry) > 0) {
                                        int flurrychance = 0;
                                        switch (GetAA(aaFlurry)) {
                                                case 1:
                                                        flurrychance += 15;
                                                        break;
                                                case 2:
                                                        flurrychance += 30;
                                                        break;
                                                case 3:
                                                        flurrychance += 50;
                                                        break;
                                        }
                                        switch (GetAA(183)) {
                                                case 1:
                                                        flurrychance += 10;
                                                        break;
                                                case 2:
                                                        flurrychance += 20;
                                                        break;
                                                case 3:
                                                        flurrychance += 30;
                                                        break;
                                        }
                                        if (rand()%1000 < flurrychance) {
                                                Message_StringID(MT_CritMelee, 128);
                                                Attack(target, 13, true);
                                               
                                                //50% chance for yet another attack?
                                                if(MakeRandomFloat(0, 1) < 0.5)
                                                        Attack(target, 13, true);
                                        }
                                }

                        }
                }


Congdar 09-24-2008 10:56 AM

<crickets>

trevius 09-24-2008 07:12 PM

It sounds like you have some nice fixes/adjustments in there. I don't remember enough about the exact working of Live to help verify some of the changes you made though.

Maybe the discussion in this post can help some.
http://www.eqemulator.net/forums/showthread.php?t=26099

I think most of your code sounds about right, but someone will need to confirm everything is pretty finalized before this could go into the source.

cavedude 09-24-2008 07:19 PM

I already moved the code part of this to submissions and stickied. So I guess, we'll take it from there.

Congdar 09-26-2008 03:44 PM

I made an error on the secondary hand... the check for increase in dual_wield skill needs to change. You can get a skill up even if you don't succeed in dual wielding so delete in red... add(leave it there) in blue:
Code:

                                float random = MakeRandomFloat(0, 1);
                                //if (random > 0.9)        //this dosent make sense...
                                CheckIncreaseSkill(DUAL_WIELD);
                                if (random < DualWieldProbability  || GetAA(aaAmbidexterity)) { // Max 78% of DW
                                        if(CheckAAEffect(aaEffectRampage)) {
                                                entity_list.AEAttack(this, 30, 14);
                                        } else {
                                                Attack(target, 14);        // Single attack with offhand
                                        }
                                        CheckIncreaseSkill(DUAL_WIELD);
                                       
                                        if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {

This code change results in added flurry bonus for main hand for Raging Fury AA only on successful tripple attack as described in the AA text and removes 100% dual wield if you have Ambidexterity AA and instead using the bonus and calucuation, and removes flurry attacks from the secondary hand. If secondary is supposed to flurry (i don't think it does) or if secondary is supposed to get tripple attack then somebody needs to speak up. It also removes double skillup in dual wield.

Congdar 09-26-2008 04:51 PM

GetSkill() and GetRawSkill(). Don't change it to GetRawSkill(). It seems that
Code:

itembonuses.skillmod[DUAL_WIELD]
checks from a different place than
Code:

itembonuses.DualWeildChance
I think the second way may be for Tribute but doesn't currently add the bonus in there. Disciplines for Rogue and Bard do work in spellbonuses.DualWeildChance, so not sure if it's redundant or ?


All times are GMT -4. The time now is 06:10 PM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.