/**************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * *r ***************************************************************************/ /**************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <ctype.h> #include "merc.h" #include "db.h" #include "arena.h" #include "interp.h" #include "tables.h" #include "olc.h" #include "recycle.h" #include "lookup.h" #include "skill_tree.h" #include "math.h" struct node* talloc() { return (struct node *) malloc(sizeof(struct node)); } struct node* empty() { struct node* temp; temp = talloc(); temp->x1 = NULL; temp->x2 = NULL; temp->x3 = NULL; temp->x4 = NULL; temp->x5 = NULL; temp->prefix = "+"; temp->tn = "combat"; temp->level = 1; return temp; } void set_prefix(struct node* skill) { switch (skill->level) { case 1: skill->prefix = str_dup(""); break; case 2: skill->prefix = str_dup(" |->"); break; case 3: skill->prefix = str_dup(" | |---->"); break; case 4: skill->prefix = str_dup(" | | |--->"); break; default: skill->prefix = str_dup(" | | |--->"); break; break; } return; } void do_talents( CHAR_DATA *ch, char *argument ) { char arg[MSL]; char first[MIL]; /*int i = 0;*/ struct node* check; if (IS_NPC(ch)) return; one_argument(argument,arg); pull_skill(arg,first); check = check_skill_tree(first,arg,ch,uber()); if (arg[0] == '\0') { stc("Viable arguments are combat covert sorcery arcane worship or all.\n\r",ch); return; } // sn = match_skill("combat.offense.piercing","newskills"); // sprintf(buf,"{Bmatch_skill returned:{W%s{x, and it was supposed to return com.off.pie\n\r",tree_skill_table[sn].name); // stc(buf,ch); /* if (!str_prefix(arg,"all")) { display_node(combat(),ch,ch); stc("\n\r",ch); display_node(covert(),ch,ch); stc("\n\r",ch); display_node(sorcery(),ch,ch); stc("\n\r",ch); display_node(arcane(),ch,ch); stc("\n\r",ch);stc("Update Bonus done.(uber)\n\r",ch); display_node(worship(),ch,ch); return; }*/ if (check != NULL) { update_bonus(ch,combat()); update_bonus(ch,covert()); update_bonus(ch,sorcery()); update_bonus(ch,arcane()); update_bonus(ch,worship()); stc("{WSkill {RLevel {GBonus {YCost{x\n\r",ch); display_node(check,ch,ch); return; } else return; } void display_node (struct node* skill, CHAR_DATA *ch,CHAR_DATA *victim) { char buf[MSL],lvl[MSL],bonus[MSL],cost[MSL]; sprintf(lvl,"{W[{R%5d{W|{x",return_skill_str(victim,skill->tn)); sprintf(bonus,"{G%5d{W|{x",return_bonus_str(victim,skill->tn)); sprintf(cost,"{Y%6d{W]{x",calc_skill_cost(ch,skill->tn,1)); sprintf(buf,"{D%s{W%s%*s {x%s%s%s\n\r",skill->prefix,skill->name,(30 - (strlen(skill->name) + strlen(skill->prefix))),"",lvl,bonus,cost); stc(buf,ch); if (skill->x1 != NULL) display_node(skill->x1,ch,victim); if (skill->x2 != NULL) display_node(skill->x2,ch,victim); if (skill->x3 != NULL) display_node(skill->x3,ch,victim); if (skill->x4 != NULL) display_node(skill->x4,ch,victim); if (skill->x5 != NULL) display_node(skill->x5,ch,victim); return; } struct node* check_skill_tree(char *first,char *arg,CHAR_DATA *ch,struct node *node) { /*force function to jump from uber() to first()*/ if (!strcmp(node->name,"uber")) { if(node->x1 != NULL && !strcmp(first,node->x1->tn)) return check_skill_tree(first,arg,ch,node->x1); if(node->x2 != NULL && !strcmp(first,node->x2->tn)) return check_skill_tree(first,arg,ch,node->x2); if(node->x3 != NULL && !strcmp(first,node->x3->tn)) return check_skill_tree(first,arg,ch,node->x3); if(node->x4 != NULL && !strcmp(first,node->x4->tn)) return check_skill_tree(first,arg,ch,node->x4); if(node->x5 != NULL && !strcmp(first,node->x5->tn)) return check_skill_tree(first,arg,ch,node->x5); else return NULL; } if(!str_cmp(node->tn,arg)) return node; if(node->x1 != NULL && !str_prefix(node->x1->tn,arg)) return check_skill_tree(first,arg,ch,node->x1); if(node->x2 != NULL && !str_prefix(node->x2->tn,arg)) return check_skill_tree(first,arg,ch,node->x2); if(node->x3 != NULL && !str_prefix(node->x3->tn,arg)) return check_skill_tree(first,arg,ch,node->x3); if(node->x4 != NULL && !str_prefix(node->x4->tn,arg)) return check_skill_tree(first,arg,ch,node->x4); if(node->x5 != NULL && !str_prefix(node->x5->tn,arg)) return check_skill_tree(first,arg,ch,node->x5); else return NULL; } struct node* uber() { struct node* temp; temp = empty(); temp->name = "uber"; temp->tn = "uber"; temp->x1 = combat(); temp->x2 = covert(); temp->x3 = sorcery(); temp->x4 = arcane(); temp->x5 = worship(); temp->level = 1; return temp; } char *pull_skill( char *argument, char *arg_first ) { char cEnd; while ( isspace(*argument) ) argument++; cEnd = '.'; if ( *argument == '\'' || *argument == '"' ) cEnd = *argument++; while ( *argument != '\0' ) { if ( *argument == cEnd ) { argument++; break; } *arg_first = LOWER(*argument); arg_first++; argument++; } *arg_first = '\0'; while ( isspace(*argument) ) argument++; return argument; } void set_skill_levels( CHAR_DATA *ch,int level) { int i; if(IS_NPC(ch)) return; else { for(i = 0; i < MAX_TREE_SKILLS; i++) { ch->pcdata->skills_array[i] = level; } } return; } int return_skill_sn( CHAR_DATA *ch, int sn) { if (IS_NPC(ch)) return 0; return ch->pcdata->skills_array[sn_talent(sn)]; } int return_skill_str( CHAR_DATA *ch, char *skill_name) { int sn; if (IS_NPC(ch)) return 0; sn = match_skill(skill_name,"return_skill_str"); if (sn< 0) { debug(ch,"return_skill_str: match_skill() failed\n\r"); return 0; } if (sn == 5000) { debug(ch,"return_skill_str: match_skill() matched 'uber'(5000)\n\r",ch); return 0; } return ch->pcdata->skills_array[sn]; } int return_bonus_sn( CHAR_DATA *ch, int sn) { if (IS_NPC(ch)) return 0; return ch->pcdata->bonus_array[sn_talent(sn)]; } int return_bonus_str( CHAR_DATA *ch, char *skill_name) { int sn; sn = match_skill(skill_name,"return_bonus_str"); if (IS_NPC(ch)) return 0; if (sn < 0) { debug(ch,"return_bonus: match_skill() failed\n\r",ch); debug(ch,"skill_name %s, sn %d\n\r",skill_name,sn); return 0; } if (sn == 5000) { debug(ch,"return_bonus: match_skill() found UBER(5000)\n\r",ch); return 0; } return ch->pcdata->bonus_array[sn]; } void do_upgrade( CHAR_DATA *ch, char *argument ) { char arg1[MSL],arg2[MSL],buf[MSL],first[MSL]; /*char *token_str,*copy; char **tokens;*/ CHAR_DATA *mob; int level,i=0; struct node* to_raise; /*copy = strdup(argument);*/ argument = one_argument( argument, arg1 ); strcpy(arg2,argument); level = atoi(arg2); if ( IS_NPC(ch) ) return; if ( !IS_AWAKE(ch) ) { send_to_char( "In your dreams, or what?\n\r", ch ); return; } for ( mob = ch->in_room->people; mob != NULL; mob = mob->next_in_room ) { if ( IS_NPC(mob) && IS_SET(mob->act, ACT_PRACTICE) ) break; } if ( mob == NULL ) { send_to_char( "You can't do that here.\n\r", ch ); return; } if ( ch->pcdata->sp <= 0 ) { send_to_char( "You have no skill points left.\n\r", ch ); return; } if (!is_number(arg2)) { stc("Please specify a numeric number of levels to raise\n\r",ch); return; } pull_skill(arg1,first); to_raise = check_skill_tree(first,arg1,ch,uber()); if ( to_raise == NULL) { stc("No such skill found, please check your spelling and try again.\n\r",ch); return; } if ( ch->pcdata->sp < calc_skill_cost(ch,arg1,level) || ch->pcdata->sp <= 0) { sprintf(buf,"You would need %d Skill Points to raise %s by that many levels\n\r",calc_skill_cost(ch,arg1,level),arg1); stc(buf,ch); return; } ch->pcdata->sp -= calc_skill_cost(ch,arg1,level); boost_skill(ch,arg1,level); update_bonus(ch,combat()); update_bonus(ch,covert()); update_bonus(ch,sorcery()); update_bonus(ch,arcane()); update_bonus(ch,worship()); sprintf(buf,"You raise {W%s{x to {R%d{x\n\r",to_raise->tn,return_skill_str(ch,to_raise->tn)); stc(buf,ch); /* * The following is some code for tokenizing * the argument string into tokens, and then * putting them in an array of strings. Idea * turned out to be useless, cause of the way * check_skill_tree works (recursively),but * I'm leaving the code anyways. * -Enzo */ /* if((tokens = malloc(4 * sizeof(char*) * 24)) == NULL) { stc("do_upgrade: tokens malloc failed.\n\r",ch); return; } for(i=0;i<=3;i++) { if((tokens[i] = malloc(24 * sizeof(char))) == NULL) { stc("do_upgrade: tokens[i] malloc failed.\n\r",ch); return; } tokens[i] = strdup(""); } for(i=0;i<=3;i++) { if(i==0) { token_str = strtok(copy,"."); if(token_str == NULL || STRLEN(token_str) < 1) { stc("Your argument was invalid.\n\r",ch); return; } } if(token_str != NULL && STRLEN(token_str) >= 1 ) { tokens[i] = str_dup(token_str); token_str = strtok(NULL," ."); } if(isdigit(tokens[i][0])) { tokens[i] = str_dup(""); } } ptc(ch,"%s[.]%s[.]%s[.]%s",tokens[0],tokens[1],tokens[2],tokens[3]); free(tokens); free(copy); */ return; } void boost_skill( CHAR_DATA *ch, char *skill_name,int ammount) { struct node* to_raise; char first[MSL]; int sn; sn = match_skill(skill_name,"boost_skill"); if (IS_NPC(ch)) return; else { if (sn < 0) { stc("match_skill failed in boost_skill\n\r",ch); return; } if (sn == 5000) { stc("match_skill found UBER in boost_skill\n\r",ch); return; } else { ch->pcdata->skills_array[sn] += ammount; } pull_skill(skill_name,first); to_raise = check_skill_tree(first,skill_name,ch,uber()); if (to_raise != NULL) { if (to_raise->x1 != NULL) boost_skill(ch,to_raise->x1->tn,ammount); if (to_raise->x2 != NULL) boost_skill(ch,to_raise->x2->tn,ammount); if (to_raise->x3 != NULL) boost_skill(ch,to_raise->x3->tn,ammount); if (to_raise->x4 != NULL) boost_skill(ch,to_raise->x4->tn,ammount); if (to_raise->x5 != NULL) boost_skill(ch,to_raise->x5->tn,ammount); return; } else return; } } //(base_cost)^2/10 - (((class_bonus * 2) + (race_bonus)) * (skill_level)/ 2.5 int calc_one_skill_cost(CHAR_DATA *ch,char *skill_name,int level) { int current = return_skill_str(ch,skill_name); int raise = current + level; int total = 0; int skill,stat; int a,b,c,d,i; char first[MSL]; pull_skill(skill_name,first); for (i = 0; i < SKILL_GROUPS;i++) { if (!strcmp(first,check_skill_group[i].name)) { skill = check_skill_group[i].skill; stat = check_skill_group[i].stat; break; } } while (current <= raise) { a = pow(20 + current,2)/10; b = class_table[ch->class].skill_bonus[stat] * 2; c = pc_race_table[ch->race].skill_bonus[skill]; d = current; total += a + ((b + c) * d/2.5); current ++; } return total; } int calc_skill_cost(CHAR_DATA *ch,char *skill_name,int level) { struct node* to_raise; long total = 0; char first[MSL]; pull_skill(skill_name,first); to_raise = check_skill_tree(first,skill_name,ch,uber()); if (to_raise != NULL) { if (to_raise->x1 == NULL && to_raise->x2 == NULL && to_raise->x3 == NULL && to_raise->x4 == NULL && to_raise->x5 == NULL) { total = calc_one_skill_cost(ch,skill_name,level); return total; } else { if (to_raise->x1 != NULL) total += calc_skill_cost(ch,to_raise->x1->tn,level); if (to_raise->x2 != NULL) total += calc_skill_cost(ch,to_raise->x2->tn,level); if (to_raise->x3 != NULL) total += calc_skill_cost(ch,to_raise->x3->tn,level); if (to_raise->x4 != NULL) total += calc_skill_cost(ch,to_raise->x4->tn,level); if (to_raise->x5 != NULL) total += calc_skill_cost(ch,to_raise->x5->tn,level); return total; } } return total; } void do_remote_talents( CHAR_DATA *ch, char *argument ) { char arg1[MSL]; char arg2[MSL]; char first[MIL]; int i = 0; struct node* check; CHAR_DATA *victim; if (IS_NPC(ch)) return; argument = one_argument(argument,arg1); one_argument(argument,arg2); if ( arg1[0] == '\0' ) { send_to_char( "Remote View whose score?\n\r", ch ); return; } if ( ( victim = get_char_world( ch, arg1 ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char( "Just use score you mook\n\r", ch ); return; } if (arg2[0] == '\0') { stc("Viable arguments are combat covert sorcery arcane worship or all.\n\r",ch); return; } pull_skill(arg2,first); check = check_skill_tree(first,arg2,victim,uber()); if (!str_prefix(arg2,"all")) { display_node(combat(),ch,victim); stc("\n\r",ch); display_node(covert(),ch,victim); stc("\n\r",ch); display_node(sorcery(),ch,victim); stc("\n\r",ch); display_node(arcane(),ch,victim); stc("\n\r",ch); display_node(worship(),ch,victim); return; } else if (check != NULL) { display_node(check,ch,victim); return; } else return; } int calc_bonus(CHAR_DATA *ch,struct node* node) { int skill = 0; int stat = 0; double current = 0; int i; int bonus = 10; char first[MSL]; if (IS_NPC(ch)) return 42; else { pull_skill(node->tn,first); for (i = 0; i < SKILL_GROUPS;i++) { if (!strcmp(first,check_skill_group[i].name)) { skill = check_skill_group[i].skill; stat = check_skill_group[i].stat; break; } } current = sqrt(return_skill_str(ch,node->tn)); bonus = (((get_curr_stat(ch,stat)/10) * pc_race_table[ch->race].skill_bonus[skill] * class_table[ch->class].skill_bonus[stat]) / 4) + (current * 8); return bonus; } } void set_bonus(CHAR_DATA *ch,char *skill_name) { struct node* node; char first[MSL]; int sn; char buf[MSL]; long bonus = 0; pull_skill(skill_name,first); node = check_skill_tree(first,skill_name,ch,uber()); sn = match_skill(skill_name,"set_bonus"); if (IS_NPC(ch)) return; else if (node != NULL) { if (sn < 0) { stc("match_skill failed in set_bonus\n\r",ch); sprintf(buf,"skill_name %s, sn %d\n\r",skill_name,sn); stc(buf,ch); return; } if (sn == 5000) { stc("match_skill found UBER in set_bonus\n\r",ch); return; } bonus = calc_bonus(ch,node); ch->pcdata->bonus_array[sn] = bonus; // sprintf(buf,"%s bonus[%d] = %d\n\r",node->tn,sn,bonus); // stc(buf,ch); return; } return; } void update_bonus(CHAR_DATA *ch,struct node *node) { /*Check to see if its the uber node*/ if (!strcmp(node->name,"uber")) { if(node->x1 != NULL) update_bonus(ch,node->x1); if(node->x2 != NULL) update_bonus(ch,node->x2); if(node->x3 != NULL) update_bonus(ch,node->x3); if(node->x4 != NULL) update_bonus(ch,node->x4); if(node->x5 != NULL) update_bonus(ch,node->x5); return; } /* Here we set the skills bonus*/ set_bonus(ch,node->tn); /* And here we set the skill's level to the average levels of its children skills*/ set_parent_avg(ch,node); /*Recursion!!*/ if(node->x1 != NULL) update_bonus(ch,node->x1); if(node->x2 != NULL) update_bonus(ch,node->x2); if(node->x3 != NULL) update_bonus(ch,node->x3); if(node->x4 != NULL) update_bonus(ch,node->x4); if(node->x5 != NULL) update_bonus(ch,node->x5); return; } void set_parent_avg(CHAR_DATA *ch,struct node *node) { int counter = 0; int sum = 0; int sn = 0; if (node->x1 == NULL && node->x2 == NULL && node->x3 == NULL && node->x4 == NULL && node->x5 == NULL) { return; } if(node->x1 != NULL) { counter++; sum += return_skill_str(ch,node->x1->tn); } if(node->x2 != NULL) { counter++; sum += return_skill_str(ch,node->x2->tn); } if(node->x3 != NULL) { counter++; sum += return_skill_str(ch,node->x3->tn); } if(node->x4 != NULL) { counter++; sum += return_skill_str(ch,node->x4->tn); } if(node->x5 != NULL) { counter++; sum += return_skill_str(ch,node->x5->tn); } sn = match_skill(node->tn,"set_parent_avg"); ch->pcdata->skills_array[sn] = sum/counter; return; } /* * Lookup a skill by name. */ int match_skill( const char *name,char * called_by ) { int sn; char buf[MSL]; if(!strcmp(name,"uber")) { return 5000; } for ( sn = 0; sn < MAX_TREE_SKILLS; sn++ ) { if ( tree_skill_table[sn].name == NULL ) continue; if (!str_prefix( name, tree_skill_table[sn].name)) { if(name != NULL && !str_prefix(called_by,"return_skill_str")) sprintf(buf,"{W%s:{xparameter name = %s\ttree_skill_table[%d].name = %s", called_by,name,sn, tree_skill_table[sn].name); return sn; } } return -1; } void convert_char(CHAR_DATA *ch) { int sn; long total = 0; char buf[MSL]; if(IS_NPC(ch)) { stc("Talent function on a mob, incorrect usage.\n\r",ch); return; } for ( sn = 0; sn < MAX_SKILL; sn++ ) { if ( skill_table[sn].name == NULL ) break; total += ch->pcdata->learned[sn]; } ch->pcdata->sp = total; ch->version = 6; sprintf(buf,"{WDue to character conversion, you have been given %d SP's{x\n\r",total); stc(buf,ch); return; } int weapon_talent(int v0) { switch (v0) { case WEAPON_SWORD : return com_o_s_s; case WEAPON_DAGGER : return com_o_p_d; case WEAPON_SPEAR : return com_o_p_s; case WEAPON_MACE : return com_o_b_m; case WEAPON_AXE : return com_o_s_a; case WEAPON_FLAIL : return com_o_b_f; case WEAPON_WHIP : return com_o; case WEAPON_POLEARM : return com_o_s_p; case WEAPON_BOW : return com_o_p_m; default : return -1; } } int sn_talent(int sn) { if(sn == gsn_backstab) return cov_s_st; if(sn == gsn_circle) return cov_s_a; if(sn == gsn_dodge) return com_d_d; if(sn == gsn_envenom) return cov_m_p; if(sn == gsn_hide) return cov_s_h; if(sn == gsn_peek) return cov_s_sn; if(sn == gsn_pick_lock) return cov_m_l; if(sn == gsn_sneak) return cov_s_sn; if(sn == gsn_steal) return cov_m_s; if(sn == gsn_disarm) return com_o; if(sn == gsn_counter) return com_d_c; if(sn == gsn_enhanced_damage) return com_s_ma; if(sn == gsn_kick) return com_o; if(sn == gsn_parry) return com_d_p; if(sn == gsn_rescue) return com_d; if((sn == gsn_second_attack) ||(sn == gsn_third_attack) ||(sn == gsn_fourth_attack) ||(sn == gsn_fifth_attack)) return com_s_mu; if((sn == gsn_second_cast) ||(sn == gsn_third_cast)) return arc; if((sn == gsn_blindness) ||(sn == gsn_charm_person) ||(sn == gsn_curse)) return arc_a_p; if((sn == gsn_invis) ||(sn == gsn_mass_invis) ||(sn == gsn_sleep) ||(sn == gsn_fly)) return sor_h_e_p; if(sn == gsn_poison) return sor_h_e; if(sn == gsn_plague) return arc_a_p; if(sn == gsn_sanctuary) return wor_b_p_p; /*legionare */ if((sn == gsn_strike) ||(sn == gsn_shield_wall) //com_d_s com_d ||(sn == gsn_phalanx) //com_o ||(sn == gsn_fortify) ||(sn == gsn_precision)) //com_o return com_s_ma; /* draconian */ if(sn == gsn_find_dragon) return arc_n_s; if(sn == gsn_sever) return com_s_ma; /* sensei */ if((sn == gsn_haduken) //wor_m_o ||(sn == gsn_triple_kick)) //com_o_u return com_s_ma; if(sn == gsn_shadow_slip) return cov_s_sn; if(sn == gsn_fatality) return com_s_ma; //com_o_u /* zealot */ if(sn == gsn_smite) return com_s_ma; //wor_m_o /* dagashi */ if(sn == gsn_burst_of_speed) return com_s_ma; if(sn == gsn_coat) return cov_m_p; if(sn == gsn_dagashi_poison) return cov_m_p; if(sn == gsn_gouge) return com_s_ma; //cov_s_a + com_o_u /* new gsns */ if(sn == gsn_axe) return com_o_s_a; if(sn == gsn_dagger) return com_o_p_d; if(sn == gsn_flail) return com_o_b_f; if(sn == gsn_mace) return com_o_b_m; if(sn == gsn_polearm) return com_o_s_p; if(sn == gsn_shield_block) return com_d_s; if(sn == gsn_spear) return com_o_p_s; if(sn == gsn_sword) return com_o_s_s; if(sn == gsn_whip) return com_o_u; if(sn == gsn_bow) return com_o_p_m; if(sn == gsn_bash) return com_o_b; if(sn == gsn_berserk) return com_s_ma; if(sn == gsn_dirt) return com_o_u; if(sn == gsn_hand_to_hand) return com_o_u; if(sn == gsn_trip) return com_o_u; if(sn == gsn_whirlwind) return com_s_ma; if((sn == gsn_fast_healing) ||(sn == gsn_haggle)) return com_s; if(sn == gsn_lore) return sor; if(sn == gsn_meditation) return wor; if((sn == gsn_scrolls) ||(sn == gsn_staves) ||(sn == gsn_wands) ||(sn == gsn_recall)) return sor; if(sn == gsn_phase) return arc_a_p; if((sn == gsn_search) ||(sn == gsn_forging)) return com; if(sn == gsn_create_golem) return arc_n_s; else { switch (sn) { case (1): return sor_w_e; /* acid blast */ case (2): return wor_b_p_p; /* armor */ case (3): return wor_b_e_b; /* bless */ case (5): return sor_w_e; /* burning hands */ case (6): return sor_w_e; /* call lightning */ case (7): return sor_h_e_p; /* calm */ case (8): return arc_a_p; /* cancellation */ case (9): return wor_m_o; /* cause critical */ case (10): return wor_m_o; /* cause light */ case (11): return wor_m_o; /* cause serious */ case (12): return sor_w_w; /* chain lightning */ case (13): return sor_h_e_p; /* change sex */ case (15): return sor_w_e; /* chill touch */ case (16): return sor_w_e; /* colour spray */ case (17): return sor_h_e_o; /* continual light */ case (18): return sor_w_w; /* control weather */ case (19): /* create food */ case (20): /* create rose */ case (21): /* create spring */ case (22): return sor_h_e_o; /* create water */ case (23): return wor_b_h_c; /* cure blindness */ case (24): return wor_b_h_r; /* cure critical */ case (25): return wor_b_h_c; /* cure disease */ case (26): return wor_b_h_r; /* cure light */ case (27): return wor_b_h_r; /* cure poison */ case (28): return wor_b_h_c; /* cure serious */ case (30): return wor_m_o; /* demonfire */ case (31): /* detect evil */ case (32): /* detect good */ case (33): /* detect hidden */ case (34): /* detect invis */ case (35): /* detect magic */ case (36): /* detect poison */ case (37): return sor_h_d; /* discern weakness */ case (38): return wor_m_o; /* dispel evil */ case (39): return wor_m_o; /* dispel good */ case (40): return arc_a; /* dispel magic */ case (41): return wor_m_o; /* divine right com_s_ma */ case (42): return arc_a_p; /* dragonfury */ case (43): return arc_p_m; /* elemental shield */ case (44): return sor_w_e; /* earthquake */ case (45): /* enchant armor */ case (46): return sor_h_e_o; /* enchant weapon */ case (47): return sor_w_e; /* energy drain */ case (48): return -1; /* erecover */ case (49): return wor_m_o; /* exodus */ case (50): return sor_w_e; /* faerie fire */ case (51): return sor_w_w; /* faerie fog */ case (52): return sor_w_p; /* farsight */ case (53): return wor_b_e; /* fanatics flame */ case (54): return arc_g_f; /* fireball */ case (55): return arc_g_f; /* fireshield */ case (56): return sor_w_e; /* fireproof */ case (57): return wor_m_o; /* flamestrike */ case (58): return wor_m_o; /* judgement */ case (59): return sor_h_e_p; /* fly */ case (60): return sor_h_e_o; /* floating disc */ case (61): return wor_b_e_b; /* frenzy */ case (62): return sor_h_t; /* gate */ case (63): return sor_h_e_p; /* giant strength */ case (64): return arc_g_et; /* giga blast */ case (66): return wor_b_h_r; /* greater healing */ case (67): return wor_m_o; /* harm */ case (68): return sor_h_e_p; /* haste */ case (69): return wor_b_h_r; /* heal */ case (70): return sor_h_e_o; /* heat metal */ case (71): return wor_m_o; /* heavenly justice */ case (72): return arc_a_p; /* hold person */ case (73): return wor_b_p_p; /* holy armor */ case (74): return wor_b_h; /* holy word */ case (75): return sor_h_d; /* identify */ case (76): return sor_h_d; /* infravision */ case (78): return sor_w_p; /* know alignment */ case (79): return arc_g_wi; /* lightning bolt */ case (80): return sor_w_p; /* locate object */ case (81): return arc_g_et; /* magic missile */ case (82): return wor_b_h_r; /* mass healing */ case (84): return -1; /* minsc power */ case (85): /* mind thrust */ case (86): /* mind blast */ case (87): return sor_w_p; /* mind crush */ case (88): return -1; /* mrecover */ case (89): return sor_h_d; /* mystic sight */ case (90): /* nexus */ case (91): /* pass door */ case (94): return sor_h_t; /* portal */ case (95): return -1; /* precover */ case (96): /* protection evil */ case (97): return wor_b_p_s; /* protection good */ case (98): return wor_m_o; /* ray of truth */ case (99): return sor_h_e_o; /* recharge */ case (100): return wor_b_h_c; /* refresh */ case (101): return arc_a; /* remove curse */ case (102): return arc_p_p; /* repulsar */ case (103): return arc_a_o; /* runic scribing */ case (104): return arc_a_o; /* rune of warding */ case (106): return wor_b_p; /* shield */ case (107): return sor_w_e; /* shocking grasp */ case (108): return arc_n_r; /* skeleton dance */ case (110): return sor_h_e_p; /* slow */ case (111): return arc_p_p; /* stone skin */ case (112): return sor_h_t; /* summon */ case (113): return arc_g_et; /* supernova */ case (114): return sor_h_t; /* teleport */ case (115): return -1; /* thermonuclear blast */ case (116): return arc_g_ea; /* venom lance */ case (117): return sor_h_e_p; /* ventriloquate */ case (118): return arc_a_o; /* vise grip */ case (119): return sor_h_e_p; /* weaken */ case (120): return arc_n_r; /* spectral hand */ case (121): return arc_g_ea; /* acid breath */ case (122): return arc_g_f; /* fire breath */ case (123): return arc_g_wa; /* frost breath */ case (124): return arc_g_wi; /* gas breath */ case (125): return arc_g_et; /* lightning breath */ case (126): return arc_g; /* elemental wrath */ case (137): return -1; /* general purpose */ case (138): return -1; /* high explosive */ case (203): return -1; /* smiling death */ case (204): return -1; /* mantis dance */ case (205): return -1; /* deadly fingertips */ default: return -1; } } } void do_record_sn( CHAR_DATA *ch, char *argument ) { int sn; FILE *fp = NULL; if ((fp = fopen(SN_FILE, "w")) == NULL) { perror(SN_FILE); return; } stc("Beggining sn loop..\n\r",ch); for ( sn = 0; sn < MAX_SKILL; sn++ ) { if ( skill_table[sn].name == NULL ) { continue; } if ( skill_table[sn].pgsn != NULL) { continue; } else { ptc(ch,"%s found! (%d)\n\r",skill_table[sn].name,sn); fprintf(fp,"%d: %s\n",sn,skill_table[sn].name); } } stc("All SN's have been outputed to sn.txt\n\r",ch); fclose(fp); unlink(STAT_FILE); } void gain_sp( CHAR_DATA *ch, CHAR_DATA *victim ) { int gain = 0; gain += victim->level * 100; if(victim->hitroll > 1000 || victim->hitroll * 2 > 1000) gain += victim->hitroll; else gain += victim->hitroll * 2; gain += sqrt(victim->level); debug(ch,"gain_sp: sqrt()=%ld\n\r",sqrt(victim->level)); ptc(ch,"{xYou gain %d skill points.\n\r",gain); ch->pcdata->sp += gain; }