I eliminated all the "multipliers" in my code in favor of consistency and simplicity. I award 1 raw skill point per success. I adjust the RawToBase and BaseToRaw conversions.
In this way, I've adjusted my skill gains so they're fairly fast early on, then get progressively slower as a skill rises.
This is a copy of my exported CheckSkill function:
Code:
use uo;
use os;
use util;
include "include/attributes";
program SyshookCheckSkill ( )
Syslog ( "Installing skillcheck..." );
return 1;
endprogram
exported function NewCheckSkill ( character, skillid, difficulty )
var attribute := GetAttributeIDBySkillID ( skillid );
var player_Skill := GetAttribute ( character, attribute );
var deniedTest := BaseToRaw ( player_Skill );
var skillCheck;
// Because I deny some skills based on class, if the skill is zero, the test
// auto-fails
if ( deniedTest == 0 )
SendSysMessage ( character, "You are untrained in this area." );
return 0;
endif
// Because I start all skills for newb characters at 0.1, to help move
// the skill along set the player's skill at 13 for the check.
if ( player_Skill < 13 )
skillCheck := 13;
else
skillCheck := player_Skill;
endif
// If the character skill is under the difficulty by more than 5, they fail.
if ( skillCheck <= ( difficulty - 5 ) )
return 0;
// If the character skill is 15 or more than the difficulty, they auto-suceed
elseif ( skillCheck >= ( difficulty + 15 ) )
// In character creation, we pre-calculated skill caps based on class
// and race choices. Those values are stored as props on the character.
var charMaxAttribute := ( "max" + attribute );
var maxSkill := GetObjProperty ( character, charMaxAttribute );
// Convert the skill to its raw form.
var rawMaxSkill := BaseToRaw ( maxSkill );
rawMaxSkill := ( rawMaxSkill + 1 );
// Find out what the character's current skill is and convert it to raw form.
var currentRawSkill := BaseToRaw ( player_Skill );
var possibleNewRawSkill := ( currentRawSkill + 1);
// If the character's skill isn't capped, award 1 raw skill point.
if ( rawMaxSkill > possibleNewRawSkill )
AwardRawSkill ( character, attribute, 1 );
StatIncrease ( character, skillid );
endif
return 1;
else
// The character's skill must be somewhere between 5 under and 15 over
// the difficulty of the skill test, so let's do a random check.
var dieRoll := ( skillCheck + 20 );
dieRoll := RandomInt ( dieRoll );
if ( dieRoll <= skillCheck )
// The check suceeded! Now go and award skill.
var charMaxAttribute := ( "max" + attribute );
var maxSkill := GetObjProperty ( character, charMaxAttribute );
var rawMaxSkill := BaseToRaw ( maxSkill );
rawMaxSkill := ( rawMaxSkill + 1 );
var currentRawSkill := BaseToRaw ( player_Skill );
var possibleNewRawSkill := ( currentRawSkill + 1);
if ( rawMaxSkill > possibleNewRawSkill )
AwardRawSkill ( character, attribute, 1 );
StatIncrease ( character, skillid );
endif
return 1;
else
// The skill check failed, so don't award anyone anything and return
// the failure.
return 0;
endif
endif
endfunction
Then, if you look at the BaseToRaw and RawToBase conversions:
Code:
function BaseToRaw ( base )
if ( base <= 200 )
return CInt ( base * 20 );
elseif ( base > 200 and base <= 300 )
return 4000 + ( CInt ( base - 200 ) * 80 );
elseif ( base > 300 and base <= 400 )
return 8000 + ( CInt ( base - 300 ) * 80 );
elseif ( base > 400 and base <= 500 )
return 16000 + ( CInt ( base - 400 ) * 320 );
elseif ( base > 500 and base <= 600 )
return 32000 + ( CInt ( base - 500 ) * 320 );
elseif ( base > 600 and base <= 700 )
return 64000 + ( CInt ( base - 600 ) * 1280 );
elseif ( base > 700 and base <= 800 )
return 128000 + ( CInt ( base - 700 ) * 1280 );
elseif ( base > 800 and base <= 900 )
return 256000 + ( CInt ( base - 800 ) * 5120 );
elseif ( base > 900 and base <= 1000 )
return 512000 + ( CInt ( base - 900 ) * 5120 );
elseif ( base > 1000 and base <= 1100 )
return 1024000 + ( CInt ( base - 1000 ) * 10240 );
elseif ( base > 1100 and base <= 1200 )
return 2048000 + ( CInt ( base - 1100 ) * 10240 );
elseif ( base > 1200 and base <= 1300 )
return 3072000 + ( CInt ( base - 1200 ) * 10240 );
elseif ( base > 1300 and base <= 1400 )
return 4096000 + ( CInt ( base - 1300 ) * 10240 );
elseif ( base > 1400 and base <= 1500 )
return 5120000 + ( CInt ( base - 1400 ) * 10240 );
elseif ( base > 1500 and base <= 1600 )
return 6144000 + ( CInt ( base - 1500 ) * 10240 );
elseif ( base > 1600 and base <= 1700 )
return 7168000 + ( CInt ( base - 1600 ) * 10240 );
elseif ( base > 1700 and base <= 1800 )
return 8192000 + ( CInt ( base - 1700 ) * 10240 );
elseif ( base > 1800 and base <= 1900 )
return 9216000 + ( CInt ( base - 1800 ) * 10240 );
elseif ( base > 1900 and base <= 2000 )
return 10240000 + ( CInt ( base - 1900 ) * 10240 );
endif
endfunction
function RawToBase ( rawpoints )
if ( rawpoints <= 2000 )
return CInt ( CInt ( rawpoints / 20 ));
elseif ( rawpoints > 2000 and rawpoints <= 4000 )
return CInt ( CInt ( ( rawpoints - 2000 ) / 20 ) + 100 );
elseif ( rawpoints > 4000 and rawpoints <= 8000 )
return CInt ( CInt ( ( rawpoints - 4000 ) / 80 ) + 200 );
elseif ( rawpoints > 8000 and rawpoints <= 16000 )
return CInt ( CInt ( ( rawpoints - 8000 ) / 80 ) + 300 );
elseif ( rawpoints > 16000 and rawpoints <= 32000 )
return CInt ( CInt ( ( rawpoints - 16000 ) / 320 ) + 400 );
elseif ( rawpoints > 32000 and rawpoints <= 64000 )
return CInt ( CInt ( ( rawpoints - 32000 ) / 320 ) + 500 );
elseif ( rawpoints > 64000 and rawpoints <= 128000 )
return CInt ( CInt ( ( rawpoints - 64000 ) / 1280 ) + 600 );
elseif ( rawpoints > 128000 and rawpoints <= 256000 )
return CInt ( CInt ( ( rawpoints - 128000 ) / 1280 ) + 700 );
elseif ( rawpoints > 256000 and rawpoints <= 512000 )
return CInt ( CInt ( ( rawpoints - 256000 ) / 5120 ) + 800 );
elseif ( rawpoints > 512000 and rawpoints <= 1024000 )
return CInt ( CInt ( ( rawpoints - 512000 ) / 5120 ) + 900 );
elseif ( rawpoints > 1024000 and rawpoints <= 2048000 )
return CInt ( CInt ( ( rawpoints - 1024000 ) / 10240 ) + 1000 );
elseif ( rawpoints > 2048000 and rawpoints <= 3072000 )
return CInt ( CInt ( ( rawpoints - 2048000 ) / 10240 ) + 1100 );
elseif ( rawpoints > 3072000 and rawpoints <= 4096000 )
return CInt ( CInt ( ( rawpoints - 3072000 ) / 10240 ) + 1200 );
elseif ( rawpoints > 4096000 and rawpoints <= 5120000 )
return CInt ( CInt ( ( rawpoints - 4096000 ) / 10240 ) + 1300 );
elseif ( rawpoints > 5120000 and rawpoints <= 6144000 )
return CInt ( CInt ( ( rawpoints - 5120000 ) / 10240 ) + 1400 );
elseif ( rawpoints > 6144000 and rawpoints <= 7168000 )
return CInt ( CInt ( ( rawpoints - 6144000 ) / 10240 ) + 1500 );
elseif ( rawpoints > 7168000 and rawpoints <= 8192000 )
return CInt ( CInt ( ( rawpoints - 7168000 ) / 10240 ) + 1600 );
elseif ( rawpoints > 8192000 and rawpoints <= 9216000 )
return CInt ( CInt ( ( rawpoints - 8192000 ) / 10240 ) + 1700 );
elseif ( rawpoints > 9216000 and rawpoints <= 10240000 )
return CInt ( CInt ( ( rawpoints - 9216000 ) / 10240 ) + 1800 );
elseif ( rawpoints > 10240000 and rawpoints <= 11264000 )
return CInt ( CInt ( ( rawpoints - 10240000 ) / 10240 ) + 1900 );
elseif ( rawpoints > 11264000 and rawpoints <= 12288000 )
return CInt ( CInt ( ( rawpoints - 11264000 ) / 10240 ) + 2000 );
endif
endfunction
You can see that until a character reaches a skill of 30, it requires 20 successful skill checks to equal a 0.1 skill gain. As their skills increase, the number of successes required to gain 0.1 in a skill increases.