r p g skills WIP.
This commit is contained in:
@@ -9,16 +9,13 @@ GLOBAL_LIST_INIT(skill_datums, init_skill_datums())
|
||||
S = new path
|
||||
.[S.type] = S
|
||||
|
||||
/proc/get_skill_datum(path)
|
||||
return GLOB.skill_datums[path]
|
||||
|
||||
/proc/sanitize_skill_value(path, value)
|
||||
var/datum/skill/S = get_skill_datum(path)
|
||||
var/datum/skill/S = GET_SKILL_DATUM(path)
|
||||
// don't check, if we runtime let it happen.
|
||||
return S.sanitize_value(value)
|
||||
|
||||
/proc/is_skill_value_greater(path, existing, new_value)
|
||||
var/datum/skill/S = get_skill_datum(path)
|
||||
var/datum/skill/S = GET_SKILL_DATUM(path)
|
||||
// don't check, if we runtime let it happen.
|
||||
return S.is_value_greater(existing, new_value)
|
||||
|
||||
@@ -30,6 +27,8 @@ GLOBAL_LIST_INIT(skill_datums, init_skill_datums())
|
||||
var/name
|
||||
/// Our description
|
||||
var/desc
|
||||
/// Color of the name as shown in the html readout
|
||||
var/name_color = "#000000"
|
||||
/// Our progression type
|
||||
var/progression_type
|
||||
/// Abstract type
|
||||
@@ -41,6 +40,13 @@ GLOBAL_LIST_INIT(skill_datums, init_skill_datums())
|
||||
/datum/skill/proc/sanitize_value(new_value)
|
||||
return new_value
|
||||
|
||||
/**
|
||||
* Sets the new value of this skill in the holder skills list.
|
||||
* As well as possible feedback messages or secondary effects on value change, that's on you.
|
||||
*/
|
||||
/datum/skill/proc/set_skill(datum/skill_holder/H, value, mob/owner)
|
||||
H.skills[type] = value
|
||||
|
||||
/**
|
||||
* Checks if a value is greater
|
||||
*/
|
||||
@@ -93,3 +99,85 @@ GLOBAL_LIST_INIT(skill_datums, init_skill_datums())
|
||||
/datum/skill/enum/sanitize_value(new_value)
|
||||
if(new_value in valid_values)
|
||||
return new_value
|
||||
|
||||
/**
|
||||
* Classing r p g styled skills, tiered by lvl, and current/nextlvl experience.
|
||||
*/
|
||||
/datum/skill/experience
|
||||
abstract_type = /datum/skill/experience
|
||||
var/standard_xp_lvl_up = STD_XP_LVL_UP //the standard required to level up. def: 100
|
||||
var/xp_lvl_multiplier = STD_XP_LVL_UP //standard required level up exp multiplier. def: 2 (100, 200, 400, 800 etc.)
|
||||
var/max_lvl = STD_MAX_LVL
|
||||
var/level_up_method = STANDARD_LEVEL_UP //how levels are calculated.
|
||||
var/list/levels = list() //level thresholds, if associative, these will be preceded by tiers such as "novice" or "trained"
|
||||
var/associative = FALSE //See above.
|
||||
var/unskilled_tier = "Unskilled" //Only relevant for associative experience levels
|
||||
|
||||
//Builds the levels list.
|
||||
/datum/skill/experience/New()
|
||||
. = ..()
|
||||
var/max_assoc = ""
|
||||
var/max_assoc_start = 1
|
||||
for(var/lvl in 1 to max_lvl)
|
||||
var/value
|
||||
switch(level_up_method)
|
||||
if(STANDARD_LEVEL_UP)
|
||||
value = XP_LEVEL(standard_xp_lvl_up, xp_lvl_multiplier, lvl)
|
||||
if(DWARFY_LEVEL_UP)
|
||||
value = DORF_XP_LEVEL(standard_xp_lvl_up, xp_lvl_multiplier, lvl)
|
||||
value = round(value)
|
||||
if(!associative)
|
||||
levels += value
|
||||
continue
|
||||
if(max_assoc)
|
||||
levels["[max_assoc] +[max_assoc_start++]"] = value
|
||||
continue
|
||||
var/key = LAZYACCESS(levels, lvl)
|
||||
if(!key)
|
||||
if(lvl == 1) //You dun goof it.
|
||||
stack_trace("Skill datum [src] was set to have an associative levels list despite the latted having no key.")
|
||||
associative = FALSE
|
||||
levels += value
|
||||
continue
|
||||
max_assoc = levels[lvl-1]
|
||||
levels["[max_assoc] +[max_assoc_start++]"] = value
|
||||
levels[key] = value
|
||||
|
||||
|
||||
/datum/skill/experience/sanitize_value(new_value)
|
||||
return round(max(new_value, 0))
|
||||
|
||||
/datum/skill/experience/set_skill(datum/skill_holder/H, value, mob/owner)
|
||||
var/old_value = H.skills[type]
|
||||
H.skills[type] = value
|
||||
if(value > old_value)
|
||||
|
||||
/datum/skill/experience/standard_render_value(value)
|
||||
var/current_lvl = associative ? unskilled_tier : 0
|
||||
var/current_lvl_xp_sum = 0
|
||||
var/next_lvl_xp_sum
|
||||
for(var/lvl in 1 to max_lvl)
|
||||
next_lvl_xp_sum = associative ? levels[levels[lvl]] : levels[lvl]
|
||||
if(value < next_lvl_xp_sum)
|
||||
break
|
||||
current_lvl_xp_sum = next_lvl_xp_sum
|
||||
current_lvl = associative ? levels[lvl] : current_lvl+1
|
||||
|
||||
return "[associative ? current_lvl : "Lvl. [current_lvl]"] ([value - current_lvl_xp_sum]/[next_lvl_xp_sum])[value > next_lvl_xp_sum ? " \[MAX!\]" : ""]"
|
||||
|
||||
/datum/skill/experience/job
|
||||
levels = ("Basic", "Trained", "Experienced", "Master")
|
||||
associative = TRUE
|
||||
|
||||
//quite the reference, no?
|
||||
/datum/skill/experience/dwarfy
|
||||
abstract_type = /datum/skill/experience/dwarfy
|
||||
standard_xp_lvl_up = DORF_XP_LVL_UP
|
||||
xp_lvl_multiplier = DORF_XP_LVL_MULTI
|
||||
max_lvl = DORF_MAX_LVL
|
||||
levels = list("Novice", "Adequate", "Competent", "Skilled",
|
||||
"Proficient", "Talented", "Adept", "Expert",
|
||||
"Professional", "Accomplished", "Great", "Master",
|
||||
"High Master", "Grand Master", "Legendary")
|
||||
associative = TRUE
|
||||
unskilled_tier = "Dabbling"
|
||||
|
||||
@@ -33,36 +33,37 @@
|
||||
/**
|
||||
* Sets the value of a skill.
|
||||
*/
|
||||
/datum/skill_holder/proc/set_skill_value(skill, value)
|
||||
if(!ispath(skill))
|
||||
/datum/skill_holder/proc/set_skill_value(skill, value, owner)
|
||||
if(!ispath(skill, /datum/skill))
|
||||
CRASH("Invalid set_skill_value call. Use typepaths.") //until a time when we somehow need text ids for dynamic skills, I'm enforcing this.
|
||||
LAZYINITLIST(skills)
|
||||
value = sanitize_skill_value(skill, value)
|
||||
var/datum/skill/S = GET_SKILL_DATUM(path)
|
||||
value = S.sanitize_value(value)
|
||||
if(!isnull(value))
|
||||
skills[skill] = value
|
||||
LAZYINITLIST(skills)
|
||||
S.set_skill(src, value, owner)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Boosts a skill to a value if not aobve
|
||||
*/
|
||||
/datum/skill_holder/proc/boost_skill_value_to(skill, value)
|
||||
/datum/skill_holder/proc/boost_skill_value_to(skill, value, mob/owner)
|
||||
var/current = get_skill_value(skill)
|
||||
if(!is_skill_value_greater(skill, current, value))
|
||||
return FALSE
|
||||
set_skill_value(skill, value)
|
||||
set_skill_value(skill, value, owner)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Automatic skill increase, multiplied by skill affinity if existing.
|
||||
* Only works if skill is numerical.
|
||||
*/
|
||||
/datum/skill_holder/proc/auto_gain_experience(skill, value)
|
||||
/datum/skill_holder/proc/auto_gain_experience(skill, value, mob/owner)
|
||||
if(!ispath(skill, /datum/skill/numerical))
|
||||
CRASH("You cannot auto increment a non numerical skill!")
|
||||
var/current = get_skill_value(skill)
|
||||
var/affinity = get_skill_affinity(skill)
|
||||
boost_skill_value_to(skill, current + (value * affinity))
|
||||
boost_skill_value_to(skill, current + (value * affinity), owner)
|
||||
|
||||
/**
|
||||
* Generates a HTML readout of our skills.
|
||||
@@ -73,6 +74,6 @@
|
||||
out += "<table style=\"width:100%\"><tr><th><b>Skill</b><th><b>Value</b></tr>"
|
||||
for(var/path in skills)
|
||||
var/datum/skill/S = GLOB.skill_datums[path]
|
||||
out += "<tr><td>[S.name]</td><td>[S.standard_render_value(skills[path])]</td></tr>"
|
||||
out += "<tr><td><font color='[S.name_color]'>[S.name]</font></td><td>[S.standard_render_value(skills[path])]</td></tr>"
|
||||
out += "</table>"
|
||||
return out.Join("")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
/datum/skill/experience/job/wiring
|
||||
name = "Wiring"
|
||||
desc = "How proficient and knowledged you are at wiring beyond laying cables on the floor."
|
||||
Reference in New Issue
Block a user