/*************************************************************************** * 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. * ***************************************************************************/ #include <glib.h> #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <merc.h> #include <tables.h> #include <interp.h> #include <fight.h> void set_attack_flag(CHAR_DATA *ch, CHAR_DATA *victim) { if ( ch == victim ) return; if (ch == NULL || victim == NULL) return; if (IS_NPC(ch) || IS_NPC(victim)) return; /* Attack Flag Check */ if (!CAN_PK(ch) || !CAN_PK(victim)) return; if (IS_SABBAT(victim)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_SABBAT)) SET_BIT(ch->pk_sect, ATTACK_SABBAT); } else if (IS_FOLLOWERS(victim)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_SABBAT)) SET_BIT(ch->pk_sect, ATTACK_FOLLOWERS); } else if (IS_CAMARILLA(victim)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_CAMARILLA)) SET_BIT(ch->pk_sect, ATTACK_CAMARILLA); } else if (IS_WYRM(victim)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_WYRM)) SET_BIT(ch->pk_sect, ATTACK_WYRM); } else if (IS_PACK(victim)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_PACK)) SET_BIT(ch->pk_sect, ATTACK_PACK); } else if (IS_CLASS(victim,CLASS_VAMPIRE)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_VAMP)) SET_BIT(ch->pk_sect, ATTACK_VAMP); } else if (IS_CLASS(victim,CLASS_MAGE)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_MAGE)) SET_BIT(ch->pk_sect, ATTACK_MAGE); } else if (IS_SWWF(victim)) { ch->attack_timer = 8; if (!IS_SET(ch->act, PLR_ATTACK)) SET_BIT(ch->act, PLR_ATTACK); if (!IS_SET(ch->pk_sect, ATTACK_WWF)) SET_BIT(ch->pk_sect, ATTACK_WWF); } return; } bool check_pk_range(CHAR_DATA *ch, CHAR_DATA *victim) { int chclass,victimclass; if (ch->race <= 0 ) chclass = 0; else if (ch->race <= 4 ) chclass = 1; else if (ch->race <= 9 ) chclass = 2; else if (ch->race <= 14) chclass = 3; else if (ch->race <= 19) chclass = 4; else if (ch->race <= 24) chclass = 5; else chclass = 6; if (victim->race <= 0 ) victimclass = 0; else if (victim->race <= 4 ) victimclass = 1; else if (victim->race <= 9 ) victimclass = 2; else if (victim->race <= 14) victimclass = 3; else if (victim->race <= 19) victimclass = 4; else if (victim->race <= 24) victimclass = 5; else victimclass = 6; if ( chclass > victimclass ) return TRUE; else return FALSE; } bool check_pk(CHAR_DATA *ch, CHAR_DATA *victim,int flag) { /* Universal Check all by Spiralsoft(tm) <g> */ bool pksect = FALSE; bool canpk = FALSE; if ( ch == NULL || victim == NULL) return FALSE; if (IS_NPC(victim) || IS_NPC(ch)) return FALSE; if (!CAN_PK(ch) || !CAN_PK(victim)) return TRUE; if (IS_SET(flag,CHECK_DELAY)) { if (HAS_DELAY(ch) || HAS_DELAY(victim)) { if (IS_NPC(victim)) { bug("Damn mobs.",0); return FALSE; } send_to_char("You or your victim has a delay timer, please wait to attack (type 'help wait' for more info.)\n\r",ch); return TRUE; } } if (IS_ITEMAFF(victim, ITEMA_ARTIFACT)){ return FALSE; } canpk = check_pk_range(ch,victim); if (IS_SET(flag,CHECK_ATTACK)) { /* Check for attack flag */ if ( canpk && !IS_SET(victim->act,PLR_ATTACK)) { send_to_char("Go pick on someone else.\n\r",ch); return TRUE; } if (IS_SET(victim->act,PLR_ATTACK) && canpk ) { /* Check for Sect, this is done by bit */ if (IS_SET(victim->pk_sect,ATTACK_SABBAT) && !IS_SABBAT(ch)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_FOLLOWERS) && !IS_FOLLOWERS(ch)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_CAMARILLA) && !IS_CAMARILLA(ch)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_WYRM) && !IS_WYRM(ch)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_PACK) && !IS_PACK(ch)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_VAMP) && !IS_CLASS(ch,CLASS_VAMPIRE)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_WWF) && !IS_CLASS(ch,CLASS_WEREWOLF)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_MAGE) && !IS_CLASS(ch,CLASS_MAGE)) pksect = TRUE; if (IS_SET(victim->pk_sect,ATTACK_ANYONE)) pksect = TRUE; if (pksect == TRUE) { send_to_char("They did nothing to you or your sect, you can't attack them.\n\r",ch); return TRUE; } } } return FALSE; } bool check_safe_imm(CHAR_DATA *ch) { CHAR_DATA *wch; for (wch = char_list; wch != NULL; wch = wch->next) { if (wch->in_room == NULL) continue; if (!IS_NPC(wch) && wch->in_room == ch->in_room && IS_IMMORTAL(wch) && IS_SET(wch->pcdata->comm, COMM_IMM_SAFE)) return TRUE; } return FALSE; } bool is_tempsafe( CHAR_DATA *ch ) { if ( ch->fighting == NULL && ch->in_room != NULL && IS_SET(ch->in_room->room_flags,ROOM_SAFE) ) { switch (weather_info[ch->in_room->sector_type].sunlight) { case SUN_DARK: return FALSE; case SUN_LIGHT: case SUN_SET: case SUN_RISE: return TRUE; } } return FALSE; } bool is_safe( CHAR_DATA *ch, CHAR_DATA *victim ) { /* Ethereal people can only attack other ethereal people */ if (ch->plane != victim->plane){ send_to_char("They are not on this plane.\n\r",ch); return TRUE; } if ( ch->in_room != NULL && IS_SET(ch->in_room->room_flags,ROOM_SAFE) && victim->pk_timer < 1) { switch (weather_info[ch->in_room->sector_type].sunlight) { case SUN_DARK: break; case SUN_LIGHT: case SUN_SET: case SUN_RISE: send_to_char( "You cannot fight in a safe room during the daytime.\n\r", ch ); return TRUE; } } if ( IS_HEAD(ch,LOST_HEAD) || IS_EXTRA(ch,EXTRA_OSWITCH) ) { send_to_char( "Objects cannot fight!\n\r", ch ); return TRUE; } else if ( IS_HEAD(victim,LOST_HEAD) || IS_EXTRA(victim,EXTRA_OSWITCH)) { send_to_char( "You cannot attack an object.\n\r", ch ); return TRUE; } if ( IS_NPC(ch) || IS_NPC(victim) ) return FALSE; /* Thx Josh! */ if ( victim->fighting == ch ) return FALSE; if (IS_ITEMAFF(ch, ITEMA_PEACE)) { send_to_char( "You are unable to attack them.\n\r", ch ); return TRUE; } switch(ch->plane) { case PLANE_SPIRIT: return TRUE; case PLANE_PUNISHMENT: return TRUE; case PLANE_IMMORTAL: return TRUE; } if (IS_ITEMAFF(victim, ITEMA_PEACE)) { send_to_char( "You can't seem to attack them.\n\r", ch ); return TRUE; } if ( check_pk(ch,victim,CHECK_DELAY)) { return TRUE; } if ( ch->trust > LEVEL_BUILDER ) { send_to_char( "You cannot fight if you have implementor powers!\n\r", ch ); return TRUE; } if ( victim->trust > LEVEL_BUILDER ) { send_to_char( "You cannot fight someone with implementor powers!\n\r", ch ); return TRUE; } if ( !CAN_PK(ch) || !CAN_PK(victim) ) { send_to_char( "Both players must be avatars to fight.\n\r", ch ); return TRUE; } if ( ch->desc == NULL || ( victim->desc == NULL && victim->pk_timer < 1 )) { if (victim->position != POS_FIGHTING) { send_to_char( "They are currently link dead with no combat timer.\n\r", ch ); send_to_char( "Are you that much of a pussy that you have to kill link dead?\n\r", ch ); return TRUE; } } return FALSE; } bool no_attack( CHAR_DATA *ch, CHAR_DATA *victim ) { /* Ethereal people can only attack other ethereal people */ if (ch->plane != victim->plane){ send_to_char("They are not on this plane.\n\r",ch); return TRUE; } if ( ch->in_room != NULL && is_safe(ch,victim) ) { send_to_char( "You cannot fight in a safe room.\n\r", ch ); return TRUE; } if ( IS_HEAD(ch,LOST_HEAD) || IS_EXTRA(ch,EXTRA_OSWITCH) ) { send_to_char( "Objects cannot fight!\n\r", ch ); return TRUE; } else if ( IS_HEAD(victim,LOST_HEAD) || IS_EXTRA(victim,EXTRA_OSWITCH) ) { send_to_char( "You cannot attack objects.\n\r", ch ); return TRUE; } return FALSE; } /* * See if an attack justifies a KILLER flag. */ void check_killer( CHAR_DATA *ch, CHAR_DATA *victim ) { /* * Follow charm thread to responsible character. * Attacking someone's charmed char is hostile! */ while ( IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL ) victim = victim->master; /* * NPC's are fair game. * So are killers and thieves. */ if ( IS_NPC(victim) ) return; /* * Charm-o-rama. */ if ( IS_SET(ch->affected_by, AFF_CHARM) ) { if ( ch->master == NULL ) { affect_strip( ch, gsn_charm_person ); REMOVE_BIT( ch->affected_by, AFF_CHARM ); return; } stop_follower( ch ); return; } return; } void calc_stat(CHAR_DATA *ch, CHAR_DATA *victim) { /* Check for attack flag */ if ( victim->race >= ch->race && victim->race > 0 ) { ch->race++; victim->race--; } ch->pkill++; victim->pdeath++; }