/** * This is the training hall inherit. * @author Shaydz * @changed Moved some of the code to the skill handler. * - Sandoz, June 2003. */ #include <skills.h> private string teaching_skill; /** @ignore yes */ void create() { TO->add_help_file("training_hall"); } /* create() */ /** @ignore yes */ int do_advance_internal( string skill, int to, int by ) { string *bits, skill_name, outer_name; int lvl, max_lvl, tmp, total_xp, i; bits = explode( implode( explode( skill, " " ), "."), "."); if( strlen(bits[0]) == 2 ) { if( bits[0][0..1] != teaching_skill[0..1] ) { add_failed_mess("You cannot advance "+skill+" here.\n"); return 0; } } else { if( bits[0] != teaching_skill ) { add_failed_mess("You cannot advance "+skill+" here.\n"); return 0; } } if( !skill_name = SKILL_H->query_skill(bits) ) { add_failed_mess("The skill "+skill+" does not exist.\n"); return 0; } if( !SKILL_H->query_allowed_to_teach(skill_name) ) { add_failed_mess("You cannot learn "+skill_name+" in here.\n"); return 0; } lvl = TP->query_skill( skill_name ); if( !by && to ) by = to - lvl; if( by <= 0 ) { if( !by ) add_failed_mess("You are already at level "+lvl+" in "+ skill_name+".\n"); else add_failed_mess("You cannot regress below your current " "skill level.\n"); return 0; } if( SKILL_H->query_only_leaf(skill_name) ) { if( sizeof( SKILL_H->query_immediate_children(skill_name) ) ) { add_failed_mess("You can only advance the outer skills " "(eg: general.riding.horse), not the internal skills " "(eg: general.riding, or general).\n"); return 0; } } else { bits = explode( skill_name, "."); if( sizeof( bits ) > 1 ) { outer_name = implode( bits[ 0 .. sizeof( bits ) - 2 ], "." ); if( ( sizeof( bits ) - 1 ) * 5 > TP->query_skill( outer_name ) ) { add_failed_mess("You are not at a high enough level in "+ outer_name+" to advance "+skill_name+" yet.\n"); return 0; } } } max_lvl = STD_GUILD_OBJ->query_skill_max_level( skill_name,TP ); if( lvl >= max_lvl ) { add_failed_mess("You cannot advance any further in "+ skill_name+" here.\n"); return 0; } for( i = 0; i < by; i++ ) { tmp = SKILL_H->query_skill_cost( TP, skill_name, i ); if( TP->query_xp() < tmp + total_xp ) { if( !i ) { add_failed_mess("Your lack of experience prevents you from " "improving "+skill_name+".\n"); return 0; } else { tell_object( TP, "Your lack of experience prevents you from " "taking all the advancement you requested in "+ skill_name+". You are only trained up to level "+ ( i + lvl )+".\n"); } break; } if( ( lvl + i ) >= max_lvl ) { tell_object( TP, "This training hall hasn't the resources to " "train you as far as you requested in "+skill_name+". You " "are trained to level "+max_lvl+" instead.\n"); break; } total_xp += tmp; } if( !total_xp ) { add_failed_mess("Oh dear, something has gone wrong.\n"); return 0; } TP->adjust_xp( -total_xp ); TP->add_skill_level( skill_name, i, total_xp ); event( TO, "guild_advance", bits, lvl, lvl+i ); tell_object( TP, "You advance your skill in "+skill_name+" from level "+ lvl+" to "+( lvl + i )+" for "+total_xp+" xp.\n"); tell_room( TO, TP->the_short()+" $V$0=advances,advance$V$ $V$0="+ TP->HIS+",their$V$ skills.\n", TP ); return 1; } /* do_advance_internal() */ /** @ignore yes */ int do_advance( string skill ) { return do_advance_internal( skill, 0, 1 ); } /* do_advance() */ /** @ignore yes */ int do_advance_by( string skill, int num ) { return do_advance_internal( skill, 0, num ); } /* do_advance_by() */ /** @ignore yes */ int do_advance_to( string skill, int num ) { return do_advance_internal( skill, num, 0 ); } /* do_advance_to() */ /** @ignore yes */ private string rec_cost( mixed arr, string path, int depth, int only_leaf, int brief ) { int i, depth_gap, ndots, o_l, tmp, lvl, max_lvl; string str, lpath; depth_gap = ( depth - 1 ) * 2; ndots = 19 - depth_gap; str = ""; for( i = 0; i < sizeof(arr); i += SKILL_ARR_SIZE ) { lpath = path + arr[i]; lvl = TP->query_skill(lpath); max_lvl = STD_GUILD_OBJ->query_skill_max_level( lpath, TP ); o_l = only_leaf; if( depth == 1 ) o_l = SKILL_H->query_only_leaf( lpath ); if( lvl >= max_lvl ) { if( !brief ) { str += sprintf("%*'| 's%-*'.'s%4d/%3d mastered\n", depth_gap, "", ndots, arr[ i ], lvl, max_lvl ); } } else { if( !o_l || !sizeof( arr[ i + SKILL_BIT] ) ) { if( ( o_l && sizeof( arr[ i + SKILL_BIT] ) ) || !SKILL_H->query_allowed_to_teach(lpath) ) { str += sprintf("%*'| 's%-*'.'s\n", depth_gap, "", ndots+18, arr[ i ] ); } else { tmp = SKILL_H->query_skill_cost( TP, lpath, 0 ); str += sprintf("%*'| 's%-*'.'s%4d/%3d %6d xp\n", depth_gap, "", ndots, arr[ i ], lvl, max_lvl, tmp ); } } else if( o_l ) { str += sprintf("%*'| 's%-*'.'s\n", depth_gap, "", ndots+18, arr[ i ] ); } } if( lvl >= depth * 5 || o_l ) { reset_eval_cost(); str += rec_cost( arr[ i + SKILL_BIT ], lpath +".", depth + 1, o_l, brief ); } } return str; } /* rec_cost() */ /** @ignore yes */ int do_cost_internal( string skill, int to, int by ) { string *bits, skill_name, outer_name; int lvl, max_lvl, i, tmp; bits = explode( implode( explode( skill, " "), "."), "."); if( strlen(bits[0]) == 2 ){ if( bits[0][0..1] != teaching_skill[0..1] ) { add_failed_mess("You cannot advance "+skill+" here, so we can't " "tell you how much it would cost.\n"); return 0; } } else { if( bits[0] != teaching_skill ) { add_failed_mess("You cannot advance "+skill+" here.\n"); return 0; } } if( !skill_name = SKILL_H->query_skill( bits ) ) { add_failed_mess("There is no such skill as "+skill+".\n"); return 0; } if( !SKILL_H->query_allowed_to_teach(skill_name) ) { add_failed_mess("You cannot learn "+skill_name+" in here.\n"); return 0; } lvl = TP->query_skill( skill_name ); if( !by && to ) by = to - lvl; if( !by ) { add_failed_mess("It won't cost you anything to stay at the same " "level.\n"); return 0; } if( by < 0 ) { add_failed_mess("We don't give refund xp for regressing skills.\n"); return 0; } bits = explode( skill_name, "."); if( sizeof( bits ) > 1 ) { if( SKILL_H->query_only_leaf(skill_name) ) { if( sizeof( SKILL_H->query_immediate_children(skill_name) ) ) { add_failed_mess("You can only advance the outer skills " "(eg: general.riding.horse), not the internal skills " "(eg: general.riding, or general).\n"); return 0; } } else { outer_name = implode( bits[ 0 .. sizeof( bits ) - 2 ], "."); if( ( sizeof(bits) - 1 ) * 5 > TP->query_skill( outer_name ) ) { add_failed_mess("You are not at a high enough level in "+ outer_name+" to advance "+skill_name+" yet.\n"); return 0; } } } max_lvl = STD_GUILD_OBJ->query_skill_max_level( skill_name, TP ); if( lvl >= max_lvl ) { add_failed_mess("Sorry, our teachers are not capable of instructing " "you above level "+max_lvl+" in "+skill_name+".\n"); return 0; } for( i = 0;i < by; i++ ) { if( ( lvl + i ) >= max_lvl ) { tell_object( TP, "Sorry, our teachers are only able to instruct " "you up to level "+max_lvl+" in "+skill_name+".\n"); break; } tmp += SKILL_H->query_skill_cost( TP, skill_name, i ); } printf("It would cost you %d xp to raise %s from level %d to %d.\n", tmp, skill_name, lvl, ( lvl + i ) ); return 1; } /* do_cost_internal() */ /** @ignore yes */ int do_cost( string skill ) { string *bits, list; mixed arr; int i; bits = explode( implode( explode( skill, " "), "."), "."); if( strlen(bits[0]) == 2 ) { if( bits[0][0..1] != teaching_skill[0..1] ) { add_failed_mess("You cannot advance "+skill+" here.\n"); return 0; } } else { if( bits[0] != teaching_skill ) { add_failed_mess("You cannot advance "+skill+" here.\n"); return 0; } } arr = SKILL_H->query_skills(); if( !arr ) { add_failed_mess("Oops, something seems to have broken.\n"); return 0; } i = member_array( skill, arr ); if( i != -1 ) { list = sprintf( "%-*'='s\n", TP->query_cols() - 1, "======SKILLS=======Cur/Max==For Next"); list += sprintf("%#*-s\n", TP->query_cols(), rec_cost( arr[ i + 3 ], skill+".", 2, 0, 0 ) ); list += sprintf("%*'='|s\n", TP->query_cols() - 1, "> You have "+TP->query_xp()+" points to spend. <"); TP->more_string( list, CAP( skill ), 1 ); return 1; } return do_cost_internal( skill, 0, 1 ); } /* do_cost() */ /** @ignore yes */ int do_cost_to( string skill, int num ) { return do_cost_internal( skill, num, 0 ); } /* do_cost_to() */ /** @ignore yes */ int do_cost_by( string skill, int num ) { return do_cost_internal( skill, 0, num ); } /* do_cost_to() */ /** @ignore yes */ varargs void set_teaching_skill( string skill ) { teaching_skill = skill; } /** @ignore yes */ string query_teaching_skill() { return teaching_skill; } /** @ignore yes */ void init() { add_command("advance", "<string>", (: do_advance($4[0]) :) ); add_command("advance", "<string> to <number>", (: do_advance_to( $4[0], $4[1] ) :) ); add_command("advance", "<string> by <number>", (: do_advance_by( $4[0], $4[1] ) :) ); add_command("cost", "<string>", (: do_cost($4[0]) :) ); add_command("cost", "<string> to <number>", (: do_cost_to($4[0], $4[1]) :) ); add_command("cost", "<string> by <number>", (: do_cost_by($4[0], $4[1]) :) ); } /* init() */