Click here to Skip to main content
15,672,179 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
If such a request has already been asked, please accept my apologies. I looked for samples, read up on the player and monster classes, and player and monster stats on other sites, and nothing appeared to fit with the game's code without re-writing some of it. I attempted copying dexterity to turn it into strength, but it didn't work. I eventually came to a dead end. How might I add strength to affect damage for player & monster? Is it something I'd have to place in combatservice, attackwithweapon, or both? I get my stats from a JSON file. Dexterity is currently the only stat available in the game. It defines which one attacks first—the player or monster.


the dexterity code/formula

CombatService.cs

    using Engine.Models;
    using Engine.Shared;
    using SOSCSRPG.Core;

    namespace Engine.Services
    {
        public static class CombatService
        {
        public enum Combatant
        {
            Player,
            Opponent
        }

        public static Combatant FirstAttacker(Player player, Monster 
        opponent)
        {
            // Formula is: ((Dex(player)^2 - Dex(monster)^2)/10) + 
               Random(-10/10)
            // For dexterity values from 3 to 18, this should produce 
               an offset of +/- 
            41.5
            int playerDexterity = 
            player.GetAttribute("DEX").ModifiedValue * 

            player.GetAttribute("DEX").ModifiedValue;
            int opponentDexterity = 
            opponent.GetAttribute("DEX").ModifiedValue * 

            opponent.GetAttribute("DEX").ModifiedValue;
            decimal dexterityOffset = (playerDexterity - 
            opponentDexterity) / 10m;
            int randomOffset = DiceService.Instance.Roll(20).Value - 
            10;
            decimal totalOffset = dexterityOffset + randomOffset;

            return DiceService.Instance.Roll(100).Value <= 50 + 
            totalOffset 
                       ? Combatant.Player 
                       : Combatant.Opponent;
        }

        public static bool AttackSucceeded(LivingEntity attacker, 
        LivingEntity target)
        {
            // Currently using the same formula as FirstAttacker 
               initiative.
            // This will change as we include attack/defense skills,
            // armor, weapon bonuses, enchantments/curses, etc.
            int playerDexterity = 
            attacker.GetAttribute("DEX").ModifiedValue * 

            attacker.GetAttribute("DEX").ModifiedValue;
            int opponentDexterity = 
            target.GetAttribute("DEX").ModifiedValue * 

            target.GetAttribute("DEX").ModifiedValue;
            decimal dexterityOffset = (playerDexterity - 
            opponentDexterity) / 10m;
            int randomOffset = DiceService.Instance.Roll(20).Value - 
            10;
            decimal totalOffset = dexterityOffset + randomOffset;

            return DiceService.Instance.Roll(100).Value <= 50 + 
           totalOffset;
        }
    }
}


The code for weapon damage

Attackwithweapon.cs

using System;
    using Engine.Models;
    using Engine.Services;
    using SOSCSRPG.Core;

    namespace Engine.Actions
    {
        public class AttackWithWeapon : BaseAction, IAction
        {
            private readonly string _damageDice;

            public AttackWithWeapon(GameItem itemInUse, string 
            damageDice)
            : base(itemInUse)
        {
            if (itemInUse.Category != GameItem.ItemCategory.Weapon)
            {
                throw new ArgumentException($"{itemInUse.Name} is not a 
                weapon");
            }

            if (string.IsNullOrWhiteSpace(damageDice))
            {
                throw new ArgumentException("damageDice must be valid 
                dice notation");
            }

            _damageDice = damageDice;
        }

        public void Execute(LivingEntity actor, LivingEntity target)
        {
            string actorName = (actor is Player) ? "You" : $"The 
           {actor.Name.ToLower()}";
            string targetName = (target is Player) ? "you" : $"the 
           {target.Name.ToLower()}";

            if(CombatService.AttackSucceeded(actor, target))
            {
                int damage = 
                DiceService.Instance.Roll(_damageDice).Value;

                ReportResult($"{actorName} hit {targetName} for 
                {damage} point{(damage > 1 ? "s" : "")}.");

                target.TakeDamage(damage);
            }
            else
            {
                ReportResult($"{actorName} missed {targetName}.");
            }
        }
    }
}


What I have tried:

I tried changing Dexterity to Strength here since that's the only place where Dexterity is used, but it didn't work. I don't touch the formula. I don't add Dexterity to attack with weapons because I'm unsure I should.

CombatService.cs

    using Engine.Models;
    using Engine.Shared;
    using SOSCSRPG.Core;

    namespace Engine.Services
    {
        public static class CombatService
        {
        public enum Combatant
        {
            Player,
            Opponent
        }

        public static Combatant FirstAttacker(Player player, Monster 
        opponent)
        {
            // Formula is: ((STR(player)^2 - STR(monster)^2)/10) + 
               Random(-10/10)
            // For strength values from 3 to 18, this should produce 
               an offset of +/- 
            41.5
            int playerStrength = 
            player.GetAttribute("STR").ModifiedValue * 

            player.GetAttribute("STR").ModifiedValue;
            int opponentStrength = 
            opponent.GetAttribute("STR").ModifiedValue * 

            opponent.GetAttribute("STR").ModifiedValue;
            decimal strengthOffset = (playerStrength - 
            opponentStrength) / 10m;
            int randomOffset = DiceService.Instance.Roll(20).Value - 
            10;
            decimal totalOffset = strengthOffset + randomOffset;

            return DiceService.Instance.Roll(100).Value <= 50 + 
            totalOffset 
                       ? Combatant.Player 
                       : Combatant.Opponent;
        }

        public static bool AttackSucceeded(LivingEntity attacker, 
        LivingEntity target)
        {
            // Currently using the same formula as FirstAttacker 
               initiative.
            // This will change as we include attack/defense skills,
            // armor, weapon bonuses, enchantments/curses, etc.
            int playerStrength = 
            attacker.GetAttribute("STR").ModifiedValue * 

            attacker.GetAttribute("STR").ModifiedValue;
            int opponentStrength = 
            target.GetAttribute("STR").ModifiedValue * 

            target.GetAttribute("STR").ModifiedValue;
            decimal strengthOffset = (playerStrength - 
            opponentStrength) / 10m;
            int randomOffset = DiceService.Instance.Roll(20).Value - 
            10;
            decimal totalOffset = strengthOffset + randomOffset;

            return DiceService.Instance.Roll(100).Value <= 50 + 
           totalOffset;
        }
    }
}
Posted
Updated 21-Dec-21 16:49pm

1 solution

You need a "standard" / baseline for inflicting damage; then you vary the damage as the strength varies.

e.g.

One company (64 men), lying down, open formation, firing, can inflict a loss of 5, in one minute, on the party fired on under similar conditions.

The standard strength is 64. If there were 2 companies firing under similar conditions (128 men; twice the "strength"), the losses to the other party would be 2 x 5 = 10.

Then the factors of lying versus standing, etc. will add "adjustment" factors like .5 or 2 more times, etc. (e.g. casualties are higher standing in line vs lying down).

If it's man vs man, it's a question of how much each varies from the standard (weaker or stronger), simply by some factor; e.g. 0.9; 1.1

A "random" win element may be used to let the underdog win sometimes.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900