/* /lib/abilities.c * From the Dead Souls LPC Library * Handles learned traits * Created by Descartes of Borg 950122 * Version: @(#) abilities.c 1.22@(#) * Last modified: 97/01/03 */ inherit LIB_LEVEL; private int Level = 1; private mapping Skills = ([]); private static mapping SkillsBonus = ([]); // abstract methods varargs void eventPrint(string str, mixed args...); // end abstract methods string array GetPrimarySkills(); varargs void SetSkill(string skill, int level, mixed cls); /* ***************** abilities.c attributes ***************** */ /* GetBaseSkillLevel() returns the unmodified skill level */ int GetBaseSkillLevel(string skill){ if( !Skills[skill] ){ return 0; } else { return Skills[skill]["level"]; } } int GetLevel(){ return Level; } /* static int ResetLevel() * * description * takes the average skill level of the primary skills and divided by 4 * and sets the level to that number * * returns the new level */ /* * Excuse me, wtf is the point of this? */ int ResetLevel(){ string array skills = GetPrimarySkills(); int num = sizeof(skills); int points = 0; if( num < 1 ){ return (Level = 1); } foreach(string skill in skills){ points += Skills[skill]["level"]; } Level = (points/num)/2; if( Level < 1 ){ Level = 1; } return Level; } int SetLevel(int x){ string array skills = GetPrimarySkills(); if(!Level){ foreach(string skill in skills){ SetSkill(skill, 2*x); } } return (Level = x); } int GetMaxSkillPoints(string skill, int level){ if( !Skills[skill] ){ return 0; } else if( level == 0 ){ return 200; } else { int cl, x; if( !(cl = Skills[skill]["class"]) ){ return level * 600; } if( cl > 4 ){ cl = 4; } if( cl < 1 ){ cl = 4; } x = level; while( cl-- ){ x *= level; } return (x * 400); } } string array GetPrimarySkills(){ return filter(keys(Skills), (: Skills[$1]["class"] == 1 :)); } /* varargs int AddSkill(string skill, int classes) * string skill - the skill being added (required) * int classes - the class of the skill (optional) * * defaults * classes defaults to 1, primary class * * description * Used to add a new ability to the list of abilities. "skill" is the name * of the skill being added, and "class" represents the ranking of that skill * * returns 1 on success, 0 on failure */ varargs int AddSkill(string skill, int cls, int level){ if( !stringp(skill) ){ error("Bad argument 1 to AddSkill().\n\tExpected: string, Got: " + typeof(skill) + "\n"); } if( !nullp(Skills[skill]) ){ return 0; } if( !cls ){ cls = 1; } if(!level){ level = 1; } else if( cls < 0 || cls > 4){ return 0; } Skills[skill] = ([ "points" : 0, "level" : level, "class" : cls ]); return 1; } mapping GetSkill(string skill){ return copy(Skills[skill]); } void RemoveSkill(string skill){ if( !Skills[skill] ){ return; } map_delete(Skills, skill); } /* varargs void SetSkill(string skill, int level, int classes) * string skill - the name of the skill being set (required) * int level - the level to which that skill is being set (required) * int classes - the class to which the skill is being set (optional) * * defaults * classes will default to 1, primary class * * description * sets the skill "skill" to the level "level" * if a classes is given, its class is set to it, otherwise the class is * set to 1 * useful mostly for monster types, probably should have override * protections in the user object (should use AddSkill() for users) */ varargs void SetSkill(string skill, int level, mixed cls){ int tmp; if(cls && !intp(cls)){ tmp = 1; cls = tmp; } if( !stringp(skill) ){ error("Bad argument 1 to SetSkill().\n\tExpected: string, Got: " + typeof(skill) + "\n"); } if( !cls ){ if( Skills[skill] ){ cls = Skills[skill]["class"]; } else { cls = 1; } } else if( cls < 1 || cls > 4){ return 0; } Skills[skill] = ([ "points" : 0, "level" : level, "class" : cls ]); } string array GetSkills(){ return keys(Skills); } mapping GetSkillsMap(){ return copy(Skills); } void AddSkillBonus(string skill, mixed f){ if( !SkillsBonus[skill] ){ SkillsBonus[skill] = ([]); } SkillsBonus[skill][previous_object()] = f; } varargs void RemoveSkillBonus(string skill, object ob){ if( !SkillsBonus[skill] ){ return; } if( !ob ){ ob = previous_object(); } if( !ob || !SkillsBonus[skill][ob] ){ return; } map_delete(SkillsBonus[skill], ob); } int GetSkillBonus(string skill){ object ob; int x = 0; if( !SkillsBonus[skill] ){ return 0; } if(intp(SkillsBonus[skill])) return SkillsBonus[skill]; foreach(ob in keys(SkillsBonus[skill])){ if( !ob ) continue; else if(intp(SkillsBonus[skill][ob])) x += SkillsBonus[skill][ob]; else x += evaluate(SkillsBonus[skill][ob], skill); } return x; } int GetSkillClass(string skill){ if( !Skills[skill] ){ return 0; } else { return Skills[skill]["class"]; } } /* GetSkillLevel() returns the base skill level + any bonuses */ int GetSkillLevel(string skill){ return (GetBaseSkillLevel(skill) + GetSkillBonus(skill)); } /* int AddSkillPoints(string skill, int x) * string name - the skill to which points are being added * int x - the number of points being added * * description * adds "x" points to the total for skill "skill" * if the points go over the max for the current skill level, * then the level is raised 1 * if the points go under 0, then the skill level is lowered * * returns the skill level after addition */ int AddSkillPoints(string name, int x){ int y; if( !Skills[name] ){ return 0; } Skills[name]["points"] += x; while( Skills[name]["points"] < 0 ){ /* lost skills! */ if( Skills[name]["level"] == 1 ){ Skills[name]["points"] = 0; } else { int tmp; tmp = --Skills[name]["level"]; Skills[name]["points"] += GetMaxSkillPoints(name, tmp); if( Skills[name]["class"] == 1 ){ } } } y = GetMaxSkillPoints(name, Skills[name]["level"]); while( Skills[name]["points"] > y ){ int max; if( Skills[name]["class"] == 1 ){ max = 2; } else { max = 1; } if( Skills[name]["level"] >= ((GetLevel()+max) *2) ){ Skills[name]["points"] = y; } else { eventPrint("%^YELLOW%^You are a bit more adept with your " + name + "."); Skills[name]["level"]++; Skills[name]["points"] -= y; if( Skills[name]["class"] == 1 ){ } } y = GetMaxSkillPoints(name, Skills[name]["level"]); } return Skills[name]["level"]; } /* ******************* abilities.c events ********************* */ /** * Trains a skill based on a scale of 1-100 in favour of success and 1-100 * against success. Any particular thing (like calculating whether a player * hits an enemy) determins whether an operation succeeds or fails. For * example, pro = melee attack, con = melee defense. While the con may * be greater than the pro, combat may randomize that. You still reward * based on the absolutes. Success is flagged to this method. The value of * training looks like this: * highest- pro: 0, con: 100, success: 1 * moderate- pro: 100, con: 0, success: 1 * moderate- pro: 0, con 100, success: 0 * low- pro: 100, con: 0, success: 0 * This means if you have everything going against you and you succeed, you * get the highest reward. If you have everything going for you and you fail, * you get nothing. * Adjustments are made for your level and any multiplier bonuses. */ varargs void eventTrainSkill(string skill, int pro, int con, int array a...){ int level = (GetLevel()/8 + 1); int val, success, bonus; if( sizeof(a) ){ success = a[0]; if( sizeof(a) == 2 ){ bonus = a[1]; } else { bonus = 1; } } else { success = 1; bonus = 1; } if( con > 100 ){ con = 100; } if( con < 0 ){ con = 0; } if( pro > 100 ){ pro = 100; } if( pro < 0 ){ pro = 0; } val = (con - pro + (200*success) + 100)/8; AddSkillPoints(skill, (bonus * val * level * level) + 1); } /* ****************** abilities.c driver applies **************** */ static void create(){ }