/* ************************************************************************ * file: spec_procs.c , Special module. Part of DIKUMUD * * Usage: Procedures handling special procedures for object/room/mobile * * Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * ************************************************************************* */ #include "os.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" #include "spells.h" #include "limits.h" #include "prototypes.h" /* external vars */ extern struct room_data *world; extern struct char_data *character_list; extern struct descriptor_data *descriptor_list; extern struct index_data *obj_index; extern struct time_info_data time_info; /* extern procedures */ void hit (struct char_data *ch, struct char_data *victim, int type); void gain_exp (struct char_data *ch, int gain); char *str_dup (char *source); void cast_burning_hands (int level, struct char_data *ch, char *arg, int type, struct char_data *victim, struct obj_data *tar_obj); void cast_chill_touch (int level, struct char_data *ch, char *arg, int type, struct char_data *victim, struct obj_data *tar_obj); void cast_colour_spray (int level, struct char_data *ch, char *arg, int type, struct char_data *victim, struct obj_data *tar_obj); void cast_energy_drain (int level, struct char_data *ch, char *arg, int type, struct char_data *victim, struct obj_data *tar_obj); void cast_fireball (int level, struct char_data *ch, char *arg, int type, struct char_data *victim, struct obj_data *tar_obj); void cast_magic_missile (int level, struct char_data *ch, char *arg, int type, struct char_data *victim, struct obj_data *tar_obj); void cast_blindness (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); void cast_curse (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); void cast_sleep (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); /* Dragon breath .. */ void cast_fire_breath (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); void cast_frost_breath (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); void cast_acid_breath (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); void cast_gas_breath (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); void cast_lightning_breath (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); /* Data declarations */ struct social_type { char *cmd; int next_line; }; /* ******************************************************************** * Special procedures for rooms * ******************************************************************** */ char *how_good (int percent) { static char buf[256]; if (percent == 0) strcpy (buf, " (not learned)"); else if (percent <= 10) strcpy (buf, " (awful)"); else if (percent <= 20) strcpy (buf, " (bad)"); else if (percent <= 40) strcpy (buf, " (poor)"); else if (percent <= 55) strcpy (buf, " (average)"); else if (percent <= 70) strcpy (buf, " (fair)"); else if (percent <= 80) strcpy (buf, " (good)"); else if (percent <= 85) strcpy (buf, " (very good)"); else strcpy (buf, " (Superb)"); return (buf); } int guild (struct char_data *ch, int cmd, char *arg) { char arg1[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; int number, i, percent; extern char *spells[]; extern struct spell_info_type spell_info[MAX_SPL_LIST]; extern struct int_app_type int_app[26]; static char *w_skills[] = { "kick", /* No. 50 */ "bash", "rescue", "\n" }; static char *t_skills[] = { "sneak", /* No. 45 */ "hide", "steal", "backstab", "pick", "\n" }; if ((cmd != 164) && (cmd != 170)) return (FALSE); for (; *arg == ' '; arg++); switch (GET_CLASS (ch)) { case CLASS_MAGIC_USER:{ if (!*arg) { sprintf (buf, "You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn); send_to_char (buf, ch); send_to_char ("You can practise any of these spells:\n\r", ch); for (i = 0; *spells[i] != '\n'; i++) if (spell_info[i + 1].spell_pointer && (spell_info[i + 1].min_level_magic <= GET_LEVEL (ch))) { send_to_char (spells[i], ch); send_to_char (how_good (ch->skills[i + 1].learned), ch); send_to_char ("\n\r", ch); } return (TRUE); } number = old_search_block (arg, 0, strlen (arg), spells, FALSE); if (number == -1) { send_to_char ("You do not know of this spell...\n\r", ch); return (TRUE); } if (GET_LEVEL (ch) < spell_info[number].min_level_magic) { send_to_char ("You do not know of this spell...\n\r", ch); return (TRUE); } if (ch->specials.spells_to_learn <= 0) { send_to_char ("You do not seem to be able to practice now.\n\r", ch); return (TRUE); } if (ch->skills[number].learned >= 95) { send_to_char ("You are already learned in this area.\n\r", ch); return (TRUE); } send_to_char ("You Practice for a while...\n\r", ch); ch->specials.spells_to_learn--; percent = ch->skills[number].learned + MAX (25, int_app[GET_INT (ch)].learn); ch->skills[number].learned = MIN (95, percent); if (ch->skills[number].learned >= 95) { send_to_char ("You are now learned in this area.\n\r", ch); return (TRUE); } } break; case CLASS_THIEF:{ if (!*arg) { sprintf (buf, "You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn); send_to_char (buf, ch); send_to_char ("You can practise any of these skills:\n\r", ch); for (i = 0; *t_skills[i] != '\n'; i++) { send_to_char (t_skills[i], ch); send_to_char (how_good (ch->skills[i + 45].learned), ch); send_to_char ("\n\r", ch); } return (TRUE); } number = search_block (arg, t_skills, FALSE); if (number == -1) { send_to_char ("You do not know of this spell...\n\r", ch); return (TRUE); } if (ch->specials.spells_to_learn <= 0) { send_to_char ("You do not seem to be able to practice now.\n\r", ch); return (TRUE); } if (ch->skills[number + SKILL_SNEAK].learned >= 85) { send_to_char ("You are already learned in this area.\n\r", ch); return (TRUE); } send_to_char ("You Practice for a while...\n\r", ch); ch->specials.spells_to_learn--; percent = ch->skills[number + SKILL_SNEAK].learned + MIN (int_app[GET_INT (ch)].learn, 12); ch->skills[number + SKILL_SNEAK].learned = MIN (85, percent); if (ch->skills[number + SKILL_SNEAK].learned >= 85) { send_to_char ("You are now learned in this area.\n\r", ch); return (TRUE); } } break; case CLASS_CLERIC:{ if (!*arg) { sprintf (buf, "You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn); send_to_char (buf, ch); send_to_char ("You can practise any of these spells:\n\r", ch); for (i = 0; *spells[i] != '\n'; i++) if (spell_info[i + 1].spell_pointer && (spell_info[i + 1].min_level_cleric <= GET_LEVEL (ch))) { send_to_char (spells[i], ch); send_to_char (how_good (ch->skills[i + 1].learned), ch); send_to_char ("\n\r", ch); } return (TRUE); } number = old_search_block (arg, 0, strlen (arg), spells, FALSE); if (number == -1) { send_to_char ("You do not know of this spell...\n\r", ch); return (TRUE); } if (GET_LEVEL (ch) < spell_info[number].min_level_cleric) { send_to_char ("You do not know of this spell...\n\r", ch); return (TRUE); } if (ch->specials.spells_to_learn <= 0) { send_to_char ("You do not seem to be able to practice now.\n\r", ch); return (TRUE); } if (ch->skills[number].learned >= 95) { send_to_char ("You are already learned in this area.\n\r", ch); return (TRUE); } send_to_char ("You Practice for a while...\n\r", ch); ch->specials.spells_to_learn--; percent = ch->skills[number].learned + MAX (25, int_app[GET_INT (ch)].learn); ch->skills[number].learned = MIN (95, percent); if (ch->skills[number].learned >= 95) { send_to_char ("You are now learned in this area.\n\r", ch); return (TRUE); } } break; case CLASS_WARRIOR:{ if (!*arg) { sprintf (buf, "You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn); send_to_char (buf, ch); send_to_char ("You can practise any of these skills:\n\r", ch); for (i = 0; *w_skills[i] != '\n'; i++) { send_to_char (w_skills[i], ch); send_to_char (how_good (ch->skills[i + SKILL_KICK].learned), ch); send_to_char ("\n\r", ch); } return (TRUE); } number = search_block (arg, w_skills, FALSE); if (number == -1) { send_to_char ("You do not have ability to practise this skill!\n\r", ch); return (TRUE); } if (ch->specials.spells_to_learn <= 0) { send_to_char ("You do not seem to be able to practice now.\n\r", ch); return (TRUE); } if (ch->skills[number + SKILL_KICK].learned >= 80) { send_to_char ("You are already learned in this area.\n\r", ch); return (TRUE); } send_to_char ("You Practice for a while...\n\r", ch); ch->specials.spells_to_learn--; percent = ch->skills[number + SKILL_KICK].learned + MIN (12, int_app[GET_INT (ch)].learn); ch->skills[number + SKILL_KICK].learned = MIN (80, percent); if (ch->skills[number + SKILL_KICK].learned >= 80) { send_to_char ("You are now learned in this area.\n\r", ch); return (TRUE); } } break; } return FALSE; } int dump (struct char_data *ch, int cmd, char *arg) { struct obj_data *k; char buf[100]; struct char_data *tmp_char; int value = 0; void do_drop (struct char_data *ch, char *argument, int cmd); char *fname (char *namelist); for (k = world[ch->in_room].contents; k; k = world[ch->in_room].contents) { sprintf (buf, "The %s vanish in a puff of smoke.\n\r", fname (k->name)); for (tmp_char = world[ch->in_room].people; tmp_char; tmp_char = tmp_char->next_in_room) if (CAN_SEE_OBJ (tmp_char, k)) send_to_char (buf, tmp_char); extract_obj (k); } if (cmd != 60) return (FALSE); do_drop (ch, arg, cmd); value = 0; for (k = world[ch->in_room].contents; k; k = world[ch->in_room].contents) { sprintf (buf, "The %s vanish in a puff of smoke.\n\r", fname (k->name)); for (tmp_char = world[ch->in_room].people; tmp_char; tmp_char = tmp_char->next_in_room) if (CAN_SEE_OBJ (tmp_char, k)) send_to_char (buf, tmp_char); value += MAX (1, MIN (50, k->obj_flags.cost / 10)); extract_obj (k); } if (value) { act ("You are awarded for outstanding performance.", FALSE, ch, 0, 0, TO_CHAR); act ("$n has been awarded for being a good citizen.", TRUE, ch, 0, 0, TO_ROOM); if (GET_LEVEL (ch) < 3) gain_exp (ch, value); else GET_GOLD (ch) += value; } return TRUE; } int mayor (struct char_data *ch, int cmd, char *arg) { static char open_path[] = "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S."; static char close_path[] = "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S."; /* const struct social_type open_path[] = { {"G",0} }; static void *thingy = 0; static int cur_line = 0; for (i=0; i < 1; i++) { if (*(open_path[cur_line].cmd) == '!') { i++; exec_social(ch, (open_path[cur_line].cmd)+1, open_path[cur_line].next_line, &cur_line, &thingy); } else { exec_social(ch, open_path[cur_line].cmd, open_path[cur_line].next_line, &cur_line, &thingy); } */ static char *path; static int index; static bool move = FALSE; void do_move (struct char_data *ch, char *argument, int cmd); void do_open (struct char_data *ch, char *argument, int cmd); void do_lock (struct char_data *ch, char *argument, int cmd); void do_unlock (struct char_data *ch, char *argument, int cmd); void do_close (struct char_data *ch, char *argument, int cmd); if (!move) { if (time_info.hours == 6) { move = TRUE; path = open_path; index = 0; } else if (time_info.hours == 20) { move = TRUE; path = close_path; index = 0; } } if (cmd || !move || (GET_POS (ch) < POSITION_SLEEPING) || (GET_POS (ch) == POSITION_FIGHTING)) return FALSE; switch (path[index]) { case '0': case '1': case '2': case '3': do_move (ch, "", path[index] - '0' + 1); break; case 'W': GET_POS (ch) = POSITION_STANDING; act ("$n awakens and groans loudly.", FALSE, ch, 0, 0, TO_ROOM); break; case 'S': GET_POS (ch) = POSITION_SLEEPING; act ("$n lies down and instantly falls asleep.", FALSE, ch, 0, 0, TO_ROOM); break; case 'a': act ("$n says 'Hello Honey!'", FALSE, ch, 0, 0, TO_ROOM); act ("$n smirks.", FALSE, ch, 0, 0, TO_ROOM); break; case 'b': act ("$n says 'What a view! I must get something done about that dump!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'c': act ("$n says 'Vandals! Youngsters nowadays have no respect for anything!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'd': act ("$n says 'Good day, citizens!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'e': act ("$n says 'I hereby declare the bazaar open!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'E': act ("$n says 'I hereby declare Midgaard closed!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'O': do_unlock (ch, "gate", 0); do_open (ch, "gate", 0); break; case 'C': do_close (ch, "gate", 0); do_lock (ch, "gate", 0); break; case '.': move = FALSE; break; } index++; return FALSE; } /* ******************************************************************** * General special procedures for mobiles * ******************************************************************** */ /* SOCIAL GENERAL PROCEDURES If first letter of the command is '!' this will mean that the following command will be executed immediately. "G",n : Sets next line to n "g",n : Sets next line relative to n, fx. line+=n "m<dir>",n : move to <dir>, <dir> is 0,1,2,3,4 or 5 "w",n : Wake up and set standing (if possible) "c<txt>",n : Look for a person named <txt> in the room "o<txt>",n : Look for an object named <txt> in the room "r<int>",n : Test if the npc in room number <int>? "s",n : Go to sleep, return false if can't go sleep "e<txt>",n : echo <txt> to the room, can use $o/$p/$N depending on contents of the **thing "E<txt>",n : Send <txt> to person pointed to by thing "B<txt>",n : Send <txt> to room, except to thing "?<num>",n : <num> in [1..99]. A random chance of <num>% success rate. Will as usual advance one line upon sucess, and change relative n lines upon failure. "O<txt>",n : Open <txt> if in sight. "C<txt>",n : Close <txt> if in sight. "L<txt>",n : Lock <txt> if in sight. "U<txt>",n : Unlock <txt> if in sight. */ /* Execute a social command. */ void exec_social (struct char_data *npc, char *cmd, int next_line, int *cur_line, void **thing) { bool ok; void do_move (struct char_data *ch, char *argument, int cmd); void do_open (struct char_data *ch, char *argument, int cmd); void do_lock (struct char_data *ch, char *argument, int cmd); void do_unlock (struct char_data *ch, char *argument, int cmd); void do_close (struct char_data *ch, char *argument, int cmd); if (GET_POS (npc) == POSITION_FIGHTING) return; ok = TRUE; switch (*cmd) { case 'G': *cur_line = next_line; return; case 'g': *cur_line += next_line; return; case 'e': act (cmd + 1, FALSE, npc, *thing, *thing, TO_ROOM); break; case 'E': act (cmd + 1, FALSE, npc, 0, *thing, TO_VICT); break; case 'B': act (cmd + 1, FALSE, npc, 0, *thing, TO_NOTVICT); break; case 'm': do_move (npc, "", *(cmd + 1) - '0' + 1); break; case 'w': if (GET_POS (npc) != POSITION_SLEEPING) ok = FALSE; else GET_POS (npc) = POSITION_STANDING; break; case 's': if (GET_POS (npc) <= POSITION_SLEEPING) ok = FALSE; else GET_POS (npc) = POSITION_SLEEPING; break; case 'c': /* Find char in room */ *thing = get_char_room_vis (npc, cmd + 1); ok = (*thing != 0); break; case 'o': /* Find object in room */ *thing = get_obj_in_list_vis (npc, cmd + 1, world[npc->in_room].contents); ok = (*thing != 0); break; case 'r': /* Test if in a certain room */ ok = (npc->in_room == atoi (cmd + 1)); break; case 'O': /* Open something */ do_open (npc, cmd + 1, 0); break; case 'C': /* Close something */ do_close (npc, cmd + 1, 0); break; case 'L': /* Lock something */ do_lock (npc, cmd + 1, 0); break; case 'U': /* UnLock something */ do_unlock (npc, cmd + 1, 0); break; case '?': /* Test a random number */ if (atoi (cmd + 1) <= number (1, 100)) ok = FALSE; break; default: break; } /* End Switch */ if (ok) (*cur_line)++; else (*cur_line) += next_line; } void npc_steal (struct char_data *ch, struct char_data *victim) { int gold; if (IS_NPC (victim)) return; if (GET_LEVEL (victim) > 20) return; if (AWAKE (victim) && (number (0, GET_LEVEL (ch)) == 0)) { act ("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, victim, TO_VICT); act ("$n tries to steal gold from $N.", TRUE, ch, 0, victim, TO_NOTVICT); } else { /* Steal some gold coins */ gold = (int) ((GET_GOLD (victim) * number (1, 10)) / 100); if (gold > 0) { GET_GOLD (ch) += gold; GET_GOLD (victim) -= gold; } } } int snake (struct char_data *ch, int cmd, char *arg) { void cast_poison (int level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj); if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (ch->specials.fighting && (ch->specials.fighting->in_room == ch->in_room) && (number (0, 32 - GET_LEVEL (ch)) == 0)) { act ("$n bites $N!", 1, ch, 0, ch->specials.fighting, TO_NOTVICT); act ("$n bites you!", 1, ch, 0, ch->specials.fighting, TO_VICT); cast_poison (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, ch->specials.fighting, 0); return TRUE; } return FALSE; } int thief (struct char_data *ch, int cmd, char *arg) { struct char_data *cons; if (cmd) return FALSE; if (GET_POS (ch) != POSITION_STANDING) return FALSE; for (cons = world[ch->in_room].people; cons; cons = cons->next_in_room) if ((!IS_NPC (cons)) && (GET_LEVEL (cons) < 21) && (number (1, 5) == 1)) npc_steal (ch, cons); return TRUE; } int magic_user (struct char_data *ch, int cmd, char *arg) { struct char_data *vict; if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (!ch->specials.fighting) return FALSE; /* Find a dude to do evil things upon ! */ for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) if (vict->specials.fighting == ch && number (0, 2) == 0) break; if (!vict) return FALSE; if ((vict != ch->specials.fighting) && (GET_LEVEL (ch) > 13) && (number (0, 7) == 0)) { act ("$n utters the words 'dilan oso'.", 1, ch, 0, 0, TO_ROOM); cast_sleep (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } if ((GET_LEVEL (ch) > 12) && (number (0, 6) == 0)) { act ("$n utters the words 'gharia miwi'.", 1, ch, 0, 0, TO_ROOM); cast_curse (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } if ((GET_LEVEL (ch) > 7) && (number (0, 5) == 0)) { act ("$n utters the words 'koholian dia'.", 1, ch, 0, 0, TO_ROOM); cast_blindness (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } if ((GET_LEVEL (ch) > 12) && (number (0, 8) == 0) && IS_EVIL (ch)) { act ("$n utters the words 'ib er dranker'.", 1, ch, 0, 0, TO_ROOM); cast_energy_drain (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } switch (GET_LEVEL (ch)) { case 1: case 2: case 3: case 4: act ("$n utters the words 'hahili duvini'.", 1, ch, 0, 0, TO_ROOM); cast_magic_missile (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); break; case 5: case 6: case 7: case 8: act ("$n utters the words 'grynt oef'.", 1, ch, 0, 0, TO_ROOM); cast_burning_hands (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); break; case 9: case 10: act ("$n utters the words 'sjulk divi'.", 1, ch, 0, 0, TO_ROOM); cast_lightning_bolt (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); break; case 11: case 12: case 13: case 14: act ("$n utters the words 'nasson hof'.", 1, ch, 0, 0, TO_ROOM); cast_colour_spray (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); break; default: act ("$n utters the words 'tuborg'.", 1, ch, 0, 0, TO_ROOM); cast_fireball (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); break; } return TRUE; } int bat_red (struct char_data *ch, int cmd, char *arg) { struct char_data *vict; if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (!ch->specials.fighting) return FALSE; /* Find a dude to do evil things upon ! */ for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) if (vict->specials.fighting == ch && number (0, 2) == 0) break; if (!vict) return FALSE; act ("$n breathes fire.", 1, ch, 0, 0, TO_ROOM); cast_fire_breath (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } int bat_white (struct char_data *ch, int cmd, char *arg) { struct char_data *vict; if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (!ch->specials.fighting) return FALSE; /* Find a dude to do evil things upon ! */ for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) if (vict->specials.fighting == ch && number (0, 2) == 0) break; if (!vict) return FALSE; act ("$n breathes frost.", 1, ch, 0, 0, TO_ROOM); cast_frost_breath (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } int bat_black (struct char_data *ch, int cmd, char *arg) { struct char_data *vict; if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (!ch->specials.fighting) return FALSE; /* Find a dude to do evil things upon ! */ for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) if (vict->specials.fighting == ch && number (0, 2) == 0) break; if (!vict) return FALSE; act ("$n breathes acid.", 1, ch, 0, 0, TO_ROOM); cast_acid_breath (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } int bat_blue (struct char_data *ch, int cmd, char *arg) { struct char_data *vict; if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (!ch->specials.fighting) return FALSE; /* Find a dude to do evil things upon ! */ for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) if (vict->specials.fighting == ch && number (0, 2) == 0) break; if (!vict) return FALSE; act ("$n breathes lightning.", 1, ch, 0, 0, TO_ROOM); cast_lightning_breath (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, vict, 0); return TRUE; } int bat_green (struct char_data *ch, int cmd, char *arg) { if (cmd) return FALSE; if (GET_POS (ch) != POSITION_FIGHTING) return FALSE; if (!ch->specials.fighting) return FALSE; if (number (0, 3) != 0) return FALSE; act ("$n breathes gas.", 1, ch, 0, 0, TO_ROOM); cast_gas_breath (GET_LEVEL (ch), ch, "", SPELL_TYPE_SPELL, 0, 0); return TRUE; } /* ******************************************************************** * Special procedures for mobiles * ******************************************************************** */ int guild_guard (struct char_data *ch, int cmd, char *arg) { char buf[256], buf2[256]; if (cmd > 6 || cmd < 1) return FALSE; strcpy (buf, "The guard humiliates you, and block your way.\n\r"); strcpy (buf2, "The guard humiliates $n, and blocks $s way."); if ((ch->in_room == real_room (3017)) && (cmd == 3)) { if (GET_CLASS (ch) != CLASS_MAGIC_USER) { act (buf2, FALSE, ch, 0, 0, TO_ROOM); send_to_char (buf, ch); return TRUE; } } else if ((ch->in_room == real_room (3004)) && (cmd == 1)) { if (GET_CLASS (ch) != CLASS_CLERIC) { act (buf2, FALSE, ch, 0, 0, TO_ROOM); send_to_char (buf, ch); return TRUE; } } else if ((ch->in_room == real_room (3027)) && (cmd == 2)) { if (GET_CLASS (ch) != CLASS_THIEF) { act (buf2, FALSE, ch, 0, 0, TO_ROOM); send_to_char (buf, ch); return TRUE; } } else if ((ch->in_room == real_room (3021)) && (cmd == 2)) { if (GET_CLASS (ch) != CLASS_WARRIOR) { act (buf2, FALSE, ch, 0, 0, TO_ROOM); send_to_char (buf, ch); return TRUE; } } return FALSE; } int puff (struct char_data *ch, int cmd, char *arg) { void do_say (struct char_data *ch, char *argument, int cmd); if (cmd) return (0); switch (number (0, 60)) { case 0: do_say (ch, "My god! It's full of stars!", 0); return (1); case 1: do_say (ch, "How'd all those fish get up here?", 0); return (1); case 2: do_say (ch, "I'm a very female dragon.", 0); return (1); case 3: do_say (ch, "I've got a peaceful, easy feeling.", 0); return (1); default: return (0); } } int fido (struct char_data *ch, int cmd, char *arg) { struct obj_data *i, *temp, *next_obj; if (cmd || !AWAKE (ch)) return (FALSE); for (i = world[ch->in_room].contents; i; i = i->next_content) { if (GET_ITEM_TYPE (i) == ITEM_CONTAINER && i->obj_flags.value[3]) { act ("$n savagely devour a corpse.", FALSE, ch, 0, 0, TO_ROOM); for (temp = i->contains; temp; temp = next_obj) { next_obj = temp->next_content; obj_from_obj (temp); obj_to_room (temp, ch->in_room); } extract_obj (i); return (TRUE); } } return (FALSE); } int janitor (struct char_data *ch, int cmd, char *arg) { struct obj_data *i, *temp, *next_obj; if (cmd || !AWAKE (ch)) return (FALSE); for (i = world[ch->in_room].contents; i; i = i->next_content) { if (IS_SET (i->obj_flags.wear_flags, ITEM_TAKE) && ((i->obj_flags.type_flag == ITEM_DRINKCON) || (i->obj_flags.cost <= 10))) { act ("$n picks up some trash.", FALSE, ch, 0, 0, TO_ROOM); obj_from_room (i); obj_to_char (i, ch); return (TRUE); } } return (FALSE); } int cityguard (struct char_data *ch, int cmd, char *arg) { struct char_data *tch, *evil; int max_evil; if (cmd || !AWAKE (ch) || (GET_POS (ch) == POSITION_FIGHTING)) return (FALSE); max_evil = 300; evil = 0; for (tch = world[ch->in_room].people; tch; tch = tch->next_in_room) { if (tch->specials.fighting) { if ((GET_ALIGNMENT (tch) < max_evil) && (IS_NPC (tch) || IS_NPC (tch->specials.fighting))) { max_evil = GET_ALIGNMENT (tch); evil = tch; } } } if (evil && !IS_EVIL (evil->specials.fighting)) { act ("$n screams 'PROTECT THE INNOCENT! BANZAI!!! CHARGE!!! ARARARAGGGHH!'", FALSE, ch, 0, 0, TO_ROOM); hit (ch, evil, TYPE_UNDEFINED); return (TRUE); } return (FALSE); } int pet_shops (struct char_data *ch, int cmd, char *arg) { char buf[MAX_STRING_LENGTH], pet_name[256]; int pet_room; struct char_data *pet; pet_room = ch->in_room + 1; if (cmd == 59) { /* List */ send_to_char ("Available pets are:\n\r", ch); for (pet = world[pet_room].people; pet; pet = pet->next_in_room) { sprintf (buf, "%8d - %s\n\r", 3 * GET_EXP (pet), pet->player.short_descr); send_to_char (buf, ch); } return (TRUE); } else if (cmd == 56) { /* Buy */ arg = one_argument (arg, buf); arg = one_argument (arg, pet_name); /* Pet_Name is for later use when I feel like it */ if (!(pet = get_char_room (buf, pet_room))) { send_to_char ("There is no such pet!\n\r", ch); return (TRUE); } if (GET_GOLD (ch) < (GET_EXP (pet) * 3)) { send_to_char ("You don't have enough gold!\n\r", ch); return (TRUE); } GET_GOLD (ch) -= GET_EXP (pet) * 3; pet = read_mobile (pet->nr, REAL); GET_EXP (pet) = 0; SET_BIT (pet->specials.affected_by, AFF_CHARM); if (*pet_name) { sprintf (buf, "%s %s", pet->player.name, pet_name); free (pet->player.name); pet->player.name = str_dup (buf); sprintf (buf, "%sA small sign on a chain around the neck says 'My Name is %s'\n\r", pet->player.description, pet_name); free (pet->player.description); pet->player.description = str_dup (buf); } char_to_room (pet, ch->in_room); add_follower (pet, ch); /* Be certain that pet's can't get/carry/use/weild/wear items */ IS_CARRYING_W (pet) = 1000; IS_CARRYING_N (pet) = 100; send_to_char ("May you enjoy your pet.\n\r", ch); act ("$n bought $N as a pet.", FALSE, ch, 0, pet, TO_ROOM); return (TRUE); } /* All commands except list and buy */ return (FALSE); } /* Idea of the LockSmith is functionally similar to the Pet Shop */ /* The problem here is that each key must somehow be associated */ /* with a certain player. My idea is that the players name will */ /* appear as the another Extra description keyword, prefixed */ /* by the words 'item_for_' and followed by the player name. */ /* The (keys) must all be stored in a room which is (virtually) */ /* adjacent to the room of the lock smith. */ int pray_for_items (struct char_data *ch, int cmd, char *arg) { char buf[256]; int key_room, gold; bool found; struct obj_data *tmp_obj, *obj; struct extra_descr_data *ext; if (cmd != 176) /* You must pray to get the stuff */ return FALSE; key_room = 1 + ch->in_room; strcpy (buf, "item_for_"); strcat (buf, GET_NAME (ch)); gold = 0; found = FALSE; for (tmp_obj = world[key_room].contents; tmp_obj; tmp_obj = tmp_obj->next_content) for (ext = tmp_obj->ex_description; ext; ext = ext->next) if (str_cmp (buf, ext->keyword) == 0) { if (gold == 0) { gold = 1; act ("$n kneels and at the altar and chants a prayer to Odin.", FALSE, ch, 0, 0, TO_ROOM); act ("You notice a faint light in Odin's eye.", FALSE, ch, 0, 0, TO_CHAR); } obj = read_object (tmp_obj->item_number, REAL); obj_to_room (obj, ch->in_room); act ("$p slowly fades into existence.", FALSE, ch, obj, 0, TO_ROOM); act ("$p slowly fades into existence.", FALSE, ch, obj, 0, TO_CHAR); gold += obj->obj_flags.cost; found = TRUE; } if (found) { GET_GOLD (ch) -= gold; GET_GOLD (ch) = MAX (0, GET_GOLD (ch)); return TRUE; } return FALSE; } int worm_ritual (struct char_data *ch, int cmd, char *arg) { struct obj_data *scroll, *herbs, *blood; struct char_data *tmpch; char buf[MAX_INPUT_LENGTH]; bool found, equipped = FALSE; int room; static int scroll_nr = -1, herbs_nr = -1, blood_nr = -1, to_room = -1; if (scroll_nr < 1) { scroll_nr = real_object (5012); herbs_nr = real_object (5002); blood_nr = real_object (5003); to_room = real_room (5040); } if (cmd != 207) return FALSE; arg = one_argument (arg, buf); if (!(scroll = get_obj_in_list_vis (ch, buf, ch->carrying))) { scroll = ch->equipment[HOLD]; equipped = TRUE; } /* which scroll */ found = (scroll && (scroll->item_number == scroll_nr)); if (!found) return FALSE; act ("$n recites $p.", TRUE, ch, scroll, 0, TO_ROOM); act ("You recite $p which dissolves.", FALSE, ch, scroll, 0, TO_CHAR); room = ch->in_room; blood = get_obj_in_list_num (blood_nr, world[room].contents); herbs = get_obj_in_list_num (herbs_nr, world[room].contents); if (!blood || !herbs || (blood->obj_flags.value[1] < 2)) return TRUE; act ("$p dissolves into thin air.", TRUE, ch, herbs, 0, TO_ROOM); act ("$p dissolves into thin air.", TRUE, ch, herbs, 0, TO_CHAR); act ("$p is emptied from blood.", FALSE, ch, blood, 0, TO_ROOM); act ("$p is emptied from blood.", FALSE, ch, blood, 0, TO_CHAR); obj_from_room (herbs); extract_obj (herbs); /* herbs dissapear */ blood->obj_flags.value[1] = 0; /* empty for blood */ blood->obj_flags.weight -= 2; /* correct weight */ if (equipped) unequip_char (ch, HOLD); extract_obj (scroll); act ("You feel yanked downwards.....", FALSE, ch, 0, 0, TO_ROOM); act ("You feel yanked downwards.....", FALSE, ch, 0, 0, TO_CHAR); /* Move'em */ tmpch = world[room].people; while (world[room].people) { char_from_room (tmpch); char_to_room (tmpch, to_room); tmpch = world[room].people; } return TRUE; } /* ******************************************************************** * Special procedures for objects * ******************************************************************** */ #define CHAL_ACT \ "You are torn out of reality!\n\r\ You roll and tumble through endless voids for what seems like eternity...\n\r\ \n\r\ After a time, a new reality comes into focus... you are elsewhere.\n\r" int chalice (struct char_data *ch, int cmd, char *arg) { /* 222 is the normal chalice, 223 is chalice-on-altar */ struct obj_data *chalice; char buf1[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH]; static int chl = -1, achl = -1; if (chl < 1) { chl = real_object (222); achl = real_object (223); } switch (cmd) { case 10: /* get */ if (!(chalice = get_obj_in_list_num (chl, world[ch->in_room].contents)) && CAN_SEE_OBJ (ch, chalice)) if (!(chalice = get_obj_in_list_num (achl, world[ch->in_room].contents)) && CAN_SEE_OBJ (ch, chalice)) return (0); /* we found a chalice.. now try to get us */ do_get (ch, arg, cmd); /* if got the altar one, switch her */ if (chalice == get_obj_in_list_num (achl, ch->carrying)) { extract_obj (chalice); chalice = read_object (chl, VIRTUAL); obj_to_char (chalice, ch); } return (1); break; case 67: /* put */ if (!(chalice = get_obj_in_list_num (chl, ch->carrying))) return (0); argument_interpreter (arg, buf1, buf2); if (!str_cmp (buf1, "chalice") && !str_cmp (buf2, "altar")) { extract_obj (chalice); chalice = read_object (achl, VIRTUAL); obj_to_room (chalice, ch->in_room); send_to_char ("Ok.\n\r", ch); } return (1); break; case 176: /* pray */ if (!(chalice = get_obj_in_list_num (achl, world[ch->in_room].contents))) return (0); do_action (ch, arg, cmd); /* pray */ send_to_char (CHAL_ACT, ch); extract_obj (chalice); act ("$n is torn out of existence!", TRUE, ch, 0, 0, TO_ROOM); char_from_room (ch); char_to_room (ch, real_room (2500)); /* before the fiery gates */ do_look (ch, "", 15); return (1); break; default: return (0); break; } return (0); } int kings_hall (struct char_data *ch, int cmd, char *arg) { if (cmd != 176) return (0); do_action (ch, arg, 176); send_to_char ("You feel as if some mighty force has been offended.\n\r", ch); send_to_char (CHAL_ACT, ch); act ("$n is struck by an intense beam of light and vanishes.", TRUE, ch, 0, 0, TO_ROOM); char_from_room (ch); char_to_room (ch, real_room (1420)); /* behind the altar */ do_look (ch, "", 15); return (1); }