A few Bug-Fixes and Ideas

This commit is contained in:
JamDog 2010-11-06 15:47:38 +00:00
parent 222be04ec5
commit d4454288b1
9 changed files with 249 additions and 150 deletions

View file

@ -12,8 +12,8 @@
#define __CLASS_C__
/* This file attempts to concentrate most of the code which must be changed
* in order for new classes to be added. If you're adding a new class, you
* should go through this entire file from beginning to end and add the
* in order for new classes to be added. If you're adding a new class, you
* should go through this entire file from beginning to end and add the
* appropriate new special cases for your new class. */
#include "conf.h"
@ -53,7 +53,7 @@ const char *class_menu =
" [W]arrior\r\n"
" [M]agic-user\r\n";
/* The code to interpret a class letter -- used in interpreter.c when a new
/* The code to interpret a class letter -- used in interpreter.c when a new
* character is selecting a class and by 'set class' in act.wizard.c. */
int parse_class(char arg)
{
@ -68,9 +68,9 @@ int parse_class(char arg)
}
}
/* bitvectors (i.e., powers of two) for each class, mainly for use in do_who
/* bitvectors (i.e., powers of two) for each class, mainly for use in do_who
* and do_users. Add new classes at the end so that all classes use sequential
* powers of two (1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, etc.) up to
* powers of two (1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, etc.) up to
* the limit of your bitvector_t, typically 0-31. */
bitvector_t find_class_bitvector(const char *arg)
{
@ -82,17 +82,17 @@ bitvector_t find_class_bitvector(const char *arg)
return (ret);
}
/* These are definitions which control the guildmasters for each class.
* The first field (top line) controls the highest percentage skill level a
* character of the class is allowed to attain in any skill. (After this
/* These are definitions which control the guildmasters for each class.
* The first field (top line) controls the highest percentage skill level a
* character of the class is allowed to attain in any skill. (After this
* level, attempts to practice will say "You are already learned in this area."
*
* The second line controls the maximum percent gain in learnedness a character
* is allowed per practice -- in other words, if the random die throw comes out
* higher than this number, the gain will only be this number instead.
*
* The third line controls the minimu percent gain in learnedness a character
* is allowed per practice -- in other words, if the random die throw comes
* The third line controls the minimu percent gain in learnedness a character
* is allowed per practice -- in other words, if the random die throw comes
* out below this number, the gain will be set up to this number.
*
* The fourth line simply sets whether the character knows 'spells' or 'skills'.
@ -117,20 +117,20 @@ int prac_params[4][NUM_CLASSES] = {
};
/* The appropriate rooms for each guildmaster/guildguard; controls which types
* of people the various guildguards let through. i.e., the first line shows
* that from room 3017, only MAGIC_USERS are allowed to go south. Don't forget
* of people the various guildguards let through. i.e., the first line shows
* that from room 3017, only MAGIC_USERS are allowed to go south. Don't forget
* to visit spec_assign.c if you create any new mobiles that should be a guild
* master or guard so they can act appropriately. If you "recycle" the
* existing mobs that are used in other guilds for your new guild, then you
* master or guard so they can act appropriately. If you "recycle" the
* existing mobs that are used in other guilds for your new guild, then you
* don't have to change that file, only here. Guildguards are now implemented
* via triggers. This code remains as an example. */
struct guild_info_type guild_info[] = {
/* Midgaard */
{ CLASS_MAGIC_USER, 3017, SOUTH },
{ CLASS_CLERIC, 3004, NORTH },
{ CLASS_THIEF, 3027, EAST },
{ CLASS_WARRIOR, 3021, EAST },
{ CLASS_MAGIC_USER, 3017, SOUTH },
{ CLASS_CLERIC, 3004, NORTH },
{ CLASS_THIEF, 3027, EAST },
{ CLASS_WARRIOR, 3021, EAST },
/* Brass Dragon */
{ -999 /* all */ , 5065, WEST },
@ -139,7 +139,7 @@ struct guild_info_type guild_info[] = {
{ -1, NOWHERE, -1}
};
/* Saving throws for : MCTW : PARA, ROD, PETRI, BREATH, SPELL. Levels 0-40. Do
/* Saving throws for : MCTW : PARA, ROD, PETRI, BREATH, SPELL. Levels 0-40. Do
* not forget to change extern declaration in magic.c if you add to this. */
byte saving_throws(int class_num, int type, int level)
{
@ -1344,7 +1344,7 @@ int thaco(int class_num, int level)
/* Roll the 6 stats for a character... each stat is made of the sum of the best
* 3 out of 4 rolls of a 6-sided die. Each class then decides which priority
* 3 out of 4 rolls of a 6-sided die. Each class then decides which priority
* will be given for the best to worst stats. */
void roll_real_abils(struct char_data *ch)
{
@ -1456,13 +1456,13 @@ void do_start(struct char_data *ch)
GET_COND(ch, HUNGER) = 24;
GET_COND(ch, DRUNK) = 0;
SET_BIT_AR(PRF_FLAGS(ch), PRF_AUTOEXIT);
SET_BIT_AR(PRF_FLAGS(ch), PRF_AUTOEXIT);
if (CONFIG_SITEOK_ALL)
SET_BIT_AR(PLR_FLAGS(ch), PLR_SITEOK);
}
/* This function controls the change to maxmove, maxmana, and maxhp for each
/* This function controls the change to maxmove, maxmana, and maxhp for each
* class every time they gain a level. */
void advance_level(struct char_data *ch)
{
@ -1521,8 +1521,8 @@ void advance_level(struct char_data *ch)
}
/* This simply calculates the backstab multiplier based on a character's level.
* This used to be an array, but was changed to be a function so that it would
* be easier to add more levels to your MUD. This doesn't really create a big
* This used to be an array, but was changed to be a function so that it would
* be easier to add more levels to your MUD. This doesn't really create a big
* performance hit because it's not used very often. */
int backstab_mult(int level)
{
@ -1559,8 +1559,8 @@ int invalid_class(struct char_data *ch, struct obj_data *obj)
return FALSE;
}
/* SPELLS AND SKILLS. This area defines which spells are assigned to which
* classes, and the minimum level the character must be to use the spell or
/* SPELLS AND SKILLS. This area defines which spells are assigned to which
* classes, and the minimum level the character must be to use the spell or
* skill. */
void init_spell_levels(void)
{
@ -1587,6 +1587,7 @@ void init_spell_levels(void)
spell_level(SPELL_FIREBALL, CLASS_MAGIC_USER, 15);
spell_level(SPELL_CHARM, CLASS_MAGIC_USER, 16);
spell_level(SPELL_IDENTIFY, CLASS_MAGIC_USER, 20);
spell_level(SPELL_FLY, CLASS_MAGIC_USER, 22);
spell_level(SPELL_ENCHANT_WEAPON, CLASS_MAGIC_USER, 26);
spell_level(SPELL_CLONE, CLASS_MAGIC_USER, 30);
@ -1637,7 +1638,7 @@ void init_spell_levels(void)
spell_level(SKILL_BASH, CLASS_WARRIOR, 12);
}
/* This is the exp given to implementors -- it must always be greater than the
/* This is the exp given to implementors -- it must always be greater than the
* exp required for immortality, plus at least 20,000 or so. */
#define EXP_MAX 10000000

View file

@ -27,7 +27,7 @@
/* Utility functions */
/* Thanks to James Long for his assistance in plugging the memory leak that
/* Thanks to James Long for his assistance in plugging the memory leak that
* used to be here. - Welcor */
/* Adds a variable with given name and value to trigger. */
void add_var(struct trig_var_data **var_list, const char *name, const char *value, long id)
@ -75,8 +75,8 @@ char *skill_percent(struct char_data *ch, char *skill)
return retval;
}
/* Search through all the persons items, including containers. 0 if it doesnt
* exist, and greater then 0 if it does! Jamie Nelson. Now also searches by
/* Search through all the persons items, including containers. 0 if it doesnt
* exist, and greater then 0 if it does! Jamie Nelson. Now also searches by
* vnum and returns the number of matching objects. - Welcor */
int item_in_list(char *item, obj_data *list)
{
@ -115,8 +115,8 @@ int item_in_list(char *item, obj_data *list)
return count;
}
/* BOOLEAN return, just check if a player or mob has an item of any sort,
* searched for by name or id. Searching equipment as well as inventory, and
/* BOOLEAN return, just check if a player or mob has an item of any sort,
* searched for by name or id. Searching equipment as well as inventory, and
* containers. Jamie Nelson */
int char_has_item(char *item, struct char_data *ch)
{
@ -401,11 +401,11 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
* - count number of objects in room X with this name/id/vnum
* %findmob.<room vnum X>(<mob vnum Y>)%
* - count number of mobs in room X with vnum Y
* For example you want to check how many PC's are in room with vnum 1204. PC's
* For example you want to check how many PC's are in room with vnum 1204. PC's
* have the vnum -1 so: %echo% players in room 1204: %findmob.1204(-1)%
* Or say you had a bank, and you want a script to check the number of bags of
* gold (vnum: 1234). In the vault (vnum: 453). Use: %findobj.453(1234)% and it
* will return the number of bags of gold.
* Or say you had a bank, and you want a script to check the number of bags of
* gold (vnum: 1234). In the vault (vnum: 453). Use: %findobj.453(1234)% and it
* will return the number of bags of gold.
* Addition inspired by Jamie Nelson */
else if (!str_cmp(var, "findmob")) {
if (!field || !*field || !subfield || !*subfield) {
@ -530,7 +530,7 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
if (c) {
if (!str_cmp(field, "global")) { /* get global of something else */
if (!str_cmp(field, "global")) { /* get global of something else */
if (IS_NPC(c) && c->script) {
find_replacement(go, c->script, NULL, MOB_TRIGGER,
subfield, NULL, NULL, str, slen);
@ -581,8 +581,18 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
snprintf(str, slen, "%d", GET_CHA(c));
}
else if (!str_cmp(field, "class"))
sprinttype(GET_CLASS(c), pc_class_types, str, slen);
else if (!str_cmp(field, "class")) {
if (subfield && *subfield) {
int cl = get_class_by_name(subfield);
if (cl != -1) {
GET_CLASS(c) = cl;
snprintf(str, slen, "1");
} else {
snprintf(str, slen, "0");
}
} else
sprinttype(GET_CLASS(c), pc_class_types, str, slen);
}
else if (!str_cmp(field, "con")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
@ -672,14 +682,14 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
else
snprintf(str, slen, "%d", char_has_item(subfield, c));
}
else if (!str_cmp(field, "hasattached")) {
if (!(subfield && *subfield) || !IS_NPC(c))
*str = '\0';
else {
i = atoi(subfield);
snprintf(str, slen, "%d", trig_is_attached(SCRIPT(c), i));
}
}
else if (!str_cmp(field, "hasattached")) {
if (!(subfield && *subfield) || !IS_NPC(c))
*str = '\0';
else {
i = atoi(subfield);
snprintf(str, slen, "%d", trig_is_attached(SCRIPT(c), i));
}
}
else if (!str_cmp(field, "heshe"))
snprintf(str, slen, "%s", HSSH(c));
else if (!str_cmp(field, "himher"))
@ -766,8 +776,13 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
break;
case 'l':
if (!str_cmp(field, "level"))
snprintf(str, slen, "%d", GET_LEVEL(c));
if (!str_cmp(field, "level")) {
if (subfield && *subfield) {
int lev = atoi(subfield);
GET_LEVEL(c) = MIN(MAX(lev, 0), LVL_IMMORT-1);
} else
snprintf(str, slen, "%d", GET_LEVEL(c));
}
break;
case 'm':
if (!str_cmp(field, "mana")) {
@ -846,19 +861,19 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
snprintf(str, slen, "%d", GET_PRACTICES(c));
}
else if (!str_cmp(field, "pref")) {
if (subfield && *subfield) {
int pref = get_flag_by_name(preference_bits, subfield);
if (!IS_NPC(c) && pref != NOFLAG && PRF_FLAGGED(c, pref))
strcpy(str, "1");
else
strcpy(str, "0");
} else
strcpy(str, "0");
if (subfield && *subfield) {
int pref = get_flag_by_name(preference_bits, subfield);
if (!IS_NPC(c) && pref != NOFLAG && PRF_FLAGGED(c, pref))
strcpy(str, "1");
else
strcpy(str, "0");
} else
strcpy(str, "0");
}
break;
case 'q':
if (!IS_NPC(c) && (!str_cmp(field, "questpoints") ||
!str_cmp(field, "qp") || !str_cmp(field, "qpnts")))
if (!IS_NPC(c) && (!str_cmp(field, "questpoints") ||
!str_cmp(field, "qp") || !str_cmp(field, "qpnts")))
{
if (subfield && *subfield) {
int addition = atoi(subfield);
@ -866,25 +881,25 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
snprintf(str, slen, "%d", GET_QUESTPOINTS(c));
}
else if (!str_cmp(field, "quest"))
{
else if (!str_cmp(field, "quest"))
{
if (!IS_NPC(c) && (GET_QUEST(c) != NOTHING) && (real_quest(GET_QUEST(c)) != NOTHING))
snprintf(str, slen, "%d", GET_QUEST(c));
else
strcpy(str, "0");
}
else if (!str_cmp(field, "questdone"))
{
if (!IS_NPC(c) && subfield && *subfield) {
int q_num = atoi(subfield);
if (is_complete(c, q_num))
strcpy(str, "1");
else
strcpy(str, "0");
}
else
strcpy(str, "0");
}
snprintf(str, slen, "%d", GET_QUEST(c));
else
strcpy(str, "0");
}
else if (!str_cmp(field, "questdone"))
{
if (!IS_NPC(c) && subfield && *subfield) {
int q_num = atoi(subfield);
if (is_complete(c, q_num))
strcpy(str, "1");
else
strcpy(str, "0");
}
else
strcpy(str, "0");
}
break;
case 'r':
if (!str_cmp(field, "room")) { /* in NOWHERE, return the void */
@ -1058,15 +1073,15 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
*str = '\x1';
switch (LOWER(*field)) {
case 'a':
if (!str_cmp(field, "affects")) {
if (subfield && *subfield) {
if (!str_cmp(field, "affects")) {
if (subfield && *subfield) {
if (check_flags_by_name_ar(GET_OBJ_AFFECT(o), NUM_AFF_FLAGS, subfield, affected_bits) == TRUE)
snprintf(str, slen, "1");
else
snprintf(str, slen, "0");
snprintf(str, slen, "1");
else
snprintf(str, slen, "0");
} else
snprintf(str, slen, "0");
}
snprintf(str, slen, "0");
}
case 'c':
if (!str_cmp(field, "cost")) {
if (subfield && *subfield) {
@ -1127,13 +1142,13 @@ o->contains) ? "1" : "0"));
else
strcpy(str, "0");
}
else if (!str_cmp(field, "hasattached")) {
if (!(subfield && *subfield))
*str = '\0';
else {
i = atoi(subfield);
snprintf(str, slen, "%d", trig_is_attached(SCRIPT(o), i));
}
else if (!str_cmp(field, "hasattached")) {
if (!(subfield && *subfield))
*str = '\0';
else {
i = atoi(subfield);
snprintf(str, slen, "%d", trig_is_attached(SCRIPT(o), i));
}
}
break;
case 'i':
@ -1146,9 +1161,9 @@ o->contains) ? "1" : "0"));
else
*str = '\0';
}
else if (!str_cmp(field, "is_pc")) {
strcpy(str, "-1");
}
else if (!str_cmp(field, "is_pc")) {
strcpy(str, "-1");
}
break;
case 'n':
if (!str_cmp(field, "name"))
@ -1200,12 +1215,12 @@ o->contains) ? "1" : "0"));
snprintf(str, slen, "%d", GET_OBJ_VAL(o, 3));
break;
case 'w':
if (!str_cmp(field, "wearflag")) {
if (!str_cmp(field, "wearflag")) {
if (subfield && *subfield) {
if (can_wear_on_pos(o, find_eq_pos_script(subfield)))
snprintf(str, slen, "1");
else
snprintf(str, slen, "0");
if (can_wear_on_pos(o, find_eq_pos_script(subfield)))
snprintf(str, slen, "1");
else
snprintf(str, slen, "0");
} else
snprintf(str, slen, "0");
}
@ -1325,27 +1340,27 @@ o->contains) ? "1" : "0"));
else
*str = '\0';
}
else if (!str_cmp(field, "hasattached")) {
if (!(subfield && *subfield))
*str = '\0';
else {
i = atoi(subfield);
snprintf(str, slen, "%d", trig_is_attached(SCRIPT(r), i));
}
else if (!str_cmp(field, "hasattached")) {
if (!(subfield && *subfield))
*str = '\0';
else {
i = atoi(subfield);
snprintf(str, slen, "%d", trig_is_attached(SCRIPT(r), i));
}
}
else if (!str_cmp(field, "zonenumber"))
snprintf(str, slen, "%d", zone_table[r->zone].number);
else if (!str_cmp(field, "zonename"))
else if (!str_cmp(field, "zonenumber"))
snprintf(str, slen, "%d", zone_table[r->zone].number);
else if (!str_cmp(field, "zonename"))
snprintf(str, slen, "%s", zone_table[r->zone].name);
else if (!str_cmp(field, "roomflag")) {
if (subfield && *subfield) {
room_rnum thisroom = real_room(r->number);
if (check_flags_by_name_ar(ROOM_FLAGS(thisroom), NUM_ROOM_FLAGS, subfield, room_bits) == TRUE)
snprintf(str, slen, "1");
else
snprintf(str, slen, "0");
else if (!str_cmp(field, "roomflag")) {
if (subfield && *subfield) {
room_rnum thisroom = real_room(r->number);
if (check_flags_by_name_ar(ROOM_FLAGS(thisroom), NUM_ROOM_FLAGS, subfield, room_bits) == TRUE)
snprintf(str, slen, "1");
else
snprintf(str, slen, "0");
} else
snprintf(str, slen, "0");
snprintf(str, slen, "0");
}
else if (!str_cmp(field, "north")) {
if (R_EXIT(r, NORTH)) {
@ -1489,10 +1504,10 @@ o->contains) ? "1" : "0"));
}
}
/* Now automatically checks if the variable has more then one field in it. And
* if the field returns a name or a script UID or the like it can recurse. If
* you supply a value like, %actor.int.str% it wont blow up on you either. Now
* also lets subfields have variables parsed inside of them so that: %echo%
/* Now automatically checks if the variable has more then one field in it. And
* if the field returns a name or a script UID or the like it can recurse. If
* you supply a value like, %actor.int.str% it wont blow up on you either. Now
* also lets subfields have variables parsed inside of them so that: %echo%
* %actor.gold(%actor.gold%)% will double the actors gold every time its called.
* - Jamie Nelson */

