/************************************************************************ Realms of Aurealis James Rhone aka Vall of RoA guild.c General procs for various guildmasters and guild procs. Now just flag a mob with the guildmaster flag. *** BE AWARE OF ALL RIGHTS AND RESERVATIONS *** All rights reserved henceforth. Please note that no guarantees are associated with any code from Realms of Aurealis. All code which has been released to the general public has been done so with an 'as is' pretense. RoA is based on both Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well as the RoA license. *** Read, Learn, Understand, Improve *** *************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structures.h" #include "utils.h" #include "comm.h" #include "handler.h" #include "db.h" #include "magic.h" #include "mudlimits.h" #include "interpreter.h" #include "acmd.h" #include "lists.h" #include "affect.h" #include "global.h" // external functions extern int find_skill_num(char *name); extern int find_gskill_num(char *name); // return a measurement string for skill/spell proficiencies char *how_good(int percent) { static char buf[64]; if (percent == 0) strcpy(buf, " (%4unknown%0)"); else if (percent <= 10) strcpy(buf, " (%1awful%0) "); else if (percent <= 20) strcpy(buf, " (%1bad%0) "); else if (percent <= 40) strcpy(buf, " (%1poor%0) "); else if (percent <= 55) strcpy(buf, " (%0average%0)"); else if (percent <= 70) strcpy(buf, " (%0fair%0) "); else if (percent <= 80) strcpy(buf, " (%6good%0) "); else if (percent <= 85) strcpy(buf, " (%Bskilled%0)"); else strcpy(buf, " (%BSuperb%0) "); return (buf); } // each class has a different learning curve per prac int get_learned_percentage(chdata *ch, int spl) { int perc; if (IS_NPC(ch)) return 0; perc = (GET_INT(ch) * 2) - 6; switch(GET_CLASS(ch)) { case CLASS_WARRIOR: return (GET_SKILL(ch, spl) + MIN(perc, 14)); case CLASS_THIEF: return (GET_SKILL(ch, spl) + MIN(perc, 16)); case CLASS_MONK: return (GET_SKILL(ch, spl) + MIN(perc, 18)); case CLASS_RANGER: case CLASS_BARD: return (GET_SKILL(ch, spl) + MIN(perc, 20)); // primarily spell casters case CLASS_CLERIC: case CLASS_WARLOCK: case CLASS_MAGE: case CLASS_SHAMAN: case CLASS_MADEPT: case CLASS_DRUID: return (GET_SKILL(ch, spl) + MAX(14, perc)); default: return 0; } } // each spell/skill has a min level when it can be practiced // major update 7/8/98 -jtrhone // pretty major MADEPT (and similar classed) bug in this function TO BE FIXED (soon) 8/12/98 -jtrhone int get_spell_min_level(chdata *ch, int spl) { int cls = GET_CLASS(ch); extern int num_remorts(chdata *ch); if (IS_NPC(ch) || IS_IMMORTAL(ch)) return 0; // if their current natural class has it available, return that num switch (cls) { case CLASS_MADEPT: // if they madept and their skill array says they know it, then return their level if (ch->skills[spl].learned) return ((int)GET_LEVEL(ch)); break; default: if (clarray[cls].skills[spl].minlevel < LEV_IMM) return clarray[cls].skills[spl].minlevel; break; } // otherwise, they might be a remort... if (num_remorts(ch)) for (cls=0; cls < NUM_CLASSES; cls++) if (PLR2_FLAGGED(ch, (1 << cls))) { switch (cls+1) { case CLASS_MADEPT: // if they remort madept and their skill array says they know it, then return their level if (ch->skills[spl].learned) return ((int)GET_LEVEL(ch)); break; default: if (clarray[cls+1].skills[spl].minlevel < LEV_IMM) return clarray[cls+1].skills[spl].minlevel; break; } } return LEV_IMM; } /* this is how good player can learn a certain skill or spell */ // incorporated in clarray 7/8/98 -jtrhone int get_max_percentage(chdata *ch) { if (IS_NPC(ch)) return 0; else return clarray[(int)GET_CLASS(ch)].max_perc; } // trade pracs for stats... 3/1/98 -jtrhone ACMD(do_train) { chdata *mob; char *argu = argument; sbyte *stat = NULL; BOOL sc = FALSE; if (IS_NPC(ch) || INVALID_ROOM(ch->in_room)) return; skip_spaces(&argu); if (!*argu) { send_to_char("Usage: train <str | int | wis | dex | con>.\n\r",ch); return; } /* else we have an argu, look for a guildie */ for (mob = world[ch->in_room].people; mob; mob=mob->next_in_room) if (MOB2_FLAGGED(mob, MOB2_TRAINER)) break; if (!mob) { send_to_char("There is nobody here to train you.\n\r",ch); return; } // spellcasters use full train_pracs sc = (IS_NAT_WARLOCK(ch) || IS_NAT_MAGE(ch) || IS_NAT_CLERIC(ch) || IS_NAT_MADEPT(ch) || IS_NAT_DRUID(ch)); // see if they have enough pracs... if ((sc && SPELLS_TO_LEARN(ch) < train_pracs) || SPELLS_TO_LEARN(ch) < (train_pracs*3)/4) { sprintf(buf, "You lack the required %d practices to train.\n\r", sc ? train_pracs : (train_pracs*3)/4); S2C(); return; } if (is_abbrev(argu, "strength")) stat = &ch->real_abils.str; else if (is_abbrev(argu, "intelligence")) stat = &ch->real_abils.intel; else if (is_abbrev(argu, "wisdom")) stat = &ch->real_abils.wis; else if (is_abbrev(argu, "dexterity")) stat = &ch->real_abils.dex; else if (is_abbrev(argu, "constitution")) stat = &ch->real_abils.con; else { send_to_char("Unknown attribute. <str | int | wis | dex | con>.\n\r",ch); return; } // see if they CAN train it... if (*stat >= 18) { send_to_char("You cannot train that stat any higher.\n\r",ch); return; } if (sc) SPELLS_TO_LEARN(ch) -= train_pracs; else SPELLS_TO_LEARN(ch) -= (train_pracs * 3) / 4; *stat += 1; affect_total(ch); act("You train for a while.",FALSE,ch,0,0,TO_CHAR); act("$n trains for a while.",FALSE,ch,0,0,TO_ROOM); } // mega update, new skill/dialect arrays, 6/20/98 -jtrhone // split up dialg pracs into do_study // even more 7/8/98 -jtrhone ACMD(do_practice) { chdata *mob; int i = 0; BOOL line; int skl; char *argu = argument; static char buf[20000]; if (IS_NPC(ch)) return; *buf ='\0'; skip_spaces(&argu); if (!*argu) { sprintf(buf, "You have got %d practice sessions left.\n\r" "You can practice the following:\n\r", SPELLS_TO_LEARN(ch)); S2C(); for (i = 1, line = TRUE, *buf = '\0'; i < MAX_SKILLS-1; i++) if (GET_LEVEL(ch) >= get_spell_min_level(ch, i) && *skill_names[i] && !SPELL_FLAGGED(i, S_NPCONLY)) { sprintf(buf2, "%-23.23s %s ", skill_names[i], how_good(GET_SKILL(ch, i))); if ((line = !line)) strcat(buf2, "\n\r"); str_cat(buf, buf2, 20000, "do_practice"); } str_cat(buf, "\n\r", 20000, "do_practice"); page_string(ch->desc, buf, 1); return; } /* else we have an argu, look for a guildie */ for (mob = world[ch->in_room].people; mob; mob=mob->next_in_room) if (SPC_FLAGGED(mob, SPC_GMASTER)) break; if (!mob) { sprintf(buf,"You may only practice in the %s guild.\n\r", clarray[(int)GET_CLASS(ch)].class_name); S2C(); return; } skl = find_skill_num(argu); // SPELL_ARMOR is the first, and it is # 1 (roa) if (skl < SPELL_ARMOR || skl >= MAX_SKILLS) { act("$N looks at you with a confused expression.", TRUE,ch,0,mob,TO_CHAR); return; } if (GET_LEVEL(ch) < get_spell_min_level(ch, skl)) { act("$N chuckles at you.", TRUE,ch,0,mob,TO_CHAR); return; } if (SPELLS_TO_LEARN(ch) <= 0) { send_to_char("You are unable to practice now.\n\r", ch); return; } if (GET_SKILL(ch, skl) >= get_max_percentage(ch)) { send_to_char("You are already learned in this area.\n\r", ch); return; } /* skill min level less than min level, updated 7/8/98 -jtrhone */ i = get_spell_min_level(ch, skl); if (i < mob->npc_specials.min_train_level) { act("$N will not teach you something so basic, seek someone else.",FALSE, ch, 0, mob, TO_CHAR); return; } /* higher than max level */ if (i > mob->npc_specials.max_train_level) { act("$N is unable to teach you such a skill, seek someone else.",FALSE, ch, 0, mob, TO_CHAR); return; } // else he will teach em... sprintf(buf, "$N teaches you a bit about %%6%s%%0.", skill_names[skl]); act(buf, FALSE, ch, 0, mob, TO_CHAR); act("You practice for a while...", FALSE, ch, 0, mob, TO_CHAR); act("$n practices for a while.",FALSE,ch,0,0,TO_ROOM); SPELLS_TO_LEARN(ch)--; SET_SKILL(ch, skl, MIN(get_max_percentage(ch), get_learned_percentage(ch, skl))); if (GET_SKILL(ch, skl) >= get_max_percentage(ch)) { sprintf(buf, "You have mastered %%6%s%%0.", skill_names[skl]); act(buf, FALSE, ch, 0, mob, TO_CHAR); } } // new, just practice in dialect/gskill array... 6/20/98 -jtrhone ACMD(do_study) { chdata *mob; int i = 0; BOOL line; int skl; char *argu = argument; static char buf[20000]; if (IS_NPC(ch)) return; *buf ='\0'; skip_spaces(&argu); if (!*argu) { sprintf(buf, "You have got %d practice sessions left.\n\r" "You can study the following:\n\r", SPELLS_TO_LEARN(ch)); S2C(); strcpy(buf,"%6-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-%0 " "%BDialects%0" "%6 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-%0\n\r"); // first, show them dialects... for (i = 0, line = TRUE; i < MAX_GSKILLS; i++) if (*gskill_names[i] && GSKILL_FLAGGED(i, G_DIALECT) && ch->gskills[i].learned) { sprintf(buf2, "%-23.23s %s ", gskill_names[i], how_good(ch->gskills[i].perc)); if ((line = !line)) strcat(buf2, "\n\r"); str_cat(buf, buf2, 20000, "do_study"); } strcat(buf, "\n\r"); strcat(buf,"%6-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-%0 " "%BMisc%0" "%6 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-%0\n\r"); // now for general skills... for (i = 0, line = TRUE; i < MAX_GSKILLS; i++) if (*gskill_names[i] && !GSKILL_FLAGGED(i, G_DIALECT) && ch->gskills[i].learned) { sprintf(buf2, "%-23.23s %s ", gskill_names[i], how_good(ch->gskills[i].perc)); if ((line = !line)) strcat(buf2, "\n\r"); str_cat(buf, buf2, 20000, "do_study"); } str_cat(buf, "\n\r", 20000, "do_study"); page_string(ch->desc, buf, 1); return; } /* else we have an argu, look for a guildie */ for (mob = world[ch->in_room].people; mob; mob=mob->next_in_room) if (SPC_FLAGGED(mob, SPC_GMASTER)) break; if (!mob) { sprintf(buf, "You may only study in the %s guild.\n\r", clarray[(int)GET_CLASS(ch)].class_name); S2C(); return; } skl = find_gskill_num(argu); if (skl < 0 || skl >= MAX_GSKILLS) { act("$N looks at you with a confused expression.", TRUE,ch,0,mob,TO_CHAR); return; } if (SPELLS_TO_LEARN(ch) <= 0) { send_to_char("You are unable to study now.\n\r", ch); return; } if (ch->gskills[skl].perc >= 95) { send_to_char("You have already mastered this area.\n\r", ch); return; } // else he will teach em... sprintf(buf, "$N teaches you a bit about %%6%s%%0.", gskill_names[skl]); act(buf, FALSE, ch, 0, mob, TO_CHAR); act("You study for a while...", FALSE, ch, 0, mob, TO_CHAR); act("$n studies for a while.",FALSE,ch,0,0,TO_ROOM); SPELLS_TO_LEARN(ch)--; ch->gskills[skl].perc += (GET_INT(ch) * 2) - 6; ch->gskills[skl].perc = MIN(95, ch->gskills[skl].perc); if (ch->gskills[skl].perc >= 95) { sprintf(buf, "You have mastered %%6%s%%0.", gskill_names[skl]); act(buf, FALSE, ch, 0, mob, TO_CHAR); } } ACMD(do_wpractice) { chdata *mob; if (IS_NPC(ch)) return; if (!IS_WARLOCK(ch)) { send_to_char("You know not of such magic.\n\r",ch); return; } for (mob = world[ch->in_room].people; mob; mob=mob->next_in_room) if (SPC_FLAGGED(mob, SPC_GMASTER)) break; if (!mob) { send_to_char("You may only improve your casting ability in your guild.\n\r",ch); return; } if (SPELLS_TO_LEARN(ch) <= 0) { send_to_char("You cannot practice now.\n\r",ch); return; } if ((int)GET_WLEVEL(ch) >= GET_LEVEL(ch)) { send_to_char("You cannot improve your casting ability above your current level!\n\r",ch); return; } SPELLS_TO_LEARN(ch)--; GET_WLEVEL(ch)++; if (GET_INT(ch) >= 18) GET_WLEVEL(ch)++; GET_WLEVEL(ch) = MIN(GET_LEVEL(ch), GET_WLEVEL(ch)); sprintf(buf, "You have improved your casting ability to level %%6%d%%0.\n\r", GET_WLEVEL(ch)); S2C(); }