/*************************************************************************** * 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-1996 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Tartarus/doc/rom.license * ***************************************************************************/ /*************************************************************************** * Tartarus code is copyright (C) 1997-1998 by Daniel Graham * * In using this code you agree to comply with the Tartarus license * * found in the file /Tartarus/doc/tartarus.doc * ***************************************************************************/ /*************************************************************************** * POSmud code is copyright (C) 1999-2000 and for exclusive use of * * POSmud only. Hah! * ***************************************************************************/ #include "include.h" #define HITS (dt==gsn_kick||dt==gsn_lunge||dt==gsn_downstrike||dt==gsn_throw||dt==gsn_crush||dt==gsn_bash) /* command procedures needed */ DECLARE_DO_FUN(do_quit); DECLARE_DO_FUN(do_say); DECLARE_DO_FUN(do_backstab ); DECLARE_DO_FUN(do_emote ); DECLARE_DO_FUN(do_ambush ); DECLARE_DO_FUN(do_berserk ); DECLARE_DO_FUN(do_deathstyle ); DECLARE_DO_FUN(do_bash ); DECLARE_DO_FUN(do_trip ); DECLARE_DO_FUN(do_dirt ); DECLARE_DO_FUN(do_flee ); DECLARE_DO_FUN(do_kick ); DECLARE_DO_FUN(do_disarm ); DECLARE_DO_FUN(do_get ); DECLARE_DO_FUN(do_recall ); DECLARE_DO_FUN(do_yell ); DECLARE_DO_FUN(do_myell ); DECLARE_DO_FUN(do_sacrifice ); DECLARE_DO_FUN(do_circle_stab ); DECLARE_DO_FUN(do_battlecry ); DECLARE_DO_FUN(do_steel_nerves ); DECLARE_DO_FUN(do_look); DECLARE_DO_FUN(do_crush); DECLARE_DO_FUN(do_tail ); DECLARE_DO_FUN(do_undead_drain); DECLARE_DO_FUN(do_executioners_grace); DECLARE_DO_FUN(do_bind); DECLARE_DO_FUN(do_unbind); DECLARE_DO_FUN(do_blitz); DECLARE_SPELL_FUN(spell_evil_eye); DECLARE_SPELL_FUN(spell_power_word_kill); DECLARE_DO_FUN(do_echo); DECLARE_DO_FUN(do_help); DECLARE_DO_FUN(do_cb); DECLARE_DO_FUN(do_ccb); //DECLARE_DO_FUN(do_arena_echo); void temp_death_log(CHAR_DATA *killer, CHAR_DATA *dead); void perm_death_log(CHAR_DATA *ch, int deltype); /* * Local functions. */ void check_downstrike args( (CHAR_DATA *ch, CHAR_DATA *victim) ); void check_assist args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); bool check_dodge args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); bool check_questdodge args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); bool check_block args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); void check_killer args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); bool check_parry args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); //bool check_flourintine args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); bool check_spin args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); bool check_displacement args( (CHAR_DATA *ch, CHAR_DATA *victim) ); bool check_defiant_absorb args((CHAR_DATA *ch, CHAR_DATA *victim, int dt )); bool check_shield_block args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); void dam_message args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dam,int dt, bool immune ) ); void death_cry args( ( CHAR_DATA *ch ) ); void group_gain args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); int xp_compute args( ( CHAR_DATA *gch, CHAR_DATA *victim,int group_amount, int glevel ) ); bool is_safe args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); void make_corpse args( ( CHAR_DATA *killer, CHAR_DATA *ch ) ); void one_hit args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt )); void mob_hit args( ( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) ); void raw_kill args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); void disarm args( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); int battlecry_multiplier args( ( CHAR_DATA *ch, int dt) ); void do_counter_parry args( (CHAR_DATA *ch,CHAR_DATA *victim, int dt,int dam) ); void check_ground_control args( (CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam) ); void check_ranger_staff args( (CHAR_DATA *ch,OBJ_DATA *wield) ); void check_clown_mallet args( (int level,CHAR_DATA *ch,CHAR_DATA *victim, OBJ_DATA *wield) ); void golden_weapon args( (CHAR_DATA *ch,OBJ_DATA *wield) ); void check_ceial_tat args ( (CHAR_DATA *ch) ); void check_outlaw_badge args( (CHAR_DATA *ch) ); bool check_counter args( (CHAR_DATA *ch,CHAR_DATA *victim, int dam,int dt) ); bool check_palm args( (CHAR_DATA *ch ) ); void check_follow_through args( ( CHAR_DATA *ch, CHAR_DATA *victim,int dam) ); bool check_roll args( (CHAR_DATA *ch,CHAR_DATA *victim,int dt) ); void check_red_shield args(( CHAR_DATA *ch) ); void check_bracelets args((CHAR_DATA *ch)); void wing_beating args((CHAR_DATA *ch) ); void etched_pendant args((CHAR_DATA *ch) ); void hammer_pendant args((CHAR_DATA *ch) ); void kyr_tattoo args((CHAR_DATA *ch,CHAR_DATA *victim) ); void dev_tattoo args((CHAR_DATA *ch,CHAR_DATA *victim) ); void cei_tattoo(CHAR_DATA *ch); void deo_tattoo args( (CHAR_DATA *ch, CHAR_DATA *victim) ); void gra_tattoo args( (CHAR_DATA *ch, CHAR_DATA *victim) ); void mer_tattoo(CHAR_DATA *ch); void kra_tattoo args((CHAR_DATA *ch,CHAR_DATA *victim) ); void xanthr_tattoo args((CHAR_DATA *ch,CHAR_DATA *victim) ); bool check_crown_blood args((CHAR_DATA *ch,CHAR_DATA *victim,int dt, int dam, int dam_type)); void check_blue_talon args((CHAR_DATA *ch, CHAR_DATA *victim)); int check_cutter args((CHAR_DATA *ch,CHAR_DATA *victim)); bool eye_of_beholder_absorb args((CHAR_DATA *ch,CHAR_DATA *victim, int dt, int dam, int dam_type)); void do_strap args((CHAR_DATA *victim,OBJ_DATA *strap)); bool check_unholy_bless args((CHAR_DATA *ch, CHAR_DATA *victim)); void check_cheap_shot args((CHAR_DATA *ch, CHAR_DATA *victim)); void check_parting_blow args((CHAR_DATA *ch, CHAR_DATA *victim)); bool arena; bool check_distance args((CHAR_DATA *ch, CHAR_DATA *victim, int dt )); bool check_ironhands args((CHAR_DATA *ch, CHAR_DATA *victim, int dt )); bool check_unarmed_defense args((CHAR_DATA *ch, CHAR_DATA *victim, int dt )); char *get_dam_message args((CHAR_DATA *ch, int dt)); char * get_attack_noun args((CHAR_DATA *ch, int dt)); int get_attack_number args((CHAR_DATA *ch, int dt)); bool check_dispel( int dis_level, CHAR_DATA *victim, int sn); bool check_cutoff(CHAR_DATA *ch, CHAR_DATA *victim); bool check_chargeset args( ( CHAR_DATA *ch, CHAR_DATA *victim )); void do_arena_echo(const char *txt); int check_imperial_training(CHAR_DATA *ch); bool check_wall_thorns args((CHAR_DATA *ch)); bool check_bloody args((CHAR_DATA *ch)); bool isShifted args ((CHAR_DATA *ch)); int get_shifted args ((CHAR_DATA *ch)); bool check_rangermob(CHAR_DATA *mob); CHAR_DATA *jujitsu_victim; /* * Control the fights going on. * Called periodically by update_handler. */ void violence_update( void ) { CHAR_DATA *ch; CHAR_DATA *ch_next; CHAR_DATA *victim; int regen, to_heal; OBJ_DATA *torque; OBJ_DATA *obj; //for ( ch = char_list; ch != NULL; ch = ch->next ) for ( ch = char_list; ch != NULL; ch = ch_next ) { ch_next = ch->next; obj = get_eq_char(ch,WEAR_HEAD); if (obj != NULL && obj->pIndexData->vnum == OBJ_VNUM_TIARA) { ch->mana = UMIN(ch->mana + number_range(1,4),ch->max_mana); } obj = get_eq_char(ch,WEAR_HOLD); if (obj != NULL && obj->pIndexData->vnum == 14739) { /* greater symbol of magic */ ch->mana = UMIN(ch->mana + number_range(1,3),ch->max_mana); } /* regen */ if (!IS_NPC(ch)) { regen = get_skill(ch,gsn_regeneration); to_heal = (ch->max_hit - ch->hit); if (number_percent() <= ch->level*2) { if ((ch->hit < ch->max_hit) && ch->noregen_dam < to_heal && number_percent() < regen) { if (number_percent() < 3) check_improve(ch,gsn_regeneration,TRUE,4); ch->hit += number_range(1,3); } } } if (ch->regen_rate != 0) { if (ch->regen_rate > 0) regen = number_range(1,ch->regen_rate); else regen = number_range(1,-ch->regen_rate); if (ch->hit < ch->max_hit) { if (ch->regen_rate > 0) ch->hit = UMIN(ch->hit + regen,ch->max_hit); else ch->hit = UMIN(ch->hit - regen,ch->max_hit); } } torque = get_eq_char(ch,WEAR_NECK_1); if (torque == NULL) torque = get_eq_char(ch,WEAR_NECK_2); if (torque != NULL) { if (torque->pIndexData->vnum == OBJ_VNUM_TORQUE) if (ch->hit < ch->max_hit) ch->hit = UMIN(ch->hit + dice(1,3),ch->max_hit); } if ( ( victim = ch->fighting ) == NULL || ch->in_room == NULL ) continue; if (IS_NPC(ch) && (!IS_NPC(ch->fighting)) && !IS_SET(ch->act,ACT_NO_TRACK) && !IS_AFFECTED(ch,AFF_CHARM) && !IS_SET(ch->act,ACT_IS_HEALER) && !IS_SET(ch->act,ACT_BANKER)) ch->last_fought = ch->fighting; update_pc_last_fight(ch,ch->fighting); if ( IS_AWAKE(ch) && ch->in_room == victim->in_room ) multi_hit( ch, victim, TYPE_UNDEFINED ); else stop_fighting( ch, FALSE ); if ( ( victim = ch->fighting ) == NULL ) continue; if ( IS_NPC( ch ) ) { if ( HAS_TRIGGER( ch, TRIG_FIGHT ) ) mp_percent_trigger( ch, victim, NULL, NULL, TRIG_FIGHT ); if ( HAS_TRIGGER( ch, TRIG_HPCNT ) ) mp_hprct_trigger( ch, victim ); } /* * Fun for the whole family! */ check_assist(ch,victim); } return; } /* for auto assisting */ void check_assist(CHAR_DATA *ch,CHAR_DATA *victim) { CHAR_DATA *rch, *rch_next; for (rch = ch->in_room->people; rch != NULL; rch = rch_next) { rch_next = rch->next_in_room; if (!IS_NPC(rch) && rch->ghost > 0) continue; if (IS_AWAKE(rch) && rch->fighting == NULL) { /* NPC assisting group (for charm, zombies, elementals..added by Ceran */ if (IS_NPC(rch) && (IS_AFFECTED(rch,AFF_CHARM)) && is_same_group(rch,ch) ) { multi_hit(rch,victim,TYPE_UNDEFINED); continue; } /* quick check for ASSIST_PLAYER */ if (!IS_NPC(ch) && IS_NPC(rch) && IS_SET(rch->off_flags,ASSIST_PLAYERS) && rch->level + 6 > victim->level) { do_emote(rch,"screams and attacks!"); multi_hit(rch,victim,TYPE_UNDEFINED); continue; } /* PCs next */ if ( !IS_NPC(ch) || IS_AFFECTED(ch,AFF_CHARM)) { /* First check defending */ if (rch->defending != NULL) { CHAR_DATA *fch; fch = ch->fighting; if (rch->defending != NULL && rch->defending == ch && fch != NULL && fch->fighting == ch && number_percent() < get_skill(rch,gsn_defend) && number_percent() > 40 && number_percent() < get_skill(rch,gsn_rescue)) { act("$n leaps to $N's rescue!",rch,0,ch,TO_NOTVICT); act("$n leaps to your rescue!",rch,0,ch,TO_VICT); act("You leap to $N's rescue!",rch,0,ch,TO_CHAR); if (is_safe(rch,fch)) return; WAIT_STATE( rch, skill_table[gsn_rescue].beats ); WAIT_STATE(ch,12); check_improve(rch,gsn_defend,TRUE,1); stop_fighting( fch, FALSE ); stop_fighting( ch, FALSE ); set_fighting( rch, fch ); set_fighting( fch, rch ); if (IS_NPC(fch) && (fch->pIndexData->vnum == MOB_VNUM_COVEN || fch->pIndexData->vnum == MOB_VNUM_ACADIAN || fch->pIndexData->vnum == MOB_VNUM_PROTECTOR || fch->pIndexData->vnum == MOB_VNUM_RAVAGER || fch->pIndexData->vnum == MOB_VNUM_BRIAR || fch->pIndexData->vnum == MOB_VNUM_PROTECTOR) ) set_fighting(ch,fch); continue; } } if ( ( (!IS_NPC(rch) && IS_SET(rch->act,PLR_AUTOASSIST)) || IS_AFFECTED(rch,AFF_CHARM)) && is_same_group(ch,rch) && !is_safe(rch, victim)) multi_hit (rch,victim,TYPE_UNDEFINED); continue; } /* now check the NPC cases */ if (IS_NPC(ch) && !IS_AFFECTED(ch,AFF_CHARM)) { if ( (IS_NPC(rch) && IS_SET(rch->off_flags,ASSIST_ALL)) || (IS_NPC(rch) && rch->group && rch->group == ch->group) || (IS_NPC(rch) && rch->race == ch->race && IS_SET(rch->off_flags,ASSIST_RACE)) || (IS_NPC(rch) && IS_SET(rch->off_flags,ASSIST_ALIGN) && ((IS_GOOD(rch) && IS_GOOD(ch)) || (IS_EVIL(rch) && IS_EVIL(ch)) || (IS_NEUTRAL(rch) && IS_NEUTRAL(ch)))) || (rch->pIndexData == ch->pIndexData && IS_SET(rch->off_flags,ASSIST_VNUM))) { CHAR_DATA *vch; CHAR_DATA *target; int number; if (number_bits(1) == 0) continue; target = NULL; number = 0; for (vch = ch->in_room->people; vch; vch = vch->next) { if (can_see(rch,vch) && is_same_group(vch,victim) && number_range(0,number) == 0) { target = vch; number++; } } if (target != NULL) { do_emote(rch,"screams and attacks!"); multi_hit(rch,target,TYPE_UNDEFINED); } } } } } } /* * Do one group of attacks. */ void multi_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; int dual_chance; int trinal_chance; int attacks; int form; int i; AFFECT_DATA *paf; AFFECT_DATA *paf_next; OBJ_DATA *obj; OBJ_DATA *wield; if (is_affected(ch,gsn_timestop)) { if (ch->fighting != NULL) ch->fighting = NULL; return; } /* decrement the wait */ if (ch->desc == NULL) ch->wait = UMAX(0,ch->wait - PULSE_VIOLENCE); if (ch->level == MAX_LEVEL) { ch->wait = 0; } if (ch->desc == NULL) ch->daze = UMAX(0,ch->daze - PULSE_VIOLENCE); if (ch->level == MAX_LEVEL) ch->daze = 0; for ( paf = ch->affected; paf != NULL; paf = paf_next ) { paf_next = paf->next; if (paf->wait > 0) { paf->wait -= 1; } /* jujitsu check - start */ if ( paf->type == gsn_jujitsu && paf->wait == 0) { char jujitsubuf[MSL]; int jujitsu_chance, dam; jujitsu_victim = paf->owner; jujitsu_chance = get_skill(ch,gsn_jujitsu); dam = (ch->drain_level + ch->level)/2; dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(ch->level/5,ch->level/4); if (jujitsu_victim->fighting != ch) { sprintf(jujitsubuf,"%s is not fighting you anymore, and you cannot complete your manuever.\n\r",jujitsu_victim->name); send_to_char(jujitsubuf,ch); affect_strip(ch,gsn_jujitsu); } else { if (number_percent() < jujitsu_chance) { send_to_char("{GATTACK 1!!!!{x\n\r",ch); damage(ch,jujitsu_victim,dam,gsn_jujitsu,DAM_BASH,TRUE); jujitsu_chance -= 10; dam -= number_range(0,(ch->drain_level + ch->level)/6); if (number_percent() < jujitsu_chance) { send_to_char("{GATTACK 2!!!!{x\n\r",ch); damage(ch,jujitsu_victim,dam,gsn_jujitsu,DAM_BASH,TRUE); jujitsu_chance -= 10; dam -= number_range(0,(ch->drain_level + ch->level)/6); if (number_percent() < jujitsu_chance) { send_to_char("{GATTACK 3!!!!{x\n\r",ch); damage(ch,jujitsu_victim,dam,gsn_jujitsu,DAM_BASH,TRUE); jujitsu_chance -= 10; dam -= number_range(0,(ch->drain_level + ch->level)/6); if (number_percent() < jujitsu_chance) { send_to_char("{GATTACK 4!!!!{x\n\r",ch); damage(ch,jujitsu_victim,dam,gsn_jujitsu,DAM_BASH,TRUE); jujitsu_chance -= 10; dam -= number_range(0,(ch->drain_level + ch->level)/6); if (number_percent() < jujitsu_chance) { send_to_char("{GATTACK 5!!!!{x\n\r",ch); damage(ch,jujitsu_victim,dam,gsn_jujitsu,DAM_BASH,TRUE); } } } } } affect_strip(ch,gsn_jujitsu); } } /* jujitsu check - end */ } if(is_affected(victim,gsn_snare) && number_percent()<11 && victim->fighting!=NULL) { act("In the chaos of combat, the snare holding $n comes loose.",victim,0,0,TO_ROOM); act("In the chaos of combat, the snare holding you comes loose.",victim,0,0,TO_CHAR); affect_strip(victim,gsn_snare); } /* no attacks for stunnies -- just a check */ if (ch->position < POS_RESTING) return; if (IS_NPC(ch)) { if (ch->pIndexData->vnum == MOB_VNUM_WATER_ELEMENTAL) { if (number_percent() < 20) { do_bash(ch,""); } } if (ch->pIndexData->vnum == MOB_VNUM_AIR_ELEMENTAL) { if (number_percent() < 20) { do_trip(ch,""); } } } if (IS_NPC(ch)) { mob_hit(ch,victim,dt); return; } if( isShifted(ch) ) { form = get_shifted(ch); attacks = number_range(1, form_table[form].attacks); for(i = 0; i < attacks; i++) { one_hit(ch, victim, dt); } return; } one_hit( ch, victim, dt ); if (ch->fighting != victim) return; check_bracelets(ch); wing_beating(ch); hammer_pendant(ch); etched_pendant(ch); kyr_tattoo(ch,victim); dev_tattoo(ch,victim); mer_tattoo(ch); cei_tattoo(ch); deo_tattoo(ch,victim); gra_tattoo(ch,victim); kra_tattoo(ch,victim); xanthr_tattoo(ch,victim); obj = get_eq_char(ch,WEAR_BRAND); if (ch->fighting == victim) if ( (wield = get_eq_char(ch,WEAR_WIELD)) != NULL) { if (ch->fighting == victim && wield->pIndexData->vnum == 14726) check_blue_talon(ch,ch->fighting); } if ( ch->fighting != victim || dt == gsn_backstab || (dt == gsn_ambush) ) return; if (IS_AFFECTED(ch,AFF_HASTE)) one_hit(ch,victim,dt); chance = get_skill(ch,gsn_second_attack)/2; dual_chance = get_skill(ch,gsn_dual_wield)/2; trinal_chance = get_skill(ch,gsn_tertiary_wield)/2; if (is_affected(ch,gsn_maehslin) && number_percent() < 65) { act("The amber aura around $n intenses and their movements become more fluid!",ch,0,0,TO_VICT); act("$n's amber aura intenses and their movements become more fluid!" ,ch,0,0,TO_NOTVICT); act("Your amber aura intenses and your movements become more fluid!",ch,0,0,TO_CHAR); one_hit(ch,victim,dt); chance*=1.25; dual_chance*=1.25; chance*=1.25; } if (IS_AFFECTED(ch,AFF_HASTE)) { chance*=1.25; dual_chance*=1.25; chance*=1.25; } if (IS_AFFECTED(ch,AFF_SLOW)) { chance /= 2; dual_chance /= 2; trinal_chance /= 2; } if (check_imperial_training(ch) == IMPERIAL_DEFENSE) { chance /= 2.5; dual_chance /= 2.5; } if ( number_percent( ) < chance ) { one_hit( ch, victim, dt ); check_improve(ch,gsn_second_attack,TRUE,5); if ( ch->fighting != victim ) return; } check_bracelets(ch); wing_beating(ch); if ( (wield = get_eq_char(ch,WEAR_WIELD)) != NULL) { if (ch->fighting == victim && wield->pIndexData->vnum == 14726) check_blue_talon(ch,ch->fighting); } if (get_eq_char(ch,WEAR_DUAL_WIELD) != NULL && ch->pcdata->learned[gsn_second_attack] > 10) { if (number_percent( ) < dual_chance) { one_hit(ch,victim,gsn_dual_wield); check_improve(ch,gsn_dual_wield,TRUE,3); if (ch->fighting != victim) return; } else check_improve(ch,gsn_dual_wield,FALSE,3); } if (get_eq_char(ch,WEAR_TERTIARY_WIELD) != NULL && ch->pcdata->learned[gsn_second_attack] > 10) { if (number_percent( ) < trinal_chance) { one_hit(ch,victim,gsn_tertiary_wield); check_improve(ch,gsn_tertiary_wield,TRUE,3); if (ch->fighting != victim) return; } else check_improve(ch,gsn_tertiary_wield,FALSE,3); } if (!IS_NPC(ch) && !str_cmp(class_table[ch->class].name,"monk") && (get_eq_char(ch,WEAR_WIELD) != NULL) ) return; /* Monks can't get 3/4th attack with a weapon */ chance = get_skill(ch,gsn_third_attack)/4; if (IS_AFFECTED(ch,AFF_SLOW)) chance = 0; if (is_affected(ch,skill_lookup("haste"))) chance*=1.3; if ( number_percent( ) < chance ) { one_hit( ch, victim, dt ); check_improve(ch,gsn_third_attack,TRUE,6); if ( ch->fighting != victim ) return; } dual_chance = get_skill(ch,gsn_dual_wield)/4; if (is_affected(ch,skill_lookup("haste"))) dual_chance*=1.2; if (get_eq_char(ch,WEAR_DUAL_WIELD) != NULL && ch->pcdata->learned[gsn_third_attack] > 10) { if (number_percent( ) < dual_chance) { one_hit(ch,victim,gsn_dual_wield); check_improve(ch,gsn_dual_wield,TRUE,3); if (ch->fighting != victim) return; } else check_improve(ch,gsn_dual_wield,FALSE,3); } trinal_chance = get_skill(ch,gsn_tertiary_wield)/3; if (is_affected(ch,skill_lookup("haste"))) trinal_chance*=1.2; if (get_eq_char(ch,WEAR_TERTIARY_WIELD) != NULL && ch->pcdata->learned[gsn_third_attack] > 10) { if (number_percent( ) < trinal_chance) { one_hit(ch,victim,gsn_tertiary_wield); check_improve(ch,gsn_tertiary_wield,TRUE,3); if (ch->fighting != victim) return; } else check_improve(ch,gsn_tertiary_wield,FALSE,3); } chance = get_skill(ch,gsn_fourth_attack)/5; if (IS_AFFECTED(ch,AFF_SLOW)) chance /= 2; if (is_affected(ch,skill_lookup("haste"))) chance*=1.3; if ( number_percent() < chance ) { one_hit( ch, victim, dt ); check_improve(ch,gsn_fourth_attack,TRUE,6); if (ch->fighting != victim ) return; } dual_chance = get_skill(ch,gsn_dual_wield)/4; if (is_affected(ch,skill_lookup("haste"))) dual_chance*=1.2; if (get_eq_char(ch,WEAR_DUAL_WIELD) != NULL && ch->pcdata->learned[gsn_fourth_attack] > 10) { if (number_percent( ) < dual_chance) { one_hit(ch,victim,gsn_dual_wield); check_improve(ch,gsn_dual_wield,TRUE,6); if (ch->fighting != victim) return; } else check_improve(ch,gsn_dual_wield,FALSE,5); } trinal_chance = get_skill(ch,gsn_tertiary_wield)/6; if (is_affected(ch,skill_lookup("haste"))) trinal_chance*=1.1; if (get_eq_char(ch,WEAR_TERTIARY_WIELD) != NULL && ch->pcdata->learned[gsn_fourth_attack] > 85) { if (number_percent( ) < trinal_chance) { one_hit(ch,victim,gsn_tertiary_wield); check_improve(ch,gsn_tertiary_wield,TRUE,3); if (ch->fighting != victim) return; } else check_improve(ch,gsn_tertiary_wield,FALSE,3); } /* zealotism */ chance = get_skill(ch,gsn_zealotism)/4; if (chance != 0) { if (IS_AFFECTED(ch,AFF_SLOW)) chance /= 2; if (IS_AFFECTED(ch,AFF_HASTE)) chance*=1.25; if (is_affected(ch,gsn_bloodthirst)) chance*=1.25; if (is_affected(ch,gsn_rage_of_dioxide)) chance*=1.35; if (IS_AFFECTED(ch,AFF_BERSERK)) chance*=1.25; for (i=0; i<(chance/20); i++) { act("Delirious with zeal, you strike $N again!",ch,0,victim,TO_CHAR); one_hit(ch, victim, dt); } check_improve(ch,gsn_zealotism,TRUE,1); if (ch->fighting != victim ) return; } /* imperial training */ if (check_imperial_training(ch) == IMPERIAL_OFFENSE && get_skill(ch,gsn_third_attack)>80) { chance = number_range(1,2); for (i=0; i<chance; i++) one_hit(ch, victim, dt); } return; } /* procedure for all mobile attacks */ void mob_hit (CHAR_DATA *ch, CHAR_DATA *victim, int dt) { int chance,number; int dual_chance; CHAR_DATA *vch, *vch_next; one_hit(ch,victim,dt); if (ch->fighting != victim) return; /* Area attack -- BALLS nasty! */ if (IS_SET(ch->off_flags,OFF_AREA_ATTACK)) { for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next; if ((vch != victim && vch->fighting == ch)) one_hit(ch,vch,dt); } } if (is_affected(ch,skill_lookup("haste")) || (IS_SET(ch->off_flags,OFF_FAST) && !IS_AFFECTED(ch,AFF_SLOW))) one_hit(ch,victim,dt); if (ch->fighting != victim || dt == gsn_backstab) return; chance = get_skill(ch,gsn_second_attack)/2; dual_chance = ch->level*2/3; if (IS_AFFECTED(ch,AFF_SLOW) && !IS_SET(ch->off_flags,OFF_FAST)) { dual_chance /= 2; chance /= 2; } if (number_percent() < chance) { one_hit(ch,victim,dt); if (ch->fighting != victim) return; } if (IS_AFFECTED(ch,AFF_HASTE)) dual_chance *= 6/4; if (number_percent() < dual_chance && get_eq_char(ch,WEAR_DUAL_WIELD) != NULL) { one_hit(ch,victim,gsn_dual_wield); if (ch->fighting != victim) return; } chance = get_skill(ch,gsn_third_attack)/4; dual_chance *= 2/3; if (IS_AFFECTED(ch,AFF_SLOW) && !IS_SET(ch->off_flags,OFF_FAST)) { dual_chance = 0; chance = 0; } if (IS_AFFECTED(ch,AFF_HASTE)) dual_chance *= 3/2; if (number_percent() < chance) { one_hit(ch,victim,dt); if (ch->fighting != victim) return; } if (number_percent() < dual_chance && get_eq_char(ch,WEAR_DUAL_WIELD) != NULL) { one_hit(ch,victim,gsn_dual_wield); if (ch->fighting != victim) return; } /* oh boy! Fun stuff! */ if (ch->wait > 0) return; number = number_range(0,2); if (number == 1 && IS_SET(ch->act,ACT_MAGE)) { /* { mob_cast_mage(ch,victim); return; } */ ; } if (number == 2 && IS_SET(ch->act,ACT_CLERIC)) { /* { mob_cast_cleric(ch,victim); return; } */ ; } /* now for the skills */ number = number_range(0,9); switch(number) { case (0) : if (IS_SET(ch->off_flags,OFF_BASH)) do_bash(ch,""); else if (IS_SET(ch->off_flags,OFF_TAIL)) do_tail(ch,""); break; case (1) : if (IS_SET(ch->off_flags,OFF_BERSERK) && !IS_AFFECTED(ch,AFF_BERSERK)) do_berserk(ch,""); break; case (2) : if (IS_SET(ch->off_flags,OFF_DISARM) || (get_weapon_sn(ch) != gsn_hand_to_hand && (IS_SET(ch->act,ACT_WARRIOR) || IS_SET(ch->act,ACT_THIEF)))) do_disarm(ch,""); break; case (3) : if (IS_SET(ch->off_flags,OFF_KICK)) do_kick(ch,""); break; case (4) : if (IS_SET(ch->off_flags,OFF_KICK_DIRT)) do_dirt(ch,""); break; case (5) : if (IS_SET(ch->off_flags,OFF_TAIL)) { do_tail(ch,""); } break; case (6) : if (IS_SET(ch->off_flags,OFF_TRIP)) do_trip(ch,""); break; case (7) : if (IS_SET(ch->off_flags,OFF_CRUSH)) { do_crush(ch,"") ; } break; case (8) : if (IS_SET(ch->off_flags,OFF_BACKSTAB)) { do_backstab(ch,""); } else if (IS_SET(ch->off_flags,OFF_UNDEAD_DRAIN)) do_undead_drain(ch,""); break; case (9) : if ( IS_SET(ch->off_flags,OFF_UNDEAD_DRAIN)) { do_undead_drain(ch,""); } break; } } /* * Hit one guy once. */ void one_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt) { OBJ_DATA *wield; OBJ_DATA *backfist_wield; OBJ_DATA *backfist_dual; OBJ_DATA *backfist_shield; OBJ_DATA *backfist_hold; int victim_ac; int thac0; OBJ_DATA *obj; int bcry; int thac0_00; int thac0_32; int dam, mdam, bladam, tchance; int diceroll, diceroll2 = 0; int sn,skill; int dam_type; int tmp_dt; int handcounter=0; bool result; bool exeresult; int exedam; int form; /*sn = -1;*/ const char *attack; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; int thesn; /* just in case */ if (victim == ch || ch == NULL || victim == NULL) return; /* * Can't beat a dead char! * Guard against weird room-leavings. */ if ( victim->position == POS_DEAD || ch->in_room != victim->in_room ) return; /* * Figure out the type of damage message. */ if(isShifted(ch)) { form = get_shifted(ch); dt = TYPE_HIT + attack_lookup(form_table[form].attack_type); } wield = get_eq_char( ch, WEAR_WIELD ); backfist_wield = get_eq_char( victim, WEAR_WIELD ); backfist_dual = get_eq_char( victim, WEAR_DUAL_WIELD ); backfist_shield = get_eq_char( victim, WEAR_SHIELD ); backfist_hold = get_eq_char( victim, WEAR_HOLD ); if ( dt == TYPE_UNDEFINED ) { dt = TYPE_HIT; if ( wield != NULL && wield->item_type == ITEM_WEAPON ) dt += wield->value[3]; else dt += ch->dam_type; } if(is_affected(ch,gsn_executioner) && number_percent()<5) { act("$n suddenly darts forward with impossible agility and gracefully strikes you!",ch,0,victim,TO_VICT); act("$n suddenly darts forward with impossible agility and gracefully strikes $N!",ch,0,victim,TO_NOTVICT); act("Imbued with the grace of an executioner, you suddenly dart forward with impossible agility and gracefully strike $N!",ch,0,victim,TO_CHAR); exedam=GET_DAMROLL(ch)+140; exeresult = damage( ch, victim, exedam, gsn_executioner, DAM_HOLY, TRUE ); } if(is_affected(victim,gsn_executioner) && number_percent()<7 && dt!=gsn_flurry && dt!=gsn_drum) { act("$n smoothly redirects $N's attack, and with lithe grace unleashes a deadly riposte!",victim,0,ch,TO_NOTVICT); act("You smoothly redirect $N's attack and with lithe grace unleash a deadly riposte!",victim,0,ch,TO_CHAR); act("$n smoothly redirects your attack and with lithe grace unleashes a deadly riposte!",victim,0,ch,TO_VICT); exedam=GET_DAMROLL(ch)+100; exeresult = damage( victim, ch, exedam, gsn_executioner, DAM_HOLY, TRUE ); } if(get_skill(victim,gsn_backfist) !=0) { if (backfist_wield != NULL) handcounter += 1; if (backfist_dual != NULL) handcounter += 1; if (backfist_shield != NULL) handcounter += 1; if (backfist_hold != NULL) handcounter += 1; if (number_percent() < (get_skill(victim,gsn_backfist)/5) && handcounter < 2) { act("$n steps in quickly to strike $N with a quick backfist!",victim,0,ch,TO_NOTVICT); act("You step in quickly to strike $N with a quick backfist!",victim,0,ch,TO_CHAR); act("$n steps in quickly to strike you with a quick backfist!!",victim,0,ch,TO_VICT); exeresult = damage( victim, ch, GET_DAMROLL(victim)+75, gsn_backfist, DAM_BASH, TRUE ); check_improve(victim,gsn_backfist,TRUE,1); } else { check_improve(victim,gsn_backfist,FALSE,1); } } if (dt < TYPE_HIT) if (wield != NULL) dam_type = attack_table[wield->value[3]].damage; else dam_type = attack_table[ch->dam_type].damage; else dam_type = attack_table[dt - TYPE_HIT].damage; if (dam_type == -1) dam_type = DAM_BASH; /* get the weapon skill */ sn = get_weapon_sn(ch); skill = 20 + get_weapon_skill(ch,sn); /* DUAL WIELD..kinda messy here */ if (dt == gsn_dual_wield || dt == gsn_tertiary_wield) { if (dt == gsn_dual_wield) wield = get_eq_char( ch, WEAR_DUAL_WIELD ); else wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); tmp_dt = TYPE_HIT; if ( wield != NULL && wield->item_type == ITEM_WEAPON ) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt < TYPE_HIT) if (wield != NULL) dam_type = attack_table[wield->value[3]].damage; else dam_type = attack_table[ch->dam_type].damage; else dam_type = attack_table[dt - TYPE_HIT].damage; if (dam_type == -1) dam_type = DAM_BASH; if (wield == NULL) sn = -1; else switch (wield->value[0]) { default: sn = -1; break; case (WEAPON_SWORD): sn = gsn_sword; break; case (WEAPON_DAGGER): sn = gsn_dagger; break; case (WEAPON_SPEAR): sn = gsn_spear; break; case (WEAPON_MACE): sn = gsn_mace; break; case (WEAPON_AXE): sn = gsn_axe; break; case (WEAPON_FLAIL): sn = gsn_flail; break; case (WEAPON_WHIP): sn = gsn_whip; break; case (WEAPON_POLEARM): sn = gsn_polearm; break; } skill = 10 + get_weapon_skill(ch,sn); } if(get_skill(victim,skill_lookup("blademaster"))>0 && !(cabal_down(ch,CABAL_PROTECTOR))) { tchance=3+((get_skill(victim,skill_lookup("blademaster"))-75)/3); if(is_affected(victim,AFF_HASTE)) tchance+=2; if(is_affected(victim,AFF_SLOW)) tchance-=5; if(number_percent()<tchance) { tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (wield != NULL && dt!=gsn_tertiary_wield) { if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { attack = attack_table[0].name; } sprintf(buf1,"$n parries $N's %s, and skillfully unleashes an attack of $s own!",attack); act(buf1,victim,0,ch,TO_NOTVICT); sprintf(buf2,"You parry $N's %s and skillfully unleash an attack of your own!",attack); act(buf2,victim,0,ch,TO_CHAR); sprintf(buf3,"$n parries your %s and skillfully unleashes an attack of $s own!",attack); act(buf3,victim,0,ch,TO_VICT); thesn=skill_lookup("blademaster"); bladam = number_range( wield->value[1], wield->value[2]); bladam += GET_DAMROLL(ch)+(number_percent()/2); exeresult = damage( victim, ch, bladam, thesn, DAM_SLASH, TRUE ); check_improve(victim,skill_lookup("blademaster"),TRUE,2); return; } } } /* * Calculate to-hit-armor-class-0 versus armor. */ if ( IS_NPC(ch) ) { thac0_00 = 20; thac0_32 = -4; /* as good as a thief */ if (IS_SET(ch->act,ACT_WARRIOR)) thac0_32 = -10; else if (IS_SET(ch->act,ACT_THIEF)) thac0_32 = -4; else if (IS_SET(ch->act,ACT_CLERIC)) thac0_32 = 2; else if (IS_SET(ch->act,ACT_MAGE)) thac0_32 = 6; } else { thac0_00 = class_table[ch->class].thac0_00; thac0_32 = class_table[ch->class].thac0_32; } thac0 = interpolate( ch->level + ch->drain_level, thac0_00, thac0_32 ); if (thac0 < 0) thac0 = thac0/2; if (thac0 < -5) thac0 = -5 + (thac0 + 5) / 2; thac0 -= GET_HITROLL(ch) * skill/100; thac0 += 5 * (100 - skill) / 100; if (dt == gsn_backstab) thac0 -= 10 * (100 - get_skill(ch,gsn_backstab)); if (dt == gsn_ambush) thac0 -= 15 * (100 - get_skill(ch,gsn_ambush)); if (dt == gsn_impale) thac0 -= 15 * (100 - get_skill(ch,gsn_ambush)); switch(dam_type) { case(DAM_PIERCE):victim_ac = GET_AC(victim,AC_PIERCE)/10; break; case(DAM_BASH): victim_ac = GET_AC(victim,AC_BASH)/10; break; case(DAM_SLASH): victim_ac = GET_AC(victim,AC_SLASH)/10; break; default: victim_ac = GET_AC(victim,AC_EXOTIC)/10; break; }; if (victim_ac < -15) victim_ac = (victim_ac + 15) / 5 - 15; if ( !can_see( ch, victim ) ) victim_ac -= 4; if ( victim->position < POS_FIGHTING) victim_ac += 4; if (victim->position < POS_RESTING) victim_ac += 6; /* * The moment of excitement! */ while ( ( diceroll = number_bits( 5 ) ) >= 20 ) ; if ( diceroll == 0 || ( diceroll != 19 && diceroll < thac0 - victim_ac ) ) { /* Miss. */ damage( ch, victim, 0, dt, dam_type, TRUE ); tail_chain( ); return; } /* * Hit. * Calc damage. */ if ( IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL)) if (!ch->pIndexData->new_format) { dam = number_range( ( ch->level + ch->drain_level) / 2, (ch->drain_level + ch->level) * 3 / 2 ); if ( wield != NULL ) dam += dam / 2; } else dam = dice(ch->damage[DICE_NUMBER],ch->damage[DICE_TYPE]); else { if (sn != -1) check_improve(ch,sn,TRUE,5); if ( wield != NULL ) { if (wield->pIndexData->new_format) dam = dice(wield->value[1],wield->value[2]) * skill/100; else dam = number_range( wield->value[1] * skill/100, wield->value[2] * skill/100); if (get_eq_char(ch,WEAR_SHIELD) == NULL) /* no shield = more */ dam = dam * 11/10; if (wield->level - (ch->drain_level + ch->level) >= 35) dam = (dam*6)/10; else if (wield->level - (ch->drain_level + ch->level) >= 25) dam = (dam*7)/10; else if (wield->level - (ch->drain_level + ch->level) >= 15) dam = (dam*8)/10; else if (wield->level - (ch->drain_level + ch->level) >= 5) dam = (dam*9)/10; /* sharpness! */ if (IS_WEAPON_STAT(wield,WEAPON_SHARP)) { int percent; if ((percent = number_percent()) <= (skill / 8)) dam = 2 * dam + (dam * 2 * percent / 100); } } else dam = number_range( 1 + 4 * skill/100, 2 * ch->level/3 * skill/100); } /* * Bonuses. */ dam += (ch->drain_level + ch->level)/8; if ( get_skill(ch,gsn_enhanced_damage) > 0 ) { diceroll = number_percent(); if (get_skill(ch,gsn_enhanced_damage_two) > 0) { diceroll2 = number_percent(); if (diceroll2 < get_skill(ch,gsn_enhanced_damage_two) && diceroll2 < get_skill(ch,gsn_enhanced_damage) ) { check_improve(ch,gsn_enhanced_damage_two,TRUE,5); diceroll2 = diceroll2 + 5; diceroll = diceroll2; } } if (get_skill(ch,gsn_enhanced_damage_three) > 0) { check_improve(ch,gsn_enhanced_damage_three,TRUE,3); diceroll += get_skill(ch,gsn_enhanced_damage_three)/3; } if (diceroll <= get_skill(ch,gsn_enhanced_damage)) { check_improve(ch,gsn_enhanced_damage,TRUE,6); dam += (dam * diceroll/125); } } else { dam *= 7; dam /= 10; } if ( !IS_AWAKE(victim) ) dam *= 2; else if (victim->position < POS_FIGHTING) dam = dam * 3 / 2; if ( dt == gsn_backstab && wield != NULL) { if ( wield->value[0] != 2 ) dam *= 2 + ((ch->level + ch->drain_level) / 10) ; else dam *= 2 + ((ch->drain_level + ch->level) / 8); } if ( dt == gsn_ambush ) dam *= 5/2 + ((ch->drain_level + ch->level) / 6 ); mdam = GET_DAMROLL(ch); /* Let's cut back on mage's damage a bit */ dam += mdam * UMIN(100,skill) /100; if (!IS_NPC(ch)) if (!str_cmp(class_table[ch->class].name,"monk")) { if (wield == NULL && get_eq_char(ch,WEAR_DUAL_WIELD) == NULL) dam += (2*(ch->drain_level + ch->level)/5); } if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_HYDRA) { if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_HYDRA_SLAYER) dam = dice(17,50); } if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_STALKER) { dam *= .6; } bcry = battlecry_multiplier(ch,dt); if (wield != NULL && wield->pIndexData->vnum == 23265) if (check_cutter(ch,victim) > 1) dam += dice(10,3); if (bcry == 1 && wield == NULL) { if (check_palm(ch)) { act("$n strikes a powerful open handed blow!",ch,0,0,TO_ROOM); act("You strike a powerful open handed blow!",ch,0,0,TO_CHAR); if ((ch->drain_level + ch->level) <= 39) { dam *= 3; dam /= 2; } else dam *= 2; } } if (bcry == 1 && ch->cabal != CABAL_RAVAGER) { if ((obj = get_eq_char(ch,WEAR_HANDS)) != NULL && obj->pIndexData->vnum == 29711 && number_percent() < 10) { act("$n delivers a blow of deadly force!",ch,0,0,TO_ROOM); act("You deliver a blow of deadly force!",ch,0,0,TO_CHAR); bcry = 2; } } dam *= bcry; if ( (get_skill(ch,gsn_cblow) > 0) || (ch->level < skill_table[gsn_cblow].skill_level[ch->class]) ) { if ((wield != NULL) && ((wield->value[0] == WEAPON_STAFF) || (wield->value[0] == WEAPON_AXE)) && (number_percent() < get_skill(ch,gsn_cblow)/3) ) { act("$n lands a crushing blow!",ch,0,0,TO_ROOM); act("You land a crushing blow!",ch,0,0,TO_CHAR); dam *=1.5; check_improve(ch,gsn_cblow,TRUE,2); } } if (wield != NULL && IS_WEAPON_STAT(wield,WEAPON_VORPAL) && number_percent() < 20) { act("$p emits a fierce red glow as it lashes violently at $N!",ch,wield,victim,TO_CHAR); act("$p emits a fierce red glow as it lashes violently at You!",ch,wield,victim,TO_VICT); act("$p emits a fierce red glow as it lashes violently at $N!",ch,wield,victim,TO_NOTVICT); dam *= 1.5; } if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_AVENGER) { if (IS_WEAPON_STAT(wield,WEAPON_SHADOWBANE) && number_percent() < 7) { act("$p flares and sears $N!",ch,wield,victim,TO_CHAR); act("$p flares and sears you!",ch,wield,victim,TO_VICT); act("$p flares and sears $N!",ch,wield,victim,TO_NOTVICT); dam *= 2; } if (IS_WEAPON_STAT(wield,WEAPON_LIGHTBRINGER) && number_percent() < 10) { act("$p flares and sears $N!",ch,wield,victim,TO_CHAR); act("$p flares and sears you!",ch,wield,victim,TO_VICT); act("$p flares and sears $N!",ch,wield,victim,TO_NOTVICT); dam *= 3; dam /=2; } } if (bcry == 1) { if (wield != NULL && wield->pIndexData->vnum == 24309) { if (number_percent() < 6) { act("$n's $p lands a crushing blow!",ch,wield,0,TO_ROOM); act("Your $p lands a crushing blow!",ch,wield,0,TO_CHAR); dam *= 2; } } /* sword of planes and mace disruption .. go right before damage report*/ if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_SWORD_PLANES) { if (IS_NPC(victim) && ( IS_SET(victim->act,ACT_UNDEAD) || victim->pIndexData->vnum == MOB_VNUM_FIRE_ELEMENTAL || victim->pIndexData->vnum == MOB_VNUM_AIR_ELEMENTAL || victim->pIndexData->vnum == MOB_VNUM_WATER_ELEMENTAL || victim->pIndexData->vnum == MOB_VNUM_EARTH_ELEMENTAL || victim->pIndexData->vnum == MOB_VNUM_DRAGON || victim->pIndexData->vnum == MOB_VNUM_UNICORN || is_name(victim->name,"demon") || is_name(victim->name,"familiar") || is_name(victim->name,"golem") ) ) { if (!(saves_spell(ch->level,victim,DAM_ENERGY)) && (!saves_spell(ch->level + 3,victim,DAM_ENERGY)) && (!saves_spell(wield->level,victim,DAM_OTHER)) && number_percent() < 50) { act("$n's body suddenly crumples as $p draws $s lifeforce back to the outer planes!", victim,wield,0,TO_ROOM); raw_kill(ch,victim); return; } else if (IS_SET(victim->affected_by, AFF_SANCTUARY) ) { dam += (dam/2); /* partiallyNegates sanc */ } } } else if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_MACE_DISRUPTION) { if (IS_NPC(victim) && ( IS_SET(victim->act,ACT_UNDEAD)) ) { if (!saves_spell(ch->level,victim,DAM_ENERGY) && !saves_spell(ch->level,victim,DAM_ENERGY) && !saves_spell(ch->level,victim,DAM_OTHER)) { act("$N's body explodes under $n's mace of disruption!",ch,0,victim,TO_NOTVICT); act("$N's body explodes under your mace of disruption!",ch,0,victim,TO_CHAR); raw_kill(ch,victim); return; } else if (IS_SET(victim->affected_by,AFF_SANCTUARY)) { dam += (3* dam/4); } } } if (IS_NPC(ch) && ch->pIndexData->vnum == 19000 && number_percent() < 4) { act("$n bellows a cry and unleashes a mighty blow upon you!",ch,0,victim,TO_VICT); act("$n bellows a cry and unleashes a mighty blow upon $N",ch,0,victim,TO_NOTVICT); dam += dice(ch->level,3); } } if ( dam <= 0 ) dam = 1; if((get_skill(ch,skill_lookup("truestrike")))>0 && (number_percent()<((get_skill(ch,skill_lookup("truestrike"))-40)/5)-3) && !(cabal_down(ch,CABAL_PROTECTOR))) { act("$n unleashes a blow of true accuracy, striking through your defenses!",ch,0,victim,TO_VICT); act("$n unleashes a blow of true accuracy, striking through $N's defenses!",ch,0,victim,TO_NOTVICT); act("You unleash a blow of true accuracy, striking through $N's defenses!",ch,0,victim,TO_CHAR); dam*=1; result = damage( ch, victim, dam, dt, DAM_TRUESTRIKE, TRUE ); check_improve(ch,skill_lookup("truestrike"),TRUE,1); } else { result = damage( ch, victim, dam, dt, dam_type, TRUE ); } check_outlaw_badge(ch); check_red_shield(ch); check_ceial_tat(ch); if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_CLOWN_MALLET) check_clown_mallet(ch->level,ch,ch->fighting, wield); if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_RANGER_STAFF) check_ranger_staff(ch,wield); if (wield != NULL && wield->pIndexData->vnum == OBJ_VNUM_DRAGON_WEAPON && dt!=gsn_tertiary_wield) golden_weapon(ch,wield); if (wield != NULL && wield->pIndexData->vnum == 8003) check_ranger_staff(ch,wield); /* Staff of magi call */ if(isShifted(ch)) { form = get_shifted(ch); dam = dice(form_table[form].dice_num, form_table[form].dice_type); dam += form_table[form].dice_add; } /* but do we have a funky weapon? */ if (result && wield != NULL) { int dam; if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_POISON)) { int level; AFFECT_DATA *poison, af; if ((poison = affect_find(wield->affected,gsn_poison)) == NULL) level = wield->level; else level = poison->level; if (!saves_spell(level / 2,victim,DAM_POISON)) { send_to_char("You feel poison coursing through your veins.", victim); act("$n is poisoned by the venom on $p.", victim,wield,NULL,TO_ROOM); init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SPELL; af.type = gsn_poison; af.level = level * 3/4; af.duration = level / 2; af.location = APPLY_STR; af.modifier = -1; af.bitvector = AFF_POISON; affect_join( victim, &af ); } /* weaken the poison if it's temporary */ if (poison != NULL) { poison->level = UMAX(0,poison->level - 2); poison->duration = UMAX(0,poison->duration - 1); if (poison->level == 0 || poison->duration == 0) act("The poison on $p has worn off.",ch,wield,NULL,TO_CHAR); } } if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_VAMPIRIC) && number_percent() < 8) { dam = number_range(wield->level/2, wield->level); act("$p draws life from $n.",victim,wield,NULL,TO_ROOM); act("You feel $p drawing your life away.", victim,wield,NULL,TO_CHAR); damage_old(ch,victim,dam,0,DAM_NEGATIVE,FALSE); ch->hit = UMIN(ch->hit + dam, ch->max_hit); } if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_FLAMING) && number_percent() < 15) { dam = number_range(1,wield->level / 4 + 1); act("$n is burned by $p.",victim,wield,NULL,TO_ROOM); act("$p sears your flesh.",victim,wield,NULL,TO_CHAR); fire_effect( (void *) victim,wield->level/2,dam,TARGET_CHAR); damage(ch,victim,dam,0,DAM_FIRE,FALSE); } if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_FROST) && number_percent() < 15) { dam = number_range(1,wield->level / 6 + 2); act("$p freezes $n.",victim,wield,NULL,TO_ROOM); act("The cold touch of $p surrounds you with ice.", victim,wield,NULL,TO_CHAR); cold_effect(victim,wield->level/2,dam,TARGET_CHAR); damage(ch,victim,dam,0,DAM_COLD,FALSE); } if (ch->fighting == victim && IS_WEAPON_STAT(wield,WEAPON_SHOCKING) && number_percent() < 15) { dam = number_range(1,wield->level/5 + 2); act("$n is struck by lightning from $p.",victim,wield,NULL,TO_ROOM); act("You are shocked by $p.",victim,wield,NULL,TO_CHAR); shock_effect(victim,wield->level/2,dam,TARGET_CHAR); damage(ch,victim,dam,0,DAM_LIGHTNING,FALSE); } } tail_chain( ); return; } void check_red_shield(CHAR_DATA *ch) { OBJ_DATA *shield; shield = get_eq_char(ch,WEAR_SHIELD); if (shield == NULL) return; if (shield->pIndexData->vnum != 23728) return; if (number_percent() < 6) { act("The cross on $n's shield glows a soft red.",ch,shield,0,TO_ROOM); act("The cross on your shield glows a soft red.",ch,shield,0,TO_CHAR); obj_cast_spell(skill_lookup("cure critical"), 45, ch, ch, shield); } return; } void check_outlaw_badge(CHAR_DATA *ch) { OBJ_DATA *badge; badge = get_eq_char(ch,WEAR_NECK_1); if (badge == NULL) badge = get_eq_char(ch,WEAR_NECK_2); if (badge == NULL) return; if (badge->pIndexData->vnum == OBJ_VNUM_BADGE && number_percent() < 8) { act("$n's $p glows bright blue!",ch,badge,0,TO_ROOM); act("Your $p glows bright blue!",ch,badge,0,TO_CHAR); obj_cast_spell(skill_lookup("cure critical"), badge->level, ch, ch, badge); } return; } void check_ceial_tat(CHAR_DATA *ch) { OBJ_DATA *tattoo; tattoo = get_eq_char(ch,WEAR_BRAND); if (tattoo == NULL) return; if (tattoo->pIndexData->vnum == 72 && number_percent() < 3) { act("$n's $p begins to suck life from his opponent!",ch,tattoo,0,TO_ROOM); act("Your $p begins to suck the life out of your opponent!",ch,tattoo,0,TO_CHAR); obj_cast_spell(skill_lookup("cure critical"), tattoo->level, ch, ch, tattoo); } return; } void check_clown_mallet(int level, CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *wield) { AFFECT_DATA af; if (number_percent() < 2) { if (wield->pIndexData->vnum == OBJ_VNUM_CLOWN_MALLET) { act("$p begins to eminate a haunting tune.",ch,wield,0,TO_ROOM); act("$p puts your foe to sleep!",ch,wield,0,TO_CHAR); } init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_clown_mallet; af.aftype = AFT_SKILL; af.level = ch->level; af.duration = 2; af.location = 0; af.modifier = 0; af.bitvector = AFF_SLEEP; affect_to_char( victim, &af ); stop_fighting( victim, TRUE); stop_fighting( ch, TRUE); victim->position = POS_SLEEPING; ch->position = POS_STANDING; } return; } /* void check_clown_mallet(int level,CHAR_DATA *ch,CHAR_DATA *victim, OBJ_DATA *wield) { AFFECT_DATA af; if (wield->pIndexData->vnum == OBJ_VNUM_CLOWN_MALLET) { act("$n lands a devasating blow!",ch,wield,0,TO_ROOM); act("You land a devastating blow!",ch,wield,0,TO_CHAR); af.where = TO_AFFECTS; af.type = gsn_sleep; af.level = ch->level; af.duration = level / 2; af.location = 0; af.modifier = 0; af.bitvector = AFF_SLEEP; affect_to_char( victim, &af ); } return; } */ void check_ranger_staff(CHAR_DATA *ch,OBJ_DATA *wield) { if (number_percent() < 7) { if (wield->pIndexData->vnum == OBJ_VNUM_RANGER_MAGIC) { act("$p glows softly.",ch,wield,0,TO_ROOM); act("Your body warms as your staff restores you!",ch,wield,0,TO_CHAR); } else { act("$p glows a burning green!",ch,wield,0,TO_ROOM); act("Your staff of the magi glows burning green!",ch,wield,0,TO_CHAR); } ch->hit = UMIN( ch->hit + 75, ch->max_hit ); } return; } void golden_weapon(CHAR_DATA *ch,OBJ_DATA *wield) { if (number_percent() < 7 && ch->in_room->vnum!=ROOM_FORCE_DUEL) { act("$n's weapon glows brilliant gold.",ch,wield,0,TO_ROOM); act("Your body warms as your weapon heals you!",ch,wield,0,TO_CHAR); ch->hit = UMIN( ch->hit + 75, ch->max_hit ); } return; } int avenger_multiplier(CHAR_DATA *ch,OBJ_DATA *wield) { int avenge; avenge = 1; if (IS_EVIL(ch->fighting) && wield != NULL) { if (number_percent() < 7 && IS_WEAPON_STAT(wield,WEAPON_SHADOWBANE)) avenge = 2; if (number_percent() < 7 && IS_WEAPON_STAT(wield,WEAPON_LIGHTBRINGER)) avenge = 3/2; } return avenge; } int battlecry_multiplier(CHAR_DATA *ch, int dt) { OBJ_DATA *obj; int battlecry; int chance; int mod; battlecry = 1; if (IS_NPC(ch)) return 1; if (!is_affected(ch,gsn_battlecry) && !IS_NPC(ch)) return 1; if (cabal_down(ch,CABAL_RAVAGER)) return 1; if (IS_NPC(ch) && ch->pIndexData->vnum != MOB_VNUM_RAVAGER && !is_affected(ch,gsn_battlecry)) return battlecry; if (dt==gsn_flurry || dt==gsn_drum) return 1; if ((ch->drain_level + ch->level) < skill_table[gsn_battlecry].skill_level[ch->class] && !IS_NPC(ch)) return 1; if ((obj = get_eq_char(ch,WEAR_HANDS)) != NULL && obj->pIndexData->vnum == 29711) mod = 3; else mod = 0; if (number_percent( ) > (mod + 14)) return 1; chance = get_skill(ch,gsn_battlecry); if (IS_NPC(ch) ) chance = 100; if (chance > 2) { if (number_percent( ) > (chance - 10) ) { send_to_char("You fail to deliver a blow of deadly force.\n\r",ch); if (ch->pcdata->learned[gsn_battlecry] < 100) { send_to_char("You learn from your mistakes and become better at battlecry.\n\r",ch); ch->pcdata->learned[gsn_battlecry]++; } } else { send_to_char("You deliver a blow of deadly force!\n\r",ch); act("$n delivers a blow of deadly force!",ch,NULL,NULL,TO_ROOM); check_improve(ch,gsn_battlecry,TRUE,1); if ((ch->drain_level + ch->level) <= 29) battlecry = 2; else if ((ch->drain_level + ch->level) <= 39) battlecry = 3; else if ((ch->drain_level + ch->level) <= 49) battlecry = 4; else if ((ch->drain_level + ch->level) <= 59) battlecry = 5; else battlecry = 5; } } if (dt == gsn_circle) battlecry = UMIN(battlecry,3); if (dt == gsn_lunge) battlecry = UMIN(battlecry,3); if (dt == gsn_backstab) battlecry = UMIN(battlecry,2); if (dt == gsn_dual_backstab) battlecry = UMIN(battlecry,2); if (dt == gsn_ambush) battlecry = UMIN(battlecry,2); if (dt == gsn_flurry) battlecry = 3; if (dt == gsn_drum) battlecry = 3; if (cabal_down(ch,CABAL_RAVAGER)) battlecry = 1; return battlecry; } /* * Inflict damage from a hit. */ bool damage(CHAR_DATA *ch,CHAR_DATA *victim,int dam,int dt,int dam_type, bool show) { OBJ_DATA *corpse; bool immune; OBJ_DATA *obj; OBJ_DATA *wield; bool kineticresult; int kineticdam; int originaldam; if ( victim->position == POS_DEAD ) return FALSE; if (IS_NPC(ch) && spellbaned(ch,victim,dt)) return FALSE; if (is_safe(ch,victim)) return FALSE; originaldam=dam; /* * Stop up any residual loopholes. */ if ( dam > 1500 && dt >= TYPE_HIT) { dam = 1500; } if ( victim != ch ) { /* * Certain attacks are forbidden. * Most other attacks are returned. */ if ( is_safe( ch, victim ) ) return FALSE; check_killer( ch, victim ); if ( victim->position > POS_STUNNED ) { if ( victim->fighting == NULL ) { set_fighting( victim, ch ); if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) ) mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL ); } if (victim->timer <= 4) victim->position = POS_FIGHTING; } if ( victim->position > POS_STUNNED ) { if ( ch->fighting == NULL ) set_fighting( ch, victim ); } /* * More charm stuff. */ if ( victim->master == ch ) stop_follower( victim ); } if ( (dt >= TYPE_HIT || dt == gsn_dual_wield || dt == gsn_tertiary_wield) && ch != victim) { if ( check_spin(ch,victim, dt)) return FALSE; if ( check_parry( ch, victim, dt ) ) { do_counter_parry(ch,victim,dt, dam); return FALSE; } if ( check_distance( ch, victim, dt ) ) return FALSE; if ( check_block( ch, victim, dt) ) return FALSE; if ( check_dodge( ch, victim, dt ) ) return FALSE; if ( check_questdodge( ch, victim, dt ) ) return FALSE; if ( check_shield_block(ch,victim, dt)) return FALSE; if ( check_defiant_absorb(ch,victim,dt)) return FALSE; if (check_displacement( ch, victim)) return FALSE; if ( check_ironhands( ch, victim, dt ) ) return FALSE; if ( check_unarmed_defense( ch, victim, dt ) ) return FALSE; } //stuff for elementalist if (is_affected(victim,gsn_static_charge)) { affect_strip(victim,gsn_static_charge); damage_old(victim,ch,victim->level * number_range(6,8),gsn_static_charge,DAM_LIGHTNING,TRUE); } /* damage reduction */ if (dam > 85) { dam = (dam - 85); dam *= 7; dam /= 10; dam += 85; } if (is_affected(victim,gsn_fireshield) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .65; if (is_affected(victim,gsn_wraithform) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .65; if (is_affected(victim,gsn_stoneskin) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .8; if (is_affected(victim,gsn_shield) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .8; if (is_affected(victim,gsn_kinetic_shield) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .75; if (is_affected(victim,gsn_barrier) && dt!=gsn_barrier && dam_type!=DAM_TRUESTRIKE) dam *= .50; if (is_affected(victim,gsn_shackles)) dam *= 1.5; if (is_affected(victim, gsn_soften)) dam *= 1.3; if (is_affected(ch,gsn_rage)) dam *= 1.25; un_camouflage( ch, NULL); un_earthfade(ch,NULL); un_hide(ch, NULL); un_invis(ch, NULL); un_sneak(ch, NULL); un_duo(ch, NULL); /* * Damage modifiers. */ //elemental shields /* if (is_affected(victim, gsn_shield_of_flames)) dam *= .9; if (is_affected(victim, gsn_shield_of_frost)) dam *= .88; if (is_affected(victim, gsn_shield_of_bubbles)) dam *= .86; if (is_affected(victim, gsn_shield_of_dust)) dam *= .83; //slightly more defensive if (is_affected(victim, gsn_shield_of_lightning)) dam *= .86; if (is_affected(victim, gsn_shield_of_wind)) dam *= .86; */ //orduno brand stuff if (is_affected(victim, gsn_body_of_wood)) { dam /= 10; dam *= 9; } if (is_affected(victim, gsn_body_of_clay)) { dam /= 10; dam *= 8; } if (is_affected(victim, gsn_body_of_iron)) { dam /= 10; dam *= 7; } if (is_affected(victim, gsn_body_of_steel)) { dam /= 10; dam *= 6; } if ((is_affected(victim, gsn_body_of_stone)) && (!is_affected(victim, gsn_ressist)) && (!IS_AFFECTED(victim, AFF_SANCTUARY))) { dam /= 10; dam *= 5; } if (is_affected(victim, gsn_body_of_diamond)) { dam /= 10; dam *= 4; } if ( dam > 1 && !IS_NPC(victim) && victim->pcdata->condition[COND_DRUNK] > 10 ) dam = 9 * dam / 10; if ( dam > 1 && IS_AFFECTED(victim, AFF_SANCTUARY) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) { if ( (dt >= TYPE_HIT || dt == gsn_dual_wield || dt == gsn_tertiary_wield)) { if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield == NULL ) dam /= 2; else if (wield->pIndexData->vnum != 29724) dam /= 2; } else dam /= 2; } if (is_affected(victim,gsn_shroud)) dam *= 1; if (is_affected(victim,gsn_steel_nerves)) dam *= .9; obj = get_eq_char(ch,WEAR_HEAD); if (obj != NULL && obj->pIndexData->vnum == OBJ_VNUM_TIARA && (dam_type == DAM_COLD || dam_type == DAM_FIRE || dam_type == DAM_HOLY || dam_type == DAM_NEGATIVE || dam_type == DAM_ACID) ) { if (dam > 125) { dam = (dam - 125); dam *= 6; dam /= 10; dam += 125; } } if (check_crown_blood(ch,victim,dt,dam,dam_type)) return FALSE; if ((dt >= TYPE_HIT || dt==gsn_backstab || HITS) && (ch != victim) && (is_affected(victim,gsn_steel_nerves)) && dam > 1 && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) { dam *= .8; } if ((dt >= TYPE_HIT || dt==gsn_backstab || HITS) && (ch != victim) && dam > 1 && dam_type!=DAM_TRUESTRIKE) { dam -= dam*3/10; } if ( dam > 1 && ((IS_AFFECTED(victim, AFF_PROTECT_EVIL) && IS_EVIL(ch) ) || (IS_AFFECTED(victim, AFF_PROTECT_GOOD) && IS_GOOD(ch) )) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam -= dam / 4; if (is_affected(victim,gsn_spellbane) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) { if (dam_type > 3) { dam *= 7; dam /= 10; } } if (isShifted(victim)) dam *= (victim->dam_reduc * 0.01); immune = FALSE; /* Check for absorb */ if (check_absorb(ch,victim,dt)) return FALSE; if (eye_of_beholder_absorb(ch,victim,dt,dam,dam_type)) return FALSE; /* * Check for parry, and dodge. */ switch(check_immune(victim,dam_type)) { case(IS_IMMUNE): immune = TRUE; dam = 0; break; case(IS_RESISTANT): if (IS_NPC(victim)) dam -= dam/3; else dam -= dam/3; break; case(IS_VULNERABLE): dam += dam/3; break; } if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if ( dt == gsn_tertiary_wield ) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (show) dam_message( ch, victim, dam, dt, immune ); if ( (dt >= TYPE_HIT || dt == gsn_dual_wield || dt == gsn_tertiary_wield || dt == gsn_drum || dt==gsn_flurry) && ch != victim) { if (is_affected(victim,gsn_kinetic_shield) && dam>0) { if(number_percent()<67 || dam>150) { act("$n's kinetic shield reacts to $N's attack!",victim,0,ch,TO_NOTVICT); act("Your kinetic shield reacts to $N's attack!",victim,0,ch,TO_CHAR); act("$n's kinetic shield reacts to your attack!",victim,0,ch,TO_VICT); kineticdam=originaldam*.15; kineticresult = damage_old( victim, ch, kineticdam, gsn_kinetic_shield, DAM_ENERGY, TRUE ); }} if (is_affected(victim,gsn_self_immolation) && dam>0) { act("$N is burned by the flames surrounding $n!",victim,NULL,ch,TO_NOTVICT); act("$N is burned by the flames surrounding you!",victim,NULL,ch,TO_CHAR); act("You are burned by the flames engulfing $n!",victim,NULL,ch,TO_VICT); damage_old(victim,ch,number_range(30,100),gsn_flames,DAM_FIRE, TRUE); } } if (dam == 0) return FALSE; /* * Hurt the victim. * Inform the victim of his new state. */ victim->hit -= dam; if (dam_type == DAM_FIRE || dam_type == DAM_ACID) victim->noregen_dam += dam; if (victim->noregen_dam > victim->max_hit) victim->noregen_dam = victim->max_hit; if ( !IS_NPC(victim) && victim->level >= LEVEL_IMMORTAL && victim->hit < 1 ) victim->hit = 1; update_pos( victim ); switch( victim->position ) { case POS_MORTAL: act( "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are mortally wounded, and will die soon, if not aided.\n\r", victim ); break; case POS_INCAP: act( "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are incapacitated and will slowly die, if not aided.\n\r", victim ); break; case POS_STUNNED: act( "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM ); send_to_char("You are stunned, but will probably recover.\n\r", victim ); break; case POS_DEAD: act( "$n is DEAD!!", victim, 0, 0, TO_ROOM ); send_to_char( "You have been KILLED!!\n\r\n\r", victim ); break; default: if ( dam > victim->max_hit / 4 ) send_to_char( "That really did HURT!\n\r", victim ); if ( victim->hit < victim->max_hit / 4 ) send_to_char( "You sure are BLEEDING!\n\r", victim ); break; } /* * Sleep spells and extremely wounded folks. */ if ( !IS_AWAKE(victim) && ch != victim) stop_fighting( victim, FALSE ); /* * Payoff for killing things. */ if ( victim->position == POS_DEAD ) { group_gain( ch, victim ); if ( !IS_NPC(victim) ) { sprintf( log_buf, "%s killed by %s at %d", victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->vnum ); log_string( log_buf ); } /* * Dying penalty: */ raw_kill(ch, victim ); /* * Death trigger */ if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) ) { victim->position = POS_STANDING; mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH ); } if (!IS_NPC(ch) && (corpse = get_obj_list(ch,"corpse",ch->in_room->contents)) != NULL && corpse->item_type == ITEM_CORPSE_NPC && can_see_obj(ch,corpse)) { OBJ_DATA *coins; corpse = get_obj_list( ch, "corpse", ch->in_room->contents ); if ( IS_SET(ch->act, PLR_AUTOLOOT) && corpse && corpse->contains) /* exists and not empty */ do_get( ch, "all corpse" ); if (IS_SET(ch->act,PLR_AUTOGOLD) && corpse && corpse->contains && /* exists and not empty */ !IS_SET(ch->act,PLR_AUTOLOOT)) if ((coins = get_obj_list(ch,"gcash",corpse->contains)) != NULL) do_get(ch, "all.gcash corpse"); if ( IS_SET(ch->act, PLR_AUTOSAC) ) { if ( IS_SET(ch->act,PLR_AUTOLOOT) && corpse && corpse->contains) return TRUE; /* leave if corpse has treasure */ else do_sacrifice( ch, "corpse" ); } } return TRUE; } if ( victim == ch ) return TRUE; /* * Take care of link dead people. */ if ( !IS_NPC(victim) && victim->desc == NULL ) { if ( number_range( 0, victim->wait ) == 0 ) { do_recall( victim, "" ); return TRUE; } } /* * Wimp out? */ /*if ( IS_NPC(victim) && dam > 0 && victim->wait < PULSE_VIOLENCE / 2) { if ( ( IS_SET(victim->act, ACT_WIMPY) && number_bits( 2 ) == 0 && victim->hit < victim->max_hit / 5) || ( IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL && victim->master->in_room != victim->in_room) && !is_centurion(victim) ) do_flee( victim, "" ); }*/ if(ch->in_room != victim->in_room || dt == gsn_parting_blow) return TRUE; if ( IS_NPC(victim) && dam > 0 && victim->wait < PULSE_VIOLENCE / 2) { if ( (( IS_SET(victim->act, ACT_WIMPY) && number_bits( 2 ) == 0 && victim->hit < victim->max_hit / 5)) || (( IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL && victim->master->in_room != victim->in_room && !is_centurion(victim) ) && dt != gsn_parting_blow)) do_flee( victim, "" ); } if (victim->level >= 30) { if ( !IS_NPC(victim) && victim->hit > 0 && victim->hit <= victim->wimpy && victim->wait < PULSE_VIOLENCE / 2 && dt != gsn_parting_blow) do_flee( victim, "" ); } else { if ( !IS_NPC(victim) && victim->hit > 0 && (victim->hit*100)/victim->max_hit <= victim->wimpy && victim->wait < PULSE_VIOLENCE / 2 && dt != gsn_parting_blow) do_flee( victim, "" ); } tail_chain( ); return TRUE; } /* * Inflict damage from a hit. */ bool damage_old( CHAR_DATA *ch, CHAR_DATA *victim, int dam, int dt, int dam_type, bool show ) { OBJ_DATA *corpse; bool immune; OBJ_DATA *obj; OBJ_DATA *wield; bool kineticresult; int kineticdam; int originaldam; CHAR_DATA *owner = NULL; bool nosafe = FALSE; if ((dt == gsn_poison || dt == gsn_plague) && (ch != victim)) { owner = ch; ch = victim; nosafe = TRUE; } if (!nosafe && is_safe(ch,victim)) return FALSE; if ( victim->position == POS_DEAD ) return FALSE; if (IS_NPC(ch) && spellbaned(ch,victim,dt)) return FALSE; if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_RAVAGER) { if (spellbaned(ch,victim,dt)) return FALSE; } if (is_safe(ch,victim)) return FALSE; /* * Stop up any residual loopholes. */ originaldam=dam; if ( dam > 1400 && dt >= TYPE_HIT) { bug( "Damage: %d: more than 1400 points!", dam ); dam = 1400; } if ( victim != ch ) { /* * Certain attacks are forbidden. * Most other attacks are returned. */ if ( is_safe( ch, victim ) ) return FALSE; check_killer( ch, victim ); if ( (dt >= TYPE_HIT || dt == gsn_backstab || dt == gsn_ambush || dt == gsn_cleave || dt == gsn_deathstrike) && ch != victim && dam_type!=DAM_TRUESTRIKE) { if (check_counter(ch,victim,dam,dt)) return FALSE; if(is_affected(victim,gsn_steel_nerves) && dt!=gsn_kinetic_shield) dam*=.8; } if(dt==gsn_dual_backstab || HITS) { if(is_affected(victim,gsn_steel_nerves) && dam_type!=DAM_TRUESTRIKE) dam=dam*6/10; } if ( victim->position > POS_STUNNED ) { if ( victim->fighting == NULL ) set_fighting( victim, ch ); if (victim->timer <= 4) victim->position = POS_FIGHTING; } if ( victim->position > POS_STUNNED ) { if ( ch->fighting == NULL ) set_fighting( ch, victim ); /* * If victim is charmed, ch might attack victim's master. */ if ( IS_NPC(ch) && IS_NPC(victim) && IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL && victim->master->in_room == ch->in_room && number_bits( 3 ) == 0 ) { stop_fighting( ch, FALSE ); multi_hit( ch, victim->master, TYPE_UNDEFINED ); return FALSE; } } /* * More charm stuff. */ if ( victim->master == ch ) stop_follower( victim ); } /* * Inviso attacks ... not. */ un_camouflage(ch,NULL); un_hide(ch, NULL); un_invis(ch, NULL); un_sneak(ch, NULL); if (( (dt >= TYPE_HIT || dt == gsn_dual_wield) || (dt == gsn_tertiary_wield) ) && ch != victim) { if ( check_parry( ch, victim, dt ) ) { do_counter_parry(ch,victim,dt, dam); return FALSE; } //if ( check_flourintine( ch, victim, dt ) ) // return FALSE; if ( check_block( ch, victim, dt) ) return FALSE; if ( check_dodge( ch, victim, dt ) ) return FALSE; if ( check_questdodge( ch, victim, dt ) ) return FALSE; if ( check_shield_block(ch,victim, dt)) return FALSE; //if ( check_phase( ch, victim) ) // return FALSE; if (check_displacement( ch, victim)) return FALSE; if ( check_spin(ch,victim, dt)) return FALSE; } /* damage reduction */ if (dam > 85) { dam = (dam - 85); dam *= 7; dam /= 10; dam += 85; } /* * Damage modifiers. */ if (is_affected(ch, gsn_rage)) { dam *= 5; dam /= 4; } //elemental shields if (is_affected(victim, gsn_shield_of_flames)) dam *= .9; if (is_affected(victim, gsn_shield_of_frost)) dam *= .88; if (is_affected(victim, gsn_shield_of_bubbles)) dam *= .86; if (is_affected(victim, gsn_shield_of_dust)) dam *= .83; //slightly more defensive if (is_affected(victim, gsn_shield_of_lightning)) dam *= .86; if (is_affected(victim, gsn_shield_of_wind)) dam *= .86; //orduno brand stuff if (is_affected(victim, gsn_body_of_wood)) { dam /= 10; dam *= 9; } if (is_affected(victim, gsn_body_of_clay)) { dam /= 10; dam *= 8; } if (is_affected(victim, gsn_body_of_iron)) { dam /= 10; dam *= 7; } if (is_affected(victim, gsn_body_of_steel)) { dam /= 10; dam *= 6; } if ((is_affected(victim, gsn_body_of_stone)) && (!is_affected(victim, gsn_steel_nerves)) && (!IS_AFFECTED(victim, AFF_SANCTUARY))) { dam /= 10; dam *= 5; } if (is_affected(victim, gsn_body_of_diamond)) { dam /= 10; dam *= 4; } if ( dam > 1 && !IS_NPC(victim) && victim->pcdata->condition[COND_DRUNK] > 10 ) dam = 9 * dam / 10; if ( dam > 1 && IS_AFFECTED(victim, AFF_SANCTUARY) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) { if ( (dt >= TYPE_HIT || dt == gsn_dual_wield || dt == gsn_tertiary_wield)) { if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield == NULL ) dam /= 2; else if (wield->pIndexData->vnum != 29724) dam /= 2; } else dam /=2; } obj = get_eq_char(ch,WEAR_HEAD); if (obj != NULL && obj->pIndexData->vnum == OBJ_VNUM_TIARA && (dam_type == DAM_COLD || dam_type == DAM_FIRE || dam_type == DAM_HOLY || dam_type == DAM_NEGATIVE || dam_type == DAM_ACID) ) { if (dam > 125) { dam = (dam - 125); dam *= 6; dam /= 10; dam += 125; } } if (is_affected(victim,gsn_fireshield) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .5; if (is_affected(victim,gsn_wraithform) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .6; if (is_affected(victim,gsn_stoneskin) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .7; if (is_affected(victim,gsn_shield) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .7; if (is_affected(victim,gsn_kinetic_shield) && dt!=gsn_kinetic_shield && dam_type!=DAM_TRUESTRIKE) dam *= .7; if (is_affected(victim,gsn_shackles)) dam *= 1.5; if (is_affected(ch,gsn_rage_of_dioxide)) dam *= 1.15; if (check_crown_blood(ch,victim,dt,dam,dam_type)) return FALSE; if ( dam > 1 && ((IS_AFFECTED(victim, AFF_PROTECT_EVIL) && IS_EVIL(ch) ) || (IS_AFFECTED(victim, AFF_PROTECT_GOOD) && IS_GOOD(ch) )) && dam_type!=DAM_TRUESTRIKE) dam -= dam / 4; immune = FALSE; if (check_absorb(ch,victim,dt)) return FALSE; if (eye_of_beholder_absorb(ch,victim,dt,dam,dam_type)) return FALSE; /* * Check for parry, and dodge. */ switch(check_immune(victim,dam_type)) { case(IS_IMMUNE): immune = TRUE; dam = 0; break; case(IS_RESISTANT): if (IS_NPC(victim)) dam -= dam/3; else dam -= dam/5; break; case(IS_VULNERABLE): dam += dam/3; break; } if (show) dam_message( ch, victim, dam, dt, immune ); if ( (dt >= TYPE_HIT || dt == gsn_dual_wield || dt == gsn_tertiary_wield || dt == gsn_drum || dt==gsn_flurry) && ch != victim) { if (is_affected(victim,gsn_kinetic_shield) && dam>0) { if(number_percent()<67 || originaldam>175) { act("$n's kinetic shield reacts to $N's attack!",victim,0,ch,TO_NOTVICT); act("Your kinetic shield reacts to $N's attack!",victim,0,ch,TO_CHAR); act("$n's kinetic shield reacts to your attack!",victim,0,ch,TO_VICT); kineticdam=originaldam*.15; kineticresult = damage_old( victim, ch, kineticdam, gsn_kinetic_shield, DAM_ENERGY, TRUE ); } if (is_affected(victim,gsn_self_immolation) && dam>0) { act("$N is burned by the flames engulfing $n!",victim,NULL,ch,TO_NOTVICT); act("$N is burned by the flames engulfing you!",victim,NULL,ch,TO_CHAR); act("You are burned by the flames engulfing $n!",victim,NULL,ch,TO_VICT); damage_old(victim,ch,number_range(30,100),gsn_flames,DAM_FIRE, TRUE); } } } if (dam == 0) return FALSE; /* * Hurt the victim. * Inform the victim of his new state. */ victim->hit -= dam; if (dam_type == DAM_FIRE || dam_type == DAM_ACID) victim->noregen_dam += dam; if (victim->noregen_dam > victim->max_hit) victim->noregen_dam = victim->max_hit; if ( !IS_NPC(victim) && victim->level >= LEVEL_IMMORTAL && victim->hit < 1 ) victim->hit = 1; update_pos( victim ); switch( victim->position ) { case POS_MORTAL: act( "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are mortally wounded, and will die soon, if not aided.\n\r", victim ); break; case POS_INCAP: act( "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM ); send_to_char( "You are incapacitated and will slowly die, if not aided.\n\r", victim ); break; case POS_STUNNED: act( "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM ); send_to_char("You are stunned, but will probably recover.\n\r", victim ); break; case POS_DEAD: act( "$n is DEAD!!", victim, 0, 0, TO_ROOM ); send_to_char( "You have been KILLED!!\n\r\n\r", victim ); break; default: if ( dam > victim->max_hit / 4 ) send_to_char( "That really did HURT!\n\r", victim ); if ( victim->hit < victim->max_hit / 4 ) send_to_char( "You sure are BLEEDING!\n\r", victim ); break; } /* * Sleep spells and extremely wounded folks. */ if ( !IS_AWAKE(victim) && ch != victim) stop_fighting( victim, FALSE ); /* * Payoff for killing things. */ if ( victim->position == POS_DEAD ) { group_gain( ch, victim ); if ( !IS_NPC(victim) ) { sprintf( log_buf, "%s killed by %s at %d", victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->vnum ); log_string( log_buf ); } /* * Dying penalty: */ raw_kill(ch, victim ); /* RT new auto commands */ if ( !IS_NPC(ch) && IS_NPC(victim) ) { corpse = get_obj_list( ch, "corpse", ch->in_room->contents ); if ( IS_SET(ch->act, PLR_AUTOLOOT) && corpse && corpse->contains) /* exists and not empty */ do_get( ch, "all corpse" ); if (IS_SET(ch->act,PLR_AUTOGOLD) && corpse && corpse->contains && /* exists and not empty */ !IS_SET(ch->act,PLR_AUTOLOOT)) do_get(ch, "gold corpse"); if ( IS_SET(ch->act, PLR_AUTOSAC) ) { if ( IS_SET(ch->act,PLR_AUTOLOOT) && corpse && corpse->contains) return TRUE; /* leave if corpse has treasure */ else do_sacrifice( ch, "corpse" ); } } return TRUE; } if ( victim == ch ) return TRUE; /* * Take care of link dead people. */ if ( !IS_NPC(victim) && victim->desc == NULL ) { if ( number_range( 0, victim->wait ) == 0 ) { do_recall( victim, "" ); return TRUE; } } /* * Wimp out? */ if ( IS_NPC(victim) && dam > 0 && victim->wait < PULSE_VIOLENCE / 2) { if ( ( IS_SET(victim->act, ACT_WIMPY) && number_bits( 2 ) == 0 && victim->hit < victim->max_hit / 5) || ( IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL && victim->master->in_room != victim->in_room ) ) do_flee( victim, "" ); } if ( !IS_NPC(victim) && victim->hit > 0 && victim->hit <= victim->wimpy && victim->wait < PULSE_VIOLENCE / 2 ) do_flee( victim, "" ); tail_chain( ); return TRUE; } bool is_area_safe(CHAR_DATA *ch, CHAR_DATA *victim) { if (victim->in_room == NULL || ch->in_room == NULL) return TRUE; if (victim == ch ) return TRUE; if (victim->fighting == ch) return FALSE; if (IS_NPC(ch) && IS_GOOD(ch) && IS_GOOD(victim)) return FALSE; if (IS_IMMORTAL(victim) && victim->invis_level > 2) return TRUE; if (IS_IMMORTAL(ch) && IS_IMMORTAL(victim) && victim->level > LEVEL_IMMORTAL && !is_same_group(ch,victim)) return FALSE; if (IS_IMMORTAL(ch) && victim->level < ch->level && !is_same_group(ch,victim)) return FALSE; /* killing mobiles */ if (IS_NPC(victim)) { if (IS_SET(victim->in_room->room_flags,ROOM_SAFE)) { send_to_char("Not in this room.\n\r",ch); return TRUE; } if (is_same_group(ch,victim)) return TRUE; } /* killing players */ else { if (IS_SET(victim->in_room->room_flags,ROOM_SAFE)) { send_to_char("Not in this room.\n\r",ch); return TRUE; } if (IS_NPC(ch) && ch->master != NULL && !IS_NPC(ch->master)) return TRUE; if (IS_NPC(ch)) return FALSE; if (is_same_group(ch,victim)) return TRUE; } if (!IS_NPC(ch)) ch->ghost = (time_t)NULL; return FALSE; } bool is_safe(CHAR_DATA *ch, CHAR_DATA *victim) { if (victim->in_room == NULL || ch->in_room == NULL) return TRUE; if (IS_NPC(ch) && victim->invis_level >= LEVEL_HERO) return TRUE; if (!IS_NPC(ch)) { if (ch->pcdata->death_status == HAS_DIED) return TRUE; } if (!IS_NPC(victim)) { if (victim->pcdata->death_status == HAS_DIED) return TRUE; } /* Handle Link dead players , only saves from PKS, not mobs -Ceran */ if (!IS_NPC(victim) && victim->desc == NULL && !IS_NPC(ch) && victim->fighting != ch && ch->fighting != victim) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); return TRUE; } /* Protect newbies. 1 hour max - Dioxide*/ if (!IS_NPC(victim) && ((victim->played + current_time - victim->logon) < 3) && !IS_NPC(ch) && ((ch->played + current_time - ch->logon) < 3)) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); return TRUE; } if (is_affected(victim,gsn_timestop)) { act("$n is stuck in time and the gods protect $m.",victim,0,0,TO_ROOM); act("$N tries to do something but you are stuck in time and unaffected.",victim,0,ch,TO_CHAR); if (victim->fighting != NULL) victim->fighting = NULL; return TRUE; } if (victim->fighting == ch || victim == ch) return FALSE; if (IS_NPC(ch) && ch->last_fought == victim) return FALSE; if (victim->ghost > 0) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect you from $n.",ch,0,victim,TO_VICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); return TRUE; } if (ch->ghost > 0) { if (!IS_NPC(victim)) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect you from $n.",ch,0,victim,TO_VICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); return TRUE; } if (IS_AFFECTED(victim,AFF_CHARM) && victim->master != NULL && !IS_NPC(victim->master)) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect you from $n.",ch,0,victim,TO_VICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); return TRUE; } } if (IS_IMMORTAL(ch) && is_affected(ch,gsn_riot) && !IS_NPC(victim)) { send_to_char("You can't riot on mortals.\n\r",ch); return TRUE; } if (IS_IMMORTAL(ch) && ch->level > LEVEL_IMMORTAL) return FALSE; if (IS_SET(victim->act,PLR_CRIMINAL)) { if (IS_NPC(ch) && ch->pIndexData->vnum == MOB_VNUM_VIGILANTE) return FALSE; } if(IS_NPC(victim)&&victim->pIndexData->vnum==MOB_VNUM_VIGILANTE) return FALSE; /* killing mobiles */ if (IS_NPC(victim)) { if (!IS_NPC(ch)) { /* no charmed creatures unless in pk of master */ if (IS_AFFECTED(victim,AFF_CHARM) && !can_pk(ch,victim->master) && !is_centurion(victim)) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect you from $n.",ch,0,victim,TO_VICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); return TRUE; } } else { if (IS_AFFECTED(ch,AFF_CHARM) && IS_AFFECTED(victim,AFF_CHARM) && !can_pk(ch->master,victim->master)) return TRUE; } } /* killing players */ else { /* NPC doing the killing */ if (IS_NPC(ch)) { /* charmed mobs and pets cannot attack players while owned */ if (IS_AFFECTED(ch,AFF_CHARM) && ch->master != NULL && ch->master->fighting != victim && !is_centurion(ch) && !check_rangermob(ch)) { send_to_char("Players are your friends!\n\r",ch); return TRUE; } } /* player doing the killing */ else { if (!can_pk(ch, victim)) { if (!IS_IMMORTAL(victim)) { act("The gods protect $N from $n.",ch,0,victim,TO_NOTVICT); act("The gods protect you from $n.",ch,0,victim,TO_VICT); act("The gods protect $N from you.",ch,0,victim,TO_CHAR); } return TRUE; } } } return FALSE; } bool is_safe_spell(CHAR_DATA *ch, CHAR_DATA *victim, bool area ) { if (victim->in_room == NULL || ch->in_room == NULL) return TRUE; if (victim == ch && area) return TRUE; if (victim->fighting == ch || victim == ch) return FALSE; if (IS_IMMORTAL(ch) && ch->level > LEVEL_IMMORTAL && !area) return FALSE; /* killing mobiles */ if (IS_NPC(victim)) { /* safe room? */ if (IS_SET(victim->in_room->room_flags,ROOM_SAFE)) return TRUE; if (victim->pIndexData->pShop != NULL) return TRUE; /* no killing healers, trainers, etc */ if (IS_SET(victim->act,ACT_TRAIN) || IS_SET(victim->act,ACT_PRACTICE) || IS_SET(victim->act,ACT_IS_HEALER) || IS_SET(victim->act,ACT_IS_CHANGER)) return TRUE; if (!IS_NPC(ch)) { /* no pets */ if (IS_SET(victim->act,ACT_PET)) return TRUE; /* no charmed creatures unless owner */ if (IS_AFFECTED(victim,AFF_CHARM) && (area || ch != victim->master)) return TRUE; /* legal kill? -- cannot hit mob fighting non-group member */ if (victim->fighting != NULL && !is_same_group(ch,victim->fighting)) return TRUE; } else { /* area effect spells do not hit other mobs */ if (area && !is_same_group(victim,ch->fighting)) return TRUE; } } /* killing players */ else { if (area && IS_IMMORTAL(victim) && victim->level > LEVEL_IMMORTAL) return TRUE; /* NPC doing the killing */ if (IS_NPC(ch)) { /* charmed mobs and pets cannot attack players while owned */ if (IS_AFFECTED(ch,AFF_CHARM) && ch->master != NULL && ch->master->fighting != victim) return TRUE; /* safe room? */ if (IS_SET(victim->in_room->room_flags,ROOM_SAFE)) return TRUE; /* legal kill? -- mobs only hit players grouped with opponent*/ if (ch->fighting != NULL && !is_same_group(ch->fighting,victim)) return TRUE; } /* player doing the killing */ else { if (!is_cabal(ch)) return TRUE; if (IS_SET(victim->act,PLR_KILLER) || IS_SET(victim->act,PLR_THIEF)) return FALSE; if (!is_cabal(victim)) return TRUE; if (ch->level > victim->level + 8) 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) || IS_SET(victim->act, PLR_KILLER) || IS_SET(victim->act, PLR_THIEF)) return; /* * NPC's are cool of course (as long as not charmed). * Hitting yourself is cool too (bleeding). * So is being immortal (Alander's idea). * And current killers stay as they are. */ if ( IS_NPC(ch) || ch == victim || ch->level >= LEVEL_IMMORTAL || !is_cabal(ch) || IS_SET(ch->act, PLR_KILLER) || ch->fighting == victim) return; save_char_obj( ch ); return; } /* Check a counter-parry */ void do_counter_parry(CHAR_DATA *ch,CHAR_DATA *victim,int dt, int dam) { int chance; int tmp_dt; char *attack; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; if ((chance = get_skill(victim,gsn_counter_parry)) == 0 || IS_NPC(victim) || victim->level < skill_table[gsn_counter_parry].skill_level[victim->class]) return; chance /= 5; if (chance > 20) chance = 20; if (number_percent() < chance) { tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else attack = attack_table[0].name; sprintf(buf1,"You counter parry $n's %s!",attack); sprintf(buf2,"$N counter parries your %s!",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); if (cabal_down(victim,CABAL_RAVAGER)) return; damage_old(victim,ch,dam,gsn_counter_parry,TYPE_HIT,TRUE); check_improve(victim,gsn_counter_parry,TRUE,3); return; } check_improve(victim,gsn_counter_parry,FALSE,2); return; } bool check_displacement(CHAR_DATA *ch, CHAR_DATA *victim) { int chance; if (!(is_affected(victim, gsn_displacement))) return FALSE; chance = get_skill(victim,gsn_displacement); chance /= 3; chance *= 2; if (!can_see(victim,ch)) chance /=2; if (IS_AFFECTED(ch,AFF_DETECT_ILLUSION)) chance /= 4; if (number_percent() > chance + victim->level - ch->level) return FALSE; act("$n's attack passes harmlessly through $N.",ch,NULL,victim,TO_NOTVICT); act("$n's attack misses you completely.",ch,NULL,victim,TO_VICT); act("Your attack passes harmlessly through $N.",ch,NULL,victim,TO_CHAR); return TRUE; } bool check_counter(CHAR_DATA *ch,CHAR_DATA *victim,int dam,int dt) { int chance; if (dt == gsn_counter ) return FALSE; if (dt == gsn_counter_parry) return FALSE; if (ch->fighting != NULL) return FALSE; if ( (chance = get_skill(victim,gsn_counter)) == 0 || victim->level < skill_table[gsn_counter].skill_level[ch->class]) return FALSE; if (!can_see(victim,ch)) chance -= 30; if (get_eq_char(victim,WEAR_WIELD) == NULL) chance -= 50; chance += (victim->level - ch->level); if (victim->position != POS_FIGHTING && IS_AWAKE(victim)) { if (number_percent() < chance) { act("You counter $n's attack!",ch,0,victim,TO_VICT); act("$N counters your attack!",ch,0,victim,TO_CHAR); act("$N counters $n's attack!",ch,0,victim,TO_NOTVICT); check_improve(victim,gsn_counter,TRUE,1); damage_old(victim,ch,dam,gsn_counter,TYPE_UNDEFINED,TRUE); return TRUE; } } check_improve(victim,gsn_counter,FALSE,2); return FALSE; } /* * Check for parry. */ bool check_parry( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int flourintine = 0; int chance; int tmp_dt; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; OBJ_DATA *victimwield; if ( !IS_AWAKE(victim) ) return FALSE; chance = get_skill(victim,gsn_parry) / 2; if ( get_eq_char( victim, WEAR_WIELD ) == NULL ) { if (IS_NPC (victim) || isShifted(victim)) chance /= 2; else return FALSE; } if (IS_AFFECTED(victim,AFF_BLIND)) chance *= number_range(6/10,3/4); if (is_affected(victim,gsn_executioner)) chance+=20; if (is_affected(ch,gsn_rage_of_dioxide)) chance-=10; if (is_affected(victim,skill_lookup("haste"))) chance+=20; if (is_affected(ch,skill_lookup("haste"))) chance-=15; if (is_affected(victim,gsn_rage)) chance *= .75; /* The rest is all new dual wield stuff, with dam types displayed for clarity when dual wielding - Ceran */ tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) { /* Weapons affect parrying. */ switch (wield->value[0]) { default: chance+=15; break; case (WEAPON_SWORD): chance+=5; break; case (WEAPON_DAGGER): chance+=5; break; case (WEAPON_SPEAR): chance-=5; break; case (WEAPON_STAFF): chance-=5; break; case (WEAPON_MACE): chance-=5; break; case (WEAPON_AXE): chance-=5; break; case (WEAPON_FLAIL): chance+=10; break; case (WEAPON_WHIP): chance+=10; break; case (WEAPON_POLEARM): chance-=5; break; } } if((victimwield=get_eq_char(victim,WEAR_WIELD)) != NULL) { switch (victimwield->value[0]) { default: break; case (WEAPON_SWORD): chance+=10; flourintine++; break; case (WEAPON_DAGGER): chance-=20; break; case (WEAPON_SPEAR): chance+=20; break; case (WEAPON_STAFF): chance+=10; break; case (WEAPON_MACE): chance-=20; break; case (WEAPON_AXE): chance-=25; break; case (WEAPON_FLAIL): chance-=10; break; case (WEAPON_WHIP): chance-=10; break; case (WEAPON_POLEARM): chance+=10; break; } } if ((get_skill(victim,gsn_flourintine) > 0) && flourintine == 1) { check_improve(victim,gsn_flourintine,TRUE,1); chance += get_skill(victim,gsn_flourintine) / 7; } if (isShifted(victim)) chance += form_table[victim->pcdata->shifted].parry_mod; if ( number_percent( ) >= chance) { check_improve(victim,gsn_parry,FALSE,2); return FALSE; } /* imperial training */ if (!IS_NPC(ch)) { if (check_imperial_training(ch) == IMPERIAL_OFFENSE) chance -= 20; if (check_imperial_training(ch) == IMPERIAL_DEFENSE) chance += 20; } if (!IS_NPC(victim)) { if (check_imperial_training(victim) == IMPERIAL_OFFENSE) chance -= 20; if (check_imperial_training(victim) == IMPERIAL_DEFENSE) chance += 20; } if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In parry, bad dam message: dt %d.",tmp_dt); sprintf(buf1,"Player: %s Target: %s.",ch->name,victim->name); bug(buf1, 0); attack = attack_table[0].name; } sprintf(buf1,"You parry $n's %s.",attack); sprintf(buf2,"$N parries your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_parry,TRUE,2); return TRUE; } /* The rest is all new dual wield stuff, with dam types displayed for clarity when dual wielding - Ceran */ /* tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In parry, bad dam message: dt %d.",tmp_dt); sprintf(buf1,"Player: %s Target: %s.",ch->name,victim->name); bug(buf1, 0); attack = attack_table[0].name; } sprintf(buf1,"You block $n's %s with an agile cross parry.",attack); sprintf(buf2,"$N blocks your %s with an agile cross parry.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); // check_improve(victim,tsn,TRUE,1); check_improve(victim,gsn_flourintine,TRUE,2); return TRUE; } */ /* Block for monks */ bool check_block( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; int tmp_dt; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ( !IS_AWAKE(victim) ) return FALSE; if (IS_NPC(victim)) return FALSE; chance = get_skill(victim,gsn_block); if ( victim->level <skill_table[gsn_block].skill_level[victim->class]) return FALSE; chance /= 2.25; if (get_eq_char(victim,WEAR_WIELD) != NULL) return FALSE; if (!can_see(ch,victim)) chance /= 2; if (is_affected(victim,gsn_rage)) chance *= .75; if ( number_percent( ) >= chance + (victim->drain_level + victim->level) - (ch->drain_level + ch->level) ) { check_improve(victim,gsn_block,FALSE,5); return FALSE; } /* The rest is all new dual wield stuff, with dam types displayed for clarity when dual wielding - Ceran */ tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In check_block, bad dam message: dt %d.",tmp_dt); attack = attack_table[0].name; } sprintf(buf1,"You hand block $n's %s.",attack); sprintf(buf2,"$N hand blocks your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_block,TRUE,6); return TRUE; } /* * Check for shield block. */ bool check_shield_block( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; int tmp_dt; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ( !IS_AWAKE(victim) ) return FALSE; if(victim->level < skill_table[gsn_shield_block].skill_level[victim->class]) return FALSE; chance = (( get_skill(victim,gsn_shield_block) / 4) + 15); /* imperial training */ if (!IS_NPC(ch)) { if (check_imperial_training(ch) == IMPERIAL_OFFENSE) chance -= 10; if (check_imperial_training(ch) == IMPERIAL_DEFENSE) chance += 20; } if (!IS_NPC(victim)) { if (check_imperial_training(victim) == IMPERIAL_OFFENSE) chance -= 20; if (check_imperial_training(victim) == IMPERIAL_DEFENSE) chance += 10; } if ( get_eq_char( victim, WEAR_SHIELD ) == NULL ) return FALSE; chance += (victim->drain_level + victim->level - (ch->drain_level + ch->level)); if (is_affected(victim,gsn_rage)) chance *= .75; if ( number_percent( ) >= chance ) { check_improve(victim,gsn_shield_block,FALSE,4); return FALSE; } tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In shield block, bad dam message: dt %d.",tmp_dt); attack = attack_table[0].name; } sprintf(buf1,"You shield block $n's %s.",attack); sprintf(buf2,"$N shield blocks your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_shield_block,TRUE,4); return TRUE; } /* * Check for dodge. */ bool check_dodge( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; int tmp_dt; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; int dex, dexa; if ( !IS_AWAKE(victim) ) return FALSE; chance = ( 3 * get_skill(victim,gsn_dodge) / 10); dex = get_curr_stat(victim,STAT_DEX); dexa= get_curr_stat(ch,STAT_DEX); if (dex <= 5) chance += 0; else if (dex <= 10) chance += dex/2; else if (dex <=15) chance += (2*dex/3); else if (dex <= 20) chance += (8*dex/10); else chance += dex; chance+=dex-dexa; chance+=(ch->size-victim->size)*5; /*if ((get_skill(ch,gsn_ironhands)) >=95) chance+=35; else if ((get_skill(ch,gsn_ironhands)) >=85) chance+=20; else if ((get_skill(ch,gsn_ironhands)) >=75) chance+=15; else if ((get_skill(ch,gsn_ironhands)) >=65) chance+=10; else if ((get_skill(ch,gsn_ironhands)) >=55) chance+=10; else if ((get_skill(ch,gsn_ironhands)) >=45) chance+=5;*/ if (is_affected(ch,gsn_executioner)) chance+=30; /* imperial training */ if (!IS_NPC(ch)) { if (check_imperial_training(ch) == IMPERIAL_OFFENSE) chance -= 20; if (check_imperial_training(ch) == IMPERIAL_DEFENSE) chance += 20; } if (!IS_NPC(victim)) { if (check_imperial_training(victim) == IMPERIAL_OFFENSE) chance -= 20; if (check_imperial_training(victim) == IMPERIAL_DEFENSE) chance += 20; } if (is_affected(ch,gsn_rage_of_dioxide)) chance-=20; if (!can_see(victim,ch)) chance *= number_range(6/10,3/4); if (is_affected(victim,gsn_rage)) chance *= .6; if ( number_percent( ) >= chance + (victim->drain_level + victim->level) - (ch->drain_level + ch->level) ) { check_improve(victim,gsn_dodge,FALSE,4); return FALSE; } /* The rest is all new dual wield stuff, with dam types displayed for clarity when dual wielding - Ceran */ tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In dodge, bad dam message: dt %d.",tmp_dt); attack = attack_table[0].name; } sprintf(buf1,"You dodge $n's %s.",attack); sprintf(buf2,"$N dodges your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_dodge,TRUE,5); return TRUE; } /* * Check for quest dodge. */ bool check_questdodge( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; int tmp_dt; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; int dex, dexa; if ( !IS_AWAKE(victim) ) return FALSE; if (get_skill(victim,gsn_questdodge) == 0) { return FALSE; } chance = ( 3 * get_skill(victim,gsn_questdodge) / 7); dex = get_curr_stat(victim,STAT_DEX); dexa= get_curr_stat(ch,STAT_DEX); if (dex <= 5) chance += 0; else if (dex <= 10) chance += dex/2; else if (dex <=15) chance += (2*dex/3); else if (dex <= 20) chance += (8*dex/10); else chance += dex; chance+=dex-dexa; chance+=(ch->size-victim->size)*5; if (is_affected(ch,gsn_executioner)) chance+=30; if (!can_see(victim,ch)) chance /= 2; if ( number_percent( ) >= chance + (victim->drain_level + victim->level) - (ch->drain_level + ch->level) ) { check_improve(victim,gsn_questdodge,FALSE,4); return FALSE; } tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else if (dt == gsn_tertiary_wield) wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In quest dodge, bad dam message: dt %d.",tmp_dt); attack = attack_table[0].name; } sprintf(buf1,"You evade $n's %s.",attack); sprintf(buf2,"$N evades your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_questdodge,TRUE,5); return TRUE; } /* * Check for defensive spin. */ bool check_spin( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; int tmp_dt; // int weaponskill; OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ((chance = get_skill(victim,gsn_spin) / 2) == 0) { return FALSE; } wield = get_eq_char(victim,WEAR_WIELD); if (wield == NULL) { return FALSE; } if (wield != NULL) { switch (wield->value[0]) { case (WEAPON_STAFF): chance+= get_skill(victim,gsn_staff) / 10; break; case (WEAPON_SPEAR): chance+= get_skill(victim,gsn_spear) / 10; break; case (WEAPON_POLEARM): chance+= get_skill(victim,gsn_polearm) / 10; break; default: return FALSE; break; } } if ( !IS_AWAKE(victim) ) return FALSE; if ( get_eq_char( victim, WEAR_WIELD ) == NULL ) { if (IS_NPC(victim)) chance /= 2; else return FALSE; } if (IS_AFFECTED(victim,AFF_BLIND)) chance *= .6; if (is_affected(victim,skill_lookup("haste"))) chance+=20; if (is_affected(ch,skill_lookup("haste"))) chance-=15; if (is_affected(victim,gsn_rage)) chance *= .75; tmp_dt = TYPE_HIT; if ( number_percent() >= chance) { check_improve(victim,gsn_spin,FALSE,2); return FALSE; } if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { bug("In spin, bad dam message: dt %d.",tmp_dt); sprintf(buf1,"Player: %s Target: %s.",ch->name,victim->name); bug(buf1, 0); attack = attack_table[0].name; } sprintf(buf1,"Your defensive spin blocks $n's %s.",attack); sprintf(buf2,"$N's defensive spin blocks your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_spin,TRUE,2); return TRUE; } bool check_distance( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance, sn = skill_lookup("distance"); OBJ_DATA *wield; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ( !IS_AWAKE(victim) ) return FALSE; if(get_skill(victim,sn)<5) return FALSE; chance = (( get_skill(victim,sn) / 4) + 15); /* imperial training */ if (check_imperial_training(ch) == IMPERIAL_OFFENSE) chance -= 10; if (check_imperial_training(victim) == IMPERIAL_DEFENSE) chance += 10; if (check_imperial_training(victim) == IMPERIAL_OFFENSE) chance -= 20; if (check_imperial_training(ch) == IMPERIAL_DEFENSE) chance += 20; chance+=20*(victim->size-ch->size); chance+=10*(get_curr_stat(victim,STAT_STR)-get_curr_stat(ch,STAT_STR)); if(IS_AFFECTED(victim,AFF_HASTE)) chance+=15; if(IS_AFFECTED(ch,AFF_HASTE)) chance-=15; if( ((wield=get_eq_char(victim,WEAR_WIELD)) == NULL || wield->value[0]!=WEAPON_POLEARM)) return FALSE; chance += victim->level - ch->level; chance*=(1-((float)GET_HITROLL(ch) / (float) 250)); if (is_affected(victim,gsn_rage)) chance *= .75; chance=URANGE(5,chance,65); if ( number_percent( ) >= chance ) return FALSE; attack=get_dam_message(ch,dt); if(number_percent()<(chance/3)) { sprintf(buf1,"You keep $n at bay with your $p, knocking $m off balance with a counter strike."); sprintf(buf2,"$N keeps you at bay with $S $p, knocking you off balance with a counter strike."); act(buf1,ch,wield,victim,TO_VICT); act(buf2,ch,wield,victim,TO_CHAR); sprintf(buf1,"$N keeps $n at bay with $S $p, knocking $m off balance with a counter strike."); act(buf1,ch,wield,victim,TO_NOTVICT); one_hit(victim,ch,sn); WAIT_STATE(ch,PULSE_VIOLENCE*1.5); return TRUE; } sprintf(buf1,"You keep $n's %s at bay with your polearm.",attack); sprintf(buf2,"$N keeps your %s at bay with $s polearm.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,sn,TRUE,2); return TRUE; } bool check_defiant_absorb( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ( !IS_AWAKE(victim) ) return FALSE; if (!is_affected(victim,gsn_defiance)) return FALSE; attack=get_dam_message(ch,dt); if (number_percent () < 35) { sprintf(buf1,"You defiantly absorb $n's %s.",attack); sprintf(buf2,"$N defiantly absorbs your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); return TRUE; } return FALSE; } /* * Set position of a victim. */ void update_pos( CHAR_DATA *victim ) { if ( victim->hit > 0 ) { if ( victim->position <= POS_STUNNED ) victim->position = POS_STANDING; return; } if ( IS_NPC(victim) && victim->hit < 1 ) { victim->position = POS_DEAD; return; } if ( victim->hit <= -11 ) { victim->position = POS_DEAD; return; } if ( victim->hit <= -6 ) victim->position = POS_MORTAL; else if ( victim->hit <= -3 ) victim->position = POS_INCAP; else victim->position = POS_STUNNED; return; } /* * Start fights. */ void set_fighting( CHAR_DATA *ch, CHAR_DATA *victim ) { char buf[MAX_STRING_LENGTH]; if ( ch->fighting != NULL ) { bug( "Set_fighting: already fighting", 0 ); return; } if ( IS_AFFECTED(ch, AFF_SLEEP) ) affect_strip( ch, gsn_sleep ); if (is_affected(victim,gsn_trip_wire)) { send_to_char("You lost your trip wire in the frey.\n\r",victim); affect_strip(victim,gsn_trip_wire); } if (is_affected(ch,gsn_trip_wire)) { send_to_char("You lost your trip wire in the frey.\n\r",ch); affect_strip(ch,gsn_trip_wire); } ch->fighting = victim; ch->position = POS_FIGHTING; if (is_centurion(victim)) { sprintf(buf,"empire Help! %s is attacking me!",PERS(ch,victim)); do_ccb(victim,buf); } return; } /* * Stop fights. */ void stop_fighting( CHAR_DATA *ch, bool fBoth ) { CHAR_DATA *fch; for ( fch = char_list; fch != NULL; fch = fch->next ) { if ( fch == ch || ( fBoth && fch->fighting == ch ) ) { fch->fighting = NULL; fch->position = IS_NPC(fch) ? fch->default_pos : POS_STANDING; update_pos( fch ); } } return; } /* * Make a corpse out of a character. */ void make_corpse( CHAR_DATA *killer,CHAR_DATA *ch ) { char buf[MAX_STRING_LENGTH]; OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *obj_next; CHAR_DATA *itemguy; char *name; if (IS_NPC(ch) && (ch->pIndexData->vnum == MOB_VNUM_PROTECTOR || ch->pIndexData->vnum == MOB_VNUM_ACADIAN || ch->pIndexData->vnum == MOB_VNUM_COVEN || ch->pIndexData->vnum == MOB_VNUM_BRIAR || ch->pIndexData->vnum == MOB_VNUM_RAVAGER) ) { for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ((obj->pIndexData->vnum!=0) && isCabalItem(obj) ) { itemguy=killer; sprintf(buf,"As %s falls to the ground, the %s appears in the hands of %s!",ch->short_descr,obj->short_descr,itemguy->name); if(IS_NPC(killer)) { if (killer->leader!=0) itemguy=killer->leader; sprintf(buf,"As %s falls to %s's minions, the %s appears in the hands of %s!",ch->short_descr,itemguy->name,obj->short_descr,itemguy->name); } act(buf,itemguy,NULL,NULL,TO_ROOM); sprintf(buf,"As %s falls to the ground, the %s appears in your hands!",ch->short_descr,obj->short_descr); act(buf,itemguy,NULL,NULL,TO_CHAR); obj_from_char( obj ); obj_to_char(obj,itemguy); } } return; } if ( IS_NPC(ch) ) { name = ch->short_descr; corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC), 0); corpse->timer = number_range( 5, 8 ); free_string(corpse->talked); if (IS_NPC(killer)) corpse->talked = str_dup(killer->short_descr); else corpse->talked = str_dup(killer->name); if ( ch->gold > 0 ) { obj_to_obj( create_money( ch->gold, ch->silver ), corpse ); ch->gold = 0; ch->silver = 0; } corpse->cost = 0; } else { name = ch->name; corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0); corpse->timer = number_range( 20, 35 ); corpse->value[4] = ch->temple; REMOVE_BIT(ch->act,PLR_CANLOOT); free_string(corpse->talked); if (IS_NPC(killer)) corpse->talked = str_dup(killer->short_descr); else corpse->talked = str_dup(killer->name); if (!is_cabal(ch)) corpse->owner = str_dup(ch->name); else { if (ch->gold > 1 || ch->silver > 1) { obj_to_obj(create_money(ch->gold, ch->silver), corpse); ch->gold = 0; ch->silver = 0; } } corpse->cost = 0; } corpse->level = ch->level; if (IS_SET(ch->act,ACT_UNDEAD) || IS_SET(ch->form,FORM_UNDEAD)) SET_BIT(corpse->extra_flags,CORPSE_NO_ANIMATE); sprintf( buf, corpse->short_descr, name ); free_string( corpse->short_descr ); corpse->short_descr = str_dup( buf ); sprintf( buf, corpse->description, name ); free_string( corpse->description ); corpse->description = str_dup( buf ); for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { bool floating = FALSE; obj_next = obj->next_content; if (obj->wear_loc != WEAR_BRAND) { obj_from_char( obj ); } if (obj->item_type == ITEM_POTION) obj->timer = number_range(500,1000); if (obj->item_type == ITEM_SCROLL) obj->timer = number_range(1000,2500); /* Area specific objects, remove these if you don't use the area */ if (obj->pIndexData->vnum == OBJ_VNUM_HYDRA_SLAYER) obj->timer = number_range(500,1500); else if (obj->pIndexData->vnum == OBJ_VNUM_HYDRA_HEAD) obj->timer = number_range(300,900); if (IS_SET(obj->extra_flags,ITEM_ROT_DEATH) && !floating) { obj->timer = 1; REMOVE_BIT(obj->extra_flags,ITEM_ROT_DEATH); } REMOVE_BIT(obj->extra_flags,ITEM_VIS_DEATH); if (obj->item_type == ITEM_WEAPON) { if (IS_WEAPON_STAT(obj,WEAPON_LEADER)) obj_to_char(obj,ch); } if (obj->pIndexData->limcount > obj->pIndexData->limtotal && obj->pIndexData->limtotal > 0) { act("$p flashes brightly and vaporizes.",ch,obj,NULL,TO_ROOM); extract_obj( obj ); } /* if (IS_SET(obj->extra_flags,ITEM_FIXED) && !(IS_NPC(ch))) { act("$p flashes brightly and returns to its rightful owner!",ch,obj,NULL,TO_ROOM); } */ else if (floating) { if (IS_OBJ_STAT(obj,ITEM_ROT_DEATH)) /* get rid of it! */ { if (obj->contains != NULL) { OBJ_DATA *in, *in_next; act("$p evaporates,scattering its contents.", ch,obj,NULL,TO_ROOM); for (in = obj->contains; in != NULL; in = in_next) { in_next = in->next_content; obj_from_obj(in); obj_to_room(in,ch->in_room); } } else act("$p evaporates.", ch,obj,NULL,TO_ROOM); extract_obj(obj); } else { act("$p falls to the floor.",ch,obj,NULL,TO_ROOM); obj_to_room(obj,ch->in_room); } } else if (obj->wear_loc != WEAR_BRAND) { obj_to_obj( obj, corpse ); } else if (obj->wear_loc != WEAR_BOUND) { obj_to_obj( obj, corpse ); } /* else if (!( (obj->wear_loc == WEAR_BRAND) || ((IS_SET(obj->extra_flags,ITEM_FIXED)) ) ) ) { obj_to_obj( obj, corpse ); } */ } obj_to_room( corpse, ch->in_room ); return; } /* * Improved Death_cry contributed by Diavolo. */ void death_cry( CHAR_DATA *ch ) { ROOM_INDEX_DATA *was_in_room; char *msg; int door; int vnum; vnum = 0; msg = "You hear $n's death cry."; switch ( number_bits(4)) { case 0: msg = "$n hits the ground ... DEAD."; break; case 1: if (ch->material == 0) { msg = "$n splatters blood on your armor."; break; } case 2: if (IS_SET(ch->parts,PART_GUTS)) { msg = "$n spills $s guts all over the floor."; vnum = OBJ_VNUM_GUTS; } break; case 3: if (IS_SET(ch->parts,PART_HEAD)) { msg = "$n's severed head plops on the ground."; vnum = OBJ_VNUM_SEVERED_HEAD; } break; case 4: if (IS_SET(ch->parts,PART_HEART)) { msg = "$n's heart is torn from $s chest."; vnum = OBJ_VNUM_TORN_HEART; } break; case 5: if (IS_SET(ch->parts,PART_ARMS)) { msg = "$n's arm is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_ARM; } break; case 6: if (IS_SET(ch->parts,PART_LEGS)) { msg = "$n's leg is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_LEG; } break; case 7: if (IS_SET(ch->parts,PART_BRAINS)) { msg = "$n's head is shattered, and $s brains splash all over you."; vnum = OBJ_VNUM_BRAINS; } } if (IS_SET(ch->parts,PART_HEAD) && is_affected(ch,gsn_decapitate)) { msg = "$n's severed head plops on the ground."; vnum = OBJ_VNUM_SEVERED_HEAD; } act( msg, ch, NULL, NULL, TO_ROOM ); if ( vnum != 0 ) { char buf[MAX_STRING_LENGTH]; OBJ_DATA *obj; char *name; name = IS_NPC(ch) ? ch->short_descr : ch->name; obj = create_object( get_obj_index( vnum ), 0 ); obj->timer = number_range( 4, 7 ); sprintf( buf, obj->short_descr, name ); free_string( obj->short_descr ); obj->short_descr = str_dup( buf ); sprintf( buf, obj->description, name ); free_string( obj->description ); obj->description = str_dup( buf ); if (obj->item_type == ITEM_FOOD) { if (IS_SET(ch->form,FORM_POISON)) obj->value[3] = 1; else if (!IS_SET(ch->form,FORM_EDIBLE)) obj->item_type = ITEM_TRASH; } obj_to_room( obj, ch->in_room ); } if ( IS_NPC(ch) ) msg = "You hear something's death cry."; else msg = "You hear someone's death cry."; was_in_room = ch->in_room; for ( door = 0; door <= 5; door++ ) { EXIT_DATA *pexit; if ( ( pexit = was_in_room->exit[door] ) != NULL && pexit->u1.to_room != NULL && pexit->u1.to_room != was_in_room ) { ch->in_room = pexit->u1.to_room; act( msg, ch, NULL, NULL, TO_ROOM ); } } ch->in_room = was_in_room; return; } void raw_kill( CHAR_DATA *ch,CHAR_DATA *victim ) { int i, cloak = 0; // char strsave[MAX_INPUT_LENGTH]; ROOM_INDEX_DATA *location; AFFECT_DATA af; CHAR_DATA *gch; CHAR_DATA *gch_next; CHAR_DATA *shadow; CHAR_DATA *zombie; // OBJ_DATA *etched; OBJ_DATA *trophy; OBJ_DATA *duelcorpse; ROOM_INDEX_DATA *arena_room; ROOM_INDEX_DATA *old_room; char buf[MAX_STRING_LENGTH]; char wizbuf[MAX_STRING_LENGTH]; bool unholy=0; stop_fighting( victim, TRUE ); if (IS_NPC(victim) && (victim->pIndexData->vnum == MOB_VNUM_BLACK_STEED || victim->pIndexData->vnum == MOB_VNUM_RED_STEED || victim->pIndexData->vnum == MOB_VNUM_BLUE_STEED || victim->pIndexData->vnum == MOB_VNUM_GREEN_STEED)) { do_dismount(victim->master,""); act("$n vanishes into the abyss!",victim,0,0,TO_ROOM); } if(IS_NPC(victim) && (victim->pIndexData->vnum == MOB_VNUM_PROTECTOR || victim->pIndexData->vnum == MOB_VNUM_ACADIAN || victim->pIndexData->vnum == MOB_VNUM_COVEN || victim->pIndexData->vnum == MOB_VNUM_BRIAR || victim->pIndexData->vnum == MOB_VNUM_RAVAGER)) do_cb(victim,"Alas, my life has come to an end..."); if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_DECOY) { death_cry(victim); act("$n vanishes in a poof of smoke!",victim,0,0,TO_ROOM); } else { death_cry( victim ); /* Imm deaths */ if (!IS_NPC(victim) && IS_IMMORTAL(victim)) { if (victim->pcdata->imm_death) { act("$t.",victim,NULL,NULL,TO_ROOM); act("$t.",victim,NULL,NULL,TO_CHAR); } else { act("$n's skull glows brightly and $n rises from $s ashes!",victim,0,0,TO_ROOM); send_to_char("Your skull glows brightly and you rise from your ashes!\n\r",victim); } return; } /* ARENA DEATH -- Dioxide */ if (!IS_NPC(victim)) { if (arena) { /* MAIN STUFF */ sprintf(buf,"%s is killed by %s!",victim->name,ch->name); do_arena_echo(buf); char_from_room(victim); location = get_room_index(26000); char_to_room(victim,location); victim->ghost = 1; affect_strip(victim,gsn_plague); affect_strip(victim,gsn_poison); affect_strip(victim,gsn_blindness); affect_strip(victim,gsn_sleep); affect_strip(victim,gsn_curse); affect_strip(victim,gsn_decapitate); affect_strip(victim,gsn_shackles); affect_strip(victim,gsn_boneshatter); victim->hit = victim->max_hit; victim->mana = victim->max_mana; victim->move = victim->max_move; update_pos( victim); send_to_char("You have died and turned into an invincible ghost a few seconds.\n\r",victim); act("$n suddenly appears as a ghost.",victim,0,0,TO_ROOM); /* TROPHY CODE */ trophy = create_object(get_obj_index(OBJ_VNUM_ARENA_TROPHY),0); sprintf( buf, trophy->short_descr, victim->name); free_string( trophy->short_descr ); trophy->short_descr = str_dup( buf ); sprintf( buf, trophy->description, victim->name); free_string( trophy->description ); trophy->description = str_dup( buf ); obj_to_char(trophy,ch); act("You receive $p.",ch,trophy,0,TO_CHAR); act("$n receives $p.",ch,trophy,0,TO_ROOM); return; } } temp_death_log(ch,victim); //Bounty payoff for Ancient. if (!IS_NPC(victim) && (ch->pcdata->target == victim->name) && victim->pcdata->bounty > 0) { trophy = create_object(get_obj_index(OBJ_VNUM_ANCIENT_SCALP),0); sprintf( buf, trophy->short_descr, victim->name); free_string( trophy->short_descr ); trophy->short_descr = str_dup( buf); sprintf( buf, trophy->description, victim->name); free_string( trophy->description ); trophy->description = str_dup(buf); obj_to_char(trophy,ch); act("You violently carve off their scalp.",ch,0,0,TO_CHAR); act("$n violently carves off their scalp.",ch,0,0,TO_ROOM); sprintf(buf,"You recive a %d gold bounty, for killing %s.\n\r", victim->pcdata->bounty, victim->name); send_to_char("Assignment completed.\n\r", ch ); send_to_char(buf, ch); ch->gold += victim->pcdata->bounty; victim->pcdata->bounty =0; affect_strip(ch, gsn_target); ch->pcdata->target = NULL; } /* AP unholy bless check --Dioxide */ if (check_unholy_bless(ch,victim)) { unholy = TRUE; } else { unholy = FALSE; } if (is_affected(victim,gsn_unholy_timer)) { unholy = TRUE; } //strap = get_eq_char(victim, WEAR_STRAPPED); /*if (strap != NULL) { do_strap(victim,strap); }*/ make_corpse( ch,victim ); //victim->noregen_dam = 0; } sprintf( wizbuf, "%s got toasted by %s at %s [room %d]", (IS_NPC(victim) ? victim->short_descr : (victim->original_name ? victim->original_name : victim->name)), (IS_NPC(ch) ? ch->short_descr : (ch->original_name ? ch->original_name : ch->name)), ch->in_room->name, ch->in_room->vnum); if (IS_NPC(victim)) wiznet(wizbuf,NULL,NULL,WIZ_MOBDEATHS,0,0); else wiznet(wizbuf,NULL,NULL,WIZ_DEATHS,0,0); for (gch = char_list; gch != NULL; gch = gch_next) { gch_next = gch->next; if (IS_NPC(gch) && gch->master == victim) extract_char(gch,TRUE); } if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_STALKER) { if (victim->last_fought != NULL) { sprintf(buf,"enforcer My life has come to an end; %s remains at large.",victim->last_fought->name); do_ccb(victim,buf); } } for (gch = char_list; gch != NULL; gch = gch_next) { gch_next = gch->next; if (IS_NPC(gch) && (gch->pIndexData->vnum == MOB_VNUM_STALKER) && (gch->last_fought == victim)) { sprintf(buf,"enforcer %s has been terminated.",victim->name); do_ccb(gch,buf); extract_char(gch,TRUE); act("$N slowly fades away.",victim,NULL,gch,TO_NOTVICT); } } /* This next bit handles the Nightfall spell */ if (victim->nightfall != NULL && victim->nightfall->in_room == victim->in_room) { act("$n's soul is torn from it's body and formed into a shadow!",victim,0,0,TO_ROOM); act("$n rips your soul away and forms a shadow!",victim->nightfall,0,victim,TO_VICT); shadow = create_mobile(get_mob_index(MOB_VNUM_NIGHTFALL)); char_to_room(shadow,victim->in_room); free_string(shadow->short_descr); free_string(shadow->long_descr); sprintf(buf,"the shadow of %s", IS_NPC(victim) ? victim->short_descr : victim->name); shadow->short_descr = str_dup(buf); sprintf(buf,"The shadow of %s is hovering here in silence.\n\r", IS_NPC(victim) ? victim->short_descr : victim->name); shadow->long_descr = str_dup(buf); shadow->max_hit = victim->nightfall->max_hit; shadow->hit = victim->max_hit; shadow->damroll = victim->level/2; shadow->hitroll = victim->level/3; shadow->level = victim->level; shadow->armor[0] = -victim->level*4; shadow->armor[1] = -victim->level*4; shadow->armor[2] = -victim->level*4; shadow->armor[3] = -victim->level*3; SET_BIT(shadow->comm,COMM_QUIET); SET_BIT(shadow->affected_by,AFF_CHARM); shadow->leader = victim->nightfall; shadow->master = victim->nightfall; } if (victim->nightfall != NULL) { if (victim->nightfall->in_room == victim->in_room) act("You grasp onto $n's soul for you own uses!",victim,0,victim->nightfall,TO_VICT); else act("Your grasp on $n's soul fades away.",victim,0,victim->nightfall,TO_VICT); victim->nightfall = NULL; } /* Quick score time before we dump any NPCs..for 'ratings' command */ if (!IS_NPC(ch)) { if (!IS_NPC(victim)) { ch->pcdata->kills[PK_KILLS]++; if (victim->alignment > 0) { ch->pcdata->kills[PK_GOOD]++; } else if (victim->alignment == 0) { ch->pcdata->kills[PK_NEUTRAL]++; } else if (victim->alignment < 0) { ch->pcdata->kills[PK_EVIL]++; } victim->pcdata->killed[PK_KILLED]++; } } else { if (!IS_NPC(victim)) { victim->pcdata->killed[MOB_KILLED]++; } } if ( IS_NPC(victim) ) { victim->pIndexData->killed++; kill_table[URANGE(0, victim->level, MAX_LEVEL-1)].killed++; extract_char( victim, TRUE ); return; } while(victim->affected) affect_remove( victim, victim->affected ); extract_char( victim, FALSE ); if(is_affected(victim,gsn_cloak_form)) cloak=1; while(victim->affected) affect_remove( victim, victim->affected ); victim->affected_by = race_table[victim->race].aff; for (i = 0; i < 4; i++) victim->armor[i]= 100; victim->position = POS_RESTING; victim->hit = victim->pcdata->perm_hit/2; victim->mana = victim->pcdata->perm_mana/2; victim->move = victim->pcdata->perm_move/2; victim->pcdata->condition[COND_HUNGER] = 48; victim->pcdata->condition[COND_THIRST] = 48; victim->pcdata->condition[COND_DRUNK] = 0; victim->pcdata->condition[COND_FULL] = 0; victim->pcdata->condition[COND_DEHYDRATED] = 0; victim->pcdata->condition[COND_STARVING] = 0; REMOVE_BIT(victim->act,PLR_CRIMINAL); victim->ghost = 20; send_to_char("You have died and turned into an invincible ghost for a few minutes.\n\r",victim); if(cloak==1) location=get_room_index(3808); else if (victim->temple != 0) location = get_room_index(victim->temple); else location = get_room_index(ROOM_VNUM_TEMPLE); if (location == NULL) location = get_room_index(3014); if (ch->in_room != NULL && ch->in_room->vnum == 1212) location = get_room_index(3014); char_from_room(victim); char_to_room(victim,location); init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = skill_lookup("infravision"); af.duration = 20; af.location = 0; af.bitvector = AFF_INFRARED; af.modifier = 0; af.level=victim->level; affect_to_char(victim,&af); if (unholy) { init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SPELL; af.type = skill_lookup("unholy guard"); af.duration = 36; af.location = 0; af.modifier = 0; af.level=victim->level; affect_to_char(victim,&af); } victim->last_fight_name = NULL; (int)victim->last_fight_time = NULL; /* Con loss per 4 deaths. If you don't want this, and particularly perm death by going below 4 con, then remove this code...(Ceran) */ if (!IS_NPC(victim)) { victim->pcdata->death_count++; if ( (victim->pcdata->death_count >= 10) && !IS_IMMORTAL(victim) && !(victim->perm_stat[STAT_CON] < 3)) { victim->perm_stat[STAT_CON] -= 1; victim->pcdata->death_count = 0; send_to_char("With this death you feel your vitality draining away from you.\n\r",victim); } if (victim->perm_stat[STAT_CON] < 5) { send_to_char("The banshee wails as you feel closer to a permanent death.\n\r",victim); } if (victim->perm_stat[STAT_CON] < 3) { SET_BIT(victim->act, PLR_DENY); perm_death_log(victim,2); send_to_char("You gasp your final breaths. Your vitality has faded.\n\r",victim); wiznet("$N dies of constitution loss.",victim,NULL,0,0,get_trust(victim)); stop_fighting(victim,TRUE); victim->pause = 0; save_char_obj(victim); do_quit(victim, ""); } } if(!IS_NPC(ch) && ch->in_room->vnum==ROOM_FORCE_DUEL) { init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_POWER; af.type = gsn_honorable_combat; af.duration = 50; af.location = 0; af.modifier = 0; af.bitvector= 0; af.level=ch->level; affect_to_char(victim,&af); char_from_room(ch); old_room=get_room_index(ch->pcdata->old_room); arena_room=get_room_index(ROOM_FORCE_DUEL); char_to_room(ch,old_room); act("$n arrives in a blaze of white light, having triumphed honorably over $N!\n\r",ch,0,victim,TO_ROOM); for (duelcorpse = arena_room->contents; duelcorpse != NULL; duelcorpse = duelcorpse->next) { if(duelcorpse->in_room==arena_room) { obj_from_room(duelcorpse); obj_to_room(duelcorpse,old_room); } } for (zombie = arena_room->people; zombie != NULL; zombie = zombie->next_in_room) { if (zombie!=NULL && IS_NPC(zombie) && IS_AFFECTED(zombie,AFF_CHARM) && zombie->pIndexData->vnum==MOB_VNUM_ZOMBIE) { char_from_room(zombie); char_to_room(zombie,old_room); } } } do_look(victim,"auto"); return; } void group_gain( CHAR_DATA *ch, CHAR_DATA *victim ) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *gch; CHAR_DATA *lch; int xp; int members; int group_levels; /* * Monsters don't get kill xp's or alignment changes. * P-killing doesn't help either. * Dying of mortal wounds or poison doesn't give xp to anyone! */ if ( victim == ch ) return; if (!IS_NPC(victim)) /* No xp for PKs */ return; members = 0; group_levels = 0; for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room ) { if ( is_same_group( gch, ch ) ) { if(!IS_NPC(gch)) members++; group_levels+=gch->level; if(IS_NPC(gch)) group_levels+=gch->level; } } if ( members == 0 ) { members = 1; } lch = (ch->leader != NULL) ? ch->leader : ch; for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room ) { OBJ_DATA *obj; OBJ_DATA *obj_next; bool owner = FALSE; if ( !is_same_group( gch, ch ) || IS_NPC(gch)) continue; if ( gch->level - lch->level > 8 ) { send_to_char( "You are too high for this group.\n\r", gch ); continue; } if ( gch->level - lch->level < -8 ) { send_to_char( "You are too low for this group.\n\r", gch ); continue; } xp = xp_compute( gch, victim, members, group_levels ); sprintf( buf, "You receive %d experience points.\n\r", xp ); send_to_char( buf, gch ); gain_exp( gch, xp ); for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if ( obj->wear_loc == WEAR_NONE ) continue; if (is_affected(ch,gsn_cloak_form)) { ch->unholy_name = str_dup(ch->original_name); } else { ch->unholy_name = str_dup(ch->name); } if (str_cmp(obj->owner,ch->unholy_name) ) { owner = TRUE; } if ( ( IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch) ) || ( IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch) ) || ( IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch) ) || ( IS_OBJ_STAT(obj, ITEM_ANTI_LAWFUL) && (ch->pcdata->ethos > 0)) || ( IS_OBJ_STAT(obj, ITEM_ANTI_NEUT) && (ch->pcdata->ethos == 0)) || ( IS_OBJ_STAT(obj, ITEM_ANTI_CHAOTIC) && (ch->pcdata->ethos < 0)) || ( IS_WEAPON_STAT(obj,WEAPON_UNHOLY) && (owner))) { act( "You are zapped by $p.", ch, obj, NULL, TO_CHAR ); act( "$n is zapped by $p.", ch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj_to_room( obj, ch->in_room ); } } } return; } /* * Compute xp for a kill. * Also adjust alignment of killer. * Edit this function to change xp computations. */ int xp_compute( CHAR_DATA *gch, CHAR_DATA *victim, int group_amount, int glevel ) { int xp,base_exp; int level_range; double mult; mult=((double)(gch->level)/glevel)*group_amount; if(mult>=1) { mult=(1+mult)/2; } else { mult=mult*mult; } mult = URANGE(.25,mult,1.1); level_range = victim->level - gch->level; /* compute the base exp */ switch (level_range) { default : base_exp = 0; break; case -9 : base_exp = 2; break; case -8 : base_exp = 4; break; case -7 : base_exp = 7; break; case -6 : base_exp = 12; break; case -5 : base_exp = 14; break; case -4 : base_exp = 25; break; case -3 : base_exp = 36; break; case -2 : base_exp = 55; break; case -1 : base_exp = 70; break; case 0 : base_exp = 88; break; case 1 : base_exp = 110; break; case 2 : base_exp = 131; break; case 3 : base_exp = 153; break; case 4 : base_exp = 165; break; } if (level_range > 4) base_exp = 165 + 15 * (level_range - 4); if(mult<1&&level_range>4) base_exp = (2*base_exp+165)/3; if (IS_SET(victim->act,ACT_NOALIGN)) xp = base_exp; else if (gch->alignment > 0) { if (victim->alignment < 0) xp = (base_exp *4)/3; else if (victim->alignment > 0) xp = -30; else xp = base_exp; } else if (gch->alignment < 0) /* for baddies */ { if (victim->alignment > 0) xp = (base_exp * 4)/3; else if (victim->alignment < 0) xp = base_exp/2; else xp = base_exp; } else /* neutral */ { xp = base_exp; } xp = (xp*2)/3; xp=xp*mult; xp = number_range (xp, xp * 5/4); /* adjust for grouping */ if (group_amount == 2) xp = (xp * 5)/3; if (group_amount == 3) xp = (xp * 7)/3; if (group_amount > 3) xp /= (group_amount - 2); return xp; } void dam_message( CHAR_DATA *ch, CHAR_DATA *victim,int dam,int dt,bool immune ) { char buf1[256], buf2[256], buf3[256]; OBJ_DATA *wield; const char *vs; const char *vp; const char *attack; char punct; if (ch == NULL || victim == NULL) return; if ( dam == 0 ) { vs = "{Rmiss{x"; vp = "{Rmisses{x"; } else if ( dam <= 2 ) { vs = "{Rscratch{x"; vp = "{Rscratches{x"; } else if ( dam <= 4 ) { vs = "{Rgraze{x"; vp = "{Rgrazes{x"; } else if ( dam <= 7 ) { vs = "{Rhit{x"; vp = "{Rhits{x"; } else if ( dam <= 11 ) { vs = "{Rinjure{x"; vp = "{Rinjures{x"; } else if ( dam <= 15 ) { vs = "{Rwound{x"; vp = "{Rwounds{x"; } else if ( dam <= 20 ) { vs = "{Rmaul{x"; vp = "{Rmauls{x"; } else if ( dam <= 25 ) { vs = "{Rdecimate{x"; vp = "{Rdecimates{x"; } else if ( dam <= 30 ) { vs = "{Rdevastate{x"; vp = "{Rdevastates{x"; } else if ( dam <= 37 ) { vs = "{Rmaim{x"; vp = "{Rmaims{x"; } else if ( dam <= 45 ) { vs = "{RMUTILATE{x"; vp = "{RMUTILATES{x"; } else if ( dam <= 55 ) { vs = "{REVISCERATE{x"; vp = "{REVISCERATES{x"; } else if ( dam <= 65 ) { vs = "{RDISMEMBER{x"; vp = "{RDISMEMBERS{x"; } else if ( dam <= 85 ) { vs = "{RMASSACRE{x"; vp = "{RMASSACRES{x"; } else if ( dam <= 100 ) { vs = "{RMANGLE{x"; vp = "{RMANGLES{x"; } else if ( dam <= 135 ) { vs = "{R*** DEMOLISH ***{x"; vp = "{R*** DEMOLISHES ***{x"; } else if ( dam <= 160 ) { vs = "{R*** DEVASTATE ***{x"; vp = "{R*** DEVASTATES ***{x"; } else if ( dam <= 250) { vs = "{R=== OBLITERATE ==={x"; vp = "{R=== OBLITERATES ==={x"; } else if ( dam <= 330) { vs = "{R>>> ANNIHILATE <<<{x"; vp = "{R>>> ANNIHILATES <<<{x"; } else if ( dam <= 380) { vs = "{R<<< ERADICATE >>>{x"; vp = "{R<<< ERADICATES >>>{x"; } else { vs = "{Rdo UNSPEAKABLE things to{x"; vp = "{Rdoes UNSPEAKABLE things to{x"; } punct = (dam <= 33) ? '.' : '!'; if (dt == gsn_dual_wield || dt == gsn_tertiary_wield) { if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else wield = get_eq_char(ch,WEAR_TERTIARY_WIELD); dt = TYPE_HIT; if (wield != NULL) dt += wield->value[3]; else dt += ch->dam_type; } if ( dt == TYPE_HIT ) { if (ch == victim) { sprintf( buf1, "$n %s $melf%c",vp,punct); sprintf( buf2, "You %s yourself%c",vs,punct); } else { sprintf (buf1, "$n %s $N%c", vp, punct); sprintf( buf2, "You %s $N%c", vs, punct ); sprintf( buf3, "$n %s you%c", vp, punct ); } } else { if ( dt >= 0 && dt < MAX_SKILL ) attack = skill_table[dt].noun_damage; else if ( dt >= TYPE_HIT && dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[dt - TYPE_HIT].noun; else { bug( "Dam_message: bad dt %d.", dt ); dt = TYPE_HIT; attack = attack_table[0].name; } if (immune) { if (ch == victim) { sprintf(buf1,"$n is unaffected by $s own %s.",attack); sprintf(buf2,"Luckily, you are immune to that."); } else { sprintf(buf1,"$N is unaffected by $n's %s!",attack); sprintf(buf2,"$N is unaffected by your %s!",attack); sprintf(buf3,"$n's %s is powerless against you.",attack); } } else { if (ch == victim) { sprintf( buf1, "$n's %s %s $m%c", attack, vp, punct ); sprintf( buf2, "Your %s %s you%c",attack,vp,punct); } else { sprintf( buf1, "$n's %s %s $N%c", attack, vp, punct ); sprintf( buf2, "Your %s %s $N%c", attack, vp, punct ); sprintf( buf3, "$n's %s %s you%c", attack, vp, punct ); } } } if (ch == victim) { act (buf1, ch, NULL, NULL, TO_ROOM); act(buf2,ch,NULL,NULL,TO_CHAR); } else { act( buf1, ch, NULL, victim, TO_NOTVICT); act( buf2, ch, NULL, victim, TO_CHAR ); act( buf3, ch, NULL, victim, TO_VICT ); } /* Don't stop players entering guilds or quiting for starvation/poison/plague damage */ if (dt != gsn_poison && dt != gsn_plague && dt != gsn_starvation && dt != gsn_dehydrated) { if (!IS_IMMORTAL(ch)) { if (!IS_NPC(victim)) { ch->pause = 10; } else { ch->pause = 1; } } if (!IS_IMMORTAL(victim)) { if (!IS_NPC(ch)) { victim->pause = 10; } else { ch->pause = 1; } } } return; } /* * Disarm a creature. * Caller must check for successful attack. */ void disarm( CHAR_DATA *ch, CHAR_DATA *victim ) { OBJ_DATA *obj; OBJ_DATA *secondary; if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL ) return; if (IS_AFFECTED(ch,AFF_BLIND)) { act("You can't see the person to disarm them!",ch,NULL,victim,TO_CHAR); return; } if (IS_NPC(ch) && (IS_AFFECTED(ch,AFF_BLIND))) return; if ( IS_OBJ_STAT(obj,ITEM_NOREMOVE) || IS_OBJ_STAT(obj,ITEM_NODISARM)) { act("$S weapon won't budge!",ch,NULL,victim,TO_CHAR); act("$n tries to disarm you, but your weapon won't budge!", ch,NULL,victim,TO_VICT); act("$n tries to disarm $N, but fails.",ch,NULL,victim,TO_NOTVICT); return; } act( "$n DISARMS you and sends your weapon flying!", ch, NULL, victim, TO_VICT ); act( "You disarm $N!", ch, NULL, victim, TO_CHAR ); act( "$n disarms $N!", ch, NULL, victim, TO_NOTVICT ); obj_from_char( obj ); if ( IS_OBJ_STAT(obj,ITEM_NODROP) || IS_OBJ_STAT(obj,ITEM_INVENTORY) ) obj_to_char( obj, victim ); else { obj_to_room( obj, victim->in_room ); if (IS_NPC(victim) && victim->wait == 0 && can_see_obj(victim,obj)) get_obj(victim,obj,NULL); } reslot_weapon(victim); if ((secondary = get_eq_char(victim,WEAR_DUAL_WIELD)) != NULL) { unequip_char(victim,secondary); equip_char(victim,secondary,WEAR_WIELD); } return; } void do_berserk( CHAR_DATA *ch, char *argument) { int chance, hp_percent; if ((chance = get_skill(ch,gsn_berserk)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_BERSERK)) || (!IS_NPC(ch) && ch->level < skill_table[gsn_berserk].skill_level[ch->class])) { send_to_char("You turn red in the face, but nothing happens.\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_BERSERK) || is_affected(ch,gsn_berserk) || is_affected(ch,skill_lookup("frenzy"))) { send_to_char("You get a little madder.\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_CALM)) { send_to_char("You're feeling to mellow to berserk.\n\r",ch); return; } if (ch->mana < 50) { send_to_char("You can't get up enough energy.\n\r",ch); return; } /* modifiers */ /* fighting */ if (ch->position == POS_FIGHTING) chance += 10; /* damage -- below 50% of hp helps, above hurts */ if (ch->max_hit == 0) hp_percent = 0; else hp_percent = 100 * ch->hit/ch->max_hit; chance += 25 - hp_percent/2; if (number_percent() < chance) { AFFECT_DATA af; WAIT_STATE(ch,PULSE_VIOLENCE); ch->mana -= 50; ch->move /= 1.2 ; /* heal a little damage */ ch->hit += (ch->drain_level + ch->level) * 2; ch->hit = UMIN(ch->hit,ch->max_hit); send_to_char("Your pulse races as you are consumed by rage!\n\r",ch); act("$n gets a wild look in $s eyes.",ch,NULL,NULL,TO_ROOM); check_improve(ch,gsn_berserk,TRUE,2); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_berserk; af.level = ch->level + ch->drain_level; af.duration = (ch->drain_level + ch->level /2); af.modifier = UMAX(1,(ch->drain_level + ch->level)/5); af.bitvector = AFF_BERSERK; af.aftype = AFT_SKILL; af.location = APPLY_HITROLL; affect_to_char(ch,&af); af.location = APPLY_DAMROLL; affect_to_char(ch,&af); af.modifier = (ch->drain_level + ch->level); af.location = APPLY_AC; affect_to_char(ch,&af); } else { WAIT_STATE(ch,PULSE_VIOLENCE); ch->mana -= 25; send_to_char("Your pulse speeds up, but nothing happens.\n\r",ch); check_improve(ch,gsn_berserk,FALSE,2); } } void do_bash( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int dam; int chance; char buf[MAX_STRING_LENGTH]; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_bash)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_BASH) && !check_rangermob(ch)) || (!IS_NPC(ch) && ch->level < skill_table[gsn_bash].skill_level[ch->class])) { send_to_char("Bashing? What's that?\n\r",ch); return; } if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM) && !check_rangermob(ch)) return; if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim->position < POS_FIGHTING) { act("You'll have to let $M get back up first.",ch,NULL,victim,TO_CHAR); return; } if (victim == ch) { send_to_char("You try to bash your brains out, but fail.\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(victim,gsn_protective_shield)) { act("$N's bash seems to slide around you.",victim,0,ch,TO_CHAR); act("$N's bash seems to slide around $n.",victim,0,ch,TO_NOTVICT); act("Your bash seems to slide around $n.",victim,0,ch,TO_VICT); WAIT_STATE(ch,PULSE_VIOLENCE*.5); return; } if (is_affected(victim,gsn_asscounter)) { act("You deftly sidestep $N's bash, throwing them to the ground.",victim,0,ch,TO_CHAR); act("$n quickly dodges $N's bash, throwing $s down in the process.",victim,0,ch,TO_NOTVICT); act("$n deftly dodges your bash, throwing you to the ground in the process.",victim,0,ch,TO_VICT); WAIT_STATE(ch,2 * PULSE_VIOLENCE); dam = victim->level*2 + number_percent()*2 - 50; damage_old(victim,ch,dam,gsn_throw,DAM_BASH,TRUE); affect_strip( victim, gsn_asscounter ); return; } if (is_affected(victim,gsn_wraithform)) { act("$N's tries to bash you but stumbles through thin air.",victim,0,ch,TO_CHAR); act("$N's tries to bash $n but stumbles through thin air.",victim,0,ch,TO_NOTVICT); act("You stumble as you try to bash $n but stumble through thin air.",victim,0,ch,TO_VICT); WAIT_STATE(ch,PULSE_VIOLENCE*1); return; } if(is_affected(ch,gsn_shadowstrike)) { send_to_char("The shadowy arms restrict you.\n\r",ch); act("$N's tries to bash, but is restrained by shadowy arms!",ch,NULL,NULL,TO_ROOM); WAIT_STATE(ch,20); return; } /* modifiers */ /* size and weight */ chance += ch->carry_weight / 250; chance -= victim->carry_weight / 200; if (ch->size < victim->size) chance += (ch->size - victim->size) * 20; else chance += (ch->size - victim->size) * 10; /* stats */ chance += get_curr_stat(ch,STAT_STR); chance -= (get_curr_stat(victim,STAT_DEX) * 4)/3; chance -= GET_AC(victim,AC_BASH) /25; /* speed */ if (IS_SET(ch->off_flags,OFF_FAST) || is_affected(ch,skill_lookup("haste"))) chance += 10; if (IS_SET(victim->off_flags,OFF_FAST) || is_affected(victim,skill_lookup("haste"))) chance -= 40; /* level */ chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL)) { sprintf(buf,"Help! %s is bashing me!",PERS(ch,victim)); do_myell(victim,buf); } if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) ) { /* act("$n tries to bash you, but you dodge it.",ch,NULL,victim,TO_VICT); act("$N dodges your bash, you fall flat on your face.",ch,NULL,victim,TO_CHAR); WAIT_STATE(ch,PULSE_VIOLENCE*1.5); return;*/ chance -= 3 * (get_skill(victim,gsn_dodge) - chance); } /* now the attack */ if (number_percent() < chance ) { act("$n sends you sprawling with a powerful bash!", ch,NULL,victim,TO_VICT); act("You slam into $N, and send $M flying!",ch,NULL,victim,TO_CHAR); act("$n sends $N sprawling with a powerful bash.", ch,NULL,victim,TO_NOTVICT); check_improve(ch,gsn_bash,TRUE,1); WAIT_STATE(victim, 2 * PULSE_VIOLENCE); damage_old(ch,victim,number_range(2,2 + 2 * ch->size + chance/20),gsn_bash, DAM_BASH,TRUE); WAIT_STATE(ch,skill_table[gsn_bash].beats); victim->position = POS_RESTING; if (!IS_NPC(ch) && (ch->class == CLASS_WARRIOR) && (number_percent() < ch->level)) ch->pcdata->sp++; } else { damage_old(ch,victim,0,gsn_bash,DAM_BASH,FALSE); act("You fall flat on your face!", ch,NULL,victim,TO_CHAR); act("$n falls flat on $s face.", ch,NULL,victim,TO_NOTVICT); act("You evade $n's bash, causing $m to fall flat on $s face.", ch,NULL,victim,TO_VICT); check_cheap_shot(victim,ch); check_improve(ch,gsn_bash,FALSE,1); ch->position = POS_RESTING; WAIT_STATE(ch,skill_table[gsn_bash].beats); } check_killer(ch,victim); } void do_dirt( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance; char buf[MAX_STRING_LENGTH]; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_dirt)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_KICK_DIRT) && ch->pIndexData->vnum!=MOB_VNUM_TEMPLAR) || (!IS_NPC(ch) && ch->level < skill_table[gsn_dirt].skill_level[ch->class])) { send_to_char("You get your feet dirty.\n\r",ch); return; } if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't in combat!\n\r",ch); return; } } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (IS_AFFECTED(victim,AFF_BLIND)) { act("$E's already been blinded.",ch,NULL,victim,TO_CHAR); return; } if(victim->position==POS_SLEEPING) { send_to_char("Their eyes are closed.\n\r",ch); return; } if (victim == ch) { send_to_char("Very funny.\n\r",ch); return; } if (is_safe(ch,victim)) return; if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim) { act("But $N is such a good friend!",ch,NULL,victim,TO_CHAR); return; } if (is_affected(victim, gsn_shield_of_dust)) { act("Your dirt is blocked by $N's shield of dust!",ch,NULL,victim,TO_CHAR); act("$n kicks dirt at you but it is stoped by your shield of dust!", ch,NULL,victim,TO_VICT); act("$n's dirt is deflected by $N's shield of dust!",ch,NULL,victim,TO_NOTVICT); return; } /* modifiers */ /* dexterity */ chance += get_curr_stat(ch,STAT_DEX); chance -= 2 * get_curr_stat(victim,STAT_DEX); /* speed */ if (IS_SET(ch->off_flags,OFF_FAST) || is_affected(ch,skill_lookup("haste"))) chance += 10; if (IS_SET(victim->off_flags,OFF_FAST) || is_affected(victim,skill_lookup("haste"))) chance -= 30; /* level */ chance += (ch->drain_level + ch->level - victim->level - victim->drain_level) * 2; /* sloppy hack to prevent false zeroes */ if (chance % 5 == 0) chance += 1; /* terrain */ switch(ch->in_room->sector_type) { case(SECT_INSIDE): chance -= 20; break; case(SECT_CITY): chance -= 10; break; case(SECT_FIELD): chance += 5; break; case(SECT_FOREST): break; case(SECT_HILLS): break; case(SECT_MOUNTAIN): chance -= 10; break; case(SECT_WATER_SWIM): chance = 0; break; case(SECT_WATER_NOSWIM): chance = 0; break; case(SECT_AIR): chance = 0; break; case(SECT_DESERT): chance += 10; break; } if (chance == 0) { send_to_char("There isn't any dirt to kick.\n\r",ch); return; } /* now the attack */ if (number_percent() < chance) { AFFECT_DATA af; act("$n is blinded by the dirt in $s eyes!",victim,NULL,NULL,TO_ROOM); act("$n kicks dirt in your eyes!",ch,NULL,victim,TO_VICT); if (!IS_NPC(ch) && !IS_NPC(victim) && ( (victim->fighting == NULL) || (ch->fighting == NULL))) do_myell(victim,"Help! Someone just kicked dirt in my eyes!"); damage(ch,victim,number_range(2,5),gsn_dirt,DAM_NONE,TRUE); send_to_char("You can't see a thing!\n\r",victim); check_improve(ch,gsn_dirt,TRUE,2); WAIT_STATE(ch,skill_table[gsn_dirt].beats); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_dirt; af.aftype = AFT_MALADY; af.level = ch->level + ch->drain_level; af.duration = 0; af.location = APPLY_HITROLL; af.modifier = -4; af.bitvector = AFF_BLIND; affect_to_char(victim,&af); } else { /* PK yells....add these to most attacks that can initiate PKs. -Ceran */ if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL)) { switch(number_range(0,1)) { case (0): sprintf(buf,"Help! %s just tried to kick dirt in my eyes!",PERS(ch,victim)); break; case (1): sprintf(buf,"Die, %s you dirty fool!",PERS(ch,victim)); break; } do_myell(victim,buf); } damage(ch,victim,0,gsn_dirt,DAM_NONE,TRUE); check_improve(ch,gsn_dirt,FALSE,2); WAIT_STATE(ch,skill_table[gsn_dirt].beats); } check_killer(ch,victim); } void do_trip( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance; int dam; AFFECT_DATA af; char buf[MAX_STRING_LENGTH]; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_trip)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TRIP) && ch->pIndexData->vnum!=MOB_VNUM_TEMPLAR) || (!IS_NPC(ch) && ch->level < skill_table[gsn_trip].skill_level[ch->class])) { send_to_char("Tripping? What's that?\n\r",ch); return; } if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (is_safe(ch,victim)) return; if (IS_AFFECTED(victim,AFF_FLYING) && !is_affected(victim,gsn_earthbind)) { act("$S feet aren't on the ground.",ch,NULL,victim,TO_CHAR); return; } if (victim->position < POS_FIGHTING) { act("$N is already down.",ch,NULL,victim,TO_CHAR); return; } if (victim == ch) { send_to_char("You fall flat on your face!\n\r",ch); WAIT_STATE(ch,2 * skill_table[gsn_trip].beats); act("$n trips over $s own feet!",ch,NULL,NULL,TO_ROOM); return; } if (is_affected(victim,gsn_asscounter)) { act("You dart to the side kicking the inside of $N's knee!",victim,0,ch,TO_CHAR); act("$n darts to the side kicking the inside of $N's knee!",victim,0,ch,TO_NOTVICT); act("$n dodges your trip, then kicks the inside of your knee!",victim,0,ch,TO_VICT); WAIT_STATE(victim,1 * PULSE_VIOLENCE); dam = victim->level*2 + number_percent()*2 - 50; damage_old(victim,ch,dam,gsn_legbreak,DAM_BASH,TRUE); if (!is_affected(ch,gsn_legbreak)) { init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_MALADY; af.type = gsn_legbreak; af.level = victim->level; af.duration = victim->level/5; af.bitvector = 0; af.location = APPLY_DEX; af.modifier = 1-(victim->level/5); affect_to_char(ch,&af); } affect_strip( victim, gsn_asscounter ); return; } if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim) { act("$N is your beloved master.",ch,NULL,victim,TO_CHAR); return; } /* modifiers */ /* size */ if (ch->size < victim->size) chance += (ch->size - victim->size) * 10; /* bigger = harder to trip */ /* dex */ chance += get_curr_stat(ch,STAT_DEX); chance -= get_curr_stat(victim,STAT_DEX) * 3 / 2; /* speed */ if (IS_SET(ch->off_flags,OFF_FAST) || is_affected(ch,skill_lookup("haste"))) chance += 10; if (IS_SET(victim->off_flags,OFF_FAST) || is_affected(victim,skill_lookup("haste"))) chance -= 40; if(is_affected(victim,gsn_cloak_form)) chance+=10; /* level */ chance += (ch->drain_level + ch->level - victim->level - victim->drain_level) * 2; /* now the attack */ if (number_percent() < chance) { act("$n trips you and you go down!",ch,NULL,victim,TO_VICT); act("You trip $N and $N goes down!",ch,NULL,victim,TO_CHAR); act("$n trips $N, sending $M to the ground.",ch,NULL,victim,TO_NOTVICT); check_improve(ch,gsn_trip,TRUE,1); if (!IS_NPC(ch) && !IS_NPC(victim) && (ch->fighting == NULL || victim->fighting == NULL)) { sprintf(buf,"Help! %s just tripped me!",PERS(ch,victim)); do_myell(victim,buf); } WAIT_STATE(victim,2 * PULSE_VIOLENCE); WAIT_STATE(ch,skill_table[gsn_trip].beats); victim->position = POS_RESTING; damage(ch,victim,number_range(2, 2 + 2 * victim->size),gsn_trip, DAM_BASH,TRUE); check_downstrike(ch,victim); check_cheap_shot(ch,victim); } else { if (!IS_NPC(ch) && !IS_NPC(victim) && (ch->fighting == NULL || victim->fighting == NULL)) { sprintf(buf,"Help! %s just tried to trip me!",PERS(ch,victim)); do_myell(victim,buf); } damage(ch,victim,0,gsn_trip,DAM_BASH,TRUE); WAIT_STATE(ch,skill_table[gsn_trip].beats*2/3); check_improve(ch,gsn_trip,FALSE,1); } check_killer(ch,victim); } void do_steel_nerves(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_steel_nerves)) == 0 || (ch->level < skill_table[gsn_steel_nerves].skill_level[ch->class])) { send_to_char("Huh?\n\r",ch); return; } if (is_affected(ch,gsn_steel_nerves)) { send_to_char("You feel as invincible as you will ever feel.\n\r",ch); return; } if (ch->mana < 100) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > ch->pcdata->learned[gsn_steel_nerves]) { ch->mana -= 50; send_to_char("You try to make yourself feel invincible, but fail.\n\r",ch); return; } init_affect(&af); af.where = TO_AFFECTS; af.duration = 3 + (ch->level)/10; af.location = 0; af.modifier = 0; af.level = ch->level + ch->drain_level; af.type = gsn_steel_nerves; af.aftype = AFT_POWER; af.bitvector = AFF_DETECT_INVIS; affect_to_char(ch,&af); af.bitvector = AFF_DETECT_MAGIC; affect_to_char(ch,&af); send_to_char("You build up an intense mental resolve and prepare for coming battles.\n\r",ch); act("$n seems to glower and look deadly.",ch,NULL,NULL,TO_ROOM); send_to_char("Your eyes tingle.\n\r",ch); send_to_char("You are more sensitive to the prescence of magical auras.\n\r",ch); ch->mana -= 100; return; } void do_battlecry( CHAR_DATA *ch, char *argument) { AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_battlecry)) == 0 || (ch->level < skill_table[gsn_battlecry].skill_level[ch->class])) { send_to_char("Huh?\n\r",ch); return; } if (cabal_down(ch,CABAL_RAVAGER)) return; if (is_affected(ch,gsn_battlecry)) { send_to_char("You are already as angry as you can be.\n\r",ch); return; } if (ch->mana < 40) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > ch->pcdata->learned[gsn_battlecry]) { send_to_char("You build up your rage but it dies down too fast.\n\r",ch); ch->mana -= 20; return; } ch->mana -= 40; init_affect(&af); af.where = TO_AFFECTS; af.level = ch->level + ch->drain_level; af.duration = (ch->drain_level + ch->level)/2; af.type = gsn_battlecry; af.modifier = 3; af.location = APPLY_HITROLL; af.bitvector = 0; af.aftype = AFT_POWER; affect_to_char(ch,&af); send_to_char("You are filled with total fury as you let out a battlecry!\n\r",ch); act("$n lets out a chilling battlecry and begins frothing at the mouth.",ch,NULL,NULL,TO_ROOM); return; } void do_hit( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; one_argument( argument, arg ); if ( ch->position != POS_FIGHTING ) { send_to_char( "You're not fighting anyone.\n\r", ch ); return; } if ( arg[0] == '\0' ) { send_to_char( "Switch targets to whom?\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char( "Are you crazy?\n\r", ch ); return; } if ( victim->fighting != ch ) { send_to_char( "That person isn't fighting you.\n\r", ch ); return; } ch->fighting = victim; return; } void do_kill( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Kill whom?\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } /* Allow player killing */ if ( !IS_NPC(victim) ) { send_to_char( "You must MURDER a player.\n\r", ch ); return; } if ( victim == ch ) { send_to_char( "You hit yourself. Ouch!\n\r", ch ); multi_hit( ch, ch, TYPE_UNDEFINED ); return; } if ( is_safe( ch, victim ) ) return; if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim ) { act( "$N is your beloved master.", ch, NULL, victim, TO_CHAR ); return; } if ( ch->position == POS_FIGHTING ) { send_to_char( "You do the best you can!\n\r", ch ); return; } WAIT_STATE( ch, 1 * PULSE_VIOLENCE ); multi_hit( ch, victim, TYPE_UNDEFINED ); return; } void do_murde( CHAR_DATA *ch, char *argument ) { send_to_char( "If you want to MURDER, spell it out.\n\r", ch ); return; } void do_murder( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Murder whom?\n\r", ch ); return; } if ((IS_AFFECTED(ch,AFF_CHARM) || (IS_NPC(ch) && IS_SET(ch->act,ACT_PET))) && !is_centurion(ch) && !check_rangermob(ch)) return; if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char( "Suicide is a mortal sin.\n\r", ch ); return; } if ( is_safe( ch, victim ) ) return; if (check_chargeset(ch,victim)) {return;} if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim ) { act( "$N is your beloved master.", ch, NULL, victim, TO_CHAR ); return; } if ( ch->position == POS_FIGHTING ) { send_to_char( "You do the best you can!\n\r", ch ); return; } WAIT_STATE( ch, 1 * PULSE_VIOLENCE ); if (IS_NPC(ch)) sprintf(buf, "Help! I am being attacked by %s!",ch->short_descr); else { switch(number_range(1,6)) { default: sprintf(buf, "Help! I am being attacked by %s!",PERS(ch,victim)); break; case (1): sprintf(buf, "Help! I am being attacked by %s!",PERS(ch,victim)); break; case (2): sprintf(buf, "Die %s, you dirty fool!", PERS(ch,victim)); break; case (3): case (4): sprintf(buf, "Help! %s is attacking me!", PERS(ch,victim)); break; case (5): sprintf(buf, "How dare you attack me %s!", PERS(ch,victim)); break; case (6): sprintf(buf, "Help! %s is hurting me!", PERS(ch,victim)); break; } } /* Added a myell hack of yell so Enforcer cabal members can see if a PK yell is faked or not (see myell in act_comm.c for this). -Ceran */ do_myell( victim, buf ); multi_hit( ch, victim, TYPE_UNDEFINED ); return; } void do_ambush( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; char buf[MAX_STRING_LENGTH]; int chance; one_argument( argument, arg); if (arg[0] == '\0') { send_to_char("Ambush whom?\n\r",ch); return; } if (ch->fighting != NULL) { send_to_char("But you're still fighting!\n\r",ch); return; } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } else if (!IS_AFFECTED(ch, AFF_CAMOUFLAGE) || can_see(victim, ch) ) { send_to_char("But they can still see you.\n\r",ch); return; } if ( victim == ch ) { send_to_char("That's just not possible.\n\r",ch); return; } if ( is_safe( ch, victim ) ) return; if (check_chargeset(ch,victim)) {return;} chance = get_skill(ch,gsn_moving_ambush); if (victim->fighting != NULL && ( chance < 3 || ch->level < skill_table[gsn_moving_ambush].skill_level[ch->class])) { send_to_char("They are moving around too much to ambush.\n\r",ch); return; } if (victim->fighting != NULL && number_percent() >= chance) { send_to_char("You can't quite pin them down for your ambush.\n\r",ch); return; } if (!IS_NPC(ch) && !IS_NPC(victim) && victim->fighting == NULL) { sprintf(buf,"Help! I've been ambushed by %s!",PERS(ch,victim)); do_myell(victim,buf); } WAIT_STATE( ch, skill_table[gsn_ambush].beats ); if ( (number_percent( ) < get_skill(ch, gsn_ambush) ) || ( get_skill(ch,gsn_ambush) >= 2 && !IS_AWAKE(victim) ) ) { check_improve(ch,gsn_ambush, TRUE,1); multi_hit( ch, victim, gsn_ambush ); } else { check_improve(ch,gsn_ambush, FALSE,1); damage( ch, victim, 0, gsn_ambush, DAM_NONE, TRUE); } return; } void do_backstab( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; int dam; char buf[MAX_STRING_LENGTH]; one_argument( argument, arg ); if ( (get_skill(ch,gsn_backstab) == 0 ) || ch->level < skill_table[gsn_backstab].skill_level[ch->class]) { if (!IS_NPC(ch)) { send_to_char("You don't know how to backstab.\n\r",ch); return; } } if (arg[0] == '\0') { send_to_char("Backstab whom?\n\r",ch); return; } if (ch->fighting != NULL) { send_to_char("You're facing the wrong end.\n\r",ch); return; } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if ( victim == ch ) { send_to_char( "How can you sneak up on yourself?\n\r", ch ); return; } obj= get_eq_char(ch,WEAR_WIELD); if (obj == NULL) { send_to_char("You must be wielding a weapon to backstab.\n\r",ch); return; } if (obj->value[0] != WEAPON_DAGGER) { obj = get_eq_char(ch,WEAR_DUAL_WIELD); if (obj == NULL) { send_to_char("You must be wielding a weapon to backstab.\n\r",ch); return; } } if (obj->value[0] != WEAPON_DAGGER) { send_to_char("You need to be wielding a dagger to backstab.\n\r",ch); return; } if ( is_safe(ch, victim ) ) return; if (check_chargeset(ch,victim)) {return;} if ( victim->fighting != NULL ) { send_to_char( "That person is moving around too much to backstab.\n\r", ch ); return; } if (victim->hit < victim->max_hit*5/10) { act( "$N is hurt and suspicious ... you can't sneak up.", ch, NULL, victim, TO_CHAR ); return; } WAIT_STATE( ch, skill_table[gsn_backstab].beats ); if ( number_percent( ) < get_skill(ch,gsn_backstab) || ( get_skill(ch,gsn_backstab) >= 2 && !IS_AWAKE(victim) ) ) { check_improve(ch,gsn_backstab,TRUE,1); if (!IS_NPC(ch) && !IS_NPC(victim) && victim->fighting == NULL) { switch(number_range(0,1)) { case (0): sprintf(buf,"Die, %s you backstabbing fool!",PERS(ch,victim)); break; case (1): sprintf(buf,"Help! I'm being backstabbed by %s!",PERS(ch,victim)); break; } do_myell(victim,buf); } one_hit( ch, victim, gsn_backstab ); } else { check_improve(ch,gsn_backstab,FALSE,1); if (!IS_NPC(ch) && !IS_NPC(victim) && victim->fighting == NULL) { switch(number_range(0,1)) { case (0): sprintf(buf,"Die, %s you backstabbing fool!",PERS(ch,victim)); break; case (1): sprintf(buf,"Help! I'm being backstabbed by %s!",PERS(ch,victim)); break; } do_myell(victim,buf); } damage( ch, victim, 0, gsn_backstab,DAM_NONE,TRUE); } if (ch->level < skill_table[gsn_dual_backstab].skill_level[ch->class]) return; if (number_range(0,3) == 0) { if (get_skill(ch,gsn_dual_backstab) != 100) check_improve(ch,gsn_dual_backstab,FALSE,1); return; } if (number_percent() > (get_skill(ch,gsn_dual_backstab) + ch->level - victim->level) ) { check_improve(ch,gsn_dual_backstab,FALSE,1); dam = 0; } else { dam = dice(obj->value[1], obj->value[2]) * get_skill(ch,gsn_dual_backstab)/100; if ((ch->drain_level + ch->level) < 35) dam *= number_range(2,4); else if ((ch->drain_level + ch->level) < 40) dam *= number_range(2,5); else if ((ch->drain_level + ch->level) < 45) dam *= number_range(3,5); else if ((ch->drain_level + ch->level) < 50) dam *= number_range(10,25); /* 4,6 */ else dam *= number_range(15,30); /* 4,7 */ dam += (ch->damroll * get_skill(ch,gsn_dual_backstab)/100); } dam *= battlecry_multiplier(ch,gsn_dual_backstab); damage_old(ch,victim,dam,gsn_dual_backstab,DAM_NONE,TRUE); dam *= battlecry_multiplier(ch,gsn_dual_backstab); damage_old(ch,victim,dam,gsn_dual_backstab,DAM_NONE,TRUE); return; } void do_rescue( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; CHAR_DATA *fch; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Rescue whom?\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char( "What about fleeing instead?\n\r", ch ); return; } if ( !IS_NPC(ch) && IS_NPC(victim) ) { send_to_char( "Doesn't need your help!\n\r", ch ); return; } if ( ( fch = victim->fighting ) == NULL ) { send_to_char( "That person is not fighting right now.\n\r", ch ); return; } if (is_safe(ch,victim->fighting)) return; WAIT_STATE( ch, skill_table[gsn_rescue].beats ); if ( number_percent( ) > get_skill(ch,gsn_rescue)) { send_to_char( "You fail the rescue.\n\r", ch ); check_improve(ch,gsn_rescue,FALSE,1); return; } WAIT_STATE(victim,12); act( "You rescue $N!", ch, NULL, victim, TO_CHAR ); act( "$n rescues you!", ch, NULL, victim, TO_VICT ); act( "$n rescues $N!", ch, NULL, victim, TO_NOTVICT ); check_improve(ch,gsn_rescue,TRUE,1); stop_fighting( fch, FALSE ); stop_fighting( victim, FALSE ); set_fighting( ch, fch ); set_fighting( fch, ch ); return; } void do_kick( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; int dam; if ( !IS_NPC(ch) && ch->level < skill_table[gsn_kick].skill_level[ch->class] ) { send_to_char( "You better leave the martial arts to fighters.\n\r", ch ); return; } if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_KICK)) return; if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } WAIT_STATE( ch, skill_table[gsn_kick].beats ); if ( get_skill(ch,gsn_kick) > number_percent()) { dam = (ch->drain_level + ch->level)/2; dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(0,(ch->drain_level + ch->level)/6); dam += number_range(ch->level/5,ch->level/4); if (!IS_NPC(ch)) { if (!str_cmp(class_table[ch->class].name,"transmuter")) if (!str_cmp(class_table[ch->class].name,"necromancer")) if (!str_cmp(class_table[ch->class].name,"elementalist")) { dam *= 3; dam /= 4; } } damage(ch,victim,dam, gsn_kick,DAM_BASH,TRUE); check_improve(ch,gsn_kick,TRUE,1); check_follow_through(ch,victim,dam); } else { damage( ch, victim, 0, gsn_kick,DAM_BASH,TRUE); check_improve(ch,gsn_kick,FALSE,1); } check_killer(ch,victim); return; } void do_disarm( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim=0; OBJ_DATA *obj; int dam; AFFECT_DATA af; int chance,hth,ch_weapon,vict_weapon,ch_vict_weapon; hth = 0; if ((chance = get_skill(ch,gsn_disarm)) == 0) { send_to_char( "You don't know how to disarm opponents.\n\r", ch ); return; } if ( get_eq_char( ch, WEAR_WIELD ) == NULL && ((hth = get_skill(ch,gsn_hand_to_hand)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_DISARM) && !check_rangermob(ch)))) { send_to_char( "You must wield a weapon to disarm.\n\r", ch ); return; } if (IS_AFFECTED(ch,AFF_BLIND)) { act("You can't see the person to disarm them!",ch,NULL,victim,TO_CHAR); return; } if (IS_NPC(ch) && (IS_AFFECTED(ch,AFF_BLIND))) return; if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } if (is_affected(victim,gsn_asscounter)) { act("With blinding speed you hit $N's arm, breaking it!",victim,0,ch,TO_CHAR); act("With blinding speed $n hits $N's arm, breaking it!",victim,0,ch,TO_NOTVICT); act("With blinding speed $n hits your arm, breaking it instantly!",victim,0,ch,TO_VICT); WAIT_STATE(victim,2 * PULSE_VIOLENCE); dam = victim->level*2 + number_percent()*2 - 50; damage_old(victim,ch,dam,gsn_armbreak,DAM_BASH,TRUE); if (!is_affected(ch,gsn_armbreak)) { init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_armbreak; af.aftype = AFT_MALADY; af.level = victim->level; af.duration = victim->level/5; af.bitvector = 0; af.location = APPLY_DEX; af.modifier = 1-(victim->level/5); affect_to_char(ch,&af); af.location = APPLY_STR; af.modifier = 1-(victim->level/5); af.bitvector = 0; affect_to_char(ch,&af); } affect_strip( victim, gsn_asscounter ); return; } if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL ) { send_to_char( "Your opponent is not wielding a weapon.\n\r", ch ); return; } if (is_affected(victim,gsn_spiderhands) ) { act("You try to disarm $N, but $s hands stick to his weapon.", ch,NULL,victim,TO_CHAR); act("$n tries to disarm you, but your hands stick to your weapon.", ch,NULL,victim,TO_VICT); act("$n tries to disarm $N, but their hands stick to their weapon.", ch,NULL,victim,TO_NOTVICT); return; } /* find weapon skills */ ch_weapon = get_weapon_skill(ch,get_weapon_sn(ch)); vict_weapon = get_weapon_skill(victim,get_weapon_sn(victim)); ch_vict_weapon = get_weapon_skill(ch,get_weapon_sn(victim)); /* modifiers */ chance *= 6; chance /=10; /* skill */ if ( get_eq_char(ch,WEAR_WIELD) == NULL) chance = chance * hth/150; else chance = chance * ch_weapon/100; chance += (ch_vict_weapon/2 - vict_weapon) / 2; /* dex vs. strength */ chance += get_curr_stat(ch,STAT_DEX); chance -= 2 * get_curr_stat(victim,STAT_STR); /* level */ chance += (ch->drain_level + ch->level - victim->drain_level - victim->level) * 2; /* and now the attack */ if (number_percent() < chance) { WAIT_STATE( ch, skill_table[gsn_disarm].beats ); disarm( ch, victim ); check_improve(ch,gsn_disarm,TRUE,1); } else { WAIT_STATE(ch,skill_table[gsn_disarm].beats); act("You fail to disarm $N.",ch,NULL,victim,TO_CHAR); act("$n tries to disarm you, but fails.",ch,NULL,victim,TO_VICT); act("$n tries to disarm $N, but fails.",ch,NULL,victim,TO_NOTVICT); check_improve(ch,gsn_disarm,FALSE,1); } check_killer(ch,victim); return; } void do_circle_stab( CHAR_DATA *ch, char *argument ) { bool attempt_dual; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; CHAR_DATA *v_check; CHAR_DATA *v_next; OBJ_DATA *obj; int chance; int dam; attempt_dual = FALSE; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_circle)) == 0 || IS_NPC(ch) || (!IS_NPC(ch) && ch->level < skill_table[gsn_circle].skill_level[ch->class]) ) { send_to_char("Circling? What's that?\n\r",ch); return; } if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (ch->fighting == NULL) { send_to_char("You can't circle someone like that.\n\r",ch); return; } for (v_check = ch->in_room->people; v_check != NULL; v_check = v_next) { v_next = v_check->next_in_room; if (v_check->fighting == ch) { send_to_char("Not while you're defending yourself!\n\r",ch); return; } } if (victim == ch) { send_to_char("huh?\n\r", ch); return; } obj = get_eq_char(ch,WEAR_WIELD); if (obj == NULL || obj->value[0] != WEAPON_DAGGER) { attempt_dual = TRUE; obj = get_eq_char(ch,WEAR_DUAL_WIELD); } if (obj == NULL) { send_to_char("You must wield a dagger to circle stab.\n\r",ch); return; } if (obj->value[0] != 2) { send_to_char("You must wield a dagger to circle stab.\n\r",ch); return; } chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); chance = URANGE(5, chance, 95); WAIT_STATE(ch,skill_table[gsn_circle].beats); if (number_percent() < chance) { act("You circle around $N to land a critical strike.",ch,NULL,victim,TO_CHAR); act("$n cirlces around you to land a critical strike.",ch,NULL,victim,TO_VICT); act("$n circles $N to land a critical strike.",ch,NULL,victim,TO_NOTVICT); check_improve(ch,gsn_circle,TRUE,1); dam = dice(obj->value[1],obj->value[2]); dam += 40; if ((ch->drain_level + ch->level) <= 15) dam *= 1; else if ((ch->drain_level + ch->level) <= 20) dam *= 3/2; else if ((ch->drain_level + ch->level) < 25) dam *= 2; else if ((ch->drain_level + ch->level) < 30) dam *= 7/3; else if ((ch->drain_level + ch->level) < 40) dam *= 5/2; else if ((ch->drain_level + ch->level) <= 49) dam *= 7/2; else if ((ch->drain_level + ch->level) <= 55) dam *= 10/3; else dam *= 10/3; dam *= battlecry_multiplier(ch,gsn_circle); damage_old(ch,victim,dam,gsn_circle, attack_table[obj->value[3]].damage, TRUE); } else { check_improve(ch,gsn_circle,FALSE,1); damage_old(ch,victim,0,gsn_circle,DAM_NONE,TRUE); } return; } void do_surrender( CHAR_DATA *ch, char *argument ) { CHAR_DATA *mob; if ( (mob = ch->fighting) == NULL ) { send_to_char( "But you're not fighting!\n\r", ch ); return; } act( "You surrender to $N!", ch, NULL, mob, TO_CHAR ); act( "$n surrenders to you!", ch, NULL, mob, TO_VICT ); act( "$n tries to surrender to $N!", ch, NULL, mob, TO_NOTVICT ); stop_fighting( ch, TRUE ); if ( !IS_NPC( ch ) && IS_NPC( mob ) && ( !HAS_TRIGGER( mob, TRIG_SURR ) || !mp_percent_trigger( mob, ch, NULL, NULL, TRIG_SURR ) ) ) { act( "$N seems to ignore your cowardly act!", ch, NULL, mob, TO_CHAR ); multi_hit( mob, ch, TYPE_UNDEFINED ); } } void do_sla( CHAR_DATA *ch, char *argument ) { send_to_char( "If you want to SLAY, spell it out.\n\r", ch ); return; } void do_slay( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Slay whom?\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( ch == victim ) { send_to_char( "Suicide is a mortal sin.\n\r", ch ); return; } if ( !IS_NPC(victim) && victim->level >= get_trust(ch)) { send_to_char( "You failed.\n\r", ch ); return; if (IS_NPC(ch) && (ch->pIndexData->vnum != MOB_VNUM_PROTECTOR) && (ch->pIndexData->vnum != MOB_VNUM_ACADIAN) && (ch->pIndexData->vnum != MOB_VNUM_COVEN) && (ch->pIndexData->vnum != MOB_VNUM_BRIAR) && (ch->pIndexData->vnum != MOB_VNUM_RAVAGER) && (ch->pIndexData->vnum != MOB_VNUM_VIGILANTE) ) { send_to_char( "You failed.\n\r", ch ); return; } } act( "You point at $M and $S heart stops!", ch, NULL, victim, TO_CHAR ); act( "$n points at you and your heart suddenly stops!", ch, NULL, victim, TO_VICT ); act( "$n points at $N and $E falls over clenching his chest!", ch, NULL, victim, TO_NOTVICT ); raw_kill(ch, victim ); return; } void spell_evil_eye(int sn,int level, CHAR_DATA *ch,void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam, modify, saves; if (victim == ch) { send_to_char("You can't do such a thing.\n\r",ch); return; } act("$n's eyes turn pitch-black and a surging darkness erupts at $N.",ch,NULL,victim,TO_NOTVICT); act("Your eyes turn pitch-black and a stream of pure negative energy streams out at $N.",ch,NULL,victim,TO_CHAR); send_to_char("You feel a sudden intense agony burning into your skull.\n\r",victim); if (IS_SET(victim->affected_by,AFF_BLIND) ) { dam = dice(level,8); if (saves_spell(level,victim, DAM_NEGATIVE) ) dam /= 2; damage_old(ch,victim,dam,sn,DAM_NEGATIVE, TRUE); return; } saves = 1; for (modify = 0; modify < 4; modify ++) { if (saves_spell(level, victim, DAM_NEGATIVE)) saves++; } if (saves == 0) { act("$n's surging darkness devestates $N's skull, killing $M instantly!",ch,NULL,victim,TO_NOTVICT); act("Your darkness slays $N!",ch,NULL,victim,TO_CHAR); send_to_char("With a violent burning sensation your mind vaporises.\n\r",victim); raw_kill(ch,victim); return; } dam = dice(level, 16); dam /= (saves + 1); damage_old(ch,victim,dam,sn,DAM_NEGATIVE,TRUE); return; } void spell_power_word_kill(int sn,int level,CHAR_DATA *ch,void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam,saves,modify; saves = 0; act("$n points a finger at $N and utters the word, 'Die'.",ch,NULL,victim,TO_NOTVICT); act("$n points a finger at you and utters the word, 'Die'.",ch,NULL,victim,TO_VICT); send_to_char("You intone a word of unholy power.\n\r",ch); for ( modify = 0; modify < 5; modify++) { if (saves_spell(level-1,victim,DAM_NEGATIVE) ) saves++; } if(IS_IMMORTAL(ch) && (victim->level<ch->level)) { saves=0; } if (saves == 0) { act("$N shudders in shock as $S heart explodes!", ch, NULL,victim,TO_NOTVICT); send_to_char("You feel your heart rupture in a vilent explosion of pain!\n\r",victim); act("Your word of power vaporises $N's heart, killing $M instantly!",ch,NULL,victim,TO_CHAR); raw_kill(ch,victim); return; } dam = dice(level,14); dam /= saves; damage_old(ch,victim,dam,sn,DAM_NEGATIVE,TRUE); return; } void do_lunge( CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int chance, dam; char arg[MAX_INPUT_LENGTH]; OBJ_DATA *wield; int multiplier; dam = 0; one_argument(argument,arg); if ((chance = get_skill(ch,gsn_lunge) ) == 0 || (ch->level < skill_table[gsn_lunge].skill_level[ch->class]) ) { send_to_char("Lunging? What's that?\n\r",ch); return; } if (arg[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,arg)) == NULL ) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't lunge at yourself!\n\r",ch); return; } wield = get_eq_char(ch,WEAR_WIELD); if ((wield == NULL) || (( wield->value[0] != WEAPON_SWORD) && ( wield->value[0] != WEAPON_SPEAR) && ( wield->value[0] != WEAPON_POLEARM) )) { send_to_char("You must be wielding a sword, spear or polearm to lunge.\n\r",ch); return; } if (is_safe(ch,victim) ) return; if (check_chargeset(ch,victim)) {return;} chance += ch->carry_weight/25; chance -= victim->carry_weight/20; chance += (ch->size - victim->size)*20; chance -= get_curr_stat(victim,STAT_DEX); chance += get_curr_stat(ch,STAT_STR)/3; chance += get_curr_stat(ch,STAT_DEX)/2; if (is_affected(ch,skill_lookup("haste")) ) chance += 10; if (is_affected(victim,skill_lookup("haste")) ) chance = 20; chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); act("$n attempts to impale $N with a quick lunge!",ch,0,victim,TO_NOTVICT); act("You attempt to impale $N with a quick lunge!",ch,0,victim,TO_CHAR); act("$n attempts to impale you with a quick lunge!",ch,0,victim,TO_VICT); if (number_percent() < chance) { check_improve(ch,gsn_lunge,TRUE,1); WAIT_STATE(ch,skill_table[gsn_lunge].beats); if (wield->pIndexData->new_format) dam = dice(wield->value[1],wield->value[2]); else dam = number_range(wield->value[1],wield->value[2]); if (get_skill(ch,gsn_enhanced_damage) > 0 ) { if (number_percent() <= get_skill(ch,gsn_enhanced_damage) ) { check_improve(ch,gsn_enhanced_damage,TRUE,1); dam += dam*(number_range(60,100)/100) * ch->pcdata->learned[gsn_enhanced_damage]/100; } } dam += GET_DAMROLL(ch); dam *= ch->pcdata->learned[gsn_lunge]; dam /= 100; multiplier = number_range((ch->drain_level + ch->level)/8,(ch->drain_level + ch->level)/4); multiplier /= 10; multiplier += 6/4; dam *= multiplier; dam *= battlecry_multiplier(ch, gsn_lunge); if (dam <= 0) dam = 1; damage_old(ch,victim,dam,gsn_lunge,DAM_PIERCE,TRUE); } else { damage_old(ch,victim,dam,gsn_lunge,DAM_PIERCE,TRUE); check_improve(ch,gsn_lunge,FALSE,1); WAIT_STATE(ch,skill_table[gsn_lunge].beats); } return; } void do_blackjack( CHAR_DATA *ch,char *argument) { char arg[MAX_INPUT_LENGTH]; AFFECT_DATA af; CHAR_DATA *victim; int chance,size; char buf[MAX_STRING_LENGTH]; if (IS_NPC(ch) ) return; one_argument(argument,arg); if ((chance = get_skill(ch,gsn_blackjack)) == 0 || ( ch->level < skill_table[gsn_blackjack].skill_level[ch->class]) ) { send_to_char("You don't know how to blackjack.\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Blackjack who?\n\r",ch); return; } if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("Amusing, but not possible.\n\r",ch); return; } if (is_safe(ch,victim)) return; if (check_chargeset(ch,victim)) {return;} update_pc_last_fight(ch,victim); size=victim->size-ch->size; if(size>2) { send_to_char("That person is too large to blackjack.\n\r",ch); return; } if (!(str_cmp(race_table[victim->race].name,"lich"))) { act("You whack $N over the head with a heavy looking sack, but with no affect.",ch,0,victim,TO_CHAR); act("$n whacks $N over the head with a heavy looking sack, but with no affect.",ch,0,victim,TO_NOTVICT); send_to_char("You feel a sudden pain erupt through the back of your skull. It doesn't affect you.\n\r",victim); return; } if (victim->position == POS_SLEEPING) { send_to_char("But that person is already asleep!\n\r",ch); return; } if (is_affected(victim,gsn_blackjack_timer) || is_affected(victim,gsn_blackjack) ) { send_to_char("They are guarding their head too well right now.\n\r",ch); return; } chance *= 75; chance /= 90; chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); if(size>0) chance -= 15*size; if (is_affected(victim,skill_lookup("haste"))) chance -= 50; if (is_affected(ch,skill_lookup("haste"))) chance += 10; if (get_eq_char(victim,WEAR_HEAD) != NULL) chance -= 10; if(is_affected(victim,gsn_cloak_form)) chance+=10; if (victim->position == POS_FIGHTING) { chance -= 30; } init_affect(&af); af.where = TO_AFFECTS; af.level = ch->level + victim->drain_level; af.location = 0; af.type = gsn_blackjack; af.modifier = 0; af.bitvector = 0; af.aftype = AFT_SKILL; if (ch->level == MAX_LEVEL) { chance = 100; } if (number_percent() < chance) { act("You whack $N over the head with a heavy looking sack. Ouch.",ch,0,victim,TO_CHAR); act("$n whacks $N over the head with a heavy looking sack. Ouch.",ch,0,victim,TO_NOTVICT); send_to_char("You feel a sudden pain erupt through the back of your skull.\n\r",victim); af.duration = 2; affect_to_char(victim,&af); af.type=gsn_blackjack_timer; af.duration=4; affect_to_char(victim,&af); stop_fighting( victim, TRUE); victim->position = POS_SLEEPING; check_improve(ch,gsn_blackjack,TRUE,1); WAIT_STATE(ch,2*PULSE_VIOLENCE); return; } else { act("You attempt to blackjack $N but fail.",ch,0,victim,TO_CHAR); act("$n attempts to blackjack $N but misses.",ch,0,victim,TO_NOTVICT); act("$n hits you over the head with a heavy sack.",ch,0,victim,TO_VICT); af.duration = 2; affect_to_char(victim,&af); check_improve(ch,gsn_blackjack,FALSE,1); damage_old(ch,victim,2 + 2*number_range(2,5), gsn_blackjack,DAM_BASH,TRUE); WAIT_STATE(ch, 2*PULSE_VIOLENCE); if (!IS_NPC(victim)) { sprintf(buf, "Help! %s tried to blackjack me!",PERS(ch,victim)); do_myell(victim,buf); multi_hit(ch,victim,TYPE_UNDEFINED); } } return; } void do_bandage(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; AFFECT_DATA af; one_argument(argument,arg); if ( (get_skill(ch,gsn_bandage) == 0) || (ch->level < skill_table[gsn_bandage].skill_level[ch->class]) ) { send_to_char("Huh?\n\r",ch); return; } if (is_affected(ch,gsn_bandage)) { send_to_char("You can't apply more aid yet.\n\r",ch); return; } if (ch->mana < 15) { send_to_char("You don't have the mana.\n\r",ch); return; } if (arg[0] == '\0') victim = ch; else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (number_percent() > ch->pcdata->learned[gsn_bandage]) { act("You fail to apply battle dressing to $N's wounds.",ch,0,victim,TO_CHAR); act("$n fumbles with $s bandages but fails to use them effectively.",ch,0,0,TO_ROOM); ch->mana -= 7; check_improve(ch,gsn_bandage,FALSE,3); return; } ch->mana -= 15; if (victim != ch) { act("$n applies bandages to $N's battle wounds.",ch,0,victim,TO_NOTVICT); act("You apply bandages to $N's battle wounds.",ch,0,victim,TO_CHAR); act("$n applies bandages to your battle wounds.",ch,0,victim,TO_VICT); } else { act("$n applies bandages to $mself.",ch,0,0,TO_ROOM); send_to_char("You apply battle dressing to yourself.\n\r",ch); } send_to_char("You feel better.\n\r",victim); victim->hit = UMIN(victim->hit + (9*ch->level), victim->max_hit); if (number_percent() < 60) { if (IS_AFFECTED(victim,AFF_PLAGUE)) { affect_strip(victim,gsn_plague); act("The sores on $n's body vanish.\n\r",victim,0,0,TO_ROOM); send_to_char("The sores on your body vanish.\n\r",victim); } } if (number_percent() < 60) { if (is_affected(victim, gsn_blindness)) { affect_strip(victim, gsn_blindness); send_to_char("Your vision returns!\n\r",victim); } } if (number_percent() < 60) { if (is_affected(victim,gsn_poison)) { affect_strip(victim,gsn_poison); send_to_char("A warm feeling goes through your body.\n\r",victim); act("$n looks better.",victim,0,0,TO_ROOM); } if (is_affected(victim,gsn_poison_dust)) { affect_strip(victim,gsn_poison_dust); send_to_char("The dust in your eyes is cleaned out.\n\r",victim); act("The dust in $n's eyes looks cleaned out.",victim,0,0,TO_ROOM); } } check_improve(ch,gsn_bandage,TRUE,3); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_bandage; af.location = 0; af.duration = 2; af.modifier = 0; af.bitvector = 0; af.level = ch->level; af.aftype = AFT_POWER; affect_to_char(ch,&af); return; } void do_herb(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; AFFECT_DATA af; one_argument(argument,arg); if ( (get_skill(ch,gsn_herb) == 0) || (ch->level < skill_table[gsn_herb].skill_level[ch->class]) ) { send_to_char("Huh?\n\r",ch); return; } if (is_affected(ch,gsn_herb)) { send_to_char("You can't find any more herbs.\n\r",ch); return; } if ((ch->in_room->sector_type != SECT_FOREST) && (ch->in_room->sector_type != SECT_HILLS) && (ch->in_room->sector_type != SECT_MOUNTAIN) ) { send_to_char("You can't find any herbs here.\n\r",ch); return; } if (arg[0] == '\0') victim = ch; else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (number_percent() > ch->pcdata->learned[gsn_herb]) { send_to_char("You search for herbs but fail to find any.\n\r",ch); act("$n looks about in the bushes but finds nothing.",ch,0,0,TO_ROOM); check_improve(ch,gsn_herb,FALSE,4); return; } if (victim != ch) { act("$n applies herbs to $N.",ch,0,victim,TO_NOTVICT); act("You apply herbs to $N.",ch,0,victim,TO_CHAR); act("$n applies herbs to you.",ch,0,victim,TO_VICT); } if (victim == ch) { act("$n applies herbs to $mself.",ch,0,0,TO_ROOM); send_to_char("You find herbs and apply them to yourself.\n\r",ch); } send_to_char("You feel better.\n\r",victim); if (IS_AFFECTED(victim,AFF_PLAGUE) && number_percent() > 30) { affect_strip(victim,gsn_plague); act("The sores on $n's body vanish.\n\r",victim,0,0,TO_ROOM); send_to_char("The sores on your body vanish.\n\r",victim); } check_improve(ch,gsn_herb,TRUE,4); victim->hit = UMIN(victim->hit + (4*(ch->drain_level + ch->level)), victim->max_hit); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_herb; af.location = 0; af.duration = 4; af.modifier = 0; af.bitvector = 0; af.aftype = AFT_SKILL; af.level = ch->level + ch->drain_level; affect_to_char(ch,&af); return; } void do_cleave(CHAR_DATA *ch,char *argument) { OBJ_DATA *weapon; CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; int dam, chance, dam_type; char buf[MAX_STRING_LENGTH]; int sn; int skill; if ( ( ( chance = get_skill(ch,gsn_cleave)) == 0) || (ch->level < skill_table[gsn_cleave].skill_level[ch->class]) ) { send_to_char("You don't know how to cleave.\n\r",ch); return; } one_argument(argument,arg); weapon = get_eq_char(ch,WEAR_WIELD); if (weapon == NULL) { send_to_char("You need to wield a sword or axe to cleave.\n\r",ch); return; } if ((weapon->value[0] != WEAPON_SWORD) && (weapon->value[0] != WEAPON_AXE) ) { send_to_char("You need to wield a sword or axe to cleave.\n\r",ch); return; } if ( (victim = get_char_room(ch,arg)) == NULL ) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't do such a thing.\n\r",ch); return; } if (victim->fighting != NULL) { send_to_char("They are moving too much to cleave.\n\r",ch); return; } if (victim->hit < victim->max_hit*9/10) { send_to_char("They are too hurt and watchful to cleave right now...\n\r",ch); return; } if (is_safe(ch,victim)) return; if (check_chargeset(ch,victim)) {return;} chance /= 5; if ((ch->drain_level + ch->level - victim->drain_level + victim->level) < 0) chance -= (ch->drain_level + ch->level - victim->drain_level - victim->level)*3; else chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); chance += get_curr_stat(ch,STAT_STR)/2; chance -= get_curr_stat(victim,STAT_DEX)/3; /* Improve evasion */ chance -= get_curr_stat(victim,STAT_STR)/4; /* Improve repelling */ chance -= get_curr_stat(victim,STAT_CON)/4; /* Shock survival */ dam_type = attack_table[weapon->value[3]].damage; if (!can_see(victim,ch)) chance += 5; chance -= dice(2,6); chance = URANGE(2,chance,10); if (number_percent() < 50) sprintf(buf,"Die, %s you butchering fool!",PERS(ch,victim)); else sprintf(buf,"Help! %s just tried to cleave me in half!",PERS(ch,victim)); sn = get_weapon_sn(ch); skill = get_weapon_skill(ch,sn) + ch->pcdata->learned[gsn_cleave] + 10; skill = URANGE(0,skill/2,100); if (get_skill(ch,gsn_zealotism) == 100) { chance += 100; } if (IS_IMP(ch)) { chance += 100; } act("You make a brutal swing at $N in an attempt to cleave them in half.",ch,0,victim,TO_CHAR); act("$n attempts to cleave you in half with a brutal slice.",ch,0,victim,TO_VICT); act("$n makes an attempt to cleave $N in half.",ch,0,victim,TO_NOTVICT); if (IS_IMP(victim)) { act("You make a brutal swing at $N in an attempt to cleave them in half, but miss and chop your own head off.",ch,0,victim,TO_CHAR); act("$n attempts to cleave you in half with a brutal slice, but misses and chops thier own head off.",ch,0,victim,TO_VICT); act("$n makes an attempt to cleave $N in half but misses and chops their own head off!",ch,0,victim,TO_NOTVICT); raw_kill(victim,ch); return; } if (IS_NPC(victim)) victim->last_fought = ch; if (number_percent() > chance) { check_improve(ch,gsn_cleave,FALSE,5); if (weapon->pIndexData->new_format) dam = dice(weapon->value[1],weapon->value[2])*skill/100; else dam = number_range(weapon->value[1]*skill/100,weapon->value[2]*skill/100); dam *= number_range((ch->drain_level + ch->level)/10,(ch->drain_level + ch->level)/7); damage_old(ch,victim,dam,gsn_cleave,dam_type,TRUE); if (!IS_NPC(victim) && !IS_NPC(ch) && victim->hit > 1) do_myell(victim,buf); WAIT_STATE(ch,PULSE_VIOLENCE*3); WAIT_STATE(victim,PULSE_VIOLENCE*2); return; } act("Your cleave slices $S body in half with a clean cut!",ch,0,victim,TO_CHAR); act("$n cleaves you in half, tearing your body into two bloody bits!",ch,0,victim,TO_VICT); act("$n cleaves $N into to bits of bloody flesh!",ch,0,victim,TO_NOTVICT); check_improve(ch,gsn_cleave,TRUE,5); raw_kill(ch,victim); return; } void do_deathstrike(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int chance, dam; char arg[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH]; /* AFFECT_DATA af; */ one_argument(argument,arg); if (IS_NPC(ch)) return; if ((get_skill(ch,gsn_deathstrike) == 0) || ch->level < skill_table[gsn_deathstrike].skill_level[ch->class]) { send_to_char("Huh?\n\r",ch); return; } if (is_affected(ch,gsn_deathstrike)) { send_to_char("You can't build up the intensity to deathstrike yet.\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Attempt to destroy who's skull?\n\r",ch); return; } if ( (victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't do that.\n\r",ch); return; } if (victim->fighting != NULL || victim->position == POS_FIGHTING) { send_to_char("They are moving around too much to get in close for the kill.\n\r",ch); return; } if (is_safe(ch,victim)) return; if (victim->hit < victim->max_hit) { send_to_char("They have too much blood on them right now to locate their strike point.\n\r",ch); return; } chance = get_skill(ch,gsn_deathstrike)/2; chance += ch->level; chance -= victim->level * 3/2; chance -= number_range(0,15); if (!can_see(victim,ch)) chance += 10; if (victim->position == POS_FIGHTING) chance -= 25; else if (victim->position == POS_SLEEPING) chance += 10; else chance -= 10; chance /= 2; chance = URANGE(2,chance,90); act("$n strikes out at $N with deadly intensity.",ch,0,victim,TO_NOTVICT); act("You strike out at $N with deadly intensity.",ch,0,victim,TO_CHAR); act("$n strikes at you with deadly intensity.",ch,0,victim,TO_VICT); if (number_percent() < chance) { send_to_char("With agonising pain your skull is smashed by the blow!\n\r",victim); act("Your blow shatters $N's skull into bloody fragments!",ch,0,victim,TO_CHAR); act("$N's skull is shattered into bits of mangled flesh and bone by $n's strike!",ch,0,victim,TO_NOTVICT); raw_kill(ch,victim); check_improve(ch,gsn_deathstrike,TRUE,3); return; } else { send_to_char("You feel a sharp pain searing your skull!\n\r",victim); act("Your deathstrike smashes $N's skull but fails to kill.",ch,0,victim,TO_CHAR); dam = ch->level * 2; dam += dice(ch->level, 4); damage_old(ch,victim,dam,gsn_deathstrike,DAM_PIERCE,TRUE); check_improve(ch,gsn_deathstrike,FALSE,3); if (!IS_NPC(victim) && !IS_NPC(ch) && (victim->hit > 1)) { sprintf(buf,"Help! %s just tried to kill me!",PERS(ch,victim)); do_myell(victim,buf); } multi_hit(victim,ch,TYPE_UNDEFINED); } return; } void do_crush(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int chance, dam; if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM)) return; if ( (chance = get_skill(ch,gsn_crush)) == 0 || ch->level < skill_table[gsn_crush].skill_level[ch->class]) if (!IS_NPC(ch)) { send_to_char("Crushing, how do you do that again?\n\r",ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r",ch); return; } if (is_affected(victim,gsn_protective_shield)) { act("$N's crush attempt seems to slide around you.",victim,0,ch,TO_CHAR); act("$N's crush attempt seems to slide around $n.",victim,0,ch,TO_NOTVICT); act("Your crush attempt seems to slide around $n.",victim,0,ch,TO_VICT); WAIT_STATE(ch,PULSE_VIOLENCE*2); return; } if (is_affected(victim,gsn_wraithform)) { act("$N's crush attempt seems to slide around you.",victim,0,ch,TO_CHAR); act("$N's crush attempt seems to slide around $n.",victim,0,ch,TO_NOTVICT); act("Your crush attempt seems to slide around $n.",victim,0,ch,TO_VICT); WAIT_STATE(ch,PULSE_VIOLENCE*2); return; } chance -= chance/4; chance += (ch->drain_level + ch->level - victim->drain_level - victim->level) * 2; chance += get_curr_stat(ch,STAT_STR); chance -= get_curr_stat(victim,STAT_DEX)/3; chance -= get_curr_stat(victim,STAT_STR)/2; if (ch->size < victim->size) chance += (ch->size - victim->size)*25; else chance += (ch->size - victim->size)*10; if (number_percent() < chance) { if (check_roll(ch,victim, gsn_crush)) { check_improve(ch,gsn_crush,TRUE,2); act("$N rolls free of $n's crush.",ch,0,victim,TO_NOTVICT); act("You roll out of $n's crush attempt.",ch,0,victim,TO_VICT); act("$N rolls free of your crush attempt.",ch,0,victim,TO_CHAR); return; } act("$n grabs you and slams you to the ground with bone crushing force!",ch,0,victim,TO_VICT); act("You grab $N and slam $M to the ground with bone crushing force!",ch,0,victim,TO_CHAR); act("$n slams $N to the ground with bone crushing force!",ch,0,victim,TO_NOTVICT); check_improve(ch,gsn_crush,TRUE,4); if ((ch->drain_level + ch->level) < 20) dam = 20; else if ((ch->drain_level + ch->level) < 25) dam = 30; else if ((ch->drain_level + ch->level) < 30) dam = 40; else if ((ch->drain_level + ch->level) < 35) dam = 50; else if ((ch->drain_level + ch->level) < 40) dam = 60; else if ((ch->drain_level + ch->level) < 52) dam = 70; else dam = 70; dam += str_app[get_curr_stat(ch,STAT_STR)].todam; WAIT_STATE(victim,2*PULSE_VIOLENCE); WAIT_STATE(ch,2*PULSE_VIOLENCE); damage_old(ch,victim,dam,gsn_crush,DAM_BASH,TRUE); victim->position = POS_RESTING; if (ch->fighting == victim) check_ground_control(ch,victim,chance,dam); return; } act("Your crush attempt misses $N.",ch,0,victim,TO_CHAR); act("$n lashes out wildly with $s arms but misses.",ch,0,0,TO_ROOM); WAIT_STATE(ch,2*PULSE_VIOLENCE); check_improve(ch,gsn_crush,FALSE,3); return; } void check_ground_control(CHAR_DATA *ch,CHAR_DATA *victim,int chance,int dam) { if (chance < 10) return; if (dam == 0) return; chance += get_skill(ch,gsn_ground_control)/2; chance /= 3; chance -= number_range(5,15); chance = URANGE(5,chance,60); if (ch->level < skill_table[gsn_ground_control].skill_level[ch->class]) return; if (number_percent() > chance) { check_improve(ch,gsn_ground_control,FALSE,3); return; } act("With brutal skill you grind $N against the ground with your weight.",ch,0,victim,TO_CHAR); act("$n takes hold of $N and grinds $M against the ground.",ch,0,victim,TO_NOTVICT); act("$n grinds you against the ground with brutal skill.",ch,0,victim,TO_VICT); dam -= 10; check_improve(ch,gsn_ground_control,TRUE,2); damage_old(ch,victim,dam,gsn_ground_control,DAM_BASH,TRUE); WAIT_STATE(victim,2*PULSE_VIOLENCE); return; } void do_riot(CHAR_DATA *ch,char *argument) { CHAR_DATA *gch; int bonus; AFFECT_DATA af; if ( (get_skill(ch,gsn_riot) == 0 ) || ch->level < skill_table[gsn_riot].skill_level[ch->class]) { send_to_char("Huh?\n\r",ch); return; } if (ch->mana < 40) { send_to_char("You don't have the mana.\n\r",ch); return; } if (is_affected(ch,gsn_riot)) { send_to_char("You can't stir up another riot yet.\n\r",ch); return; } if (number_percent() > ch->pcdata->learned[gsn_riot]) { send_to_char("You try to incite a riot amongst your group but fail.\n\r",ch); act("$n gestures around angrily, trying to build up anger and discord but fails.",ch,0,0,TO_ROOM); ch->mana -= 20; check_improve(ch,gsn_riot,FALSE,2); return; } send_to_char("You stir up a riot with your actions!\n\r",ch); init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_POWER; af.type = gsn_riot; af.level = ch->level + ch->drain_level; af.bitvector = 0; af.duration = ( 2 + (ch->drain_level + ch->level)/8); af.location = APPLY_HITROLL; if ((ch->drain_level + ch->level) < 20) bonus = 6; else if ((ch->drain_level + ch->level) < 25) bonus = 7; else if ((ch->drain_level + ch->level) < 30) bonus = 8; else if ((ch->drain_level + ch->level) < 35) bonus = 9; else if ((ch->drain_level + ch->level) < 38) bonus = 10; else bonus = 12; af.modifier = bonus; affect_to_char(ch,&af); af.location = APPLY_DAMROLL; affect_to_char(ch,&af); send_to_char("You are filled with terrible fury!\n\r",ch); for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) { if (!is_same_group(ch,gch) || !IS_AWAKE(gch)) continue; if (is_affected(gch,gsn_riot)) continue; if (gch->trust > 51) continue; if (gch == ch) continue; af.location = APPLY_DAMROLL; affect_to_char(gch,&af); af.location = APPLY_HITROLL; affect_to_char(gch,&af); send_to_char("You are filled with a terrible fury!\n\r",gch); act("$n gets a terrible look of anger in $s eyes.",gch,0,0,TO_ROOM); } check_improve(ch,gsn_riot,TRUE,2); ch->mana -= 40; return; } void do_tail(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance, dam; int knock; one_argument(argument,arg); if ((IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM) && (!check_rangermob(ch))) ) return; if ( (chance = get_skill(ch,gsn_tail)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TAIL)) || (!IS_NPC(ch) && ch->level < skill_table[gsn_tail].skill_level[ch->class])) { send_to_char("You don't have a tail to strike with like that.\n\r",ch); return; } if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } chance = URANGE(5,chance,90); chance += (ch->level - victim->level); chance -= get_curr_stat(victim,STAT_DEX); chance += get_curr_stat(ch,STAT_DEX)/3; chance += get_curr_stat(ch,STAT_STR)/3; act("$n violently lashes out with $s tail.",ch,0,0,TO_ROOM); send_to_char("You violently lash out with your tail!\n\r",ch); if (number_percent() > chance) { damage_old(ch,victim,0,gsn_tail,DAM_BASH,TRUE); return; } dam = dice(ch->level, 3); knock = (ch->level + 15); damage_old(ch,victim,dam,gsn_tail,DAM_BASH,TRUE); if (number_percent() < knock) { act("$n is sent crashing to the ground by the force of the blow!",victim,0,0,TO_ROOM); send_to_char("The tail strike sends you crashing to the ground!\n\r",victim); WAIT_STATE(victim,( 3 * PULSE_VIOLENCE/2)); } WAIT_STATE(ch,2*PULSE_VIOLENCE); return; } void do_spellbane(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (get_skill(ch,gsn_spellbane) < 10 || ch->level < skill_table[gsn_spellbane].skill_level[ch->class]) { send_to_char("Huh?\n\r",ch); return; } if (is_affected(ch,gsn_spellbane)) { send_to_char("You are already turning spells.\n\r",ch); return; } if (ch->mana < 50) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > get_skill(ch,gsn_spellbane)) { send_to_char("You think of your hatred of magic but can not sustain it.\n\r",ch); act("$n makes some angry gestures and goes red in the face, but nothing happens.",ch,0,0,TO_ROOM); ch->mana -= 25; check_improve(ch,gsn_spellbane,FALSE,1); return; } init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_spellbane; af.level = ch->level + ch->drain_level; af.duration = (5 + (ch->drain_level + ch->level)/5); af.location = APPLY_SAVES; af.modifier = (-5 -ch->level/4); af.bitvector = 0; af.aftype = AFT_POWER; affect_to_char(ch,&af); act("$n fills the air with $s hatred of magic.",ch,0,0,TO_ROOM); send_to_char("You surround yourself with your hatred of magic.\n\r",ch); if (is_affected(ch,gsn_undead_drain)) { if (saves_spell(50,ch,DAM_OTHER)) { send_to_char("Your spellbane burns away the negative draining magic of the undead.\n\r",ch); affect_strip(ch,gsn_undead_drain); } } check_improve(ch,gsn_spellbane,TRUE,1); ch->mana -= 50; return; } bool spellbaned(CHAR_DATA *caster, CHAR_DATA *victim, int sn) { bool status = FALSE; int chance; if (!is_affected(victim,gsn_spellbane)) return FALSE; if(skill_table[sn].ctype == CMD_NONE) return FALSE; if ( sn >= TYPE_HIT && sn < (TYPE_HIT + MAX_DAMAGE_MESSAGE) ) return FALSE; if ( skill_table[sn].target == TAR_CHAR_DEFENSIVE) status = TRUE; else { chance = 25 + (victim->drain_level + victim->level - caster->level - caster->drain_level) * 2; chance -= victim->saving_throw; if (IS_NPC(victim) && victim->pIndexData->vnum == MOB_VNUM_RAVAGER) chance += 25; chance = URANGE(10,chance,25); if (number_percent() < chance) status = TRUE; } if (status) { act("$n's spellbane reflects $N's spell!",victim,0,caster,TO_NOTVICT); act("Your spellbane reflects $N's spell!",victim,0,caster,TO_CHAR); act("$n's spellbane reflects your spell!",victim,0,caster,TO_VICT); damage_old(victim,caster,dice(caster->level,2),gsn_spellbane,DAM_ENERGY,TRUE); } return status; } void do_throw(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int dam, chance; char arg[MAX_INPUT_LENGTH]; if ( (chance = get_skill(ch,gsn_throw)) == 0 || ch->level < skill_table[gsn_throw].skill_level[ch->class]) { send_to_char("Throwing? What's that?\n\r",ch); return; } one_argument(argument,arg); if (arg[0] == '\0') victim = ch->fighting; else victim = get_char_room(ch,arg); if (victim == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("Now that would be a bit stupid.\n\r",ch); return; } if ((victim->fighting != ch) && (ch->fighting != victim)) { send_to_char("But you aren't engaged in combat with them.\n\r",ch); return; } if (hands_full(ch)) { send_to_char("You can't throw, your hands are filled with items.\n\r",ch); return; } /* if (is_affected(ch,gsn_palm)) { send_to_char("You can't throw, you're fighting with open hand palms.\n\r",ch); return; } */ if (is_affected(victim,gsn_protective_shield)) { act("$N's throw seems to slide around you.",victim,0,ch,TO_CHAR); act("$N's throw seems to slide around $n.",victim,0,ch,TO_NOTVICT); act("Your throw seems to slide around $n.",victim,0,ch,TO_VICT); WAIT_STATE(ch,PULSE_VIOLENCE*2); return; } chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); chance -= get_curr_stat(victim,STAT_DEX); chance += get_curr_stat(ch,STAT_DEX)/2; chance *= 9; chance /= 10; chance = URANGE(5, chance, 90); if (number_percent() > chance) { dam = 0; check_improve(ch,gsn_throw,FALSE,3); } else { if (check_roll(ch,victim,gsn_throw)) { check_improve(ch,gsn_throw,TRUE,2); act("$N rolls free of $n's throw.",ch,0,victim,TO_NOTVICT); act("You roll out of $n's throw attempt.",ch,0,victim,TO_VICT); act("$N rolls free of your throw attempt.",ch,0,victim,TO_CHAR); return; } if ((ch->drain_level + ch->level) <= 18) dam = 30; else if ((ch->drain_level + ch->level) <= 22) dam = 35; else if ((ch->drain_level + ch->level) <= 25) dam = 40; else if ((ch->drain_level + ch->level) <= 28) dam = 45; else if ((ch->drain_level + ch->level) <= 32) dam = 48; else if ((ch->drain_level + ch->level) <= 35) dam = 52; else if ((ch->drain_level + ch->level) <= 38) dam = 56; else if ((ch->drain_level + ch->level) <= 40) dam = 60; else if ((ch->drain_level + ch->level) <= 43) dam = 64; else if ((ch->drain_level + ch->level) <= 45) dam = 68; else if ((ch->drain_level + ch->level) <= 48) dam = 70; else dam = 72; act("$n grabs $N and throws $M to the ground with stunning force!",ch,0,victim,TO_NOTVICT); act("You grab $N and throw $M to the ground with stunning force!",ch,0,victim,TO_CHAR); act("$n grabs you and throws you to the ground with stunning force!",ch,0,victim,TO_VICT); dam += str_app[get_curr_stat(ch,STAT_STR)].todam; check_improve(ch,gsn_throw,TRUE,3); WAIT_STATE(victim,2*PULSE_VIOLENCE); } damage_old(ch,victim,dam,gsn_throw,DAM_BASH,TRUE); WAIT_STATE(ch,2*PULSE_VIOLENCE); if (ch->fighting == victim) check_ground_control(ch,victim,chance,dam); return; } void do_palm(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_palm)) == 0 || ch->level < skill_table[gsn_palm].skill_level[ch->class]) { send_to_char("You don't have the ability to use palm striking martial arts.\n\r",ch); return; } if (is_affected(ch,gsn_palm)) { send_to_char("You're already fighting with concentrated open hand martial arts.\n\r",ch); return; } if (ch->mana <= 60) { send_to_char("You don't have the mana.\n\r",ch); return; } if (get_eq_char(ch,WEAR_WIELD) != NULL || get_eq_char(ch,WEAR_DUAL_WIELD) != NULL) { send_to_char("You can't start using open palm striking while using weapons.\n\r",ch); return; } if (number_percent() >= chance) { send_to_char("You flex your hands but cannot grasp the concentration required.\n\r",ch); check_improve(ch,gsn_palm,FALSE,2); ch->mana -= 30; return; } act("$n slowly spreads $s hands and a look of deadly concentration clouds $s eyes.",ch,0,0,TO_ROOM); send_to_char("You feel your mind relax and pass power to your opened hands.\n\r",ch); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_palm; af.location = 0; af.modifier = 0; af.duration = ((ch->drain_level + ch->level)/3); af.level = ch->drain_level + ch->level; af.bitvector = 0; af.aftype = AFT_SKILL; affect_to_char(ch,&af); check_improve(ch,gsn_palm,TRUE,2); return; } bool check_palm(CHAR_DATA *ch) { if (!is_affected(ch,gsn_palm)) return FALSE; if (number_percent() > 15) return FALSE; return TRUE; } void do_nerve(CHAR_DATA *ch,char *argument) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_nerve)) == 0 || ch->level < skill_table[gsn_nerve].skill_level[ch->class]) { send_to_char("You don't know how to use nerve pressure tactics.\n\r",ch); return; } one_argument(argument,arg); if (arg[0] == '\0') victim = ch->fighting; else victim = get_char_room(ch,arg); if (victim == NULL) { send_to_char("Attempt to put pressure on who's nerves?\n\r",ch); return; } if (victim == ch) { send_to_char("You can't do that.\n\r",ch); return; } if (is_safe(ch,victim)) return; if (is_affected(victim,gsn_nerve)) { send_to_char("They have already been weakened using nerve pressure.\n\r",ch); return; } chance += (ch->drain_level + ch->level - victim->level - victim->drain_level)*3; chance -= get_curr_stat(victim,STAT_DEX)/3; chance += get_curr_stat(ch,STAT_DEX)/2; chance -= get_curr_stat(victim,STAT_CON)/3; if (number_percent() > chance) { act("$n grasps $N's arm but fails to apply the right pressure point.",ch,0,victim,TO_NOTVICT); act("You grasp $N's arm but fail to apply the right pressure point.",ch,0,victim,TO_CHAR); act("$n grasps your arm but fails to apply the right pressure point.",ch,0,victim,TO_VICT); check_improve(ch,gsn_nerve,FALSE,3); WAIT_STATE(ch,PULSE_VIOLENCE); return; } else { act("$n grasps $N's arm and weakens $m with pressure points.",ch,0,victim,TO_NOTVICT); act("You grasp $N's arm and weaken $m with pressure points.",ch,0,victim,TO_CHAR); act("$n grasps your arm and weakens you with pressure point.",ch,0,victim,TO_VICT); check_improve(ch,gsn_nerve,TRUE,3); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_nerve; af.location = APPLY_STR; af.duration = ((ch->drain_level + ch->level)/5); af.bitvector = 0; af.modifier = -3; af.aftype = AFT_SKILL; af.level = ch->drain_level + ch->level; affect_to_char(victim,&af); WAIT_STATE(ch,PULSE_VIOLENCE); } if (!IS_NPC(ch) && !IS_NPC(victim) && (ch->fighting == NULL || victim->fighting == NULL) ) { sprintf(buf,"Help, %s is attacking me!",PERS(ch,victim)); do_myell(victim,buf); } if (victim->fighting == NULL) { multi_hit(victim,ch,TYPE_UNDEFINED); } return; } void check_follow_through(CHAR_DATA *ch, CHAR_DATA *victim, int dam) { int chance; chance = get_skill(ch,gsn_follow_through); if (ch->level <skill_table[gsn_follow_through].skill_level[ch->class]) return; chance /= 2; chance -= number_range(0,15); if (chance <= 0) return; if (number_percent() < chance) { act("$n's leg sweeps around and strikes with a follow through!",ch,0,0,TO_ROOM); act("Your leg sweeps around to land a follow through kick!",ch,0,0,TO_CHAR); damage_old(ch,victim, 4*dam/5, gsn_follow_through, DAM_BASH,TRUE); check_improve(ch,gsn_follow_through,TRUE,2); } else check_improve(ch,gsn_follow_through,FALSE,3); return; } void do_blindness_dust(CHAR_DATA *ch,char *argument) { CHAR_DATA *vch; CHAR_DATA *vch_next; AFFECT_DATA af; int chance; bool fighting = FALSE; char buf[MAX_STRING_LENGTH]; if ( (chance = get_skill(ch,gsn_blindness_dust)) == 0 || ch->level < skill_table[gsn_blindness_dust].skill_level[ch->class]) { send_to_char("You don't know how to make blindness dust to throw.\n\r",ch); return; } if (ch->mana < 18) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > chance) { act("$n hurls some dust into the air but it is blown away.",ch,0,0,TO_ROOM); send_to_char("You throw out some dust but it is blown away.\n\r",ch); ch->mana -= 9; check_improve(ch,gsn_blindness_dust,FALSE,2); WAIT_STATE(ch,12); return; } act("$n hurls a handful of dust into the room!",ch,0,0,TO_ROOM); send_to_char("You throw a handful of blindness dust into the room!\n\r",ch); check_improve(ch,gsn_blindness_dust,TRUE,2); if (ch->fighting != NULL) fighting = TRUE; init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_blindness_dust; af.level = ch->drain_level + ch->level; af.duration = 1; af.bitvector = AFF_BLIND; af.location = APPLY_HIT; af.modifier = -3; af.aftype = AFT_SKILL; ch->mana -= 18; WAIT_STATE(ch,12); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe(ch,vch)) continue; if (is_same_group(ch,vch)) continue; if (!IS_AFFECTED(vch,AFF_BLIND) && !saves_spell(ch->drain_level + ch->level,vch,DAM_OTHER)) { act("$n appears blinded.",vch,0,0,TO_ROOM); send_to_char("You get dust in your eyes.\n\r",vch); affect_to_char(vch,&af); } if (!IS_NPC(vch) && !IS_NPC(ch) && (vch->fighting == NULL || (!fighting))) { sprintf(buf,"Help! %s just threw dust in my eyes!",PERS(ch,vch)); do_myell(vch,buf); } if (vch->fighting == NULL) multi_hit(vch,ch,TYPE_UNDEFINED); } return; } void do_poison_dust(CHAR_DATA *ch,char *argument) { CHAR_DATA *vch; CHAR_DATA *vch_next; AFFECT_DATA af; int chance; bool fighting = FALSE; char buf[MAX_STRING_LENGTH]; if ( (chance = get_skill(ch,gsn_poison_dust)) == 0 || ch->level < skill_table[gsn_poison_dust].skill_level[ch->class]) { send_to_char("You don't know how to make poison dust to throw.\n\r",ch); return; } if (ch->mana < 20) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > chance) { act("$n hurls some dust into the air but it is blown away.",ch,0,0,TO_ROOM); send_to_char("You throw out some dust but it is blown away.\n\r",ch); ch->mana -= 10; WAIT_STATE(ch,12); check_improve(ch,gsn_poison_dust,FALSE,2); return; } act("$n hurls a handful of dust into the room!",ch,0,0,TO_ROOM); send_to_char("You throw a handful of poison dust into the room!\n\r",ch); check_improve(ch,gsn_poison_dust,TRUE,2); if (ch->fighting != NULL) fighting = TRUE; init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_poison_dust; af.level = ch->drain_level + ch->level; af.duration = (ch->drain_level + ch->level)/5; af.bitvector = AFF_POISON; af.location = APPLY_STR; af.modifier = -3; af.aftype = AFT_SKILL; ch->mana -= 20; WAIT_STATE(ch,12); for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (is_safe(ch,vch)) continue; if (is_same_group(ch,vch)) continue; if (!IS_AFFECTED(vch,AFF_POISON) && !saves_spell(ch->drain_level + ch->level,vch,DAM_OTHER)) { act("$n turns green and looks sick.",vch,0,0,TO_ROOM); send_to_char("You suddenly feel very sick.\n\r",vch); affect_to_char(vch,&af); } if (!IS_NPC(vch) && !IS_NPC(ch) && (vch->fighting == NULL || (!fighting))) { sprintf(buf,"Help! %s just threw dust in my eyes!",PERS(ch,vch)); do_myell(vch,buf); } if (vch->fighting == NULL) multi_hit(vch,ch,TYPE_UNDEFINED); } return; } bool check_roll(CHAR_DATA *ch, CHAR_DATA *victim, int dt) { int chance; if ( (chance = get_skill(victim,gsn_roll)) == 0 || victim->level < skill_table[gsn_roll].skill_level[victim->class]) return FALSE; chance *= 4; chance /= 5; chance += get_curr_stat(victim,STAT_DEX); chance -= victim->carry_weight/100; if (number_percent() > chance) { check_improve(victim,gsn_roll,FALSE,2); return FALSE; } check_improve(victim,gsn_roll,TRUE,2); return TRUE; } void do_warcry(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; int chance; if ( (chance = get_skill(ch,gsn_warcry)) == 0 || ch->level < skill_table[gsn_warcry].skill_level[ch->class]) { send_to_char("You don't know how to warcry properly.\n\r",ch); return; } if (is_affected(ch,gsn_warcry)) { send_to_char("You are already affected by a warcry.\n\r",ch); return; } if (ch->mana < 20) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > chance) { act("$n makes some soft grunting noises.",ch,0,0,TO_ROOM); send_to_char("You make soft grunting sounds but nothing happens.\n\r",ch); check_improve(ch,gsn_warcry,FALSE,2); ch->mana -= 10; WAIT_STATE(ch,12); return; } act("$n lets out a blood freezing warcry!",ch,0,0,TO_ROOM); send_to_char("You let out a fierce warcry!\n\r",ch); check_improve(ch,gsn_warcry,TRUE,2); init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = gsn_warcry; af.modifier = (ch->drain_level + ch->level)/7; af.location = APPLY_HITROLL; af.duration = ch->drain_level + ch->level; af.bitvector = 0; af.level = ch->drain_level + ch->level; affect_to_char(ch,&af); af.location = APPLY_SAVES; af.modifier = -(ch->level/10); affect_to_char(ch,&af); ch->mana -= 20; WAIT_STATE(ch,12); return; } void do_strangle(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; int chance; AFFECT_DATA af; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_strangle)) == 0 || ch->level < skill_table[gsn_strangle].skill_level[ch->class]) { send_to_char("You don't know how to strangle properly.\n\r",ch); return; } if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("Try using a piece of rope and a high tree branch maybe?\n\r",ch); return; } if (is_affected(victim,gsn_strangle) && !IS_AWAKE(victim)) { send_to_char("They are already lying on the ground unconcious.\n\r",ch); return; } if (victim->position == POS_FIGHTING) { send_to_char("They are moving around too much to strangle.\n\r",ch); return; } if (is_safe(ch,victim)) return; if (check_chargeset(ch,victim)) {return;} if (!(str_cmp(race_table[victim->race].name,"lich"))) { act("$n grabs hold of $N's neck, but with no affect.",ch,0,victim,TO_NOTVICT); act("You grab hold of $N's neck, but with no affect",ch,0,victim,TO_CHAR); send_to_char("Someone grabs hold of your neck. It doesn't affect you.\n\r",victim); return; } update_pc_last_fight(ch,victim); if (is_affected(victim,gsn_strangle) || is_affected(victim,gsn_strangle_timer) ) { send_to_char("They are guarding their necks too well right now.\n\r",ch); return; } init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = gsn_strangle; af.level = ch->drain_level + ch->level; af.duration = 2; af.modifier = 0; af.location = 0; af.bitvector = AFF_SLEEP; affect_to_char(victim,&af); chance /= 2; chance += ( 2*(ch->drain_level + ch->level) - 2*(victim->drain_level + victim->level)); chance -= get_curr_stat(victim,STAT_DEX)/2; chance += 10; if(is_affected(victim,gsn_cloak_form)) chance+=20; if (chance > 85) chance = 85; if (number_percent() < 50) sprintf(buf,"Help! %s is trying to strangle me!",PERS(ch,victim)); else sprintf(buf,"Help! %s just tried to strangle me!",PERS(ch,victim)); if (number_percent() > chance) { af.bitvector = 0; af.duration = 2; affect_to_char(victim,&af); damage_old(ch,victim,0,gsn_strangle,DAM_BASH,TRUE); check_improve(ch,gsn_strangle,FALSE,2); WAIT_STATE(ch,12); if (!IS_NPC(ch) && !IS_NPC(victim)) do_myell(victim,buf); multi_hit(victim,ch,TYPE_UNDEFINED); return; } act("$n grabs hold of $N's neck and puts them to sleep.",ch,0,victim,TO_NOTVICT); act("You grab hold of $N's neck and put them to sleep.",ch,0,victim,TO_CHAR); send_to_char("Someone grabs hold of your neck and puts you to sleep.\n\r",victim); victim->position = POS_SLEEPING; check_improve(ch,gsn_strangle,TRUE,2); WAIT_STATE(ch,12); return; } void check_downstrike(CHAR_DATA *ch,CHAR_DATA *victim) { OBJ_DATA *wield; int dam; int chance; chance = get_skill(ch,gsn_downstrike); if (chance <= 10) return; if (ch->level < skill_table[gsn_downstrike].skill_level[ch->class]) return; chance /= 4.5; chance += (ch->drain_level + ch->level - victim->level - victim->drain_level); chance -= get_curr_stat(victim,STAT_DEX)/3; chance += get_curr_stat(ch,STAT_DEX)/3; chance = URANGE(2, chance, 35); if (number_percent() > chance) { check_improve(victim,gsn_downstrike,FALSE,2); return; } wield = get_eq_char(ch,WEAR_WIELD); if (wield == NULL || wield->value[0]!=2) wield = get_eq_char(ch,WEAR_DUAL_WIELD); if (wield == NULL || wield->value[0]!=2) return; dam = dice(wield->value[1],wield->value[2]); dam += ch->damroll; act("You strike at $N with a downward thrust of your dagger!",ch,0,victim,TO_CHAR); act("$n strikes at you with a downward thrust of $s dagger!",ch,0,victim,TO_VICT); act("$n strikes at $N with a downward thrust of $s dagger!",ch,0,victim,TO_NOTVICT); check_improve(victim,gsn_downstrike,TRUE,2); damage_old(ch,victim,dam,gsn_downstrike,attack_table[wield->value[3]].damage, TRUE); return; } void do_enlist(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; int level; char buf[MAX_STRING_LENGTH]; AFFECT_DATA af; int chance; CHAR_DATA *check; chance = get_skill(ch,gsn_enlist); if (chance <= 10 || ch->level < skill_table[gsn_enlist].skill_level[ch->class]) { send_to_char("You do not have the skills required to enlist mercenary aid.\n\r",ch); return; } one_argument(argument,arg); if (is_affected(ch,gsn_enlist)) { send_to_char("You haven't built up the nerve to recruit anyone else yet.\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Who do you wish to enlist as a follower?\n\r",ch); return; } if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't recruit yourself.\n\r",ch); return; } if (!IS_NPC(victim)) { send_to_char("Why not just ask them to join you?\n\r",ch); return; } for (check = char_list; check != NULL; check = check->next) { if (is_affected(check,gsn_enlist) && check->master == ch) { send_to_char("You already have a devoted recruit following you.\n\r",ch); return; } } if (!IS_SET(victim->act,ACT_WARRIOR)) { send_to_char("You may only enlist the aid of those trained as warriors.\n\r",ch); return; } level = ch->drain_level + ch->level; if ((IS_GOOD(ch) && IS_EVIL(victim)) || (IS_EVIL(ch) && IS_GOOD(victim))) level = 0; if (IS_NEUTRAL(victim) || IS_NEUTRAL(ch)) level -= 4; if (IS_AFFECTED(victim,AFF_CHARM)) level = 0; if ( (victim->level + 8) > level) level = 0; if (saves_spell(level,victim,DAM_OTHER) || level == 0) { if (number_percent() < 50) do_say(victim,"I don't follow scum such as you!"); else do_say(victim,"You couldn't recruit a mangy dog to your company!"); sprintf(buf,"Help! I'm being attacked by %s!",PERS(victim,ch)); do_myell(ch,buf); multi_hit(victim,ch,TYPE_UNDEFINED); return; } victim->leader = ch; victim->master = ch; init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = gsn_enlist; af.modifier = 0; af.level = ch->drain_level + ch->level; af.bitvector = AFF_CHARM; af.duration = ch->drain_level + ch->level; af.location = 0; affect_to_char(victim,&af); af.bitvector = 0; af.duration = 15; affect_to_char(ch,&af); act("$N salutes you and prepares to follow into combat.",ch,0,victim,TO_CHAR); act("$N salutes $n and falls into line with $s.",ch,0,victim,TO_NOTVICT); return; } void do_tame(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; int chance; chance = get_skill(ch,gsn_tame); one_argument(argument,arg); if (arg[0] == '\0') victim = ch->fighting; else victim = get_char_room(ch,arg); if (victim == NULL) { send_to_char("They aren't here to tame though.\n\r",ch); return; } if (!IS_NPC(victim)) { send_to_char("Why not just talk to them about your problems?\n\r",ch); return; } else if (!IS_SET(victim->act,ACT_AGGRESSIVE) && !IS_SET(victim->off_flags,SPAM_MURDER)) { send_to_char("They are as tame as they can be.\n\r",ch); return; } chance += (ch->drain_level + ch->level - victim->level - victim->drain_level)*3; if (chance > 90) chance = 90; WAIT_STATE(ch,12); if (number_percent() > chance) { act("$n tries to calm down $N but fails.",ch,0,victim,TO_NOTVICT); act("$n tries to calm you down but fails.",ch,0,victim,TO_VICT); act("You try to calm $N down but fail.",ch,0,victim,TO_CHAR); check_improve(ch,gsn_tame,FALSE,2); return; } act("$n calms $N down.",ch,0,victim,TO_NOTVICT); act("You calm $N down.",ch,0,victim,TO_CHAR); act("$n calms you down.",ch,0,victim,TO_VICT); check_improve(ch,gsn_tame,TRUE,2); stop_fighting(victim,TRUE); victim->last_fought = NULL; REMOVE_BIT(victim->act,ACT_AGGRESSIVE); REMOVE_BIT(victim->off_flags,SPAM_MURDER); return; } void do_find_water(CHAR_DATA *ch,char *argument) { OBJ_DATA *spring; int chance; chance = get_skill(ch,gsn_find_water); if (chance > 95) chance = 95; if (chance == 0 || ch->level < skill_table[gsn_find_water].skill_level[ch->class]) { send_to_char("You poke the ground with a stick but find no water that way.\n\r",ch); return; } if (ch->mana < 15) { send_to_char("You don't have the mana.\n\r",ch); return; } if (ch->in_room->sector_type == SECT_WATER_SWIM || ch->in_room->sector_type == SECT_WATER_NOSWIM) { send_to_char("Water water all around but not a drop to drink..\n\r",ch); return; } if (number_percent() > chance) { act("$n pokes the ground with a stick then scratches $s head.",ch,0,0,TO_ROOM); send_to_char("You poke about on the ground but fail to find any water.\n\r",ch); check_improve(ch,gsn_find_water,FALSE,1); ch->mana -= 7; WAIT_STATE(ch,18); return; } act("$n pokes at the ground and digs up a spring of natural water!",ch,0,0,TO_ROOM); send_to_char("You poke about for a bit and eventually dig up a spring of water.\n\r",ch); WAIT_STATE(ch,18); ch->mana -= 15; spring = create_object(get_obj_index(OBJ_VNUM_SPRING),0); check_improve(ch,gsn_find_water,TRUE,1); obj_to_room(spring,ch->in_room); return; } void do_track(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int chance, dir; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; dir = 0; chance = get_skill(ch,gsn_track); if (chance == 0 || ch->level < skill_table[gsn_track].skill_level[ch->class]) { send_to_char("You peer intently at the ground but discern nothing.\n\r",ch); return; } one_argument(argument,arg); victim = get_char_world(ch,arg); chance *= 2; chance /= 3; if (ch->in_room->sector_type == SECT_INSIDE) chance -= 40; else if (ch->in_room->sector_type == SECT_CITY) chance -= 35; else if (ch->in_room->sector_type >= SECT_WATER_SWIM && ch->in_room->sector_type < SECT_DESERT) chance = 0; else if (ch->in_room->sector_type == SECT_FOREST) chance += 25; if (victim != NULL && !IS_NPC(victim)) dir = victim->pcdata->track_dir[ch->in_room->vnum]; if (number_percent() > chance || victim == NULL || !IS_NPC(victim) || dir == 0) { act("$n peers intently at the ground but doesn't seem to find anything.",ch,0,0,TO_ROOM); send_to_char("You peer intently at the ground but uncover nothing new.\n\r",ch); check_improve(ch,gsn_track,FALSE,2); WAIT_STATE(ch,18); return; } act("$n peers at the ground and seems more enlightened.",ch,0,0,TO_ROOM); sprintf(buf,"You peer at the surroundings and find that %s left %s last time they were here.\n\r", victim->name, (dir == 1) ? "north" : (dir == 2) ? "east" : (dir == 3) ? "south" : (dir == 4) ? "west" : (dir == 5) ? "up" : "down"); send_to_char(buf,ch); WAIT_STATE(ch,18); check_improve(ch,gsn_track,TRUE,2); return; } void do_shield_cleave(CHAR_DATA *ch,char *argument) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; int chance; OBJ_DATA *weapon; OBJ_DATA *shield; bool using_primary = TRUE; CHAR_DATA *victim; one_argument(argument,arg); if (arg[0] == '\0') victim = ch->fighting; else victim = get_char_room(ch,arg); chance = get_skill(ch,gsn_shield_cleave); if (chance == 0 || ch->level < skill_table[gsn_shield_cleave].skill_level[ch->class]) { send_to_char("You don't know the methods to cleave a shield in two.\n\r",ch); return; } weapon = get_eq_char(ch,WEAR_WIELD); if (weapon == NULL) { weapon = get_eq_char(ch,WEAR_DUAL_WIELD); using_primary = FALSE; } if (weapon == NULL || (weapon->value[0] != WEAPON_SWORD && weapon->value[0] != WEAPON_AXE) ) { send_to_char("You must be wielding an axe of sword to shield cleave.\n\r",ch); return; } if (victim == NULL) { send_to_char("But they aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("That isn't possible.\n\r",ch); return; } if ((shield = get_eq_char(victim,WEAR_SHIELD)) == NULL) { send_to_char("But they aren't using a shield.\n\r",ch); return; } chance *= 9; chance /= 10; chance += (ch->level - victim->level)*3; chance -= shield->level; if (!using_primary) chance -= 15; if (!IS_NPC(victim) && ch->fighting != victim) { sprintf(buf,"Help! %s just shield cleaved me!",PERS(ch,victim)); do_yell(victim,buf); } if (number_percent() > chance) { act("$n makes a might blow at $N's shield but fails to cleave it.",ch,0,victim,TO_NOTVICT); act("$n lands a mighty blow to your shield but fails to cleave it.",ch,0,victim,TO_VICT); act("You strike a mighty blow to $N's shield but fail to cleave it.",ch,0,victim,TO_CHAR); check_improve(ch,gsn_shield_cleave,FALSE,1); WAIT_STATE(ch,12); multi_hit(victim,ch,-1); return; } act("$n's mighty blow cleaves $N's shield in half!",ch,0,victim,TO_NOTVICT); act("Your might blow cleaves $N's shield in half!",ch,0,victim,TO_CHAR); act("$n strikes your shield with powerful force, cleaving it in two!",ch,0,victim,TO_VICT); extract_obj(shield); WAIT_STATE(ch,12); check_improve(ch,gsn_shield_cleave,TRUE,1); multi_hit(victim,ch,-1); return; } /* more race skills...Ceran */ void do_breath_fire(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; CHAR_DATA *victim; OBJ_DATA *obj_lose; OBJ_DATA *obj_next; char arg[MAX_INPUT_LENGTH]; int dam, chance; int hpch, level; level = ch->drain_level + ch->level; chance = get_skill(ch,gsn_breath_fire); if (chance == 0 || ch->level < skill_table[gsn_breath_fire].skill_level[ch->class]) { send_to_char("You aren't able to breath fire.\n\r",ch); return; } if (is_affected(ch,gsn_breath_fire)) { send_to_char("You haven't yet regained the heat in your body to create more flames.\n\r",ch); return; } one_argument(argument,arg); if (arg[0] == '\0') victim = ch->fighting; else victim = get_char_room(ch,arg); if (victim == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (ch->mana < 20) { send_to_char("You don't have the mana.\n\r",ch); return; } if (number_percent() > chance) { send_to_char("You try to breath forth fire but only smokes comes out.\n\r",ch); act("$n opens $s mouth but only a thick plume of black smoke comes forth.",ch,0,0,TO_ROOM); ch->mana -= 10; check_improve(ch,gsn_breath_fire,FALSE,1); return; } init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = gsn_breath_fire; af.location = 0; af.modifier = 0; af.duration = 4; af.bitvector = 0; af.level = ch->drain_level + ch->level; affect_to_char(ch,&af); act("$n breaths forth a cone of searing flames!",ch,0,0,TO_ROOM); send_to_char("You breath forth a cone of searing flames!\n\r",ch); if ( number_percent( ) < level && !saves_spell( level - 2, victim,DAM_FIRE ) ) { for ( obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next ) { char *msg; obj_next = obj_lose->next_content; if ( number_bits( 2 ) != 0 ) continue; switch ( obj_lose->item_type ) { default: continue; case ITEM_CONTAINER: msg = "$p ignites and burns!"; break; case ITEM_POTION: msg = "$p bubbles and boils!"; break; case ITEM_SCROLL: msg = "$p crackles and burns!"; break; case ITEM_STAFF: msg = "$p smokes and chars!"; break; case ITEM_WAND: msg = "$p sparks and sputters!"; break; case ITEM_FOOD: msg = "$p blackens and crisps!"; break; case ITEM_PILL: msg = "$p melts and drips!"; break; } act( msg, victim, obj_lose, NULL, TO_CHAR ); extract_obj( obj_lose ); } } hpch = UMAX( 10, ch->hit ); dam = number_range( (hpch/7) + 1, hpch/3 ); if ( saves_spell( level - 2, victim, DAM_FIRE ) ) dam /= 2; damage_old( ch, victim, dam, gsn_breath_fire, DAM_FIRE,TRUE); check_improve(ch,gsn_breath_fire,TRUE,1); return; } void do_rear_kick(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int dam; /* AFFECT_DATA af; */ if (str_cmp(race_table[ch->race].name,"centaur")) { send_to_char("You don't have a centaur's rear legs to kick like that.\n\r",ch); return; } if ( !IS_NPC(ch) && ch->level < skill_table[gsn_rear_kick].skill_level[ch->class] ) { send_to_char("You do not have the ability to rear kick yet.\n\r",ch ); return; } if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_KICK)) return; if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You are not fighting anyone.\n\r", ch ); return; } WAIT_STATE( ch, 24 ); act("$n whips about and kicks out with $s hind legs!",ch,0,0,TO_ROOM); act("You whip about and kick out with your hind legs!",ch,0,0,TO_CHAR); if ( IS_NPC(ch) || number_percent( ) < ch->pcdata->learned[gsn_rear_kick] ) { dam = number_range(ch->level/2,ch->level); dam += get_curr_stat(ch,STAT_STR); dam += number_range(1,ch->drain_level + ch->level); dam += number_range((ch->drain_level + ch->level)/4, (ch->drain_level + ch->level)/2); if (dam < 1) dam = 1; if (dam > 140) dam = 140; damage_old( ch, victim, dam, gsn_rear_kick,DAM_BASH, TRUE ); check_improve(ch,gsn_rear_kick,TRUE,1); } else { damage_old( ch, victim, 0, gsn_rear_kick,DAM_BASH,TRUE ); check_improve(ch,gsn_rear_kick,FALSE,1); } return; } /* Wings of fallen angel..put in multi_hit, right after 1st and 2nd attacks */ void wing_beating(CHAR_DATA *ch) { OBJ_DATA *wings; CHAR_DATA *vch; int sn_windwall; int dam; if (IS_NPC(ch)) return; if ( (wings = get_eq_char(ch,WEAR_ABOUT) ) == NULL) return; if (wings->pIndexData->vnum != OBJ_VNUM_WINGS) return; if (number_percent() > 6) return; act("The shredded wings on $n's back unfold and beat with savage force!",ch,0,0,TO_ROOM); send_to_char("The shredded wings on your back unfold and beat with savage force!\n\r",ch); sn_windwall = skill_lookup("windwall"); if (sn_windwall == -1) return; for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (vch->fighting == ch && number_percent() < 40) break; } if (vch == NULL) vch = ch->fighting; if (vch == NULL) return; dam = dice(45,4); if (saves_spell(45,vch, DAM_BASH)) dam /= 2; damage_old(ch,vch,dam, sn_windwall, DAM_BASH,TRUE); return; } void hammer_pendant(CHAR_DATA *ch) { OBJ_DATA *hammer; OBJ_DATA *hammer2; if (IS_NPC(ch)) return; if (number_percent() > 40) return; hammer = get_eq_char(ch,WEAR_NECK_1); hammer2 = get_eq_char(ch,WEAR_NECK_2); if (hammer != NULL) { if (hammer->pIndexData->vnum == 11454) { ch->hit = UMIN( ch->hit + 20, ch->max_hit ); act("$n's hammer pendant glows brightly and he looks healthier.",ch,0,0,TO_ROOM); send_to_char( "Your hammer pendant glows brightly and you feel a rush of health!\n\r", ch); } } if (hammer2 != NULL) { if (hammer2->pIndexData->vnum == 11454) { ch->hit = UMIN( ch->hit + 20, ch->max_hit ); act("$n's hammer pendant glows brightly and he looks healthier.",ch,0,0,TO_ROOM); send_to_char( "Your hammer pendant glows brightly and you feel a rush of health!\n\r", ch); } } return; } void etched_pendant(CHAR_DATA *ch) { OBJ_DATA *hammer; OBJ_DATA *hammer2; if (IS_NPC(ch)) return; if (number_percent() > 25) return; hammer = get_eq_char(ch,WEAR_NECK_1); hammer2 = get_eq_char(ch,WEAR_NECK_2); if (hammer != NULL) { if (hammer->pIndexData->vnum == 11453) { ch->hit = UMIN( ch->hit + 40, ch->max_hit ); act("$n's etched pendant writhes upon his chest.",ch,0,0,TO_ROOM); send_to_char( "Your etched pendant writhes upon your chest!\n\r", ch); } } if (hammer2 != NULL) { if (hammer2->pIndexData->vnum == 11453) { ch->hit = UMIN( ch->hit + 40, ch->max_hit ); act("$n's etched pendant writhes upon his chest.",ch,0,0,TO_ROOM); send_to_char( "Your etched pendant writhes upon your chest!\n\r", ch); } } return; } void mer_tattoo(CHAR_DATA *ch) //Merthairu's tattoo, Ceial { OBJ_DATA *brand; CHAR_DATA *vch; int sn_mert_brand; brand = get_eq_char(ch,WEAR_BRAND); sn_mert_brand = skill_lookup("ball lightning"); vch=ch->fighting; if (brand == NULL) return; if (brand->pIndexData->vnum == 68 && number_percent() < 12) { act("A demon enshrouded in flames sends forth a ball of lightning!",ch,0,0,TO_ROOM); act("A demon enshrouded in flames sends forth a ball of lightning at your foes!",ch,0,0,TO_CHAR); (*skill_table[sn_mert_brand].spell_fun) (sn_mert_brand, 60,ch,vch,TAR_CHAR_OFFENSIVE); } if (vch->in_room != ch->in_room || vch->ghost > 0) return; } void deo_tattoo(CHAR_DATA *ch, CHAR_DATA *victim) { OBJ_DATA *brand; brand = get_eq_char(ch,WEAR_BRAND); if (brand != NULL) { if (brand->pIndexData->vnum == 58) { if ((number_percent() < .5) && (!IS_NPC(victim))) { act("{R$n's $p flares violently.{x",ch,brand,NULL,TO_NOTVICT); act("{R$n's $p flares violently.{x",ch,brand,NULL,TO_VICT); act("{RYour $p flares violently.{x",ch,brand,NULL,TO_CHAR); send_to_char("Perhaps you should run away?\n\r",victim); } if (number_percent() < 1) { act("{r$n's $p flares brightly, stealing $N's last living breath. {x",ch,brand,victim,TO_NOTVICT); act("{r$n's $p flares brightly, stealing your last living breath.{x",ch,brand,victim,TO_VICT); act("{rYour $p flares brightly, stealing $N's last living breath. {x",ch,brand,victim,TO_CHAR); raw_kill(ch,victim); } if ((number_percent() < 2.5) && (IS_NPC(victim))) { act("{R$n's $p emits a fierce glow.{x",ch,brand,NULL,TO_NOTVICT); act("{R$n's $p emits a fierce glow.{x",ch,brand,NULL,TO_VICT); act("{RYour $p emits a fierce glow.{x",ch,brand,NULL,TO_CHAR); send_to_char("Perhaps you should run away?\n\r",victim); } if (number_percent() < 7) { act("{R$n's $p pulses with a red luminance!{x",ch,brand,0,TO_ROOM); act("{RYour $p pulses with a red luminance!{x",ch,brand,0,TO_CHAR); obj_cast_spell(skill_lookup("acid needles"), ch->level, ch, victim, brand); } if (number_percent() < 18) { act("{G$n's $p emits a soft glow!{x",ch,brand,0,TO_ROOM); act("{GYour $p emits a soft glow!{x",ch,brand,0,TO_CHAR); obj_cast_spell(skill_lookup("rejuvenate"), ch->level, ch, ch, brand); } } } return; } void gra_tattoo(CHAR_DATA *ch, CHAR_DATA *victim) { OBJ_DATA *brand; brand = get_eq_char(ch,WEAR_BRAND); if (brand != NULL) { if (brand->pIndexData->vnum == 77) { if (ch->last_fought == victim || (IS_NPC(victim))) { brand->timer = 0; } if ((number_percent() < 5) && (brand->timer == 0)) { brand->timer = 10; act("{r$n's $p seems to come to life as it glares at $N.{x",ch,brand,victim,TO_NOTVICT); act("{r$n's $p seems to come to life as it glares at you.{x",ch,brand,victim,TO_VICT); act("{rYour $p seems to come to life as it glares at $N.{x",ch,brand,victim,TO_CHAR); send_to_char("A strange feeling of fear suddenly overcomes you...perhaps you should consider running away?\n\r",victim); } if ((brand->timer == 9)) { brand->timer = 8; act("{r$n's $p begins to flare, as an uneasy look comes over $N's face.{x",ch,brand,victim,TO_NOTVICT); act("{r$n's $p begins to flare, as you begin to feel uneasy.{x",ch,brand,victim,TO_VICT); act("{rYour $p begins to flare, as an uneasy look comes over $N's face.{x",ch,brand,victim,TO_CHAR); } if ((brand->timer == 7)) { brand->timer = 6; act("{r$N gasps for air as blood begins to flow from $S pores.{x",ch,brand,victim,TO_NOTVICT); act("{rYou gasp for air as blood begins to flow from your pores.{x",ch,brand,victim,TO_VICT); act("{r$N gasps for air as blood begins to flow from $S pores.{x",ch,brand,victim,TO_CHAR); } if ((brand->timer == 5)) { brand->timer = 4; act("{r$N's eyes begin to glaze over as the blood trickles down $s face.{x",ch,brand,victim,TO_NOTVICT); act("{rYour eyes begin to glaze over as the blood trickles down your face.{x",ch,brand,victim,TO_VICT); act("{r$N's eyes begin to glaze over as the blood trickles down $S face.{x",ch,brand,victim,TO_CHAR); } if ((brand->timer == 3)) { brand->timer = 0; act("{rWith a final groping of $S flailing arms, $N collapses to the floor...{RDEAD!!{x",ch,brand,victim,TO_NOTVICT); act("{rWith a final groping of your flailing arms, you collapses to the floor...{RDEAD!!{x",ch,brand,victim,TO_VICT); act("{rWith a final groping of $S flailing arms, $N collapses to the floor...{RDEAD!!{x",ch,brand,victim,TO_CHAR); raw_kill(ch,victim); } if ((number_percent() < 9) && (brand->timer == 0)) { act("{G$n's $p glows a pale green as your skin begins to burn.{x",ch,brand,victim,TO_VICT); act("{G$n's $p glows a pale green.{x",ch,brand,0,TO_ROOM); act("{GYour $p glows a pale green as $N's skin begins to burn.{x",ch,brand,victim,TO_CHAR); obj_cast_spell(skill_lookup("acid needles"), ch->level, ch, victim, brand); } if ((number_percent() < 18) && (brand->timer == 0)) { act("{Y$n's $p glows ever so softly as a look of relief overcomes $s face.{x",ch,brand,0,TO_ROOM); act("{YYour $p glows ever so softly.{x",ch,brand,0,TO_CHAR); obj_cast_spell(skill_lookup("rejuvenate"), ch->level, ch, ch, brand); } } } return; } void cei_tattoo(CHAR_DATA *ch) //My tattoo, Ceial { OBJ_DATA *brand; int sn_cei_brand; brand = get_eq_char(ch,WEAR_BRAND); sn_cei_brand = skill_lookup("heal"); if (brand == NULL) return; if (brand->pIndexData->vnum == 70 && number_percent() < 15) { act("$n's brand glows brightly flowing energy into him and healing his wounds.",ch,0,0,TO_ROOM); act("$n seems to be filled with a divine energy and his wounds heal.",ch,0,0,TO_CHAR); obj_cast_spell(sn_cei_brand,60,ch,ch,brand); } return; } void kra_tattoo(CHAR_DATA *ch,CHAR_DATA *victim ) { OBJ_DATA *kratattoo; if (number_percent() > 25) return; kratattoo = get_eq_char(ch,WEAR_BRAND); if (kratattoo != NULL) { if (kratattoo->pIndexData->vnum == 59) { ch->hit = UMIN( ch->hit + 100, ch->max_hit); act("$n's mark of the dark dragon seems to drain the light around $n momentarily.",ch,0,0,TO_ROOM); send_to_char( "You mark of the dark dragon seems to drain the light around you momentarily!\n\r", ch); } } return; } void kyr_tattoo(CHAR_DATA *ch,CHAR_DATA *victim) { OBJ_DATA *kyrtattoo; if (number_percent() > 4) return; kyrtattoo = get_eq_char(ch, WEAR_BRAND); if (kyrtattoo != NULL) { if (kyrtattoo->pIndexData->vnum == 60) { act("$n's crimson caduceus glows dark red.",ch,0,0,TO_VICT); act("$n's crimson caduceus glows dark red.",ch,0,0,TO_NOTVICT); act("Your crimson caduceus glows dark red.",ch,0,0,TO_CHAR); ch->hit = UMIN( ch->hit + 75, ch->max_hit ); } } return; } void xanthr_tattoo(CHAR_DATA *ch, CHAR_DATA *victim) { OBJ_DATA *brand; brand = get_eq_char(ch,WEAR_BRAND); if (brand != NULL) { if (brand->pIndexData->vnum == 65) { if ((number_percent() < 14)) //&& (!IS_NPC(victim))) { switch ((number_percent()-1)/20) { case 4: { act("The small diamond on $n's $p flashes with a brilliant light.",ch,brand,NULL,TO_NOTVICT); act("The small diamond on $n's $p burns you with a brilliant light.",ch,brand,NULL,TO_VICT); act("The small diamond on your $p flashes with a brilliant light.",ch,brand,NULL,TO_CHAR); obj_cast_spell(skill_lookup("wrath"), ch->level, ch, victim, brand); break; } case 3: { act("The ruby over the thumb on $n's $p flares suddenly.",ch,brand,NULL,TO_NOTVICT); act("The ruby over the thumb on $n's $p flares at you suddenly.",ch,brand,NULL,TO_VICT); act("The ruby over the thumb on your $p flares suddenly.",ch,brand,NULL,TO_CHAR); obj_cast_spell(skill_lookup("nova"), ch->level, ch, victim, brand); break; } case 2: { act("The small pearl on $n's $p vibrates slightly for a moment.",ch,brand,NULL,TO_NOTVICT); act("The small pearl on $n's $p vibrates slightly for a moment.",ch,brand,NULL,TO_VICT); act("The small pearl on your $p vibrates slightly for a moment.",ch,brand,NULL,TO_CHAR); obj_cast_spell(skill_lookup("sanctuary"), ch->level, ch, ch, brand); break; } case 1: { act("The turquoise stone on $n's $p glows faintly.",ch,brand,NULL,TO_NOTVICT); act("The turquoise stone on $n's $p glows faintly.",ch,brand,NULL,TO_VICT); act("The turquoise stone on your $p glows faintly.",ch,brand,NULL,TO_CHAR); obj_cast_spell(skill_lookup("weaken"), ch->level, ch, victim, brand); break; } case 0: { act("The sapphire gem on $n's $p burns with a blue light.",ch,brand,NULL,TO_NOTVICT); act("The sapphire gem on $n's $p burns with a blue light.",ch,brand,NULL,TO_VICT); act("The sapphire gem on your $p burns with a blue light.",ch,brand,NULL,TO_CHAR); obj_cast_spell(skill_lookup("heal"), ch->level, ch, ch, brand); break; } default: break; } } } } } void do_strap(CHAR_DATA *victim,OBJ_DATA *strap) { CHAR_DATA *vch; CHAR_DATA *vch_next; if (strap->pIndexData->vnum == 5750) { act("\x01B[1;31m$n's $p explodes in a blinding flash of light!\x01B[0;37m",victim,strap,0,TO_ROOM); act("\x01B[1;31mYour $p explodes in a blinding flash of light!\x01B[0;37m",victim,strap,0,TO_CHAR); for (vch = victim->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (vch == victim) { continue; } if (IS_NPC(vch)) { continue; } if (vch->level > LEVEL_HERO) { continue; } act("$n detonates in an eruption of blood and fluids!",vch,strap,0,TO_ROOM); act("You detonate in an eruption of blood and fluids!",vch,strap,0,TO_CHAR); act( "$n is DEAD!!", vch, 0, 0, TO_ROOM ); send_to_char( "You have been KILLED!!\n\r\n\r", vch ); raw_kill(victim,vch); } unequip_char(victim,strap); obj_from_char(strap); extract_obj(strap); } if (strap->pIndexData->vnum == 5751) { unequip_char(victim,strap); obj_from_char(strap); extract_obj(strap); } return; } void dev_tattoo(CHAR_DATA *ch, CHAR_DATA *victim) { // OBJ_DATA *devtattoo; // CHAR_DATA *templar; // AFFECT_DATA af; // CHAR_DATA *vch; if (number_percent() > 5) return; /* devtattoo = get_eq_char(ch, WEAR_BRAND); if(victim!=NULL && IS_NPC(victim) && IS_EVIL(victim) && devtattoo!=NULL && devtattoo->pIndexData->vnum == 54) { for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (IS_NPC(vch) && vch->pIndexData->vnum == MOB_VNUM_TEMPLAR) break; } if (vch != NULL) return FALSE; act("The tattoo of a valiant knight on $n blazes with a white light and a golden figure steps forth.",ch,0,0,TO_ROOM); act("Your tattoo of a valiant knight blazes with a white light and a golden figure steps forth.",ch,0,0,TO_CHAR); templar = create_mobile( get_mob_index(MOB_VNUM_TEMPLAR) ); char_to_room(templar,ch->in_room); SET_BIT(templar->affected_by, AFF_CHARM); templar->master = templar->leader = ch; multi_hit( templar, victim, TYPE_UNDEFINED ); }*/ } bool check_crown_blood(CHAR_DATA *ch, CHAR_DATA *victim, int dt, int dam, int dam_type) { OBJ_DATA *obj; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; int mod; char *attack; mod = 0; if (dam_type != DAM_COLD && dam_type != DAM_NEGATIVE) return FALSE; obj = get_eq_char(victim,WEAR_HEAD); if (obj == NULL) return FALSE; if (obj->pIndexData->vnum != OBJ_VNUM_CROWN_BLOOD) return FALSE; if (!saves_spell(ch->level,victim,DAM_COLD)) return FALSE; if ( dt >= 0 && dt < MAX_SKILL ) attack = skill_table[dt].noun_damage; else if ( dt >= TYPE_HIT && dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[dt - TYPE_HIT].noun; else { bug( "Dam_message: bad dt %d.", dt ); dt = TYPE_HIT; attack = attack_table[0].name; } sprintf(buf1,"$N's crown glows and %s is unaffected by $n's %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it", attack); sprintf(buf2,"Your crown glows and you are unaffected by $n's %s!", attack); sprintf(buf3,"$N's crown glows blue and %s is unaffected by your %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it", attack); act(buf1,ch,0,victim,TO_NOTVICT); act(buf2,ch,0,victim,TO_VICT); act(buf3,ch,0,victim,TO_CHAR); if (IS_NPC(victim)) return TRUE; if (dam < 30) mod = -5; else if (dam < 50) mod = -4; else if (dam < 80) mod = -2; else if (dam < 120) mod = -1; else if (dam < 180) mod = 0; else if (dam < 350) mod = 1; else if (dam < 450) mod = 2; else if (dam < 600) mod = 3; else if (dam < 750) mod = 4; else mod += 6; if (saves_spell(51 + mod, victim, DAM_OTHER)) return TRUE; if (saves_spell(51 + mod,victim,DAM_OTHER)) return TRUE; act("$n's crown of frozen blood shudders and explodes!",ch,0,0,TO_ROOM); send_to_char("Your crown of frozen blood shudders and explodes!\n\r",ch); extract_obj(obj); return TRUE; } /* ioun stone..blue, green and red blue == for any magic dam green == for any holy||negative red == for any weapon Add stone timers in so they decay after 999 ticks anyway. (~8 hrs) All limit 2 bool check_blue_ioun(CHAR_DATA *ch,CHAR_DATA *victim,int dt, int dam, int dam_type) { OBJ_DATA *obj; char bu1f[MAX_STRING_LENGTH]; char bu2f[MAX_STRING_LENGTH]; char bu3f[MAX_STRING_LENGTH]; char *dam; if (dam_type != DAM_HOLY && dam_type != DAM_FIRE && dam_type != DAM_NEGATIVE && dam_type != DAM_COLD && dam_type != DAM_ACID && dam_type != DAM_ENERGY && DAM_TYPE != DAM_LIGHT) return FALSE; obj = get_eq_char(victim,WEAR_HOLD); if (obj == NULL) return FALSE; if (obj->pIndexData->vnum != OBJ_VNUM_BLUE_IOUN) return FALSE; if (!saves_spell(ch->level,victim,DAM_OTHER)) return FALSE; if (dt >= TYPE_HIT && dt < (TYPE_HIT + MAX_DAMAGE_MESSAGE) ) dam = dam_table[dt].noun; else dam = skill_table[dt].dam_message; sprintf(buf1,"$N's ioun stone glows and %s is unaffected by $n's %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it",dam); sprintf(buf2,"Your ioun stone glows and you are unaffected by $n's %s!", dam); sprintf(buf3,"$N's ioun stone glows blue and %s is unaffected by your %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it", dam); act(buf1,ch,0,victim,TO_NOTVICT); act(buf2,ch,0,victim,TO_VICT); act(buf3,ch,0,victim,TO_CHAR); if (IS_NPC(victim)) return TRUE; if (dam < 20) mod = -3; else if (dam < 40) mod = -2; else if (dam < 60) mod = -1; else if (dam < 80) mod = 0; else if (dam < 100) mod = 1; else if (dam < 120) mod = 2; else if (dam < 150) mod = 3; else if (dam < 200) mod = 4; else if (dam < 400) mod = 6; else mod = 8; chance = 50 + (51 + mod - victim->level) * 5; chance -= victim->saving_spell; if (number_percent() > chance) return TRUE; act("$n's blue ioun stone shudders and explodes!",ch,0,0,TO_ROOM); send_to_char("Your blue ioun stone shudders and explodes!",ch,0,0,TO_CHAR); extract_obj(obj); return TRUE; } bool check_green_ioun(CHAR_DATA *ch,CHAR_DATA *victim,int dt, int dam, int dam_type) { OBJ_DATA *obj; char bu1f[MAX_STRING_LENGTH]; char bu2f[MAX_STRING_LENGTH]; char bu3f[MAX_STRING_LENGTH]; char *dam; if (dam_type != DAM_HOLY && dam_type != DAM_NEGATIVE return FALSE; obj = get_eq_char(victim,WEAR_HOLD); if (obj == NULL) return FALSE; if (obj->pIndexData->vnum != OBJ_VNUM_GREEN_IOUN) return FALSE; if (!saves_spell(ch->level,victim,DAM_OTHER)) return FALSE; if (dt >= TYPE_HIT && dt < (TYPE_HIT + MAX_DAMAGE_MESSAGE) ) dam = dam_table[dt].noun; else dam = skill_table[dt].dam_message; sprintf(buf1,"$N's ioun stone glows and %s is unaffected by $n's %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it",dam); sprintf(buf2,"Your ioun stone glows and you are unaffected by $n's %s!",dam); sprintf(buf3,"$N's ioun stone glows blue and %s is unaffected by your %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it",dam); act(buf1,ch,0,victim,TO_NOTVICT); act(buf2,ch,0,victim,TO_VICT); act(buf3,ch,0,victim,TO_CHAR); if (IS_NPC(victim)) return TRUE; if (dam < 20) mod = -3; else if (dam < 40) mod = -2; else if (dam < 60) mod = -1; else if (dam < 80) mod = 0; else if (dam < 100) mod = 1; else if (dam < 120) mod = 2; else if (dam < 150) mod = 3; else if (dam < 200) mod = 4; else if (dam < 400) mod = 6; else mod += 8; chance = 50 + (45 + mod - victim->level) * 5; chance -= victim->saving_spell; if (number_percent() > chance) return TRUE; if (number_percent() > chance) return TRUE; act("$n's green ioun stone shudders and explodes!",ch,0,0,TO_ROOM); send_to_char("Your green ioun stone shudders and explodes!",ch,0,0,TO_CHAR); extract_obj(obj); return TRUE; } bool check_red_ioun(CHAR_DATA *ch,CHAR_DATA *victim,int dt, int dam, int dam_type) { OBJ_DATA *obj; char bu1f[MAX_STRING_LENGTH]; char bu2f[MAX_STRING_LENGTH]; char bu3f[MAX_STRING_LENGTH]; char *dam; if (dam_type != DAM_BASH && dam_type != DAM_SLASH && dam_type != DAM_PIERCE) return FALSE; obj = get_eq_char(victim,WEAR_HOLD); if (obj == NULL) return FALSE; if (obj->pIndexData->vnum != OBJ_VNUM_RED_IOUN) return FALSE; if (!saves_spell(ch->level,victim,DAM_OTHER)) return FALSE; if (dt >= TYPE_HIT && dt < (TYPE_HIT + MAX_DAMAGE_MESSAGE) ) dam = dam_table[dt].noun; else dam = skill_table[dt].dam_message; sprintf(buf1,"$N's ioun stone glows and %s is unaffected by $n's %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it",dam); sprintf(buf2,"Your ioun stone glows and you are unaffected by $n's %s!",dam); sprintf(buf3,"$N's ioun stone glows blue and %s is unaffected by your %s!", (victim->sex == 1) ? "he" : (ch->sex == 2) ? "she" : "it",dam); act(buf1,ch,0,victim,TO_NOTVICT); act(buf2,ch,0,victim,TO_VICT); act(buf3,ch,0,victim,TO_CHAR); if (IS_NPC(victim)) return TRUE; if (dam < 10) mod = -3; else if (dam < 20) mod = -2; else if (dam < 30) mod = -1; else if (dam < 40) mod = 0; else if (dam < 50) mod = 1; else if (dam < 65) mod = 2; else if (dam < 75) mod = 3; else if (dam < 85) mod = 4; else if (dam < 100) mod = 6; else mod += 8; chance = 50 + (47 + mod - victim->level) * 5; chance -= victim->saving_spell; if (number_percent() > chance) return TRUE; if (number_percent() > chance) return TRUE; act("$n's red ioun stone shudders and explodes!",ch,0,0,TO_ROOM); send_to_char("Your red ioun stone shudders and explodes!",ch,0,0,TO_CHAR); extract_obj(obj); return TRUE; } */ void check_bracelets(CHAR_DATA *ch) { OBJ_DATA *obj1; OBJ_DATA *obj2; CHAR_DATA *vch; int sn_dispel; bool hair_1 = FALSE, hair_2 = FALSE, blood_1 = FALSE, blood_2 = FALSE; if (IS_NPC(ch)) return; obj1 = get_eq_char(ch,WEAR_WRIST_L); if (obj1 != NULL) { if (obj1->pIndexData->vnum == OBJ_VNUM_HAIR_BRACELET) hair_1 = TRUE; else if (obj1->pIndexData->vnum == OBJ_VNUM_BLOOD_BRACELET) blood_1 = TRUE; } obj2 = get_eq_char(ch,WEAR_WRIST_R); if (obj2 != NULL) { if (obj2->pIndexData->vnum == OBJ_VNUM_HAIR_BRACELET) hair_2 = TRUE; else if (obj2->pIndexData->vnum == OBJ_VNUM_BLOOD_BRACELET) blood_2 = TRUE; } if (!hair_1 && !hair_2 && !blood_1 && !blood_2) return; if ( (vch = ch->fighting) == NULL) return; if (!IS_EVIL(vch) && ((hair_1) || (hair_2)) ) return; if (!IS_GOOD(vch) && ((blood_1) || (blood_2)) ) return; if ((blood_1) || (blood_2)) sn_dispel = skill_lookup("dispel good"); else sn_dispel = skill_lookup("dispel evil"); if (blood_1 && number_percent() < 12) { act("The blood on $n's bracelet hisses and steams.",ch,0,0,TO_ROOM); act("The blood on your bracelet hisses and steams.",ch,0,0,TO_CHAR); (*skill_table[sn_dispel].spell_fun) (sn_dispel, 55,ch,vch,TAR_CHAR_OFFENSIVE); } if (vch->in_room != ch->in_room || vch->ghost > 0) return; if (blood_2 && number_percent() < 10) { act("The blood on $n's bracelet hisses and steams.",ch,0,0,TO_ROOM); act("The blood on your bracelet hisses and steams.",ch,0,0,TO_CHAR); (*skill_table[sn_dispel].spell_fun) (sn_dispel, 55,ch,vch,TAR_CHAR_OFFENSIVE); return; } if (hair_1 && number_percent() < 12) { act("The hair on $n's bracelet shimmers softly.",ch,0,0,TO_ROOM); act("The hair on your bracelet shimmers softly.",ch,0,0,TO_CHAR); (*skill_table[sn_dispel].spell_fun) (sn_dispel, 55, ch,vch,TAR_CHAR_OFFENSIVE); } if (vch->in_room != ch->in_room || vch->ghost > 0) return; if (hair_2 && number_percent() < 10) { act("The hair on $n's bracelet shimmers softly.",ch,0,0,TO_ROOM); act("The hair on your bracelet shimmers softly.",ch,0,0,TO_CHAR); (*skill_table[sn_dispel].spell_fun) (sn_dispel, 55,ch,vch,TAR_CHAR_OFFENSIVE); } return; } void check_blue_talon(CHAR_DATA *ch, CHAR_DATA *victim) { int sn; if (number_percent() < 10) { send_to_char("Electricity from the blue talon jolts you violently!\n\r",victim); act("Electricity from the blue talon jolts $n!",victim,NULL,NULL,TO_ROOM); sn = skill_lookup("shocking grasp"); (*skill_table[sn].spell_fun) (sn,ch->level,ch,victim,TAR_CHAR_OFFENSIVE); return; } return; } /* Flesh-cutter code */ /* In check_palm strike: if ((is_affected(ch,gsn_mutilated_left_hand) || is_affected(ch,gsn_mutilated_right_hand) && number_percent() > ch->level ) { send_to_char("The nerves in your hand spasm and you fail the palm strike.\n\r",ch); } */ int check_cutter(CHAR_DATA *ch,CHAR_DATA *victim) { int cut; int part; AFFECT_DATA af; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; char *part_name; if (number_percent() > 4 || saves_spell(ch->level - 5,victim,DAM_SLASH)) return 1; if (IS_SET(ch->form,FORM_INTANGIBLE) || IS_SET(ch->form,FORM_MIST) || IS_SET(ch->form,FORM_SNAKE) || IS_SET(ch->form,FORM_INSECT) || IS_SET(ch->form,FORM_WORM) || IS_SET(ch->form,FORM_BLOB) || IS_SET(ch->form,FORM_FISH) || IS_SET(ch->form,FORM_BIRD)) return 1; part = number_range(0,11); cut = 1; part_name = "left hand"; init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_MALADY; af.duration = 3; af.bitvector = 0; af.level = ch->level; switch(part) { case (0): case (1): case (2): /* left arm */ if (is_affected(victim,gsn_mutilated_left_arm) || !IS_SET(victim->parts,PART_ARMS)) return 1; part_name = "left arm"; af.type = gsn_mutilated_left_arm; af.modifier = -3; af.location = APPLY_HITROLL; affect_to_char(victim,&af); af.modifier = -3; af.location = APPLY_DAMROLL; affect_to_char(victim,&af); cut = 2; break; case (3): case (4): case (5): /* right arm */ if (is_affected(victim,gsn_mutilated_right_arm) || !IS_SET(victim->parts,PART_ARMS)) return 1; part_name = "right arm"; af.type = gsn_mutilated_right_arm; af.modifier = -3; af.location = APPLY_HITROLL; affect_to_char(victim,&af); af.modifier = -3; af.location = APPLY_DAMROLL; affect_to_char(victim,&af); cut = 2; break; case (6): case (7): /* left leg */ if (is_affected(victim,gsn_mutilated_left_leg) || !IS_SET(victim->parts,PART_LEGS)) return 1; part_name = "left leg"; af.type = gsn_mutilated_left_leg; af.modifier = -2; af.location = APPLY_DEX; affect_to_char(victim,&af); af.modifier = -(number_range(20,50)); af.location = APPLY_MOVE; affect_to_char(victim,&af); cut = 2; break; case (8): case (9): /* right leg */ if (is_affected(victim,gsn_mutilated_right_leg) || !IS_SET(victim->parts,PART_LEGS)) return 1; part_name = "right leg"; af.type = gsn_mutilated_right_leg; af.modifier = -2; af.location = APPLY_DEX; affect_to_char(victim,&af); af.modifier = -(number_range(20,50)); af.location = APPLY_MOVE; affect_to_char(victim,&af); cut = 2; break; case (10): /* left hand */ if (is_affected(victim,gsn_mutilated_left_hand) || !IS_SET(victim->parts,PART_HANDS)) return 1; part_name = "left hand"; af.type = gsn_mutilated_left_hand; af.modifier = -2; af.location = APPLY_HITROLL; affect_to_char(victim,&af); af.modifier = -2; af.location = APPLY_DAMROLL; affect_to_char(victim,&af); cut = 2; break; case (11): /* right hand */ if (is_affected(victim,gsn_mutilated_right_hand) || !IS_SET(victim->parts,PART_HANDS)) return 1; part_name = "right hand"; af.type = gsn_mutilated_right_hand; af.modifier = -2; af.location = APPLY_HITROLL; affect_to_char(victim,&af); af.modifier = -2; af.location = APPLY_DAMROLL; affect_to_char(victim,&af); cut = 2; break; default: /* right hand */ if (is_affected(victim,gsn_mutilated_right_hand) || !IS_SET(victim->parts,PART_HANDS)) return 1; part_name = "right hand"; af.type = gsn_mutilated_right_hand; af.modifier = -2; af.location = APPLY_HITROLL; affect_to_char(victim,&af); af.modifier = -2; af.location = APPLY_DAMROLL; affect_to_char(victim,&af); cut = 2; break; } sprintf(buf1,"$n's flesh-cutter cruelly mangles $N's %s!",part_name); sprintf(buf2,"Your flesh-cutter cruelly mangles $N's %s!",part_name); sprintf(buf3,"$n's flesh-cutter cruelly mangles your %s!",part_name); act(buf1,ch,0,victim,TO_NOTVICT); act(buf2,ch,0,victim,TO_CHAR); act(buf3,ch,0,victim,TO_VICT); return cut; } bool eye_of_beholder_absorb(CHAR_DATA *ch,CHAR_DATA *victim,int dt,int dam,int dam_type) { int chance; OBJ_DATA *eye; eye = get_eq_char(victim,WEAR_LIGHT); if (eye == NULL) return FALSE; if (eye->pIndexData->vnum != 14003) return FALSE; if (dt > TYPE_HIT && dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) return FALSE; if (dam_type == DAM_SLASH || dam_type == DAM_BASH || dam_type == DAM_PIERCE) return FALSE; chance = 50 + (victim->level - ch->level) * 5; if (dam <= 20) chance += 15; else if (dam <= 40) chance += 10; else if (dam <= 60) chance += 0; else if (dam <= 80) chance -= 5; else if (dam <= 100) chance -= 10; else if (dam <= 120) chance -= 15; else if (dam <= 140) chance -= 20; else if (dam <= 160) chance -= 25; else if (dam <= 180) chance -= 30; else if ( dam <= 200) chance -= 35; else chance -= 40; chance += victim->saving_throw/4; if (number_percent() < chance) { act("$n's eye of a beholder nullifies the magic around $m.",victim,0,0,TO_ROOM); act("Your eye of a beholder nullifies the magic around you.",victim,0,0,TO_CHAR); return TRUE; } return FALSE; } /* dying of old age */ void age_death(CHAR_DATA *ch) { ROOM_INDEX_DATA *pRoomIndex; OBJ_DATA *obj; OBJ_DATA *obj_next; if (IS_NPC(ch)) return; if (IS_GOOD(ch)) pRoomIndex = get_room_index(ROOM_VNUM_DEATH_GOOD); else if (IS_EVIL(ch)) pRoomIndex = get_room_index(ROOM_VNUM_DEATH_EVIL); else pRoomIndex = get_room_index(ROOM_VNUM_DEATH_NEUTRAL); if (pRoomIndex == NULL) pRoomIndex = get_room_index(1212); if (pRoomIndex == NULL) pRoomIndex = get_room_index(ch->temple); if (pRoomIndex == NULL) return; /* For now default to the players recall, or midgaard */ pRoomIndex = get_room_index(ch->temple); if (pRoomIndex == NULL) pRoomIndex = get_room_index(3001); for (obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; extract_obj(obj); } /* All items are poofed at age death */ stop_fighting(ch,TRUE); make_corpse(ch,ch); char_from_room(ch); char_to_room(ch,pRoomIndex); do_look(ch,"auto"); send_to_char("You have died and become a permenant ghost, awaiting your final departure.\n\r",ch); return; } void do_forage(CHAR_DATA *ch,char *argument) { OBJ_DATA *berry_1; OBJ_DATA *berry_2; int chance, found; if ( (chance = get_skill(ch,gsn_forage)) == 0 || (ch->level < skill_table[gsn_forage].skill_level[ch->class]) ) { send_to_char("You aren't able to decide on which plants are edible.\n\r",ch); return; } if (ch->in_room->sector_type != SECT_FOREST) { send_to_char("You aren't in a suitable forest region where you can apply your plant lore.\n\r",ch); return; } if (chance > 90) chance = 90; if (number_percent() > chance) { act("$n messes about in the undergrowth but comes up looking perplexed.",ch,0,0,TO_ROOM); send_to_char("You search around but find nothing you can recognise as edible.\n\r",ch); check_improve(ch,gsn_forage,FALSE,2); WAIT_STATE(ch,12); return; } act("$n messes about in the nearby bushes and comes out with some berries.",ch,0,0,TO_ROOM); send_to_char("You search around and find some edible berries in the bushes.\n\r",ch); check_improve(ch,gsn_forage,TRUE,2); found = number_range(1,3); berry_1 = create_object(get_obj_index(OBJ_VNUM_BERRY),1); if (berry_1 == NULL) return; obj_to_char(berry_1,ch); if (found >= 2) { berry_2 = create_object(get_obj_index(OBJ_VNUM_BERRY),1); obj_to_char(berry_2,ch); } /* if (found >= 3) { berry_3 = create_object(get_obj_index(OBJ_VNUM_BERRY),1); obj_to_char(berry_3,ch); } if (found >= 4) { berry_4 = create_object(get_obj_index(OBJ_VNUM_BERRY),1); obj_to_char(berry_4,ch); } */ return; } void do_defend(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; char arg[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; one_argument(argument,arg); if ( (get_skill(ch,gsn_defend) == 0) || (ch->level < skill_table[gsn_defend].skill_level[ch->class]) ) { send_to_char("You aren't able to defend other people.\n\r",ch); return; } if (arg[0] == '\0') { if (ch->defending == NULL) sprintf(buf,"You aren't defending anyone right now.\n\r"); else sprintf(buf,"You are defending %s.\n\r",ch->defending->name); send_to_char(buf,ch); return; } victim = get_char_room(ch,arg); if (victim == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You no longer defend anyone.\n\r",ch); ch->defending = NULL; return; } if (IS_NPC(victim)) { send_to_char("They don't need to be defended.\n\r",ch); return; } if (ch->defending != NULL) { act("You stop defending $N.",ch,0,ch->defending,TO_CHAR); act("$n stops defending you.",ch,0,ch->defending,TO_VICT); } sprintf(buf,"You start defending %s.\n\r",victim->name); ch->defending = victim; act("$n is now defending you.",ch,0,victim,TO_VICT); return; } void do_intimidate(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; int chance; chance = get_skill(ch,gsn_intimidate); chance *= 8; chance /= 10; one_argument(argument,arg); if (arg[0] == '\0') victim = ch->fighting; else victim = get_char_room(ch,arg); if (victim == NULL) { send_to_char("Trying to intimidate those imaginary friends again?\n\r",ch); return; } if (!IS_NPC(victim)) { send_to_char("Why not just threaten them yourself?\n\r",ch); return; } else if (!IS_SET(victim->act,ACT_AGGRESSIVE) && !IS_SET(victim->off_flags,SPAM_MURDER)) { send_to_char("They are pretty passive as it is, why anger them further?\n\r",ch); return; } else if (IS_SET(victim->off_flags,OFF_INTIMIDATED)) { send_to_char("They won't be intimidated any further by anyone.\n\r",ch); return; } chance += (ch->level*3 - victim->level*3); if (IS_GOOD(victim)) chance -= 20; if (chance > 70) chance = 70; WAIT_STATE(ch,12); if (number_percent() > chance) { act("$n tries to intimidate $N into submission but just makes a fool of $mself.",ch,0,victim,TO_NOTVICT); act("You try to intimidate $N into submission but just make a fool of yourself.",ch,0,victim,TO_CHAR); check_improve(ch,gsn_intimidate,FALSE,1); return; } act("$n stares down $N with $s overwhelming prescence.",ch,0,victim,TO_NOTVICT); act("You stare down $N with your overwhelming prescence.",ch,0,victim,TO_CHAR); check_improve(ch,gsn_intimidate,TRUE,1); stop_fighting(victim,TRUE); victim->last_fought = NULL; SET_BIT(victim->off_flags,OFF_INTIMIDATED); return; } /* New flee...this allows 'flee <direction>' for the thief skill escape. -Ceran */ void do_flee( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *was_in; ROOM_INDEX_DATA *now_in; CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; int attempt, chance, dir; if ( ( victim = ch->fighting ) == NULL ) { if ( ch->position == POS_FIGHTING ) ch->position = POS_STANDING; send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } if (is_affected(ch,gsn_bloody_shackles)) { check_bloody(ch); } if (IS_ROOM_AFFECTED(ch->in_room,AFF_ROOM_WALL_THORNS)) { check_wall_thorns(ch); } if (is_affected(ch,gsn_aristaeia)) { send_to_char("You are too filled with righteous wrath to flee!\n\r",ch); check_parting_blow(ch,victim); return; } if (is_affected(ch,gsn_shadowstrike) && number_percent()<20) { act("$n tries to flee but the shadowy arms stop his movements.",ch,0,0,TO_ROOM); act("You try to flee but the shadow arms block you.",ch,0,0,TO_CHAR); WAIT_STATE(ch,2*PULSE_VIOLENCE); return; } if (is_affected(ch,gsn_shackles) && number_percent()<20) { act("$n tries to flee but trips over his shackles.",ch,0,0,TO_ROOM); act("You try to flee but trip over your shackles.",ch,0,0,TO_CHAR); WAIT_STATE(ch,PULSE_VIOLENCE); check_cheap_shot(ch->fighting,ch); return; } if (is_affected(ch,gsn_bloodthirst) && number_percent()<20 ) { send_to_char("You gasp for breath as you attempt to snap out of your insanity!\n\r",ch); act("$n gasps for breath, attempting to snap out of $s insanity!",ch,NULL,NULL,TO_ROOM); WAIT_STATE(ch,PULSE_VIOLENCE); } if (is_affected(ch,gsn_bind) ) { act("$n attempts to flee but his bindings cause him to trip up and fall!",ch,0,0,TO_ROOM); act("You attempt to flee but your bindings cause you to trip up and fall!",ch,0,0,TO_CHAR); WAIT_STATE(ch,PULSE_VIOLENCE); check_cheap_shot(ch->fighting,ch); check_parting_blow(ch,victim); return; } if (check_cutoff(ch,victim)) { return; } one_argument(argument,arg); chance = get_skill(ch,gsn_escape); if (chance > 90) chance=90; dir = 10; if (arg[0] == '\0') dir=10; else if (!str_cmp(arg,"north")) dir=0; else if (!str_cmp(arg,"east")) dir=1; else if (!str_cmp(arg,"south")) dir=2; else if (!str_cmp(arg,"west")) dir=3; else if (!str_cmp(arg,"up")) dir=4; else if (!str_cmp(arg,"down")) dir=5; else dir=10; was_in = ch->in_room; if (was_in==NULL) { bug("In do_flee: ch->in_room is NULL.",0); return; } if (chance>0 && number_percent()>chance && dir!=10) { send_to_char("Trying to escape...\n\r",ch); } for ( attempt = 0; attempt < 6; attempt++ ) { EXIT_DATA *pexit; int door; if (dir>5 || dir<0) door=number_door()%6; else door = dir; pexit = was_in->exit[door]; if ( pexit == 0) continue; if (pexit->u1.to_room == NULL || ( IS_SET(pexit->exit_info, EX_CLOSED) && (!IS_AFFECTED(ch,AFF_PASS_DOOR) )) || number_range(0,ch->daze) != 0 || ( IS_NPC(ch) && IS_SET(pexit->u1.to_room->room_flags, ROOM_NO_MOB) ) ) continue; check_parting_blow(ch,victim); move_char( ch, door, FALSE ); if ( ( now_in = ch->in_room ) == was_in ) continue; stop_fighting(ch,TRUE); ch->last_fought = NULL; ch->in_room = was_in; act( "$n has fled!", ch, NULL, NULL, TO_ROOM ); ch->in_room = now_in; if ( !IS_NPC(ch) ) { send_to_char( "You flee from combat!\n\r", ch ); if (dir != 10 && get_skill(ch,gsn_escape) > 2) check_improve(ch,gsn_escape,2,TRUE); } return; } send_to_char( "PANIC! You couldn't escape!\n\r", ch ); return; } /* Some more new skills..Ceran */ void do_lash(CHAR_DATA *ch,char *argument) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance; char buf[MAX_STRING_LENGTH]; OBJ_DATA *weapon; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_lash)) == 0 && ch->level < skill_table[gsn_lash].skill_level[ch->class]) { send_to_char("You don't have the skill to lash people's legs.\n\r",ch); return; } if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM)) return; weapon = get_eq_char(ch,WEAR_WIELD); if (weapon == NULL || (weapon->value[0] != WEAPON_WHIP && weapon->value[0] != WEAPON_FLAIL) ) { chance -= 15; weapon = get_eq_char(ch,WEAR_DUAL_WIELD); } if (weapon == NULL) { send_to_char("You aren't wielding any weapon to lash with.\n\r",ch); return; } if (weapon->value[0] != WEAPON_WHIP && weapon->value[0] != WEAPON_FLAIL) { send_to_char("You need to be wielding a whip or flail to lash.\n\r",ch); return; } if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim->position == POS_SLEEPING || victim->position == POS_RESTING) { act("$N isn't on $S feet.",ch,NULL,victim,TO_CHAR); return; } if (victim == ch) { send_to_char("You try to lash your feet and look clumsy doing it.\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(victim,AFF_FLYING) && !is_affected(victim,gsn_earthbind)) { act("$S feet aren't on the ground.",ch,NULL,victim,TO_CHAR); return; } */ /* speed */ if (IS_SET(ch->off_flags,OFF_FAST) || is_affected(ch,skill_lookup("haste"))) chance += 5; if (IS_SET(victim->off_flags,OFF_FAST) || is_affected(victim,skill_lookup("haste"))) chance -= 35; chance += get_curr_stat(ch,STAT_DEX)/2; chance -= get_curr_stat(victim,STAT_DEX)/2; if (IS_AFFECTED(victim,AFF_FLYING)) chance -= dice(2,5); if (!IS_NPC(ch) && (ch->class == CLASS_TRANSMUTER || ch->class == CLASS_NECROMANCER || ch->class == CLASS_ELEMENTALIST) ) chance -= 10; /* CLS - not sure if you are going to make a number_chance() function, but until you do i stuck in rnadom */ if (is_affected(victim,gsn_fireshield) && number_percent()>35) { act("$S's shield of flame singes your whip as you attempt to lash him!",ch,NULL,victim,TO_CHAR); act("Your shield of flame singes $n's whip as he tries to lash you!",ch,0,victim,TO_VICT); WAIT_STATE(ch,PULSE_VIOLENCE*2); return; } /* level */ chance += (ch->level - victim->level)*3; chance -= 25; if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL)) { sprintf(buf,"Help! %s is lashing me!",PERS(ch,victim)); do_myell(victim,buf); } if (number_percent() > chance) { act("$n lashes at $N's legs but misses.",ch,0,victim,TO_NOTVICT); act("$n lashes at your legs but misses.",ch,0,victim,TO_VICT); act("You lash at $N's legs but miss.",ch,0,victim,TO_CHAR); check_improve(ch,gsn_lash,FALSE,1); WAIT_STATE(ch,skill_table[gsn_lash].beats); return; } act("$n lashes $N's legs, sending $M crashing down.",ch,0,victim,TO_NOTVICT); act("$n lashes your legs, sending you crashing to the ground.",ch,0,victim,TO_VICT); act("You lash $N's legs, sending $M crashing to the ground.",ch,0,victim,TO_CHAR); check_improve(ch,gsn_lash,TRUE,1); WAIT_STATE(victim,PULSE_VIOLENCE*3); WAIT_STATE(ch,PULSE_VIOLENCE*3); damage_old(ch,victim,dice(2,7),gsn_lash,DAM_BASH,TRUE); victim->position = POS_RESTING; return; } void do_pugil(CHAR_DATA *ch,char *argument) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; int chance; int dam; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_pugil)) == 0 || IS_NPC(ch) || (!IS_NPC(ch) && ch->level < skill_table[gsn_pugil].skill_level[ch->class]) ) { send_to_char("You're not trained in the art of pugiling.\n\r",ch); return; } if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (ch->fighting == NULL) { send_to_char("You can't pugil someone like that.\n\r",ch); return; } if (victim == ch) { send_to_char("That would be a bit stupid.\n\r", ch); return; } obj = get_eq_char(ch,WEAR_WIELD); if (obj == NULL || obj->value[0] != WEAPON_STAFF) { send_to_char("You must be wielding a staff to pugil.\n\r",ch); return; } chance += (ch->level - victim->level); chance = URANGE(5, chance, 90); WAIT_STATE(ch,skill_table[gsn_pugil].beats); if (number_percent() < chance) { act("You smash $N with a bone crushing pugil!",ch,NULL,victim,TO_CHAR); act("$n smashes you with a bone crushing pugil!",ch,NULL,victim,TO_VICT); act("$n pugils $N with a bone crushing pugil!",ch,NULL,victim,TO_NOTVICT); check_improve(ch,gsn_pugil,TRUE,1); dam = dice(obj->value[1],obj->value[2]); dam += (get_skill(ch,gsn_enhanced_damage) * dam/100); if (ch->level <= 20) { dam *= number_range(10,13); dam /= 10; } else if (ch->level <= 25) { dam *= number_range(11,14); dam /= 10; } else if (ch->level <= 30) { dam *= number_range(12,15); dam /= 10; } else if (ch->level <= 35) { dam *= number_range(12,17); dam /= 10; } else if (ch->level <= 40) { dam *= number_range(13,18); dam /= 10; } else { dam *= number_range(14,20); dam /= 10; } damage_old(ch,victim,dam,gsn_pugil, attack_table[obj->value[3]].damage, TRUE); } else { check_improve(ch,gsn_pugil,FALSE,1); damage_old(ch,victim,0,gsn_pugil,DAM_NONE,TRUE); } return; } void do_protection_heat_cold(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; int chance; chance = get_skill(ch,gsn_protection_heat_cold); if (chance == 0 || ch->level <skill_table[gsn_protection_heat_cold].skill_level[ch->class]) { send_to_char("You don't know how to protect yourself from the elements.\n\r",ch); return; } if (is_affected(ch,gsn_protection_heat_cold)) { send_to_char("You are already protected from the elements.\n\r",ch); return; } if (number_percent() > chance) { send_to_char("You try to protect yourself from the elements but fail.\n\r",ch); check_improve(ch,gsn_protection_heat_cold,FALSE,1); return; } init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = gsn_protection_heat_cold; af.level = ch->level; af.modifier = 0; af.duration = ch->level; af.bitvector = 0; af.location = 0; affect_to_char(ch,&af); send_to_char("You are protected from the elements.\n\r",ch); check_improve(ch,gsn_protection_heat_cold,TRUE,1); return; } void do_undead_drain(CHAR_DATA *ch,char *argument) { CHAR_DATA *vch; int sn_drain; if (ch->level < 40) return; for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room) { if (vch->fighting == ch && number_percent() > 70) break; } if (vch == NULL) vch = ch->fighting; sn_drain = skill_lookup("undead drain"); if (sn_drain == -1) return; (*skill_table[sn_drain].spell_fun) (sn_drain,ch->level,ch,vch,TAR_CHAR_OFFENSIVE); return; } char * check_evaluation_fight(CHAR_DATA *ch,CHAR_DATA *victim) { int percent; char wound[100]; char buf[MAX_STRING_LENGTH]; if ((victim = ch->fighting) != NULL && can_see(ch,victim)) { if (victim->max_hit > 0) percent = victim->hit * 100 / victim->max_hit; else percent = -1; if (percent >= 100) sprintf(wound,"is in perfect condition."); else if (percent >= 95) sprintf(wound,"has a few scratches."); else if (percent >= 90) sprintf(wound,"has a few bruises."); else if (percent >= 80) sprintf(wound,"has some small wounds."); else if (percent >= 70) sprintf(wound,"has some big nasty cuts."); else if (percent >= 60) sprintf(wound,"has quite a few wounds."); else if (percent >= 50) sprintf(wound,"is bleeding profusely."); else if (percent >= 40) sprintf(wound,"is gushing blood."); else if (percent >= 30) sprintf(wound,"is screaming in pain."); else if (percent >= 20) sprintf(wound,"is spasming in shock."); else if (percent >= 10) sprintf(wound,"is writhing on the ground."); else if (percent >= 1) sprintf(wound,"is convulsing near death."); else sprintf(wound,"is nearly dead."); } return str_dup(buf); } void do_iron_resolve(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; if (is_affected(ch,gsn_iron_resolve)) { send_to_char("Your mind is already firmly set on your inner being.\n\r",ch); return; } if (ch->mana < 100) { send_to_char("You don't have the mental concentration right now.\n\r",ch); return; } if (number_percent() > get_skill(ch,gsn_iron_resolve)) { send_to_char("You try to concentrate on your inner being but fail to maintain it.\n\r",ch); ch->mana -= 50; WAIT_STATE(ch,12); return; } send_to_char("You feel yourself come together as mind and body.\n\r",ch); init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SKILL; af.type = gsn_iron_resolve; af.level = ch->level; af.location = 0; af.bitvector = 0; af.modifier = 0; af.duration = ch->level/3; ch->mana -= 100; WAIT_STATE(ch,12); } void do_quiet_movement(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; int chance; chance = get_skill(ch,gsn_quiet_movement); if (chance == 0 || ch->level < skill_table[gsn_quiet_movement].skill_level[ch->class]) { send_to_char("You don't know how to move with silent stealth through the wilderness.\n\r",ch); return; } if (is_affected(ch,gsn_quiet_movement)) { send_to_char("You are already attempting to move silently through the wilderness.\n\r",ch); return; } if (ch->in_room->sector_type == SECT_FOREST) { send_to_char("You attempt to move quietly through the forest.\n\r",ch); } else if (ch->in_room->sector_type == SECT_MOUNTAIN) { send_to_char("You attempt to move quietly through the mountains.\n\r",ch); } else if (ch->in_room->sector_type == SECT_HILLS) { send_to_char("You attempt to move quietly through the hills.\n\r",ch); } else { send_to_char("You aren't in the right kind of wilderness to mvoe quietly.\n\r",ch); return; } if (number_percent() > chance) { check_improve(ch,gsn_quiet_movement,FALSE,1); return; } check_improve(ch,gsn_quiet_movement,TRUE,1); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_quiet_movement; af.aftype = AFT_SKILL; af.location = 0; af.modifier = 0; af.duration = ch->level; af.level = ch->level; af.bitvector = 0; affect_to_char(ch,&af); return; } void do_executioners_grace(CHAR_DATA *ch,char *argument) { AFFECT_DATA af; int chance; chance = get_skill(ch,gsn_executioner); if(chance==0) { send_to_char("You don't know how to move with the deadly grace of an executioner.\n\r",ch); return; } if(number_percent() > chance) { send_to_char("You fail to move with the deadly grace of an executioner.\n\r",ch); WAIT_STATE(ch,PULSE_VIOLENCE*4); return; } if(is_affected(ch,gsn_executioner)) { send_to_char("You are already moving with the deadly grace of an executioner.\n\r",ch); WAIT_STATE(ch,PULSE_VIOLENCE*4); return; } send_to_char("You begin to flow with the deadly grace of an executioner.\n\r",ch); init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_executioner; af.location = APPLY_DAMROLL; af.modifier = 20; af.level = 60; af.duration = 50; af.bitvector = 0; af.aftype = AFT_SKILL; ch->mana-=300; affect_to_char(ch,&af); return; } void do_spike(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int chance, dam; char arg[MAX_INPUT_LENGTH]; one_argument(argument,arg); if (IS_NPC(ch)) return; if (ch->position == POS_FIGHTING) { send_to_char("You can't spike them in the heat of battle.\n\r",ch); return; } if ((get_skill(ch,gsn_spike) == 0) || ch->level < skill_table[gsn_spike].skill_level[ch->class]) { send_to_char("Huh?\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Attempt to spike which person?\n\r",ch); return; } if ( (victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't do that.\n\r",ch); return; } if (victim->fighting != NULL || victim->position == POS_FIGHTING) { send_to_char("They are moving around too much to get in close for the kill.\n\r",ch); return; } if (is_safe(ch,victim)) return; chance = get_skill(ch,gsn_spike)/2; chance += ch->level; chance -= victim->level * 3/2; chance -= number_range(0,15); if (!can_see(victim,ch)) chance += 10; if (victim->position == POS_FIGHTING) chance -= 25; else if (victim->position == POS_SLEEPING) chance += 10; else chance -= 10; chance /= 2; chance = URANGE(2,chance,90); act("$n strikes out at $N with deadly intensity.",ch,0,victim,TO_NOTVICT); act("You strike out at $N with deadly intensity.",ch,0,victim,TO_CHAR); act("$n strikes at you with deadly intensity.",ch,0,victim,TO_VICT); if (number_percent() < chance) { send_to_char("With agonising pain your skull is smashed by the blow!\n\r",victim); act("Your blow shatters $N's skull into bloody fragments!",ch,0,victim,TO_CHAR); act("$N's skull is shattered into bits of mangled flesh and bone by $n's strike!",ch,0,victim,TO_NOTVICT); raw_kill(ch,victim); WAIT_STATE(ch,PULSE_VIOLENCE*2); check_improve(ch,gsn_spike,TRUE,2); return; } else { send_to_char("You feel a sharp pain searing your skull!\n\r",victim); act("Your deathstrike smashes $N's skull but fails to kill.",ch,0,victim,TO_CHAR); dam = ch->level * 2; dam += dice(ch->level, 4); damage_old(ch,victim,dam,gsn_spike,DAM_PIERCE,TRUE); WAIT_STATE(ch,PULSE_VIOLENCE); check_improve(ch,gsn_spike,FALSE,1); } return; } bool check_unholy_bless(CHAR_DATA *ch, CHAR_DATA *victim) { AFFECT_DATA af; AFFECT_DATA *paf; AFFECT_DATA *paf_next; // Some reasons it is not working well. //int sn, hitmod, manamod, hrollmod, drollmod, vdrollmod, i; // Now this should be working. int sn, hitmod = 0, manamod = 0, hrollmod = 0, drollmod = 0, vdrollmod = 0, i; if (IS_NPC(victim) && (victim->pIndexData->vnum != MOB_VNUM_PLRMOB) ) { return FALSE; } if (!is_affected(ch,gsn_unholy_bless)) { return FALSE; } if (is_affected(victim,gsn_unholy_timer)) { return FALSE; } /*if (!IS_NPC(victim) && ((victim->played + current_time - victim->logon) / 3600) < 3) { return FALSE; }*/ if (isNewbie(victim)) { return FALSE; } sn = skill_lookup("unholy bless"); /* check if victim is AP and take his charges */ //if (is_affected(victim,gsn_unholy_bless)) { if (is_affected(victim,gsn_unholy_bless) && victim != ch) { for ( paf = victim->affected; paf != NULL; paf = paf_next ) { paf_next = paf->next; if ( paf->type == sn ) { switch (paf->location) { default: break; case APPLY_DAMROLL: vdrollmod = paf->modifier; break; } } } vdrollmod = (vdrollmod - 1) / 6; if (vdrollmod < 1) { vdrollmod = 0; } } else { vdrollmod = 0; } for (i=0; i < vdrollmod+1; i++) { for ( paf = ch->affected; paf != NULL; paf = paf_next ) { paf_next = paf->next; if ( paf->type == sn ) { switch (paf->location) { default: break; case APPLY_HIT: hitmod = paf->modifier; affect_remove( ch, paf ); break; case APPLY_MANA: manamod = paf->modifier; affect_remove( ch, paf ); break; case APPLY_HITROLL: hrollmod = paf->modifier; affect_remove( ch, paf ); break; case APPLY_DAMROLL: drollmod = paf->modifier; affect_remove( ch, paf ); break; } } } hitmod += 10; manamod += 10; hrollmod += 3; drollmod += 3; init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_SPELL; af.type = sn; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.modifier = hitmod; af.location = APPLY_HIT; affect_to_char(ch,&af); af.modifier = manamod; af.location = APPLY_MANA; affect_to_char(ch,&af); af.modifier = hrollmod; af.location = APPLY_HITROLL; affect_to_char(ch,&af); af.modifier = drollmod; af.location = APPLY_DAMROLL; affect_to_char(ch,&af); act("\x01B[1;31m$n's body pulses as power drains from $N's corpse!\x01B[0;37m",ch,0,victim,TO_NOTVICT); act("\x01B[1;31m$n's body pulses as power drains from your corpse!\x01B[0;37m",ch,0,victim,TO_VICT); act("\x01B[1;31mYour body pulses as you drain power from $N's corpse!\x01B[0;37m",ch,0,victim,TO_CHAR); } return TRUE; } void do_bind(CHAR_DATA *ch,char *argument) { CHAR_DATA *victim; int chance; AFFECT_DATA af; char arg[MAX_INPUT_LENGTH]; one_argument(argument,arg); if (IS_NPC(ch)) return; if (get_skill(ch,gsn_bind) == 0) { send_to_char("Huh?\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Attempt to bind who?\n\r",ch); return; } if ( (victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You can't do that.\n\r",ch); return; } if (victim->position != POS_SLEEPING) { send_to_char("They must be sleeping for you to bind them.\n\r",ch); return; } if (is_affected(victim,gsn_bind)) { send_to_char("They are already bound.\n\r",ch); return; } chance = get_skill(ch,gsn_bind)-20; if(is_affected(victim,AFF_HASTE)) chance-=30; if(is_affected(ch,AFF_HASTE)) chance+=15; if(get_curr_stat(victim,STAT_DEX)>get_curr_stat(ch,STAT_DEX)) chance-=20; if(number_percent() < chance) { af.aftype = AFT_SKILL; init_affect(&af); af.where = TO_AFFECTS; af.type = gsn_bind; af.level = ch->level; af.duration = -1; af.bitvector = AFF_BLIND; af.modifier = -5; af.location = APPLY_DEX; affect_to_char(victim,&af); act("$n puts a sack over $N's head and ties a rope around his legs tightly.",ch,0,victim,TO_NOTVICT); act("You feel someone putting something over your head and legs.",ch,0,victim,TO_VICT); act("You put a sack over $N's head and tie a rope around his legs tightly.",ch,0,victim,TO_CHAR); WAIT_STATE(ch,PULSE_VIOLENCE); check_improve(ch,gsn_bind,TRUE,1); } else { init_affect(&af); af.where = TO_AFFECTS; af.aftype = AFT_INVIS; af.type = gsn_bind; af.level = ch->level; af.duration = 3; af.bitvector = 0; af.modifier = 0; af.location = APPLY_HITROLL; affect_to_char(victim,&af); act("$n tries to put a sack over $N's head but it rips.",ch,0,victim,TO_NOTVICT); send_to_char("You feel someone trying to put something over your head and legs.",victim); act("You try to put a sack over $N's head but it rips.",ch,0,victim,TO_CHAR); WAIT_STATE(ch,PULSE_VIOLENCE*3); check_improve(ch,gsn_bind,FALSE,3); } return; } void check_cheap_shot(CHAR_DATA *ch, CHAR_DATA *victim) { int chance; int dam; chance=get_skill(ch,gsn_cheap_shot); if(chance<2) return; if(is_affected(victim,AFF_HASTE)) chance-=30; if(is_affected(ch,AFF_HASTE)) chance+=15; if(is_affected(victim,AFF_FLYING)) chance-=20; chance*=.75; if(number_percent() < chance) { act("Seizing upon $N's moment of weakness, you brutally kick him while he's down!",ch,0,victim,TO_CHAR); act("Seizing upon your moment of weakness, $n brutally kicks you while you're down!",ch,0,victim,TO_VICT); act("Seizing upon $N's moment of weakness, $n brutally kicks him while he's down!",ch,0,victim,TO_NOTVICT); dam=40; if(number_percent() < 26) { act("$N grunts in pain as you land a particularly vicious kick!",ch,0,victim,TO_CHAR); act("You grunt in pain as $n lands a particularly vicious kick!",ch,0,victim,TO_VICT); act("$N grunts in pain as $n lands a particularly vicious kick!",ch,0,victim,TO_NOTVICT); dam=125; WAIT_STATE(victim,PULSE_VIOLENCE); } damage_old(ch,victim,dam,gsn_cheap_shot,DAM_PIERCE,TRUE); check_improve(ch,gsn_cheap_shot,TRUE,1); WAIT_STATE(victim,PULSE_VIOLENCE); return; } else { send_to_char("You were unable to get a cheap shot in.\n\r",ch); check_improve(ch,gsn_cheap_shot,FALSE,1); return; } } void do_unbind(CHAR_DATA *ch,char *argument) { if(!is_affected(ch,gsn_bind)) { send_to_char("You are not bound.\n\r",ch); return; } if(number_percent()>30) { act("You break free of the bindings on your head and legs.",ch,0,0,TO_CHAR); act("$n breaks free of the bindings on $s head and legs.",ch,0,0,TO_ROOM); affect_strip( ch, gsn_bind ); WAIT_STATE(ch,PULSE_VIOLENCE); } else { act("You fail to break free of the bindings on your head and legs.",ch,0,0,TO_CHAR); act("$n fails to break free of the bindings on $s head and legs.",ch,0,0,TO_ROOM); WAIT_STATE(ch,PULSE_VIOLENCE); } } void do_blitz( CHAR_DATA *ch, char *argument ) // Do not disable this! -Det. { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance, imod; char buf[MAX_STRING_LENGTH]; bool isDS; if (cabal_down(ch,CABAL_RAVAGER)) return; one_argument(argument,arg); if ((chance = get_skill(ch,gsn_blitz)) == 0) { send_to_char("Blitzing? What's that?\n\r",ch); return; } if (IS_NPC(ch) && IS_AFFECTED(ch,AFF_CHARM)) return; if (arg[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,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim->position < POS_FIGHTING) { act("You'll have to let $M get back up first.",ch,NULL,victim,TO_CHAR); return; } if (victim == ch) { send_to_char("You try to blitz your brains out, but fail.\n\r",ch); return; } if ((victim->fighting!=ch) && (ch->fighting != NULL)) { send_to_char("You must be directly fighting that person to blitz them.\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; } /* modify chance */ chance += ch->carry_weight / 200; chance -= victim->carry_weight / 200; if (ch->size < victim->size) { chance += (ch->size - victim->size) * 5; } else { chance += (ch->size - victim->size) * 5; } if (is_affected(victim,gsn_protective_shield)) { chance -= 5; } if (is_affected(victim,gsn_wraithform)) { chance -= 5; } if (is_affected(victim,gsn_kinetic_shield)) { chance -= 5; } if (is_affected(victim,gsn_fireshield)) { chance -= 5; } chance += get_curr_stat(ch,STAT_STR) + 5; chance -= (get_curr_stat(victim,STAT_DEX)); chance -= GET_AC(victim,AC_BASH) /20; if (IS_SET(ch->off_flags,OFF_FAST) || is_affected(ch,skill_lookup("haste"))) { chance += 10; } if (is_affected(ch,skill_lookup("bloodthirst"))) { chance += 10; } if (is_affected(ch,skill_lookup("berserk"))) { chance += 10; } if (IS_SET(victim->off_flags,OFF_FAST) || is_affected(victim,skill_lookup("haste"))) { chance -= 5; } chance += (ch->level - victim->level); if (!IS_NPC(ch) && !IS_NPC(victim) && (victim->fighting == NULL || ch->fighting == NULL)) { sprintf(buf,"Help! %s is blitzing me!",PERS(ch,victim)); do_myell(victim,buf); } if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) ) { chance -= 3 * (get_skill(victim,gsn_dodge) - chance); } imod = 15; isDS = FALSE; /* now the attack */ if (number_percent() < chance - 20) { act("$n pummels you to the ground with excruciating force!", ch,NULL,victim,TO_VICT); act("You slam into $N, pummeling $M into the ground!",ch,NULL,victim,TO_CHAR); act("$n pummels $N into the ground with a powerful blitz.",ch,NULL,victim,TO_NOTVICT); damage_old(ch,victim,(3 * ch->size + chance),gsn_blitz,DAM_BASH,TRUE); check_improve(ch,gsn_blitz,TRUE,3); WAIT_STATE(victim,PULSE_VIOLENCE*2); WAIT_STATE(ch,2*PULSE_VIOLENCE); if (number_percent() < chance - imod) { if (is_affected(victim,gsn_sanctuary) && (number_percent() < chance-imod)) { if (check_dispel(ch->level,victim,skill_lookup("sanctuary"))) { act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM); act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR); act("The white aura about $n vanishes!",victim,NULL,NULL,TO_ROOM); isDS = TRUE; } } if ((isDS == FALSE) && is_affected(victim,gsn_fireshield) && (number_percent() < chance-imod)) { if (check_dispel(ch->level,victim,skill_lookup("fireshield"))) { act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM); act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR); act("The fire around $n vanishes!",victim,NULL,NULL,TO_ROOM); isDS = TRUE; } } if ((isDS == FALSE) && is_affected(victim,gsn_stoneskin) && (number_percent() < chance-imod)) { if (check_dispel(ch->level,victim,skill_lookup("stone skin"))) { act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM); act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR); act("The skin of $n softens into flesh!",victim,NULL,NULL,TO_ROOM); isDS = TRUE; } } if ((isDS == FALSE) && is_affected(victim,gsn_wraithform) && (number_percent() < chance-imod)) { if (check_dispel(ch->level,victim,skill_lookup("wraithform"))) { act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM); act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR); act("The body of $n fades back into the Prime Material Plane!",victim,NULL,NULL,TO_ROOM); isDS = TRUE; } } if ((isDS == FALSE) && is_affected(victim,gsn_shroud) && (number_percent() < chance-imod)) { if (check_dispel(ch->level,victim,skill_lookup("shroud"))) { act("$n looks stunned as $s mind wanders from $s spells.",victim,0,0,TO_ROOM); act("Your head throbs with pain as you lose control over your spells.",victim,0,0,TO_CHAR); act("The black aura about $n vanishes!",victim,NULL,NULL,TO_ROOM); isDS = TRUE; } } } } else { damage_old(ch,victim,0,gsn_blitz,DAM_BASH,FALSE); act("You fall over and bite the dust!",ch,NULL,victim,TO_CHAR); act("$n falls flat on $s face, eating a mouthful of dirt.",ch,NULL,victim,TO_NOTVICT); act("You evade $n's blitz, and $e falls flat on $s face.",ch,NULL,victim,TO_VICT); check_cheap_shot(victim,ch); check_improve(ch,gsn_blitz,FALSE,3); ch->position = POS_RESTING; WAIT_STATE(ch,2*PULSE_VIOLENCE); } return; } void check_parting_blow( CHAR_DATA *ch, CHAR_DATA *victim ) { if (get_skill(victim,gsn_parting_blow) > 1) { if (number_percent() < get_skill(victim,gsn_parting_blow)) { act("You get in one more shot as $N flees.",victim,0,ch,TO_CHAR); act("$n gets in one more shot as $N flees.",victim,0,ch,TO_NOTVICT); act("$n gets in one more shot as you flee.",victim,0,ch,TO_VICT); one_hit(victim,ch,gsn_parting_blow); check_improve(victim,gsn_parting_blow,TRUE,1); } else { check_improve(victim,gsn_parting_blow,TRUE,1); } } return; } bool check_ironhands( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ( !IS_AWAKE(victim) ) return FALSE; if (IS_NPC(victim)) return FALSE; if ((chance = get_skill(victim,gsn_ironhands)) == 0) return FALSE; if (get_eq_char(victim,WEAR_WIELD) != NULL) return FALSE; if (!can_see(ch,victim)) chance *= number_range(6/10,3/4); if ( number_percent( ) >= ((chance + (victim->level +ch->level) - 10)/2)) { check_improve(victim,gsn_ironhands,FALSE,5); return FALSE; } /* The rest is all new dual wield stuff, with dam types displayed for clarity when dual wielding - Ceran */ attack=get_dam_message(ch,dt); sprintf(buf1,"You parry $n's %s.",attack); sprintf(buf2,"$N parries your %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_ironhands,TRUE,6); return TRUE; } bool check_unarmed_defense( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { int chance; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char *attack; if ( !IS_AWAKE(victim) ) return FALSE; if (IS_NPC(victim)) return FALSE; if ((chance = get_skill(victim,gsn_unarmed_defense)) == 0) return FALSE; if (get_eq_char(victim,WEAR_WIELD) != NULL) return FALSE; if (!can_see(ch,victim)) { chance *= number_range(6/10,3/4); } chance -= (get_curr_stat(victim,STAT_DEX) - get_curr_stat(ch,STAT_DEX))*4; chance -= (victim->level - ch->level)*2; if (number_percent() >= (chance)) { check_improve(victim,gsn_unarmed_defense,FALSE,5); return FALSE; } attack=get_dam_message(ch,dt); sprintf(buf1,"You deftly avoid $n's %s.",attack); sprintf(buf2,"$N deftly avoids %s.",attack); act(buf1,ch,0,victim,TO_VICT); act(buf2,ch,0,victim,TO_CHAR); check_improve(victim,gsn_unarmed_defense,TRUE,6); return TRUE; } char *get_dam_message(CHAR_DATA *ch, int dt) { return get_attack_noun(ch,dt); } char * get_attack_noun(CHAR_DATA *ch, int dt) { OBJ_DATA *wield; int tmp_dt; char *attack; tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[tmp_dt - TYPE_HIT].noun; else { attack = attack_table[17].noun; } return attack; } int get_attack_number(CHAR_DATA *ch, int dt) { OBJ_DATA *wield; int tmp_dt; tmp_dt = TYPE_HIT; if (dt == gsn_dual_wield) wield = get_eq_char(ch,WEAR_DUAL_WIELD); else wield = get_eq_char(ch,WEAR_WIELD); if (wield != NULL) tmp_dt += wield->value[3]; else tmp_dt += ch->dam_type; if (tmp_dt > TYPE_HIT && tmp_dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) return (tmp_dt - TYPE_HIT); return 1; } void do_gslay (CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; one_argument (argument, arg); if (arg[0] == '\0') { send_to_char ("Slay whom?\n\r", ch); return; } if ((victim = get_char_world (ch, arg)) == NULL) { send_to_char ("They aren't here.\n\r", ch); return; } if (ch == victim) { send_to_char ("Suicide is a mortal sin.\n\r", ch); return; } if (!IS_NPC (victim) && victim->level >= get_trust (ch)) { send_to_char ("You failed.\n\r", ch); return; } act ("You slay $M in accordance with your will!", ch, NULL, victim, TO_CHAR); act ("$n slays you according to his will!", ch, NULL, victim, TO_VICT); act ("$n slays $N in accordance with his will!", ch, NULL, victim, TO_NOTVICT); sprintf(buf, "{WAn Immortal {Gglares at {Y%s {Gand he explodes into a million pieces!{x", victim->name); do_echo(ch, buf); raw_kill (ch, victim ); do_help(ch, "rules" ); return; }