Warband Script Enhancer 2 (v1.1.2.0)

Users who are viewing this thread

Raising ironflesh attribute button not clickable and reading str based attributes not readable after adding sf_inactive flag on other hardcoded skills is bugged for me in my own module here is what i did
Code:
skills = [
  ("trade","Trade",sf_base_att_cha|sf_effects_party|sf_inactive,10,"Every level of this skill reduces your trade penalty by 5%%. (Party skill)"),
  ("leadership","Leadership",sf_base_att_cha|sf_inactive,10,"Every point increases maximum number of troops you can command by 5, increases your party morale and reduces troop wages by 5%%. (Leader skill)"),
  ("prisoner_management","Prisoner Management",sf_base_att_cha|sf_inactive,10,"Every level of this skill increases maximum number of prisoners by %d. (Leader skill)"),
  ("herding", "Herding", sf_base_att_int, 10, "Ability to herd animals and breed them."),
  ("prospecting", "Prospecting", sf_base_att_int, 10, "Ability to prospect ores (as prospecting level gets higher, you get more quality from ores) and search for natural resources."),
  ("forestry", "Forestry", sf_base_att_int, 10, "Ability to plant, fertilize the trees and gather saplings from them."),
  ("labouring", "Labouring", sf_base_att_str, 10, "Ability to mine and cut down."),
  ("persuasion","Persuasion", sf_base_att_int|sf_inactive,10, "This skill helps you make other people accept your point of view. It also lowers the minimum level of relationship needed to get NPCs to do what you want. (Personal skill)"),
  ("engineer", "Engineer", sf_base_att_int, 10, "This skill allows you to construct buildings and siege equipments."),
  ("first_aid", "First Aid", sf_base_att_int, 10, "Ability to tend bleeding."),
  ("surgery", "Surgery", sf_base_att_int, 10, "Ability to do surgeries and fix limbs."),
  ("wound_treatment", "Wound Treatment", sf_base_att_int, 10, "Ability to treat tended wounds."),
  ("inventory_management", "Inventory Management", sf_base_att_int|sf_inactive, 10, "Increases inventory capacity by +6 kg per skill level."),
  ("spotting","Spotting",sf_base_att_int|sf_effects_party|sf_inactive,10,"Party seeing range is increased by 10%% per skill level. (Party skill)"),
  ("pathfinding","Path-finding",sf_base_att_int|sf_effects_party|sf_inactive,10,"Party map speed is increased by 3%% per skill level. (Party skill)"),
  ("tactics","Tactics",sf_base_att_int|sf_effects_party|sf_inactive,10,"Every two levels of this skill increases starting battle advantage by 1. (Party skill)"),
  ("tracking", "Tracking", sf_base_att_int, 10, "Tracks become more informative."),
  ("trainer", "Trainer", sf_base_att_int, 10, "Increase amount of experience gained. (Train someone to get experience for this skill.)"),
  ("tailoring", "Tailoring", sf_base_att_agi, 10, "Ability to sew clothes and make heraldry."),
  ("weapon_smithing", "Weapon Smithing", sf_base_att_int, 10, "Ability to forge weapons."),
  ("armour_smithing", "Armour Smithing", sf_base_att_int, 10, "Ability to knit armors and forge armor plates."),
  ("white_smithing", "White Smithing", sf_base_att_int, 10, "This skill allows you to mint coins. (You need to be in a kingdom and kingdom's official to mint coin.)"),
  ("looting","Looting",sf_base_att_agi|sf_effects_party|sf_inactive,10,"This skill increases the amount of loot obtained by 10%% per skill level. (Party skill)"),
  ("horse_archery", "Horse Archery", sf_base_att_agi, 10, "Reduces damage and accuracy penalties for archery and throwing from horseback."),
  ("riding", "Riding", sf_base_att_agi, 10, "Enables you to ride horses of higher difficulty levels and increases your riding speed and manuever."),
  ("athletics", "Athletics", sf_base_att_agi, 10, "Improves your running speed."),
  ("shield", "Shield", sf_base_att_agi, 10, "Gives ability to repair shield and reduces the durability damage to shields by 8%%"),
  ("weapon_master", "Weapon Master", sf_base_att_agi, 10, "Gives ability to repair weapons and reduces the durability damage to weapons by 3%%"),
  ("reserved_9","Reserved Skill 9",sf_base_att_agi|sf_inactive,10,"This is a reserved skill."),
  ("reserved_10","Reserved Skill 10",sf_base_att_agi|sf_inactive,10,"This is a reserved skill."),
  ("reserved_11","Reserved Skill 11",sf_base_att_agi|sf_inactive,10,"This is a reserved skill."),
  ("reserved_12","Reserved Skill 12",sf_base_att_agi|sf_inactive,10,"This is a reserved skill."),
  ("reserved_13","Reserved Skill 13",sf_base_att_agi|sf_inactive,10,"This is a reserved skill."),
  ("power_draw","Power Draw",sf_base_att_str,10,"Lets character use more powerful bows. Each point to this skill (up to four plus power-draw requirement of the bow) increases bow damage by 14%%. (Personal skill)"),
  ("power_throw","Power Throw",sf_base_att_str,10,"Each point to this skill increases throwing damage by 10%%. (Personal skill)"),
  ("power_strike","Power Strike",sf_base_att_str,10,"Each point to this skill increases melee damage by 8%%. (Personal skill)"),
  ("ironflesh","Ironflesh",sf_base_att_str,10,"Each point to this skill increases hit points by +2. (Personal skill)"),
  ("reserved_14","Reserved Skill 14",sf_base_att_str|sf_inactive,10,"This is a reserved skill."),
  ("reserved_15","Reserved Skill 15",sf_base_att_str|sf_inactive,10,"This is a reserved skill."),
  ("reserved_16","Reserved Skill 16",sf_base_att_str|sf_inactive,10,"This is a reserved skill."),
  ("reserved_17","Reserved Skill 17",sf_base_att_str|sf_inactive,10,"This is a reserved skill."),
  ("reserved_18","Reserved Skill 18",sf_base_att_str|sf_inactive,10,"This is a reserved skill."),
]
 
