/* Hack of one_hit so we can use the checks again elsewhere. * The goal of this is to be able to be used in skills such as bash, * to detect chance of hit. * also, if use_weapon is false, it takes dt as a skill, and gets the skill's % * learned and uses that as its skill-value. * so for backstab, we do a. * is_hit(ch, victim, gsn_backstab, true, false); * this makes it use the weapons data, and influence later by the skill check * but if we do a..... * is_hit(ch, victim, gsn_trip, false, false); * we purely base the chance to hit off of the AC value's and the * skill value of gsn_trip on the user. * * This effectively gives skills a better skill check, then the average * system that was used, which was just based purely on the skill level * and the player/victim level. And Misc other stats. * * With this I put a modified do_bash to showcase the simple system * * Note: This works well, changing all the skills to this method * is fast, and easy, and returns a much faster method of * registering a hit, so all you need todo is create your damage modifiers. * * * This can be used within one_hit, to replace the existing hit code, * why duplicate when you don't need to * * * Credit: I require no credit, but if you want to mention me, please feel * free to. Questions, comments, concerns, I can be reached on mudbytes * or on my mud, CombatMud. sandstorm.arthmoor.com port 9696 * Cheers. */ /* did we hit? -- Darien*/ bool is_hit(CHAR_DATA *ch, CHAR_DATA *victim, int dt, bool use_weapon, bool secondary) { OBJ_DATA *wield; int victim_ac; int thac0; int thac0_00; int thac0_32; int diceroll; int sn = 0,skill; int dam_type; if(use_weapon) { if (!secondary) wield = get_eq_char( ch, WEAR_WIELD ); else wield = get_eq_char( ch, WEAR_SECONDARY ); /* get the weapon skill */ sn = get_weapon_sn(ch); skill = 20 + get_weapon_skill(ch,sn); } else { // we're a skill! skill = get_skill(ch, dt); } 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 (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; /* * 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->iclass].thac0_00; thac0_32 = class_table[ch->iclass].thac0_32; } thac0 = interpolate( ch->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; /* special skill checks here * If we use a weapon, then we modify here if it is a special skill * if no weapon is used, then the skill-value is already set. * and that doesn't affect thaco unless you specify otherwise. * an example of this would be trip. */ if(use_weapon) { // weapon-skills if (dt == skill_lookup("backstab")) thac0 -= 10 * (100 - get_skill(ch,skill_lookup("backstab"))); // bash is a slow but powerful hit, so thac0 goes up slightly, // making it a harder hit, this is optional if (dt == skill_lookup("bash")) thac0 += 2 * (100 - get_skill(ch,skill_lookup("bash"))); } else { // affect thac0 with non-weapon-skills. // so for trip, we lower the thac0 (which = good) if(dt == gsn_trip) thac0 -= 10 * (100 - skill); } 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! * hit or miss! */ while ( ( diceroll = number_bits( 5 ) ) >= 20 ) ; if ( diceroll == 0 || ( diceroll != 19 && diceroll < thac0 - victim_ac ) ) { /* Miss. */ return FALSE; } // we hit the enemy, lets return true and do this return true; } /**************************************************************************************************/ /* bash revamped as an example of what can be done with this minor change */ void do_bash( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; int chance; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_bash)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_BASH)) || (!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 (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_NPC(victim) && victim->fighting != NULL && !is_same_group(ch,victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim) { act("But $N is your friend!",ch,NULL,victim,TO_CHAR); return; } // okay, here we go. // chance is just used as a damage modifier // thats it, thats all. chance = 0; /* modifiers */ /* size and weight */ chance += ch->carry_weight / 250; chance -= victim->carry_weight / 200; if (ch->size < victim->size) chance += (ch->size - victim->size) * 15; 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,AFF_HASTE)) chance += 10; if (IS_SET(victim->off_flags,OFF_FAST) || IS_AFFECTED(victim,AFF_HASTE)) chance -= 30; /* level */ chance += (ch->level - victim->level); if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) ) { chance -= 3 * (get_skill(victim,gsn_dodge) - chance); } /* now the attack, very simple, */ if(is_hit(ch, victim, gsn_bash, true, false)) { 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); DAZE_STATE(victim, 3 * PULSE_VIOLENCE); WAIT_STATE(ch,skill_table[gsn_bash].beats); victim->position = POS_RESTING; damage(ch, victim, number_range(2, 2 + 2 * ch->size + chance/20), gsn_bash, DAM_BASH,FALSE); } else // moment of sadness { damage(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_improve(ch,gsn_bash,FALSE,1); ch->position = POS_RESTING; WAIT_STATE(ch,skill_table[gsn_bash].beats * 3/2); } check_killer(ch,victim); }