I start with 50% then I add the user's skill and subtract the challenge rating to come out with the final goal, but I found that even capping the chance to 5% minimum and 95% maximum didn't provide the graduation into likelihood that I was craving.
The concept of this skill use function is to allow a user to constantly progress in levels but also have a chance at long shots as well as failure at something he is trained in. In other words keeping the challenge within reach for longer then a normal experience. It also increases the reward of progression the more well matched the challenge encouraging the user to seek out challenges his or her level of skill.
Thanks to Lummox, Kaiochao, Flame Guardian and everyone else who joined in my many questions for all for helping me understand what I know so far.
skill
var
label
learnrate
rank
exp
mob/proc/SkillUse(skill/Skill, TargetSkill,TargetLabel=null)
//constructing skill or challenge
var/tmp/skill/TSkill
if(istype(TargetSkill,/skill))
TSkill = TargetSkill
else
TSkill.rank = TargetSkill
TSkill.label = TargetLabel
// Initialize Skill Check
var/tmp/Roll = rand(1,100)
var/tmp/Diff = 50 + Skill.rank - TSkill.rank
//Difficulty Throttling - Used to keep the worlds difficulties more capable with all ranges.
var/tmp/Trade
var/tmp/OrigDiff = Diff
//Underkill Throttling - For keeping things from getting Weak too Fast!
if(Diff < -75) {Diff = 1;goto DiffChanged}
if(Diff >= -75 && Diff < -45) {Trade = abs(Diff) - 45;Trade = round(Trade / 6); Diff = 5 - Trade;goto DiffChanged}
if(Diff >= -45 && Diff < -20) {Trade = abs(Diff) - 20;Trade = round(Trade / 5); Diff = 10 - Trade;goto DiffChanged}
if(Diff >= -20 && Diff < 0) {Trade = abs(Diff);Trade = round(Trade / 4); Diff = 15 - Trade;goto DiffChanged}
if(Diff >= 0 && Diff < 15) {Trade = Diff;Trade = round(Trade / 3); Diff = 20 - Trade;goto DiffChanged}
if(Diff >= 15 && Diff < 25) {Trade = Diff - 15;Trade = round(Trade / 2); Diff = 25 - Trade;goto DiffChanged}
//OverKill Throttling - For keeping things from getting Strong too Fast!
if(Diff > 75 && Diff <= 85) {Trade = Diff - 75;Trade = round(Trade / 2); Diff = 75 + Trade;goto DiffChanged}
if(Diff > 85 && Diff <= 100){Trade = Diff - 85;Trade = round(Trade / 3); Diff = 80 + Trade;goto DiffChanged}
if(Diff > 100 && Diff <= 120){Trade = Diff - 100;Trade = round(Trade / 4); Diff = 85 + Trade;goto DiffChanged}
if(Diff > 120 && Diff <= 145){Trade = Diff - 120;Trade = round(Trade / 5); Diff = 90 + Trade;goto DiffChanged}
if(Diff > 145 && Diff <= 175){Trade = Diff - 145;Trade = round(Trade / 6); Diff = 95 + Trade;goto DiffChanged}
if(Diff > 175) {Diff = 99;goto DiffChanged}
// Difficulty Change due to Throttle reporting
DiffChanged:
usr << "[OrigDiff]% Throttled to [Diff]% Difficulty."
// Roll for Skill Check
var/tmp/Result
if(Roll <= Diff)
Result = abs(Roll - Diff)
if(Roll > Diff)
var/tmp/Fail = Roll - Diff
Result = (Fail - Fail) - Fail
usr << "[usr.name]'s [Skill.label] vs [TSkill.label]<br>50% +[Skill.rank] vs [TSkill.rank] = [Diff]% 1d100([Roll]) *[Result]*"
// Skill advancement
var/tmp/XP
if(Diff < 30) XP = 1
if(Diff >= 30 && Diff < 35) XP = 2
if(Diff >= 35 && Diff < 40) XP = 3
if(Diff >= 40 && Diff < 45) XP = 4
if(Diff >= 45 && Diff < 55) XP = 5
if(Diff >= 55 && Diff < 60) XP = 4
if(Diff >= 60 && Diff < 65) XP = 3
if(Diff >= 65 && Diff < 70) XP = 2
if(Diff >= 70 && Diff < 100) XP = 1
//XP Report
if(XP >= 3)
var/image/I = image('cloud.dmi',usr)
I.icon_state = "exp"
I.pixel_y = 32
I.pixel_x = -8
usr << I
animate(I, pixel_y = 64, time = 30)
spawn(20) animate(I, alpha = 0, time = 10)
spawn(30) del I
//Success/Failure Adjustment for XP
if(Result < 0) XP = XP * 2
//Award XP to player skill
Skill.exp += XP
//Skill Leveling & Reporting
var/tmp/GoalLvl = Skill.rank + 1
var/tmp/NxtLvl = round((GoalLvl * 10) * Skill.learnrate)// <-------Testing OUT 10 instead
var/tmp/ToLvl = NxtLvl - Skill.exp
if(Skill.exp >= NxtLvl)
Skill.rank++
Skill.exp = 0
usr << "You gained a New Rank of [Skill.rank] in [Skill.label]"
else
usr << "[XP] Exp - [Skill.label] Next Level in [ToLvl] Exp"
return Result