Raising ironflesh attribute button not clickable and reading str based attributes not readable after adding sf_inactive flag on other hardcoded skills is bugged for me in my own module here is what i did
This is not a wse2 bug, the same behavior is observed in the warband. Moreover, the only thing the sf_inactive flag does is hide the skill from the character window. It does not disable the skill itself.
 
Last edited:
Hello. Using WSE2 launcher i cant launch the game, nor i can open the configurations and it doesnt show available mods.it gives me some 0xc000007b error. Tried reinstaling the game, unsubing mods from the workshop and reinstalled direct and microsoft visual studios . Might know what is the problem ?
The error is related to corrupted or missing Microsoft Visual C++ components. Try uninstalling all package versions and then reinstalling them.
 
@K700 , thanks for all your efforts. Can you show how shooting accuracy is calculated?
C++:
void mbAgent::updateAccuracy()
{
    float inaccuracy = 0.0f;
    float accuracyNoise = 0.0f;
    mbItem item = getWieldedItem(ah_primary);

    if (item.isValid())
    {
        mbItemKind *itemKind = item.getItemKind();
        int type = itemKind->getType();

        if (itemKind->isRangedWeapon())
        {
            float holdTime = m_rangedHoldTimer.getElapsedTime();
            rglVector4 noiseInput(holdTime, holdTime + 3.0f, holdTime * 1.5f);
            rglVector4 noise = rglPerlin(0.7f, noiseInput);
            float noiseFactor = (noise.x + noise.y) * 1.9f;
            float turnFactor = rglMax(rglAbs(m_turnInaccuracy) - 1.0f, 0.0f);

            if (type == itp_type_bow)
            {
                float skillFactor = g_game->getTroopSkill(m_troopNo, skl_power_draw, true) * 20.0f + (int)getTroop()->getProficiency(wpf_archery);
                float damageFactor = item.getDifficulty() * 10.0f + item.getRangedDamage() * 8.0f + 70.0f;
                float accuracyFactor = item.getAccuracy() * 0.01f * m_modifiers[am_accuracy];
                
                inaccuracy = rglMax((damageFactor + 50.0f - skillFactor) * 0.00006f, 0.0f);

                if (m_attackAction != aa_free)
                {
                    if (hasMount())
                    {
                        float speedScalar = rglAbs(getHorseAgent()->m_speed.y);
                        
                        if (!m_isOnGround)
                            speedScalar += 6.0f;

                        if (speedScalar > 1.0f)
                        {
                            int horseArcherySkill = g_game->getTroopSkill(m_troopNo, skl_horse_archery, true);
                            int ridingSkill = g_game->getTroopSkill(m_troopNo, skl_riding, true);
                            float speedFactor = rglMax(((speedScalar + 3.0f) - (ridingSkill + 5.0f) * (horseArcherySkill * (skillFactor + 200.0f)) * 0.0004f) * 0.008f, 0.0f) * (4.0f / (horseArcherySkill + 4.0f)) * 1.4f;
                            
                            inaccuracy += speedFactor;
                            accuracyNoise = speedFactor * noiseFactor;
                        }
                    }
                    else
                    {
                        float speedScalar = m_speed.length();

                        if (!m_isOnGround)
                            speedScalar += 2.0f;

                        if (speedScalar > 0.0f)
                        {
                            float speedFactor = (speedScalar + 3.0f) / (skillFactor + 1000.0f) * 50.0f * 1.4f;

                            inaccuracy += speedFactor;
                            accuracyNoise = speedFactor * noiseFactor;
                        }
                    }

                    float minIdealHoldTime = 1.25f / getActionSpeed(ah_primary);
                    float maxIdealHoldTime = minIdealHoldTime + rglMax((skillFactor - damageFactor * 0.5f) * 0.01f, 0.3f);

                    if (holdTime < minIdealHoldTime)
                    {
                        inaccuracy += rglMax((minIdealHoldTime - holdTime) / minIdealHoldTime - skillFactor * 0.001f, 0.0f);
                    }
                    else if (holdTime > maxIdealHoldTime)
                    {
                        float holdFactor = rglMin((holdTime - maxIdealHoldTime) * 0.4f, 1.0f) * damageFactor * 0.0006f;

                        inaccuracy += holdFactor * 0.5f;
                        
                        rglVector4 holdNoise = rglPerlin(0.4f, noiseInput);

                        accuracyNoise += rglMax((holdNoise.x + holdNoise.y) * 0.5f, -0.5f) * holdFactor;
                    }
                    
                    inaccuracy += rglMax(100.0f / (skillFactor + 100.0f) * turnFactor, 0.0f) * 0.5f + (1.0f - accuracyFactor) * 0.08f;
                    inaccuracy = rglMax(inaccuracy, 0.0f);
                }
                else
                {
                    inaccuracy = 0.0f;
                }
            }
            else if (type == itp_type_crossbow || type == itp_type_pistol || type == itp_type_musket)
            {
                float accuracyFactor = item.getAccuracy() * 0.01f * m_modifiers[am_accuracy];
                int proficiency = (int)getTroop()->getProficiency(type == itp_type_crossbow ? wpf_crossbow : wpf_firearms);
                int damage = item.getRangedDamage();

                if (m_attackAction != aa_free && item.getMaxAmmo() != item.getUsedAmmo())
                {
                    float skillFactor = proficiency + 100.0f;

                    inaccuracy = rglMax(0.6f - holdTime * skillFactor * 0.01f, 0.0f) + rglMax((damage + damage + 100.0f - proficiency) * 0.0001f, 0.0f);
                    
                    if (!hasMount())
                    {
                        float speedScalar = m_speed.length();

                        if (!m_isOnGround)
                            speedScalar += 2.0f;

                        if (speedScalar > 0.01f)
                        {
                            float speedFactor = (rglConfig::Battle::bUseCrossbowAsFirearm) ? rglClamp(((itemKind->m_capabilities & itcf_reload_pistol) ? 2.0f : 6.0f) * (speedScalar - proficiency * 0.01f) / proficiency * 1.4f, 0.0f, 1.0f) : (3.0f * (speedScalar + 3.0f) / skillFactor * 1.4f);

                            inaccuracy += speedFactor;
                            accuracyNoise = speedFactor * noiseFactor;
                        }
                    }
                    else
                    {
                        float speedScalar = rglAbs(getHorseAgent()->m_speed.y);

                        if (speedScalar > 1.0f)
                        {
                            if (!m_isOnGround)
                                speedScalar += 6.0f;

                            int horseArcherySkill = g_game->getTroopSkill(m_troopNo, skl_horse_archery, true);
                            int ridingSkill = g_game->getTroopSkill(m_troopNo, skl_riding, true);
                            float speedFactor = rglMax(((speedScalar + 5.0f) - (ridingSkill + 5.0f) * ((horseArcherySkill + 2.0f) * (proficiency + 150.0f)) * 0.0004f) * 0.005f, 0.0f) * (4.0f / (horseArcherySkill + 4.0f)) * 1.4f;
                            
                            inaccuracy += speedFactor;
                            accuracyNoise = speedFactor * noiseFactor;
                        }
                    }

                    if (rglConfig::Battle::bUseCrossbowAsFirearm)
                    {
                        float aiFactor = 0.08f;
                        if (g_basicGame.isSingleplayer())
                        {
                            aiFactor = 0.065f;
                            if (m_no != g_mission->m_playerAgentNo)
                            {
                                if (g_mission->isValidAgent(g_mission->m_playerAgentNo) && isEnemyWith(g_mission->getPlayerAgent()))
                                    aiFactor = 0.08f * rglConfig::BattleAi::iReduceBattleAi * 0.15f + 1.0f;
                                else
                                    aiFactor = 0.08f;
                            }
                        }

                        inaccuracy += rglMax(100.0f / proficiency * turnFactor, 0.0f) * ((itemKind->m_capabilities & itcf_reload_pistol) ? 0.2f : 0.65f) + (1.0f - accuracyFactor) * aiFactor;
                    }
                    else
                    {
                        inaccuracy += rglMax(100.0f / skillFactor * turnFactor, 0.0f) * 0.35f + (1.0f - accuracyFactor) * 0.08f;
                    }
                    
                    inaccuracy = rglMax(inaccuracy, 0.0f);
                }
                else
                {
                    inaccuracy = 0.0f;
                }
            }
            else
            {
                float skillFactor = g_game->getTroopSkill(m_troopNo, skl_power_throw, true) * 20.0f + (int)getTroop()->getProficiency(wpf_throwing);
                float accuracyFactor = item.getAccuracy() * 0.01f * m_modifiers[am_accuracy];

                if (m_attackAction != aa_free)
                {
                    float damageFactor = (item.getDifficulty() * 5.0f + item.getRangedDamage() + 30.0f) * 8.0f;

                    inaccuracy = rglMax((damageFactor - skillFactor) * 0.00012f, 0.0f);

                    if (!hasMount())
                    {
                        float speedScalar = m_speed.length();

                        if (!m_isOnGround)
                            speedScalar += 2.0f;

                        if (speedScalar > 0.0f)
                        {
                            float speedFactor = (speedScalar + 3.0f) / (skillFactor + 50.0f) * 0.8f * 1.4f;

                            inaccuracy += speedFactor;
                            accuracyNoise = speedFactor * noiseFactor;
                        }
                    }
                    else
                    {
                        float speedScalar = rglAbs(getHorseAgent()->m_speed.y);

                        if (speedScalar > 1.0f)
                        {
                            if (!m_isOnGround)
                                speedScalar += 6.0f;

                            int horseArcherySkill = g_game->getTroopSkill(m_troopNo, skl_horse_archery, true);
                            int ridingSkill = g_game->getTroopSkill(m_troopNo, skl_riding, true);
                            float speedFactor = rglMax(((speedScalar + 5.0f) - (ridingSkill + 5.0f) * (horseArcherySkill * (skillFactor + 200.0f)) * 0.0004f) * 0.004f, 0.0f) * (4.0f / (horseArcherySkill + 4.0f)) * 1.4f;
                            
                            inaccuracy += speedFactor;
                            accuracyNoise = speedFactor * noiseFactor;
                        }
                    }

                    inaccuracy += rglMax(100.0f / (skillFactor + 100.0f) * turnFactor, 0.0f) * 0.3f + (1.0f - accuracyFactor) * 0.08f;
                    inaccuracy = rglMax(inaccuracy, 0.0f);
                }
                else
                {
                    inaccuracy = 0.0f;
                }
            }
        }
    }

    float timeFactor = g_frameTimes[2];

    if (m_attackAction != aa_free)
        timeFactor *= 5.0f;

    if (inaccuracy > m_inaccuracy)
        timeFactor *= 2.0f;

    timeFactor = rglMin(timeFactor, 1.0f);
    m_inaccuracy = rglLerp(m_inaccuracy, inaccuracy, timeFactor);
    m_accuracyNoise = rglLerp(m_accuracyNoise, accuracyNoise, timeFactor);
}
 
