-=My Weapon Proficiency System=- I started off with Fabrizio Baldi's Weapon Proficiency System, although there is nearly none of his code in this, i thought i should let you know that some credit should go to him. Anyway, his code works on practising spells to become proficient with a weapon. I didn't want this, i wanted it so that the more you use the weapon, the more proficient you get with the weapon. I thought it was a bit more realistic. And with this, there are additions to hitroll, overall damage and shields. ****WARNING***** I have ascii pfiles, if you want to do this the same way as me with binary, you will need a pfile wipe or convert. **************** but i'll include both ascii and binary version. Although I haven't tested the binary version, it's just what i would code if i had binary pfiles. backup your pfile before and if anything goes wrong, just take out the code and restore the pfile, nothing lost. first open structs.h ~~~~~~~~~~~~~~~~~~~~ above this structure "struct player_special_data_saved" +#define MAX_PROFS 100 + +struct wprof_data { + int vnum; + int prof; +}; at the end of this structure "struct player_special_data" + struct wprof_data profs[MAX_PROFS]; /* Character's Proficencies */ and then at the end of the file put +struct weapon_prof_data { + sh_int to_hit; + sh_int to_ac; + sh_int add_dam; +}; (If you have Binary Pfiles do the following) go down to "struct affected_type affected[MAX_AFFECT];" in char_file_u and add this below it + struct wprof_data profs[MAX_PROFS]; /* Character's Proficencies */ (End of structs.h code for Binary Pfiles) now open constants.c ~~~~~~~~~~~~~~~~~~~~ and place anywhere in the file +const struct weapon_prof_data wprof[] = { +/* HR AC ADDDAM */ + { 0, 0, 90}, /* Not Used */ + { 1, 0, 4}, /* prof <= 20 */ + { 2, 0, 4}, /* prof <= 40 */ + { 3, 0, 3}, /* prof <= 60 */ + { 4, 0, 3}, /* prof <= 80 */ + { 6, -1, 2}, /* prof <= 85 */ + { 7, -2, 2}, /* prof <= 90 */ + { 8, -3, 2}, /* prof <= 95 */ + { 9, -4, 1}, /* prof <= 99 */ + { 10, -5, 1}, /* prof == 100 */ + { -1, 0, 90} /* prof == 0 */ + +/* for Add dam, it's player level divided by that number is added */ +}; now open utils.h ~~~~~~~~~~~~~~~~ and place the following at the top of the file: +int get_wprof(struct char_data *ch); +void add_wprof(struct char_data *ch); then place this anywhere +#define GET_PROF_VNUM(ch, i) ((ch)->player_specials->profs[i].vnum) +#define GET_PROF_PROF(ch, i) ((ch)->player_specials->profs[i].prof) now open utils.c ~~~~~~~~~~~~~~~~ place this at the bottom of the file: I know it's not neat, but it works. +int get_wprof(struct char_data *ch) +{ + int i, vnum = 0, prof = 0; + + if (IS_NPC(ch)) + return(10); + + if (GET_EQ(ch, WEAR_WIELD)) + vnum = GET_OBJ_VNUM(GET_EQ(ch, WEAR_WIELD)); + + if (!vnum) /* No Weapon */ + return(10); + + for (i = 0; i < MAX_PROFS; i++) { + if (vnum == GET_PROF_VNUM(ch, i)) + prof = (GET_PROF_PROF(ch, i) / 100); + } + if (prof == 0) + return(10); + else if (prof <= 20) + return(1); + else if (prof <= 40) + return(2); + else if (prof <= 60) + return(3); + else if (prof <= 80) + return(4); + else if (prof <= 85) + return(5); + else if (prof <= 90) + return(6); + else if (prof <= 95) + return(7); + else if (prof <= 99) + return(8); + else + return(9); +} + +void add_wprof(struct char_data *ch) +{ + int done = FALSE, i, vnum = 0; + + if (IS_NPC(ch)) + return; + + if (GET_EQ(ch, WEAR_WIELD)) + vnum = GET_OBJ_VNUM(GET_EQ(ch, WEAR_WIELD)); + + if (!vnum) /* No Weapon */ + return; + + for (i = 0; i < MAX_PROFS; i++) { + if (vnum == GET_PROF_VNUM(ch, i)) { + if (GET_PROF_PROF(ch, i) < 10000) + GET_PROF_PROF(ch, i) += 1; + done = TRUE; + } + } + if (!done) { + for (i = 0; i < MAX_PROFS; i++) { + if (!GET_PROF_VNUM(ch, i) && !done) { + GET_PROF_VNUM(ch, i) = vnum; + GET_PROF_PROF(ch, i) = 1; + done = TRUE; + } + } + } + /* Uh Oh, We've gone over the MAX, let's clear + out profs. and make an excuse + */ + if (!done) { + for (i = 0; i < MAX_PROFS; i++) { + GET_PROF_VNUM(ch, i) = 0; + GET_PROF_PROF(ch, i) = 0; + } + send_to_char("^4You have used too many weapons and are starting to forget them!\r\n", ch); + send_to_char("Oh No! You've forgotten how to use any weapon.\r\n", ch); + } + return; +} now open db.c ~~~~~~~~~~~~~ (Start of ASCII Code) go to "load_char(char *name, struct char_data *ch)" and add above "while(fbgetline(fl, line)) {" + for (i = 0; i < MAX_PROFS; i++) { + ch->player_specials->profs[i].vnum = 0; + ch->player_specials->profs[i].prof = 0; + } then below "PRF_FLAGS(ch) = asciiflag_conv(line);" + else if(!strcmp(tag, "Prof")) { + i = 0; + do { + fbgetline(fl, line); + sscanf(line, "%d %d", &num, &num2); + GET_PROF_VNUM(ch, i) = num; + GET_PROF_PROF(ch, i) = num2; + i++; + } while (num != 0); + } now go down to "void save_char(struct char_data * ch, sh_int load_room)" and below "fbprintf(fl, "0 0 0 0 0\n");" add + fprintf(fl, "Prof:\n"); + for(i = 0; i < MAX_PROFS; i++) { + if (GET_PROF_VNUM(ch, i) && GET_PROF_PROF(ch, i)) + fbprintf(fl, "%d %d\n", GET_PROF_VNUM(ch, i), GET_PROF_PROF(ch, i)); + } + fbprintf(fl, "0 0\n"); (the End of db.c for ASCII Pfiles) (Start of db.c for Binary Pfiles) find "void store_to_char(struct char_file_u * st, struct char_data * ch)" and below the following: for (i = 0; i < MAX_AFFECT; i++) { if (st->affected[i].type) affect_to_char(ch, &st->affected[i]); } put + for (i = 0; i < MAX_PROFS; i++) { + if (st->profs[i].vnum) { + GET_PROF_VNUM(ch, i) = st->profs[i].vnum; + GET_PROF_PROF(ch, i) = st->profs[i].prof; + } + } now find "void char_to_store(struct char_data * ch, struct char_file_u * st)" and below the following: for (i = 0; i < MAX_AFFECT; i++) { if (st->affected[i].type) affect_to_char(ch, &st->affected[i]); } put + for (i = 0; i < MAX_PROFS; i++) { + if (GET_PROF_VNUM(ch, i)) { + st->profs[i].vnum = GET_PROF_VNUM(ch, i); + st->profs[i].prof = GET_PROF_PROF(ch, i); + } + } (the End of db.c for Binary Pfiles) now open fight.c ~~~~~~~~~~~~~~~~ at the top of the file put: +extern struct weapon_prof_data wprof[]; now find "int compute_armor_class(struct char_data *ch)" and below "int armorclass = GET_AC(ch);" put: + struct obj_data *wielded = GET_EQ(ch, WEAR_WIELD); then below this: if (AWAKE(ch)) armorclass += dex_app[GET_DEX(ch)].defensive * 10; put: if (!IS_NPC(ch)) if (wielded && GET_OBJ_TYPE(wielded) == ITEM_WEAPON) armorclass += wprof[get_wprof(ch)].to_ac * 10; find "void hit(struct char_data * ch, struct char_data * victim, int type)" and put "int pdam;" at the top of this function. now find "calc_thaco -= GET_HITROLL(ch);" and just below it put: + calc_thaco -= wprof[get_wprof(ch)].to_hit; now find "dam += GET_DAMROLL(ch);" and place below it, the following: + pdam = (GET_LEVEL(ch) / (wprof[get_wprof(ch)].add_dam)); + dam += pdam; now in "void perform_violence(void)" a couple of lines before "hit(ch, FIGHTING(ch), TYPE_UNDEFINED);" make some space and put: + if (!IS_NPC(ch)) { + add_wprof(ch); + + /* Warriors and Human's learn twice as quick */ + if (IS_HUMAN(ch) || IS_WARRIOR(ch)) + add_wprof(ch); + } if you have multiple attacks, make sure this doesn't get done for each attack, just per round. ****AFTER THIS IS OPTIONAL**** now open act.informative.c ~~~~~~~~~~~~~~~~~~~~~~~~~~ and below "ACMD(do_exits);" put "ACMD(do_wprof);" then at the very bottom of the file put: +ACMD(do_wprof) +{ + struct obj_data *obj; + int i, some = FALSE; + + send_to_char("*** Tactical Stats ***\r\n\r\n", ch); + for (i = 0; i < MAX_PROFS; i++) { + if (GET_PROF_PROF(ch, i) / 100) { + obj = read_object(real_object(GET_PROF_VNUM(ch, i)), REAL); + sprintf(buf, " ^4[%3d]^0 percent tactics learned on: ^4%s^0\r\n", (GET_PROF_PROF(ch, i) / 100), obj->short_description); + send_to_char(buf, ch); + some = TRUE; + } + } + if (!some) { + send_to_char("You have no decent tactical knowledge on any weapon.\r\n", ch); + } +} now open interpreter.c ~~~~~~~~~~~~~~~~~~~~~~ below "ACMD(do_wizutil);" put "ACMD(do_wprof);" then below the following line: { "tackle" , POS_NORMAL , do_action , 0, 0, NP, 0, NULL }, put: + { "tactical" , POS_NORMAL , do_wprof , 0, 0, NP, 0, NULL }, That should be it. Subliminal m_gally@hotmail.com