/*************************************************************************** * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * * Chastain, Michael Quan, and Mitchell Tse. * * * * * * In order to use any part of this Merc Diku Mud, you must comply with * * * both the original Diku license in 'license.doc' as well the Merc * * * license in 'license.txt'. In particular, you may not remove either of * * * these copyright notices. * * * * * * Much time and thought has gone into this software and you are * * * benefitting. We hope that you share your changes too. What goes * * * around, comes around. * * ****************************************************************************/ /*************************************************************************** * * ROM 2.4 is copyright 1993-1998 Russ Taylor * * * ROM has been brought to you by the ROM consortium * * * Russ Taylor (rtaylor@hypercube.org) * * * Gabrielle Taylor (gtaylor@hypercube.org) * * * Brian Moore (zump@rom.org) * * * By using this code, you have agreed to follow the terms of the * * * ROM license, in the file Rom24/doc/rom.license * * ****************************************************************************/ #include <sys/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <ctype.h> #include <unistd.h> #include "merc.h" #include "interp.h" #include "clans/new_clans.h" #include "clans/new_clans_comm.h" #include "clans/new_clans_io.h" #include "clans/new_clans_util.h" //Iblis - created this file since fight.c is so fucking big, all new fight stuff goes here void pk_chan args((char* text)); //Iblis - Kalian fear skill void do_fear (CHAR_DATA* ch, char* argument) { CHAR_DATA *victim, *victim_next; ROOM_INDEX_DATA *was_in, *now_in; int attempt; if (get_skill(ch,gsn_fear) < 1) { send_to_char("If you dressed up as a mouse, even an elephant wouldn't be scared of you.\n\r",ch); return; } if (is_affected (ch, gsn_fear)) { send_to_char ("You are way too scared to consider scaring anyone.\n\r", ch); return; } if (IS_AFFECTED (ch, AFF_CALM) || is_affected (ch, skill_lookup ("Quiet Mountain Lake"))) { send_to_char ("You are feeling too mellow to frighten anyone.\n\r", ch); return; } WAIT_STATE (ch, skill_table[gsn_fear].beats); send_to_char("You attempt to strike fear into your assailants.\n\r",ch); for (victim = ch->in_room->people; victim != NULL; victim = victim_next) { victim_next = victim->next_in_room; if (victim == ch) continue; if (get_position(victim) <= POS_SLEEPING || victim->position == POS_MOUNTED) continue; if (IS_AFFECTED (victim, AFF_CALM)) continue; if (!IS_NPC(victim) && victim->class == PC_CLASS_CHAOS_JESTER) continue; if (IS_NPC (victim) && (victim->pIndexData->pShop != NULL || IS_SET (victim->act, ACT_TRAIN) || IS_SET (victim->act, ACT_PRACTICE) || IS_SET (victim->act, ACT_IS_HEALER) || IS_SET (victim->act2, ACT_NOMOVE))) continue; if (saves_spell (ch->level, victim, DAM_MENTAL)) continue; if (get_skill(ch,gsn_fear) < number_percent()) continue; if (ch->fighting != victim && victim->fighting != ch) continue; if (victim->position == POS_RESTING || victim->position == POS_SITTING) do_stand (victim, ""); was_in = victim->in_room; for (attempt = 0; attempt < 6; attempt++) { EXIT_DATA *pexit; int door; AFFECT_DATA af; door = attempt; if ((pexit = was_in->exit[door]) == 0 || pexit->u1.to_room == NULL || number_percent() < 50 || IS_SET (pexit->exit_info, EX_CLOSED) || (IS_NPC (victim) && IS_SET (pexit->u1.to_room->room_flags, ROOM_NO_MOB))) continue; act ("You have struck fear directly into $N's heart, causing $M to flee with terror.", ch, NULL, victim, TO_CHAR); act ("$N has struck fear directly into $n's heart, causing $m to flee with terror.", victim, NULL, ch, TO_NOTVICT); act ("$N has struck fear directly into your heart, causing you to you flee for your life.", victim, NULL, ch, TO_CHAR); move_char (victim, door, FALSE); af.where = TO_AFFECTS; af.type = gsn_fear; af.level = ch->level; af.duration = number_range(0,(ch->level > 75)?2:1); af.location = APPLY_HITROLL; af.permaff = FALSE; af.composition = FALSE; af.comp_name = str_dup (""); if (!IS_NPC (victim)) af.modifier = -5; else af.modifier = -2; af.bitvector = AFF_CALM; affect_to_char (victim, &af); if ((now_in = victim->in_room) != was_in) break; } if ((now_in = victim->in_room) == was_in) continue; stop_fighting (victim, TRUE); } } //Iblis - Kalian illusion skill void do_illusion (CHAR_DATA* ch, char* argument) { CHAR_DATA *victim;//, *victim_next; MOB_INDEX_DATA* pMobIndex; char buf[MAX_STRING_LENGTH]; if (get_skill(ch,gsn_illusion) < 1) { send_to_char("You attempt to make an illusion, but alas, you have NO skill.\n\r",ch); return; } if ((pMobIndex = get_mob_index (MOB_VNUM_ILLUSION)) == NULL) { send_to_char ("No mob has that vnum.\n\r", ch); return; } if (IS_NPC(ch)) return; if (ch->mana < 150 || ch->il_ticks != 0) { send_to_char ("You do not have the strength to make an illusion.\n\r",ch); return; } ch->mana -= 150; ch->il_ticks = 24; victim = create_mobile (pMobIndex); SET_BIT(victim->act, ACT_SENTINEL); SET_BIT(victim->act2, ACT_ILLUSION); SET_BIT(victim->act2, ACT_NOMOVE); free_string(victim->name); victim->name = str_dup(ch->name); free_string(victim->short_descr); victim->short_descr = str_dup(ch->name); free_string(victim->long_descr); strcpy(buf,"`g"); strcat(buf,capitalize(ch->name)); strcat(buf,ch->pcdata->title); strcat(buf,"`` is here.\n\r"); victim->long_descr = str_dup(buf); victim->ticks_remaining = ch->level/10; char_to_room (victim, ch->in_room); act("An illusion appears out of thin air.\n\r",ch,NULL,NULL,TO_ROOM); send_to_char("You successfully conjure an illusion.\n\r",ch); WAIT_STATE (ch, skill_table[gsn_illusion].beats); } //Iblis - sets oneself killable (turns off multikill protection) void do_killable(CHAR_DATA* ch, char* argument) { char buf[MAX_STRING_LENGTH]; if (IS_NPC(ch)) return; // if (current_time - ch->pcdata->last_pkdeath < (60*MULTIKILL_WAIT_TIME)) if (ch->pcdata->last_pkdeath != 0) { ch->pcdata->last_pkdeath = 0; send_to_char("You have declared yourself killable to the world.\n\r",ch); sprintf(buf,"`l%s's `kprotective aura fades.``",ch->name); pk_chan(buf); WAIT_STATE (ch, PULSE_VIOLENCE*5); } else { send_to_char("The world already knows you can be killed. Apparently you forgot, though.\n\r",ch); return; } } //Iblis - Kalian suck skill void do_suck (CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam, multiplier; if (!IS_NPC (ch) && ch->level < level_for_skill (ch, gsn_suck)) { send_to_char ("You better leave sucking to the Kalians.\n\r", ch); return; } if (get_skill (ch, gsn_suck) < 1) { send_to_char ("You don't know how to suck (yes you are very stupid)!\n\r", ch); return; } multiplier = 1; if (argument[0] == '\0') { if ((victim = ch->fighting) == NULL) { send_to_char ("You aren't fighting anyone.\n\r", ch); return; } } else if ((victim = get_char_room (ch, argument)) == NULL) { send_to_char ("They aren't here.\n\r", ch); return; } if (ch == victim) { send_to_char("You suck yourself, and you enjoy it fully.\n\r",ch); return; } if (ch->fighting == NULL && ch->position == POS_STANDING) multiplier *= 2; WAIT_STATE (ch, skill_table[gsn_suck].beats); if (get_skill (ch, gsn_suck) > number_percent ()) { dam = 2*number_range (1, ch->level)*multiplier; if (IS_SET(victim->act,ACT_UNDEAD)) dam=0; if (dam > 0 && check_immune (victim, DAM_NEGATIVE) != IS_IMMUNE && !(is_safe (ch, victim))) { act ("$N's vampiric bite `bdraws`` life from $n.", victim, NULL, ch, TO_NOTVICT); act ("Your vampiric bite `bdraws`` life from $n.", victim, NULL, ch, TO_VICT); act ("You feel $N's vampiric bite `bdrawing`` your life away.", victim, NULL, ch, TO_CHAR); damage_old (ch, victim, dam, gsn_suck, DAM_NEGATIVE, FALSE); if ( time_info.hour > 18 && time_info.hour < 5) multiplier *= 2; ch->hit += (((dam/9) < 5)?5:dam/9*multiplier); } else { act ("You miss $n completely. Can you even attack them?", victim, NULL, ch, TO_VICT); } check_improve (ch, gsn_suck, TRUE, 1); } else { damage (ch, victim, 0, gsn_suck, DAM_VAMPIRIC, FALSE); act ("$N's vampiric bite `imisses`` $n.", victim, NULL, ch, TO_NOTVICT); act ("Your vampiric bite `bmisses`` $n.", victim, NULL, ch, TO_VICT); act ("You watch as $N's vampiric bite `bmisses ``you.", victim, NULL, ch, TO_CHAR); check_improve (ch, gsn_suck, FALSE, 1); } return; } //Iblis - A function to adjust the damage so it does the damage the code says it should //(IE it makes it high enough so after dam adjusting code in damage() it does //the correct amound of damage int adjust_damage(int dam_to_do) { int damage; if (dam_to_do < 35) return dam_to_do; if (dam_to_do <= 80) { damage = ((dam_to_do-35)*2)+35; } else { damage = ( (( ((dam_to_do-80)*2) +45)*2) +35); } return damage; } //Iblis - toggle for the ranger aggression skill void do_aggression (CHAR_DATA * ch, char *argument) { if (get_skill (ch, gsn_aggression) < 1 || IS_NPC(ch)) { send_to_char ("You don't know how to be aggressive!\n\r", ch); return; } if (!str_cmp(argument,"rage")) { if (ch->pcdata->aggression) { send_to_char("You get a little more aggressive.\n\r",ch); return; } else { ch->pcdata->aggression = 1; send_to_char("`iYou are overcome with the desire to kill!\n\r",ch); act("$n's skin turns red as $e works $mself into a frenzy!",ch,NULL,NULL,TO_ROOM); WAIT_STATE (ch, skill_table[gsn_aggression].beats); return; } } if(!str_cmp(argument,"calm")) { if (!ch->pcdata->aggression) { send_to_char("A relaxing massage couldn't get you any calmer.\n\r",ch); return; } else { ch->pcdata->aggression = 0; send_to_char("You close your eyes and take deep breaths to calm yourself down.\n\r",ch); act("$n closes $s eyes and takes deep breaths to calm down.\n\r",ch,NULL,NULL,TO_ROOM); WAIT_STATE (ch, skill_table[gsn_aggression].beats); return; } } send_to_char("You are currently ",ch); if (ch->pcdata->aggression) send_to_char("overcome with a desire to kill anything that crosses your path.\n\r",ch); else send_to_char("without a care in the world.\n\r",ch); } //Iblis - simple function which checks aggression should be triggered when ch enters a room bool check_aggression(CHAR_DATA *ch) { int i = 0; int counter = 0; CHAR_DATA *tch=NULL; if (IS_NPC(ch)) return FALSE; if (ch->pcdata->aggression && (ch->pcdata->loner || ch->clan != CLAN_BOGUS)) { for(tch = ch->in_room->people;tch != NULL;tch = tch->next_in_room) { if (!IS_NPC(tch) && ch != tch && (tch->pcdata->loner || tch->clan != CLAN_BOGUS) && can_see(ch,tch) && !IS_IMMORTAL(tch)) ++counter; } if (counter > 0) { counter = number_range(1,counter); for(tch = ch->in_room->people;tch != NULL;tch = tch->next_in_room) { if (!IS_NPC(tch) && ch != tch && (tch->pcdata->loner || tch->clan != CLAN_BOGUS) && can_see(ch,tch) && !IS_IMMORTAL(tch)) if (counter == ++i) { act("`i$n snarls and throws $mself at you!``",ch,NULL,tch,TO_VICT); act("`i$n snarls and throws $mself at $N!``",ch,NULL,tch,TO_NOTVICT); do_kill(ch,tch->name); return TRUE; } } } else return FALSE; } else { for (tch = ch->in_room->people;tch != NULL;tch = tch->next_in_room) if (!IS_NPC(tch) && tch->pcdata->aggression && (tch->pcdata->loner || tch->clan != CLAN_BOGUS) && tch->fighting == NULL && can_see(tch,ch)) { act("`i$n snarls and throws $mself at you!``",tch,NULL,ch,TO_VICT); act("`i$n snarls and throws $mself at $N!``",tch,NULL,ch,TO_NOTVICT); do_kill(tch,ch->name); return TRUE; } } return FALSE; } //Iblis - function called in fight.c when a stun hits void stun_char(CHAR_DATA *ch, CHAR_DATA *victim) { short stunamount; if (victim->stunned) return; stunamount = number_range(1,3); if (victim->stunned > 0) victim->stunned += stunamount; else victim->stunned = stunamount; WAIT_STATE (victim, 12*stunamount); act ("`bYou strike a powerful blow to $N's `bnerve center, stunning $M.``", ch, NULL, victim, TO_CHAR); act ("`b$n strikes you with a powerful blow that makes you go numb.``", ch, NULL, victim, TO_VICT); act ("`b$n stuns $N `bwith a powerful strike, temporarily paralyzing $M.``", ch, NULL, victim, TO_NOTVICT); return; } //Iblis - Nidae spear skill void do_spear (CHAR_DATA *ch, char *argument) { int chance; CHAR_DATA *victim; if ((chance = get_skill(ch,gsn_spear)) < 1) { send_to_char("You pretend to get speared through the heart, but no one is buying it.\n\r",ch); return; } if (argument[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char ("But you aren't fighting anyone!\n\r", ch); return; } } else if ((victim = get_char_room (ch, argument)) == NULL) { send_to_char ("They aren't here.\n\r", ch); return; } if (is_safe (ch, victim)) return; if (IS_AFFECTED (ch, AFF_CHARM) && ch->master == victim) { act ("But $N is your friend!", ch, NULL, victim, TO_CHAR); return; } if (IS_AFFECTED (ch, AFF_CALM) || is_affected (ch, skill_lookup ("Quiet Mountain Lake"))) { send_to_char ("You are feeling too peaceful to do that now.\n\r", ch); return; } if (ch->hit < 15) { send_to_char("You do not have enough within you to create a spear.\n\r",ch); return; } else ch->hit -= 15; WAIT_STATE (ch, skill_table[gsn_spear].beats); if (chance > number_percent ()) { act("You summon your strength to form a spear made of pure ice and throw it at $N.",ch,NULL,victim,TO_CHAR); act("$n seems to get a little shorter as $e forms a spear of ice and throw it at $N.",ch,NULL,victim,TO_NOTVICT); act("$n seems to get a little shorter as $e forms a spear of ice and throw it at you.",ch,NULL,victim,TO_VICT); damage (ch, victim, ch->level-14 + dice(1,10), gsn_spear, DAM_COLD, TRUE); return; } else { act("You summon your strength to form a spear made of pure ice and throw it at $N.",ch,NULL,victim,TO_CHAR); act("$n seems to get a little shorter as $e forms a spear of ice and throw it at $N.",ch,NULL,victim,TO_NOTVICT); act("$n seems to get a little shorter as $e forms a spear of ice and throw it at you.",ch,NULL,victim,TO_VICT); damage (ch, victim, 0, gsn_spear, DAM_COLD, TRUE); return; } } void larva_hit(CHAR_DATA *ch,CHAR_DATA *victim) { AFFECT_DATA *paf, af; for (paf = victim->affected; paf != NULL; paf = paf->next) { if (paf->type == gsn_larva) break; } if (paf == NULL) { af.where = TO_AFFECTS; af.type = gsn_larva; af.level = ch->level * 3 / 4; af.duration = 10; af.location = APPLY_NONE; af.modifier = 5; af.bitvector = 0; af.permaff = FALSE; af.composition = FALSE; af.comp_name = str_dup (ch->name); affect_join (victim, &af); } else { af.where = TO_AFFECTS; af.type = gsn_larva; af.level = ch->level * 3 / 4; af.duration = paf->duration; af.location = APPLY_NONE; af.modifier = paf->modifier; af.bitvector = 0; af.permaff = FALSE; af.composition = FALSE; af.comp_name = str_dup (ch->name); af.duration += 10; if (af.duration > 20) af.duration = 20; af.modifier += 1; if (af.modifier > 10) af.modifier = 10; affect_remove(victim,paf); affect_to_char(victim,&af); } }