Thanks.
Similar to the shooting accuracy, can you show attack value (hit point) algorithm?
I'm interested in how warband calculated hit point after an agent was attacked.
 
C++:
void mbMission::calculateDamage(const mbItem &item, mbMissile *missile, float &damage, bool &isThrust, int srcAgentNo, int dstAgentNo, mbAttack &attack, bool displayMessages)
{
    rglVector4 srcVelocity = 0.0f;
    rglVector4 dstVelocity = 0.0f;
    mbAgent *srcAgent = isValidAgent(srcAgentNo) ? getAgent(srcAgentNo) : NULL;
    mbAgent *dstAgent = isValidAgent(dstAgentNo) ? getAgent(dstAgentNo) : NULL;

    if (dstAgent)
    {
        if (dstAgent->hasMount())
        {
            mbAgent *dstHorseAgent = dstAgent->getHorseAgent();
           
            dstVelocity = dstHorseAgent->m_scaledTransform.f * dstHorseAgent->m_speed.y;
        }
        else
        {
            dstVelocity = dstAgent->m_scaledTransform.transformDirToParent(rglVector4(dstAgent->m_speed.x, dstAgent->m_speed.y, 0.0f));
        }
    }

    bool isCouching = false;

    if (missile)
    {
        isThrust = true;

        float speedFactor;
        rglVector4 velocity = missile->getVelocity();

        if (dstAgentNo < 0)
            speedFactor = velocity.length();
        else
            speedFactor = (dstVelocity - velocity).length();

        damage = rglPow(speedFactor / ((rglConfig::Battle::bTakeAttackersSpeedForRangedSpeedBonus) ? missile->m_speed : rglMax(missile->m_missileSpeed, 0.001f)), rglConfig::Battle::fMissileDamageSpeedPower) * missile->m_damage * attack.m_power;

        if (srcAgent)
            damage *= srcAgent->m_modifiers[am_ranged_damage];
    }
    else
    {
        if (srcAgent)
        {
            if (srcAgent->hasMount())
            {
                mbAgent *srcHorseAgent = srcAgent->getHorseAgent();
           
                srcVelocity = srcHorseAgent->m_scaledTransform.f * srcHorseAgent->m_speed.y;
            }
            else
            {
                srcVelocity = srcAgent->m_scaledTransform.transformDirToParent(rglVector4(srcAgent->m_speed.x, srcAgent->m_speed.y, 0.0f));
            }

            isCouching = srcAgent->isCouching();
        }

        isThrust = attack.m_type == at_thrust;
        bool hasUpperStab = false;

        if (!item.isValid())
        {
            if (srcAgent)
                damage = (srcAgent->getTroop()->getAttribute(atr_str) * 0.3f + 2.0f) * attack.m_power;
            else
                damage = 10.0f;
        }
        else
        {
            if (item.getItemKind()->m_capabilities & itcf_overswing_spear)
            {
                hasUpperStab = true;

                if (attack.m_type == at_overswing)
                    isThrust = true;
            }

            damage = (float)item.getDamage(isThrust);

            if (!isCouching)
            {
                damage *= attack.m_power;
                damage *= attack.getHoldFactor() * 0.5f + 0.5f;
            }
        }

        rglVector4 direction = dstVelocity - srcVelocity;
        float speed = direction.normalize();

        if (srcAgent && isCouching)
        {
            rglVector4 lanceDir = srcAgent->m_scaledTransform.transformDirToParent(srcAgent->m_entity->m_skeleton->getBoneTransform(hb_item_r).f).normalized();
           
            damage = (damage + 5.0f) * rglPow(speed, 1.8f);
            damage *= (0.2f - direction.dot(lanceDir)) * 0.2f * rglConfig::Battle::fCouchedLanceDamageMultiplier;
           
            if (rglConfig::Messages::bShowDamage && displayMessages && g_basicGame.isSingleplayer())
            {
                rglString message;

                if (srcAgentNo == m_playerAgentNo)
                    displayMessage(MB_UI("ui_delivered_couched_lance_damage"), 0xFFD03030);
                else if (dstAgentNo == m_playerAgentNo)
                    displayMessage(MB_UI("ui_received_couched_lance_damage"), 0xFFD03030);
            }
        }
        else
        {
            if (attack.m_type == at_overswing && !hasUpperStab)
                damage *= 1.1f;
           
            rglVector4 attackDirection;
            rglVector4 attackForward = attack.m_curSwordTransform.f.normalized();

            switch (attack.m_type)
            {
            case at_thrust:
                attackDirection = attackForward;
                break;
            case at_overswing:
                attackDirection = attackForward.cross(attackForward.cross(rglVector4::Up).normalized()).normalized();
                break;
            case at_swing_left:
                attackDirection = attackForward.cross(rglVector4::Up).normalized();
                break;
            case at_swing_right:
                attackDirection = -attackForward.cross(rglVector4::Up).normalized();
                break;
            }

            float sweetSpotFactor = getSweetSpotFactor(srcAgentNo, dstAgentNo, hasUpperStab);
            float speedBonus = ((!srcAgent || !srcAgent->hasMount()) && (!dstAgent || !dstAgent->hasMount())) ? 19.5f : 15.5f;

            if (rglConfig::Battle::bItemSpeedAffectSpeedBonusForDamage)
                speedBonus *= item.getSpeedRating() * 0.01f;

            if (attack.m_type == at_thrust)
                speedBonus *= 0.93f;

            if (sweetSpotFactor >= 0.000001f)
            {
                speedBonus = rglClamp((speedBonus * rglClamp(sweetSpotFactor, 0.0f, 1.2f) - attackDirection.dot(direction) * speed) / speedBonus, 0.0f, 3.0f);
                speedBonus = rglPow(speedBonus, rglConfig::Battle::fMeleeDamageSpeedPower);
                damage *= speedBonus;
               
                int speedBonusValue = rglRound((speedBonus - 1.0f) * 100.0f);

                if (rglConfig::Messages::bShowDamage && speedBonusValue && displayMessages && srcAgentNo == m_playerAgentNo && g_basicGame.isSingleplayer())
                {
                    rglString message;

                    if (speedBonusValue > 0)
                        message = MB_UIF("ui_speed_bonus_plus", speedBonusValue);
                    else
                        message = MB_UIF("ui_speed_bonus", speedBonusValue);

                    displayMessage(message, 0xFFFFFFFF);
                }
            }
            else
            {
                damage = 0.0f;
            }
        }

        if (srcAgent)
            damage *= srcAgent->m_modifiers[am_damage];
    }

    if (srcAgent && item.isValid())
    {
        mbItemKind *itemKind = item.getItemKind();
        int type = itemKind->getType();
        mbTroop *troop = srcAgent->getTroop();
        mbItem shieldItem = srcAgent->getWieldedItem(ah_secondary);

        if (!isCouching || rglConfig::Battle::bApplySkillForCouchingDamage)
        {
            int proficiency = (int)troop->getProficiency(itemKind->getProficiency(shieldItem.isValid()));

            if (type == itp_type_crossbow)
            {
                if (m_weather.m_precipitationType == wpr_rain)
                    damage *= 0.75f;
            }
            else
            {
                damage *= proficiency * 0.01f * 0.15f + 0.85f;

                if (type == itp_type_bow)
                {
                    damage *= rglMin(g_game->getTroopSkill(srcAgent->m_troopNo, skl_power_draw, true), item.getDifficulty() + 4) * 0.14f + 1.0f;

                    if (srcAgent->m_horseAgentNo != -1)
                        damage *= g_game->getTroopSkill(srcAgent->m_troopNo, skl_horse_archery, true) * 0.019f + 0.8f;

                    if (m_weather.m_precipitationType == wpr_rain)
                        damage *= 0.9f;
                }
                else if (type == itp_type_thrown)
                {
                    damage *= g_game->getTroopSkill(srcAgent->m_troopNo, skl_power_throw, true) * 0.1f + 1.0f;

                    if (srcAgent->m_horseAgentNo != -1)
                        damage *= g_game->getTroopSkill(srcAgent->m_troopNo, skl_horse_archery, true) * 0.019f + 0.8f;
                }
                else if (itemKind->isMeleeWeapon())
                {
                    damage *= g_game->getTroopSkill(srcAgent->m_troopNo, skl_power_strike, true) * 0.08f + 1.0f;
                }

                damage += troop->getAttribute(atr_str) / 5.0f;
            }
        }
       
        if (type == itp_type_two_handed || type == itp_type_polearm)
        {
            if (rglConfig::Battle::bAdjustedTwoHandedAndPolearmPenalties)
            {
                if (srcAgent->hasMount())
                {
                    if (type == itp_type_polearm)
                        damage *= 0.75f;

                    if (itemKind->m_properties & itp_two_handed)
                        damage *= 0.8f;
                }
                else if (shieldItem.isValid())
                {
                    damage *= 0.9f;
                }
            }
            else
            {
                if (shieldItem.isValid() || srcAgent->hasMount())
                {
                    damage *= 0.85f;

                    if (type == itp_type_polearm)
                        damage *= 0.85f;

                    if (itemKind->m_properties & itp_two_handed)
                        damage *= 0.9f;
                }
            }
        }
    }

    damage = rglClamp(damage, 0.0f, 500.0f);
}

