/* -*- LPC -*- */ /* * $Locker: $ * $Id: score.c,v 1.35 2003/06/05 01:22:45 pinkfish Exp $ * * */ inherit "/cmds/base"; #include <config.h> #include <library.h> #include <quest_handler.h> #ifndef __DISTRIBUTION_LIB__ #include <deity.h> #endif #include <top_ten_tables.h> #include <player_handler.h> #include <clubs.h> #include <player.h> #include <nomic_system.h> #include <tune.h> #include <skills.h> #include <combat.h> #define essify(x,y) (x > 1 || x == 0 ? " " y "s" : " " y) #define LIMIT 150 int score_quests(object ob, int sorted) { string *quests; mixed *quest_info; if ( !this_player()->query_creator() && ob->query_property("dead")) { write( "You are just a disembodied spirit. What use does a wispy thing " "like you have for a collection of meaningless numbers?\n" ); return 1; } if(this_player()->query_role_playing()) { write("Sorry, you're roleplaying.\n"); return 1; } quests = LIBRARY->query_quests( ob->query_name() ); if ( !sizeof( quests ) ) { printf( "You have not completed any quests.\n" ); return 1; } quest_info = map(quests, (: ({ QUEST_HANDLER->query_quest_title($1), QUEST_HANDLER->query_quest_story($1) }) :)); if (sorted) { quest_info = sort_array(quest_info, (: strcmp($1[0], $2[0]) :)); } write( "$P$Quests$P$You have completed the following quests:\n"+ implode( map_array( map_array( quest_info, (: " \""+ $1[0] +"\", in which you "+ replace( $1[1], "was", "were" ) :) ), (: sprintf( $1[ 0 .. 24 ] +"%*-=s", $(ob)->query_cols() - 30, $1[ 25 .. ] ) :) ), ",\n" ) +".\n" ); /* Wow. That is impressive. --Presto */ return 1; } /* score_quests() */ int query_verbose(object ob, string verbose) { if (!verbose) { return ob->query_verbose("score"); } if (verbose == "verbose") { return 1; } return 0; } /* query_verbose() */ int score_stats(object ob, string verbose) { string word; int stat; string ret; if ( !this_player()->query_creator() && ob->query_property("dead")) { write( "You are just a disembodied spirit. What use does a wispy thing " "like you have for a collection of meaningless numbers?\n" ); return 1; } if(this_player()->query_role_playing()) { ret = ""; if(stat = (this_player()->query_tmp_str() + this_player()->query_bonus_str())) { if ( stat > 0 ) { ret += "You feel stronger than usual.\n"; } else { ret += "You feel weaker than usual.\n"; } } if ( stat = ( this_player()->query_tmp_int() + this_player()->query_bonus_int() ) ) { if ( stat > 0 ) { ret += "You feel smarter than normal.\n"; } else { ret += "You feel less smart than normal.\n"; } } if ( stat = ( this_player()->query_tmp_con() + this_player()->query_bonus_con() ) ) { if ( stat > 0 ) { ret += "You feel more healthy than usual.\n"; } else { ret += "You feel a bit sickly.\n"; } } if ( stat = ( this_player()->query_tmp_dex() + this_player()->query_bonus_dex() ) ) { if ( stat > 0 ) { ret += "You feel more nimble than usual.\n"; } else { ret += "You feel more clumsy than you normally do.\n"; } } if ( stat = ( this_player()->query_tmp_wis() + this_player()->query_bonus_wis() ) ) { if ( stat > 0 ) { ret += "You feel mentally attuned.\n"; } else { ret += "You feel a bit vague.\n"; } } if ( !strlen( ret ) ) { ret += "You feel fine.\n"; } printf( "%s", ret ); } else { word = ( ob->query_weight() / 20 ) +"."+ ( ob->query_weight() % 10 ); if (query_verbose(ob, verbose)) { printf( "%-#*s\n", ob->query_cols(), "Constitution ... "+ ob->query_con() +"\n"+ "Dexterity ...... "+ ob->query_dex() +"\n"+ "Intelligence ... "+ ob->query_int() +"\n"+ "Strength ....... "+ ob->query_str() +"\n"+ "Wisdom ......... "+ ob->query_wis() +"\n"+ "Height ......... "+ ob->query_height() +" cm\n"+ "Weight ......... "+ word +"kg\n" ); } else { printf( "%-#*s\n", ob->query_cols(), "Con: "+ ob->query_con() +"\nDex: "+ ob->query_dex() +"\n"+ "Int: "+ ob->query_int() +"\nStr: "+ ob->query_str() +"\n"+ "Wis: "+ ob->query_wis() +"\nHgt: "+ ob->query_height() +" cm\n"+ "Wgt: "+ word +"kg\n" ); } } return 1; } /* score_stats() */ int calc_percent( float x, float y ) { return to_int( ( to_float( x ) / to_float( y ) ) * 100 ); } /* calc_percent() */ string find_hp_string( int current, int max ) { if ( this_player()->query_property( "dead" ) ) { return "you are dead\n"; } switch( calc_percent( current, max ) ) { case 90..100: return "you are in perfect health"; case 70..89: return "you are slightly wounded"; case 50..69: return "you are moderately wounded"; case 30..49: return "you are seriously wounded"; case 15..29: return "you are critically wounded"; case 6..14: return "you are fatally wounded"; case 0..5: return "you are near death"; default: return "you are broken"; } } /* find_hp_string() */ string find_gp_string( int current, int max ) { if ( this_player()->query_property( "dead" ) ) { return "you are dead\n"; } switch( calc_percent( current, max ) ) { case 90..100: return "you are full of energy"; case 70..89: return "you are enthusiastic"; case 50..69: return "you are not quite so full of beans"; case 30..49: return "you are weary"; case 15..29: return "you are tired"; case 6..14: return "you are exhausted"; case 0..5: return "you are nearly unconscious"; default: return "you are broken"; } } /* find_gp_string() */ int calc_xp_cost( string skill ) { int lvl; int my_lvl; int cost; int j; int total; int total2; int num = 1; my_lvl = this_player()->query_skill_bonus( skill, 1 ); lvl = this_player()->query_skill(skill); cost = DEFAULT_COST; if( SKILL_OB->query_skill_cost(skill) > 0 ) { cost *= SKILL_OB->query_skill_cost(skill); } cost *= STD_COST/5; total2 = 0; total = 0; if ( !my_lvl ) { my_lvl = 1; } for ( j = 0; j < num; j++) { int k; k = 2 * this_player()->calc_bonus( lvl + j, skill, 1 ) / my_lvl + 1; total2 += cost * ( ( lvl + j ) / LEVEL_DIV + 1 ) * k * k / 2; /* This stops people taking advantage of two's complement. */ if ( total > total2 ) { num = j; break; } else { total = total2; } } if (!total) { total = cost; } return total; } /* calc_xp_cost() */ string find_xp_string( int current ) { string *skills = ({ "magic", "faith", "fighting", "covert", "crafts" }); int xptotal; foreach( string skill in skills ) { xptotal += calc_xp_cost( skill ); } xptotal /= sizeof( skills ); //tell_creator( find_player( "terano" ), "%s: Current XP is: %d, Avg XP is %d, Ratio is: %d.\n", // this_player()->query_name(), current, xptotal, calc_percent( current, xptotal ) ); switch( calc_percent( current, xptotal ) ) { //Less than average case 0..20: return "you don't think you can learn much at the moment"; case 21..59: return "by the luck of a coin, you might be able to learn something new"; case 60..100: return "if you squeezed it, you could gain some insight"; //1 level case 101..300: return "you might be able to learn something new, if you found the right teacher"; //3 levels of average case 301..400: return "a small amount could be learned with training"; case 401..800: return "a bit of training might be in order"; case 801..1200: return "you could very well learn something new from training"; case 1201..1500: return "you could benefit from training"; case 1501..2000: return "you feel like training might help"; case 2001..2500: return "you should consider training your skills"; //25 levels of average case 2501..4000: return "your skills could be greatly improved with training"; default: return "certainly a hearty training session is in order"; } } string find_wimpy_string( int wimpy ) { if ( wimpy ) { return "you will flee when "+ find_hp_string( wimpy, 100 ); } return "you will not flee"; } /* find_wimpy_string() */ string find_surrender_string( int surr ) { if ( surr ) { return "you will surrender when "+ find_hp_string( surr, 100 ); } return "you will not surrender"; } /* find_surrender_string() */ string find_align_string( object tp ) { string ret = ""; string word = tp->query_deity(); ret = ""; word = tp->query_deity(); if ( !tp ) { return ""; } ret += "you are "; ret += tp->align_string(); if ( stringp( word ) ) { ret += " and in the service of "; ret += capitalize( word ); ret += ", "; #ifndef __DISTRIBUTION_LIB__ ret += DEITY->query_title( word ); #endif } return ret; } /* find_align_string() */ string find_death_string( int remaining ) { if ( !this_player()->query_deaths() ) { return "Death has never visited you in a professional capacity"; } switch ( remaining ) { case 0..0: return "Death has a special interest in your next appointment"; case 1..3: return "Death is starting to lose patience with you"; case 4..7: return "You and Death are on good terms"; default: return "You have an \"arrangement\" with Death"; } } /* find_death_string() */ int score_rp(object me, string verbose) { if(query_verbose(me, verbose)) { printf( "%s.\n%s and %s.\n%s.\n%s.\n%s.\n%s.\n%s.\n", "You are "+ me->query_cap_name() +" "+me->query_gtitle(), capitalize( find_hp_string( me->query_hp(), me->query_max_hp() ) ), find_gp_string( me->query_gp(), me->query_max_gp() ), capitalize( find_xp_string( me->query_xp() ) ), capitalize( find_align_string( me ) ), capitalize( find_wimpy_string( me->query_wimpy() ) ), //find_surrender_string( me->query_surrender() ), "You are "+ me->burden_string() + " and " + this_player()->query_temp_str(), find_death_string( me->query_max_deaths() - me->query_deaths() ) ); } else { printf( "%s and %s.\n%s.\n", capitalize( find_hp_string( me->query_hp(), me->query_max_hp() ) ), find_gp_string( me->query_gp(), me->query_max_gp() ), capitalize( find_xp_string( me->query_xp() ) ) ); } return 1; } int score_burden(object me, string verbose) { write( sprintf("You are %s (%d%%).\n", me->burden_string(), me->query_burden())); return 1; } int score_normal(object ob, string verbose) { string word; string guild_ob; string area; string* magistrates; string* citizens; int age, temp1, temp2, temp3, temp4; int no_title; if ( !this_player()->query_creator() && ob->query_property("dead")) { write( "You are just a disembodied spirit. What use does a wispy thing " "like you have for a collection of meaningless numbers?\n" ); return 1; } if(ob->query_role_playing()) return score_rp(ob, verbose); if (query_verbose(ob, verbose)) { guild_ob = ob->query_guild_ob(); if (!guild_ob) { guild_ob = "/std/guilds/warrior"; no_title = 1; } temp1 = ob->query_hp(); temp2 = ob->query_gp(); temp3 = (int)LIBRARY->query_quest_points( ob->query_name() ); temp4 = ob->query_sp(); printf( "%-=*s", ob->query_cols(), "You have " + temp1 + " (" + ob->query_max_hp() + ") hit" + essify(temp1, "point") + ", " + temp2 + " (" + ob->query_max_gp() + ") guild" + essify(temp2, "point") + ", " + temp3 + " (" + (int)QUEST_HANDLER->query_total_qp() + ") quest" + essify(temp3, "point") + " and " + temp4 + " (" + ob->query_max_sp() + ") social" + essify( temp4, "point") + ".\n" ); if ( guild_ob && find_object( guild_ob ) ) { printf( "%-=*s", ob->query_cols(), "Your current experience is " + ob->query_xp() + " and you are level " + (int)ob->query_level() + " in the " + (no_title?"Adventurers' Guild":guild_ob->query_short()) + ((ob->query_guild_ob() == "/std/guilds/thief" && !(ob->query_guild_data() == 0)) ? ", specialised as a " + ob->query_guild_data() : "") + "; your overall rating is " + (int)TOP_TEN_HANDLER-> calculate_rating( ob ) + ".\n" ); } else { printf( "%-=*s", ob->query_cols(), "Your current experience is " + ob->query_xp() +".\n" ); } temp1 = ob->query_deaths(); temp2 = ob->query_max_deaths() - temp1; printf( "%-=*s", ob->query_cols(), "You have died " + temp1 + essify(temp1, "time") + " and can die " + temp2 + essify(temp2, "time") + " before you are completely " "dead.\n" ); if ( ob->query_wimpy() ) { printf( "Your wimpy is set to %d%%.\n", ob->query_wimpy() ); } else { printf( "You are in brave mode.\n" ); } #ifdef USE_SURRENDER if (ob->query_surrender()) { printf("You will surrender at %d%% of your maximum hit points.\n", ob->query_surrender()); } else { printf("You won't surrender.\n"); } #endif printf( "You are %s (%d%%) and %s.\n", ob->burden_string(), ob->query_burden(), this_player()->query_temp_str()); word = ob->query_deity(); #ifndef __DISTRIBUTION_LIB__ if ( stringp( word ) ) { printf( "You are %s, worshipping %s.\n", ob->align_string(), capitalize( word ) +", "+ (string)DEITY->query_title( word ) ); } else { printf( "You are %s, worshipping no god.\n", ob->align_string() ); } #endif // // Put any citizenship memberships in here. // citizens = ({ }); magistrates = ({ }); word = ob->query_name(); foreach (area in NOMIC_HANDLER->query_citizenship_areas()) { if (NOMIC_HANDLER->is_magistrate_of(area, word)) { magistrates += ({ area }); } else if (NOMIC_HANDLER->is_citizen_of(area, word)) { citizens += ({ area }); } } if (sizeof(magistrates)) { printf("You are a magistrate of: " + query_multiple_short(magistrates) + ".\n"); } if (sizeof(citizens)) { printf("You are a citizen of: " + query_multiple_short(citizens) + ".\n"); } // // Player killer check. // if ( ob->query_property( PKER ) ) { printf( "You are registered as a player killer.\n" ); } if ( m_sizeof( ob->query_hide_invis() ) ) { printf( "%-=*s\n", ob->query_cols(), "You are " + query_multiple_short( m_indices( ob->query_hide_invis() ) + ({ }) ) + "." ); } printf( "%-=*s", ob->query_cols(), (string)ob->extra_score() ); age = -ob->query_time_on(); temp3 = ob->query_no_logins(); word = sprintf("You are %s old and have logged in %d %s.\n", query_time_string(age, -1), temp3, (temp3 == 1 ? "time" : "times")); printf("%-=*s", ob->query_cols(), word); } else { printf( "%-=*s", ob->query_cols(), "Hp: " + ob->query_hp() + "(" + ob->query_max_hp() + ") Gp: " + ob->query_gp() + "(" + ob->query_max_gp() + ") Xp: "+ ob->query_xp() + "\n" ); } return 1; } /* score_normal() */ string create_relationship_text( string relationship, mapping data ) { string *relatives; int size; if ( !( relatives = data[ relationship ] ) ) return ""; if ( !size = sizeof( relatives ) ) return ""; if ( size == 1 ) { return capitalize( relatives[0] ) + " is your " + relationship; } return query_multiple_short( map( sort_array( relatives, 1 ), (: capitalize( $1 ) :) ) ) + " are your " + pluralize( relationship ); } /* create_relationship_text() */ int get_gender( string name ) { int gender; gender = PLAYER_HANDLER->test_gender( name ); if ( gender ) gender -= 1; return gender; } /* get_gender() */ int score_relationships( object ob, int verbose ) { string txt, family; string *sorted; class relationship_data *bing; mapping grouped; family = ob->query_family_name(); if ( !family || !CLUB_HANDLER->is_family( family ) ) { add_failed_mess( "You're not in a family!\n" ); return 0; } bing = CLUB_HANDLER->query_relationships( family, ob->query_name() ); if ( !sizeof( bing ) ) { add_failed_mess( "You have no relatives.\n" ); return 0; } grouped = unique_mapping( bing, (: CLUB_HANDLER->query_relationship_gender( CLUB_HANDLER->query_opposite_relationship( $1->relationship ), get_gender( $1->related_to ) ) :) ); grouped = map( grouped, (: map( $2, (: $1->related_to :) ) :) ); sorted = sort_array( keys( grouped ), 1 ); txt = implode( map( sorted, (: create_relationship_text( $1, $(grouped) ) :) ), ".\n" ); tell_object( ob, "$P$Relationships$P$" + txt + ".\n" ); return 1; } /* score_relationships() */ int score_align( object ob, int verbose ) { int upper, lower, middle, align; string god, opinion; if (ob->query_property( "dead" )) { write( "You're dead. Things such as 'good' and 'evil' are no longer of your concern.\n" ); return 1; } if( !ob->query_deity() ) { write( "You are " + ob->align_string() + ", and not worried about " "the approval of any deity at all.\n" ); } else { god = ob->query_deity(); align = ob->query_al(); #ifndef __DISTRIBUTION_LIB__ lower = DEITY->query_al_lower( god ); upper = DEITY->query_al_upper( god ); middle = DEITY->query_al_middle( god ); opinion = "pleased with"; if( align <= lower - LIMIT || align >= upper + LIMIT ) opinion = "very angry with"; if( ( align < lower && align > lower - LIMIT ) || ( align > upper && align < upper + LIMIT ) ) opinion = "quite annoyed with"; if( ( align >= lower && align <= lower + LIMIT ) || ( align <= upper && align >= upper - LIMIT ) ) opinion = "a little concerned about"; if( align > middle - ( LIMIT / 2 ) && align < middle + ( LIMIT / 2 ) ) opinion = "very happy with"; write( "You are " + ob->align_string() + ". " + capitalize( god ) + " is " + opinion + " you.\n" ); #else write( "You are " + ob->align_string() + ", and not worried about " "the approval of any deity at all.\n" ); #endif } return 1; } /* score_align */ int score_fighting( object player, int verbose ) { object *attacker_list; object *attacker_list_here; string ret; class tactics tactics; attacker_list = player->query_attacker_list() - ({ 0 }); ret = ""; if ( attacker_list ) { attacker_list_here = filter( attacker_list, (: $1 && living( $1 ) && environment( $1 ) == environment( $(player) ) :) ); if ( !sizeof( attacker_list ) ) { ret += "You are not fighting anything!\n"; } else { attacker_list -= attacker_list_here; if (sizeof(attacker_list_here)) { ret += "$I$5=You are currently fighting " + query_multiple_short( attacker_list_here ) + " here.\n"; } if (sizeof(attacker_list)) { ret += "$I$5=You are currently fighting " + query_multiple_short( attacker_list ) + " (these are " "people you will auto attack on sight).\n" ; } } } tactics = (class tactics) this_player()->query_tactics(); ret += "$I$0=Your current tactics are:\n" " Attitude : "+ tactics->attitude +"\n" " Response : "+ tactics->response +"\n" #ifdef USE_SURRENDER " Mercy : "+ (tactics->mercy?tactics->mercy:"none") + "\n" #endif " Focus : "+ (tactics->focus_zone?tactics->focus_zone:"none") + "\n" #ifdef USE_DISTANCE " Target distance: "+ (tactics->ideal_distance?tactics->ideal_distance:"none") + "\n" #endif " Attack : "+ (tactics->attack == "both" ? "both" : (tactics->attack?tactics->attack:"both")) + "\n" " Parry : " + (tactics->parry == "both" ? "both" : (tactics->parry?tactics->parry:"both")) + "\n" " Unarmed Parry : " + (tactics->parry_unarmed ? "yes" : "no") + "\n"; write(ret); return 1; } /* score_fighting() */ int score_temperature( object player, int verbose ) { return "/cmds/player/temp_erature"->cmd(); } /* score_fighting() */ mixed *query_patterns() { return ({ "quests", (: score_quests(this_player(), 0) :), "quests sorted", (: score_quests(this_player(), 1) :), "{brief|verbose} stats", (: score_stats(this_player(), $4[0]) :), "stats", (: score_stats(this_player(), 0) :), "{brief|verbose}", (: score_normal(this_player(), $4[0]) :), "relationships", (: score_relationships( this_player(), 0 ) :), "temperature", (: score_temperature( this_player(), 0 ) :), "burden", (: score_burden( this_player(), 0 ) :), "", (: score_normal(this_player(), 0) :), "{align|alignment}", (: score_align(this_player(), 0) :), "fighting", (: score_fighting( this_player(), 0 ) :) }); } /* query_patterns() */