// guild.c // People come to the guild and buy skill training for gold. // Ideally, you'd like to have people train in skills, taking up time. But // it's super-boring having people type "kill dummy" over and over and // seeing "You hit the target dummy" eternally. So instead, you can trade // gold for skills, straight up. That way you have them spend the time // getting more gold instead :) // Written by Mobydick@TMI-2, 11-15-92 // Please leave the credits part of this header in place. // You can delete the rest of it. #include <mudlib.h> inherit ROOM ; // The variable trainable_skills stores the skills which this guild can // train you in. mixed trainable_skills ; // This function sets the skills you can train in at this guild. // If you pass the string argument ALL, then you can train in all // skills. Otherwise, you should pass an array of strings and the skills // names in that array are trainable, others are not. void set_trainable_skills (mixed skills) { trainable_skills = skills ; } // This function returns 1 if the guild trains in the skill and 0 if not. // It does NOT error check to make sure the string is actually a skill. int can_train (string skill) { // If trainable_skills is not set, or is set to "ALL", then we can train it. if (!trainable_skills) return 1 ; if (trainable_skills=="ALL") return 1 ; // If it is not a member of trainable_skills, we cannot train it. if (member_array(skill,trainable_skills)==-1) return 0 ; // It is a member of trainable skills, so we can train in it. return 1 ; } // Init adds the cost and train commands. You must call this if you // add your own init functions. void init() { add_action ("buy_skill", "train") ; add_action ("list_costs", "list") ; } // This function returns the cost of improving a named skill. // Right now it is set up so that the cost is 1 gp per 2 skill uses needed // to improve the skill the hard way. To do this, we copied the // skill improvement formula into this object. You don't need to have // the cost related to the use points, but we thought we'd set it up that // way. If you want to keep it that way, and you change the improvement // function, change this one too. int cost_of_skill (string str) { int i, cost, uses ; string *names ; mapping skills, stats ; skills = this_player()->query_skills() ; names = keys(skills) ; if (member_array(str,names)==-1) return -1 ; stats = this_player()->query_skill_stats() ; uses = (50-stats[str])*(2*skills[str]+1) ; cost = (uses-1)/2+1 ; return cost ; } // This function lets players buy skill improvements for gold. The cost // function is hardwired in here: you can change it if you want to. int buy_skill (string skill) { int cost, wealth, res ; if (!skill) { notify_fail ("What skill would you like to train in?\n") ; return 0 ; } // In the default mudlib, all skill names are capitalized. If you use // lowercase skill names, then replace this with a call to lower_case. // You probably should not use both capital and lowercase skill names, // but if you do, dike this out completely. skill = capitalize(skill) ; cost = cost_of_skill(skill) ; if (cost==-1) { notify_fail ("That is not a valid skill. Type \"skills\" to see a list of your options, or\n"+ "\"list\" to see the costs of all skills you could buy.\n") ; return 0 ; } if (!can_train(skill)) { notify_fail ("This guild cannot train you in that function.\n") ; return 0 ; } wealth = this_player()->query("wealth/gold") ; if (wealth<cost) { notify_fail ("The training would cost you "+cost+" gold coins, which you don't have.\n") ; return 0 ; } this_player()->set("wealth/gold",wealth-cost) ; // Increase the player's carrying capacity. res = this_player()->query("capacity") ; this_player()->set("capacity", res+cost) ; write ("You train laboriously and your skill improves.\n") ; res = this_player()->query_skill(skill) ; this_player()->change_skill_level(skill,res+1) ; // We do not change his skill use points. That way, if he was one use short // of improving before training, he will be one use short of making the next // improvement plus the number of extra uses required the make the higher // level. This way, the player always gets credit for the total number of // uses to make the level, rather than the number he needs to make it just // up to the new level. This seems fairer since the cost is the same whether // he needs 1 use or 1000, but it also means a player might buy skill level // N and very quickly improve again to skill level N+1. You could, if you // wanted, set his skill use points back to zero after training, and if // you REALLY wanted to you could have the price of training reflect this. // We chose not to, though; this way is less code, and easier code to read // (although the explanatory comment may eat the gain :) return 1 ; } int list_costs() { int i, s ; mapping skills ; string *names, *s_names ; skills = this_player()->query_skills() ; names = skills ? keys(skills) : ({ }); s_names = sort_array(names,"sort_skills",this_object()) ; write("Skill Cost\n") ; write("------------------------------\n") ; s = sizeof(names) ; for (i=0;i<s;i++) { if (!can_train(s_names[i])) continue ; write(sprintf("%25-s %d gold\n",s_names[i],cost_of_skill(s_names[i]))) ; } return 1 ; } int sort_skills (string s1, string s2) { return strcmp (s1,s2) ; }