void mbAgent::soakBlow(mbBlow &blow)
{
    int armorType;

    if (isHorse())
    {
        armorType = 1;
    }
    else
    {
        switch (blow.m_boneNo)
        {
        case hb_head:
            armorType = 0;
            break;
        case hb_thigh_l:
        case hb_thigh_r:
        case hb_calf_l:
        case hb_calf_r:
        case hb_foot_l:
        case hb_foot_r:
            armorType = 2;
            break;
        default:
            armorType = 1;
            break;
        }
    }

    float armor = (float)m_armor[armorType];

    if (isHuman() && blow.hasFlags(blf_ranged))
    {
        mbItem shieldItem = getShieldOnBack();

        if (shieldItem.isValid())
        {
            mbItemKind *shieldItemKind = shieldItem.getItemKind();
            rglTransform carryTransform;
            int carryBoneNo;
            int carryType;

            shieldItemKind->getCarryValues(carryTransform, carryBoneNo, carryType);

            rglTransform shieldTransform = getBoneTransform(carryBoneNo).transformToParent(carryTransform);
           
            shieldTransform.normalize();

            if (blow.m_missileDirection.dot(shieldTransform.u) < - 0.5f)
            {
                rglVector4 missileLength = blow.m_missileDirection * 4.0f;
                rglDynamicCapsule capsule(0.0f, blow.m_missilePosition - missileLength, blow.m_missilePosition + missileLength);
                rglSphere sphere(0.0f, shieldTransform.o);

                if (shieldItemKind->getShieldWidth() > rglGetCapsuleSphereDistance(&capsule, &sphere))
                {
                    armor += shieldItem.getBodyArmor() + 10;

                    if (m_no == g_mission->m_playerAgentNo)
                        g_mission->displayMessage(MB_UI("ui_hit_shield_on_back"), 0xFFFFFFFF);
                }
            }
        }
    }

    float soakFactor;
    float reductionFactor;

    switch (blow.m_damageType)
    {
    case dt_cut:
        soakFactor = armor * rglConfig::Battle::fCutSoakFactor;
        reductionFactor = armor * rglConfig::Battle::fCutReduceFactor;
        break;
    case dt_pierce:
        soakFactor = armor * rglConfig::Battle::fPierceSoakFactor;
        reductionFactor = armor * rglConfig::Battle::fPierceReduceFactor;
        break;
    case dt_blunt:
        soakFactor = armor * rglConfig::Battle::fBluntSoakFactor;
        reductionFactor = armor * rglConfig::Battle::fBluntReduceFactor;
        break;
    default:
        soakFactor = 0.0f;
        reductionFactor = 0.0f;
        break;
    }

    if (blow.m_item.isValid() && blow.m_item.getItemKind()->m_properties & itp_extra_penetration)
    {
        soakFactor *= rglConfig::Battle::fExtraSoakFactor;
        reductionFactor *= rglConfig::Battle::fExtraReduceFactor;
    }
   
    float damage = rglRandf(0.9f, 1.0f) * blow.m_rawDamage;
    float soakedDamage = ((rglConfig::Battle::bReduceDamageRandomness) ? rglRandf(0.7f, 0.75f) : rglRandf(0.45f, 1.0f)) * soakFactor;
    float reducedDamage = ((rglConfig::Battle::bReduceDamageRandomness) ? rglRandf(0.7f, 0.75f) : rglRandf(0.45f, 1.0f)) * reductionFactor * 0.014f;

    if (reductionFactor < 0.0001f)
        reducedDamage = 0.0f;
    else
        reducedDamage = (1.0f - 1.0f / exp(reducedDamage)) * rglMax(damage - soakedDamage, 0.0f);

    blow.m_soakedDamage = rglRound(reducedDamage + soakedDamage);
    blow.m_inflictedDamage = damage - blow.m_soakedDamage;

    if (isHorse() && blow.m_boneNo == hrsb_head || isHuman() && blow.m_boneNo == hb_head)
    {
        blow.m_inflictedDamage *= 1.2f;

        if (blow.m_item.isValid() && blow.m_item.getItemKind()->isRangedWeapon())
            blow.m_inflictedDamage *= 1.75f;
    }
    else if (isHuman())
    {
        switch (blow.m_boneNo)
        {
        case hb_thigh_l:
        case hb_thigh_r:
        case hb_foot_l:
        case hb_foot_r:
        case hb_calf_l:
        case hb_calf_r:
            blow.m_inflictedDamage *= 0.9f;
            break;
        }
    }

    blow.m_inflictedDamage = rglClamp(blow.m_inflictedDamage, 0.0f, 500.0f);
}