View file

@ -413,6 +413,13 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
to_vict = "Your eyes tingle.";
break;
case SPELL_FLY:
af[0].duration = 24;
SET_BIT_AR(af[0].bitvector, AFF_FLYING);
accum_duration = TRUE;
to_vict = "You float above the ground.";
break;
case SPELL_INFRAVISION:
af[0].duration = 12 + level;
SET_BIT_AR(af[0].bitvector, AFF_INFRAVISION);

View file

@ -34,6 +34,8 @@ static void medit_save_to_disk(zone_vnum zone_num);
static void medit_disp_positions(struct descriptor_data *d);
static void medit_disp_sex(struct descriptor_data *d);
static void medit_disp_attack_types(struct descriptor_data *d);
static bool medit_illegal_mob_flag(int fl);
static int medit_get_mob_flag_by_number(int num);
static void medit_disp_mob_flags(struct descriptor_data *d);
static void medit_disp_aff_flags(struct descriptor_data *d);
static void medit_disp_menu(struct descriptor_data *d);
@ -328,14 +330,57 @@ static void medit_disp_attack_types(struct descriptor_data *d)
write_to_output(d, "Enter attack type : ");
}
/* Find mob flags that shouldn't be set by builders */
static bool medit_illegal_mob_flag(int fl)
{
int i;
/* add any other flags you dont want them setting */
const int illegal_flags[] = {
MOB_ISNPC,
MOB_NOTDEADYET,
};
const int num_illegal_flags = sizeof(illegal_flags)/sizeof(int);
for (i=0; i < num_illegal_flags;i++)
if (fl == illegal_flags[i])
return (TRUE);
return (FALSE);
}
/* Due to illegal mob flags not showing in the mob flags list,
we need this to convert the list number back to flag value */
static int medit_get_mob_flag_by_number(int num)
{
int i, count = 0;
for (i = 0; i < NUM_MOB_FLAGS; i++) {
if (medit_illegal_mob_flag(i)) continue;
if ((++count) == num) return i;
}
/* Return 'illegal flag' value */
return -1;
}
/* Display mob-flags menu. */
static void medit_disp_mob_flags(struct descriptor_data *d)
{
int i, count = 0, columns = 0;
char flags[MAX_STRING_LENGTH];
get_char_colors(d->character);
clear_screen(d);
column_list(d->character, 0, action_bits, NUM_MOB_FLAGS, TRUE);
/* Mob flags has special handling to remove illegal flags from the list */
for (i = 0; i < NUM_MOB_FLAGS; i++) {
if (medit_illegal_mob_flag(i)) continue;
write_to_output(d, "%s%2d%s) %-20.20s %s", grn, ++count, nrm, action_bits[i],
!(++columns % 2) ? "\r\n" : "");
}
sprintbitarray(MOB_FLAGS(OLC_MOB(d)), action_bits, AF_ARRAY_MAX, flags);
write_to_output(d, "\r\nCurrent flags : %s%s%s\r\nEnter mob flags (0 to quit) : ", cyn, flags, nrm);
}
@ -478,7 +523,7 @@ static void medit_disp_stats_menu(struct descriptor_data *d)
void medit_parse(struct descriptor_data *d, char *arg)
{
int i = -1;
int i = -1, j;
char *oldtext = NULL;
if (OLC_MODE(d) > MEDIT_NUMERICAL_RESPONSE) {
@ -837,8 +882,13 @@ void medit_parse(struct descriptor_data *d, char *arg)
case MEDIT_NPC_FLAGS:
if ((i = atoi(arg)) <= 0)
break;
else if (i <= NUM_MOB_FLAGS)
else if ( (j = medit_get_mob_flag_by_number(i)) == -1) {
write_to_output(d, "Invalid choice!\r\n");
write_to_output(d, "Enter mob flags (0 to quit) :");
return;
} else if (j <= NUM_MOB_FLAGS) {
TOGGLE_BIT_AR(MOB_FLAGS(OLC_MOB(d)), (i - 1));
}
medit_disp_mob_flags(d);
return;
@ -1008,7 +1058,7 @@ void medit_parse(struct descriptor_data *d, char *arg)
case MEDIT_ALIGNMENT:
GET_ALIGNMENT(OLC_MOB(d)) = LIMIT(i, -1000, 1000);
medit_disp_stats_menu(d);
medit_disp_stats_menu(d);
return;
case MEDIT_COPY:

View file

@ -21,6 +21,7 @@
#include "boards.h"
#include "improved-edit.h"
#include "oasis.h"
#include "class.h"
#include "dg_scripts.h" /* for trigedit_string_cleanup */
#include "modify.h"
#include "quest.h"
@ -278,7 +279,7 @@ ACMD(do_skillset)
struct char_data *vict;
char name[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH], helpbuf[MAX_STRING_LENGTH];
int skill, value, i, qend;
int skill, value, i, qend, pc, pl;
argument = one_argument(argument, name);
@ -302,6 +303,8 @@ ACMD(do_skillset)
return;
}
skip_spaces(&argument);
pc = GET_CLASS(vict);
pl = GET_LEVEL(vict);
/* If there is no chars in argument */
if (!*argument) {
@ -347,6 +350,13 @@ ACMD(do_skillset)
send_to_char(ch, "You can't set NPC skills.\r\n");
return;
}
if ((spell_info[skill].min_level[(pc)] >= LVL_IMMORT) && (pl < LVL_IMMORT)) {
send_to_char(ch, "%s cannot be learned by mortals.\r\n", spell_info[skill].name);
return;
} else if (spell_info[skill].min_level[(pc)] > pl) {
send_to_char(ch, "%s is a level %d %s.\r\n", GET_NAME(vict), pl, pc_class_types[pc]);
send_to_char(ch, "The minimum level for %s is %d for %ss.\r\n", spell_info[skill].name, spell_info[skill].min_level[(pc)], pc_class_types[pc]);
}
/* find_skill_num() guarantees a valid spell_info[] index, or -1, and we
* checked for the -1 above so we are safe here. */

View file

@ -183,7 +183,7 @@ int find_skill_num(char *name)
/* This function is the very heart of the entire magic system. All invocations
* of all types of magic -- objects, spoken and unspoken PC and NPC spells, the
* works -- all come through this function eventually. This is also the entry
* works -- all come through this function eventually. This is also the entry
* point for non-spoken or unrestricted spells. Spellnum 0 is legal but silently
* ignored here, to make callers simpler. */
int call_magic(struct char_data *caster, struct char_data *cvict,
@ -429,8 +429,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
}
/* cast_spell is used generically to cast any spoken spell, assuming we already
* have the target char/obj and spell number. It checks all restrictions,
* prints the words, etc. Entry point for NPC casts. Recommended entry point
* have the target char/obj and spell number. It checks all restrictions,
* prints the words, etc. Entry point for NPC casts. Recommended entry point
* for spells cast by NPCs via specprocs. */
int cast_spell(struct char_data *ch, struct char_data *tch,
struct obj_data *tobj, int spellnum)
@ -512,12 +512,12 @@ ACMD(do_cast)
}
t = strtok(NULL, "\0");
skip_spaces(&s);
skip_spaces(&s);
/* spellnum = search_block(s, spells, 0); */
spellnum = find_skill_num(s);
if ((spellnum < 1) || (spellnum > MAX_SPELLS) || !*s) {
if ((spellnum < 1) || (spellnum > MAX_SPELLS) || !*s) {
send_to_char(ch, "Cast what?!?\r\n");
return;
}
@ -710,8 +710,8 @@ void unused_spell(int spl)
* charm, curse), or is otherwise nasty.
* routines: A list of magic routines which are associated with this spell
* if the spell uses spell templates. Also joined with bitwise OR ('|').
* See the documentation for a more detailed description of these fields. You
* only need a spello() call to define a new spell; to decide who gets to use
* See the documentation for a more detailed description of these fields. You
* only need a spello() call to define a new spell; to decide who gets to use
* a spell or skill, look in class.c. -JE */
void mag_assign_spells(void)
{
@ -834,6 +834,10 @@ void mag_assign_spells(void)
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE,
NULL);
spello(SPELL_FLY, "fly", 40, 20, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS,
"You drift slowly to the ground.");
spello(SPELL_GROUP_HEAL, "group heal", 80, 60, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS,
NULL);
@ -936,7 +940,7 @@ void mag_assign_spells(void)
NULL);
/* Declaration of skills - this actually doesn't do anything except set it up
* so that immortals can use these skills by default. The min level to use
* so that immortals can use these skills by default. The min level to use
* the skill for other classes is set up in class.c. */
skillo(SKILL_BACKSTAB, "backstab");
skillo(SKILL_BASH, "bash");

