Dump of #19051 (Generic Skill Object) @create $root_class named Generic Skill Object:Generic,Skill,Object @prop #19051."dependant" {} r ;;#19051.("dependant") = {{}, {}} @prop #19051."learn" 10 r @prop #19051."encumbrance" 0 r @prop #19051."insanity" 0 r @prop #19051."injury" 0 r @prop #19051."fatigue" 0 r @prop #19051."dep_names" {} r @prop #19051."neg_deps" {} r @prop #19051."neg_dep_names" {} r @prop #19051."max_level" 25 r @prop #19051."caps" {} r @prop #19051."cap_names" {} r @prop #19051."cap_boost_mult" 1 r @prop #19051."enc_ins_inj_fat" {} rc ;;#19051.("enc_ins_inj_fat") = {0, 0, 0, 0} @prop #19051."improve_learn_ok" 1 rc @prop #19051."improve_task" 264748148 r "#19051.("queue") => E_PERM (Permission denied) @prop #19051."move_dependent" 0 r "#19051.("key") => E_PERM (Permission denied) ;;#19051.("aliases") = {"Generic", "Skill", "Object"} ;;#19051.("description") = "An indicator of skill in some nameless area." ;;#19051.("object_size") = {15902, 1141286561} @verb #19051:"resolve" this none this @program #19051:resolve ":resolve(, , [FLAG no_improve], [OBJ permissions]) => NUM result of skill roll for character, with modfier added on."; "The no_improve flag, if given and true, prevents the doll's skill improvement routine from being called at all."; "The permissions argument overrides the regular perm check for gm probationary status in deciding whether or not to call the doll's improve routine."; if (caller_perms() in (rpg = $local.rpg).gms) {char, mod, ?no_imp = 0, ?perms = caller_perms()} = args; if (valid(doll = rpg:get_doll(char))) no_imp = no_imp || (valid(doll.duelee) && (`rpg:get_doll(doll.duelee).duelee ! E_INVIND' == doll.character)); res = rpg:roll(doll:total(this) + mod) - (pen = this:penalty(doll)); res = this:slowness_mod(res - this:stinkcloud_pen(doll), doll); ic = this:slowness_mod(max(20, random(180) - 60), doll) - pen; if (no_imp) "... don't call improve ..."; else if ((res > -20) && (res < ic)) (perms in rpg.probation) || this:check_improve(doll); endif this:track_usage(); endif doll.last_action = time(); return res; else return -200; endif else return 100 - random(200); "Return some random nonsensical number, just so prospective GMs can practice with resolves and not get E_TYPEs from an E_PERM."; endif . @verb #19051:"moveto" this none this @program #19051:moveto {where} = args; if ($local.rpg:is_grandmaster(caller_perms()) || caller_perms().wizard) return pass(where); else return E_PERM; endif . @verb #19051:"penalty" this none this @program #19051:penalty {doll} = args; if (caller == this) return ((((4 + (this.injury * doll.inj)) + (this.insanity * doll.ins)) + (this.fatigue * doll.fat)) + ((this.encumbrance * doll:encumbrance()) / 3)) / min(25, doll.end || 15); endif return 0; "THX (#105941) - Mon Mar 29, 1999 - subst /10/(doll.end || 15)/2"; . @verb #19051:"property_name" this none this @program #19051:property_name "Return the corresponding property name on $local.rpg.doll."; return this.aliases[1]; . @verb #19051:"initialize" this none this rx @program #19051:initialize if ((caller == this) || $perm_utils:controls(caller_perms(), this)) this:moveto($local.rpg.skills); $quota_utils:object_bytes(this); return pass(@args); else return E_PERM; endif "Profane 13-DEC-95 1126 EST -- $quota:utils:object_size."; . @verb #19051:"recycle" this none this rx @program #19051:recycle if ((caller == this) || $perm_utils:controls(caller_perms(), this)) propname = this:property_name(); delete_property($local.rpg.doll, propname); delete_property($local.rpg.skills, propname); return pass(@args); else return E_PERM; endif . @verb #19051:"description" this none this @program #19051:description "Return the description, plus a line detailing which skills affect this one."; deps = this.dependant; atts = deps[1]; skills = deps[2]; if (atts || skills) depstr = (((this:title() + " is a skill directly influenced by ") + (atts ? "the attributes " + $string_utils:title_list(atts) | "")) + (skills ? ((atts ? ", and " | "") + "the skill(s) ") + $string_utils:title_list(skills) | "")) + "."; else depstr = this:title() + " is a basic attribute."; endif return {@(typeof(base = pass(@args)) == LIST) ? base | {base}, depstr}; "DR 10-APR-94 -- Tweaked the spacing in 'the skills'."; . @verb #19051:"tell_stats" this none this @program #19051:tell_stats stats = properties($local.RPG.skill_object); player:tell($string_utils:centre(this.name, 40, "-")); dep = this.dependant; player:tell("Dependant Attributes: ", $string_utils:nn(dep[1], "", "None")); player:tell("Dependant Skills: ", $string_utils:nn(dep[2], "", "None")); player:tell(""); for pn in (setremove(stats, "dependant")) player:tell($string_utils:left(pn, 18), ": ", $string_utils:print(this.(pn))); endfor player:tell($string_utils:space(40, "-")); . @verb #19051:"stinkcloud_pen*alty" this none this @program #19051:stinkcloud_penalty ":stinkcloud_penalty() => NUM penalty that doll should have to a resolve roll for being under the influence of stinkcloud"; {doll} = args; rpg = $local.rpg; if ((rpg.magic_db.sc_combat_effect in doll.view_effects) && (data = doll:read_misc_note("stinkcloud"))) if (caller != this) "Return some random nonsensical number, just so prospective GMs can practice with resolves and not get E_TYPEs from an E_PERM."; return 99 - random(200); endif {qual, time} = data; qual = (qual > 0) ? qual | 0; cloud_pen = min(max((time - time()) + (qual * toint(sqrt(tofloat(qual)))), 1), qual); if ((rpg.skills.shock:resolve(doll, -cloud_pen) >= 0) || ((time() - time) > 1200)) doll:erase_misc_note("stinkcloud"); rpg.magic_db.sc_combat_effect:remove(doll); rpg:playertell(doll.character, "You have finally recovered from the effects of the stinking cloud."); cloud_pen = 0; else if (random(4) == 1) rpg:playertell(doll.character, "You are still reeling from the effects of the stinking cloud. . ."); rpg:say_action("%N % and %.", doll.character); endif endif return cloud_pen; endif return 0; "Irin Mon Sep 9 17:15:12 1996 PDT -- replaced $math_utils:sqrt() with sqrt(). Set max penalty to equal quality."; "THX 18-FEB-1997 - tossed in scatters where appropriate to kill list indexings. Cleaned up a bit."; "Profane (#30788) - Tue Jan 13, 1998 - simplify security"; "THX (#105941) - Wed Jun 13, 2001 - Put security check inside the check for stinkcloud presence and checked for stinkcloud effect in doll.view_effects before doll:read_misc_note(\"stinkcloud\"). This saves ~100 ticks for every single resolve call! But we should still get rid of this hack."; . @verb #19051:"fake_resolve pseudoresolve" this none this @program #19051:fake_resolve ":fake_resolve(, , [NUM skill score,LIST dependant, NUM learn, NUM encumbrance pen, NUM insanity pen, NUM injury pen, NUM fatigue pen]) => As a regular resolve, but allows you to pass parameters for various penalty bits."; if (!$local.rpg:trusted(caller_perms())) return 100 - random(200); elseif (!valid(doll = $local.rpg:get_doll(args[1]))) return E_INVARG; else mod = args[2]; l = length(args); score = (l > 2) ? args[3] | doll.(this:property_name()); dependant = (l > 3) ? args[4] | this.dependant; learn = (l > 4) ? args[5] | this.learn; insanity = (l > 5) ? args[6] | this.insanity; injury = (l > 6) ? args[7] | this.injury; fatigue = (l > 7) ? args[8] | this.fatigue; total = score; for dep_att in (dependant[1]) total = total + doll.(dep_att.aliases[1]); endfor for dep_att in (dependant[2]) total = total + doll:total(dep_att); endfor pen = ((((4 + (injury * doll.inj)) + (insanity * doll.ins)) + (fatigue * doll.fat)) + ((encumbrance * doll:encumbrance()) / 10)) / 10; res = $local.rpg:roll((total + mod) - pen); res = res - this:stinkcloud_pen(doll); doll.last_action = time(); return res; endif . @verb #19051:"cap" this none this @program #19051:cap "#19051:cap(doll) => returns maximum value that the skill can have, for purposes of $local.rpg.doll:improve."; $local.rpg:secure(); if (cn = this.cap_names) {doll} = args; top = 0; for c in (cn) top = max(top, doll.(c)); endfor return top; else return this.max_level; endif "Each skill has a list of cap names. These are compiled by #34595:update_skills, when skills are changed. Each skill has an individual cap, and each one depends on either its own cap, or if it has none, the caps of all skills higher on it in the hierarchy. Thus, melee is based on CAPmelee, while rapier is capped by CAPsword and CAPweap1. Somebody come up with a less obscure method. Please! ;) -- Irin."; . @verb #19051:"improve_learn_ok" this none this @program #19051:improve_learn_ok return this.(verb); . @verb #19051:"slowness_mod" this none this @program #19051:slowness_mod "Makes it more difficult to improve if you're hasted. Easier of slowed."; "I realize the code is a bit of an eye-sore. So, what it does is take the first argument, `res' and will halve it for a slowness of 2 and make it half again its original value for a slowness of 18. Those are the min and max values and everything in-between is proportionate. A slowness of 10 would be unchanged."; {res, doll} = args; if (caller == this) return toint(tofloat(res) * doll.slowness_mod); else return res; endif "Mooshie (#106469) - Fri Dec 26, 1997 - Added. I hope I never have to look back on this and wonder how I was doing it."; "Mooshie (#106469) - Thu Feb 5, 1998 - Faster version. :set_att now hooks .slowness modifications and sets .slowness_mod appropriately."; . @verb #19051:"check_improve" this none this @program #19051:check_improve ":check_improve(OBJ doll)"; {doll} = args; (rpg = $local.rpg):secure(); who = doll.character; if ((`idle_seconds(who) ! ANY => -1' < 0) && (!(who.owner in rpg.gms))) raise(E_PERM, "No skill improvement for disconnected players."); elseif (this.move_dependent && doll:stymied()) return; endif root = $code_utils:verb_loc(); root.queue = {@root.queue, {doll, this, callers()}}; "Okay, we're basically checking if the improve_task has ended, or suspended in someone else's queue here. I.e., some idiot player's :tell verb."; if ((!$code_utils:task_valid(root.improve_task)) || (`task_stack(root.improve_task) ! ANY' == E_PERM)) fork z (0) root:do_improve(); endfork root.improve_task = z; endif . @verb #19051:"do_improve" this none this @program #19051:do_improve ":do_improve()"; (rpg = $local.rpg):secure(); root = $code_utils:verb_loc(); while (root.queue && (root.improve_task == task_id())) {doll, skill, callers} = root.queue[1]; root.queue = root.queue[2..$]; if (`doll.(skill.aliases[1]) || 1 ! ANY') doll:improve(skill, 0, callers); endif rpg:s_i_f_i_n(); endwhile . @verb #19051:"track_usage" this none this @program #19051:track_usage return; . @verb #19051:"penalty_trusted" this none this @program #19051:penalty_trusted {doll} = args; $local.rpg:secure(); return this:penalty(doll); . @verb #19051:"stinkcloud_pen(old)" this none this @program #19051:stinkcloud_pen(old) ":stinkcloud_penalty() => NUM penalty that doll should have to a resolve roll for being under the influence of stinkcloud"; if (caller != this) "Return some random nonsensical number, just so prospective GMs can practice with resolves and not get E_TYPEs from an E_PERM."; return 99 - random(200); else {doll} = args; rpg = $local.rpg; if (data = doll:read_misc_note("stinkcloud")) {qual, time} = data; qual = (qual > 0) ? qual | 0; cloud_pen = min(max((time - time()) + (qual * toint(sqrt(tofloat(qual)))), 1), qual); if ((rpg.skills.shock:resolve(doll, -cloud_pen) >= 0) || ((time() - time) > 1200)) doll:erase_misc_note("stinkcloud"); rpg.magic_db.sc_combat_effect:remove(doll); rpg:playertell(doll.character, "You have finally recovered from the effects of the stinking cloud."); cloud_pen = 0; else if (random(4) == 1) rpg:playertell(doll.character, "You are still reeling from the effects of the stinking cloud. . ."); rpg:say_action("%N % and %.", doll.character); endif endif return cloud_pen; endif endif "Irin Mon Sep 9 17:15:12 1996 PDT -- replaced $math_utils:sqrt() with sqrt(). Set max penalty to equal quality."; "THX1138 18-FEB-1997 - tossed in scatters where appropriate to kill list indexings. Cleaned up a bit."; "Profane (#30788) - Tue Jan 13, 1998 - simplify security"; . "***finished***