spec_procs.c
1 /* ************************************************************************ 2 * File: spec_procs.c Part of CircleMUD * 3 * Usage: implementation of special procedures for mobiles/objects/rooms * 4 * * 5 * All rights reserved. See license.doc for complete information. * 6 * * 7 * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * 8 * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * 9 ************************************************************************ */ 10 11 #include "conf.h" 12 #include "sysdep.h" 13 14 #include "structs.h" 15 #include "utils.h" 16 #include "comm.h" 17 #include "interpreter.h" 18 #include "handler.h" 19 #include "db.h" 20 #include "spells.h" 21 #include "constants.h" 22 23 /* external vars */ 24 extern struct time_info_data time_info; 25 extern struct spell_info_type spell_info[]; 26 extern struct guild_info_type guild_info[]; 27 28 /* extern functions */ 29 ACMD(do_drop); 30 ACMD(do_gen_door); 31 ACMD(do_say); 32 ACMD(do_action); 33 34 /* local functions */ 35 void sort_spells(void); 36 int compare_spells(const void *x, const void *y); 37 const char *how_good(int percent); 38 void list_skills(struct char_data *ch); 39 SPECIAL(guild); 40 SPECIAL(dump); 41 SPECIAL(mayor); 42 void npc_steal(struct char_data *ch, struct char_data *victim); 43 SPECIAL(snake); 44 SPECIAL(thief); 45 SPECIAL(magic_user); 46 SPECIAL(guild_guard); 47 SPECIAL(puff); 48 SPECIAL(fido); 49 SPECIAL(janitor); 50 SPECIAL(cityguard); 51 SPECIAL(pet_shops); 52 SPECIAL(bank); 53 54 55 /* ******************************************************************** 56 * Special procedures for mobiles * 57 ******************************************************************** */ 58 59 int spell_sort_info[MAX_SKILLS + 1]; 60 61 int compare_spells(const void *x, const void *y) 62 { 63 int a = *(const int *)x, 64 b = *(const int *)y; 65 66 return strcmp(spell_info[a].name, spell_info[b].name); 67 } 68 69 void sort_spells(void) 70 { 71 int a; 72 73 /* initialize array, avoiding reserved. */ 74 for (a = 1; a <= MAX_SKILLS; a++) 75 spell_sort_info[a] = a; 76 77 qsort(&spell_sort_info[1], MAX_SKILLS, sizeof(int), compare_spells); 78 } 79 80 const char *how_good(int percent) 81 { 82 if (percent < 0) 83 return " error)"; 84 if (percent == 0) 85 return " (not learned)"; 86 if (percent <= 10) 87 return " (awful)"; 88 if (percent <= 20) 89 return " (bad)"; 90 if (percent <= 40) 91 return " (poor)"; 92 if (percent <= 55) 93 return " (average)"; 94 if (percent <= 70) 95 return " (fair)"; 96 if (percent <= 80) 97 return " (good)"; 98 if (percent <= 85) 99 return " (very good)"; 100 101 return " (superb)"; 102 } 103 104 const char *prac_types[] = { 105 "spell", 106 "skill" 107 }; 108 109 #define LEARNED_LEVEL 0 /* % known which is considered "learned" */ 110 #define MAX_PER_PRAC 1 /* max percent gain in skill per practice */ 111 #define MIN_PER_PRAC 2 /* min percent gain in skill per practice */ 112 #define PRAC_TYPE 3 /* should it say 'spell' or 'skill'? */ 113 114 /* actual prac_params are in class.c */ 115 extern int prac_params[4][NUM_CLASSES]; 116 117 #define LEARNED(ch) (prac_params[LEARNED_LEVEL][(int)GET_CLASS(ch)]) 118 #define MINGAIN(ch) (prac_params[MIN_PER_PRAC][(int)GET_CLASS(ch)]) 119 #define MAXGAIN(ch) (prac_params[MAX_PER_PRAC][(int)GET_CLASS(ch)]) 120 #define SPLSKL(ch) (prac_types[prac_params[PRAC_TYPE][(int)GET_CLASS(ch)]]) 121 122 void list_skills(struct char_data *ch) 123 { 124 const char *overflow = "\r\n**OVERFLOW**\r\n"; 125 int i, sortpos, nlen; 126 size_t len = 0; 127 char buf2[MAX_STRING_LENGTH]; 128 129 if (!GET_PRACTICES(ch)) { 130 send_to_char(ch, "You have no practice sessions remaining.\r\n"); 131 return; 132 } 133 134 len = snprintf(buf2, sizeof(buf2), "You have %d practice session%s remaining.\r\n" 135 "You know of the following %ss:\r\n", GET_PRACTICES(ch), 136 GET_PRACTICES(ch) == 1 ? "" : "s", SPLSKL(ch)); 137 138 for (sortpos = 1; sortpos <= MAX_SKILLS; sortpos++) { 139 i = spell_sort_info[sortpos]; 140 if (GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) { 141 nlen = snprintf(buf2 + len, sizeof(buf2) - len, "%-20s %s\r\n", spell_info[i].name, how_good(GET_SKILL(ch, i))); 142 if (len + nlen >= sizeof(buf2) || nlen < 0) 143 break; 144 len += nlen; 145 } 146 } 147 if (len >= sizeof(buf2)) 148 strcpy(buf2 + sizeof(buf2) - strlen(overflow) - 1, overflow); /* strcpy: OK */ 149 150 page_string(ch->desc, buf2, TRUE); 151 } 152 153 154 SPECIAL(guild) 155 { 156 int skill_num, percent; 157 158 if (IS_NPC(ch) || !CMD_IS("practice")) 159 return (FALSE); 160 161 skip_spaces(&argument); 162 163 if (!*argument) { 164 list_skills(ch); 165 return (TRUE); 166 } 167 if (GET_PRACTICES(ch) <= 0) { 168 send_to_char(ch, "You do not seem to be able to practice now.\r\n"); 169 return (TRUE); 170 } 171 172 skill_num = find_skill_num(argument); 173 174 if (skill_num < 1 || 175 GET_LEVEL(ch) < spell_info[skill_num].min_level[(int) GET_CLASS(ch)]) { 176 send_to_char(ch, "You do not know of that %s.\r\n", SPLSKL(ch)); 177 return (TRUE); 178 } 179 if (GET_SKILL(ch, skill_num) >= LEARNED(ch)) { 180 send_to_char(ch, "You are already learned in that area.\r\n"); 181 return (TRUE); 182 } 183 send_to_char(ch, "You practice for a while...\r\n"); 184 GET_PRACTICES(ch)--; 185 186 percent = GET_SKILL(ch, skill_num); 187 percent += MIN(MAXGAIN(ch), MAX(MINGAIN(ch), int_app[GET_INT(ch)].learn)); 188 189 SET_SKILL(ch, skill_num, MIN(LEARNED(ch), percent)); 190 191 if (GET_SKILL(ch, skill_num) >= LEARNED(ch)) 192 send_to_char(ch, "You are now learned in that area.\r\n"); 193 194 return (TRUE); 195 } 196 197 198 199 SPECIAL(dump) 200 { 201 struct obj_data *k; 202 int value = 0; 203 204 for (k = world[IN_ROOM(ch)].contents; k; k = world[IN_ROOM(ch)].contents) { 205 act("$p vanishes in a puff of smoke!", FALSE, 0, k, 0, TO_ROOM); 206 extract_obj(k); 207 } 208 209 if (!CMD_IS("drop")) 210 return (FALSE); 211 212 do_drop(ch, argument, cmd, SCMD_DROP); 213 214 for (k = world[IN_ROOM(ch)].contents; k; k = world[IN_ROOM(ch)].contents) { 215 act("$p vanishes in a puff of smoke!", FALSE, 0, k, 0, TO_ROOM); 216 value += MAX(1, MIN(50, GET_OBJ_COST(k) / 10)); 217 extract_obj(k); 218 } 219 220 if (value) { 221 send_to_char(ch, "You are awarded for outstanding performance.\r\n"); 222 act("$n has been awarded for being a good citizen.", TRUE, ch, 0, 0, TO_ROOM); 223 224 if (GET_LEVEL(ch) < 3) 225 gain_exp(ch, value); 226 else 227 GET_GOLD(ch) += value; 228 } 229 return (TRUE); 230 } 231 232 233 SPECIAL(mayor) 234 { 235 char actbuf[MAX_INPUT_LENGTH]; 236 237 const char open_path[] = 238 "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S."; 239 const char close_path[] = 240 "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S."; 241 242 static const char *path = NULL; 243 static int path_index; 244 static bool move = FALSE; 245 246 if (!move) { 247 if (time_info.hours == 6) { 248 move = TRUE; 249 path = open_path; 250 path_index = 0; 251 } else if (time_info.hours == 20) { 252 move = TRUE; 253 path = close_path; 254 path_index = 0; 255 } 256 } 257 if (cmd || !move || (GET_POS(ch) < POS_SLEEPING) || 258 (GET_POS(ch) == POS_FIGHTING)) 259 return (FALSE); 260 261 switch (path[path_index]) { 262 case '0': 263 case '1': 264 case '2': 265 case '3': 266 perform_move(ch, path[path_index] - '0', 1); 267 break; 268 269 case 'W': 270 GET_POS(ch) = POS_STANDING; 271 act("$n awakens and groans loudly.", FALSE, ch, 0, 0, TO_ROOM); 272 break; 273 274 case 'S': 275 GET_POS(ch) = POS_SLEEPING; 276 act("$n lies down and instantly falls asleep.", FALSE, ch, 0, 0, TO_ROOM); 277 break; 278 279 case 'a': 280 act("$n says 'Hello Honey!'", FALSE, ch, 0, 0, TO_ROOM); 281 act("$n smirks.", FALSE, ch, 0, 0, TO_ROOM); 282 break; 283 284 case 'b': 285 act("$n says 'What a view! I must get something done about that dump!'", 286 FALSE, ch, 0, 0, TO_ROOM); 287 break; 288 289 case 'c': 290 act("$n says 'Vandals! Youngsters nowadays have no respect for anything!'", 291 FALSE, ch, 0, 0, TO_ROOM); 292 break; 293 294 case 'd': 295 act("$n says 'Good day, citizens!'", FALSE, ch, 0, 0, TO_ROOM); 296 break; 297 298 case 'e': 299 act("$n says 'I hereby declare the bazaar open!'", FALSE, ch, 0, 0, TO_ROOM); 300 break; 301 302 case 'E': 303 act("$n says 'I hereby declare Midgaard closed!'", FALSE, ch, 0, 0, TO_ROOM); 304 break; 305 306 case 'O': 307 do_gen_door(ch, strcpy(actbuf, "gate"), 0, SCMD_UNLOCK); /* strcpy: OK */ 308 do_gen_door(ch, strcpy(actbuf, "gate"), 0, SCMD_OPEN); /* strcpy: OK */ 309 break; 310 311 case 'C': 312 do_gen_door(ch, strcpy(actbuf, "gate"), 0, SCMD_CLOSE); /* strcpy: OK */ 313 do_gen_door(ch, strcpy(actbuf, "gate"), 0, SCMD_LOCK); /* strcpy: OK */ 314 break; 315 316 case '.': 317 move = FALSE; 318 break; 319 320 } 321 322 path_index++; 323 return (FALSE); 324 } 325 326 327 /* ******************************************************************** 328 * General special procedures for mobiles * 329 ******************************************************************** */ 330 331 332 void npc_steal(struct char_data *ch, struct char_data *victim) 333 { 334 int gold; 335 336 if (IS_NPC(victim)) 337 return; 338 if (GET_LEVEL(victim) >= LVL_IMMORT) 339 return; 340 if (!CAN_SEE(ch, victim)) 341 return; 342 343 if (AWAKE(victim) && (rand_number(0, GET_LEVEL(ch)) == 0)) { 344 act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, victim, TO_VICT); 345 act("$n tries to steal gold from $N.", TRUE, ch, 0, victim, TO_NOTVICT); 346 } else { 347 /* Steal some gold coins */ 348 gold = (GET_GOLD(victim) * rand_number(1, 10)) / 100; 349 if (gold > 0) { 350 GET_GOLD(ch) += gold; 351 GET_GOLD(victim) -= gold; 352 } 353 } 354 } 355 356 357 /* 358 * Quite lethal to low-level characters. 359 */ 360 SPECIAL(snake) 361 { 362 if (cmd || GET_POS(ch) != POS_FIGHTING || !FIGHTING(ch)) 363 return (FALSE); 364 365 if (IN_ROOM(FIGHTING(ch)) != IN_ROOM(ch) || rand_number(0, GET_LEVEL(ch)) != 0) 366 return (FALSE); 367 368 act("$n bites $N!", 1, ch, 0, FIGHTING(ch), TO_NOTVICT); 369 act("$n bites you!", 1, ch, 0, FIGHTING(ch), TO_VICT); 370 call_magic(ch, FIGHTING(ch), 0, SPELL_POISON, GET_LEVEL(ch), CAST_SPELL); 371 return (TRUE); 372 } 373 374 375 SPECIAL(thief) 376 { 377 struct char_data *cons; 378 379 if (cmd || GET_POS(ch) != POS_STANDING) 380 return (FALSE); 381 382 for (cons = world[IN_ROOM(ch)].people; cons; cons = cons->next_in_room) 383 if (!IS_NPC(cons) && GET_LEVEL(cons) < LVL_IMMORT && !rand_number(0, 4)) { 384 npc_steal(ch, cons); 385 return (TRUE); 386 } 387 388 return (FALSE); 389 } 390 391 392 SPECIAL(magic_user) 393 { 394 struct char_data *vict; 395 396 if (cmd || GET_POS(ch) != POS_FIGHTING) 397 return (FALSE); 398 399 /* pseudo-randomly choose someone in the room who is fighting me */ 400 for (vict = world[IN_ROOM(ch)].people; vict; vict = vict->next_in_room) 401 if (FIGHTING(vict) == ch && !rand_number(0, 4)) 402 break; 403 404 /* if I didn't pick any of those, then just slam the guy I'm fighting */ 405 if (vict == NULL && IN_ROOM(FIGHTING(ch)) == IN_ROOM(ch)) 406 vict = FIGHTING(ch); 407 408 /* Hm...didn't pick anyone...I'll wait a round. */ 409 if (vict == NULL) 410 return (TRUE); 411 412 if (GET_LEVEL(ch) > 13 && rand_number(0, 10) == 0) 413 cast_spell(ch, vict, NULL, SPELL_POISON); 414 415 if (GET_LEVEL(ch) > 7 && rand_number(0, 8) == 0) 416 cast_spell(ch, vict, NULL, SPELL_BLINDNESS); 417 418 if (GET_LEVEL(ch) > 12 && rand_number(0, 12) == 0) { 419 if (IS_EVIL(ch)) 420 cast_spell(ch, vict, NULL, SPELL_ENERGY_DRAIN); 421 else if (IS_GOOD(ch)) 422 cast_spell(ch, vict, NULL, SPELL_DISPEL_EVIL); 423 } 424 425 if (rand_number(0, 4)) 426 return (TRUE); 427 428 switch (GET_LEVEL(ch)) { 429 case 4: 430 case 5: 431 cast_spell(ch, vict, NULL, SPELL_MAGIC_MISSILE); 432 break; 433 case 6: 434 case 7: 435 cast_spell(ch, vict, NULL, SPELL_CHILL_TOUCH); 436 break; 437 case 8: 438 case 9: 439 cast_spell(ch, vict, NULL, SPELL_BURNING_HANDS); 440 break; 441 case 10: 442 case 11: 443 cast_spell(ch, vict, NULL, SPELL_SHOCKING_GRASP); 444 break; 445 case 12: 446 case 13: 447 cast_spell(ch, vict, NULL, SPELL_LIGHTNING_BOLT); 448 break; 449 case 14: 450 case 15: 451 case 16: 452 case 17: 453 cast_spell(ch, vict, NULL, SPELL_COLOR_SPRAY); 454 break; 455 default: 456 cast_spell(ch, vict, NULL, SPELL_FIREBALL); 457 break; 458 } 459 return (TRUE); 460 461 } 462 463 464 /* ******************************************************************** 465 * Special procedures for mobiles * 466 ******************************************************************** */ 467 468 SPECIAL(guild_guard) 469 { 470 int i; 471 struct char_data *guard = (struct char_data *)me; 472 const char *buf = "The guard humiliates you, and blocks your way.\r\n"; 473 const char *buf2 = "The guard humiliates $n, and blocks $s way."; 474 475 if (!IS_MOVE(cmd) || AFF_FLAGGED(guard, AFF_BLIND)) 476 return (FALSE); 477 478 if (GET_LEVEL(ch) >= LVL_IMMORT) 479 return (FALSE); 480 481 for (i = 0; guild_info[i].guild_room != NOWHERE; i++) { 482 /* Wrong guild or not trying to enter. */ 483 if (GET_ROOM_VNUM(IN_ROOM(ch)) != guild_info[i].guild_room || cmd != guild_info[i].direction) 484 continue; 485 486 /* Allow the people of the guild through. */ 487 if (!IS_NPC(ch) && GET_CLASS(ch) == guild_info[i].pc_class) 488 continue; 489 490 send_to_char(ch, "%s", buf); 491 act(buf2, FALSE, ch, 0, 0, TO_ROOM); 492 return (TRUE); 493 } 494 495 return (FALSE); 496 } 497 498 499 500 SPECIAL(puff) 501 { 502 char actbuf[MAX_INPUT_LENGTH]; 503 504 if (cmd) 505 return (FALSE); 506 507 switch (rand_number(0, 60)) { 508 case 0: 509 do_say(ch, strcpy(actbuf, "My god! It's full of stars!"), 0, 0); /* strcpy: OK */ 510 return (TRUE); 511 case 1: 512 do_say(ch, strcpy(actbuf, "How'd all those fish get up here?"), 0, 0); /* strcpy: OK */ 513 return (TRUE); 514 case 2: 515 do_say(ch, strcpy(actbuf, "I'm a very female dragon."), 0, 0); /* strcpy: OK */ 516 return (TRUE); 517 case 3: 518 do_say(ch, strcpy(actbuf, "I've got a peaceful, easy feeling."), 0, 0); /* strcpy: OK */ 519 return (TRUE); 520 default: 521 return (FALSE); 522 } 523 } 524 525 526 527 SPECIAL(fido) 528 { 529 struct obj_data *i, *temp, *next_obj; 530 531 if (cmd || !AWAKE(ch)) 532 return (FALSE); 533 534 for (i = world[IN_ROOM(ch)].contents; i; i = i->next_content) { 535 if (!IS_CORPSE(i)) 536 continue; 537 538 act("$n savagely devours a corpse.", FALSE, ch, 0, 0, TO_ROOM); 539 for (temp = i->contains; temp; temp = next_obj) { 540 next_obj = temp->next_content; 541 obj_from_obj(temp); 542 obj_to_room(temp, IN_ROOM(ch)); 543 } 544 extract_obj(i); 545 return (TRUE); 546 } 547 548 return (FALSE); 549 } 550 551 552 553 SPECIAL(janitor) 554 { 555 struct obj_data *i; 556 557 if (cmd || !AWAKE(ch)) 558 return (FALSE); 559 560 for (i = world[IN_ROOM(ch)].contents; i; i = i->next_content) { 561 if (!CAN_WEAR(i, ITEM_WEAR_TAKE)) 562 continue; 563 if (GET_OBJ_TYPE(i) != ITEM_DRINKCON && GET_OBJ_COST(i) >= 15) 564 continue; 565 act("$n picks up some trash.", FALSE, ch, 0, 0, TO_ROOM); 566 obj_from_room(i); 567 obj_to_char(i, ch); 568 return (TRUE); 569 } 570 571 return (FALSE); 572 } 573 574 575 SPECIAL(cityguard) 576 { 577 struct char_data *tch, *evil, *spittle; 578 int max_evil, min_cha; 579 580 if (cmd || !AWAKE(ch) || FIGHTING(ch)) 581 return (FALSE); 582 583 max_evil = 1000; 584 min_cha = 6; 585 spittle = evil = NULL; 586 587 for (tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) { 588 if (!CAN_SEE(ch, tch)) 589 continue; 590 591 if (!IS_NPC(tch) && PLR_FLAGGED(tch, PLR_KILLER)) { 592 act("$n screams 'HEY!!! You're one of those PLAYER KILLERS!!!!!!'", FALSE, ch, 0, 0, TO_ROOM); 593 hit(ch, tch, TYPE_UNDEFINED); 594 return (TRUE); 595 } 596 597 if (!IS_NPC(tch) && PLR_FLAGGED(tch, PLR_THIEF)) { 598 act("$n screams 'HEY!!! You're one of those PLAYER THIEVES!!!!!!'", FALSE, ch, 0, 0, TO_ROOM); 599 hit(ch, tch, TYPE_UNDEFINED); 600 return (TRUE); 601 } 602 603 if (FIGHTING(tch) && GET_ALIGNMENT(tch) < max_evil && (IS_NPC(tch) || IS_NPC(FIGHTING(tch)))) { 604 max_evil = GET_ALIGNMENT(tch); 605 evil = tch; 606 } 607 608 if (GET_CHA(tch) < min_cha) { 609 spittle = tch; 610 min_cha = GET_CHA(tch); 611 } 612 } 613 614 if (evil && GET_ALIGNMENT(FIGHTING(evil)) >= 0) { 615 act("$n screams 'PROTECT THE INNOCENT! BANZAI! CHARGE! ARARARAGGGHH!'", FALSE, ch, 0, 0, TO_ROOM); 616 hit(ch, evil, TYPE_UNDEFINED); 617 return (TRUE); 618 } 619 620 /* Reward the socially inept. */ 621 if (spittle && !rand_number(0, 9)) { 622 static int spit_social; 623 624 if (!spit_social) 625 spit_social = find_command("spit"); 626 627 if (spit_social > 0) { 628 char spitbuf[MAX_NAME_LENGTH + 1]; 629 630 strncpy(spitbuf, GET_NAME(spittle), sizeof(spitbuf)); /* strncpy: OK */ 631 spitbuf[sizeof(spitbuf) - 1] = '\0'; 632 633 do_action(ch, spitbuf, spit_social, 0); 634 return (TRUE); 635 } 636 } 637 638 return (FALSE); 639 } 640 641 642 #define PET_PRICE(pet) (GET_LEVEL(pet) * 300) 643 644 SPECIAL(pet_shops) 645 { 646 char buf[MAX_STRING_LENGTH], pet_name[256]; 647 room_rnum pet_room; 648 struct char_data *pet; 649 650 /* Gross. */ 651 pet_room = IN_ROOM(ch) + 1; 652 653 if (CMD_IS("list")) { 654 send_to_char(ch, "Available pets are:\r\n"); 655 for (pet = world[pet_room].people; pet; pet = pet->next_in_room) { 656 /* No, you can't have the Implementor as a pet if he's in there. */ 657 if (!IS_NPC(pet)) 658 continue; 659 send_to_char(ch, "%8d - %s\r\n", PET_PRICE(pet), GET_NAME(pet)); 660 } 661 return (TRUE); 662 } else if (CMD_IS("buy")) { 663 664 two_arguments(argument, buf, pet_name); 665 666 if (!(pet = get_char_room(buf, NULL, pet_room)) || !IS_NPC(pet)) { 667 send_to_char(ch, "There is no such pet!\r\n"); 668 return (TRUE); 669 } 670 if (GET_GOLD(ch) < PET_PRICE(pet)) { 671 send_to_char(ch, "You don't have enough gold!\r\n"); 672 return (TRUE); 673 } 674 GET_GOLD(ch) -= PET_PRICE(pet); 675 676 pet = read_mobile(GET_MOB_RNUM(pet), REAL); 677 GET_EXP(pet) = 0; 678 SET_BIT(AFF_FLAGS(pet), AFF_CHARM); 679 680 if (*pet_name) { 681 snprintf(buf, sizeof(buf), "%s %s", pet->player.name, pet_name); 682 /* free(pet->player.name); don't free the prototype! */ 683 pet->player.name = strdup(buf); 684 685 snprintf(buf, sizeof(buf), "%sA small sign on a chain around the neck says 'My name is %s'\r\n", 686 pet->player.description, pet_name); 687 /* free(pet->player.description); don't free the prototype! */ 688 pet->player.description = strdup(buf); 689 } 690 char_to_room(pet, IN_ROOM(ch)); 691 add_follower(pet, ch); 692 693 /* Be certain that pets can't get/carry/use/wield/wear items */ 694 IS_CARRYING_W(pet) = 1000; 695 IS_CARRYING_N(pet) = 100; 696 697 send_to_char(ch, "May you enjoy your pet.\r\n"); 698 act("$n buys $N as a pet.", FALSE, ch, 0, pet, TO_ROOM); 699 700 return (TRUE); 701 } 702 703 /* All commands except list and buy */ 704 return (FALSE); 705 } 706 707 708 709 /* ******************************************************************** 710 * Special procedures for objects * 711 ******************************************************************** */ 712 713 714 SPECIAL(bank) 715 { 716 int amount; 717 718 if (CMD_IS("balance")) { 719 if (GET_BANK_GOLD(ch) > 0) 720 send_to_char(ch, "Your current balance is %d coins.\r\n", GET_BANK_GOLD(ch)); 721 else 722 send_to_char(ch, "You currently have no money deposited.\r\n"); 723 return (TRUE); 724 } else if (CMD_IS("deposit")) { 725 if ((amount = atoi(argument)) <= 0) { 726 send_to_char(ch, "How much do you want to deposit?\r\n"); 727 return (TRUE); 728 } 729 if (GET_GOLD(ch) < amount) { 730 send_to_char(ch, "You don't have that many coins!\r\n"); 731 return (TRUE); 732 } 733 GET_GOLD(ch) -= amount; 734 GET_BANK_GOLD(ch) += amount; 735 send_to_char(ch, "You deposit %d coins.\r\n", amount); 736 act("$n makes a bank transaction.", TRUE, ch, 0, FALSE, TO_ROOM); 737 return (TRUE); 738 } else if (CMD_IS("withdraw")) { 739 if ((amount = atoi(argument)) <= 0) { 740 send_to_char(ch, "How much do you want to withdraw?\r\n"); 741 return (TRUE); 742 } 743 if (GET_BANK_GOLD(ch) < amount) { 744 send_to_char(ch, "You don't have that many coins deposited!\r\n"); 745 return (TRUE); 746 } 747 GET_GOLD(ch) += amount; 748 GET_BANK_GOLD(ch) -= amount; 749 send_to_char(ch, "You withdraw %d coins.\r\n", amount); 750 act("$n makes a bank transaction.", TRUE, ch, 0, FALSE, TO_ROOM); 751 return (TRUE); 752 } else 753 return (FALSE); 754 } 755