====== Arbitary Combat System ====== * Attacker rolls 1d20 + ATTACK (character attribute) * Defender may either "Dodge" (roll 1d20 + Agility, must beat attack roll to dodge entirely), or may "Block", which guarantees the attack lands, but reduces damage by the Block value, to a minimum of 1 damage. * Critical hits (natural 20s) do double damage. // A sample (GS)script for an arbitary combat system. // The attacker selects a target to attack, and the target gets two choices // They can try evade damage entirely by using an AGILITY buffed roll // Or they can BLOCK which will subtract their block value from the damage // (minimum damage 1). If the attacker rolls a 20 and lands damage // (of any kind) it is doubled as a critical hit. We report this as a // "mighty swing" in the output // have the caller select a target Character target=gsSelectCharacter(CALLER,"Select a target to attack"); // have the target select a defence type String defencetype=gsGetChoice(target,CALLER+" is attacking you, pick a defence type!",["Dodge","Block"]); // do some attack rolls ; the attacker gets their "ATTACK" attribute added // just because otherwise this code biases the defender who gets their bonus Integer naturalattackroll=gsRand(1,20); // note we force this KV into an Integer, naturally it's a string and that // will ruin the maths later. Integer attackvalue=gsGetKV(CALLER,"Characters.Attack"); Integer attackroll=naturalattackroll+attackvalue; Integer defenceroll=gsRand(1,20); // only gets a bonus if "dodge" mode if (defencetype=="Dodge") { Integer naturalagility=gsGetKV(CALLER,"Characters.Agility"); defenceroll=defenceroll+naturalagility; } // and calculate the attack String output=""; Integer originaldamage=gsRand(1,6); // 1-6 damage Integer damage=originaldamage; // for debugging, so we can see the original if (defencetype=="Dodge") { // all or nothing attack if (defenceroll>attackroll) { // miss output=" swings at "+target+", but misses!"; damage=0; } else { // hit... // is it a crit? if (naturalattackroll==20) { output=" swings mightily at "+target; damage=damage*2; } else { output=" swings at "+target; } } } if (defencetype=="Block") { // defence roll does nothing, we just take damage. maybe double. // double it before the block value. you may wish to do it after // which would make the minimum crit damage blockable to 2 rather than 1 output=" strikes against "+target+"'s shield"; if (naturalattackroll==20) { damage=damage*2; output=" strikes mightily against "+target+"'s shield"; } Integer blockvalue=gsGetKV(CALLER,"Characters.Block"); damage=damage-blockvalue; if (damage<1) { damage=1; } // cap the reduction to 1 damage } // add damage to the message, if any was done if (damage>0) { output=output+", dealing "+damage+" points of damage"; } Integer discard=gsSayAsChar(CALLER,"/me "+output); // and inflict the damage. Need an API call for this :P // this ought to work for now discard=gsAPIX(CALLER,"Roller.rollDamageAgainst",[target+"","1","1","1","1","1","0",damage+"",CALLER+output]);