View file

@ -1,13 +1,13 @@
/**
* @file spells.h
* Constants and function prototypes for the spell system.
*
*
* Part of the core tbaMUD source code distribution, which is a derivative
* of, and continuation of, CircleMUD.
*
* All rights reserved. See license for complete information.
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.
*
* All rights reserved. See license for complete information.
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.
*/
#ifndef _SPELLS_H_
#define _SPELLS_H_
@ -82,16 +82,17 @@
#define SPELL_WORD_OF_RECALL 42 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_REMOVE_POISON 43 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_SENSE_LIFE 44 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_ANIMATE_DEAD 45 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_DISPEL_GOOD 46 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_GROUP_ARMOR 47 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_GROUP_HEAL 48 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_GROUP_RECALL 49 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_ANIMATE_DEAD 45 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_DISPEL_GOOD 46 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_GROUP_ARMOR 47 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_GROUP_HEAL 48 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_GROUP_RECALL 49 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_INFRAVISION 50 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_WATERWALK 51 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_IDENTIFY 52 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_IDENTIFY 52 /* Reserved Skill[] DO NOT CHANGE */
#define SPELL_FLY 53 /* Reserved Skill[] DO NOT CHANGE */
/** Total Number of defined spells */
#define NUM_SPELLS 52
#define NUM_SPELLS 53
/* Insert new spells here, up to MAX_SPELLS */
#define MAX_SPELLS 130
@ -109,13 +110,13 @@
#define SKILL_TRACK 140 /* Reserved Skill[] DO NOT CHANGE */
/* New skills may be added here up to MAX_SKILLS (200) */
/* NON-PLAYER AND OBJECT SPELLS AND SKILLS: The practice levels for the spells
* and skills below are _not_ recorded in the players file; therefore, the
* intended use is for spells and skills associated with objects (such as
/* NON-PLAYER AND OBJECT SPELLS AND SKILLS: The practice levels for the spells
* and skills below are _not_ recorded in the players file; therefore, the
* intended use is for spells and skills associated with objects (such as
* SPELL_IDENTIFY used with scrolls of identify) or non-players (such as NPC
* only spells). */
/* To make an affect induced by dg_affect look correct on 'stat' we need to
/* To make an affect induced by dg_affect look correct on 'stat' we need to
* define it with a 'spellname'. */
#define SPELL_DG_AFFECT 298

View file

@ -21,6 +21,7 @@
#include "spells.h"
#include "handler.h"
#include "interpreter.h"
#include "class.h"
/** Aportable random number function.
@ -1471,3 +1472,12 @@ void new_affect(struct affected_type *af)
for (i=0; i<AF_ARRAY_MAX; i++) af->bitvector[i]=0;
}
/* Handy function to get class ID number by name (abbreviations allowed) */
int get_class_by_name(char *classname)
{
int i;
for (i=0; i<NUM_CLASSES; i++)
if (is_abbrev(classname, pc_class_types[i])) return(i);
return (-1);
}

View file

@ -67,6 +67,7 @@ IDXTYPE atoidx( const char *str_to_conv );
char *strfrmt(char *str, int w, int h, int justify, int hpad, int vpad);
char *strpaste(char *str1, char *str2, char *joiner);
void new_affect(struct affected_type *af);
int get_class_by_name(char *classname);
/* Public functions made available form weather.c */
void weather_and_time(int mode);