00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #if defined(macintosh)
00029 #include <types.h>
00030 #include <time.h>
00031 #else
00032 #include <sys/types.h>
00033 #endif
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <time.h>
00038 #include "merc.h"
00039 #include "interp.h"
00040 #include "magic.h"
00041
00042
00043
00044
00045 DECLARE_SPEC_FUN (spec_breath_any);
00046 DECLARE_SPEC_FUN (spec_breath_acid);
00047 DECLARE_SPEC_FUN (spec_breath_fire);
00048 DECLARE_SPEC_FUN (spec_breath_frost);
00049 DECLARE_SPEC_FUN (spec_breath_gas);
00050 DECLARE_SPEC_FUN (spec_breath_lightning);
00051 DECLARE_SPEC_FUN (spec_cast_adept);
00052 DECLARE_SPEC_FUN (spec_cast_cleric);
00053 DECLARE_SPEC_FUN (spec_cast_judge);
00054 DECLARE_SPEC_FUN (spec_cast_mage);
00055 DECLARE_SPEC_FUN (spec_cast_undead);
00056 DECLARE_SPEC_FUN (spec_executioner);
00057 DECLARE_SPEC_FUN (spec_fido);
00058 DECLARE_SPEC_FUN (spec_guard);
00059 DECLARE_SPEC_FUN (spec_janitor);
00060 DECLARE_SPEC_FUN (spec_mayor);
00061 DECLARE_SPEC_FUN (spec_poison);
00062 DECLARE_SPEC_FUN (spec_thief);
00063 DECLARE_SPEC_FUN (spec_nasty);
00064 DECLARE_SPEC_FUN (spec_troll_member);
00065 DECLARE_SPEC_FUN (spec_ogre_member);
00066 DECLARE_SPEC_FUN (spec_patrolman);
00067 DECLARE_SPEC_FUN (spec_wolf_forest);
00068 DECLARE_SPEC_FUN (spec_panther_forest);
00069
00070 const struct spec_type spec_table[] = {
00071 {"spec_breath_any", spec_breath_any},
00072 {"spec_breath_acid", spec_breath_acid},
00073 {"spec_breath_fire", spec_breath_fire},
00074 {"spec_breath_frost", spec_breath_frost},
00075 {"spec_breath_gas", spec_breath_gas},
00076 {"spec_breath_lightning", spec_breath_lightning},
00077 {"spec_cast_adept", spec_cast_adept},
00078 {"spec_cast_cleric", spec_cast_cleric},
00079 {"spec_cast_judge", spec_cast_judge},
00080 {"spec_cast_mage", spec_cast_mage},
00081 {"spec_cast_undead", spec_cast_undead},
00082 {"spec_executioner", spec_executioner},
00083 {"spec_fido", spec_fido},
00084 {"spec_guard", spec_guard},
00085 {"spec_janitor", spec_janitor},
00086 {"spec_mayor", spec_mayor},
00087 {"spec_poison", spec_poison},
00088 {"spec_thief", spec_thief},
00089 {"spec_nasty", spec_nasty},
00090 {"spec_troll_member", spec_troll_member},
00091 {"spec_ogre_member", spec_ogre_member},
00092 {"spec_patrolman", spec_patrolman},
00093 {"spec_wolf_forest", spec_wolf_forest},
00094 {"spec_panther_forest", spec_panther_forest},
00095 {NULL, NULL}
00096 };
00097
00098
00099
00100
00101 SPEC_FUN *spec_lookup (const char *name)
00102 {
00103 int i;
00104
00105 for (i = 0; spec_table[i].name != NULL; i++)
00106 {
00107 if (LOWER (name[0]) == LOWER (spec_table[i].name[0])
00108 && !str_prefix (name, spec_table[i].name))
00109 return spec_table[i].function;
00110 }
00111
00112 return 0;
00113 }
00114
00115 char *spec_name (SPEC_FUN * function)
00116 {
00117 int i;
00118
00119 for (i = 0; spec_table[i].function != NULL; i++)
00120 {
00121 if (function == spec_table[i].function)
00122 return spec_table[i].name;
00123 }
00124
00125 return NULL;
00126 }
00127
00128 bool spec_panther_forest (CHAR_DATA *ch)
00129 {
00130 CHAR_DATA *vch, *victim = NULL;
00131 int count=0;
00132
00133 if (!IS_AWAKE(ch) || IS_AFFECTED(ch, AFF_CALM) || ch->in_room == NULL
00134 || IS_AFFECTED(ch, AFF_CHARM) || ch->fighting != NULL)
00135 return FALSE;
00136
00137 for (vch = ch->in_room->people;vch != NULL; vch = vch->next_in_room)
00138 {
00139 if (!IS_NPC(vch) || ch == vch)
00140 continue;
00141 if (vch->pIndexData->group == 301 && !is_safe(ch, vch))
00142 {
00143 if (number_range(0, count)==0)
00144 victim = vch;
00145 count ++;
00146 }
00147 }
00148 if (victim == NULL)
00149 return FALSE;
00150
00151 act ("$n peers around and jumps into the air, puncing onto $N!", ch, NULL, victim, TO_ALL);
00152 do_bash(ch, victim->name);
00153 return TRUE;
00154 }
00155
00156 bool spec_wolf_forest (CHAR_DATA *ch)
00157 {
00158 CHAR_DATA *vch, *victim = NULL;
00159 int count=0;
00160 char *message;
00161
00162 if (!IS_AWAKE(ch) || IS_AFFECTED(ch, AFF_CALM) || ch->in_room == NULL
00163 || IS_AFFECTED (ch, AFF_CHARM) || ch->fighting != NULL)
00164 return FALSE;
00165
00166 for (vch = ch->in_room->people;vch != NULL; vch = vch->next_in_room)
00167 {
00168 if (!IS_NPC(vch) || ch == vch)
00169 continue;
00170 if (vch->pIndexData->group == 302 &&!is_safe(ch, vch))
00171 {
00172 if (number_range(0,count)==0)
00173 victim=vch;
00174 count ++;
00175 }
00176 }
00177 if (victim == NULL)
00178 return FALSE;
00179 act ("$n licks $s lips and growls at $N, attacking", ch, NULL, victim, TO_ALL);
00180 multi_hit (ch, victim, TYPE_UNDEFINED);
00181 return TRUE;
00182 }
00183
00184
00185 bool spec_troll_member (CHAR_DATA * ch)
00186 {
00187 CHAR_DATA *vch, *victim = NULL;
00188 int count = 0;
00189 char *message;
00190
00191 if (!IS_AWAKE (ch) || IS_AFFECTED (ch, AFF_CALM) || ch->in_room == NULL
00192 || IS_AFFECTED (ch, AFF_CHARM) || ch->fighting != NULL)
00193 return FALSE;
00194
00195
00196 for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
00197 {
00198 if (!IS_NPC (vch) || ch == vch)
00199 continue;
00200
00201 if (vch->pIndexData->vnum == MOB_VNUM_PATROLMAN)
00202 return FALSE;
00203
00204 if (vch->pIndexData->group == GROUP_VNUM_OGRES
00205 && ch->level > vch->level - 2 && !is_safe (ch, vch))
00206 {
00207 if (number_range (0, count) == 0)
00208 victim = vch;
00209
00210 count++;
00211 }
00212 }
00213
00214 if (victim == NULL)
00215 return FALSE;
00216
00217
00218 switch (number_range (0, 6))
00219 {
00220 default:
00221 message = NULL;
00222 break;
00223 case 0:
00224 message = "$n yells 'I've been looking for you, punk!'";
00225 break;
00226 case 1:
00227 message = "With a scream of rage, $n attacks $N.";
00228 break;
00229 case 2:
00230 message =
00231 "$n says 'What's slimy Ogre trash like you doing around here?'";
00232 break;
00233 case 3:
00234 message = "$n cracks his knuckles and says 'Do ya feel lucky?'";
00235 break;
00236 case 4:
00237 message = "$n says 'There's no cops to save you this time!'";
00238 break;
00239 case 5:
00240 message = "$n says 'Time to join your brother, spud.'";
00241 break;
00242 case 6:
00243 message = "$n says 'Let's rock.'";
00244 break;
00245 }
00246
00247 if (message != NULL)
00248 act (message, ch, NULL, victim, TO_ALL);
00249 multi_hit (ch, victim, TYPE_UNDEFINED);
00250 return TRUE;
00251 }
00252
00253 bool spec_ogre_member (CHAR_DATA * ch)
00254 {
00255 CHAR_DATA *vch, *victim = NULL;
00256 int count = 0;
00257 char *message;
00258
00259 if (!IS_AWAKE (ch) || IS_AFFECTED (ch, AFF_CALM) || ch->in_room == NULL
00260 || IS_AFFECTED (ch, AFF_CHARM) || ch->fighting != NULL)
00261 return FALSE;
00262
00263
00264 for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
00265 {
00266 if (!IS_NPC (vch) || ch == vch)
00267 continue;
00268
00269 if (vch->pIndexData->vnum == MOB_VNUM_PATROLMAN)
00270 return FALSE;
00271
00272 if (vch->pIndexData->group == GROUP_VNUM_TROLLS
00273 && ch->level > vch->level - 2 && !is_safe (ch, vch))
00274 {
00275 if (number_range (0, count) == 0)
00276 victim = vch;
00277
00278 count++;
00279 }
00280 }
00281
00282 if (victim == NULL)
00283 return FALSE;
00284
00285
00286 switch (number_range (0, 6))
00287 {
00288 default:
00289 message = NULL;
00290 break;
00291 case 0:
00292 message = "$n yells 'I've been looking for you, punk!'";
00293 break;
00294 case 1:
00295 message = "With a scream of rage, $n attacks $N.'";
00296 break;
00297 case 2:
00298 message =
00299 "$n says 'What's Troll filth like you doing around here?'";
00300 break;
00301 case 3:
00302 message = "$n cracks his knuckles and says 'Do ya feel lucky?'";
00303 break;
00304 case 4:
00305 message = "$n says 'There's no cops to save you this time!'";
00306 break;
00307 case 5:
00308 message = "$n says 'Time to join your brother, spud.'";
00309 break;
00310 case 6:
00311 message = "$n says 'Let's rock.'";
00312 break;
00313 }
00314
00315 if (message != NULL)
00316 act (message, ch, NULL, victim, TO_ALL);
00317 multi_hit (ch, victim, TYPE_UNDEFINED);
00318 return TRUE;
00319 }
00320
00321 bool spec_patrolman (CHAR_DATA * ch)
00322 {
00323 CHAR_DATA *vch, *victim = NULL;
00324 OBJ_DATA *obj;
00325 char *message;
00326 int count = 0;
00327
00328 if (!IS_AWAKE (ch) || IS_AFFECTED (ch, AFF_CALM) || ch->in_room == NULL
00329 || IS_AFFECTED (ch, AFF_CHARM) || ch->fighting != NULL)
00330 return FALSE;
00331
00332
00333 for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
00334 {
00335 if (vch == ch)
00336 continue;
00337
00338 if (vch->fighting != NULL)
00339 {
00340 if (number_range (0, count) == 0)
00341 victim = (vch->level > vch->fighting->level)
00342 ? vch : vch->fighting;
00343 count++;
00344 }
00345 }
00346
00347 if (victim == NULL
00348 || (IS_NPC (victim)
00349 && victim->spec_fun == ch->spec_fun)) return FALSE;
00350
00351 if (((obj = get_eq_char (ch, WEAR_NECK_1)) != NULL
00352 && obj->pIndexData->vnum == OBJ_VNUM_WHISTLE)
00353 || ((obj = get_eq_char (ch, WEAR_NECK_2)) != NULL
00354 && obj->pIndexData->vnum == OBJ_VNUM_WHISTLE))
00355 {
00356 act ("You blow down hard on $p.", ch, obj, NULL, TO_CHAR);
00357 act ("$n blows on $p, ***WHEEEEEEEEEEEET***", ch, obj, NULL, TO_ROOM);
00358
00359 for (vch = char_list; vch != NULL; vch = vch->next)
00360 {
00361 if (vch->in_room == NULL)
00362 continue;
00363
00364 if (vch->in_room != ch->in_room
00365 && vch->in_room->area == ch->in_room->area)
00366 send_to_char ("You hear a shrill whistling sound.\n\r", vch);
00367 }
00368 }
00369
00370 switch (number_range (0, 6))
00371 {
00372 default:
00373 message = NULL;
00374 break;
00375 case 0:
00376 message = "$n yells 'All roit! All roit! break it up!'";
00377 break;
00378 case 1:
00379 message =
00380 "$n says 'Society's to blame, but what's a bloke to do?'";
00381 break;
00382 case 2:
00383 message = "$n mumbles 'bloody kids will be the death of us all.'";
00384 break;
00385 case 3:
00386 message = "$n shouts 'Stop that! Stop that!' and attacks.";
00387 break;
00388 case 4:
00389 message = "$n pulls out his billy and goes to work.";
00390 break;
00391 case 5:
00392 message =
00393 "$n sighs in resignation and proceeds to break up the fight.";
00394 break;
00395 case 6:
00396 message = "$n says 'Settle down, you hooligans!'";
00397 break;
00398 }
00399
00400 if (message != NULL)
00401 act (message, ch, NULL, NULL, TO_ALL);
00402
00403 multi_hit (ch, victim, TYPE_UNDEFINED);
00404
00405 return TRUE;
00406 }
00407
00408
00409 bool spec_nasty (CHAR_DATA * ch)
00410 {
00411 CHAR_DATA *victim, *v_next;
00412 long gold;
00413
00414 if (!IS_AWAKE (ch))
00415 {
00416 return FALSE;
00417 }
00418
00419 if (ch->position != POS_FIGHTING)
00420 {
00421 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00422 {
00423 v_next = victim->next_in_room;
00424 if (!IS_NPC (victim)
00425 && (victim->level > ch->level)
00426 && (victim->level < ch->level + 10))
00427 {
00428 do_function (ch, &do_backstab, victim->name);
00429 if (ch->position != POS_FIGHTING)
00430 {
00431 do_function (ch, &do_murder, victim->name);
00432 }
00433
00434
00435 return TRUE;
00436 }
00437 }
00438 return FALSE;
00439 }
00440
00441
00442 if ((victim = ch->fighting) == NULL)
00443 return FALSE;
00444
00445 switch (number_bits (2))
00446 {
00447 case 0:
00448 act ("$n rips apart your coin purse, spilling your gold!",
00449 ch, NULL, victim, TO_VICT);
00450 act ("You slash apart $N's coin purse and gather his gold.",
00451 ch, NULL, victim, TO_CHAR);
00452 act ("$N's coin purse is ripped apart!",
00453 ch, NULL, victim, TO_NOTVICT);
00454 gold = victim->gold / 10;
00455 victim->gold -= gold;
00456 ch->gold += gold;
00457 return TRUE;
00458
00459 case 1:
00460 do_function (ch, &do_flee, "");
00461 return TRUE;
00462
00463 default:
00464 return FALSE;
00465 }
00466 }
00467
00468
00469
00470
00471 bool dragon (CHAR_DATA * ch, char *spell_name)
00472 {
00473 CHAR_DATA *victim;
00474 CHAR_DATA *v_next;
00475 int sn;
00476
00477 if (ch->position != POS_FIGHTING)
00478 return FALSE;
00479
00480 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00481 {
00482 v_next = victim->next_in_room;
00483 if (victim->fighting == ch && number_bits (3) == 0)
00484 break;
00485 }
00486
00487 if (victim == NULL)
00488 return FALSE;
00489
00490 if ((sn = skill_lookup (spell_name)) < 0)
00491 return FALSE;
00492 (*skill_table[sn].spell_fun) (sn, ch->level, ch, victim, TARGET_CHAR);
00493 return TRUE;
00494 }
00495
00496
00497
00498
00499
00500
00501 bool spec_breath_any (CHAR_DATA * ch)
00502 {
00503 if (ch->position != POS_FIGHTING)
00504 return FALSE;
00505
00506 switch (number_bits (3))
00507 {
00508 case 0:
00509 return spec_breath_fire (ch);
00510 case 1:
00511 case 2:
00512 return spec_breath_lightning (ch);
00513 case 3:
00514 return spec_breath_gas (ch);
00515 case 4:
00516 return spec_breath_acid (ch);
00517 case 5:
00518 case 6:
00519 case 7:
00520 return spec_breath_frost (ch);
00521 }
00522
00523 return FALSE;
00524 }
00525
00526
00527
00528 bool spec_breath_acid (CHAR_DATA * ch)
00529 {
00530 return dragon (ch, "acid breath");
00531 }
00532
00533
00534
00535 bool spec_breath_fire (CHAR_DATA * ch)
00536 {
00537 return dragon (ch, "fire breath");
00538 }
00539
00540
00541
00542 bool spec_breath_frost (CHAR_DATA * ch)
00543 {
00544 return dragon (ch, "frost breath");
00545 }
00546
00547
00548
00549 bool spec_breath_gas (CHAR_DATA * ch)
00550 {
00551 int sn;
00552
00553 if (ch->position != POS_FIGHTING)
00554 return FALSE;
00555
00556 if ((sn = skill_lookup ("gas breath")) < 0)
00557 return FALSE;
00558 (*skill_table[sn].spell_fun) (sn, ch->level, ch, NULL, TARGET_CHAR);
00559 return TRUE;
00560 }
00561
00562
00563
00564 bool spec_breath_lightning (CHAR_DATA * ch)
00565 {
00566 return dragon (ch, "lightning breath");
00567 }
00568
00569
00570
00571 bool spec_cast_adept (CHAR_DATA * ch)
00572 {
00573 CHAR_DATA *victim;
00574 CHAR_DATA *v_next;
00575
00576 if (!IS_AWAKE (ch))
00577 return FALSE;
00578
00579 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00580 {
00581 v_next = victim->next_in_room;
00582 if (victim != ch && can_see (ch, victim) && number_bits (1) == 0
00583 && !IS_NPC (victim) && victim->level < 11)
00584 break;
00585 }
00586
00587 if (victim == NULL)
00588 return FALSE;
00589
00590 switch (number_bits (4))
00591 {
00592 case 0:
00593 act ("$n utters the word 'abrazak'.", ch, NULL, NULL, TO_ROOM);
00594 spell_armor (skill_lookup ("armor"), ch->level, ch, victim,
00595 TARGET_CHAR);
00596 return TRUE;
00597
00598 case 1:
00599 act ("$n utters the word 'fido'.", ch, NULL, NULL, TO_ROOM);
00600 spell_bless (skill_lookup ("bless"), ch->level, ch, victim,
00601 TARGET_CHAR);
00602 return TRUE;
00603
00604 case 2:
00605 act ("$n utters the words 'judicandus noselacri'.", ch, NULL,
00606 NULL, TO_ROOM);
00607 spell_cure_blindness (skill_lookup ("cure blindness"), ch->level,
00608 ch, victim, TARGET_CHAR);
00609 return TRUE;
00610
00611 case 3:
00612 act ("$n utters the words 'judicandus dies'.", ch, NULL, NULL,
00613 TO_ROOM);
00614 spell_cure_light (skill_lookup ("cure light"), ch->level, ch,
00615 victim, TARGET_CHAR);
00616 return TRUE;
00617
00618 case 4:
00619 act ("$n utters the words 'judicandus sausabru'.", ch, NULL, NULL,
00620 TO_ROOM);
00621 spell_cure_poison (skill_lookup ("cure poison"), ch->level, ch,
00622 victim, TARGET_CHAR);
00623 return TRUE;
00624
00625 case 5:
00626 act ("$n utters the word 'candusima'.", ch, NULL, NULL, TO_ROOM);
00627 spell_refresh (skill_lookup ("refresh"), ch->level, ch, victim,
00628 TARGET_CHAR);
00629 return TRUE;
00630
00631 case 6:
00632 act ("$n utters the words 'judicandus eugzagz'.", ch, NULL, NULL,
00633 TO_ROOM);
00634 spell_cure_disease (skill_lookup ("cure disease"), ch->level, ch,
00635 victim, TARGET_CHAR);
00636 }
00637
00638 return FALSE;
00639 }
00640
00641
00642
00643 bool spec_cast_cleric (CHAR_DATA * ch)
00644 {
00645 CHAR_DATA *victim;
00646 CHAR_DATA *v_next;
00647 char *spell;
00648 int sn;
00649
00650 if (ch->position != POS_FIGHTING)
00651 return FALSE;
00652
00653 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00654 {
00655 v_next = victim->next_in_room;
00656 if (victim->fighting == ch && number_bits (2) == 0)
00657 break;
00658 }
00659
00660 if (victim == NULL)
00661 return FALSE;
00662
00663 for (;;)
00664 {
00665 int min_level;
00666
00667 switch (number_bits (4))
00668 {
00669 case 0:
00670 min_level = 0;
00671 spell = "blindness";
00672 break;
00673 case 1:
00674 min_level = 3;
00675 spell = "cause serious";
00676 break;
00677 case 2:
00678 min_level = 7;
00679 spell = "earthquake";
00680 break;
00681 case 3:
00682 min_level = 9;
00683 spell = "cause critical";
00684 break;
00685 case 4:
00686 min_level = 10;
00687 spell = "dispel evil";
00688 break;
00689 case 5:
00690 min_level = 12;
00691 spell = "curse";
00692 break;
00693 case 6:
00694 min_level = 12;
00695 spell = "change sex";
00696 break;
00697 case 7:
00698 min_level = 13;
00699 spell = "flamestrike";
00700 break;
00701 case 8:
00702 case 9:
00703 case 10:
00704 min_level = 15;
00705 spell = "harm";
00706 break;
00707 case 11:
00708 min_level = 15;
00709 spell = "plague";
00710 break;
00711 default:
00712 min_level = 16;
00713 spell = "dispel magic";
00714 break;
00715 }
00716
00717 if (ch->level >= min_level)
00718 break;
00719 }
00720
00721 if ((sn = skill_lookup (spell)) < 0)
00722 return FALSE;
00723 (*skill_table[sn].spell_fun) (sn, ch->level, ch, victim, TARGET_CHAR);
00724 return TRUE;
00725 }
00726
00727 bool spec_cast_judge (CHAR_DATA * ch)
00728 {
00729 CHAR_DATA *victim;
00730 CHAR_DATA *v_next;
00731 char *spell;
00732 int sn;
00733
00734 if (ch->position != POS_FIGHTING)
00735 return FALSE;
00736
00737 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00738 {
00739 v_next = victim->next_in_room;
00740 if (victim->fighting == ch && number_bits (2) == 0)
00741 break;
00742 }
00743
00744 if (victim == NULL)
00745 return FALSE;
00746
00747 spell = "high explosive";
00748 if ((sn = skill_lookup (spell)) < 0)
00749 return FALSE;
00750 (*skill_table[sn].spell_fun) (sn, ch->level, ch, victim, TARGET_CHAR);
00751 return TRUE;
00752 }
00753
00754
00755
00756 bool spec_cast_mage (CHAR_DATA * ch)
00757 {
00758 CHAR_DATA *victim;
00759 CHAR_DATA *v_next;
00760 char *spell;
00761 int sn;
00762
00763 if (ch->position != POS_FIGHTING)
00764 return FALSE;
00765
00766 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00767 {
00768 v_next = victim->next_in_room;
00769 if (victim->fighting == ch && number_bits (2) == 0)
00770 break;
00771 }
00772
00773 if (victim == NULL)
00774 return FALSE;
00775
00776 for (;;)
00777 {
00778 int min_level;
00779
00780 switch (number_bits (4))
00781 {
00782 case 0:
00783 min_level = 0;
00784 spell = "blindness";
00785 break;
00786 case 1:
00787 min_level = 3;
00788 spell = "chill touch";
00789 break;
00790 case 2:
00791 min_level = 7;
00792 spell = "weaken";
00793 break;
00794 case 3:
00795 min_level = 8;
00796 spell = "teleport";
00797 break;
00798 case 4:
00799 min_level = 11;
00800 spell = "colour spray";
00801 break;
00802 case 5:
00803 min_level = 12;
00804 spell = "change sex";
00805 break;
00806 case 6:
00807 min_level = 13;
00808 spell = "energy drain";
00809 break;
00810 case 7:
00811 case 8:
00812 case 9:
00813 min_level = 15;
00814 spell = "fireball";
00815 break;
00816 case 10:
00817 min_level = 20;
00818 spell = "plague";
00819 break;
00820 default:
00821 min_level = 20;
00822 spell = "acid blast";
00823 break;
00824 }
00825
00826 if (ch->level >= min_level)
00827 break;
00828 }
00829
00830 if ((sn = skill_lookup (spell)) < 0)
00831 return FALSE;
00832 (*skill_table[sn].spell_fun) (sn, ch->level, ch, victim, TARGET_CHAR);
00833 return TRUE;
00834 }
00835
00836
00837
00838 bool spec_cast_undead (CHAR_DATA * ch)
00839 {
00840 CHAR_DATA *victim;
00841 CHAR_DATA *v_next;
00842 char *spell;
00843 int sn;
00844
00845 if (ch->position != POS_FIGHTING)
00846 return FALSE;
00847
00848 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00849 {
00850 v_next = victim->next_in_room;
00851 if (victim->fighting == ch && number_bits (2) == 0)
00852 break;
00853 }
00854
00855 if (victim == NULL)
00856 return FALSE;
00857
00858 for (;;)
00859 {
00860 int min_level;
00861
00862 switch (number_bits (4))
00863 {
00864 case 0:
00865 min_level = 0;
00866 spell = "curse";
00867 break;
00868 case 1:
00869 min_level = 3;
00870 spell = "weaken";
00871 break;
00872 case 2:
00873 min_level = 6;
00874 spell = "chill touch";
00875 break;
00876 case 3:
00877 min_level = 9;
00878 spell = "blindness";
00879 break;
00880 case 4:
00881 min_level = 12;
00882 spell = "poison";
00883 break;
00884 case 5:
00885 min_level = 15;
00886 spell = "energy drain";
00887 break;
00888 case 6:
00889 min_level = 18;
00890 spell = "harm";
00891 break;
00892 case 7:
00893 min_level = 21;
00894 spell = "teleport";
00895 break;
00896 case 8:
00897 min_level = 20;
00898 spell = "plague";
00899 break;
00900 default:
00901 min_level = 18;
00902 spell = "harm";
00903 break;
00904 }
00905
00906 if (ch->level >= min_level)
00907 break;
00908 }
00909
00910 if ((sn = skill_lookup (spell)) < 0)
00911 return FALSE;
00912 (*skill_table[sn].spell_fun) (sn, ch->level, ch, victim, TARGET_CHAR);
00913 return TRUE;
00914 }
00915
00916
00917 bool spec_executioner (CHAR_DATA * ch)
00918 {
00919 char buf[MAX_STRING_LENGTH];
00920 CHAR_DATA *victim;
00921 CHAR_DATA *v_next;
00922 char *crime;
00923
00924 if (!IS_AWAKE (ch) || ch->fighting != NULL)
00925 return FALSE;
00926
00927 crime = "";
00928 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
00929 {
00930 v_next = victim->next_in_room;
00931
00932 if (!IS_NPC (victim) && IS_SET (victim->act, PLR_KILLER)
00933 && can_see (ch, victim))
00934 {
00935 crime = "KILLER";
00936 break;
00937 }
00938
00939 if (!IS_NPC (victim) && IS_SET (victim->act, PLR_THIEF)
00940 && can_see (ch, victim))
00941 {
00942 crime = "THIEF";
00943 break;
00944 }
00945 }
00946
00947 if (victim == NULL)
00948 return FALSE;
00949
00950 sprintf (buf, "%s is a %s! PROTECT THE INNOCENT! MORE BLOOOOD!!!",
00951 victim->name, crime);
00952 REMOVE_BIT (ch->comm, COMM_NOSHOUT);
00953 do_function (ch, &do_yell, buf);
00954 multi_hit (ch, victim, TYPE_UNDEFINED);
00955 return TRUE;
00956 }
00957
00958
00959
00960 bool spec_fido (CHAR_DATA * ch)
00961 {
00962 OBJ_DATA *corpse;
00963 OBJ_DATA *c_next;
00964 OBJ_DATA *obj;
00965 OBJ_DATA *obj_next;
00966
00967 if (!IS_AWAKE (ch))
00968 return FALSE;
00969
00970 for (corpse = ch->in_room->contents; corpse != NULL; corpse = c_next)
00971 {
00972 c_next = corpse->next_content;
00973 if (corpse->item_type != ITEM_CORPSE_NPC)
00974 continue;
00975
00976 act ("$n savagely devours a corpse.", ch, NULL, NULL, TO_ROOM);
00977 for (obj = corpse->contains; obj; obj = obj_next)
00978 {
00979 obj_next = obj->next_content;
00980 obj_from_obj (obj);
00981 obj_to_room (obj, ch->in_room);
00982 }
00983 extract_obj (corpse);
00984 return TRUE;
00985 }
00986
00987 return FALSE;
00988 }
00989
00990
00991
00992 bool spec_guard (CHAR_DATA * ch)
00993 {
00994 char buf[MAX_STRING_LENGTH];
00995 CHAR_DATA *victim;
00996 CHAR_DATA *v_next;
00997 CHAR_DATA *ech;
00998 char *crime;
00999 int max_evil;
01000
01001 if (!IS_AWAKE (ch) || ch->fighting != NULL)
01002 return FALSE;
01003
01004 max_evil = 300;
01005 ech = NULL;
01006 crime = "";
01007
01008 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
01009 {
01010 v_next = victim->next_in_room;
01011
01012 if (!IS_NPC (victim) && IS_SET (victim->act, PLR_KILLER)
01013 && can_see (ch, victim))
01014 {
01015 crime = "KILLER";
01016 break;
01017 }
01018
01019 if (!IS_NPC (victim) && IS_SET (victim->act, PLR_THIEF)
01020 && can_see (ch, victim))
01021 {
01022 crime = "THIEF";
01023 break;
01024 }
01025
01026 if (victim->fighting != NULL
01027 && victim->fighting != ch && victim->alignment < max_evil)
01028 {
01029 max_evil = victim->alignment;
01030 ech = victim;
01031 }
01032 }
01033
01034 if (victim != NULL)
01035 {
01036 sprintf (buf, "%s is a %s! PROTECT THE INNOCENT!! BANZAI!!",
01037 victim->name, crime);
01038 REMOVE_BIT (ch->comm, COMM_NOSHOUT);
01039 do_function (ch, &do_yell, buf);
01040 multi_hit (ch, victim, TYPE_UNDEFINED);
01041 return TRUE;
01042 }
01043
01044 if (ech != NULL)
01045 {
01046 act ("$n screams 'PROTECT THE INNOCENT!! BANZAI!!",
01047 ch, NULL, NULL, TO_ROOM);
01048 multi_hit (ch, ech, TYPE_UNDEFINED);
01049 return TRUE;
01050 }
01051
01052 return FALSE;
01053 }
01054
01055
01056
01057 bool spec_janitor (CHAR_DATA * ch)
01058 {
01059 OBJ_DATA *trash;
01060 OBJ_DATA *trash_next;
01061
01062 if (!IS_AWAKE (ch))
01063 return FALSE;
01064
01065 for (trash = ch->in_room->contents; trash != NULL; trash = trash_next)
01066 {
01067 trash_next = trash->next_content;
01068 if (!IS_SET (trash->wear_flags, ITEM_TAKE) || !can_loot (ch, trash))
01069 continue;
01070 if (trash->item_type == ITEM_DRINK_CON
01071 || trash->item_type == ITEM_TRASH || trash->cost < 10)
01072 {
01073 act ("$n picks up some trash.", ch, NULL, NULL, TO_ROOM);
01074 obj_from_room (trash);
01075 obj_to_char (trash, ch);
01076 return TRUE;
01077 }
01078 }
01079
01080 return FALSE;
01081 }
01082
01083
01084
01085 bool spec_mayor (CHAR_DATA * ch)
01086 {
01087 static const char open_path[] =
01088 "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
01089
01090 static const char close_path[] =
01091 "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
01092
01093 static const char *path;
01094 static int pos;
01095 static bool move;
01096
01097 if (!move)
01098 {
01099 if (time_info.hour == 6)
01100 {
01101 path = open_path;
01102 move = TRUE;
01103 pos = 0;
01104 }
01105
01106 if (time_info.hour == 20)
01107 {
01108 path = close_path;
01109 move = TRUE;
01110 pos = 0;
01111 }
01112 }
01113
01114 if (ch->fighting != NULL)
01115 return spec_cast_mage (ch);
01116 if (!move || ch->position < POS_SLEEPING)
01117 return FALSE;
01118
01119 switch (path[pos])
01120 {
01121 case '0':
01122 case '1':
01123 case '2':
01124 case '3':
01125 move_char (ch, path[pos] - '0', FALSE);
01126 break;
01127
01128 case 'W':
01129 ch->position = POS_STANDING;
01130 act ("$n awakens and groans loudly.", ch, NULL, NULL, TO_ROOM);
01131 break;
01132
01133 case 'S':
01134 ch->position = POS_SLEEPING;
01135 act ("$n lies down and falls asleep.", ch, NULL, NULL, TO_ROOM);
01136 break;
01137
01138 case 'a':
01139 act ("$n says 'Hello Honey!'", ch, NULL, NULL, TO_ROOM);
01140 break;
01141
01142 case 'b':
01143 act
01144 ("$n says 'What a view! I must do something about that dump!'",
01145 ch, NULL, NULL, TO_ROOM);
01146 break;
01147
01148 case 'c':
01149 act
01150 ("$n says 'Vandals! Youngsters have no respect for anything!'",
01151 ch, NULL, NULL, TO_ROOM);
01152 break;
01153
01154 case 'd':
01155 act ("$n says 'Good day, citizens!'", ch, NULL, NULL, TO_ROOM);
01156 break;
01157
01158 case 'e':
01159 act ("$n says 'I hereby declare the city of Midgaard open!'",
01160 ch, NULL, NULL, TO_ROOM);
01161 break;
01162
01163 case 'E':
01164 act ("$n says 'I hereby declare the city of Midgaard closed!'",
01165 ch, NULL, NULL, TO_ROOM);
01166 break;
01167
01168 case 'O':
01169
01170 do_function (ch, &do_open, "gate");
01171 break;
01172
01173 case 'C':
01174 do_function (ch, &do_close, "gate");
01175
01176 break;
01177
01178 case '.':
01179 move = FALSE;
01180 break;
01181 }
01182
01183 pos++;
01184 return FALSE;
01185 }
01186
01187
01188
01189 bool spec_poison (CHAR_DATA * ch)
01190 {
01191 CHAR_DATA *victim;
01192
01193 if (ch->position != POS_FIGHTING
01194 || (victim = ch->fighting) == NULL
01195 || number_percent () > 2 * ch->level) return FALSE;
01196
01197 act ("You bite $N!", ch, NULL, victim, TO_CHAR);
01198 act ("$n bites $N!", ch, NULL, victim, TO_NOTVICT);
01199 act ("$n bites you!", ch, NULL, victim, TO_VICT);
01200 spell_poison (gsn_poison, ch->level, ch, victim, TARGET_CHAR);
01201 return TRUE;
01202 }
01203
01204
01205
01206 bool spec_thief (CHAR_DATA * ch)
01207 {
01208 CHAR_DATA *victim;
01209 CHAR_DATA *v_next;
01210 long gold, silver;
01211
01212 if (ch->position != POS_STANDING)
01213 return FALSE;
01214
01215 for (victim = ch->in_room->people; victim != NULL; victim = v_next)
01216 {
01217 v_next = victim->next_in_room;
01218
01219 if (IS_NPC (victim)
01220 || victim->level >= LEVEL_IMMORTAL
01221 || number_bits (5) != 0 || !can_see (ch, victim))
01222 continue;
01223
01224 if (IS_AWAKE (victim) && number_range (0, ch->level) == 0)
01225 {
01226 act ("You discover $n's hands in your wallet!",
01227 ch, NULL, victim, TO_VICT);
01228 act ("$N discovers $n's hands in $S wallet!",
01229 ch, NULL, victim, TO_NOTVICT);
01230 return TRUE;
01231 }
01232 else
01233 {
01234 gold =
01235 victim->gold * UMIN (number_range (1, 20),
01236 ch->level / 2) / 100;
01237 gold = UMIN (gold, ch->level * ch->level * 10);
01238 ch->gold += gold;
01239 victim->gold -= gold;
01240 silver =
01241 victim->silver * UMIN (number_range (1, 20),
01242 ch->level / 2) / 100;
01243 silver = UMIN (silver, ch->level * ch->level * 25);
01244 ch->silver += silver;
01245 victim->silver -= silver;
01246 return TRUE;
01247 }
01248 }
01249
01250 return FALSE;
01251 }