if (g_basicGame.isSingleplayer())
    {
        if (m_no == g_mission->m_playerAgentNo || m_riderAgentNo == g_mission->m_playerAgentNo)
            inflictedDamage *= rglConfig::Battle::fDamageToSelf;
        else if ((isHuman() && m_partyNo == g_game->m_mainPartyNo) || (isHorse() && hasRider() && getRiderAgent()->m_partyNo == g_game->m_mainPartyNo))
            inflictedDamage *= rglConfig::Battle::fDamageToFriends;
    }

    if (isAlive())
    {
        g_basicGame.setTriggerParam(0, m_no);
        g_basicGame.setTriggerParam(1, m_blow.m_agentNo);
        g_basicGame.setTriggerParam(2, (int)inflictedDamage);
        g_basicGame.setTriggerParam(5, (int)m_blow.m_rawDamage);
        g_basicGame.setTriggerParam(3, m_blow.m_boneNo);

        if (m_blow.m_item.isValid())
        {
            g_basicGame.m_registers[0] = m_blow.m_item.m_itemKindNo;
            g_basicGame.setTriggerParam(6, m_blow.m_item.getModifier());
        }
        else
        {
            g_basicGame.m_registers[0] = -1;
            g_basicGame.setTriggerParam(6, -1);
        }

        if (m_blow.m_missile)
        {
            g_basicGame.setTriggerParam(4, m_blow.m_missile->m_missileItem.m_itemKindNo);
            g_basicGame.setTriggerParam(7, m_blow.m_missile->m_missileItem.getModifier());
        }
        else
        {
            g_basicGame.setTriggerParam(4, -1);
            g_basicGame.setTriggerParam(7, -1);
        }
    
        g_basicGame.setTriggerParam(8, m_blow.m_damageType);
        g_basicGame.m_positionRegisters[0].o = m_blow.m_position;
        g_basicGame.m_positionRegisters[0].f = m_blow.m_rotation;
        g_basicGame.m_positionRegisters[0].u = rglVector4::Up;
        g_basicGame.m_positionRegisters[0].orthonormalize();
        
        g_basicGame.m_triggerResult = -1;
        g_mission->getTemplate()->m_triggers.execute(ti_on_agent_hit);

        if (g_basicGame.m_triggerResult >= 0)
            inflictedDamage = (float)g_basicGame.m_triggerResult;

        setHitPoints(m_floatHitPoints - inflictedDamage);
 
Last edited:
1.0.8.2
-Fixed ti_on_scene_prop_hit, ti_on_agent_blocked, ti_on_shield_hit, ti_on_shield_penetrated triggers.
-Extended ti_on_item_wielded, ti_on_item_unwielded triggers (param 3: item slot), ti_on_shield_hit trigger (param 6: item modifier, param 7: missile item modifier).
-Fixed proficiency improvement when dealing damage in singleplayer.
-Fixed failure_callback_script_no for send_message_to_url_advanced and send_post_message_to_url_advanced operations.
-Fixed knockdown chance.
 
Hi @K700 I wanna report a bug using the 'Diplomacy 4.litdum' mod, when normal NPCs (like troops, vendors or tavern NPCs) are normal but lords and ladies are bold and with weird elongated faces, launching the game without WSE2 "fixes" their faces, but with a big performance hit of course. Thanks.
 
After a short time in-game i get no more notifications messages from events, those in the down left corner. Some times it fixed by its own, but sometimes just still keep bugged, how can i fix it or how can i help to fix it?:sad:
 
Hi @K700 I wanna report a bug using the 'Diplomacy 4.litdum' mod, when normal NPCs (like troops, vendors or tavern NPCs) are normal but lords and ladies are bold and with weird elongated faces, launching the game without WSE2 "fixes" their faces, but with a big performance hit of course. Thanks.
Will be fixed in the next update.
 
This happens when there are too many notifications. Often this is a consequence of errors in scripts.
Script error in "Messages":
Some script errors in market:
That's only using WSE2 with Perisno 1.4.5.
Edit to add a new s of the logs i get:
 
Last edited:
Hello K700, I have been trying to make it so entering a battle scene has a troop use a special animation compared to others, though I cant seem to get it to work...

animation entry:
["flying_forward", acf_enforce_all, amf_keep,
[1.25, "Anim_FlightForward", 0, 29, arf_blend_in_16|arf_cyclic],
],
Code in mission_templates:
angel_animations = (
ti_on_agent_spawn, 0, 0, [],
[
(store_trigger_param_1, ":agent_id"),
(agent_get_troop_id, ":troop_id", ":agent_id"),
(eq, ":troop_id", "trp_angel"),
(agent_set_personal_animation, ":agent_id", "anim_run_forward" ,"anim_flying_forward"),
],
)
I added angel_animations, to everywhere after common_battle_mission_start, is. Also does wse2 allow more race entries than native does?
 
First, replace the default run animation with your animation and make sure it works correctly.
At the moment, WSE2 only supports 16 skins, just like warband. I can rework the engine and remove this restriction for WSE2 under the order.
 
First, replace the default run animation with your animation and make sure it works correctly.
At the moment, WSE2 only supports 16 skins, just like warband. I can rework the engine and remove this restriction for WSE2 under the order.
Would really love if the 16 skins restriction gets removed if possible, and thank you for the reply! How much is it for a commission and where could I pay you?
 
Last edited:
Back
Top Bottom