/* ************************************************************************ * File: spec_procs.c Part of CircleMUD * * Usage: implementation of special procedures for mobiles/objects/rooms * * * * All rights reserved. See license.doc for complete information. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" #include "spells.h" #include "dg_scripts.h" #include "maputils.h" /* external vars */ extern int arena_zone; extern int arena_preproom; extern int arena_observeroom; extern int arena_combatant; extern int arena_observer; extern struct char_data *arenamaster; extern struct char_data *defaultobserve; extern struct room_data *world; extern struct char_data *character_list; extern struct descriptor_data *descriptor_list; extern struct index_data *mob_index; extern struct index_data *obj_index; extern struct time_info_data time_info; extern struct command_info cmd_info[]; /* extern functions */ extern int has_boat(struct char_data *ch); void write_aliases(struct char_data *ch); void add_follower (struct char_data *ch, struct char_data *leader); void deobserve(struct char_data *); void clearobservers(struct char_data*); void linkobserve(struct char_data *who, struct char_data *to); void bup_affects(struct char_data *ch); void restore_bup_affects(struct char_data *ch); char* numdisplay(int); ACMD(do_tell); ACMD(do_action); ACMD (do_gen_comm); void Crash_rentsave (struct char_data *ch, int cost); struct social_type { char *cmd; int next_line; }; /* ******************************************************************** * Special procedures for mobiles * ******************************************************************** */ int spell_sort_info[MAX_SKILLS + 1]; extern char *spells[]; void sort_spells (void) { int a, b, tmp; /* initialize array */ for (a = 1; a < MAX_SKILLS; a++) spell_sort_info[a] = a; /* Sort. 'a' starts at 1, not 0, to remove 'RESERVED' */ for (a = 1; a < MAX_SKILLS - 1; a++) for (b = a + 1; b < MAX_SKILLS; b++) if (strcmp (spells[spell_sort_info[a]], spells[spell_sort_info[b]]) > 0) { tmp = spell_sort_info[a]; spell_sort_info[a] = spell_sort_info[b]; spell_sort_info[b] = tmp; } } 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)"); sprintf(buf+strlen(buf), " %d", percent); return (buf); } char *prac_types[] = { "spell", "skill" }; #define LEARNED_LEVEL 0 /* % known which is considered "learned" */ #define MAX_PER_PRAC 1 /* max percent gain in skill per practice */ #define MIN_PER_PRAC 2 /* min percent gain in skill per practice */ #define PRAC_TYPE 3 /* should it say 'spell' or 'skill'? */ /* actual prac_params are in class.c */ extern int prac_params[4][NUM_CLASSES]; #define LEARNED(ch) (prac_params[LEARNED_LEVEL][(int)GET_CLASS(ch)]) #define MINGAIN(ch) (prac_params[MIN_PER_PRAC][(int)GET_CLASS(ch)]) #define MAXGAIN(ch) (prac_params[MAX_PER_PRAC][(int)GET_CLASS(ch)]) #define SPLSKL(ch) (prac_types[prac_params[PRAC_TYPE][(int)GET_CLASS(ch)]]) void list_skills (struct char_data *ch) { extern char *spells[]; extern struct spell_info_type spell_info[]; int i, sortpos; if (!GET_PRACTICES (ch)) strcpy (buf, "You have no practice sessions remaining.\r\n"); else sprintf (buf, "You have %d practice session%s remaining.\r\n", GET_PRACTICES (ch), (GET_PRACTICES (ch) == 1 ? "" : "s")); sprintf (buf, "%sYou know of the following %ss:\r\n", buf, SPLSKL (ch)); strcpy (buf2, buf); for (sortpos = 1; sortpos < MAX_SKILLS; sortpos++) { i = spell_sort_info[sortpos]; if (strlen (buf2) >= MAX_STRING_LENGTH - 32) { strcat (buf2, "**OVERFLOW**\r\n"); break; } if (GET_LEVEL (ch) >= spell_info[i].min_level[(int) GET_CLASS (ch)]) { sprintf (buf, "%-20s %s\r\n", spells[i], how_good (GET_SKILL (ch, i))); strcat (buf2, buf); } } page_string (ch->desc, buf2, 1); } SPECIAL (guild) { int skill_num, percent; extern struct spell_info_type spell_info[]; extern struct int_app_type int_app[]; if (IS_NPC (ch) || !CMD_IS ("practice")) return 0; skip_spaces (&argument); if (!*argument) { list_skills (ch); return 1; } if (GET_PRACTICES (ch) <= 0) { send_to_char ("You do not seem to be able to practice now.\r\n", ch); return 1; } skill_num = find_skill_num (argument); if (skill_num < 1 || GET_LEVEL (ch) < spell_info[skill_num].min_level[(int) GET_CLASS (ch)]) { sprintf (buf, "You do not know of that %s.\r\n", SPLSKL (ch)); send_to_char (buf, ch); return 1; } if (GET_SKILL (ch, skill_num) >= LEARNED (ch)) { send_to_char ("You are already learned in that area.\r\n", ch); return 1; } send_to_char ("You practice for a while...\r\n", ch); GET_PRACTICES (ch)--; percent = GET_SKILL (ch, skill_num); percent += MIN (MAXGAIN (ch), MAX (MINGAIN (ch), int_app[GET_INT (ch)].learn)); SET_SKILL (ch, skill_num, MIN (LEARNED (ch), percent)); if (GET_SKILL (ch, skill_num) >= LEARNED (ch)) send_to_char ("You are now learned in that area.\r\n", ch); return 1; } SPECIAL (dump) { struct obj_data *k; int value = 0; ACMD (do_drop); char *fname (char *namelist); for (k = world[ch->in_room].contents; k; k = world[ch->in_room].contents) { act ("$p vanishes in a puff of smoke!", FALSE, 0, k, 0, TO_ROOM); extract_obj (k); } if (!CMD_IS ("drop")) return 0; do_drop (ch, argument, cmd, 0); for (k = world[ch->in_room].contents; k; k = world[ch->in_room].contents) { act ("$p vanishes in a puff of smoke!", FALSE, 0, k, 0, TO_ROOM); value += MAX (1, MIN (50, GET_OBJ_COST (k) / 10)); extract_obj (k); } if (value) { if (GET_LEVEL(ch) < LVL_IMMORT) { act ("You are awarded for being a good citizen.", 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 1; } SPECIAL (mayor) { ACMD (do_gen_door); static char open_path[] = "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S."; static char close_path[] = "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S."; static char *path; static int index; static bool move = FALSE; 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) < POS_SLEEPING) || (GET_POS (ch) == POS_FIGHTING)) return FALSE; switch (path[index]) { case '0': case '1': case '2': case '3': perform_move (ch, path[index] - '0', 1); break; case 'W': GET_POS (ch) = POS_STANDING; act ("$n awakens and groans loudly.", FALSE, ch, 0, 0, TO_ROOM); break; case 'S': GET_POS (ch) = POS_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 markets open!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'E': act ("$n says 'I hereby declare Anacreon closed!'", FALSE, ch, 0, 0, TO_ROOM); break; case 'O': do_gen_door (ch, "gate", 0, SCMD_UNLOCK); do_gen_door (ch, "gate", 0, SCMD_OPEN); break; case 'C': do_gen_door (ch, "gate", 0, SCMD_CLOSE); do_gen_door (ch, "gate", 0, SCMD_LOCK); break; case '.': move = FALSE; break; } index++; return FALSE; } /* ******************************************************************** * General special procedures for mobiles * ******************************************************************** */ void npc_steal (struct char_data *ch, struct char_data *victim) { int gold; if (IS_NPC (victim)) return; if (GET_LEVEL (victim) >= LVL_IMMORT) 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; } } } SPECIAL (snake) { if (cmd) return FALSE; if (GET_POS (ch) != POS_FIGHTING) return FALSE; if (FIGHTING (ch) && (FIGHTING (ch)->in_room == ch->in_room) && (number (0, 42 - GET_LEVEL (ch)) == 0)) { act ("$n bites $N!", 1, ch, 0, FIGHTING (ch), TO_NOTVICT); act ("$n bites you!", 1, ch, 0, FIGHTING (ch), TO_VICT); call_magic (ch, FIGHTING (ch), 0, SPELL_POISON, GET_LEVEL (ch)); return TRUE; } return FALSE; } SPECIAL (thief) { struct char_data *cons; if (cmd) return FALSE; if (GET_POS (ch) != POS_STANDING) return FALSE; for (cons = world[ch->in_room].people; cons; cons = cons->next_in_room) if (!IS_NPC (cons) && (GET_LEVEL (cons) < LVL_IMMORT) && (!number (0, 4))) { npc_steal (ch, cons); return TRUE; } return FALSE; } SPECIAL (magic_user) { struct char_data *vict; if (cmd || GET_POS (ch) != POS_FIGHTING) return FALSE; /* pseudo-randomly choose someone in the room who is fighting me */ for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) if (FIGHTING (vict) == ch && !number (0, 4)) break; /* if I didn't pick any of those, then just slam the guy I'm fighting */ if (vict == NULL) vict = FIGHTING (ch); if ((GET_LEVEL (ch) > 13) && (number (0, 10) == 0)) cast_spell (ch, vict, NULL, SPELL_SLEEP); if ((GET_LEVEL (ch) > 7) && (number (0, 8) == 0)) cast_spell (ch, vict, NULL, SPELL_BLINDNESS); if (number (0, 4)) return TRUE; if ( (GET_HIT(ch)/GET_MAX_HIT(ch) > 0.05) && (GET_HIT(ch)/GET_MAX_HIT(ch) < 0.5)){ if (number(1,50) > (number(1,150)-GET_LEVEL(ch))){ cast_spell(ch, ch, NULL, SPELL_HEAL); return TRUE; } } switch (GET_LEVEL (ch)) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 98: case 99: case 100: default: } return TRUE; } /* ******************************************************************** * Special procedures for mobiles * ******************************************************************** */ SPECIAL (guild_guard) { int i; extern int guild_info[][3]; struct char_data *guard = (struct char_data *) me; char *buf = "The guard humiliates you, and blocks your way.\r\n"; char *buf2 = "The guard humiliates $n, and blocks $s way."; if (!IS_MOVE (cmd) || IS_AFFECTED (guard, AFF_BLIND)) return FALSE; if (GET_LEVEL (ch) >= LVL_IMMORT) return FALSE; for (i = 0; guild_info[i][0] != -1; i++) { if ((IS_NPC (ch) || GET_CLASS (ch) != guild_info[i][0]) && world[ch->in_room].number == guild_info[i][1] && cmd == guild_info[i][2]) { send_to_char (buf, ch); act (buf2, FALSE, ch, 0, 0, TO_ROOM); return TRUE; } } return FALSE; } SPECIAL (librarian) { struct char_data *vict; if (cmd) return (0); for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { switch (number (0, 72)) { case 0: act("$n says, 'I sell books from all over the land, why not buy one?'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 1: act("$n turns a page in the book she's reading.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 2: act("$n drinks a glass of wine.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 3: act("$n says, 'I'm reading a book about ancient Midgaard.'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 4: act("$n says, 'Thanks for being quiet in the library.'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 5: act("$n winks at $N suggestively.", TRUE, ch, 0, vict, TO_ROOM); return (1); case 6: act("$n starts sorting new books.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 7: act ("$n points at the sign on the wall.", FALSE, ch, 0, 0, TO_ROOM); act ("$n says, 'If you're looking for books just type: list'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 8: act ("$n says, 'I need a vacation. I'd love to see Jhaden'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 9: act("$n puts several books on a shelf.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 10: act("$n snickers softly.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 11: act ("$n says, 'I wish people like you would write books.'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 12: act ("$n says, 'I once met AJ Trfiante here long ago.'", FALSE, ch, 0, 0, TO_ROOM); act ("$n says, 'It was at the debute of his restraunt'", FALSE, ch, 0, 0, TO_ROOM); return (1); case 13: act("$n seems to be getting tired.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 14: act("$n leaves to a back room.", FALSE, ch, 0, 0, TO_ROOM); act("$n returns with a new pile of books.", FALSE, ch, 0, 0, TO_ROOM); return (1); case 15: act ("$n says, 'I love to read. It makes you smart, you know.'", FALSE, ch, 0, 0, TO_ROOM); return (1); default: return (0); } } return (0); } SPECIAL (puff) { ACMD (do_say); if (cmd) return (0); switch (number (0, 66)) { case 0: do_say (ch, "The force is strong with this one!", 0, 0); return (1); case 1: do_say (ch, "If you only knew the POWER of the dark side", 0, 0); return (1); case 2: do_say (ch, "Read my lips.. no new taxes", 0, 0); return (1); case 3: do_say (ch, "Whenever I climb I am followed by a dog called Ego", 0, 0); return (1); case 4: do_say (ch, "I'll sleep when I'm dead", 0, 0); return (1); case 5: do_say (ch, "My advice to you is get married: if you find a good wife you'll be happy; if not, you'll become a philosopher", 0, 0); return (1); case 6: do_say (ch, "We all agree that your theory is crazy, but is it crazy enough?", 0, 0); return (1); case 7: do_say (ch, "I loved Welmar more than any woman I had ever known", 0, 0); return (1); case 8: do_say (ch, "The graveyards are full of indispensable men", 0, 0); return (1); case 9: do_say (ch, "I have an existential map; it has 'you are here' written all over it", 0, 0); return (1); default: return (0); } } SPECIAL (fido) { 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_OBJ_TYPE (i) == ITEM_CONTAINER && GET_OBJ_VAL (i, 3)) { act ("$n savagely devours 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); } SPECIAL (janitor) { struct obj_data *i; if (cmd || !AWAKE (ch)) return (FALSE); for (i = world[ch->in_room].contents; i; i = i->next_content) { if (!CAN_WEAR (i, ITEM_WEAR_TAKE)) continue; if (GET_OBJ_TYPE (i) != ITEM_DRINKCON && GET_OBJ_COST (i) >= 15) continue; 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; } SPECIAL (cityguard) { struct char_data *tch, *evil; int max_evil; if (cmd || !AWAKE (ch) || FIGHTING (ch)) return FALSE; max_evil = 1000; evil = 0; for (tch = world[ch->in_room].people; tch; tch = tch->next_in_room) { if (!IS_NPC (tch) && CAN_SEE (ch, tch) && IS_SET (PLR_FLAGS (tch), PLR_KILLER)) { act ("$n screams 'HEY!!! You're one of those PLAYER KILLERS!!!!!!'", FALSE, ch, 0, 0, TO_ROOM); hit (ch, tch, TYPE_UNDEFINED); return (TRUE); } } for (tch = world[ch->in_room].people; tch; tch = tch->next_in_room) { if (!IS_NPC (tch) && CAN_SEE (ch, tch) && IS_SET (PLR_FLAGS (tch), PLR_THIEF)) { act ("$n screams 'HEY!!! You're one of those PLAYER THIEVES!!!!!!'", FALSE, ch, 0, 0, TO_ROOM); hit (ch, tch, TYPE_UNDEFINED); return (TRUE); } } for (tch = world[ch->in_room].people; tch; tch = tch->next_in_room) { if (CAN_SEE (ch, tch) && FIGHTING (tch)) { if ((GET_ALIGNMENT (tch) < max_evil) && (IS_NPC (tch) || IS_NPC (FIGHTING (tch)))) { max_evil = GET_ALIGNMENT (tch); evil = tch; } } } if (evil && (GET_ALIGNMENT (FIGHTING (evil)) >= 0)) { act ("$n screams 'PROTECT THE INNOCENT! BANZAI! CHARGE! ARARARAGGGHH!'", FALSE, ch, 0, 0, TO_ROOM); hit (ch, evil, TYPE_UNDEFINED); return (TRUE); } return (FALSE); } #define PET_PRICE(pet) (GET_LEVEL(pet) * 300) SPECIAL (pet_shops) { char buf[MAX_STRING_LENGTH], pet_name[256]; int pet_room; struct char_data *pet; pet_room = ch->in_room + 1; if (CMD_IS ("list")) { send_to_char ("Available pets are:\r\n", ch); for (pet = world[pet_room].people; pet; pet = pet->next_in_room) { sprintf (buf, "%8d - %s\r\n", PET_PRICE (pet), GET_NAME (pet)); send_to_char (buf, ch); } return (TRUE); } else if (CMD_IS ("buy")) { argument = one_argument (argument, buf); argument = one_argument (argument, pet_name); if (!(pet = get_char_room (buf, pet_room))) { send_to_char ("There is no such pet!\r\n", ch); return (TRUE); } if (GET_GOLD (ch) < PET_PRICE (pet)) { send_to_char ("You don't have enough gold!\r\n", ch); return (TRUE); } GET_GOLD (ch) -= PET_PRICE (pet); pet = read_mobile (GET_MOB_RNUM (pet), REAL); GET_EXP (pet) = 0; SET_BIT (AFF_FLAGS (pet), AFF_CHARM); if (*pet_name) { sprintf (buf, "%s %s", pet->player.name, pet_name); /* free(pet->player.name); don't free the prototype! */ pet->player.name = str_dup (buf); sprintf (buf, "%sA small sign on a chain around the neck says 'My name is %s'\r\n", pet->player.description, pet_name); /* free(pet->player.description); don't free the prototype! */ pet->player.description = str_dup (buf); } char_to_room (pet, ch->in_room); add_follower (pet, ch); load_mtrigger(pet); /* Be certain that pets can't get/carry/use/wield/wear items */ IS_CARRYING_W (pet) = 1000; IS_CARRYING_N (pet) = 100; send_to_char ("May you enjoy your pet.\r\n", ch); act ("$n buys $N as a pet.", FALSE, ch, 0, pet, TO_ROOM); return 1; } /* All commands except list and buy */ return 0; } /* ******************************************************************** * Special procedures for objects * ******************************************************************** */ SPECIAL (temple_cleric) { struct char_data *vict; struct char_data *hitme = NULL; static int this_hour; float temp1 = 1; float temp2 = 1; if (cmd) return FALSE; if (time_info.hours != 0) { this_hour = time_info.hours; for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { if (IS_AFFECTED (vict, AFF_POISON)) hitme = vict; } if (hitme != NULL) { cast_spell (ch, hitme, NULL, SPELL_REMOVE_POISON); return TRUE; } for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { if (IS_AFFECTED (vict, AFF_BLIND)) hitme = vict; } if (hitme != NULL) { cast_spell (ch, hitme, NULL, SPELL_CURE_BLIND); return TRUE; } for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { temp1 = GET_HIT (vict) / GET_MAX_HIT (vict); if (temp1 < temp2) { temp2 = temp1; hitme = vict; } } if (hitme != NULL) { cast_spell(ch, hitme, NULL, SPELL_CURE_LIGHT); return TRUE; } } return 0; } SPECIAL (temple_healer) { struct char_data *vict; struct char_data *hitme = NULL; static int this_hour; float temp1 = 1; float temp2 = 1; if (cmd) return FALSE; if (time_info.hours != 0) { this_hour = time_info.hours; for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { if (IS_AFFECTED (vict, AFF_POISON)) hitme = vict; } if (hitme != NULL) { cast_spell (ch, hitme, NULL, SPELL_REMOVE_POISON); return TRUE; } for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { if (IS_AFFECTED (vict, AFF_CURSE)) hitme = vict; } if (hitme != NULL) { cast_spell (ch, hitme, NULL, SPELL_REMOVE_CURSE); return TRUE; } for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { if (IS_AFFECTED (vict, AFF_BLIND)) hitme = vict; } if (hitme != NULL) { cast_spell (ch, hitme, NULL, SPELL_CURE_BLIND); return TRUE; } for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { temp1 = GET_HIT (vict) / GET_MAX_HIT (vict); if (temp1 < temp2) { temp2 = temp1; hitme = vict; } } if (hitme != NULL) { cast_spell(ch, hitme, NULL, SPELL_HEAL); return TRUE; } } return 0; } SPECIAL (temple_mana_regenerator) { struct char_data *vict; struct char_data *hitme = NULL; static int this_hour; float temp1 = 1; float temp2 = 1; if (cmd) return FALSE; if (time_info.hours != 0) { this_hour = time_info.hours; for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { temp1 = GET_MANA (vict) / GET_MAX_MANA (vict); if (temp1 < temp2) { temp2 = temp1; hitme = vict; } } if (hitme != NULL) { cast_spell(ch, hitme, NULL, SPELL_REGEN_MANA); return TRUE; } } return 0; } SPECIAL (portal) { struct obj_data *obj = (struct obj_data *) me; struct obj_data *port; char obj_name[MAX_STRING_LENGTH]; if (!CMD_IS("enter")) return FALSE; argument = one_argument(argument,obj_name); if (!(port = get_obj_in_list_vis(ch, obj_name, world[ch->in_room].contents))) { return(FALSE); } if (port != obj) return(FALSE); if (port->obj_flags.value[1] <= 0 || port->obj_flags.value[1] > 32000) { send_to_char("The portal leads nowhere.\n\r", ch); return TRUE; } if (SECT(ch->in_room) == SECT_WATER_NOSWIM || SECT(port->obj_flags.value[1]) == SECT_WATER_NOSWIM) { if (RIDING(ch)) { if (!has_boat(RIDING(ch))) { send_to_char("Your mount needs a boat to go there.\r\n", ch); return TRUE; } } else if (!has_boat(ch)) { send_to_char("You need a boat to go there.\r\n", ch); return TRUE; } } act("$n enters $p, and vanishes!", FALSE, ch, port, 0, TO_ROOM); act("You enter $p, and you are transported elsewhere.", FALSE, ch, port, 0, TO_CHAR); char_from_room(ch); char_to_room(ch, port->obj_flags.value[1]); look_at_room(ch,0); act("$n appears from the glowing portal!", FALSE, ch, 0, 0, TO_ROOM); return TRUE; } extern int train_params[6][NUM_CLASSES]; SPECIAL(trainer) { char trainitem[1024]; if (IS_NPC(ch) || !CMD_IS("train")) return 0; skip_spaces(&argument); if (!*argument) { sprintf(buf,"Hit:%d Mana:%d Str:%d Con:%d Wis:%d Int:%d Dex:%d Cha:%d\r\n", (int) GET_MAX_HIT(ch), (int) GET_MAX_MANA(ch), GET_STR(ch), GET_CON(ch), GET_WIS(ch), GET_INT(ch), GET_DEX(ch), GET_CHA(ch)); sprintf(buf,"%sYou have %d training session",buf, GET_TRAINING(ch)); if (GET_TRAINING(ch) == 1) sprintf(buf,"%s.\r\n",buf); else sprintf(buf,"%ss.\r\n",buf); send_to_char(buf,ch); return 1; } if (GET_TRAINING(ch) <= 0) { send_to_char("You do not seem to be able to train now.\r\n", ch); return 1; } /* if (strcmp(argument,"hit")==0) */ if (is_abbrev(argument,"hitpoints")) { GET_TRAINING(ch) -=1; ch->points.max_hit += 10; sprintf(trainitem, "maxhits goes up by 5!"); } else if (is_abbrev(argument,"move")) { GET_TRAINING(ch) -=1; ch->points.max_move += 10; sprintf(trainitem, "maxmoves goes up by 5!"); } else if (is_abbrev(argument,"mana")) { GET_TRAINING(ch) -=1; ch->points.max_mana += 10; sprintf(trainitem, "maxmana goes up by 5!"); } else if (is_abbrev(argument,"strength")) { if (ch->real_abils.str >= train_params[0][(int)GET_CLASS(ch)]) { send_to_char("Your are already fully trained there!\r\n",ch); return 1; } GET_TRAINING(ch) -=1; ch->real_abils.str+=1; sprintf(trainitem, "strength goes up by 1!"); } else if (is_abbrev(argument,"constitution")) { if (ch->real_abils.con >= train_params[1][(int)GET_CLASS(ch)]) { send_to_char("Your are already fully trained there!\r\n",ch); return 1; } GET_TRAINING(ch) -=1; /* ch->real_abils.con+=1; */ ch->real_abils.con +=1; sprintf(trainitem, "constitution goes up by 1!"); } else if (is_abbrev(argument,"wisdom")) { if (ch->real_abils.wis >= train_params[2][(int)GET_CLASS(ch)]) { send_to_char("Your are already fully trained there!\r\n",ch); return 1; } GET_TRAINING(ch) -=1; ch->real_abils.wis +=1; sprintf(trainitem, "wisdom goes up by 1!"); } else if (is_abbrev(argument,"intelligence")) { if (ch->real_abils.intel >= train_params[3][(int)GET_CLASS(ch)]) { send_to_char("Your are already fully trained there!\r\n",ch); return 1; } GET_TRAINING(ch) -=1; ch->real_abils.intel+=1; sprintf(trainitem, "intelligence goes up by 1!"); } else if (is_abbrev(argument,"dexterity")) { if (ch->real_abils.dex >= train_params[4][(int)GET_CLASS(ch)]) { send_to_char("Your are already fully trained there!\r\n",ch); return 1; } GET_TRAINING(ch) -=1; ch->real_abils.dex+=1; sprintf(trainitem, "dexterity goes up by 1!"); } else if (is_abbrev(argument,"charisma")) { if (ch->real_abils.cha >= train_params[5][(int)GET_CLASS(ch)]) { send_to_char("Your are already fully trained there!\r\n",ch); return 1; } GET_TRAINING(ch) -=1; ch->real_abils.cha+=1; sprintf(trainitem, "charisma goes up by 1!"); } else { send_to_char("Train what?\r\n",ch); return 1; } affect_total (ch); save_char (ch, NOWHERE); sprintf(buf, "You train for a while...\r\nYour %s\r\n",trainitem); send_to_char(buf, ch); return 1; } SPECIAL(arenaentrancemaster) { // struct char_data *who, *tmp; int cmd_puke = find_command("puke"); int cmd_tell = find_command("tell"); int fee = 0; char mybuf[1024]; arenamaster = (struct char_data *) me; if (IS_NPC(ch) || !CMD_IS("arena")) return 0; skip_spaces(&argument); if (!*argument) { fee = GET_LEVEL(ch) * arena_combatant; sprintf (mybuf, "%s Welcome to my Arena! Your fee as a " "combatant will be %s coins,", GET_NAME(ch), numdisplay(fee)); fee = GET_LEVEL(ch) * arena_observer; if (fee == 0) sprintf (mybuf, "%s and as an observer it's FREE!", mybuf); else sprintf (mybuf, "%s and as an observer it's %s coins.", mybuf, numdisplay(fee)); do_tell(arenamaster, mybuf, cmd_tell, 0); deobserve(ch); clearobservers(ch); GET_ARENASTAT(ch) = ARENA_NOT; return 1; } if (is_abbrev(argument,"combatant")){ fee = GET_LEVEL(ch) * arena_combatant; if (GET_GOLD(ch) < fee){ sprintf(mybuf, "%s The fee for you is %s coins. " "You don't have enough gold!", GET_NAME(ch), numdisplay(fee)); do_tell(arenamaster, mybuf, cmd_tell, 0); do_action(arenamaster, GET_NAME(ch), cmd_puke, 0); return 1; } sprintf(mybuf, "%s That'll be %s coins, thanks!", GET_NAME(ch), numdisplay(fee)); do_tell(arenamaster, mybuf, cmd_tell, 0); GET_GOLD(ch) -= fee; GET_ARENASTAT(ch) = ARENA_COMBATANT1; act ("$n admits $N as a combatant into the arena.", FALSE, arenamaster, 0, ch, TO_NOTVICT); act ("$n admits you as a combatant into the arena.", FALSE, arenamaster, 0, ch, TO_VICT); char_from_room (ch); char_to_room (ch, real_room(arena_preproom)); act ("$n has arrived.", FALSE, ch, 0, 0, TO_NOTVICT); look_at_room (ch, 0); if (defaultobserve != NULL){ if (!IS_ARENACOMBATANT(defaultobserve)) defaultobserve = ch; }else{ defaultobserve = ch; } if (GET_LEVEL(ch) < LVL_IMMORT){ sprintf(mybuf, "%s has entered the arena as a combatant.", GET_NAME(ch)); log (mybuf); do_gen_comm (arenamaster, mybuf, 1, SCMD_ARENA); } bup_affects(ch); } else if (is_abbrev(argument,"observer")){ fee = GET_LEVEL(ch) * arena_observer; if (GET_GOLD(ch) < fee){ sprintf(mybuf, "%s The fee for you is %s coins. " "You don't have enough gold!", GET_NAME(ch), numdisplay(fee)); do_tell(arenamaster, mybuf, cmd_tell, 0); do_action(arenamaster, GET_NAME(ch), cmd_puke, 0); return 1; } bzero(mybuf, 1024); if (defaultobserve == NULL) sprintf(mybuf, "%s Looks like there's currently no combatants there.", GET_NAME(ch)); else if (!IS_ARENACOMBATANT(defaultobserve)) sprintf(mybuf, "%s Looks like there's currently no combatants there.", GET_NAME(ch)); if (strlen(mybuf) > 0){ do_tell(arenamaster, mybuf, cmd_tell, 0); return 1; } if (fee == 0){ sprintf(mybuf,"%s It's free to observe now!", GET_NAME(ch)); }else{ sprintf(mybuf, "%s That'll be %d coins, thanks!", GET_NAME(ch), fee); } do_tell(arenamaster, mybuf, cmd_tell, 0); sprintf(mybuf, "%s You're currently observing the actions of %s.", GET_NAME(ch), GET_NAME(defaultobserve)); do_tell(arenamaster, mybuf, cmd_tell, 0); /* Now let's link */ linkobserve(ch, defaultobserve); GET_GOLD(ch) -= fee; GET_ARENASTAT(ch) = ARENA_OBSERVER; act ("$n admits $N into the arena observatory.", FALSE, arenamaster, 0, ch, TO_NOTVICT); act ("$n admits you into the arena observatory.", FALSE, arenamaster, 0, ch, TO_VICT); char_from_room (ch); char_to_room (ch, real_room(arena_observeroom)); act ("$n has arrived.", FALSE, ch, 0, 0, TO_NOTVICT); look_at_room (ch, 0); if (GET_LEVEL(ch) < LVL_IMMORT){ sprintf(mybuf, "%s has entered the arena as an observer.", GET_NAME(ch)); do_gen_comm (arenamaster, mybuf, 1, SCMD_ARENA); } } else{ sprintf (mybuf, "%s Welcome to my Arena! Combatant or Observer?\r\n", GET_NAME(ch)); do_tell(arenamaster, mybuf, cmd_tell, 0); deobserve(ch); clearobservers(ch); GET_ARENASTAT(ch) = ARENA_NOT; return 1; } return 1; } SPECIAL(tent) { struct obj_data *obj; struct descriptor_data *d, *next_d; if (CMD_IS("camp")) { if (!ismap(ch->in_room)) { send_to_char("You may only setup camp on the surface map.\r\n", ch); return 1; } for (obj=ch->carrying; obj; obj=obj->next_content) { if (obj==me) { ch->player_specials->saved.mapx=rm2x(ch->in_room); ch->player_specials->saved.mapy=rm2y(ch->in_room); send_to_char("\r\nYou setup camp and safely fall asleep...\r\n", ch); act("$n sets up camp and leaves the game.", FALSE, ch, 0, 0, TO_ROOM); write_aliases(ch); Crash_rentsave(ch, 0); sprintf (buf, "%s has camped out of the game. (%s)", GET_NAME (ch), rcds(ch->in_room)); mudlog (buf, NRM, MAX (LVL_IMMORT, GET_INVIS_LEV (ch)), TRUE); for (d = descriptor_list; d; d = next_d) { next_d = d->next; if (d == ch->desc) continue; if (d->character && (GET_IDNUM (d->character) == GET_IDNUM (ch))) close_socket (d); } extract_char(ch); return 1; } } send_to_char("You carry nothing to setup camp with.\r\n", ch); return 1; } return 0; }