Skip to content

Clarify damage calculation for Blade’s main hand and off hand #135

@muzsor

Description

@muzsor

Hello!

I have noticed some unclear points regarding the damage calculation for the Blade’s main hand and off hand weapons, and I would like to kindly request some clarification.

From my understanding, the Blade’s auto attack animation cycle should proceed as follows:

  1. Main hand damage

  2. Main hand + Off hand damage

  3. Repeat the cycle...

Could you please confirm if my understanding of the auto attack animation in the game is correct?

If that’s the case, auto-attack-worker.js calculates main and off hand damage alternately, which does not correspond with the in game mechanics.

// ../components/calculations/workers/auto-attack-worker.js

self.onmessage = function (event) {

    /* Code omitted for brevity */
	
	let leftHand = false;

	/* Code omitted for brevity */

    for (let i = 0; i < cycles; i++) {
		
		/* Code omitted for brevity */
		
		// It’ll always calculate the damage for each hand separately.
		if (Context.player.job.id === 2246 && Context.player.equipment.offhand != null) {
			leftHand = !leftHand;			
		}
        
        const res = {
            damage: getDamage(leftHand),
            critical: (Context.attackFlags & Utils.ATTACK_FLAGS.CRITICAL) !== 0,
            block: (Context.attackFlags & Utils.ATTACK_FLAGS.BLOCKING) !== 0,
            miss: (Context.attackFlags & Utils.ATTACK_FLAGS.MISS) !== 0,
            parry: (Context.attackFlags & Utils.ATTACK_FLAGS.PARRY) !== 0,
            double: (Context.attackFlags & Utils.ATTACK_FLAGS.DOUBLE) !== 0,
            afterDamageProps: Context.afterDamageProps
        };

        out.push(res);
    }

    self.postMessage(out);
};

I was thinking it might be helpful to adjust it so that it loops more like the auto attack animation in the game, something like this:

// ../flyff/flyffutils.js

export const HAND_FLAGS = {
    RIGHT: 1 << 0,
    LEFT: 1 << 1,
    DUAL: (1 << 0) | (1 << 1)
}
// ../flyff/flyffdamagecalculator.js

/**
 * Get the damage done by a simulated attack in the current context.
 * @param isDualWield Whether the attack uses dual wield (attacking with both hands)
 * @returns The total damage value
 */
export function getDamage(isDualWield) {
    // Check for miss is the first thing
    if (Context.settings.missingEnabled && !Context.isSkillAttack() && (Context.attackFlags & Utils.ATTACK_FLAGS.MAGIC) == 0) {
        const hitResult = checkHitRate();
        if (hitResult != 0) {
            Context.attackFlags |= hitResult;
            return 0;
        }
    }

    let damage = 0;
    let handFlag = Utils.HAND_FLAGS.RIGHT;
    if (isDualWield) {
        handFlag = Utils.HAND_FLAGS.DUAL;
    }
    for (let flag = 0x01; flag <= 0x02; ++flag) {
        if (handFlag & flag) {
            damage += calcDamage(flag == Utils.HAND_FLAGS.LEFT);
        }
    }

    return damage;
}

// Change to calcDamage(leftHand)
function calcDamage(leftHand) {
/* ... */
} 
// ../components/calculations/workers/auto-attack-worker.js

let isDualWield = false;

const res = {
	damage: getDamage(isDualWield),
	critical: (Context.attackFlags & Utils.ATTACK_FLAGS.CRITICAL) !== 0,
	block: (Context.attackFlags & Utils.ATTACK_FLAGS.BLOCKING) !== 0,
	miss: (Context.attackFlags & Utils.ATTACK_FLAGS.MISS) !== 0,
	parry: (Context.attackFlags & Utils.ATTACK_FLAGS.PARRY) !== 0,
	double: (Context.attackFlags & Utils.ATTACK_FLAGS.DOUBLE) !== 0,
	afterDamageProps: Context.afterDamageProps
};

if (Context.player.job.id === 2246 && Context.player.equipment.offhand != null) {
	isDualWield = !isDualWield;
}

I noticed that since getDamage() includes the logic for checking hit rate, it can cause situations where the two hands don't land their hits at the same time.

It might be a good idea to separate the hit rate calculation to more accurately reflect how damage is actually handled in the game.

Another thing I’m not sure about is whether the icon only shows up when both hands crit or block at the same time, it doesn't appear with just one hand.

Maybe other options could work better, looking forward to any feedback.

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions